Skip to content

Conversation

@BraCR10
Copy link
Member

@BraCR10 BraCR10 commented Feb 10, 2026

This PR fixes empty chat messages after first-time restore on a new device.
Closes:#372

What's Included

  • Initialize chat subscription immediately after saving session during restore
  • Error handling
  • Peer object creation in restore process

Testing

  • Perform first-time restore on new device
  • Verify chat messages appear immediately after restore completes
  • Verify refresh (re-restore) still works correctly

Summary by CodeRabbit

  • New Features

    • Restored sessions now resume chat with linked peer information so chat history and live chat continue.
    • New localized error screen for missing or unavailable chat sessions.
    • Info controls now dismiss the keyboard when switching types.
    • Added English, Spanish, and Italian translations for chat error messages.
  • Bug Fixes

    • Clearer error states for missing sessions or chat partners.
    • More reliable scroll-to-bottom behavior and improved bottom padding for zoomed text.
    • Chat lists show only conversations with messages and are cleared when none exist.

Addresses issues encountered during chat restoration, including:

- Improves error handling when session or peer data is missing, displaying appropriate error messages.
- Fixes keyboard visibility tracking to ensure proper scrolling when the keyboard appears.
- Adds peer information to the session during restore.
- Increases delay waiting for messages to arrive to 10 seconds.
Addresses an issue where the role and peer were not being correctly determined during the restore process.

This commit refactors the logic for determining the user's role (buyer or seller) and their corresponding peer based on trade keys, and ensures that the role and peer are properly determined for each order during restore.

This fix resolves an issue that was preventing chat messages from being restored correctly.
Ensures the chat listener is active before historical messages arrive during the restore process.
This prevents message loss due to the broadcast stream dropping events when no listener is present.

Fixes error where chat restoring would fail
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 10, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds runtime session and peer validation in chat UI with explicit ChatErrorScreen and localization; derives and persists Peer during restore and starts chat subscriptions; tightens chat notifiers to avoid broad fallbacks and to only surface chats with messages.

Changes

Cohort / File(s) Summary
Chat UI & Widgets
lib/features/chat/screens/chat_room_screen.dart, lib/features/chat/widgets/info_buttons.dart, lib/features/chat/widgets/chat_error_screen.dart
Validate session and session.peer at runtime; return ChatErrorScreen for missing session/peer and log errors; add ChatErrorScreen widget and localization keys; wire InfoButtons.onInfoTypeChanged; guard scroll-to-bottom and adjust padding/opacity.
Restore flow & Session model
lib/features/restore/restore_manager.dart, lib/data/models/session.dart
Derive and attach Peer? peer during restore, persist Session with peer, increase historical-message wait times, initialize per-order chat subscriptions after saving sessions, and improve logging/error propagation.
Chat notifiers
lib/features/chat/notifiers/chat_room_notifier.dart, lib/features/chat/notifiers/chat_rooms_notifier.dart
Remove broad fallback query when order-specific chats are absent; clear chat state when no sessions; filter loaded/refreshed chats to those with non-empty messages and update related logging.
Localization
lib/l10n/intl_en.arb, lib/l10n/intl_es.arb, lib/l10n/intl_it.arb
Add metadata and four new localization keys for chat error screens: sessionNotFound, unableToLoadChatSession, peerInformationUnavailable, chatPartnerCouldNotBeLoaded.

Sequence Diagram

sequenceDiagram
    participant RM as RestoreManager
    participant Store as SessionStore
    participant Sub as ChatSubscriptionService
    participant CRS as ChatRoomScreen
    participant Log as Logger

    RM->>RM: derive Peer from restore payload
    RM->>Store: persist Session (with Peer?)
    alt peer present
        RM->>Sub: subscribe to chat updates for order
        Sub-->>RM: subscription active
    end

    CRS->>Store: load Session by id
    CRS->>CRS: validate session != null
    alt session null
        CRS-->>CRS: show ChatErrorScreen.sessionNotFound
        CRS->>Log: log session missing
    else
        CRS->>CRS: validate session.peer != null
        alt peer null
            CRS-->>CRS: show ChatErrorScreen.peerUnavailable
            CRS->>Log: log peer missing
        else
            CRS-->>CRS: render chat UI
            CRS->>Sub: rely on subscription for updates
        end
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • Catrya
  • grunch

