feat(client): 记住上次选择的节点 + 自动连接 toast(1.0.24)
- selectedNodeCodeProvider 改为持久化 StateNotifier(select() 落盘、启动恢复,默认智能 AUTO); 自动连接复用上次选择:智能就智能、具体就具体。 - 自动连接门控加等「选中节点已恢复」(controller.loaded),避免用到未恢复的默认值。 - 自动连接触发时弹 toast「正在自动连接到 X」(全局 ScaffoldMessenger key)。 - 测试:选中节点 select 落盘 + 重启恢复(具体/智能)。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -262,7 +262,7 @@ class ConnectionController extends StateNotifier<ConnectionState> {
|
||||
final smart = _ref.read(selectedNodeCodeProvider) == kSmartNodeCode;
|
||||
final altCode = smart ? _pickAlternativeCode(_ref.read(effectiveNodeProvider).code) : null;
|
||||
if (smart && altCode != null) {
|
||||
_ref.read(selectedNodeCodeProvider.notifier).state = altCode;
|
||||
_ref.read(selectedNodeCodeProvider.notifier).select(altCode);
|
||||
await _disconnect();
|
||||
await _connect();
|
||||
// 重连进行中给出「已自动切换」提示(connecting 态显示,连上后随 copyWith 清除)。
|
||||
|
||||
@@ -7,6 +7,7 @@ import 'dart:convert';
|
||||
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
import '../models/node.dart';
|
||||
import '../services/api_config.dart';
|
||||
@@ -96,8 +97,42 @@ final nodesProvider =
|
||||
AsyncNotifierProvider<NodesNotifier, List<Node>>(NodesNotifier.new);
|
||||
|
||||
// ── 当前选中的节点 code;'AUTO' 表示智能选择(默认)─────────────────
|
||||
//
|
||||
// 持久化:用户的选择(智能 / 具体节点)跨重启保存,启动时恢复,供自动连接复用上次选择。
|
||||
const _kSelectedNode = 'selected_node_code';
|
||||
|
||||
final selectedNodeCodeProvider = StateProvider<String>((ref) => kSmartNodeCode);
|
||||
class SelectedNodeController extends StateNotifier<String> {
|
||||
SelectedNodeController() : super(kSmartNodeCode) {
|
||||
_load();
|
||||
}
|
||||
|
||||
/// 是否已从持久化恢复完(自动连接要等它 true 再读,避免用到未恢复的默认值)。
|
||||
bool loaded = false;
|
||||
|
||||
Future<void> _load() async {
|
||||
try {
|
||||
final p = await SharedPreferences.getInstance();
|
||||
if (!mounted) return;
|
||||
final v = p.getString(_kSelectedNode);
|
||||
if (v != null && v.isNotEmpty) state = v;
|
||||
} catch (_) {
|
||||
// 测试/无平台:保留默认(智能)。
|
||||
}
|
||||
loaded = true;
|
||||
}
|
||||
|
||||
/// 选择节点(智能传 kSmartNodeCode)并持久化。
|
||||
Future<void> select(String code) async {
|
||||
state = code;
|
||||
try {
|
||||
final p = await SharedPreferences.getInstance();
|
||||
await p.setString(_kSelectedNode, code);
|
||||
} catch (_) {}
|
||||
}
|
||||
}
|
||||
|
||||
final selectedNodeCodeProvider =
|
||||
StateNotifierProvider<SelectedNodeController, String>((ref) => SelectedNodeController());
|
||||
|
||||
/// 是否处于智能选择。
|
||||
final isSmartSelectProvider = Provider<bool>(
|
||||
|
||||
Reference in New Issue
Block a user