Skip to content

Commit 9b6e017

Browse files
committed
[ver1.2.4] Add font settings. Bug fix.
1 parent 603c434 commit 9b6e017

15 files changed

+533
-354
lines changed

android/app/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
2323

2424
def flutterVersionCode = localProperties.getProperty("flutter.versionCode")
2525
if (flutterVersionCode == null) {
26-
flutterVersionCode = "245"
26+
flutterVersionCode = "261"
2727
}
2828

29-
def flutterVersionName = "1.2.3"
29+
def flutterVersionName = "1.2.4"
3030
//def flutterVersionName = localProperties.getProperty("flutter.versionName")
3131
//if (flutterVersionName == null) {
3232
// flutterVersionName = "1.0Beta3"
2 MB
Binary file not shown.
912 KB
Binary file not shown.
914 KB
Binary file not shown.
947 KB
Binary file not shown.

lib/models/app_settings_model.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ class AppSettings {
99
final String defaultPageTheme;
1010
final String defaultThemeMode;
1111
final List<int> toolbarLayout;
12+
final String defaultFonts; // 新增的字体属性
1213

1314
const AppSettings({
1415
this.defaultSftpPath,
@@ -37,6 +38,7 @@ class AppSettings {
3738
15,
3839
16
3940
],
41+
this.defaultFonts = 'maple', // 默认字体
4042
});
4143

4244
AppSettings copyWith({
@@ -49,6 +51,7 @@ class AppSettings {
4951
String? defaultPageTheme,
5052
String? defaultThemeMode,
5153
List<int>? toolbarLayout,
54+
String? defaultFonts,
5255
}) {
5356
return AppSettings(
5457
defaultSftpPath: defaultSftpPath ?? this.defaultSftpPath,
@@ -60,6 +63,7 @@ class AppSettings {
6063
defaultPageTheme: defaultPageTheme ?? this.defaultPageTheme,
6164
defaultThemeMode: defaultThemeMode ?? this.defaultThemeMode,
6265
toolbarLayout: toolbarLayout ?? this.toolbarLayout,
66+
defaultFonts: defaultFonts ?? this.defaultFonts,
6367
);
6468
}
6569

@@ -74,6 +78,7 @@ class AppSettings {
7478
'defaultPageTheme': defaultPageTheme,
7579
'defaultThemeMode': defaultThemeMode,
7680
'toolbarLayout': toolbarLayout,
81+
'defaultFonts': defaultFonts,
7782
};
7883
}
7984

@@ -89,6 +94,7 @@ class AppSettings {
8994
defaultThemeMode: map['defaultThemeMode'] ?? 'system',
9095
toolbarLayout: List<int>.from(map['toolbarLayout'] ??
9196
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]),
97+
defaultFonts: map['defaultFonts'] ?? 'maple',
9298
);
9399
}
94100

@@ -103,6 +109,7 @@ class AppSettings {
103109
defaultPageTheme: 'default',
104110
defaultThemeMode: 'system',
105111
toolbarLayout: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
112+
defaultFonts: 'maple',
106113
);
107114
}
108115
}

