Skip to content

Conversation

@AndreaDiazCorreia
Copy link
Member

@AndreaDiazCorreia AndreaDiazCorreia commented Jan 14, 2026

Add NotificationSettingsScreen with support for push notification configuration:

  • Add route for /notification_settings in app router
  • Implement UI for push notifications toggle with platform detection
  • Add notification preferences for sound and vibration settings
  • Display privacy information card explaining encrypted token approach
  • Add Settings model fields for pushNotificationsEnabled, notificationSoundEnabled, not

Summary by CodeRabbit

  • New Features

    • New Notification Settings screen with toggles for push, sound, and vibration; settings persist and controls are disabled on unsupported platforms.
    • Notification Settings card added to the main settings for quick access.
  • Improvements

    • Push integration now initializes at startup and respects user settings, automatically registering or unregistering tokens when toggled.
  • Localization

    • Added English, Spanish, and Italian UI strings for notification and privacy texts.

✏️ Tip: You can customize this high-level summary in your review settings.

…nces

Add NotificationSettingsScreen with support for push notification configuration:
- Add route for /notification_settings in app router
- Implement UI for push notifications toggle with platform detection
- Add notification preferences for sound and vibration settings
- Display privacy information card explaining encrypted token approach
- Add Settings model fields for pushNotificationsEnabled, notificationSoundEnabled, not
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 14, 2026

Walkthrough

Adds a notification settings feature: new screen and route, three persisted settings (push, sound, vibration), notifier methods to update/unregister tokens, push service gating/unregistration, main wiring for push integration, and localization entries for EN/ES/IT.

Changes

Cohort / File(s) Summary
Routing
lib/core/app_routes.dart
New top-level route /notification_settings rendering NotificationSettingsScreen with default fade transition.
Notification Settings UI
lib/features/settings/notification_settings_screen.dart
New NotificationSettingsScreen (ConsumerWidget) presenting Push Notifications, Notification Preferences, and Privacy Info; reads from settingsProvider and calls notifier update methods; platform-aware disabling for unsupported platforms.
Settings model
lib/features/settings/settings.dart
Added three boolean fields: pushNotificationsEnabled, notificationSoundEnabled, notificationVibrationEnabled; updated ctor, copyWith, toJson, and fromJson (defaults true).
Settings notifier & push handling
lib/features/settings/settings_notifier.dart, lib/services/push_notification_service.dart, lib/shared/notifiers/session_notifier.dart
Notifier: added setPushServices, updatePushNotificationsEnabled, updateNotificationSoundEnabled, updateNotificationVibrationEnabled, and _unregisterPushTokens. Push service: added isPushEnabledInSettings callback and unregisterAllTokens(). Session notifier: optional push service setter and token registration hook after session save.
Settings screen navigation
lib/features/settings/settings_screen.dart
Inserted _buildNotificationSettingsCard and navigation row linking to /notification_settings.
App init wiring
lib/main.dart
On startup, conditionally calls _initializePushNotificationIntegration to wire push services with session and settings notifiers and set isPushEnabledInSettings.
Localization
lib/l10n/intl_en.arb, lib/l10n/intl_es.arb, lib/l10n/intl_it.arb
Added ~15 new localization keys for notification settings, descriptions, and privacy bullets (EN/ES/IT).
Tests / Mocks
test/mocks.mocks.dart
Extended MockSettings getters and copyWith to include new boolean flags so mocks match updated model.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant User
  participant UI as NotificationSettingsScreen
  participant Notifier as SettingsNotifier
  participant PushSvc as PushNotificationService
  participant FCM as FCMService

  User->>UI: Toggle "Push Notifications" (on/off)
  UI->>Notifier: updatePushNotificationsEnabled(newValue)
  alt newValue == true
    Notifier->>PushSvc: (no-op here) rely on session registration / register flow
  else newValue == false
    Notifier->>Notifier: _unregisterPushTokens()
    Notifier->>PushSvc: unregisterAllTokens()
    Notifier->>FCM: unregisterToken(...) (if configured)
  end
  Notifier->>Notifier: persist state (_saveToPrefs)
  Notifier-->>UI: state updated
