Skip to content

fix(mobile): read mentions taller than the screen - #9243

Open
blakemcanally wants to merge 2 commits into
mainfrom
bmcanally/mobile-archived-solo-read
Open

blakemcanally wants to merge 2 commits into
mainfrom
bmcanally/mobile-archived-solo-read

Conversation

@blakemcanally

@blakemcanally blakemcanally commented Nov 7, 2026 •

Copy link
Copy Markdown
Contributor

Problem

Bug report (mobile 0.28.0 (46)): opening a mention from the Inbox in an archived Solo chat leaves the Inbox row unread.

The video shows the cause. Each unread row is a long agent answer. On a phone, the answer is taller than the screen, or it lands partly cut off after the deep-link jump. Mobile automatic reading writes a msg: mark only for a row that is fully visible for the 300 ms dwell. A mention row is high priority, so activity:<channel> does not read it. The mention can stay unread until the reader marks it read by hand.

The archived state is not the cause. A widget test shows that an archived Solo chat writes read marks for short messages. Archived chats make the problem easy to see, because there is no composer and the reader only reads.

Fix

  • Bottom catch-up reads mentions (parity with desktop). When the reader reaches the live bottom of a channel, catch-up now also writes a msg: mark for each loaded top-level mention and broadcast through the bottom row. It marks at most the newest 128 unread ones. Messages that the reader marked unread stay unread. This is the rule from fix(unread): read timeline mentions when catching up at the bottom buzz-app#1679 (docs/unread.md: "so a mention taller than the viewport is still read"). In a Solo chat, which shows replies inline, catch-up also marks the reply mentions through the bottom row. Threads and DMs do not change.
  • Tall rows. A row that is taller than the reading area counts as read when it covers the whole reading area for the dwell. This applies to the channel timeline and the thread view. Desktop has no rule for this case, because a desktop window is rarely shorter than a message.

Open question

A deep link places its target at 35% of the list height. A long target can still land cut off. In that case, the reader must scroll until the target fills the screen, or reach the bottom. Do we want the deep-link target to count as read when it is visible? Desktop does not do this, so I left it out.

Tests

  • reading_marks_test.dart: catch-up marks unseen top-level mentions and broadcasts. It skips replies, forced-unread messages, and messages that are already read. It applies the 128 limit to unread mentions only. A jump into history does not mark them. Added isReadableRow cases.
  • channel_detail_page_test.dart: a new regression test opens an archived Solo chat at the bottom, with a mention that is taller than the screen. The test fails on main and passes with this change.
  • channel_detail_page_test.dart: a tall row away from the bottom is read once it fills the screen. A Solo chat reads an inline reply mention at the bottom. Both tests fail on main.
  • The Android keyboard history test now clears the bottom catch-up marks before the jump, because those marks now read every mention.
  • just mobile-check and just mobile-test pass.

Human test steps

  1. Get a long agent reply that mentions you in a Solo chat, then archive the chat.
  2. Open the row from the Inbox. Scroll until the message fills the screen, or scroll to the bottom. Hold still for about one second.
  3. Go back. The row should now show as read, with no dot.

🤖 Generated with Claude Code

Opening an Inbox mention in a Solo chat could leave the row unread: a
long agent answer never fits on a phone screen, and automatic reading
only marked fully visible rows. Bottom catch-up also skipped mentions.

- Bottom catch-up now writes msg: marks for loaded top-level mentions
  and broadcasts through the bottom row (newest 128), as buzz-app does
  since block/buzz-app#1679.
- A row taller than the reading area counts as read once it covers the
  whole area for the dwell.

Co-authored-by: BlakeBot <85bbd70443139fd5c5762e34c2e214240939eb243c37f98380f69fed3b3bb4a6@buzz.block.builderlab.xyz>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Blake McAnally <bmcanally@squareup.com>
A Solo chat shows replies inline, so bottom catch-up there also marks
reply mentions through the bottom row. Adds widget tests for that and
for a tall row read away from the bottom.

Co-authored-by: BlakeBot <85bbd70443139fd5c5762e34c2e214240939eb243c37f98380f69fed3b3bb4a6@buzz.block.builderlab.xyz>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Blake McAnally <bmcanally@squareup.com>
@blakemcanally

blakemcanally commented Nov 7, 2026 •

Copy link
Copy Markdown
Contributor Author

🤖 Reviewer guide

Where to look

  • mobile/lib/features/channels/reading_marks.dart contains the whole rule change. Bottom catch-up now adds msg: marks for mentions and broadcasts. The flat flag lets a Solo chat include inline replies. isReadableRow adds the rule that a row which covers the whole screen counts as read.
  • message_list.dart and thread_detail_page.dart only switch the visibility check to isReadableRow.
  • The desktop reference is buzz-app docs/unread.md ("Away from the bottom…") and fix(unread): read timeline mentions when catching up at the bottom buzz-app#1679. Mobile matches it, except for two items: the cover rule and the flat Solo case. Desktop does not need them.

Evidence: regression tests that fail on main and pass on this branch

Test (channel_detail_page_test.dart) main this PR
reading the bottom of an archived Solo chat reads a tall mention ❌ msg:tall missing ✅
a tall row away from the bottom is read once it fills the screen ❌ no marks ✅
reading the bottom of a Solo chat reads an inline reply mention ❌ msg:tall-reply missing ✅

To run them:

cd mobile && flutter test test/features/channels/channel_detail_page_test.dart --plain-name "tall"
flutter test test/features/channels/channel_detail_page_test.dart --plain-name "inline reply mention"
flutter test test/features/channels/reading_marks_test.dart

just mobile-check and just mobile-test pass on 5e1e35b (4549 tests).

Behavior change to check: Reaching the bottom of a channel now reads every loaded top-level mention above it, up to the newest 128. Before this change, a mention stayed unread until its row was fully on screen. Messages that the reader marked unread stay unread.

Media: I did not attach the original bug recording or any screenshots. The recording shows internal conversations, and this repository is public. To reproduce on a device, open a long agent reply that mentions you in a Solo chat from the Inbox. On main, the row stays unread. With this PR, the row becomes read after you scroll until the reply fills the screen, or after you scroll to the bottom.

Comment written by BlakeBot, the AI agent of bmcanally.

@blakemcanally
blakemcanally marked this pull request as ready for review November 7, 2026 18:57
@blakemcanally
blakemcanally requested a review from a team as a code owner November 7, 2026 18:57
@blakemcanally
blakemcanally requested a review from brow November 7, 2026 18:57
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 7, 2026 •

Copy link
Copy Markdown
Codex Review Summary: ✅ Completed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-07T19:00:25.143489Z 5e1e35b Draft marked ready
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@github-actions github-actions Bot added the codex-security-review-current The posted Codex security review matches its recorded range. label Nov 7, 2026
@github-actions

github-actions Bot commented Nov 7, 2026

Copy link
Copy Markdown

🔐 Codex Security Review

Note: This is an automated, security-focused review generated by Codex.
Use it as a supplement to human review; false positives are possible.

Scope

  • Exact PR diff: f3b127e3af5c14d2314faa2b63556c3f51ec6743...5e1e35b90323bce9ed6577f388248b53a3eeaa37
  • Model: gpt-6.1-sol

💡 Click "edited" above to see earlier reviews for this PR.


Review Summary

Overall Risk: NONE

No concrete security, correctness, or reliability regressions found in the mobile read-tracking changes.

Findings

No concrete security, correctness, or reliability findings were identified.

Notes

  • Review was limited to read-only source, test, and history inspection. Builds and tests were not executed.

Generated by Codex Security Review |
Requested by: @blakemcanally |
Workflow run

This branch was successfully deployed

1 active deployment
codex-review — 5e1e35b9 Deployed Nov 7, 2026 by blakemcanally via Run Codex Security Review #13771
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

codex-security-review-current The posted Codex security review matches its recorded range.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants