Files

111 lines
3.5 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../providers/auth_provider.dart';
import '../../providers/note_refresh.dart';
import '../add/add_page.dart';
import '../assistant/assistant_page.dart';
import '../home/dashboard_page.dart';
import '../login/login_page.dart';
import '../mine/mine_page.dart';
/// 底部导航的四个 Tab 是四个「角色」,不是四个功能:
///
/// 首页 = 模块目录(卡片由 core/module/app_module.dart 生成)
/// 记录 = 全局录入入口
/// 助手 = AI(阶段 B 接入,现在是占位页)
/// 我的 = 账号、模块管理、设置
///
/// **具体模块不进 Tab** —— 记账、笔记都从首页卡片进。
/// 代价是打开 App 多一次点击才能看到账单,换来的是「以后加模块不用改这里」。
class MainShell extends ConsumerStatefulWidget {
const MainShell({super.key});
@override
ConsumerState<MainShell> createState() => _MainShellState();
}
class _MainShellState extends ConsumerState<MainShell>
with WidgetsBindingObserver {
int _index = 0; // 默认选中「首页」
@override
void initState() {
super.initState();
// 监听前后台切换:在电脑上改完笔记 → 切回 App 时数据要是新的。
// 这类「绕过 App 的写操作」没有任何通知可听,只能靠这个时机对账。
WidgetsBinding.instance.addObserver(this);
// 兜底:未登录直接回登录页
WidgetsBinding.instance.addPostFrameCallback((_) {
if (!ref.read(authProvider).isLoggedIn) {
_goLogin();
}
});
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
// resumed 才是真正的「回到前台」;inactive/paused 是离开过程中的中间态,
// 那些时候对账没意义(用户正在离开),还会白白打请求。
if (state == AppLifecycleState.resumed) {
refreshNoteDataOnResume(ref);
}
}
void _goLogin() {
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(builder: (_) => const LoginPage()),
(route) => false,
);
}
@override
Widget build(BuildContext context) {
// IndexedStack 保证四个页面常驻:写操作后各页的数据失效能立即重取,
// 用户切回时看到的就是最新数据。
const pages = [
DashboardPage(),
AddPage(),
AssistantPage(),
MinePage(),
];
return Scaffold(
body: IndexedStack(index: _index, children: pages),
bottomNavigationBar: NavigationBar(
selectedIndex: _index,
onDestinationSelected: (i) => setState(() => _index = i),
backgroundColor: Colors.white,
indicatorColor: const Color(0x33C8956E),
destinations: const [
NavigationDestination(
icon: Icon(Icons.home_outlined),
selectedIcon: Icon(Icons.home),
label: '首页',
),
NavigationDestination(
icon: Icon(Icons.add_circle_outline),
selectedIcon: Icon(Icons.add_circle),
label: '记录',
),
NavigationDestination(
icon: Icon(Icons.auto_awesome_outlined),
selectedIcon: Icon(Icons.auto_awesome),
label: '助手',
),
NavigationDestination(
icon: Icon(Icons.person_outline),
selectedIcon: Icon(Icons.person),
label: '我的',
),
],
),
);
}
}