0b86138b55
Deploy Client / build-windows (push) Successful in 1m47s
Deploy Client / build-android (push) Has been cancelled
Deploy Client / build-macos (push) Has been cancelled
Deploy Client / build-ios (push) Has been cancelled
Deploy Client / release-deploy (push) Has been cancelled
按需求去掉居中弹窗,改成不打断的顶部 banner(对照 jiu 黄条): - 非强制更新 → home_shell 顶部 UpdateBanner「发现新版本 vX + 立即更新 + ×」; 「立即更新」App 内下载安装,「×」忽略此版本(banner 隐藏,更新版本会重现) - 强制更新(force_update)→ 仍走不可关闭弹窗 showUpdateDialog - 忽略状态改 dismissedUpdateVersionProvider(按版本号,响应式);去掉 notifier 的 _dismissed - 设置页「检查更新」有更新时:清忽略版本→banner 显示 + toast,不再弹窗 - 新增 6 语「立即更新」文案。flutter analyze 仅 2 个既有 withOpacity info Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
58 lines
2.0 KiB
Dart
58 lines
2.0 KiB
Dart
// home_shell.dart — 主框架分发器(按 formFactor 选三端外壳)
|
||
//
|
||
// desktop → 侧栏 6 项 + 顶栏(对照 ui_kits/desktop)
|
||
// tablet → 暂用 MobileShell(TODO: TabletShell 侧栏双栏,对照 ui_kits/tablet)
|
||
// mobile → 底 Tab + 滑动(对照 ui_kits/mobile)
|
||
import 'package:flutter/material.dart';
|
||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||
|
||
import '../core/responsive/form_factor.dart';
|
||
import '../pangolin_theme.dart';
|
||
import '../state/app_providers.dart';
|
||
import '../state/update_provider.dart';
|
||
import '../widgets/update_dialog.dart';
|
||
import 'desktop_shell.dart';
|
||
import 'mobile_shell.dart';
|
||
import 'tablet_shell.dart';
|
||
|
||
class HomeShell extends ConsumerWidget {
|
||
const HomeShell({super.key});
|
||
|
||
@override
|
||
Widget build(BuildContext context, WidgetRef ref) {
|
||
final c = context.pangolin;
|
||
|
||
// 启动自动检查更新:watch 惰性拉起 updateProvider(延迟 3s→查→1h 轮询)。
|
||
// 非强制更新 → 顶部 banner(见下,不打断);强制更新 → 不可关闭弹窗。
|
||
ref.listen<AsyncValue<AppUpdateInfo?>>(updateProvider, (prev, next) {
|
||
final info = next.valueOrNull;
|
||
if (info != null && info.hasUpdate && info.forceUpdate) {
|
||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||
if (context.mounted) {
|
||
showUpdateDialog(context, ref.read(appTextProvider), info);
|
||
}
|
||
});
|
||
}
|
||
});
|
||
|
||
final info = ref.watch(updateProvider).valueOrNull;
|
||
final dismissedVer = ref.watch(dismissedUpdateVersionProvider);
|
||
final showBanner = info != null &&
|
||
info.hasUpdate &&
|
||
!info.forceUpdate &&
|
||
dismissedVer != info.latestVersion;
|
||
|
||
final Widget body = switch (context.formFactor) {
|
||
FormFactor.desktop => const DesktopShell(),
|
||
FormFactor.tablet => const TabletShell(),
|
||
FormFactor.mobile => const MobileShell(),
|
||
};
|
||
return Scaffold(
|
||
backgroundColor: c.bg,
|
||
body: showBanner
|
||
? Column(children: [UpdateBanner(info: info), Expanded(child: body)])
|
||
: body,
|
||
);
|
||
}
|
||
}
|