Loading
sequenceDiagram
  autonumber
  participant AppInit
  participant Container as ProviderContainer
  participant Session as SessionNotifier
  participant Settings as SettingsNotifier
  participant PushSvc as PushNotificationService
  participant FCM as FCMService

  AppInit->>Container: create providers
  AppInit->>PushSvc: instantiate services
  AppInit->>Session: SessionNotifier.setPushService(PushSvc)
  AppInit->>Settings: SettingsNotifier.setPushServices(PushSvc, FCM)
  AppInit->>PushSvc: PushSvc.isPushEnabledInSettings = () => settings.pushNotificationsEnabled
  Session->>PushSvc: after saving session -> registerToken(...) (fire-and-forget)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • Catrya
  • grunch

Poem

🐰
I hopped in code to set the bell,
Three little toggles ring so well,
Push, sound, and buzz — now stored with care,
Tokens cleaned when off — poof! — in the air,
A nibble, a hop, notifications prepared! 🎶

🚥 Pre-merge checks | ✅ 3
✅ 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 accurately describes the main feature addition: a new notification settings screen with push notification preferences, which is the primary focus of the changeset.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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.

@AndreaDiazCorreia
Copy link
Member Author

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 14, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

…cation fields

- Replace activeTrackColor and activeThumbColor with single activeColor property in Switch widgets
- Add missing notification-related getters to MockSettings (isLoggingEnabled, pushNotificationsEnabled, notificationSoundEnabled, notificationVibrationEnabled)
- Update MockSettings copyWith method to include new notification preference parameters
…anagement

- Add setPushServices method to SettingsNotifier to connect with PushNotificationService and FCMService
- Implement automatic token unregistration when user disables push notifications in settings
- Add setPushNotificationService method to SessionNotifier for automatic token registration
- Register push tokens automatically when new sessions are saved
- Initialize push notification integration in main.dart with settings
@AndreaDiazCorreia
Copy link
Member Author

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 16, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
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: 2

🤖 Fix all issues with AI agents
In `@lib/features/settings/settings_notifier.dart`:
- Around line 170-198: The enable path in updatePushNotificationsEnabled
currently only sets state and saves prefs but does not re-register tokens for
existing sessions, leaving notifications silent; modify
updatePushNotificationsEnabled so that when newValue is true it calls a new
helper (or extend _unregisterPushTokens) to iterate the app's existing
sessions/trade pubkeys (e.g., from state.sessions or the session store) and call
_pushService.registerToken(...) for each pubkey, awaiting or handling each
future and logging success/failure; ensure you check _pushService != null before
registering and add robust error handling/logging similar to the unregister path
(use _logger.i/_logger.w) and persist any necessary mapping so future toggles
can re-register.

In `@lib/shared/notifiers/session_notifier.dart`:
- Around line 141-155: The success log in _registerPushToken uses
tradePubkey.substring(0, 16) which can throw if the pubkey is shorter; guard by
computing a safe display string (e.g., if tradePubkey.length > 16 use
tradePubkey.substring(0,16) + '...' else use tradePubkey) and use that display
variable in the _logger.i call so no RangeError occurs during logging.
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 28d3b41 and 2bca681.

📒 Files selected for processing (6)
  • lib/features/settings/notification_settings_screen.dart
  • lib/features/settings/settings_notifier.dart
  • lib/main.dart
  • lib/services/push_notification_service.dart
  • lib/shared/notifiers/session_notifier.dart
  • test/mocks.mocks.dart
🚧 Files skipped from review as they are similar to previous changes (1)
  • lib/features/settings/notification_settings_screen.dart
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{dart,flutter}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{dart,flutter}: Run flutter analyze after any code change - Mandatory before commits to ensure zero linting issues
Run flutter test after any code change - Mandatory before commits to ensure all unit tests pass

Files:

  • lib/shared/notifiers/session_notifier.dart
  • lib/features/settings/settings_notifier.dart
  • lib/services/push_notification_service.dart
  • lib/main.dart
  • test/mocks.mocks.dart
