Skip to content

πŸ”„οΈ Improve unread marker display - #6484

Open
AndyScherzinger wants to merge 6 commits into
masterfrom
feat/noid/msgUnreadMarker
Open

πŸ”„οΈ Improve unread marker display#6484
AndyScherzinger wants to merge 6 commits into
masterfrom
feat/noid/msgUnreadMarker

Conversation

@AndyScherzinger

@AndyScherzinger AndyScherzinger commented Aug 12, 2026

Copy link
Copy Markdown
Member

When entering a conversation, especially when using #6454 the read-state is not always correct / read / propagated.

This PR addresses this, implementing read-status propagation

🏁 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 enhancement New feature or request 2. developing Work in progress labels Aug 12, 2026
@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/msgPreFetching branch from f978b99 to 1a1f664 Compare August 13, 2026 15:07
@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/msgUnreadMarker branch from 74641aa to f0bc26d Compare August 13, 2026 21:42
@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/msgPreFetching branch from 1a1f664 to 3f6a24d Compare August 13, 2026 21:43
@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/msgUnreadMarker branch from f0bc26d to a137536 Compare August 13, 2026 21:43
@AndyScherzinger AndyScherzinger added 3. to review Waiting for reviews AI assisted and removed 2. developing Work in progress labels Aug 13, 2026
@AndyScherzinger AndyScherzinger added this to the 25.0.0 milestone Aug 13, 2026
@AndyScherzinger
AndyScherzinger requested a review from mahibi August 13, 2026 21:47
@AndyScherzinger
AndyScherzinger marked this pull request as ready for review August 13, 2026 21:47
@AndyScherzinger AndyScherzinger changed the title Improve unread marker πŸ”„οΈ Improve unread marker Aug 14, 2026
@AndyScherzinger AndyScherzinger changed the title πŸ”„οΈ Improve unread marker πŸ”„οΈ Improve unread marker display Aug 14, 2026
Base automatically changed from feat/noid/msgPreFetching to master August 14, 2026 15:44
@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/msgUnreadMarker branch from a137536 to 8c9e228 Compare August 14, 2026 15:47
@github-actions

Copy link
Copy Markdown
Contributor

APK file: https://github.com/nextcloud/talk-android/actions/runs/31816236588/artifacts/9225804811
To test this change/fix you can simply download above APK file and install and test it in parallel to your existing Nextcloud app.
qrcode (please click on link to get QR code displayed)

The unread marker can only be placed correctly when the chat's visible
window - the latest chat block - reaches back to the last read message.
For a room without any cached chat block the catch-up fetched the newest
page, so any backlog larger than one page left a chat block floating
entirely above the unread boundary and the marker ended up pinned to the
oldest message of that block, in the middle of the unread messages.

When the unread backlog is at least one page but still closable within
the backlog rounds, anchor the initial fetch at lastReadMessage
(including the last read message itself) and close the rest of the
backlog from there, so the created chat block contains the boundary.
Smaller backlogs fit into the newest page anyway and oversized backlogs
could not be closed either way, so both keep the newest-messages fetch.

The room list prefetch passes the conversation's lastReadMessage and
unread count along, so background-prefetched rooms open with a window
the marker can be placed in.

Assisted-by: Claude Code:claude-fable-5
Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
The initial load decided the cache was usable when the newest cached
message id was at least the conversation's lastReadMessage. That check
compares against the top of the latest chat block, not its extent: a
block created by a capped newest-messages fetch (e.g. the background
prefetch) floats entirely above the unread boundary and trivially
passes, so the open path only closed the backlog above the block and
the unread marker stayed pinned to the block's oldest message, in the
middle of the unread messages.

Decide on containment instead: the cache is only trusted when the
latest chat block reaches back to lastReadMessage (or has no history
below it). Otherwise the initial window is re-fetched via
initialCatchUp, anchored at the unread boundary when the backlog is
large.

This also changes the handling of a cache whose latest block lies
completely below lastReadMessage (read further on another device):
instead of fetching the newest page into a floating block, the backlog
is closed from the newest cached message, keeping the window contiguous
across the boundary.

Assisted-by: Claude Code:claude-fable-5
Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
buildChatItems latched firstUnreadMessageId on the first emission as
"the first visible message newer than lastReadMessage". When the
visible window did not reach back to the last read message - all
visible messages unread - this resolved to the window's oldest message,
far above the true boundary, and the cached value kept the marker there
even after scrolling up loaded the older unread messages.

Only latch the marker when a message at or below lastReadMessage is
visible, proving the boundary is inside the window. Until then no
marker is shown instead of a wrong one. Temporary messages have
negative ids and don't count as proof.

Assisted-by: Claude Code:claude-fable-5
Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
The catch-up triggered by a push notification fetched the newest page
for rooms without any cached chat block, so a large unread backlog left
a chat block floating above the unread boundary β€” the same window shape
that misplaces the unread marker on chat open.

Look up the pushed room in the local conversations cache and pass its
lastReadMessage and unread count to catchUpRoom, so the initial fetch
is anchored at the boundary when the backlog calls for it. The boundary
is room-level state and therefore not passed for thread catch-ups.

Assisted-by: Claude Code:claude-fable-5
Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
Covers loadInitialMessages' choice between trusting the cached window
and re-fetching it: the backlog is closed from the newest cached message
when the latest chat block reaches the last read message (or has no
history below it), while a block floating above the boundary and an
empty cache are repaired with a fetch anchored at lastReadMessage for
large backlogs and a newest-messages fetch for small ones.

Assisted-by: Claude Code:claude-fable-5
Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
Extracts the latch condition from buildChatItems into the pure
findFirstUnreadMessageId (no behavior change) and covers it: the marker
position is only derived when a message at or below lastReadMessage is
visible, windows floating entirely above the boundary and temporary
messages with negative ids yield no marker, and a deleted or expired
boundary message is handled by any older visible message.

Assisted-by: Claude Code:claude-fable-5
Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/msgUnreadMarker branch from 8c9e228 to 4f75c5e Compare August 14, 2026 17:22
@github-actions

Copy link
Copy Markdown
Contributor

APK file: https://github.com/nextcloud/talk-android/actions/runs/31823716011/artifacts/9228623568
To test this change/fix you can simply download above APK file and install and test it in parallel to your existing Nextcloud app.
qrcode (please click on link to get QR code displayed)

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