Skip to content

Add room sync controls with polished room server status UI#172

Open
Specter242 wants to merge 9 commits intozjs81:mainfrom
Specter242:feature/room-sync-controls
Open

Add room sync controls with polished room server status UI#172
Specter242 wants to merge 9 commits intozjs81:mainfrom
Specter242:feature/room-sync-controls

Conversation

@Specter242
Copy link
Contributor

@Specter242 Specter242 commented Feb 14, 2026

Summary

  • Adds room sync service integration with per-room auto-sync controls and room status visibility.
  • Corrects room status rendering by using explicit status kinds instead of string matching.
  • Removes the redundant room status legend from Contacts to reduce clutter and rely on per-contact status text.

UI/UX polish included

  • Fixes false green status for rooms not logged in.
  • Uses consistent status color mapping based on typed status (synced, syncing, stale/waiting, disabled/not logged in).
  • Keeps room status clear directly on each room contact row.

Test plan

  • dart format on changed files
  • flutter analyze
  • Android build/install (flutter build apk --debug + adb install -r)
  • iOS test (not run: iOS device/environment unavailable)

Introduce app-side room auto-sync orchestration with per-room enablement, sync status indicators, and configurable timing controls so users can keep only selected room servers up to date.

Co-authored-by: Cursor <cursoragent@cursor.com>
@Specter242
Copy link
Contributor Author

Quick validation checklist for reviewers:

  • Open App Settings -> Room Sync and verify global toggles + numeric controls persist after app restart.
  • In Contacts, confirm room status legend appears when room servers are present.
  • For a room contact, open options and toggle Auto-sync this room; verify status reflects enable/disable state.
  • Open a room chat and confirm subtitle includes room sync status.
  • With saved room credentials, verify auto-login/catch-up runs and transitions through expected states (Syncing -> Synced, and Stale when threshold is exceeded).

If helpful, I can also attach short screen recordings for the settings flow and per-room toggle behavior.

@Specter242
Copy link
Contributor Author

Test coverage note: this change set was validated on Android hardware. I was not able to run iOS validation in this environment.

This replaces fragile string-based room sync status coloring with explicit status kinds and removes the redundant contacts legend so room status text remains clear and consistent.

Co-authored-by: Cursor <cursoragent@cursor.com>
@Specter242 Specter242 changed the title Add room sync service with per-room controls and UI status Add room sync controls with polished room server status UI Feb 14, 2026
@446564
Copy link
Collaborator

446564 commented Feb 14, 2026

I will test this out today and review, then move to #173

@Specter242
Copy link
Contributor Author

Pushed an update to :\n\n- Register manual room login in so successful manual room logins mark the room session active and persist login success.\n- Call that registration from immediately after successful login.\n\nThis fixes the status mismatch where a connected/logged-in room could still show as not synced/not logged in until auto-login kicked in.

@Specter242
Copy link
Contributor Author

Pushed an update to feature/room-sync-controls.

Changes:

  • Register manual room login in RoomSyncService so a successful manual room login marks the room session active and persists login success.
  • Call that registration from RoomLoginDialog immediately after a successful login.

Result:

  • Room status now reflects the active logged-in session immediately after manual login, instead of waiting for auto-login/background cycle.

@Specter242
Copy link
Contributor Author

Pushed an update to the PR branch () in commit .

Change included:

  • Treat any non-connected connector state as disconnected in room sync status tracking.
  • Only report room sync states when the transport is actively connected.

This fixes stale status when the device has been out of range and reconnection is still in progress.

@Specter242
Copy link
Contributor Author

Update pushed to PR branch feature/room-sync-controls in commit 151fbb3.

Included fix:

  • Treat any non-connected connector state as disconnected in room sync tracking.
  • Only show Connected room-sync statuses when transport is actively connected.

This addresses stale Connected, synced status after long out-of-range periods while reconnecting.

@Specter242
Copy link
Contributor Author

Specter242 commented Feb 21, 2026

Quick update on room-server sync behavior (focused on low traffic + better state visibility):

  • Tuned room sync defaults to be more conservative (longer interval/max interval, modest timeout/stale window) to reduce routine network load.
  • Changed per-room auto-sync default for newly seen rooms to off, so rooms are not auto-polled until explicitly enabled.
  • Kept UX smooth by auto-enabling room sync after first successful manual room login (for previously unseen rooms).
  • Improved auto-login behavior with burst+jitter pacing and push-triggered sync throttling to avoid traffic spikes.
  • Refined login retry semantics:
    • explicit auth failure stops retrying immediately
    • timeout/transport failure can retry
  • Persisted login metadata from room login responses (server timestamp, ACL permissions, firmware level) for better observability and future policy decisions.
  • Updated room-sync docs and verified with formatter + analyzer (no issues).

…trols

# Conflicts:
#	lib/models/app_settings.dart
#	lib/screens/app_settings_screen.dart
#	lib/screens/chat_screen.dart
#	lib/screens/contacts_screen.dart
#	lib/services/app_settings_service.dart
@ericszimmermann
Copy link
Contributor

ericszimmermann commented Feb 23, 2026

Sorry was meant to be for #173. Please ignore mention for this PR.

@zjs81
Copy link
Owner

zjs81 commented Mar 2, 2026

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ab76c3e261

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +305 to +309
code == respCodeNoMoreMessages ||
code == respCodeContactMsgRecv ||
code == respCodeContactMsgRecvV3 ||
code == respCodeChannelMsgRecv ||
code == respCodeChannelMsgRecvV3;

Choose a reason for hiding this comment

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

P1 Badge Mark sync complete only after end-of-queue response

This treats any incoming message frame as a successful sync cycle, but MeshCoreConnector.syncQueuedMessages() continues fetching until respCodeNoMoreMessages. If a room has multiple queued messages and the transport stalls after the first one, _markSyncSuccess() runs early, cancels the timeout, resets backoff, and updates lastSuccessfulSyncAtMs even though catch-up did not finish, which can incorrectly report rooms as healthy while backlog remains.

Useful? React with 👍 / 👎.

Copy link
Owner

Choose a reason for hiding this comment

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

@Specter242 Can you review this please

Comment on lines +157 to +161
void _onConnected() {
if (!_roomSyncEnabled) return;
_currentInterval = _defaultSyncInterval;
_scheduleNextSync(_defaultSyncInterval);
unawaited(_autoLoginSavedRooms());

Choose a reason for hiding this comment

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

P2 Badge Start room sync when setting is enabled mid-connection

Periodic sync and auto-login are only kicked off from _onConnected(), but this service never subscribes to AppSettingsService changes. In a common flow where a user connects first and then enables "Enable room auto-sync" in settings, no timer or auto-login pass is started until a reconnect/manual trigger occurs, so the new toggle does not take effect during the current session.

Useful? React with 👍 / 👎.

Copy link
Owner

Choose a reason for hiding this comment

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

@Specter242 Can you review this too?

Specter242 and others added 2 commits March 2, 2026 11:35
Address two Codex review items and two UX gaps:

P1 (Codex): _markSyncSuccess() now only fires on respCodeNoMoreMessages.
Intermediate message receipt codes (respCodeContactMsgRecv*, respCodeChannelMsgRecv*)
extend the sync timeout instead, so a large backlog draining does not
cause a premature success or a false timeout failure.

P2 (Codex): RoomSyncService now subscribes to AppSettingsService changes
via _handleSettingsChange(). Enabling room auto-sync while already
connected starts the periodic timer and auto-login immediately;
disabling it cancels both timers. The _lastRoomSyncEnabled flag tracks
the transition so the handler is a no-op when the value has not changed.

Unread badge clearing: markContactRead() for room contacts is now called
at tile-tap time (matching regular contact behaviour) rather than inside
the onLogin callback, so the badge clears consistently even if the user
later cancels the login dialog.

Login dialog bypass: _showRoomLogin() skips the login dialog for the
chat destination when the room already has an active session
(isRoomSessionActive()). The login dialog continues to appear when there
is no active session or when opening Room Management (which needs the
password for admin commands).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Resolved additive conflicts in 5 files:
- lib/main.dart: keep ChatTextScaleService (main) + RoomSyncService (PR)
- lib/models/app_settings.dart: keep mutedChannels (main) + room sync fields (PR)
- lib/services/app_settings_service.dart: keep setBatteryChemistryForRepeater (main) + room sync setters (PR)
- lib/screens/chat_screen.dart: keep chat_zoom_wrapper import (main) + room_sync_service import (PR)
- lib/screens/contacts_screen.dart: keep isFavorite (main) + roomSyncService/isRoomSessionActive (PR)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@Specter242
Copy link
Contributor Author

Changes in this update

Bug fixes (addressing Codex review)

P1 — _markSyncSuccess() fired too early (room_sync_service.dart)
_handleFrame was calling _markSyncSuccess() on any queue-related response code. It now only fires on respCodeNoMoreMessages. For intermediate message codes (respCodeContactMsgRecv, respCodeContactMsgRecvV3, respCodeChannelMsgRecv, respCodeChannelMsgRecvV3), the sync timeout timer is extended instead, so large queue drains no longer risk a false timeout.

P2 — AppSettingsService changes not observed (room_sync_service.dart)
RoomSyncService was not listening to AppSettingsService, so toggling room sync on mid-session had no effect until the next reconnect. A _handleSettingsChange listener is now added in initialize() / removed in dispose(). It detects the false → true transition while connected and immediately kicks off the sync loop and auto-login, and the true → false transition cancels pending timers.

UX improvements

Unread badge clear timing (contacts_screen.dart)
markContactRead is now called when the user taps a room tile, before the login dialog opens. Previously it was only called inside the onLogin callback, so the badge would persist until the password was accepted.

Skip login dialog when already authenticated (contacts_screen.dart, room_sync_service.dart)
When navigating to a room's chat screen, the login dialog is now bypassed if the room already has an active session (isRoomSessionActive()). The dialog is still shown for management navigation (which needs the password for admin commands) and whenever the session has expired or was never established.

Merge

Rebased/merged with origin/main — all conflicts were additive (kept ChatTextScaleService, mutedChannels, isFavorite, setBatteryChemistryForRepeater from main alongside the room sync additions).

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