Nailathalang source
I-download ang source ZIP
CH-J SM Mobile
I-browse ang mga direktoryo at file ng isang partikular na release ng application.
CH-J / SM Mobile
175 file
sm-mobile-20261016T185235Z-8e93ecc1b59a
Idinagdag: · Binuo:
1
import 'package:flutter/material.dart';2
import '../core/app_controller.dart';3
import '../core/build_info.dart';4
import '../l10n/strings.dart';5
import 'adaptive.dart';6
import 'change_password.dart';7
import 'common.dart';8
import 'gates.dart';9
import 'profile_io.dart';11
class SettingsPage extends StatefulWidget {12
final AppController controller;13
const SettingsPage(this.controller, {super.key});14
@override15
State<SettingsPage> createState() => _SettingsPageState();16
}18
class _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
@override32
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.values53
.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: busy81
? null82
: () 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: busy96
? null97
: (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: idleChoices116
.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: busy141
? null142
: () => 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
}209
}SHA-256
4337d9903f326c466ab95c4e7a61059433007d435bdfdfebf01d80dae375c29dCH-J Proprietary Software License 1.14 · Ibinibigay ang source sa ilalim ng CH-J Proprietary Software License 1.14. Hindi binabago ng pagiging available nito ang mga tuntunin ng lisensya at hindi ito nagbibigay ng karagdagang karapatan.
SHA-256 ng archive
46e427a43e87af091004f36145590bda8fe90086dfb0f631afeb5029fb0b5655