Skip to content

Mark message prefetch requests and let the server turn preloading off - #6763

Merged
mahibi merged 3 commits into
masterfrom
feat/noid/mark-prefetch-requests
Oct 12, 2026
Merged

mahibi merged 3 commits into
masterfrom
feat/noid/mark-prefetch-requests

Conversation

@AndyScherzinger

@AndyScherzinger AndyScherzinger commented Sep 23, 2026 •

Copy link
Copy Markdown
Member

The rest of this series is merged — #6744 (modifiedSince delta sync), #6745 (periodic background refresh) and #6746 (foreground refresh loop) — so this one targets master and stands on its own.

The client fetches a conversation's messages before the user asks for them — after a push notification, and after a conversation list sync. On the wire those requests look exactly like the ones a user staring at a chat screen is waiting for, and the server has no way to say it would rather the client didn't make them at all.

Two commits, each answering one half of that, plus one unrelated note to AGENTS.md.

prefetch=1 on the requests the catch-up makes

A query parameter rather than a header, so it lands in a standard access log without any server configuration. Verified against a live server: the response is byte for byte the one sent without it, so the parameter is inert and purely descriptive.

The flag travels the same route as markNotificationsAsRead, which already separates these two cases, and defaults to false. The helpers that build the request are shared with the chat the user has open (OfflineFirstChatRepository calls buildFieldMap too), so a flag set any higher up would have labelled the messages someone is actively reading as prefetched — inverting the distinction this exists to draw. There is a test for exactly that.

The mobile-preload-chat capability

Implements the client side of spreed#19509. Preloading is skipped only when the server reports the setting as false. A server that reports true, one that omits it, and one too old to know it at all all preload — an operator cannot have declined something they were never offered.

Checked at both entry points, mirroring how chat-keep-notifications is already handled: the conversation list skips the whole catch-up rather than asking room by room, and the syncer checks it too, because push notifications reach it without passing the list.

AGENTS.md: spotting a test that asserts nothing

Separate from the feature, and in its own commit so it can be dropped without touching the rest. Review on this series found three tests that passed while never reaching the code they named — an earlier guard returned first, so the assertion was never evaluated, and running the suite cannot tell that apart from a test that works. The two habits that do catch it are now written down: check that a new test fails without its fix, and take the fixture from the code path while the assertion still comes from the requirement.

Scope

Only message preloading. The conversation list sync is not gated: the capability is about chat messages, and an operator turning message preloading off has not asked for unread counts to go stale.

🚧 TODO

  • Verify the false path against a server that reports the capability — the test instance predates spreed#19509, so only the absent case could be exercised live

🏁 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 23, 2026
@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/conversation-list-foreground-sync branch from 1c54f14 to d1cf526 Compare September 23, 2026 14:21
@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/mark-prefetch-requests branch from 251d2a5 to 657f4d1 Compare September 23, 2026 14:21
@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/conversation-list-foreground-sync branch from d1cf526 to 61d24d9 Compare September 23, 2026 15:12
@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/mark-prefetch-requests branch from 657f4d1 to 7e7827c Compare September 23, 2026 15:12
@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/conversation-list-foreground-sync branch from 61d24d9 to 6cbc0f4 Compare September 24, 2026 06:09
@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/mark-prefetch-requests branch from 7e7827c to 7b03e5c Compare September 24, 2026 06:09
@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/conversation-list-foreground-sync branch from 6cbc0f4 to e314853 Compare September 24, 2026 08:29
@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/mark-prefetch-requests branch from 7b03e5c to 6ac16cc Compare September 24, 2026 08:29
@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/conversation-list-foreground-sync branch from e314853 to 79bbdf7 Compare September 24, 2026 14:43
@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/mark-prefetch-requests branch from 6ac16cc to 921f65a Compare September 24, 2026 14:43
@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/conversation-list-foreground-sync branch from 79bbdf7 to d6f1aeb Compare September 24, 2026 16:33
@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/mark-prefetch-requests branch from 921f65a to adc4b8c Compare September 24, 2026 16:33
@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/conversation-list-foreground-sync branch from d6f1aeb to f7eb4c3 Compare September 24, 2026 16:59
@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/mark-prefetch-requests branch from adc4b8c to 9877751 Compare September 24, 2026 16:59
@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/conversation-list-foreground-sync branch from f7eb4c3 to 68a5808 Compare September 25, 2026 06:35
@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/mark-prefetch-requests branch from 9877751 to da749fb Compare September 25, 2026 06:35
@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/conversation-list-foreground-sync branch from 68a5808 to 113755a Compare September 25, 2026 09:53
@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/mark-prefetch-requests branch from da749fb to 35b45fc Compare September 25, 2026 09:53
@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/conversation-list-foreground-sync branch from 113755a to ce13671 Compare September 25, 2026 10:15
@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/mark-prefetch-requests branch from 35b45fc to ac15baf Compare September 25, 2026 10:15
@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/conversation-list-foreground-sync branch from ce13671 to 697f4dc Compare September 27, 2026 17:30
@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/mark-prefetch-requests branch from ac15baf to 232f8f3 Compare September 27, 2026 17:30
@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/conversation-list-foreground-sync branch from 697f4dc to cb81f11 Compare September 27, 2026 21:45
@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/mark-prefetch-requests branch from 232f8f3 to 73ff085 Compare September 27, 2026 21:45
@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/mark-prefetch-requests branch from bb9ab2c to 4265639 Compare October 2, 2026 17:02
@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/conversation-list-foreground-sync branch from 66b34e9 to 4ac0f98 Compare October 4, 2026 08:36
@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/mark-prefetch-requests branch from 4265639 to 6f9ce45 Compare October 4, 2026 08:36
@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/conversation-list-foreground-sync branch from 4ac0f98 to dd6512e Compare October 5, 2026 22:31
@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/mark-prefetch-requests branch from 6f9ce45 to 7dc5a9f Compare October 5, 2026 22:31
@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/conversation-list-foreground-sync branch from dd6512e to cce7913 Compare October 6, 2026 05:50
@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/mark-prefetch-requests branch from 7dc5a9f to b029e76 Compare October 6, 2026 05:50
@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/conversation-list-foreground-sync branch from cce7913 to f880b1f Compare October 6, 2026 08:25
@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/mark-prefetch-requests branch from b029e76 to d6ec8c2 Compare October 6, 2026 08:25
@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/conversation-list-foreground-sync branch from f880b1f to 5bc53f9 Compare October 6, 2026 09:01
@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/mark-prefetch-requests branch from d6ec8c2 to 6b4557c Compare October 6, 2026 09:01
@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/conversation-list-foreground-sync branch from 5bc53f9 to e04abd6 Compare October 6, 2026 19:35
@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/mark-prefetch-requests branch from 6b4557c to 6405470 Compare October 6, 2026 19:35
@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/conversation-list-foreground-sync branch from e04abd6 to 5fc7b3c Compare October 6, 2026 19:50
@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/mark-prefetch-requests branch from 6405470 to 4e71eaa Compare October 6, 2026 19:50
@mahibi
mahibi force-pushed the feat/noid/conversation-list-foreground-sync branch from 5fc7b3c to 621cac5 Compare October 7, 2026 14:06
Base automatically changed from feat/noid/conversation-list-foreground-sync to master October 7, 2026 15:55
@coderabbitai

coderabbitai Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

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

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 7439b1ee-816d-4f00-aebb-57ef54b2458c

📥 Commits

Reviewing files that changed from the base of the PR and between cef0d6e and 56943c4.


📒 Files selected for processing (1)
  • AGENTS.md

🚧 Files skipped from review as they are similar to previous changes (1)
  • AGENTS.md

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 2 remain after this review.



📝 Walkthrough
📝 Walkthrough
📝 Walkthrough
📝 Walkthrough
📝 Walkthrough
📝 Walkthrough

Walkthrough

Chat catch-up skips when the server lacks the chat-keep-notifications capability or explicitly disables mobile chat preloading. The preload check allows catch-up when the setting is absent. Catch-up requests can include prefetch=1, and the option propagates through initial, anchored, backlog, and fallback requests. Background room catch-up enables prefetch for delta and initial fetches. Tests cover request fields and preload settings.


Priority: ⬇️ Low

Merge Risk: 🔵 Low · up to 56943

The change adds a prefetch marker and a server capability check for chat preloading. The remaining concern is a minor, previously raised race that could allow an unwanted room refresh, so the merge risk is low.

