mirror of
https://github.com/block/buzz.git
synced 2026-11-05 00:41:28 +00:00
codex/buzz-271-draft-prep
3 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
2fd5c122e8 |
fix(mobile): load earlier edits to thread replies when a thread opens (#8870)
## Summary In the mobile thread view, if a reply was edited before you opened the thread, the reply showed its original text and no "(edited)" marker. An edit that arrived while the thread was open worked. The thread `/query` asked only for message kinds. The channel window carries edits, reactions and deletions (aux events) only for top-level messages, so an earlier edit to a reply was in neither result. The thread query now sends `include_aux: true`, as desktop does (`buzz-app` `src/features/relay/threads.ts`). The relay already supports this on the `depth_limit` thread route: it returns the aux events for the root and every reply, plus deletions of those (`crates/buzz-relay/src/api/bridge.rs`, `bridge_thread_aux`). A relay that ignores the flag gives the same result as before. The relay sends a page's rows (at most 200 reply-marked events, of any kind) before that page's aux events. It also repeats the root's aux on every page. So `fetchCompleteThread` treats the leading run of events reply-marked into this thread, other than reactions and NIP-09 deletions, as the page's rows. Only rows count toward a page, move the cursor and feed the reply cache. A reply-marked huddle event still fills a page, and a reply-marked reaction never becomes a reply. A reply-marked edit of the root in the repeated aux can follow a short final page's rows and look like a full page, so the scan also stops when the next cursor does not advance. The thread-summary scan (`fetchCompleteThreadReplies`) still asks for replies only and pages exactly as on `main`. ### Related issue Found during the emulator testing of https://github.com/block/buzz/pull/8863. ### Testing - `just mobile-check`, `just file-size-check` and `just mobile-test` pass. - `thread_replies_provider_test.dart` adds two tests. The first checks that the query sends `include_aux` and that an edit made before the thread opens folds into its reply. The second covers pagination: a reply-marked huddle row filling a page, a reply-marked edit that is a row on one page and aux on the others, a reply-marked reaction that stays aux, 200 reply-marked reactions after 199 replies (one query), 200 reply-marked root edits after a short final page (the progress guard ends the scan), an edit reply-marked into another thread that stays aux, and that the summary scan doesn't send `include_aux`. It fails if any of these is removed: the reaction/deletion exclusion, the root check, the 200 cap, the progress guard, or the separate row and aux id sets. - `channel_detail_page_test.dart` adds a journey: it opens `ThreadDetailPage` with the real thread query and a fake relay session that sends the reply's earlier edit only when `include_aux` is set. It checks the edited text, that the original text is gone, and the marker. It fails when the flag is removed or when the provider drops aux. - Android emulator (AVD, debug build) against a local relay. Morty posts "Who can review the release notes?", Demo User replies "I can, after lunhc" and then edits the reply to "I can, after lunch", all before the thread is opened. These shots come from the first revision of this branch. The pagination changes after it give the same result for a one-page thread like this one. | Before (unfixed: the #8863 build) | After (this branch) | Live edit while the thread is open | | --- | --- | --- | | <img src="https://raw.githubusercontent.com/block/buzz/4daefdf9a427c66dd80edcc59ee664c1da63824c/pr-8870--thread-before.png" width="300" alt="Before: original reply text, no marker"> | <img src="https://raw.githubusercontent.com/block/buzz/4daefdf9a427c66dd80edcc59ee664c1da63824c/pr-8870--thread-after.png" width="300" alt="After: edited reply text with (edited)"> | <img src="https://raw.githubusercontent.com/block/buzz/4daefdf9a427c66dd80edcc59ee664c1da63824c/pr-8870--thread-live.png" width="300" alt="Live edit while the thread is open"> | Before, the thread shows the original reply text with no marker. After, it shows the edited text and "(edited)". A live edit still lands. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Signed-off-by: Logan Johnson <loganj@squareup.com> Co-authored-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
8222e99915 |
fix(mobile): keep thread references consistent across push and Inbox (#8332)
Follow-up to [#8294](https://github.com/block/buzz/pull/8294). Malformed trailing thread tags could make a notification open the right thread while Flutter indexed its reply elsewhere; uppercase references could similarly miss lowercase event IDs. Share one validated thread-reference parser between the mobile timeline, Inbox, and feed helper. It ignores malformed markers, keeps the last valid root/reply, and normalizes lookup IDs to lowercase. Native push parsing now uses the same casing. Existing thread fixtures use valid event IDs so they continue exercising real thread relationships. Add RunnerTests coverage for the production native-to-Flutter argument conversion, including buffered cold-start navigation and omitted optional thread IDs, and run it in the native CI lane. ### Validation - New parser and Inbox regressions cover malformed markers and uppercase references. Widget regressions open and highlight the exact reply for valid, uppercase, and trailing-malformed tags. - After integrating [#8106](https://github.com/block/buzz/pull/8106), Flutter analysis and the complete mobile suite pass: 3,337 tests, four existing skips. Integration preserves per-event read predicates and migrates incoming thread fixtures to valid IDs. An unchanged keyboard-history test also failed with main's original parser; recording reads before the scroll transition fixes its timing assumption while retaining visibility assertions. - Native package tests passed (127 tests), and both Runner bridge tests passed on an iOS simulator with Xcode 26.5. Removing the production `threadRootId` assignment made the bridge regression fail; restoring it passed. Native code is unchanged by the main integration. - [Current-head CI passed](https://github.com/block/buzz/actions/runs/38659307247), including Mobile and Mobile Swift. [Codex review](https://github.com/block/buzz/pull/8332#issuecomment-6181458528) and [security review](https://github.com/block/buzz/pull/8332#issuecomment-6181449235) found no issues on the integrated commit. [Owner approval](https://github.com/block/buzz/pull/8332#pullrequestreview-5526812957) covers the exact integrated commit. - Standards and spec reviews found no blockers, including the merge resolutions and test adjustments. Validation is scoped to mobile/native per VISION_MOBILE; unrelated repository-wide checks were stopped, not counted as passing. The bridge test covers serialization and buffering, not end-to-end APNs delivery or app launch. No new physical-device acceptance is claimed; routine post-merge dogfood remains human-owned. --------- Signed-off-by: Tom Brow <tomb@block.xyz> |
||
|
|
ef2aa1ae38 |
fix(mobile): preserve thread replies through refresh failures (#7757)
## Summary A failed mobile thread refresh could briefly remove replies and show “0 replies” even though Riverpod still retained the previous result. Read the retained reply value directly and merge it with pending local replies through errors and retries. When a reopened thread has no retained result, show loading or failure instead of a false zero count. Error status remains visible alongside retained replies. No additional cache or retention is introduced. Current main intentionally disposes thread queries on close; reopening still fetches fresh data. The recorded symptom is reproduced by the failed-refresh test, but the recording alone does not establish its network trigger. ### Related issue Related to #4831 (thread refresh and disposal behavior), incorporated into main through #6691. No duplicate for this rendering defect found. ### Testing - Reproduced disappearing cached replies in widget tests before the fix; the new retry/recovery, terminal-error, reopen/loading, initial-error, and empty-result tests now pass. - Provider coverage verifies cached and pending local replies survive a failed refresh and confirmation still clears the local overlay. - All five new widget regressions, the existing hydration/scroll-position regression, all nine thread-provider tests, Flutter analysis, and the final-head full mobile pre-push gate passed (2,261 tests passed; four skipped). - Phone-width and large-text rendering checked with synthetic messages. [Before/after screenshots](https://github.com/block/buzz/pull/7757#issuecomment-5743469556). - All final-head GitHub checks passed, including mobile tests, Android debug APK, iOS simulator app, and unsigned iOS release builds. - Codex code review and security review are clean for `4e5f606ae`; the earlier accessibility finding is fixed and resolved. Builderbot review was requested but has not returned a result. - Broad local `just ci` could not finish: unchanged ACP timing tests failed, including `keepalive_resets_idle_past_deadline` on the lower-concurrency retry. The separate ACP run passed all 941 tests. Initial parallel mobile runs also hit timing flakes; the final-head full mobile gate passed. No unrelated native code was changed. --------- Signed-off-by: Tom Brow <tomb@block.xyz> |