What changed, and why it matters
This commit changes where the app goes when a user taps the back button on two ShopInBit screens. Previously, the back button would simply go to the previous screen; now it jumps back to a specific starting screen (the services list or the tickets list). It also wraps the screens in a Flutter widget that prevents the system's own back gesture from doing anything other than the custom navigation. There is no security issue here—this is purely a user-experience navigation fix.
No security action needed. Treat as a routine UI/UX navigation fix.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch updates two Dart files in the Stack Wallet Flutter app. It replaces generic Navigator.pop() calls with Navigator.popUntil() that stops at a named route (ServicesView.routeName or ShopInBitTicketsView.routeName) or the first route. It also wraps each Scaffold in a PopScope with canPop: false and an onPopInvokedWithResult handler that performs the same popUntil logic. No cryptographic, network, input-validation, or permission-related code is touched.
Changed components
lib/pages/shopinbit/shopinbit_order_created.dartlib/pages/shopinbit/shopinbit_payment_view.dartInspect captured patch +89 / −45
diff --git a/lib/pages/shopinbit/shopinbit_order_created.dart b/lib/pages/shopinbit/shopinbit_order_created.dart
index 92576c3..5f844f6 100644
--- a/lib/pages/shopinbit/shopinbit_order_created.dart
+++ b/lib/pages/shopinbit/shopinbit_order_created.dart
@@ -13,6 +13,7 @@ import '../../widgets/desktop/desktop_dialog_close_button.dart';
import '../../widgets/desktop/primary_button.dart';
import '../../widgets/desktop/secondary_button.dart';
import '../../widgets/rounded_white_container.dart';
+import '../more_view/services_view.dart';
import 'shopinbit_ticket_detail.dart';
class ShopInBitOrderCreated extends StatelessWidget {
@@ -22,6 +23,18 @@ class ShopInBitOrderCreated extends StatelessWidget {
final ShopInBitOrderModel model;
+ static void _popToServices(BuildContext context) {
+ Navigator.of(context).popUntil((route) {
+ if (route.settings.name == ServicesView.routeName) {
+ return true;
+ }
+ if (route.isFirst) {
+ return true;
+ }
+ return false;
+ });
+ }
+
@override
Widget build(BuildContext context) {
final isDesktop = Util.isDesktop;
@@ -118,7 +131,7 @@ class ShopInBitOrderCreated extends StatelessWidget {
if (Util.isDesktop) {
Navigator.of(context, rootNavigator: true).pop();
} else {
- Navigator.of(context).popUntil((route) => route.isFirst);
+ _popToServices(context);
}
},
),
@@ -159,29 +172,38 @@ class ShopInBitOrderCreated extends StatelessWidget {
}
return Background(
- child: Scaffold(
- backgroundColor: Theme.of(context).extension<StackColors>()!.background,
- appBar: AppBar(
- leading: AppBarBackButton(
- onPressed: () => Navigator.of(context).pop(),
+ child: PopScope(
+ canPop: false,
+ onPopInvokedWithResult: (bool didPop, dynamic result) {
+ if (!didPop) {
+ _popToServices(context);
+ }
+ },
+ child: Scaffold(
+ backgroundColor:
+ Theme.of(context).extension<StackColors>()!.background,
+ appBar: AppBar(
+ leading: AppBarBackButton(
+ onPressed: () => _popToServices(context),
+ ),
+ title: Text("ShopInBit", style: STextStyles.navBarTitle(context)),
),
- title: Text("ShopInBit", style: STextStyles.navBarTitle(context)),
- ),
- body: SafeArea(
- child: LayoutBuilder(
- builder: (context, constraints) {
- return Padding(
- padding: const EdgeInsets.all(16),
- child: SingleChildScrollView(
- child: ConstrainedBox(
- constraints: BoxConstraints(
- minHeight: constraints.maxHeight - 32,
+ body: SafeArea(
+ child: LayoutBuilder(
+ builder: (context, constraints) {
+ return Padding(
+ padding: const EdgeInsets.all(16),
+ child: SingleChildScrollView(
+ child: ConstrainedBox(
+ constraints: BoxConstraints(
+ minHeight: constraints.maxHeight - 32,
+ ),
+ child: IntrinsicHeight(child: content),
),
- child: IntrinsicHeight(child: content),
),
- ),
- );
- },
+ );
+ },
+ ),
),
),
),
diff --git a/lib/pages/shopinbit/shopinbit_payment_view.dart b/lib/pages/shopinbit/shopinbit_payment_view.dart
index 4c91dbf..fc0f0e8 100644
--- a/lib/pages/shopinbit/shopinbit_payment_view.dart
+++ b/lib/pages/shopinbit/shopinbit_payment_view.dart
@@ -32,6 +32,7 @@ import '../../widgets/desktop/secondary_button.dart';
import '../../widgets/qr.dart';
import '../../widgets/rounded_white_container.dart';
import 'shopinbit_send_from_view.dart';
+import 'shopinbit_tickets_view.dart';
class ShopInBitPaymentView extends ConsumerStatefulWidget {
const ShopInBitPaymentView({super.key, required this.model});
@@ -328,6 +329,18 @@ class _ShopInBitPaymentViewState extends ConsumerState<ShopInBitPaymentView> {
}
}
+ void _popToTickets() {
+ Navigator.of(context).popUntil((route) {
+ if (route.settings.name == ShopInBitTicketsView.routeName) {
+ return true;
+ }
+ if (route.isFirst) {
+ return true;
+ }
+ return false;
+ });
+ }
+
void _navigateToSendFrom({
required CryptoCurrency coin,
required Amount? amount,
@@ -763,34 +776,43 @@ class _ShopInBitPaymentViewState extends ConsumerState<ShopInBitPaymentView> {
}
return Background(
- child: Scaffold(
- backgroundColor: Theme.of(context).extension<StackColors>()!.background,
- appBar: AppBar(
- leading: AppBarBackButton(
- onPressed: () => Navigator.of(context).pop(),
+ child: PopScope(
+ canPop: false,
+ onPopInvokedWithResult: (bool didPop, dynamic result) {
+ if (!didPop) {
+ _popToTickets();
+ }
+ },
+ child: Scaffold(
+ backgroundColor:
+ Theme.of(context).extension<StackColors>()!.background,
+ appBar: AppBar(
+ leading: AppBarBackButton(
+ onPressed: _popToTickets,
+ ),
+ title: Text("ShopInBit", style: STextStyles.navBarTitle(context)),
),
- title: Text("ShopInBit", style: STextStyles.navBarTitle(context)),
- ),
- body: SafeArea(
- child: LayoutBuilder(
- builder: (context, constraints) {
- return Stack(
- children: [
- Padding(
- padding: const EdgeInsets.all(16),
- child: SingleChildScrollView(
- child: ConstrainedBox(
- constraints: BoxConstraints(
- minHeight: constraints.maxHeight - 32,
+ body: SafeArea(
+ child: LayoutBuilder(
+ builder: (context, constraints) {
+ return Stack(
+ children: [
+ Padding(
+ padding: const EdgeInsets.all(16),
+ child: SingleChildScrollView(
+ child: ConstrainedBox(
+ constraints: BoxConstraints(
+ minHeight: constraints.maxHeight - 32,
+ ),
+ child: IntrinsicHeight(child: content),
),
- child: IntrinsicHeight(child: content),
),
),
- ),
- if (_loading) loadingOverlay,
- ],
- );
- },
+ if (_loading) loadingOverlay,
+ ],
+ );
+ },
+ ),
),
),
),
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.