Achado — Botão de voltar da ZzAppBar ignora onWillPop (bug pré-existente)
Severidade: Médio (feature de "alterações não salvas" não dispara no caminho mais comum de saída) Status: Documentado — fora do escopo de RF-06, tratamento a decidir separadamente
O que foi observado
ShowCaseDetailController.onWillPop() (show_case_detail_controller.dart:302-324) já implementa hoje o aviso de "alterações não salvas":
Future<bool> onWillPop() async {
if (enableEditButton) {
final answer = await BottomSheetAskLauncher.ask(
icon: PhosphorIcons.info,
title: 'A vitrine possui alterações não salvas',
description: 'Deseja salvar as alterações antes de sair?',
confirmButton: BottomSheetLauncherConfirmButton(title: 'Salvar'),
cancelButton: BottomSheetLauncherCancelButton(title: 'Não salvar'),
theme: BottomSheetLauncherTheme.info,
);
...
}
return true;
}
E é conectado via WillPopScope em ShowCaseDetailLayout (show_case_detail_layout.dart:89-92):
if (onWillPop != null) {
//TODO: refatorar e validar o uso
return WillPopScope(onWillPop: onWillPop, child: scaffold);
}
O próprio comentário //TODO: refatorar e validar o uso já sinalizava suspeita sobre esse mecanismo.
O problema
ZzAppBar (theme_widgets/app_bar/zz_app_bar.dart:25-39), usado pelo ShowCaseDetailLayout sem overrideOnTapBackButton, implementa o botão de voltar assim:
return IconButton(
onPressed: () => Navigator.of(context).pop(),
icon: const Icon(PhosphorIcons.caret_left, size: 24),
);
Confirmado na documentação oficial do Flutter (Navigator.maybePop): "This method is typically called for a user-initiated pop. For example on Android it's called by the binding for the system's back button." — ou seja, é Navigator.maybePop() (não Navigator.pop()) quem consulta route.willPop()/onWillPop. Uma chamada direta a Navigator.pop() não passa por essa checagem.
Impacto
O aviso "A vitrine possui alterações não salvas" registrado via WillPopScope/onWillPop:
- Funciona quando o vendedor usa o botão físico/gesto de voltar do Android (que aciona o mecanismo de pop do sistema, que consulta
willPop). - Não dispara quando o vendedor toca na seta de voltar visível na
ZzAppBar— o caminho mais comum e mais visível de sair da tela.
Além disso, WillPopScope está depreciado desde o Flutter 3.12 (substituído por PopScope) e a nota oficial diz: "The Android predictive back feature will not work with WillPopScope."
Opções possíveis (a decidir, fora desta sessão)
- Passar
overrideOnTapBackButtonpara oZzAppBardentro deShowCaseDetailLayout, chamando o mesmoonWillPopmanualmente antes de decidir se navega. - Migrar de
WillPopScopeparaPopScope(canPop/onPopInvokedWithResult), que tem semântica mais robusta e é o caminho recomendado pelo Flutter — mas exige revisão de todos os outros usos deWillPopScopeno app (43 ocorrências em várias telas) se quisermos consistência. - Deixar como está por ora e tratar como débito técnico à parte, já que RF-06 foi escrito para descrever o comportamento desejado, não a mecânica exata de interceptação de navegação.
Resolução
(não decidido nesta sessão — fica registrado como achado técnico para tratamento futuro, fora do escopo de RF-06)