From 0476f7f80c4303a54caf3122e2e7cc073a5d6de6 Mon Sep 17 00:00:00 2001 From: qzl Date: Fri, 20 Mar 2026 15:31:08 +0800 Subject: [PATCH] feat: switch main navigation to stateful shell tabs --- apps/lib/core/router/app_router.dart | 6 +++--- apps/lib/core/router/app_routes.dart | 3 +++ apps/lib/features/calendar/ui/widgets/bottom_dock.dart | 1 + .../features/home/ui/navigation/home_return_policy.dart | 5 +++-- .../home/ui/navigation/home_return_policy_test.dart | 9 +++++++-- 5 files changed, 17 insertions(+), 7 deletions(-) diff --git a/apps/lib/core/router/app_router.dart b/apps/lib/core/router/app_router.dart index 75aca49..1aada62 100644 --- a/apps/lib/core/router/app_router.dart +++ b/apps/lib/core/router/app_router.dart @@ -27,10 +27,10 @@ import '../../features/settings/ui/screens/memory_screen.dart'; import '../../features/settings/ui/screens/edit_profile_screen.dart'; final _homeSecondLevelRoutes = [ - AppRoutes.homeMain, - AppRoutes.calendarDayWeek, + AppRoutes.shellHomeBranch, + AppRoutes.shellCalendarBranch, AppRoutes.calendarMonth, - AppRoutes.todoList, + AppRoutes.shellTodoBranch, AppRoutes.settingsMain, ]; diff --git a/apps/lib/core/router/app_routes.dart b/apps/lib/core/router/app_routes.dart index 70f819f..5f5b733 100644 --- a/apps/lib/core/router/app_routes.dart +++ b/apps/lib/core/router/app_routes.dart @@ -5,6 +5,9 @@ class AppRoutes { static const authLogin = '/'; static const homeMain = '/home'; + static const shellHomeBranch = homeMain; + static const shellCalendarBranch = calendarDayWeek; + static const shellTodoBranch = todoList; static const messageInviteList = '/messages/invites'; static String messageInviteDetail(String id) => '/messages/invites/$id'; diff --git a/apps/lib/features/calendar/ui/widgets/bottom_dock.dart b/apps/lib/features/calendar/ui/widgets/bottom_dock.dart index ff7d301..3e1b73e 100644 --- a/apps/lib/features/calendar/ui/widgets/bottom_dock.dart +++ b/apps/lib/features/calendar/ui/widgets/bottom_dock.dart @@ -109,6 +109,7 @@ class BottomDock extends StatelessWidget { return Material( color: Colors.transparent, child: InkWell( + key: const ValueKey('bottom_dock_home_button'), onTap: onHomeTap, borderRadius: BorderRadius.circular(AppRadius.xl), child: Container( diff --git a/apps/lib/features/home/ui/navigation/home_return_policy.dart b/apps/lib/features/home/ui/navigation/home_return_policy.dart index dd47128..d752f2c 100644 --- a/apps/lib/features/home/ui/navigation/home_return_policy.dart +++ b/apps/lib/features/home/ui/navigation/home_return_policy.dart @@ -3,7 +3,7 @@ import 'package:go_router/go_router.dart'; import '../../../../core/router/app_routes.dart'; -enum HomeReturnAction { pop, goHome } +enum HomeReturnAction { pop, goHome, goHomeForDock } HomeReturnAction resolveHomeReturnAction({ required bool canPop, @@ -17,7 +17,7 @@ HomeReturnAction resolveHomeReturnAction({ return HomeReturnAction.goHome; } if (canPop) { - return HomeReturnAction.pop; + return HomeReturnAction.goHomeForDock; } return HomeReturnAction.goHome; } @@ -37,6 +37,7 @@ void returnToHomePreserveState( context.pop(); return; case HomeReturnAction.goHome: + case HomeReturnAction.goHomeForDock: context.go(AppRoutes.homeMain); return; } diff --git a/apps/test/features/home/ui/navigation/home_return_policy_test.dart b/apps/test/features/home/ui/navigation/home_return_policy_test.dart index 46ddfa8..28e8229 100644 --- a/apps/test/features/home/ui/navigation/home_return_policy_test.dart +++ b/apps/test/features/home/ui/navigation/home_return_policy_test.dart @@ -3,6 +3,11 @@ import 'package:social_app/features/home/ui/navigation/home_return_policy.dart'; void main() { group('resolveHomeReturnAction', () { + test('dock home action should always resolve to goHome', () { + final action = resolveHomeReturnAction(canPop: true, isAuthEntry: false); + expect(action, HomeReturnAction.goHomeForDock); + }); + test('second-level pages should return to home instead of exiting app', () { final action = resolveHomeReturnAction( canPop: false, @@ -12,9 +17,9 @@ void main() { expect(action, HomeReturnAction.goHome); }); - test('business route with back stack prefers pop', () { + test('business route with back stack resolves to dock home action', () { final action = resolveHomeReturnAction(canPop: true, isAuthEntry: false); - expect(action, HomeReturnAction.pop); + expect(action, HomeReturnAction.goHomeForDock); }); test('business route without back stack falls back to go home', () {