lib/pages/help.dart

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,19 +54,18 @@ class _HelpPageState extends State<HelpPage> {
5454
HelpItem(
5555
title: '关于 & 反馈',
5656
content: '''
57-
ConnSSH 版本 1.2.3
58-
59-
新年快乐~
57+
ConnSSH 版本 1.2.4
6058
6159
此版本更新内容:
6260
6361
新增功能:
64-
• 服务器页面支持分组
65-
• SFTP文件下载支持sudo执行
62+
• 终端页面支持更换字体
6663
6764
问题改进:
68-
• 修复部分页面边框过细的问题
69-
• 修复 #23 帮助界面异常切换的问题
65+
• 修复备份时无法退出加载框的问题
66+
• 修复设置默认终端主题无效的问题
67+
• 增加更多终端配色方案
68+
• 修复telnet无法自定义快捷栏的问题
7069
7170
7271
如有问题或建议,请发送邮件至:

lib/pages/settings/global.dart

Lines changed: 136 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// global_settings_page.dart
2+
import 'dart:async';
23
import 'dart:io';
34

45
import 'package:file_picker_ohos/file_picker_ohos.dart';
@@ -55,131 +56,156 @@ class _GlobalSettingsPageState extends State<GlobalSettingsPage> {
5556
bool passwordObscure = true;
5657
bool confirmPasswordObscure = true;
5758

59+
// 保存主页面的 context
60+
final BuildContext pageContext = context;
61+
5862
showDialog(
59-
context: context,
60-
builder: (dialogContext) => StatefulBuilder(
61-
builder: (context, setState) {
62-
return AlertDialog(
63-
title: const Text('备份数据'),
64-
content: SingleChildScrollView(
65-
child: Column(
66-
mainAxisSize: MainAxisSize.min,
67-
children: [
68-
const SizedBox(height: 16),
69-
TextField(
70-
controller: passwordController,
71-
obscureText: passwordObscure,
72-
decoration: InputDecoration(
73-
labelText: '请设置密码',
74-
border: OutlineInputBorder(
75-
borderRadius: BorderRadius.circular(12.0),
76-
),
77-
suffixIcon: IconButton(
78-
icon: Icon(passwordObscure
79-
? Icons.visibility
80-
: Icons.visibility_off),
81-
onPressed: () =>
82-
setState(() => passwordObscure = !passwordObscure),
63+
context: pageContext,
64+
builder: (dialogContext) {
65+
return StatefulBuilder(
66+
builder: (context, setState) {
67+
return AlertDialog(
68+
title: const Text('备份数据'),
69+
content: SingleChildScrollView(
70+
child: Column(
71+
mainAxisSize: MainAxisSize.min,
72+
children: [
73+
const SizedBox(height: 16),
74+
TextField(
75+
controller: passwordController,
76+
obscureText: passwordObscure,
77+
decoration: InputDecoration(
78+
labelText: '请设置密码',
79+
border: OutlineInputBorder(
80+
borderRadius: BorderRadius.circular(12.0),
81+
),
82+
suffixIcon: IconButton(
83+
icon: Icon(passwordObscure
84+
? Icons.visibility
85+
: Icons.visibility_off),
86+
onPressed: () => setState(
87+
() => passwordObscure = !passwordObscure),
88+
),
8389
),
8490
),
85-
),
86-
const SizedBox(height: 12),
87-
TextField(
88-
controller: confirmPasswordController,
89-
obscureText: confirmPasswordObscure,
90-
decoration: InputDecoration(
91-
labelText: '确认密码',
92-
border: OutlineInputBorder(
93-
borderRadius: BorderRadius.circular(12.0),
94-
),
95-
suffixIcon: IconButton(
96-
icon: Icon(confirmPasswordObscure
97-
? Icons.visibility
98-
: Icons.visibility_off),
99-
onPressed: () => setState(() =>
100-
confirmPasswordObscure = !confirmPasswordObscure),
91+
const SizedBox(height: 12),
92+
TextField(
93+
controller: confirmPasswordController,
94+
obscureText: confirmPasswordObscure,
95+
decoration: InputDecoration(
96+
labelText: '确认密码',
97+
border: OutlineInputBorder(
98+
borderRadius: BorderRadius.circular(12.0),
99+
),
100+
suffixIcon: IconButton(
101+
icon: Icon(confirmPasswordObscure
102+
? Icons.visibility
103+
: Icons.visibility_off),
104+
onPressed: () => setState(() =>
105+
confirmPasswordObscure = !confirmPasswordObscure),
106+
),
101107
),
102108
),
103-
),
104-
const SizedBox(height: 8),
105-
if (Platform.isAndroid)
106-
const Text(
107-
'备份文件将保存在应用私有目录中,您可以通过文件管理器访问。',
108-
style: TextStyle(fontSize: 12),
109-
),
110-
],
111-
),
112-
),
113-
actions: [
114-
OutlinedButton(
115-
onPressed: () => Navigator.of(context).pop(),
116-
child: const Text('取消'),
109+
const SizedBox(height: 8),
110+
if (Platform.isAndroid)
111+
const Text(
112+
'备份文件将保存在应用私有目录中,您可以通过文件管理器访问。',
113+
style: TextStyle(fontSize: 12),
114+
),
115+
],
116+
),
117117
),
118-
OutlinedButton(
119-
onPressed: () async {
120-
if (passwordController.text.isEmpty) {
121-
ScaffoldMessenger.of(context)
122-
.showSnackBar(const SnackBar(content: Text('请输入密码')));
123-
return;
124-
}
125-
if (passwordController.text !=
126-
confirmPasswordController.text) {
127-
ScaffoldMessenger.of(context).showSnackBar(
128-
const SnackBar(content: Text('两次输入的密码不一致')));
129-
return;
130-
}
131-
132-
final NavigatorState nav = Navigator.of(context);
133-
nav.pop();
134-
135-
// 显示加载对话框
136-
showDialog(
137-
context: context,
138-
barrierDismissible: false,
139-
builder: (context) => const AlertDialog(
140-
backgroundColor: Colors.transparent,
141-
content: Column(
142-
mainAxisSize: MainAxisSize.min,
143-
children: [
144-
CircularProgressIndicator(),
145-
SizedBox(height: 16),
146-
Text('正在备份数据...'),
147-
],
118+
actions: [
119+
OutlinedButton(
120+
onPressed: () => Navigator.of(context).pop(),
121+
child: const Text('取消'),
122+
),
123+
OutlinedButton(
124+
onPressed: () async {
125+
if (passwordController.text.isEmpty) {
126+
ScaffoldMessenger.of(pageContext)
127+
.showSnackBar(const SnackBar(content: Text('请输入密码')));
128+
return;
129+
}
130+
if (passwordController.text !=
131+
confirmPasswordController.text) {
132+
ScaffoldMessenger.of(pageContext).showSnackBar(
133+
const SnackBar(content: Text('两次输入的密码不一致')));
134+
return;
135+
}
136+
137+
Navigator.of(context).pop();
138+
139+
final completer = Completer<void>();
140+
141+
final loadingDialogFuture = showDialog(
142+
context: pageContext,
143+
barrierDismissible: false,
144+
builder: (context) => const AlertDialog(
145+
backgroundColor: Colors.transparent,
146+
content: Column(
147+
mainAxisSize: MainAxisSize.min,
148+
children: [
149+
CircularProgressIndicator(),
150+
SizedBox(height: 16),
151+
Text('正在备份数据...'),
152+
],
153+
),
148154
),
149-
),
150-
);
155+
);
156+
157+
Future<void> backupOperation() async {
158+
try {
159+
final filePath = await _backupService
160+
.backupData(passwordController.text);
151161

152-
try {
153-
// 执行备份
154-
final filePath = await _backupService
155-
.backupData(passwordController.text);
162+
if (!mounted) return;
156163

157-
// 关闭加载对话框
158-
if (Navigator.of(context, rootNavigator: true).canPop()) {
159-
Navigator.of(context, rootNavigator: true).pop();
160-
}
164+
completer.complete();
161165

162-
// 显示结果
163-
_showResultDialog('备份成功', '备份文件已保存到:\n$filePath');
164-
} catch (e) {
165-
// 关闭加载对话框
166-
if (Navigator.of(context, rootNavigator: true).canPop()) {
167-
Navigator.of(context, rootNavigator: true).pop();
166+
await Future.delayed(const Duration(milliseconds: 100));
167+
168+
if (Navigator.of(pageContext, rootNavigator: true)
169+
.canPop()) {
170+
Navigator.of(pageContext, rootNavigator: true).pop();
171+
}
172+
173+
await loadingDialogFuture;
174+
175+
_showResultDialog(
176+
pageContext, '备份成功', '备份文件已保存到:\n$filePath');
177+
} catch (e) {
178+
if (!mounted) return;
179+
180+
completer.completeError(e);
181+
182+
await Future.delayed(const Duration(milliseconds: 100));
183+
184+
if (Navigator.of(pageContext, rootNavigator: true)
185+
.canPop()) {
186+
Navigator.of(pageContext, rootNavigator: true).pop();
187+
}
188+
189+
await loadingDialogFuture;
190+
191+
_showResultDialog(
192+
pageContext, '备份失败', '错误: $e\n请检查存储空间');
193+
}
168194
}
169195

170-
_showResultDialog('备份失败', '错误: $e\n请检查存储空间');
171-
}
172-
},
173-
child: const Text('备份'),
174-
),
175-
],
176-
);
177-
},
178-
),
196+
backupOperation();
197+
},
198+
child: const Text('备份'),
199+
),
200+
],
201+
);
202+
},
203+
);
204+
},
179205
);
180206
}
181207

182-
void _showResultDialog(String title, String message) {
208+
void _showResultDialog(BuildContext context, String title, String message) {
183209
showDialog(
184210
context: context,
185211
builder: (context) => AlertDialog(

0 commit comments

Comments
 (0)