Skip to content

Login logout to home#3262

Merged
ca333 merged 2 commits intodevfrom
login-logout-to-home
Oct 27, 2025
Merged

Login logout to home#3262
ca333 merged 2 commits intodevfrom
login-logout-to-home

Conversation

@smk762
Copy link
Copy Markdown
Collaborator

@smk762 smk762 commented Oct 27, 2025

Closes #3088

Though issue relates only to mobile, fix has been applied globally for consistency and UX.

To test:

  • Go to settings page (or any page except the Wallet page)
  • Create a wallet
  • confirm after login, app navigates to Wallet page
  • Go to settings page (or any page except the Wallet page)
  • confirm after logout, app navigates to Wallet page
  • Go to settings page (or any page except the Wallet page)
  • Log in to an existing wallet
  • confirm after login, app navigates to Wallet page
  • Go to settings page (or any page except the Wallet page)
  • confirm after logout, app navigates to Wallet page
  • Go to settings page (or any page except the Wallet page)
  • Log in to a hardware wallet
  • confirm after login, app navigates to Wallet page
  • Go to settings page (or any page except the Wallet page)
  • confirm after logout, app navigates to Wallet page

Summary by CodeRabbit

Release Notes

  • New Features
    • File descriptor monitoring system to track and analyze system resource usage with real-time statistics
    • Start/stop monitoring with customizable intervals (default 60 seconds)
    • Query current file descriptor counts, limits, and usage percentages
    • Automatic detailed logging when thresholds are approached or on demand

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Oct 27, 2025

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

A file descriptor (FD) monitoring system is added across iOS and Flutter. The iOS FdMonitor class periodically samples and logs FD metrics; a Flutter service wraps the native MethodChannel for cross-platform access. Additionally, login and logout flows now route users to the Wallet menu.

Changes

Cohort / File(s) Summary
iOS FD Monitor Implementation
ios/Runner/AppDelegate.swift, ios/Runner/FdMonitor.swift
AppDelegate adds method channel setup and handler for FD monitoring commands (start, stop, getCurrentCount, logDetailedStatus). New FdMonitor singleton maintains a DispatchSource timer on a dedicated queue, samples FD state at configurable intervals, retrieves metrics via getdtablesize/getrlimit/fcntl, and logs detailed per-FD type breakdowns when thresholds are exceeded.
Flutter FD Monitor Service
lib/services/fd_monitor_service.dart
New singleton service wraps native FD monitor via MethodChannel 'com.komodo.wallet/fd_monitor'. Provides start/stop lifecycle, getCurrentCount returning FdMonitorStats (openCount, tableSize, softLimit, hardLimit, percentUsed, timestamp), logDetailedStatus, and conditional startIfDebugMode. Includes error handling and convenience getters for status evaluation.
Login/Logout Routing Logic
lib/views/main_layout/main_layout.dart
Modified to route to Wallet menu (MainMenuValue.wallet) on login and logout events.

Sequence Diagram

sequenceDiagram
    participant Flutter as Flutter App
    participant Channel as MethodChannel
    participant AppDelegate as AppDelegate
    participant FdMonitor as FdMonitor
    
    Flutter->>Channel: start(intervalSeconds: 60)
    Channel->>AppDelegate: handleFdMonitorMethodCall (start)
    AppDelegate->>FdMonitor: start(intervalSeconds: 60)
    Note over FdMonitor: Creates DispatchSource timer<br/>Starts periodic sampling
    FdMonitor-->>AppDelegate: success
    AppDelegate-->>Channel: result
    Channel-->>Flutter: {status: "started"}
    
    Note over FdMonitor: Timer fires every 60s
    FdMonitor->>FdMonitor: getFileDescriptorInfo()
    Note over FdMonitor: Calls getdtablesize()<br/>getrlimit(), fcntl() per FD
    FdMonitor->>FdMonitor: logFileDescriptorStatus()
    
    Flutter->>Channel: getCurrentCount()
    Channel->>AppDelegate: handleFdMonitorMethodCall (getCurrentCount)
    AppDelegate->>FdMonitor: getCurrentCount()
    FdMonitor-->>AppDelegate: FdInfo (openCount, tableSize, softLimit, ...)
    AppDelegate-->>Channel: result
    Channel-->>Flutter: FdMonitorStats
    
    Flutter->>Channel: stop()
    Channel->>AppDelegate: handleFdMonitorMethodCall (stop)
    AppDelegate->>FdMonitor: stop()
    Note over FdMonitor: Cancels DispatchSourceTimer
    FdMonitor-->>AppDelegate: success
    AppDelegate-->>Channel: result
    Channel-->>Flutter: {status: "stopped"}
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • ios/Runner/FdMonitor.swift requires careful review of system-level APIs (getdtablesize, getrlimit, fcntl, fstat) and concurrent access patterns with DispatchQueue; verify timer lifecycle, thread safety, and correctness of FD counting logic
  • ios/Runner/AppDelegate.swift verify proper method channel setup and routing of all four commands (start, stop, getCurrentCount, logDetailedStatus)
  • lib/services/fd_monitor_service.dart verify error handling paths, null safety in FdMonitorStats construction, and consistency with native contract

Poem

🐰 File descriptors dance in queues so neat,
While FdMonitor counts them on rhythm's beat!
From iOS to Flutter, the data flows free,
And users return home where the Wallet menu should be—
A cozy route after logout's farewell! 🏠

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Out of Scope Changes Check ⚠️ Warning The PR includes substantial file descriptor monitoring functionality not mentioned in the linked issue #3088 or PR objectives: a new FdMonitor singleton class in ios/Runner/FdMonitor.swift (high code review effort), integration into ios/Runner/AppDelegate.swift, and a new Flutter service lib/services/fd_monitor_service.dart with platform channel integration. These changes implement periodic FD logging and analysis on iOS with complete Flutter bindings, represent significant new functionality unrelated to the stated goal of improving logout UX, and appear to be outside the scope of the linked issue. Remove the out-of-scope FD monitoring changes from this PR or create a separate PR for this feature. If the FD monitoring is intentionally included as a dependency or related feature, update the PR description, objectives, and link an additional issue to document this requirement.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The PR title "Login logout to home" is directly related to the navigation changes implemented in main_layout.dart, where the code now routes users to the wallet page after login and logout. This title clearly and specifically describes a real and significant part of the changeset. However, the PR also includes substantial file descriptor (FD) monitoring implementation across ios/Runner/FdMonitor.swift, ios/Runner/AppDelegate.swift, and lib/services/fd_monitor_service.dart, which are not mentioned in the title. According to the evaluation criteria, a title that refers to a real aspect of the change qualifies as at minimum partially related to the changeset.
Linked Issues Check ✅ Passed The linked issue #3088 ("Improve mobile logout UX") requires navigating users to the wallet home page after logout and improving the post-logout experience. The PR directly addresses this requirement through changes to lib/views/main_layout/main_layout.dart, which implements routing to MainMenuValue.wallet after logout (AuthorizeMode.noLogin condition) and after login (AuthorizeMode.logIn condition). The implementation applies this change globally for consistency, aligning with the stated objective to improve overall UX. All primary coding requirements from the linked issue are satisfied.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Oct 27, 2025

Visit the preview URL for this PR (updated for commit 5fd4b88):

https://walletrc--pull-3262-merge-bv4z56p0.web.app

(expires Mon, 03 Nov 2025 09:17:29 GMT)

🔥 via Firebase Hosting GitHub Action 🌎

Sign: f66a4ff03faa546f12f0ae5a841bd9eff2714dcc

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (9)
lib/views/main_layout/main_layout.dart (1)

81-81: Consider extracting the duplicated navigation logic.

The assignment routingState.selectedMenu = MainMenuValue.wallet appears in both the login and logout flows. While the duplication is minimal and each occurrence is contextually clear, extracting this into a helper method (e.g., _navigateToWallet()) could improve maintainability if this navigation logic needs to evolve.

Example refactor:

void _navigateToWallet() {
  routingState.selectedMenu = MainMenuValue.wallet;
}

Then use it in both places:

  if (state.mode == AuthorizeMode.logIn) {
    QuickLoginSwitch.trackUserLoggedIn();
    // Always route to Wallet on login
-   routingState.selectedMenu = MainMenuValue.wallet;
+   _navigateToWallet();
  }
  if (state.mode == AuthorizeMode.noLogin &&
      QuickLoginSwitch.hasBeenLoggedInThisSession) {
    routingState.resetOnLogOut();
    QuickLoginSwitch.resetOnLogout();
    // Always route to Wallet on logout
-   routingState.selectedMenu = MainMenuValue.wallet;
+   _navigateToWallet();
  }

Also applies to: 92-92

ios/Runner/AppDelegate.swift (2)

10-10: Gate debug-only launch log

The “🔴 didFinishLaunching…” log is noisy in release. Wrap in DEBUG or remove.

-    NSLog("🔴 AppDelegate: didFinishLaunchingWithOptions REACHED")
+    #if DEBUG
+    NSLog("AppDelegate: didFinishLaunchingWithOptions reached")
+    #endif

26-33: Handle missing FlutterViewController more explicitly

If window/rootVC isn’t ready yet, the channel silently isn’t created, leading to MissingPlugin errors. Log and consider retrying once the window is available (or wire via FlutterEngine if you have one).

   private func setupFdMonitorChannel() {
-    guard let controller = window?.rootViewController as? FlutterViewController else {
-      return
-    }
+    guard let controller = window?.rootViewController as? FlutterViewController else {
+      NSLog("AppDelegate: FD Monitor channel not set up — rootViewController unavailable")
+      return
+    }
ios/Runner/FdMonitor.swift (4)

1-4: Prefer explicit Darwin import and final class

Darwin exposes fcntl/fstat, S_IF*, PATH_MAX consistently; final avoids subclassing overhead for a singleton.

-import Foundation
-import OSLog
+import Foundation
+import OSLog
+import Darwin
-
-class FdMonitor {
+final class FdMonitor {

76-91: Avoid per-call ISO8601DateFormatter allocation

Reuse a static formatter to reduce allocations in periodic sampling.

-    func getCurrentCount() -> [String: Any] {
+    private static let iso8601 = ISO8601DateFormatter()
+
+    func getCurrentCount() -> [String: Any] {
         var result: [String: Any] = [:]
         queue.sync {
             let fdInfo = self.getFileDescriptorInfo()
             result = [
                 "openCount": fdInfo.openCount,
                 "tableSize": fdInfo.tableSize,
                 "softLimit": fdInfo.softLimit,
                 "hardLimit": fdInfo.hardLimit,
                 "percentUsed": fdInfo.percentUsed,
-                "timestamp": ISO8601DateFormatter().string(from: Date())
+                "timestamp": FdMonitor.iso8601.string(from: Date())
             ]
         }
         return result
     }

109-136: Tighten scan upper bound to reduce work on large tables

Open FDs cannot exceed softLimit. Scanning up to min(tableSize, softLimit) reduces syscalls on devices where tableSize > softLimit.

-        let tableSize = Int(getdtablesize())
+        let tableSize = Int(getdtablesize())
         var rlimit = rlimit()
         getrlimit(RLIMIT_NOFILE, &rlimit)
         let softLimit = Int(rlimit.rlim_cur)
         let hardLimit = Int(rlimit.rlim_max)
-        var openCount = 0
-        for fd in 0..<tableSize {
+        let maxFd = min(tableSize, softLimit)
+        var openCount = 0
+        for fd in 0..<maxFd {
             let fd32 = Int32(fd)
             errno = 0
             let flags = fcntl(fd32, F_GETFD, 0)
-            if flags != -1 || errno != EBADF {
+            if flags != -1 || errno != EBADF {
                 openCount += 1
             }
         }

202-205: Avoid logging full file paths in release builds

File paths can be sensitive. Gate path logging under DEBUG or omit the path outside debug.

-            if logged < 20 { // Only log first 20 individual FDs to avoid spam
-                logger.debug("  FD \(fd): type=\(typeStr) path=\(path)")
-            }
+            if logged < 20 {
+              #if DEBUG
+                logger.debug("  FD \(fd): type=\(typeStr) path=\(path)")
+              #else
+                logger.debug("  FD \(fd): type=\(typeStr)")
+              #endif
+            }

Please confirm intended logging policy for release builds.

lib/services/fd_monitor_service.dart (2)

158-166: Decode numeric fields via num to avoid int/double cast issues from platform channels

Platform decodes may yield num; casting to int directly can fail.

   factory FdMonitorStats.fromMap(Map<String, dynamic> map) {
     return FdMonitorStats(
-      openCount: map['openCount'] as int? ?? 0,
-      tableSize: map['tableSize'] as int? ?? 0,
-      softLimit: map['softLimit'] as int? ?? 0,
-      hardLimit: map['hardLimit'] as int? ?? 0,
-      percentUsed: (map['percentUsed'] as num?)?.toDouble() ?? 0.0,
+      openCount: (map['openCount'] as num?)?.toInt() ?? 0,
+      tableSize: (map['tableSize'] as num?)?.toInt() ?? 0,
+      softLimit: (map['softLimit'] as num?)?.toInt() ?? 0,
+      hardLimit: (map['hardLimit'] as num?)?.toInt() ?? 0,
+      percentUsed: (map['percentUsed'] as num?)?.toDouble() ?? 0.0,
       timestamp: map['timestamp'] as String? ?? '',
     );
   }

95-101: Use debugPrint instead of print for errors

Throttled and consistent with Flutter logging.

-      print('FD Monitor error getting count: ${e.message}');
+      debugPrint('FD Monitor error getting count: ${e.message}');
...
-      print('FD Monitor unexpected error: $e');
+      debugPrint('FD Monitor unexpected error: $e');
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cd8c8f8 and 9d679d4.

📒 Files selected for processing (4)
  • ios/Runner/AppDelegate.swift (1 hunks)
  • ios/Runner/FdMonitor.swift (1 hunks)
  • lib/services/fd_monitor_service.dart (1 hunks)
  • lib/views/main_layout/main_layout.dart (2 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.dart

📄 CodeRabbit inference engine (AGENTS.md)

**/*.dart: Run flutter analyze and resolve issues before committing code
Format Dart code with dart format (on changed files) before committing

Files:

  • lib/views/main_layout/main_layout.dart
  • lib/services/fd_monitor_service.dart
🧬 Code graph analysis (1)
ios/Runner/AppDelegate.swift (1)
ios/Runner/FdMonitor.swift (4)
  • start (23-57)
  • stop (59-74)
  • getCurrentCount (76-92)
  • logDetailedStatus (94-98)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
  • GitHub Check: validate_code_guidelines
  • GitHub Check: Test web-app-linux-profile
  • GitHub Check: unit_tests
  • GitHub Check: Test web-app-macos
  • GitHub Check: Build Desktop (macos)
  • GitHub Check: build_and_preview
  • GitHub Check: Build Mobile (Android)
  • GitHub Check: Build Desktop (linux)
  • GitHub Check: Build Desktop (windows)
  • GitHub Check: Build Mobile (iOS)
🔇 Additional comments (6)
lib/views/main_layout/main_layout.dart (2)

78-82: LGTM! Login navigation implemented correctly.

The navigation to the Wallet page on login is implemented appropriately within the BlocConsumer listener, which is the correct place for side effects in Flutter.


86-93: ****

The original concern is unfounded. routingState.resetOnLogOut() (lines 75–83 in routing_state.dart) does not modify the selectedMenu property—it only calls resetOnLogOut() on child states (walletState, fiatState, dexState, etc.). The subsequent assignment routingState.selectedMenu = MainMenuValue.wallet at line 92 executes without interference and correctly sets the menu as intended.

Likely an incorrect or invalid review comment.

ios/Runner/AppDelegate.swift (1)

36-68: Channel wiring and handler flow look good

Weak self capture, method dispatch, and JSON-safe payloads are correct.

ios/Runner/FdMonitor.swift (1)

22-57: Timer lifecycle and queue usage look correct

Single-queue mutation, start guard, weak self in handler, and proper cancel in stop().

lib/services/fd_monitor_service.dart (2)

5-139: Overall channel usage and API surface look good

Singleton wiring, error handling, and stats model are sensible. Minor nits above.


1-189: Run flutter analyze and dart format locally before committing

The sandbox environment does not have flutter or dart command-line tools available. You must run these checks on your local machine:

flutter analyze
dart format lib/services/fd_monitor_service.dart

Additionally, the code uses print() statements (lines 95 and 102 in getCurrentCount()) instead of proper logging. Consider using a logging package (e.g., logger) or removing debug prints for production code to align with Dart best practices.

Comment on lines +42 to +53
switch call.method {
case "start":
let intervalSeconds: TimeInterval
if let args = call.arguments as? [String: Any],
let interval = args["intervalSeconds"] as? Double {
intervalSeconds = interval
} else {
intervalSeconds = 60.0
}
FdMonitor.shared.start(intervalSeconds: intervalSeconds)
result(["success": true, "message": "FD Monitor started with interval: \(intervalSeconds)s"])

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Validate and robustly parse intervalSeconds to avoid invalid timer schedules

Currently accepts only Double and doesn’t guard against non‑positive values. A zero/negative repeat interval can lead to undefined behavior.

     case "start":
-      let intervalSeconds: TimeInterval
-      if let args = call.arguments as? [String: Any],
-         let interval = args["intervalSeconds"] as? Double {
-        intervalSeconds = interval
-      } else {
-        intervalSeconds = 60.0
-      }
-      FdMonitor.shared.start(intervalSeconds: intervalSeconds)
-      result(["success": true, "message": "FD Monitor started with interval: \(intervalSeconds)s"])
+      let intervalSeconds: TimeInterval
+      if let args = call.arguments as? [String: Any] {
+        if let n = args["intervalSeconds"] as? NSNumber {
+          intervalSeconds = n.doubleValue
+        } else if let s = args["intervalSeconds"] as? String, let v = Double(s) {
+          intervalSeconds = v
+        } else {
+          intervalSeconds = 60.0
+        }
+      } else {
+        intervalSeconds = 60.0
+      }
+      guard intervalSeconds > 0 else {
+        result(FlutterError(code: "invalid_args",
+                            message: "intervalSeconds must be > 0",
+                            details: nil))
+        return
+      }
+      FdMonitor.shared.start(intervalSeconds: intervalSeconds)
+      result(["success": true, "message": "FD Monitor started with interval: \(intervalSeconds)s"])
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
switch call.method {
case "start":
let intervalSeconds: TimeInterval
if let args = call.arguments as? [String: Any],
let interval = args["intervalSeconds"] as? Double {
intervalSeconds = interval
} else {
intervalSeconds = 60.0
}
FdMonitor.shared.start(intervalSeconds: intervalSeconds)
result(["success": true, "message": "FD Monitor started with interval: \(intervalSeconds)s"])
switch call.method {
case "start":
let intervalSeconds: TimeInterval
if let args = call.arguments as? [String: Any] {
if let n = args["intervalSeconds"] as? NSNumber {
intervalSeconds = n.doubleValue
} else if let s = args["intervalSeconds"] as? String, let v = Double(s) {
intervalSeconds = v
} else {
intervalSeconds = 60.0
}
} else {
intervalSeconds = 60.0
}
guard intervalSeconds > 0 else {
result(FlutterError(code: "invalid_args",
message: "intervalSeconds must be > 0",
details: nil))
return
}
FdMonitor.shared.start(intervalSeconds: intervalSeconds)
result(["success": true, "message": "FD Monitor started with interval: \(intervalSeconds)s"])

Comment on lines +22 to +28
Future<Map<String, dynamic>> start({double intervalSeconds = 60.0}) async {
try {
final result = await _channel.invokeMethod<Map<Object?, Object?>>(
'start',
{'intervalSeconds': intervalSeconds},
);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Validate intervalSeconds before invoking native

Prevent invalid values from reaching iOS and return a structured error early.

   Future<Map<String, dynamic>> start({double intervalSeconds = 60.0}) async {
-    try {
+    try {
+      if (intervalSeconds <= 0) {
+        return {
+          'success': false,
+          'message': 'intervalSeconds must be > 0',
+        };
+      }
       final result = await _channel.invokeMethod<Map<Object?, Object?>>(
         'start',
         {'intervalSeconds': intervalSeconds},
       );
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Future<Map<String, dynamic>> start({double intervalSeconds = 60.0}) async {
try {
final result = await _channel.invokeMethod<Map<Object?, Object?>>(
'start',
{'intervalSeconds': intervalSeconds},
);
Future<Map<String, dynamic>> start({double intervalSeconds = 60.0}) async {
try {
if (intervalSeconds <= 0) {
return {
'success': false,
'message': 'intervalSeconds must be > 0',
};
}
final result = await _channel.invokeMethod<Map<Object?, Object?>>(
'start',
{'intervalSeconds': intervalSeconds},
);
🤖 Prompt for AI Agents
lib/services/fd_monitor_service.dart around lines 22 to 28: validate
intervalSeconds before calling the platform channel by checking it is a finite
number > 0 (reject NaN, infinite, zero or negative). If invalid, do not call
_channel.invokeMethod; instead return a structured error Map (e.g. {'success':
false, 'error': 'invalid_interval', 'message': 'intervalSeconds must be a
positive finite number'}) so callers get a clear, typed failure early. Ensure
normal flow still calls the channel when validation passes.

Comment on lines +29 to +33
if (result != null) {
_isMonitoring = true;
return Map<String, dynamic>.from(result);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

_isMonitoring toggles true even when native start fails

Set it only on success to avoid inconsistent UI/state.

-      if (result != null) {
-        _isMonitoring = true;
-        return Map<String, dynamic>.from(result);
-      }
+      if (result != null) {
+        final map = Map<String, dynamic>.from(result);
+        _isMonitoring = map['success'] == true;
+        return map;
+      }
🤖 Prompt for AI Agents
In lib/services/fd_monitor_service.dart around lines 29 to 33, _isMonitoring is
being toggled true too early; ensure it is only set after the native start call
has definitively succeeded by first verifying result is non-null and (if
available) a success flag in the returned Map, then convert the result and set
_isMonitoring = true immediately after that verification before returning the
Map; do not set _isMonitoring on null or on error paths.

Comment on lines +59 to +62
if (result != null) {
_isMonitoring = false;
return Map<String, dynamic>.from(result);
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Likewise for stop(): only flip state on success

Avoid reporting monitoring stopped when native stop failed.

-      if (result != null) {
-        _isMonitoring = false;
-        return Map<String, dynamic>.from(result);
-      }
+      if (result != null) {
+        final map = Map<String, dynamic>.from(result);
+        if (map['success'] == true) {
+          _isMonitoring = false;
+        }
+        return map;
+      }
🤖 Prompt for AI Agents
In lib/services/fd_monitor_service.dart around lines 59–62, the code flips
_isMonitoring to false whenever a non-null result is returned, which can
incorrectly mark monitoring stopped if the native stop call failed; change the
logic so you only set _isMonitoring = false after verifying the native result
indicates a successful stop (e.g., result != null and a success flag or status
field is true/“stopped”); if the native call returns null or a failure status,
do not change _isMonitoring and instead propagate or return the error/failed
result.

@CharlVS CharlVS changed the base branch from main to dev October 27, 2025 09:12
@CharlVS CharlVS requested a review from Copilot October 27, 2025 09:12
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR addresses issue #3088 by ensuring the application always navigates to the Wallet page after login or logout operations, regardless of which page the user was on previously. This improves consistency and user experience across the application.

Key Changes:

  • Added automatic navigation to Wallet page after successful login
  • Added automatic navigation to Wallet page after logout

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@ca333 ca333 merged commit 6befeb7 into dev Oct 27, 2025
7 of 13 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Oct 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Improve mobile logout UX

3 participants