**/*.dart

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.dart: Use Riverpod for all state management - encapsulate business logic in Notifiers and access data only through repository classes
All code comments must be in English - use clear, concise English for variable names, function names, and comments
Always check mounted before using BuildContext after async operations to prevent errors on disposed widgets
Use const constructors where possible for better performance and immutability
Remove unused imports and dependencies to maintain code cleanliness and reduce build size

**/*.dart: Application code should be organized under lib/, grouped by domain with lib/features/<feature>/ structure, shared utilities in lib/shared/, dependency wiring in lib/core/, and services in lib/services/
Persistence, APIs, and background jobs should live in lib/data/ and lib/background/; generated localization output must be in lib/generated/ and must stay untouched
Apply flutter format . to enforce canonical Dart formatting (two-space indentation, trailing commas) before committing
Resolve every analyzer warning in Dart code
Name Riverpod providers using the <Feature>Provider or <Feature>Notifier convention
Localize all user-facing strings via ARB files and access them with S.of(context) rather than hard-coded literals

Files:

  • lib/shared/notifiers/session_notifier.dart
  • lib/features/settings/settings_notifier.dart
  • lib/services/push_notification_service.dart
  • lib/main.dart
  • test/mocks.mocks.dart
lib/shared/**/*.dart

📄 CodeRabbit inference engine (CLAUDE.md)

Follow existing feature patterns when adding new shared utilities - refer to order, chat, and auth features as implementation examples

Files:

  • lib/shared/notifiers/session_notifier.dart
lib/services/**/*.dart

📄 CodeRabbit inference engine (CLAUDE.md)

Access NostrService for all Nostr protocol interactions - NostrService manages relay connections and messaging

Files:

  • lib/services/push_notification_service.dart
lib/main.dart

📄 CodeRabbit inference engine (CLAUDE.md)

Configure timeago package locales in app initialization for proper relative time formatting (e.g., 'hace X horas' vs 'hours ago')

Files:

  • lib/main.dart
**/*.{g.dart,mocks.dart}

📄 CodeRabbit inference engine (CLAUDE.md)

Never manually edit generated files (.g.dart, .mocks.dart) or add individual ignore comments - regenerate with dart run build_runner build -d instead

Files:

  • test/mocks.mocks.dart
test/mocks.mocks.dart

📄 CodeRabbit inference engine (CLAUDE.md)

Never manually modify test/mocks.mocks.dart - it already has file-level // ignore_for_file: must_be_immutable ignore directives

Files:

  • test/mocks.mocks.dart
🧠 Learnings (24)
📓 Common learnings
Learnt from: Catrya
Repo: MostroP2P/mobile PR: 327
File: lib/features/order/notfiers/abstract_mostro_notifier.dart:141-154
Timestamp: 2025-10-14T21:12:06.887Z
Learning: In the MostroP2P mobile codebase, the notification system uses a two-layer localization pattern: providers/notifiers (without BuildContext access) call `showCustomMessage()` with string keys (e.g., 'orderTimeoutMaker', 'orderCanceled'), and the UI layer's `NotificationListenerWidget` has a switch statement that maps these keys to localized strings using `S.of(context)`. This architectural pattern properly separates concerns while maintaining full localization support for all user-facing messages.
📚 Learning: 2025-11-27T12:10:12.082Z
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: Applies to lib/features/**/notifiers/**/*.dart : Encapsulate business logic in Notifiers - Notifiers should expose state via providers and handle all complex state transitions

Applied to files:

  • lib/shared/notifiers/session_notifier.dart
  • lib/features/settings/settings_notifier.dart
  • lib/main.dart
📚 Learning: 2025-11-27T12:10:12.082Z
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: Applies to lib/features/subscriptions/subscription_manager.dart : Use SubscriptionManager with `fireImmediately: false` during SessionNotifier initialization to prevent premature execution

Applied to files:

  • lib/shared/notifiers/session_notifier.dart
  • lib/features/settings/settings_notifier.dart
  • lib/main.dart
📚 Learning: 2025-11-27T12:10:12.082Z
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: Applies to lib/features/**/providers/**/*.dart : Use Notifier pattern instead of simple StateNotifier for complex state logic requiring business rule encapsulation

Applied to files:

  • lib/shared/notifiers/session_notifier.dart
  • lib/features/settings/settings_notifier.dart
  • lib/main.dart
📚 Learning: 2025-11-27T12:10:12.082Z
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: Applies to lib/features/auth/notifiers/abstract_mostro_notifier.dart : Start 10-second cleanup timer automatically when taking orders via `startSessionTimeoutCleanup()` to prevent orphan sessions

Applied to files:

  • lib/shared/notifiers/session_notifier.dart
  • lib/main.dart
