Skip to content

Refresh the conversation list while it is open - #6746

Draft
AndyScherzinger wants to merge 2 commits into
feat/noid/conversation-list-background-syncfrom
feat/noid/conversation-list-foreground-sync
Draft

AndyScherzinger wants to merge 2 commits into
feat/noid/conversation-list-background-syncfrom
feat/noid/conversation-list-foreground-sync

Conversation

@AndyScherzinger

@AndyScherzinger AndyScherzinger commented Sep 21, 2026

Copy link
Copy Markdown
Member

Stacked on #6745, which is stacked on #6744. Review those first — their commits appear here until they merge.

With the list open, a message sent from another device only shows up when a push arrives or the user leaves and comes back. This adds the 30-second refresh timer iOS has, which matters most for the people who have no working push at all — no Play Services, no UnifiedPush distributor — for whom this becomes the only freshness mechanism the list has.

What it does

  • A loop bound to the resumed lifecycle, so it cannot run behind the screen or outlive it. It waits before the first sync rather than after: onResume already fetches, and syncing on entry would fetch twice on every resume.
  • Ticks are dropped while a sync is already in flight, so the loop can never queue behind itself, and while a search is open, so the list is not swapped out from under what the user is reading.
  • Every tick is a delta sync. Without #6744 this would be a full room list every 30 seconds.

What a reviewer should push back on

  • Two guards, not four. Being offline is already handled one layer down, where the sync returns without a request; battery saver already stops the expensive half, the message catch-up. Adding either here would only duplicate a check that exists.
  • User status dots refresh every 5 minutes, not every 30 seconds. Delta syncs drop includeStatus, because with it the server returns every one-to-one room regardless of modifiedSince and most of the saving disappears. iOS keeps status fresher here; this trades that for the request volume.
  • Accessibility: the tick reuses the existing silent sync path and introduces no animation and no focus change. Worth a TalkBack pass with focus parked mid-list.

Not in this PR

  • A full refresh on delete / disinvite signaling messages, which would let the five-minute rule relax.

🚧 TODO

  • TalkBack pass: focus parked mid-list across several ticks
  • Manual: list open on device A, message from device B, appears within ~30 s

🏁 Checklist

  • ⛑️ Tests (unit and/or integration) are included or not needed
  • 🔖 Capability is checked or not needed
  • 🔙 Backport requests are created or not needed: /backport to stable-xx.x
  • 📅 Milestone is set
  • 🌸 PR title is meaningful (if it should be in the changelog: is it meaningful to users?)

🤖 AI (if applicable)

  • The content of this PR was partly or fully generated using AI

@AndyScherzinger AndyScherzinger added this to the 25.1.0 milestone Sep 21, 2026
With the list on screen, a message sent from another device shows up
only when a push arrives or the user leaves the screen and comes back.
That gap matters most for the people who have no working push at all -
no Play Services, no UnifiedPush distributor - for whom nothing else
refreshes the list while they are looking at it.

Re-sync it every thirty seconds instead, matching the iOS timer. The
loop is bound to the resumed lifecycle, so it cannot run behind the
screen or outlive it, and it waits before the first sync rather than
after: onResume already fetches, and syncing on entering the loop would
fetch twice every time the screen is resumed.

A tick is dropped while a sync is already in flight, so the loop can
never queue behind itself, and while a search is open, where swapping
the list out would move what the user is reading. Being offline and
battery saver are deliberately not checked here: the first is already
handled where the sync would make its request, and the second already
stops the expensive half, the message catch-up it triggers.

Every tick asks only for what changed, which is what makes a timer this
short affordable at all.

Assisted-by: Claude Code:claude-opus-5
Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
The loop fires whatever else is going on, so what decides whether the
list stays usable is when a tick is dropped: one that is not dropped
while a sync is running queues requests behind each other, and one that
is not dropped during a search swaps the list out from under what the
user is reading.

The two cases pin each other down. A tick during an in-flight sync must
leave the call count at one, and a tick after the previous sync finished
must take it to two, so neither dropping every tick nor dropping none of
them passes both.

Assisted-by: Claude Code:claude-opus-5
Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/conversation-list-background-sync branch from abc0d72 to 7d19a5c Compare September 21, 2026 20:23
@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/conversation-list-foreground-sync branch from 008bbaf to e931686 Compare September 21, 2026 20:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant