CH-J SM Mobileการจัดการเซิร์ฟเวอร์ผ่าน SSH
เมนู
ซอร์สที่เผยแพร่

CH-J SM Mobile

เรียกดูไดเรกทอรีและไฟล์ของรุ่นแอปพลิเคชันที่ระบุ

ดาวน์โหลด ZIP ของซอร์ส
CH-J / SM Mobile 175 ไฟล์
sm-mobile-20261016T185235Z-8e93ecc1b59a วันที่เพิ่ม: · วันที่บิลด์:
settings_page.dart วันที่เพิ่ม: ไม่ได้บันทึกวันที่ 7.1 KB · 209 บรรทัด
โค้ด ดาวน์โหลดไฟล์
1import 'package:flutter/material.dart';
2import '../core/app_controller.dart';
3import '../core/build_info.dart';
4import '../l10n/strings.dart';
5import 'adaptive.dart';
6import 'change_password.dart';
7import 'common.dart';
8import 'gates.dart';
9import 'profile_io.dart';
11class SettingsPage extends StatefulWidget {
12 final AppController controller;
13 const SettingsPage(this.controller, {super.key});
14 @override
15 State<SettingsPage> createState() => _SettingsPageState();
18class _SettingsPageState extends State<SettingsPage> {
19 bool busy = false;
20 Future<void> action(Future<void> Function() task) async {
21 setState(() => busy = true);
22 try {
23 await task();
24 } catch (e) {
25 if (mounted) showFailure(context, e);
26 } finally {
27 if (mounted) setState(() => busy = false);
28 }
29 }
31 @override
32 Widget build(BuildContext context) {
33 final c = widget.controller;
34 return LayoutBuilder(
35 builder: (context, constraints) => ListView(
36 padding: readablePadding(constraints),
37 children: [
38 Text(
39 'CH-J · SM Mobile $appVersion',
40 style: Theme.of(context).textTheme.titleLarge,
41 ),
42 Text(buildId),
43 const SizedBox(height: 12),
44 Text(context.tr('localOnly')),
45 const SizedBox(height: 24),
46 languagePicker(context, c),
47 const SizedBox(height: 16),
48 DropdownButtonFormField<ThemeMode>(
49 initialValue: c.theme,
50 isExpanded: true,
51 decoration: InputDecoration(labelText: context.tr('theme')),
52 items: ThemeMode.values
53 .map(
54 (t) => DropdownMenuItem(
55 value: t,
56 child: Text(context.tr(t.name)),
57 ),
58 )
59 .toList(),
60 onChanged: (t) => action(() async {
61 c.theme = t!;
62 await c.saveSettings();
63 }),
64 ),
65 const SizedBox(height: 24),
66 Text(
67 context.tr('securitySection'),
68 style: Theme.of(context).textTheme.titleMedium,
69 ),
70 ListTile(
71 contentPadding: EdgeInsets.zero,
72 leading: const Icon(Icons.password),
73 title: Text(context.tr('changePassword')),
74 subtitle: Text(
75 '${context.tr('kdfInfo')}: '
76 '${c.vault.kdfName == 'argon2id' ? 'Argon2id' : 'PBKDF2-SHA256'}'
77 ' · AES-256-GCM',
78 ),
79 trailing: const Icon(Icons.chevron_right),
80 onTap: busy
81 ? null
82 : () async {
83 await Navigator.push(
84 context,
85 MaterialPageRoute(builder: (_) => ChangePasswordPage(c)),
86 );
87 if (mounted) setState(() {});
88 },
89 ),
90 SwitchListTile.adaptive(
91 contentPadding: EdgeInsets.zero,
92 title: Text(context.tr('biometric')),
93 subtitle: Text(context.tr('biometricNote')),
94 value: c.biometric,
95 onChanged: busy
96 ? null
97 : (v) => action(
98 () => c.setBiometric(v, context.tr('biometricReason')),
99 ),
100 ),
101 SwitchListTile.adaptive(
102 contentPadding: EdgeInsets.zero,
103 title: Text(context.tr('lockBackground')),
104 value: c.lockBackground,
105 onChanged: (v) => action(() async {
106 c.lockBackground = v;
107 await c.saveSettings();
108 }),
109 ),
110 const SizedBox(height: 16),
111 DropdownButtonFormField<int>(
112 isExpanded: true,
113 initialValue: c.idleMinutes,
114 decoration: InputDecoration(labelText: context.tr('idleTimeout')),
115 items: idleChoices
116 .map((i) => DropdownMenuItem(value: i, child: Text('$i')))
117 .toList(),
118 onChanged: (i) => action(() async {
119 c.idleMinutes = i!;
120 await c.saveSettings();
121 }),
122 ),
123 const SizedBox(height: 16),
124 DropdownButtonFormField<int>(
125 isExpanded: true,
126 initialValue: c.monitorSeconds,
127 decoration: InputDecoration(
128 labelText: context.tr('monitorInterval'),
129 ),
130 items: [5, 10, 30, 60]
131 .map((i) => DropdownMenuItem(value: i, child: Text('$i')))
132 .toList(),
133 onChanged: (i) => action(() async {
134 c.monitorSeconds = i!;
135 await c.saveSettings();
136 }),
137 ),
138 const SizedBox(height: 24),
139 OutlinedButton.icon(
140 onPressed: busy
141 ? null
142 : () => action(() => importProfiles(context, c)),
143 icon: const Icon(Icons.file_open),
144 label: Text(context.tr('importProfiles')),
145 ),
146 OutlinedButton.icon(
147 onPressed: busy ? null : () => action(() => exportProfiles(c)),
148 icon: const Icon(Icons.ios_share),
149 label: Text(context.tr('exportProfiles')),
150 ),
151 const SizedBox(height: 16),
152 ListTile(
153 title: Text(context.tr('license')),
154 leading: const Icon(Icons.description_outlined),
155 onTap: () => Navigator.push(
156 context,
157 MaterialPageRoute(
158 builder: (ctx) => Scaffold(
159 appBar: AppBar(title: Text(ctx.tr('license'))),
160 body: SingleChildScrollView(
161 padding: const EdgeInsets.all(20),
162 child: SelectableText(c.legal.license),
163 ),
164 ),
165 ),
166 ),
167 ),
168 ListTile(
169 title: Text(context.tr('guidance')),
170 leading: const Icon(Icons.shield_outlined),
171 onTap: () => Navigator.push(
172 context,
173 MaterialPageRoute(
174 builder: (ctx) => Scaffold(
175 appBar: AppBar(title: Text(ctx.tr('guidance'))),
176 body: SingleChildScrollView(
177 padding: const EdgeInsets.all(20),
178 child: SelectableText(
179 c.legal.guidance[Localizations.localeOf(
180 ctx,
181 ).languageCode] ??
182 c.legal.guidance['en']!,
183 ),
184 ),
185 ),
186 ),
187 ),
188 ),
189 ListTile(
190 title: Text(context.tr('componentLicenses')),
191 leading: const Icon(Icons.inventory_2_outlined),
192 onTap: () => showLicensePage(
193 context: context,
194 applicationName: 'SM Mobile',
195 applicationVersion: appVersion,
196 ),
197 ),
198 const SizedBox(height: 16),
199 FilledButton.icon(
200 onPressed: c.lock,
201 icon: const Icon(Icons.lock),
202 label: Text(context.tr('lock')),
203 ),
204 if (busy) const LinearProgressIndicator(),
205 ],
206 ),
207 );
208 }
SHA-2564337d9903f326c466ab95c4e7a61059433007d435bdfdfebf01d80dae375c29d

CH-J Proprietary Software License 1.14 · ซอร์สโค้ดนี้ให้ไว้ภายใต้ CH-J Proprietary Software License 1.14 การเปิดให้เข้าถึงไม่ได้เปลี่ยนแปลงเงื่อนไขของสัญญาอนุญาตหรือให้สิทธิ์เพิ่มเติม

SHA-256 ของไฟล์บีบอัด46e427a43e87af091004f36145590bda8fe90086dfb0f631afeb5029fb0b5655
ไฟล์