📚 Learning: 2025-10-21T21:47:03.451Z
Learnt from: Catrya
Repo: MostroP2P/mobile PR: 327
File: lib/features/order/notfiers/abstract_mostro_notifier.dart:157-182
Timestamp: 2025-10-21T21:47:03.451Z
Learning: In MostroP2P/mobile, for Action.canceled handling in abstract_mostro_notifier.dart (Riverpod StateNotifier), do not add mounted checks after async sessionNotifier.deleteSession(orderId) as they break order state synchronization during app restart. The Action.canceled flow contains critical business logic that must complete fully; Riverpod handles provider disposal automatically. Mounted checks should only protect UI operations, not business logic in StateNotifiers.

Applied to files:

  • lib/shared/notifiers/session_notifier.dart
  • lib/main.dart
📚 Learning: 2025-05-06T15:49:26.443Z
Learnt from: chebizarro
Repo: MostroP2P/mobile PR: 74
File: lib/services/mostro_service.dart:70-76
Timestamp: 2025-05-06T15:49:26.443Z
Learning: In the Mostro Mobile codebase, `eventStorageProvider` is exported from `package:mostro_mobile/shared/providers/mostro_service_provider.dart` and not from a separate `event_storage_provider.dart` file.

Applied to files:

  • lib/shared/notifiers/session_notifier.dart
  • lib/main.dart
📚 Learning: 2025-11-27T12:10:12.082Z
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: Applies to **/*.dart : Use Riverpod for all state management - encapsulate business logic in Notifiers and access data only through repository classes

Applied to files:

  • lib/shared/notifiers/session_notifier.dart
  • lib/features/settings/settings_notifier.dart
📚 Learning: 2025-11-27T12:10:12.082Z
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: Applies to lib/features/relays/**/*.dart : Use dual storage strategy: store Mostro/default relays in `settings.relays` and user relays in `settings.userRelays` with full JSON metadata via `toJson()`/`fromJson()`

Applied to files:

  • lib/shared/notifiers/session_notifier.dart
  • lib/features/settings/settings_notifier.dart
  • test/mocks.mocks.dart
📚 Learning: 2025-11-27T12:10:12.082Z
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: Applies to lib/services/nostr_service.dart : Manage all relay connections and Nostr messaging through NostrService - automatically reconnect when relay list updates

Applied to files:

  • lib/shared/notifiers/session_notifier.dart
  • lib/main.dart
  • test/mocks.mocks.dart
📚 Learning: 2025-10-14T21:12:06.887Z
Learnt from: Catrya
Repo: MostroP2P/mobile PR: 327
File: lib/features/order/notfiers/abstract_mostro_notifier.dart:141-154
Timestamp: 2025-10-14T21:12:06.887Z
Learning: In the MostroP2P mobile codebase, the notification system uses a two-layer localization pattern: providers/notifiers (without BuildContext access) call `showCustomMessage()` with string keys (e.g., 'orderTimeoutMaker', 'orderCanceled'), and the UI layer's `NotificationListenerWidget` has a switch statement that maps these keys to localized strings using `S.of(context)`. This architectural pattern properly separates concerns while maintaining full localization support for all user-facing messages.

Applied to files:

  • lib/shared/notifiers/session_notifier.dart
  • lib/features/settings/settings_notifier.dart
  • lib/main.dart
📚 Learning: 2025-11-27T12:10:12.082Z
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: Applies to lib/data/repositories/**/*.dart : Implement Repository pattern for all data access - all data operations must go through repository classes

Applied to files:

  • lib/shared/notifiers/session_notifier.dart
📚 Learning: 2025-11-27T12:10:12.082Z
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: Applies to lib/services/**/*.dart : Access NostrService for all Nostr protocol interactions - NostrService manages relay connections and messaging

Applied to files:

  • lib/shared/notifiers/session_notifier.dart
📚 Learning: 2025-05-06T15:49:26.443Z
Learnt from: chebizarro
Repo: MostroP2P/mobile PR: 74
File: lib/services/mostro_service.dart:70-76
Timestamp: 2025-05-06T15:49:26.443Z
Learning: In the Mostro Mobile codebase, Riverpod code generation is used with `Riverpod` annotations. Providers like `eventStorageProvider` are generated in `.g.dart` files from annotated functions in the main provider files. These providers are accessible by importing the main provider file (e.g., `mostro_service_provider.dart`), not by importing a separate provider file.

Applied to files:

  • lib/shared/notifiers/session_notifier.dart
  • lib/main.dart
📚 Learning: 2026-01-09T22:09:13.071Z
Learnt from: BraCR10
Repo: MostroP2P/mobile PR: 403
File: lib/features/settings/settings_notifier.dart:153-156
Timestamp: 2026-01-09T22:09:13.071Z
Learning: In lib/features/settings/settings_notifier.dart, the updateLoggingEnabled method intentionally does NOT call _saveToPrefs() because the logging toggle should not persist across app restarts. The isLoggingEnabled field is deliberately excluded from Settings.toJson() and always returns false in fromJson() for security and performance reasons, requiring users to explicitly enable logging each session.

Applied to files:

  • lib/features/settings/settings_notifier.dart
  • lib/services/push_notification_service.dart
  • test/mocks.mocks.dart
📚 Learning: 2025-11-27T12:10:12.082Z
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: Applies to lib/features/**/providers/**/*.dart : Organize Riverpod providers by feature in `features/{feature}/providers/` using Notifier pattern for complex state logic

Applied to files:

  • lib/features/settings/settings_notifier.dart
  • lib/main.dart
📚 Learning: 2025-11-27T12:10:12.082Z
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: Applies to lib/features/settings/settings.dart : Use null-aware operators (`??`) in Settings `copyWith()` method to preserve existing values for selectedLanguage and defaultLightningAddress when not explicitly overridden

Applied to files:

  • lib/features/settings/settings_notifier.dart
  • test/mocks.mocks.dart
📚 Learning: 2025-08-21T14:45:43.974Z
Learnt from: Catrya
Repo: MostroP2P/mobile PR: 272
File: lib/features/relays/widgets/relay_selector.dart:13-15
Timestamp: 2025-08-21T14:45:43.974Z
Learning: In the Mostro mobile app's RelaySelector widget (lib/features/relays/widgets/relay_selector.dart), watching relaysProvider.notifier correctly triggers rebuilds because the relaysProvider itself depends on settingsProvider (line 8 in relays_provider.dart). When blacklist changes via toggleMostroRelayBlacklist(), the settingsProvider updates, causing relaysProvider to rebuild, which then notifies widgets watching the notifier. The UI correctly reflects active/inactive states in real-time through this dependency chain.

Applied to files:

  • lib/features/settings/settings_notifier.dart
📚 Learning: 2025-11-27T12:10:12.081Z
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.081Z
Learning: Run `flutter test integration_test/` only for significant changes affecting core services and main user flows

Applied to files:

  • lib/main.dart
📚 Learning: 2025-11-27T12:10:12.082Z
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: Applies to lib/features/auth/notifiers/abstract_mostro_notifier.dart : Use `startSessionTimeoutCleanupForRequestId()` for order creation timeout protection and cancel timer automatically when any Mostro response received

Applied to files:

  • lib/main.dart
📚 Learning: 2025-11-27T12:10:12.082Z
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: Applies to lib/main.dart : Configure timeago package locales in app initialization for proper relative time formatting (e.g., 'hace X horas' vs 'hours ago')

Applied to files:

  • lib/main.dart
📚 Learning: 2025-11-27T12:10:12.082Z
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: Applies to test/mocks.mocks.dart : Never manually modify `test/mocks.mocks.dart` - it already has file-level `// ignore_for_file: must_be_immutable` ignore directives

Applied to files:

  • test/mocks.mocks.dart
📚 Learning: 2025-11-27T12:10:26.407Z
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-27T12:10:26.407Z
Learning: Applies to **/*_test.dart : Place unit tests beside their feature counterparts using the `*_test.dart` suffix and prefer Mockito fakes generated via `build_runner`

Applied to files:

  • test/mocks.mocks.dart
📚 Learning: 2025-11-27T12:10:12.082Z
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: Applies to lib/features/relays/relays_notifier.dart : Use `removeRelayWithBlacklist()` for Mostro/default relays (adds to blacklist) and `removeRelay()` for permanent user relay deletion

Applied to files:

  • test/mocks.mocks.dart
⏰ 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). (1)
  • GitHub Check: build
🔇 Additional comments (10)
lib/shared/notifiers/session_notifier.dart (2)

10-37: Clean service injection hook.

Setter-based injection keeps the notifier decoupled and is easy to wire during app initialization.


130-139: Registration hook placement is sensible.

Registering after persistence + state emit keeps side-effects out of critical save flow.

lib/main.dart (2)

17-71: Push integration wiring looks solid.

The conditional setup is safe and keeps initialization isolated when services aren’t available.


93-117: Initialization helper is clear and well-scoped.

Service wiring and settings callback are straightforward and resilient to failures.

Also applies to: 161-163

lib/services/push_notification_service.dart (3)

39-41: Settings callback hook is a good extension point.


113-117: Settings gate before registration makes sense.


194-213: Bulk unregister logic is straightforward and safe.

lib/features/settings/settings_notifier.dart (2)

8-26: Push service wiring is clean and minimal.


200-208: Notification sound/vibration toggles look good.

test/mocks.mocks.dart (1)

2001-2083: No review comment (generated file).

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Comment on lines +170 to +198
Future<void> updatePushNotificationsEnabled(bool newValue) async {
state = state.copyWith(pushNotificationsEnabled: newValue);
await _saveToPrefs();
_logger.i('Push notifications ${newValue ? 'enabled' : 'disabled'}');

// When disabling, unregister all tokens and delete FCM token
if (!newValue) {
_unregisterPushTokens();
}
}

/// Unregister all push tokens when user disables notifications
void _unregisterPushTokens() {
if (_pushService != null) {
_pushService!.unregisterAllTokens().then((_) {
_logger.i('All push tokens unregistered');
}).catchError((e) {
_logger.w('Failed to unregister push tokens: $e');
});
}

if (_fcmService != null) {
_fcmService!.deleteToken().then((_) {
_logger.i('FCM token deleted');
}).catchError((e) {
_logger.w('Failed to delete FCM token: $e');
});
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Enabling push doesn’t re-register existing sessions.

Right now only the disable path triggers token cleanup. If a user re-enables push (or enables it after having open sessions while it was off), no tokens are registered for those existing trade pubkeys. This leaves notifications silently disabled until a new session is saved.

Please add a re-registration step on enable (e.g., iterate existing sessions and call registerToken, or persist known trade pubkeys so an enable path can re-register them).

🤖 Prompt for AI Agents
In `@lib/features/settings/settings_notifier.dart` around lines 170 - 198, The
enable path in updatePushNotificationsEnabled currently only sets state and
saves prefs but does not re-register tokens for existing sessions, leaving
notifications silent; modify updatePushNotificationsEnabled so that when
newValue is true it calls a new helper (or extend _unregisterPushTokens) to
iterate the app's existing sessions/trade pubkeys (e.g., from state.sessions or
the session store) and call _pushService.registerToken(...) for each pubkey,
awaiting or handling each future and logging success/failure; ensure you check
_pushService != null before registering and add robust error handling/logging
similar to the unregister path (use _logger.i/_logger.w) and persist any
necessary mapping so future toggles can re-register.

Comment on lines +141 to +155
/// Register push notification token for a trade pubkey
void _registerPushToken(String tradePubkey) {
if (_pushService == null) {
_logger.d('Push service not available, skipping token registration');
return;
}

// Fire and forget - don't block session save on push registration
_pushService!.registerToken(tradePubkey).then((success) {
if (success) {
_logger.i('Push token registered for trade: ${tradePubkey.substring(0, 16)}...');
}
}).catchError((e) {
_logger.w('Failed to register push token: $e');
});
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Guard pubkey truncation to avoid RangeError.

Line 151 uses substring(0, 16) without checking length. If a shorter key ever arrives, this will throw during logging.

🧩 Suggested fix
-        _logger.i('Push token registered for trade: ${tradePubkey.substring(0, 16)}...');
+        final shortKey =
+            tradePubkey.length <= 16 ? tradePubkey : tradePubkey.substring(0, 16);
+        _logger.i('Push token registered for trade: $shortKey...');
🤖 Prompt for AI Agents
In `@lib/shared/notifiers/session_notifier.dart` around lines 141 - 155, The
success log in _registerPushToken uses tradePubkey.substring(0, 16) which can
throw if the pubkey is shorter; guard by computing a safe display string (e.g.,
if tradePubkey.length > 16 use tradePubkey.substring(0,16) + '...' else use
tradePubkey) and use that display variable in the _logger.i call so no
RangeError occurs during logging.

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.

2 participants