fix(client): 自动连接回调改用强类型 ref.read + 日志落文件(1.0.21)

- 自动连接回调不再用 listenManual 的 next(裸订阅会退化成 dynamic → valueOrNull 扩展崩),
  改 ref.read(nodesProvider) 拿强类型 AsyncValue,彻底躲开 dynamic 扩展坑。
- logLine 除 stdout 外落桌面端固定文件(%LOCALAPPDATA%\Pangolin\pangolin.log,每次启动截断),
  GUI/管理员启动也能拿日志,免 Tee。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
wangjia
2026-06-29 19:01:48 +08:00
parent 7fdadace4e
commit ff2f2f3c07
4 changed files with 56 additions and 8 deletions
+5 -4
View File
@@ -129,13 +129,14 @@ class _RootFlowState extends ConsumerState<RootFlow> {
// 注意:不在此处早读 settingsProvider.autoConnect —— 其 _load 是异步(SharedPreferences),
// 启动这一刻多半还没加载完,会读到默认 false 而永久跳过。改到「节点就绪」回调里再判:
// 节点要走网络拉取,远慢于本地设置读取,那时 autoConnect 必已加载到位。
// 必须标全泛型:裸 ProviderSubscription(=<dynamic>)会让 listenManual 推断成 dynamic,
// next 变 dynamic → valueOrNull(扩展 getter)在 dynamic 上不解析 → 运行期 NoSuchMethod。
// 不用回调的 next(裸 ProviderSubscription 会让它退化成 dynamic,valueOrNull 这种
// 扩展 getter 在 dynamic 上不解析 → 运行期 NoSuchMethod)。直接 ref.read 拿强类型值
late final ProviderSubscription<AsyncValue<List<Node>>> sub;
sub = ref.listenManual(nodesProvider, (prev, next) {
final nodes = next.valueOrNull ?? const <Node>[];
final av = ref.read(nodesProvider);
final nodes = av.valueOrNull ?? const <Node>[];
final ready = nodes.any((n) => n.uuid.isNotEmpty);
logLine('AutoConnect', 'nodes update: total=${nodes.length} ready=$ready loading=${next.isLoading} err=${next.hasError}');
logLine('AutoConnect', 'nodes update: total=${nodes.length} ready=$ready loading=${av.isLoading} err=${av.hasError}');
if (!ready) return;
sub.close();
final ac = ref.read(settingsProvider).autoConnect;