feat: enforce hierarchical back navigation and home-only exit
This commit is contained in:
@@ -26,15 +26,19 @@ import '../../features/settings/ui/screens/features_screen.dart';
|
||||
import '../../features/settings/ui/screens/memory_screen.dart';
|
||||
import '../../features/settings/ui/screens/edit_profile_screen.dart';
|
||||
|
||||
final _protectedRoutes = [
|
||||
final _homeSecondLevelRoutes = [
|
||||
AppRoutes.homeMain,
|
||||
AppRoutes.contactsList,
|
||||
AppRoutes.contactsAdd,
|
||||
AppRoutes.calendarDayWeek,
|
||||
AppRoutes.calendarMonth,
|
||||
'/calendar/events',
|
||||
AppRoutes.todoList,
|
||||
AppRoutes.settingsMain,
|
||||
];
|
||||
|
||||
final _protectedRoutes = [
|
||||
..._homeSecondLevelRoutes,
|
||||
AppRoutes.contactsList,
|
||||
AppRoutes.contactsAdd,
|
||||
'/calendar/events',
|
||||
AppRoutes.settingsFeatures,
|
||||
AppRoutes.settingsMemory,
|
||||
AppRoutes.settingsEditProfile,
|
||||
|
||||
@@ -119,7 +119,7 @@ class _CalendarDayWeekScreenState extends State<CalendarDayWeekScreen>
|
||||
canPop: false,
|
||||
onPopInvokedWithResult: (didPop, result) {
|
||||
if (!didPop) {
|
||||
returnToHomePreserveState(context);
|
||||
returnToHomePreserveState(context, forceGoHome: true);
|
||||
}
|
||||
},
|
||||
child: SafeArea(
|
||||
@@ -702,7 +702,7 @@ class _CalendarDayWeekScreenState extends State<CalendarDayWeekScreen>
|
||||
_calendarManager.setViewType(CalendarViewType.day);
|
||||
context.push(AppRoutes.calendarMonth);
|
||||
},
|
||||
onHomeTap: () => returnToHomePreserveState(context),
|
||||
onHomeTap: () => returnToHomePreserveState(context, forceGoHome: true),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ class _CalendarMonthScreenState extends State<CalendarMonthScreen>
|
||||
canPop: false,
|
||||
onPopInvokedWithResult: (didPop, result) {
|
||||
if (!didPop) {
|
||||
returnToHomePreserveState(context);
|
||||
returnToHomePreserveState(context, forceGoHome: true);
|
||||
}
|
||||
},
|
||||
child: SafeArea(
|
||||
@@ -522,7 +522,7 @@ class _CalendarMonthScreenState extends State<CalendarMonthScreen>
|
||||
context.push(AppRoutes.todoList);
|
||||
},
|
||||
onCalendarTap: () {},
|
||||
onHomeTap: () => returnToHomePreserveState(context),
|
||||
onHomeTap: () => returnToHomePreserveState(context, forceGoHome: true),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,11 @@ enum HomeReturnAction { pop, goHome }
|
||||
HomeReturnAction resolveHomeReturnAction({
|
||||
required bool canPop,
|
||||
required bool isAuthEntry,
|
||||
bool forceGoHome = false,
|
||||
}) {
|
||||
if (forceGoHome) {
|
||||
return HomeReturnAction.goHome;
|
||||
}
|
||||
if (isAuthEntry) {
|
||||
return HomeReturnAction.goHome;
|
||||
}
|
||||
@@ -21,10 +25,12 @@ HomeReturnAction resolveHomeReturnAction({
|
||||
void returnToHomePreserveState(
|
||||
BuildContext context, {
|
||||
bool isAuthEntry = false,
|
||||
bool forceGoHome = false,
|
||||
}) {
|
||||
final action = resolveHomeReturnAction(
|
||||
canPop: context.canPop(),
|
||||
isAuthEntry: isAuthEntry,
|
||||
forceGoHome: forceGoHome,
|
||||
);
|
||||
switch (action) {
|
||||
case HomeReturnAction.pop:
|
||||
|
||||
@@ -20,6 +20,7 @@ import 'package:social_app/features/settings/data/settings_api.dart';
|
||||
import 'package:social_app/features/settings/data/services/settings_user_cache.dart';
|
||||
import 'package:social_app/features/users/data/models/user_response.dart';
|
||||
import 'package:social_app/features/users/data/users_api.dart';
|
||||
import 'package:social_app/features/home/ui/navigation/home_return_policy.dart';
|
||||
import '../widgets/settings_page_scaffold.dart';
|
||||
|
||||
const settingsProfileEditButtonKey = ValueKey('settings_profile_edit_button');
|
||||
@@ -90,7 +91,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
||||
Widget build(BuildContext context) {
|
||||
return SettingsPageScaffold(
|
||||
title: '设置',
|
||||
onBack: () => context.pop(),
|
||||
onBack: () => returnToHomePreserveState(context, forceGoHome: true),
|
||||
body: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
|
||||
@@ -298,7 +298,7 @@ class _TodoQuadrantsScreenState extends State<TodoQuadrantsScreen> {
|
||||
canPop: false,
|
||||
onPopInvokedWithResult: (didPop, result) {
|
||||
if (!didPop) {
|
||||
returnToHomePreserveState(context);
|
||||
returnToHomePreserveState(context, forceGoHome: true);
|
||||
}
|
||||
},
|
||||
child: SafeArea(
|
||||
@@ -563,7 +563,7 @@ class _TodoQuadrantsScreenState extends State<TodoQuadrantsScreen> {
|
||||
context.push('${AppRoutes.calendarDayWeek}?date=$dateStr');
|
||||
}
|
||||
},
|
||||
onHomeTap: () => returnToHomePreserveState(context),
|
||||
onHomeTap: () => returnToHomePreserveState(context, forceGoHome: true),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,15 @@ import 'package:social_app/features/home/ui/navigation/home_return_policy.dart';
|
||||
|
||||
void main() {
|
||||
group('resolveHomeReturnAction', () {
|
||||
test('second-level pages should return to home instead of exiting app', () {
|
||||
final action = resolveHomeReturnAction(
|
||||
canPop: false,
|
||||
isAuthEntry: false,
|
||||
forceGoHome: true,
|
||||
);
|
||||
expect(action, HomeReturnAction.goHome);
|
||||
});
|
||||
|
||||
test('business route with back stack prefers pop', () {
|
||||
final action = resolveHomeReturnAction(canPop: true, isAuthEntry: false);
|
||||
expect(action, HomeReturnAction.pop);
|
||||
|
||||
Reference in New Issue
Block a user