From 3c7fb2e090e50cbbc3d3bb3dfcb625fbf7d2f095 Mon Sep 17 00:00:00 2001 From: Nikolaus Heger Date: Mon, 7 Sep 2026 19:03:18 +0800 Subject: [PATCH 1/2] fix(accounts): return to Accounts screen from flows started outside it returnToAccountsScreen popped until it found the Accounts route. Flows started from Settings > Add account (create multisig, create account, import wallet) have no Accounts route in the stack, so popUntil emptied the Navigator and left a black screen. Pop to the Accounts route when it is in the stack, otherwise pop to the root and push a fresh Accounts screen. The highlight for the new account is passed to that fresh screen directly, since the open-accounts intent listener only fires on an already-mounted screen. --- .../screens/accounts/accounts_navigation.dart | 32 +++++++++++++++---- .../v2/screens/accounts/accounts_screen.dart | 15 +++------ .../open_accounts_management_button.dart | 2 +- 3 files changed, 31 insertions(+), 18 deletions(-) diff --git a/mobile-app/lib/v2/screens/accounts/accounts_navigation.dart b/mobile-app/lib/v2/screens/accounts/accounts_navigation.dart index 496f5e75..988086dd 100644 --- a/mobile-app/lib/v2/screens/accounts/accounts_navigation.dart +++ b/mobile-app/lib/v2/screens/accounts/accounts_navigation.dart @@ -1,19 +1,39 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:resonance_network_wallet/providers/route_intent_providers.dart'; +import 'package:resonance_network_wallet/v2/screens/accounts/accounts_screen.dart'; /// Route name of the Accounts screen, used to pop back to it. const accountsScreenRouteName = 'accounts_screen'; -/// Pops back to the already-open Accounts screen. Every in-app -/// add/import/disconnect flow originates from that screen, so it stays in the -/// navigation stack and we simply pop back to it instead of rebuilding Home. +Future openAccountsScreen(BuildContext context, {String? highlightAccountId}) { + return Navigator.of(context).push( + MaterialPageRoute( + settings: const RouteSettings(name: accountsScreenRouteName), + builder: (_) => AccountsScreen(highlightAccountId: highlightAccountId), + ), + ); +} + +/// Returns to the Accounts screen after an add/import/disconnect flow. +/// +/// Pops back to the already-open Accounts screen when the flow started there. +/// Flows started elsewhere (e.g. Settings → Add account) have no Accounts route +/// in the stack, so we pop to the root and push a fresh Accounts screen instead +/// of popping the whole stack. /// /// When [highlightAccountId] is given, that account is highlighted and scrolled -/// into view once the screen is revealed. +/// into view once the screen is shown. void returnToAccountsScreen(BuildContext context, WidgetRef ref, {String? highlightAccountId}) { - if (highlightAccountId != null) { + var foundAccountsRoute = false; + Navigator.of(context).popUntil((route) { + foundAccountsRoute = route.settings.name == accountsScreenRouteName; + return foundAccountsRoute || route.isFirst; + }); + + if (!foundAccountsRoute) { + openAccountsScreen(context, highlightAccountId: highlightAccountId); + } else if (highlightAccountId != null) { ref.read(openAccountsIntentProvider.notifier).state = OpenAccountsIntent(highlightAccountId: highlightAccountId); } - Navigator.of(context).popUntil((route) => route.settings.name == accountsScreenRouteName); } diff --git a/mobile-app/lib/v2/screens/accounts/accounts_screen.dart b/mobile-app/lib/v2/screens/accounts/accounts_screen.dart index 92c52c25..cc30aeca 100644 --- a/mobile-app/lib/v2/screens/accounts/accounts_screen.dart +++ b/mobile-app/lib/v2/screens/accounts/accounts_screen.dart @@ -16,22 +16,14 @@ import 'package:resonance_network_wallet/v2/components/account_list_row.dart'; import 'package:resonance_network_wallet/v2/components/multisig_tag.dart'; import 'package:resonance_network_wallet/v2/components/private_activity_notice.dart'; import 'package:resonance_network_wallet/v2/screens/accounts/account_menu_screen.dart'; -import 'package:resonance_network_wallet/v2/screens/accounts/accounts_navigation.dart'; import 'package:resonance_network_wallet/v2/screens/accounts/multisig_account_menu_screen.dart'; import 'package:resonance_network_wallet/v2/screens/accounts/wallet_name_screen.dart'; import 'package:resonance_network_wallet/v2/screens/settings/add_account_menu_screen.dart'; -Future openAccountsScreen(BuildContext context) { - return Navigator.of(context).push( - MaterialPageRoute( - settings: const RouteSettings(name: accountsScreenRouteName), - builder: (_) => const AccountsScreen(), - ), - ); -} - class AccountsScreen extends ConsumerStatefulWidget { - const AccountsScreen({super.key}); + const AccountsScreen({super.key, this.highlightAccountId}); + + final String? highlightAccountId; @override ConsumerState createState() => _AccountsScreenState(); @@ -46,6 +38,7 @@ class _AccountsScreenState extends ConsumerState { @override void initState() { super.initState(); + _highlightAccountId = widget.highlightAccountId; _ensureEncryptedAccounts(); } diff --git a/mobile-app/lib/v2/screens/accounts/open_accounts_management_button.dart b/mobile-app/lib/v2/screens/accounts/open_accounts_management_button.dart index 85bfd9c5..40a4a28f 100644 --- a/mobile-app/lib/v2/screens/accounts/open_accounts_management_button.dart +++ b/mobile-app/lib/v2/screens/accounts/open_accounts_management_button.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:quantus_sdk/quantus_sdk.dart'; -import 'package:resonance_network_wallet/v2/screens/accounts/accounts_screen.dart'; +import 'package:resonance_network_wallet/v2/screens/accounts/accounts_navigation.dart'; class OpenAccountsManagementButton extends StatelessWidget { const OpenAccountsManagementButton({super.key}); From 161754512d2ac7eeeab2e95240309f352c3a2c3a Mon Sep 17 00:00:00 2001 From: Nikolaus Heger Date: Mon, 7 Sep 2026 19:14:58 +0800 Subject: [PATCH 2/2] docs: analyzer hangs, kill after 20 seconds and use tests as the compile check --- AGENTS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AGENTS.md b/AGENTS.md index b264da83..596feb00 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -11,7 +11,7 @@ melos run format # dart format lib test --line-length=120 across all packages melos run analyze # flutter analyze . --fatal-infos across all packages ``` -Both commands normally finish in a few seconds, but `flutter analyze` occasionally hangs. **Never wait more than 20 seconds for either command — if it hasn't finished by then, kill the process.** A run that takes longer is hung, not slow; kill it and retry. +Both commands normally finish in a few seconds, but the analyzer gets stuck on this machine: the analysis server stops consuming CPU after a few seconds and never returns. **Never wait more than 20 seconds for either command — if it hasn't finished by then, kill the process.** A run that takes longer is hung, not slow. Do not retry in a loop; use a `flutter test` run that imports the changed files as the compile check instead. Do not run `dart analyze` or `flutter analyze` directly in individual packages; use the melos scripts above so every package is covered with the right flags.