feat(mobile): desktop-parity emoji and thread experience - #3485
Conversation
The emoji tray shipped a hardcoded ~140-glyph list across five invented categories. Generate the real emoji-mart dataset desktop uses (1,870 emoji, 8 categories) into a committed asset so shortcodes, names, and keywords match byte-for-byte, and rebuild the tray on top of it with desktop's tiered search ranking over both standard and custom emoji. Reaction pills now use desktop's geometry and always show the count. Threads read top-down from the head instead of pinned against the composer, every thread message carries a + affordance, and tapping a channel message opens its thread (long-press keeps the action sheet). Also ports desktop's positive-emoji particle burst. Desktop's physics constants are unchanged, but stepped at a fixed 60Hz rather than once per frame so a 120Hz panel doesn't run the burst at double speed. Mobile reactions aren't optimistic, so picking from the quick row or the tray arms a pending burst that the pill fires once the relay echoes it back. Keyboard dismissal is threshold-based on downward drag travel. True finger-tracked dismissal needs a native UIScrollView proxy plus Android's WindowInsetsAnimationController and is deliberately out of scope. Signed-off-by: kenny lopez <klopez4212@gmail.com>
…mobile-emoji-thread-ux Signed-off-by: kenny lopez <klopez4212@gmail.com>
… scale Follow-up on device feedback for the desktop-parity emoji work: - Reactions never reached an open thread. The thread's relay query is one-shot and its `kinds` filter carries only content rows, so a reaction event could not arrive through it, and `allMessages` was a snapshot frozen when the route was pushed. Leaving and re-entering worked only because the disposed provider refetched. Union the live channel events into the thread's own list and format once, and stop falling back to the stale head when a live copy exists. - Route-guard the burst so it plays on the view the user is looking at. The channel timeline stays mounted under a pushed thread and rebuilds first, so it was claiming the pending burst. - Match the channel's reaction affordance in threads: replies show no chrome until they carry a reaction, and the head keeps a standing "+". - Add the "+" picker trigger beside existing reactions in the channel timeline, the way desktop does. - Make the emoji tray one continuous scroll with pinned section headers instead of swapping a grid per category, and span the category rail across the full width the search field uses. - Size custom emoji tiles to the same glyph and cell as native ones. - Render emoji-only bodies at 36px with 1.45em inline custom emoji, matching desktop's `emojiOnly` treatment. Signed-off-by: kenny lopez <klopez4212@gmail.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4fd8a9280c
ℹ️ 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".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Captured on a physical Pixel 10 (debug build). Emoji tray — one continuous scrollThe full emoji-mart set in a single scroll view, with a frequently-used section on top. The category rail spans the same width as the search field. Section headers pin, the rail follows the scrollScrolling into Smileys & People pins its header and moves the rail highlight — the rail is a shortcut into one list, not a page switcher. SearchDesktop's tiered ranking, extended to names and keywords, across standard and custom emoji together. Emoji-only messages render larger
Burst, and the
|
…ssal Two defects found on device. **Replies didn't show in the channel.** A reply never reaches the main timeline; the root's "N replies" row comes from the kind-39005 thread summary the relay re-emits on every reply. The channel-window merge gate dropped that kind — it is neither a timeline row nor an aux event — so the count only appeared after leaving the channel and coming back, which refetched the page. Summaries now merge into a `liveThreadSummaries` map kept beside the pages, so a root still in the live overlay (a message you just sent, which has no row yet) gets a count too. A refetched row carries its own authoritative summary and supersedes the live entry. **Drag-to-dismiss never fired.** Two independent bugs, either one fatal: - `dismissKeyboard` gated on `MediaQuery.viewInsetsOf(context).bottom > 0`, read from inside a `Scaffold` body. `Scaffold` strips the bottom view inset once it has resized for it, so that always reads 0 — a permanent no-op for both message lists and the compose bar. Read `View.of` instead. - The notification handler only looked at `ScrollUpdateNotification`. You focus the composer at the list's resting edge nearly every time, and there a downward drag moves the position nowhere: it is pure overscroll and reports `OverscrollNotification`. The most common dismissal gesture produced no notification the widget was listening for. Signed-off-by: kenny lopez <klopez4212@gmail.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4450e1a13d
ℹ️ 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".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Subscribe channel timelines to live thread summaries and retain those summaries through optimistic-message rollback. Treat initial thread replies as hydration so head-first threads stay at the head, and keep full-picker recent-emoji accounting in its single owning layer. Co-authored-by: klopez4212 <klopez4212@gmail.com> Signed-off-by: npub12zsjdqx8dud99s9h47xmk9lq93vryf7zjrae8wdrmma52cg5yglseyulst <50a12680c76f1a52c0b7af8dbb17e02c583227c290fb93b9a3defb456114223f@buzz.block.builderlab.xyz> Signed-off-by: klopez4212 <klopez4212@gmail.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b454f3f350
ℹ️ 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".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Buffer live thread summaries that race initial window hydration, retain the newest page-or-live snapshot by relay timestamp, and ignore delayed recounts that would restore stale reply badges. Co-authored-by: klopez4212 <klopez4212@gmail.com> Signed-off-by: klopez4212 <klopez4212@gmail.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 72bb6cff55
ℹ️ 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".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Signed-off-by: kenny lopez <klopez4212@gmail.com>
|
🤖 @codex review
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c45f6232da
ℹ️ 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".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Signed-off-by: kenny lopez <klopez4212@gmail.com>
|
🤖 @codex review
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8feebf8522
ℹ️ 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".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
🤖 @codex review
|
|
Codex Review: Didn't find any major issues. Nice work! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
Signed-off-by: kenny lopez <klopez4212@gmail.com>
|
🤖 @codex review
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 03d32ade00
ℹ️ 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".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
🤖 @codex review
|
Signed-off-by: kenny lopez <klopez4212@gmail.com>
|
Codex Review: Didn't find any major issues. Bravo. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
|
🤖 @codex review
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1762f8ef47
ℹ️ 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".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Signed-off-by: kenny lopez <klopez4212@gmail.com>
Signed-off-by: kenny lopez <klopez4212@gmail.com>
|
🤖 Fixed in ba0f41f. The initial page now supersedes summaries replayed before its query, while retaining only summaries that arrive during the query itself. Added regression coverage for both races.\n\n- Codex |
|
🤖 @codex review\n\n- Codex |
|
Codex Review: Didn't find any major issues. Bravo. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
|
🤖 @codex review\n\n- Codex |
|
Codex Review: Didn't find any major issues. Another round soon, please! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
| mobile-emoji-data: | ||
| node {{mobile_dir}}/scripts/generate-emoji-data.mjs |
There was a problem hiding this comment.
@klopez4212 when does this get run? Like do we need to do this as part of CI or is some developer going to have to run this?
There was a problem hiding this comment.
mmm I think this was run to rebuild the emoji tray but I dont think its actually needed ongoing..let me ask the agents to be sure
There was a problem hiding this comment.
🤖 Confirmed: this is not a runtime or normal-CI step. It was used to create the committed mobile/assets/emoji/emoji-data.json; mobile reads that bundled asset and does not load emoji-mart directly.
We should keep the generator as maintenance tooling so a future intentional bump of desktop's @emoji-mart/data can regenerate the same mobile dataset (names, shortcodes, keywords, and category order) reproducibly. It only needs to be run with that dependency update, then the resulting asset should be committed — not on every developer run or ordinary CI pass.
|
I found one remaining correctness blocker at Pre-EOSE summaries can be misclassified as post-query live mutations
This permits the following ordering:
The result can be a stale reply count/participant snapshot until another recount arrives. The provider regression test does not exercise this ordering because its fake subscription invokes listeners directly and does not model the real EVENT buffer plus EOSE boundary. Please establish a reliable delivery-phase boundary—for example, drain queued events for the subscription before completing readiness, or otherwise distinguish replay-buffered events from events genuinely received after EOSE—and add a regression test for Separately, GitHub currently reports this head as |
Signed-off-by: kenny lopez <klopez4212@gmail.com> # Conflicts: # mobile/lib/features/channels/channel_detail_page/message_bubble.dart # mobile/lib/features/channels/thread_detail_page.dart
|
🤖 @codex review
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f12b041687
ℹ️ 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".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Signed-off-by: kenny lopez <klopez4212@gmail.com>
|
🤖 @codex review
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b9dfa1f56c
ℹ️ 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".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Signed-off-by: kenny lopez <klopez4212@gmail.com>
|
🤖 @codex review
|
|
Codex Review: Didn't find any major issues. Bravo. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
|
🤖 @codex review
|
|
Codex Review: Didn't find any major issues. Keep it up! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
|
Carl commenting on Wes's behalf: I re-reviewed the updated head
The branch now contains current |
…chive * origin/main: (22 commits) feat(catalog): resolve publisher display name in catalog detail pane (#3640) feat(mesh): upgrade embedded mesh to v0.74 and harden shared compute (split 1/2 of #3467) (#3741) docs(nips): specify kind:30621 multi-repo projects (NIP-MP) (#3163) Refine agent sharing dialog (#3699) desktop: enable getUserMedia in the Linux WebKitGTK webview (#3607) fix: align responsive agent views (#3688) Add macOS agent menu-bar menu (#3565) Fix pending message feedback (#3543) fix(desktop): remove remaining Projects panel fills (#3742) feat(mobile): desktop-parity emoji and thread experience (#3485) desktop: restore direct community member adds (#3634) fix(desktop): explain open agent access (#2561) fix(cli): resolve agents from owner records (#3178) fix(desktop): remove Projects overview card fills (#3416) feat(replica): portable heartbeat-token fence with snapshot-local reader routing (#3268) fix(git): channel binding tooling + author remediation for unbound repos (#3626) feat: configure S3 URL addressing style (#3400) feat: add first-class OpenRouter provider support (#1975) feat(agent,acp): wire provider total_tokens through NIP-AM publish chain (#3593) chore(release): release Buzz Desktop version 0.5.2 (#3624) ... Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
…g-pipeline * origin/main: (25 commits) Refine agent sharing dialog (#3699) desktop: enable getUserMedia in the Linux WebKitGTK webview (#3607) fix: align responsive agent views (#3688) Add macOS agent menu-bar menu (#3565) Fix pending message feedback (#3543) fix(desktop): remove remaining Projects panel fills (#3742) feat(mobile): desktop-parity emoji and thread experience (#3485) desktop: restore direct community member adds (#3634) fix(desktop): explain open agent access (#2561) fix(cli): resolve agents from owner records (#3178) fix(desktop): remove Projects overview card fills (#3416) feat(replica): portable heartbeat-token fence with snapshot-local reader routing (#3268) fix(git): channel binding tooling + author remediation for unbound repos (#3626) feat: configure S3 URL addressing style (#3400) feat: add first-class OpenRouter provider support (#1975) feat(agent,acp): wire provider total_tokens through NIP-AM publish chain (#3593) chore(release): release Buzz Desktop version 0.5.2 (#3624) docs: add Linux rendering troubleshooting guide (#3573) fix(desktop): discover bun-installed agent CLIs in ~/.bun/bin (#3343) feat(tracing): correlate trace IDs in relay logs (#3608) ... Signed-off-by: npub1mn7jgtj4w2pd0g0zeuhxsa6jy6p0rewxz4kujt98my82ahfmp72sxjexk7 <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@buzz.block.builderlab.xyz>
…-style * origin/main: fix(acp): preserve truncated thread context (block#3340) feat(catalog): resolve publisher display name in catalog detail pane (block#3640) feat(mesh): upgrade embedded mesh to v0.74 and harden shared compute (split 1/2 of block#3467) (block#3741) docs(nips): specify kind:30621 multi-repo projects (NIP-MP) (block#3163) Refine agent sharing dialog (block#3699) desktop: enable getUserMedia in the Linux WebKitGTK webview (block#3607) fix: align responsive agent views (block#3688) Add macOS agent menu-bar menu (block#3565) Fix pending message feedback (block#3543) fix(desktop): remove remaining Projects panel fills (block#3742) feat(mobile): desktop-parity emoji and thread experience (block#3485) desktop: restore direct community member adds (block#3634) fix(desktop): explain open agent access (block#2561) fix(cli): resolve agents from owner records (block#3178) fix(desktop): remove Projects overview card fills (block#3416) feat(replica): portable heartbeat-token fence with snapshot-local reader routing (block#3268) Signed-off-by: Joah Gerstenberg <joah@squareup.com>
* origin/main: (59 commits) Fix video reviews in thread replies (#3719) feat(release): make desktop releases immutable (#3568) Make relay reconnect backoff authoritative (#3774) feat(desktop): add password-protected backups in settings (#3701) fix(desktop): reuse profiles when joining communities (#2155) Render mobile agent mention chips (#3702) fix(catalog): update Amp description (#3758) fix(acp): preserve truncated thread context (#3340) feat(catalog): resolve publisher display name in catalog detail pane (#3640) feat(mesh): upgrade embedded mesh to v0.74 and harden shared compute (split 1/2 of #3467) (#3741) docs(nips): specify kind:30621 multi-repo projects (NIP-MP) (#3163) Refine agent sharing dialog (#3699) desktop: enable getUserMedia in the Linux WebKitGTK webview (#3607) fix: align responsive agent views (#3688) Add macOS agent menu-bar menu (#3565) Fix pending message feedback (#3543) fix(desktop): remove remaining Projects panel fills (#3742) feat(mobile): desktop-parity emoji and thread experience (#3485) desktop: restore direct community member adds (#3634) fix(desktop): explain open agent access (#2561) ... # Conflicts: # desktop/scripts/check-file-sizes.mjs







Brings the Flutter app's emoji and thread surfaces up to desktop parity.
Emoji
@emoji-mart/dataset desktop uses (1,870 emoji, 8 categories), committed as an asset — so shortcodes, names, and keywords are identical across clients.just mobile-emoji-dataregenerates it.emojiSearchranking, extended to names and keywords), a frequently-used section, and one continuous scroll with pinned section headers. The category rail is a shortcut into that list, not a page switcher, and spans the full width the search field uses. Custom emoji share the native glyph size and cell.emojiOnlytreatment.EmojiBurstProvider, suppressed under reduced motion.Threads
kindsfilter carries only content rows, so a reaction event could not reach an open thread at all, andallMessageswas a snapshot frozen when the route was pushed — a new pill only appeared after leaving and re-entering, which refetched. The live channel events are now unioned into the thread's list. The burst is also route-guarded, since the channel timeline stays mounted underneath and was claiming it first.+affordance follows the channel: replies stay bare until they carry a reaction, and the head keeps a standing+.Keyboard
A deliberate downward drag past ~48px dismisses the keyboard; short scrolls leave it alone. Applies to the channel list, the thread list, and the compose bar (via a raw
Listener, so it can't steal the field's tap or selection drags).True finger-tracking dismissal is out of scope — Flutter only offers
manual/onDrag, and 1:1 tracking needs a nativeUIScrollViewproxy plus Android'sWindowInsetsAnimationController.Testing
just mobile-checkandjust mobile-testpass (965 tests). New coverage for emoji search ranking, dataset parsing, the emoji-only predicate, tray scroll/rail behavior, reaction pills and the burst, and both thread fixes above.just cigreen.