navi: honor Screen.canPop across back/swipe pop paths
canPop was documented as gating the back button / swipe but was ignored by ScreenBackHandler, XRouterBack.didPopRoute, and XRouter.canPop, so a stack entry with canPop=false was still poppable by gesture or system back. Make it authoritative in all three so a non-poppable pushed entry (e.g. an activation screen) can't be backed out from under the user.
This commit is contained in:
@@ -77,7 +77,8 @@ class XRouter extends BackButtonDispatcher
|
|||||||
late final _overlayEntry = OverlayEntry(builder: _buildContent);
|
late final _overlayEntry = OverlayEntry(builder: _buildContent);
|
||||||
|
|
||||||
bool get canPop {
|
bool get canPop {
|
||||||
if (stack.isNotEmpty) return true;
|
final top = stack.lastOrNull;
|
||||||
|
if (top != null) return top.canPop;
|
||||||
if (home is ScreenShell) {
|
if (home is ScreenShell) {
|
||||||
for (final screen in (home as ScreenShell).pages) {
|
for (final screen in (home as ScreenShell).pages) {
|
||||||
if (!screen.popped) return true;
|
if (!screen.popped) return true;
|
||||||
@@ -225,7 +226,7 @@ class XRouterBack extends RootBackButtonDispatcher {
|
|||||||
}
|
}
|
||||||
if (router.home.handleBack()) return true;
|
if (router.home.handleBack()) return true;
|
||||||
final page = router.stack.lastOrNull;
|
final page = router.stack.lastOrNull;
|
||||||
if (page != null) {
|
if (page != null && page.canPop) {
|
||||||
page.pop();
|
page.pop();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ class ScreenStackState extends State<ScreenStack> with TickerProviderStateMixin
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _updateCanPop() {
|
void _updateCanPop() {
|
||||||
final canPop = _entries.any((e) => !e.removing);
|
final canPop = _entries.any((e) => !e.removing && e.page.canPop);
|
||||||
if (canPop == _canPop) return;
|
if (canPop == _canPop) return;
|
||||||
_canPop = canPop;
|
_canPop = canPop;
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
@@ -258,7 +258,7 @@ class ScreenStackState extends State<ScreenStack> with TickerProviderStateMixin
|
|||||||
ScreenBackHandler(
|
ScreenBackHandler(
|
||||||
key: entry.key,
|
key: entry.key,
|
||||||
entry: entry,
|
entry: entry,
|
||||||
enabled: entry == top && _canPop,
|
enabled: entry == top && _canPop && entry.page.canPop,
|
||||||
onPop: () => entry.page.pop(),
|
onPop: () => entry.page.pop(),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
Reference in New Issue
Block a user