Poem

🐰 I stitched a peer into sessions with care,
Now error screens whisper when data's not there,
Subscriptions hum, logs glow in the night,
I hop, I guard, I keep the chat right—
Nibble a carrot, then bounce out of sight.

🚥 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 title 'Fix: Error restoring chat' directly addresses the PR objective of fixing empty chat messages during first-time restore, which is the primary change across all modifications.
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.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/ErrorChatRestoring

Tip

Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord.


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.

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/chat/screens/chat_room_screen.dart`:
- Around line 281-282: The alpha value passed to Colors.grey.withValues is out
of range (uses 8), so update the call (Colors.grey.withValues) to use a
floating-point alpha in [0.0,1.0], e.g., alpha: 0.03 to match the "0.03 opacity
- extremely subtle" comment, ensuring the border is rendered with the intended
low opacity rather than fully opaque.

In `@lib/features/restore/restore_manager.dart`:
- Around line 553-557: The log message in restore_manager.dart currently says
'waiting 8 seconds...' but the code uses await Future.delayed(const
Duration(seconds: 10));—update the logger.i call to state "waiting 10 seconds
for historical messages to be saved..." so the log matches the actual delay;
search for the logger.i call near the Future.delayed usage in the restore
manager method and adjust the message string accordingly.
🧹 Nitpick comments (3)
lib/features/chat/screens/chat_room_screen.dart (2)

48-147: Hardcoded user-facing strings should use S.of(context) for localization.

Lines 60–62, 76, 84–85, 111–113, 127, 135–136 all contain hardcoded English strings ('Back', 'Session not found', 'Unable to load chat session for this order', 'Peer information unavailable', 'Chat partner information could not be loaded'). Per coding guidelines, all user-facing strings must use S.of(context).yourKey with ARB files.

Additionally, the two error scaffolds (Lines 48–96 and 98–147) are nearly identical — they share the same AppBar, layout structure, and styling, differing only in icon, title, and subtitle. Consider extracting a shared _buildErrorScaffold helper to reduce the duplication.

♻️ Example: Extract a reusable error scaffold helper
Widget _buildErrorScaffold({
  required IconData icon,
  required String title,
  required String subtitle,
}) {
  return Scaffold(
    backgroundColor: AppTheme.backgroundDark,
    appBar: AppBar(
      backgroundColor: AppTheme.backgroundDark,
      elevation: 0,
      leading: IconButton(
        icon: const Icon(Icons.arrow_back, color: AppTheme.cream1),
        onPressed: () => Navigator.of(context).pop(),
      ),
      title: Text(
        S.of(context).back,
        style: const TextStyle(color: AppTheme.cream1),
      ),
    ),
    body: Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Icon(icon, size: 64, color: AppTheme.textSecondary),
          const SizedBox(height: 16),
          Text(title, style: TextStyle(color: AppTheme.textPrimary, fontSize: 18, fontWeight: FontWeight.w600)),
          const SizedBox(height: 8),
          Text(subtitle, style: TextStyle(color: AppTheme.textSecondary, fontSize: 14), textAlign: TextAlign.center),
        ],
      ),
    ),
  );
}

As per coding guidelines: "Use S.of(context).yourKey for all user-facing strings instead of hardcoded text."


46-46: Consider using ref.watch instead of ref.read for sessionProvider inside build.

Using ref.read in build() means the widget won't rebuild if the session state changes (e.g., if peer data is populated asynchronously after initial navigation). If sessionProvider is a state provider that can update, ref.watch would ensure the UI reacts to session changes — particularly relevant for the new null guards that could show/hide the error UI.

lib/features/restore/restore_manager.dart (1)

451-452: Unclear comment — "No should be used" is ambiguous.

The comment //No should be used - Default to peer-initiated is hard to parse. Consider rephrasing for clarity, e.g., // Should not be used directly — defaults to peer-initiated.

Refines the chat UI's border opacity for better visual appeal.

Increases the restore timeout to accommodate slower message
delivery, mitigating potential issues during chat restoring. This
addresses a problem where historical messages might not be fully
restored due to relay delays.
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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
lib/features/restore/restore_manager.dart (4)

499-547: ⚠️ Potential issue | 🟡 Minor

Core fix looks correct — peer derivation and early chat subscription.

The logic to determine role/peer by comparing derived trade keys against order pubkeys, then subscribing to chat before historical messages arrive, directly addresses the PR objective (fixing empty chat after restore). The approach is sound: save session first, then subscribe, so the listener is active when relay delivers historical events.

A few observations on this block:

  1. No error handling around subscribe() (Line 545): If subscribe() throws, it will bubble up and abort the entire restore loop. Consider wrapping in try-catch so a single order's chat subscription failure doesn't prevent remaining orders from being restored.

  2. Potential for orphaned subscriptions on restore failure: If the loop fails partway through (e.g., Line 493's exception), orders that already had subscribe() called will have active chat subscriptions but the restore may ultimately fail and clear state. This could lead to dangling listeners.

🛡️ Suggested: guard chat subscription to avoid aborting the loop
         if (peer != null) {
-          ref.read(chatRoomsProvider(orderDetail.id).notifier).subscribe();
-          logger.d('Restore: initialized chat listener for order ${orderDetail.id}');
+          try {
+            ref.read(chatRoomsProvider(orderDetail.id).notifier).subscribe();
+            logger.d('Restore: initialized chat listener for order ${orderDetail.id}');
+          } catch (e) {
+            logger.w('Restore: failed to initialize chat listener for order ${orderDetail.id}', error: e);
+          }
         }

641-641: ⚠️ Potential issue | 🟡 Minor

Typo: "IMPORTAN" → "IMPORTANT".

-          // IMPORTAN : we need to create new message due to synchronization with stored messages
+          // IMPORTANT: we need to create new message due to synchronization with stored messages

782-800: ⚠️ Potential issue | 🟡 Minor

Error handling in initRestoreProcess: showError('') passes empty string.

Line 785: showError('') — the empty string means the user sees no meaningful error message. Consider passing a descriptive message or a localization key that the UI can resolve.

🐛 Proposed fix
-      ref.read(restoreProgressProvider.notifier).showError('');
+      ref.read(restoreProgressProvider.notifier).showError('Restore failed. Please try again.');

Based on learnings: "The notification system uses a two-layer localization pattern: providers/notifiers call showCustomMessage() with string keys, and the UI layer maps these keys to localized strings using S.of(context)." If showError follows the same pattern, pass a key instead of a hardcoded string.


148-151: ⚠️ Potential issue | 🟠 Major

Fix guard condition logic to prevent null pointer exception on _tempTradeKey.

The guard conditions at lines 149, 241, and 303 use &&, which allows the invalid state where _tempTradeKey is null while _masterKey is non-null. Since all three methods force-unwrap _tempTradeKey! unconditionally (lines 163, 255, 317), this will cause a null pointer exception. The condition should use || instead of && to properly protect the force-unwrap.

While current initialization in initRestoreProcess() (lines 708, 719) guarantees both are set before these methods are called, the guard logic itself is insufficient and should be corrected for defensive programming.

🧹 Nitpick comments (4)
lib/features/restore/restore_manager.dart (2)

504-525: Role/peer derivation defaults to null role when neither pubkey matches.

When the user's derived pubkey matches neither buyerTradePubkey nor sellerTradePubkey (Lines 522–525), role stays null and the session is still saved. Downstream, _getActionFromStatus (Line 637) receives a null role, which works for some statuses but may produce incorrect actions for role-dependent ones (e.g., waitingBuyerInvoice, waitingPayment, active). The warning log is good, but consider whether a null role session should be saved at all — or at least document the expected behavior.


451-452: Clarify the comment on the dispute default action.

The comment //No should be used - Default to peer-initiated is unclear. Consider rewording:

-        return Action
-            .disputeInitiatedByPeer; //No should be used -  Default to peer-initiated
+        return Action
+            .disputeInitiatedByPeer; // Default; overridden in restore() when dispute data is available
lib/features/chat/screens/chat_room_screen.dart (2)

49-96: Hardcoded user-facing strings should use S.of(context) for localization.

Lines 76, 85, 127, 136 contain hardcoded English strings: 'Session not found', 'Unable to load chat session for this order', 'Peer information unavailable', 'Chat partner information could not be loaded'. These should be localized via ARB files.

Also, the two error screens share nearly identical structure (Scaffold + AppBar + centered Column with icon/text). Consider extracting a shared error widget to reduce duplication.

As per coding guidelines: "Use S.of(context).yourKey for all user-facing strings instead of hardcoded text."

Also applies to: 98-147


46-46: ref.read for session won't rebuild when the session updates.

Line 46 uses ref.read(sessionProvider(widget.orderId)) inside build(). If the session is updated (e.g., peer becomes available after restore completes), this widget won't rebuild to reflect the change. Consider using ref.watch so the screen reactively transitions from the error state to the chat UI when session/peer data becomes available.

♻️ Proposed fix
-    final session = ref.read(sessionProvider(widget.orderId));
+    final session = ref.watch(sessionProvider(widget.orderId));

Addresses the issue of duplicated error screens in the chat feature.

This commit introduces a `ChatErrorScreen` widget to handle displaying error messages related to missing sessions or unavailable peers.

Replaces the inline error screen implementations with calls to the new `ChatErrorScreen`, improving code maintainability and reducing redundancy.

Adds localization strings for the error messages.
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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
lib/features/chat/screens/chat_room_screen.dart (1)

102-105: ⚠️ Potential issue | 🟡 Minor

Hardcoded 'Back' string — use localization for consistency.

The new ChatErrorScreen correctly uses S.of(context)!.back for the same AppBar title. This screen should follow suit.

Proposed fix
-        title: const Text(
-          'Back',
-          style: TextStyle(color: AppTheme.cream1),
+        title: Text(
+          S.of(context)!.back,
+          style: const TextStyle(color: AppTheme.cream1),
         ),

As per coding guidelines: "Use S.of(context).yourKey for all user-facing strings instead of hardcoded text".

🧹 Nitpick comments (1)
lib/features/chat/widgets/chat_error_screen.dart (1)

63-75: Add const to TextStyle instances.

Both TextStyle constructors use only compile-time constants, so they can be const for widget optimization.

Proposed fix
             Text(
               title,
-              style: TextStyle(
+              style: const TextStyle(
                 color: AppTheme.textPrimary,
                 fontSize: 18,
                 fontWeight: FontWeight.w600,
               ),
             ),
             const SizedBox(height: 8),
             Text(
               subtitle,
-              style: TextStyle(
+              style: const TextStyle(
                 color: AppTheme.textSecondary,
                 fontSize: 14,
               ),

@BraCR10
Copy link
Member Author

BraCR10 commented Feb 10, 2026

Ready for review ✅

Copy link
Member

@Catrya Catrya left a comment

Choose a reason for hiding this comment

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

@BraCR10 cuando recupero el usuario ya no sale el error al abrir el chat desde la pantalla de Order details, sin embargo en la pantalla de chat no sale ese chat nunca, aunque tenga mensajes, solo lista chats antiguos de ordenes que ya estan eliminadas
fijate en este caso que la contrapartre se llama loose-monkey
Image
Image
Image

Addresses issues where chat data was not properly cleared during restore, leading to potential inconsistencies.

This commit ensures that all chat-related providers are invalidated and cleared during the restore process.
It also prevents loading chats with no messages during initial load and refresh.
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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
lib/features/restore/restore_manager.dart (1)

656-656: ⚠️ Potential issue | 🟡 Minor

Typo: "IMPORTAN" → "IMPORTANT".

-          // IMPORTAN : we need to create new message due to synchronization with stored messages
+          // IMPORTANT: we need to create new message due to synchronization with stored messages
lib/features/chat/notifiers/chat_rooms_notifier.dart (1)

64-70: ⚠️ Potential issue | 🟠 Major

Use the full session state instead of the .sessions getter to include all session types.

Line 66 reads ref.read(sessionNotifierProvider.notifier).sessions, which returns only orderId-based sessions from the _sessions map. However, the provider's state combines three session sources: _sessions, _requestIdToSession, and _pendingChildSessions. This causes refreshChatList() to miss sessions tracked by request ID and pending child sessions, creating an inconsistency with loadChats() at line 34, which correctly reads the full state via ref.read(sessionNotifierProvider).

Change line 66 to:

final sessions = ref.read(sessionNotifierProvider);
🤖 Fix all issues with AI agents
In `@lib/features/restore/restore_manager.dart`:
- Around line 466-467: Replace the unclear inline comment after the return of
Action.disputeInitiatedByPeer with a concise, clear sentence; for example change
"//No should be used -  Default to peer-initiated" to something like "// Default
to peer-initiated; use 'No' to indicate the dispute was not initiated locally"
so readers understand the intended meaning around the 'No' value and the default
behavior for Action.disputeInitiatedByPeer.
- Around line 798-800: The call to
ref.read(restoreProgressProvider.notifier).showError('') passes an empty string
so users see no error details; update the restore failure path (where
logger.e(...) is called) to pass a meaningful message or localization key to
showError — for example build a user-facing message using the caught error
(e.toString() or a sanitized message) or a localized string identifier and
include any useful context (e.g., "restoreFailed" or "${loc.restoreFailed}:
${e.toString()}") so the UI displays an actionable error instead of blank text;
ensure you reference the same notifier (restoreProgressProvider.notifier) and
keep logger.e(error: e, stackTrace: stack) unchanged.
🧹 Nitpick comments (1)
lib/features/chat/notifiers/chat_rooms_notifier.dart (1)

53-55: Filtering out empty-message chats could hide legitimate chats during initial load.

The chat.messages.isNotEmpty filter runs synchronously, but ChatRoomNotifier.initialize() loads historical messages asynchronously. If loadChats() or refreshChatList() runs before historical messages finish loading (e.g., during restore), valid chats with messages in storage will be filtered out until the next refresh.

This seems intentional for the restore fix (avoid showing empty shells), and the 10-second delay in restore_manager.dart plus the refreshChatList() call from _onChatEvent should eventually surface them. Just be aware this creates an ordering dependency — if messages load slower than expected, chats won't appear until the next event triggers a refresh.

Also applies to: 88-90

Comment on lines +466 to +467
return Action
.disputeInitiatedByPeer; //No should be used - Default to peer-initiated
Copy link
Contributor

@coderabbitai coderabbitai bot Feb 11, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Comment is unclear: "No should be used" — rephrase.

The comment //No should be used - Default to peer-initiated is grammatically unclear. Consider rephrasing.

-        return Action
-            .disputeInitiatedByPeer; //No should be used -  Default to peer-initiated
+        return Action
+            .disputeInitiatedByPeer; // Should not be used directly — default to peer-initiated
📝 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
return Action
.disputeInitiatedByPeer; //No should be used - Default to peer-initiated
return Action
.disputeInitiatedByPeer; // Should not be used directly — default to peer-initiated
🤖 Prompt for AI Agents
In `@lib/features/restore/restore_manager.dart` around lines 466 - 467, Replace
the unclear inline comment after the return of Action.disputeInitiatedByPeer
with a concise, clear sentence; for example change "//No should be used - 
Default to peer-initiated" to something like "// Default to peer-initiated; use
'No' to indicate the dispute was not initiated locally" so readers understand
the intended meaning around the 'No' value and the default behavior for
Action.disputeInitiatedByPeer.

Copy link
Member Author

@BraCR10 BraCR10 Feb 11, 2026

Choose a reason for hiding this comment

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

Please omit this typo

Copy link
Contributor

Choose a reason for hiding this comment

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

@BraCR10, understood — I'll skip this one. Feel free to reach out if you need anything else! 👍

@BraCR10
Copy link
Member Author

BraCR10 commented Feb 11, 2026

Hola @Catrya, ¡gracias por el feedback!

Revisé el flujo normal en la rama main antes de aplicar el restore, y noté que el comportamiento es el siguiente:

  • Los chats se listan hasta que alguna de las partes inicia la conversación; si el chat está vacío, no se lista.
  • Los chats en estado success no desaparecen: siguen activos incluso si el trade ya finalizó.

En este commit:
d87ab12
lo que procuré fue eliminar todos los chats en memoria antes de empezar el restore.

La idea principal es que, al hacer restore, solo se creen las suscripciones a los chats correspondientes a las sessions que el backend envió para ser restablecidas. Por otra parte:

  • Todos los chats con contenido se listarán en la sección de chats.
  • Los chats vacíos no se listarán, ya que deben ser iniciados por alguna de las partes desde la pantalla de trade, para respetar el comportamiento original.

Por mi parte lo he probando con múltiples ordenes y funciona sin presentar problemas.
Por favor, pruébalo y me confirmas si el issue persiste o si aparece algún otro problema. En caso de que sí, te agradecería si puedes revisar los logs de mostrod para descartar que esté enviando sesiones antiguas o en estado success pues como mencione en teoria el proceso de restore solo debe restaurar chats,disputas y sessions que mostrod proporciona . Hasta donde recuerdo, mostrod no debería retornar sessions en estado success porque ya están terminadas.

Copy link
Collaborator

@mostronator mostronator left a comment

Choose a reason for hiding this comment

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

✅ Approved — Critical fix for #372 (High Priority)

Problem solved

Chat messages were empty after first-time restore on a new device due to missing chat subscription initialization and Peer object creation during restore.

Review

Strengths:

  • Root cause addressed: Initializes chat subscription immediately after saving session during restore — this was the missing piece
  • Proper Peer creation: Creates Peer objects during restore process so chat screens can render correctly
  • Better error handling: New ChatErrorScreen widget with factory constructors for sessionNotFound and peerUnavailable — clean pattern
  • Cleanup of legacy code: Removed fallback query in ChatRoomNotifier that searched all chat events when order_id filter returned nothing — this was masking bugs
  • Chat list filtering: Only showing chats with messages (.where((chat) => chat.messages.isNotEmpty)) prevents the UI glitch from #379
  • Complete i18n: Error screen strings in all 3 languages

Minor observations (non-blocking):

  • The Future.delayed(Duration(milliseconds: 100)) in refreshChatList is a code smell — consider using a proper event/callback mechanism in the future
  • _clearAll() now clears chat providers before storage — good ordering

This fixes a high-priority bug with a solid approach. Well done! 🎉

Copy link
Member

@Catrya Catrya left a comment

Choose a reason for hiding this comment

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

tACK

@grunch
Copy link
Member

grunch commented Feb 11, 2026

@BraCR10 please fix conflicts

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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
lib/features/restore/restore_manager.dart (1)

656-656: ⚠️ Potential issue | 🟡 Minor

Typo: "IMPORTAN" → "IMPORTANT".

-          // IMPORTAN : we need to create new message due to synchronization with stored messages
+          // IMPORTANT: we need to create new message due to synchronization with stored messages

@BraCR10
Copy link
Member Author

BraCR10 commented Feb 12, 2026

@grunch Conflicts fixed!

Copy link
Member

@grunch grunch left a comment

Choose a reason for hiding this comment

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

LGTM

@grunch grunch merged commit 2de581f into main Feb 12, 2026
2 checks passed
@grunch grunch deleted the fix/ErrorChatRestoring branch February 12, 2026 19:07
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.

4 participants