feat(client): P6 设置项落地真实行为(#6 6F,本地部分)
- settings_provider:三开关 shared_preferences 持久化 + 副作用落地: killSwitch→VpnBridge.setKillSwitch(on:);autostart→桌面原生登录项 (launch_at_startup);smartRoute 持久化为偏好(连接时作 split_cn,见 #5)。 - settings_page → ConsumerWidget,开关接 settingsProvider;协议标签 WireGuard→REALITY/Hysteria2;版本号取 pubspec(package_info_plus)。 - 新依赖:shared_preferences / package_info_plus / launch_at_startup。 flutter analyze 0 error;114 tests passed;settings golden 重生成。 待办:#5 智能分流的 server 端 geoip-cn 下发 + autostart 真机验证(需 release .app)。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -8,28 +8,22 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import '../l10n/app_text.dart';
|
||||
import '../pangolin_theme.dart';
|
||||
import '../state/app_providers.dart';
|
||||
import '../state/settings_provider.dart';
|
||||
import '../widgets/pangolin_icons.dart';
|
||||
|
||||
class SettingsPage extends ConsumerStatefulWidget {
|
||||
class SettingsPage extends ConsumerWidget {
|
||||
const SettingsPage({super.key});
|
||||
|
||||
@override
|
||||
ConsumerState<SettingsPage> createState() => _SettingsPageState();
|
||||
}
|
||||
|
||||
class _SettingsPageState extends ConsumerState<SettingsPage> {
|
||||
// 本地演示态(暂无后端绑定),默认开,对照 dapp.jsx DSettings。
|
||||
bool _autostart = true;
|
||||
bool _smartRoute = true;
|
||||
bool _killSwitch = true;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final c = context.pangolin;
|
||||
final t = ref.watch(appTextProvider);
|
||||
final lang = ref.watch(localeProvider);
|
||||
final mode = ref.watch(themeModeProvider);
|
||||
final isDark = mode == ThemeMode.dark;
|
||||
final s = ref.watch(settingsProvider);
|
||||
final settings = ref.read(settingsProvider.notifier);
|
||||
final version = ref.watch(appVersionProvider).valueOrNull ?? '…';
|
||||
|
||||
Widget sw(bool v, ValueChanged<bool> on) =>
|
||||
Switch(value: v, activeThumbColor: c.accent, onChanged: on);
|
||||
@@ -47,9 +41,9 @@ class _SettingsPageState extends ConsumerState<SettingsPage> {
|
||||
const SizedBox(height: 16),
|
||||
// 功能开关组
|
||||
_Card(children: [
|
||||
_Row(title: t.autostart, sub: t.autostartSub, right: sw(_autostart, (v) => setState(() => _autostart = v))),
|
||||
_Row(title: t.smartRoute, sub: t.smartRouteSub, right: sw(_smartRoute, (v) => setState(() => _smartRoute = v))),
|
||||
_Row(title: t.killSwitch, sub: t.killSwitchSub, last: true, right: sw(_killSwitch, (v) => setState(() => _killSwitch = v))),
|
||||
_Row(title: t.autostart, sub: t.autostartSub, right: sw(s.autostart, settings.setAutostart)),
|
||||
_Row(title: t.smartRoute, sub: t.smartRouteSub, right: sw(s.smartRoute, settings.setSmartRoute)),
|
||||
_Row(title: t.killSwitch, sub: t.killSwitchSub, last: true, right: sw(s.killSwitch, settings.setKillSwitch)),
|
||||
]),
|
||||
const SizedBox(height: 16),
|
||||
// 配置组
|
||||
@@ -60,9 +54,9 @@ class _SettingsPageState extends ConsumerState<SettingsPage> {
|
||||
sub: isDark ? t.stateOn : t.followLight,
|
||||
right: sw(isDark, (v) => ref.read(themeModeProvider.notifier).state = v ? ThemeMode.dark : ThemeMode.light),
|
||||
),
|
||||
_Row(title: t.protocol, right: Text('WireGuard', style: PangolinText.mono.copyWith(fontSize: 13, color: c.fg3))),
|
||||
_Row(title: t.protocol, right: Text('REALITY / Hysteria2', style: PangolinText.mono.copyWith(fontSize: 13, color: c.fg3))),
|
||||
_Row(title: t.checkUpdate, right: Icon(PangolinIcons.chevronRight, size: 18, color: c.fg3), onTap: () {}),
|
||||
_Row(title: 'Version', last: true, right: Text('v1.0.0', style: PangolinText.mono.copyWith(fontSize: 13, color: c.fg3))),
|
||||
_Row(title: 'Version', last: true, right: Text(version, style: PangolinText.mono.copyWith(fontSize: 13, color: c.fg3))),
|
||||
]),
|
||||
]),
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user