Pre-merge checks | Passed 4 | Failed 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 32.56% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 43 functions across 8 files. (1 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Title check Passed The title clearly and concisely summarizes both main changes: marking message prefetch requests and allowing the server to disable preloading.
Description check Passed The description is detailed and covers the implementation, scope, testing, capability behavior, TODO, checklist, and AI usage. The screenshots section is omitted, but it is not critical for this backe…

Full details: Docstring Coverage

Explanation

Docstring coverage is 32.56% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 43 functions across 8 files. (1 skipped: 1 unsupported.)


  • Fix all pre-merge checks with AI
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2


ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 8e787c2b-5dab-4d84-b568-3b08dc343ed7
📥 Commits

Reviewing files that changed from the base of the PR and between dc6189e and 4e71eaa.

📒 Files selected for processing (8)
  • app/src/main/java/com/nextcloud/talk/chat/data/network/ChatMessageSyncer.kt
  • app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt
  • app/src/main/java/com/nextcloud/talk/conversationlist/data/OfflineConversationsRepository.kt
  • app/src/main/java/com/nextcloud/talk/conversationlist/data/network/OfflineFirstConversationsRepository.kt
  • app/src/main/java/com/nextcloud/talk/conversationlist/viewmodels/ConversationsListViewModel.kt
  • app/src/main/java/com/nextcloud/talk/utils/CapabilitiesUtil.kt
  • app/src/test/java/com/nextcloud/talk/chat/data/network/ChatMessageSyncerTest.kt
  • app/src/test/java/com/nextcloud/talk/conversationlist/viewmodels/ConversationsListViewModelForegroundRefreshTest.kt

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 3 remain after this review.

Comment thread app/src/test/java/com/nextcloud/talk/chat/data/network/ChatMessageSyncerTest.kt Outdated
@github-actions

github-actions Bot commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

📱 QA build

Download app-qa-debug.apk
QR code Open the QR code for this download
Commit 0930de4
Version 6763
Available until 7 days after this build

The QA build installs alongside a released Nextcloud app, so you can keep
using your existing install while testing.

Downloading the file requires a GitHub account, so open this link on the
device you want to test on, or transfer the APK to it.

@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/mark-prefetch-requests branch from 1aaa68d to e42062b Compare October 10, 2026 16:08

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (1)

🟡 Minor · Assert prefetch for the never-opened-room request. · ChatMessageSyncerTest.kt:283-302

app/src/test/java/com/nextcloud/talk/chat/data/network/ChatMessageSyncerTest.kt:283-302
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Assert prefetch for the never-opened-room request.

When newestMessageIdFromChatBlocks returns 0, catchUpRoom selects the background initialCatchUp path and passes prefetch = true. The request builder encodes this value as 1. This fixture captures that request but does not assert prefetch, so removing or mis-passing the argument would leave the test passing without its fix.

Suggested fix
             assertEquals(0, fieldMapCaptor.firstValue["markNotificationsAsRead"])
+            assertEquals(1, fieldMapCaptor.firstValue["prefetch"])

ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: f6cfa391-91e8-4e00-8211-362d1320806d
📥 Commits

Reviewing files that changed from the base of the PR and between e42062b and cef0d6e.

📒 Files selected for processing (1)
  • AGENTS.md

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 0 remain after this review.

Comment thread AGENTS.md Outdated
@github-actions

Copy link
Copy Markdown
Contributor

Codacy

Lint

TypemasterPR
Warnings138138
Errors1515

SpotBugs

CategoryBaseNew
Bad practice77
Correctness1111
Dodgy code4040
Internationalization33
Malicious code vulnerability33
Performance88
Security1111
Total8383

The client fetches a room's messages before the user asks for them, from
a push notification and after a conversation list sync, and on the wire
those requests are indistinguishable from the ones a user waiting on a
chat screen is making. A server operator looking at request volume
cannot tell what was speculative and what someone was waiting for.

Send prefetch=1 on the chat requests the catch-up makes. The server
ignores the parameter - the response is byte for byte the one it sends
without it - so this only makes the traffic legible in an access log,
where a query parameter needs no configuration to be recorded.

The flag travels the same route as markNotificationsAsRead, which
already separates these two cases, and defaults to false: the helpers
that build the request are shared with the chat the user has open, and
labelling those as prefetched would invert the very distinction this is
for.

Assisted-by: Claude Code:claude-opus-5
Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
Preloading a conversation's messages before the user opens it spends
the server's bandwidth on traffic nobody asked for yet. An operator who
would rather not pay that can now say so: the mobile-preload-chat
setting turns it off for mobile clients, and the server reports it in
the chat config capabilities.

Skip the catch-up when the server reports it as false. Anything else
preloads - a server that reports it true, and a server too old to know
the setting at all, which cannot mean the operator declined something
they were never offered.

Both entry points check it. The conversation list skips the whole
catch-up rather than asking room by room, and the syncer checks it too,
because push notifications reach it without passing the list.

Assisted-by: Claude Code:claude-opus-5
Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
Three tests in recent work passed while never reaching the code they
named: an earlier guard returned first, so the assertion was never
evaluated. Running the suite cannot distinguish that from a test that
works, and review caught all three rather than CI. Write down the two
habits that do catch it: check a new test fails without its fix, and
take the fixture from the code path while the assertion still comes
from the requirement.

Drop the maxIssues figure from the detekt entry rather than correcting
it. It claimed 80 against a real 114, and two attempts at describing
the budget in prose were both wrong about when it fails. The other
entries in that section only say where the config lives; this one now
does the same and leaves the numbers to detekt.yml, which cannot go
stale against itself.

Assisted-by: Claude Code:claude-opus-5
Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

3. to review Waiting for reviews AI assisted

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants