fix: back do android saia da sala em vez de fechar o viewer de imagem

O PopScope sozinho nao resolvia: GoRouterDelegate.popRoute() itera
_findCurrentNavigators(), que devolve [root, shell] e retorna
states.reversed, ou seja, o shell navigator e consultado primeiro. O
viewer e um showDialog no root navigator, entao o shell nunca ve o
PopEntry dele, popa a sala e retorna true antes de chegar no dialog.

BackButtonListener registra no BackButtonDispatcher raiz, que e
consultado antes do RouterDelegate.popRoute(), entao o viewer fecha
primeiro. Aplicado tambem no MxcImageViewer (avatar/sticker), que tinha
o mesmo defeito.
This commit is contained in:
2026-09-27 17:30:37 -03:00
parent 9f8877a741
commit d65be8a1ef
2 changed files with 66 additions and 48 deletions

View File

@@ -199,15 +199,25 @@ class ImageViewerController extends State<ImageViewer> {
}
@override
Widget build(BuildContext context) => PopScope<Object?>(
// Claim the system back button (and predictive back gesture) for the
// viewer. Without this, the request can reach go_router instead, which
// pops the chat room out of the shell and leaves the image on screen.
canPop: false,
onPopInvokedWithResult: (didPop, _) {
if (didPop) return;
Widget build(BuildContext context) => BackButtonListener(
// A [PopScope] alone is not enough here: go_router's `popRoute()` asks
// `GoRouterDelegate._findCurrentNavigators()`, which returns the shell
// navigator BEFORE the root one. The viewer is a dialog on the root
// navigator, so the shell navigator never sees its [PopEntry], pops the
// chat room instead and returns `true`, leaving the image on screen.
// A [BackButtonListener] is asked before the router gets the request at
// all, so the viewer gets to close itself first.
onBackButtonPressed: () async {
closeAction();
return true;
},
child: ImageViewerView(this),
child: PopScope<Object?>(
canPop: false,
onPopInvokedWithResult: (didPop, _) {
if (didPop) return;
closeAction();
},
child: ImageViewerView(this),
),
);
}