镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

fix(sidebar): drop the draft pencil from channel and DM rows - #2943

Merged
baxen merged 1 commit into
mainfrom
mbot/remove-draft-indicator
Nov 7, 2026
Merged

baxen merged 1 commit into
mainfrom
mbot/remove-draft-indicator

Conversation

@baxen

@baxen baxen commented Nov 7, 2026

Copy link
Copy Markdown
Collaborator

What

This removes the draft pencil that #2853 added to channel and DM rows in the sidebar.

Why

The pencil appears when a conversation or any of its threads has a draft. For a thread draft, the row doesn't say which thread it's in, so it's hard to find. Drafts & sent already lists every draft and links to where it is. Discussion: baxen and kalvin in #buzz-onedotzero.

Unchanged

  • The reply-line cue from feat(drafts): show where unsent drafts wait #2853: · ✎ Draft after a reply count, or ✎ Draft reply when nobody has replied yet. This is what helps you find a thread draft.
  • Drafts & sent and the shared draftCounts rule.
  • The temporary-channel clock shows again on rows where the pencil used to take its place.

How

  • ChannelSidebarItem.tsx: removes the marker, its useChannelDraft read and the !draft guard on TemporaryMarker.
  • Channels.module.css: removes .draftMarker and the rule it used to hide an empty indicator stack.
  • draft-places.ts: removes useChannelDraft, which no longer has callers. useThreadDraft, useShowingDraft and draftCounts stay.
  • Removes the two sidebar pencil tests from ChannelSidebarItem.test.tsx.
  • Changes the four browser journeys back to the plain row names ("Alpha" instead of "Alpha Draft").
  • docs/buzz-help.md: describes only the reply-line cue now.

Checks

  • tsc --noEmit and biome are clean.
  • vitest run src/bundled/channels src/features/messages src/features/drafts-sent: 164 files and 4118 tests pass.
  • The commit hooks and the pre-push types-and-related-unit-tests and design-system hooks pass.
  • Deferred: I didn't run the browser journeys locally; hosted CI covers them. I haven't looked at the change in the running app.

The pencil added in #2853 marked a sidebar row when the conversation or
any of its threads held a draft. A thread draft is hard to find from the
row alone, and Drafts & sent already lists every draft with a link to
where it waits, so the row marker is removed. The reply-line Draft cue
and Drafts & sent are unchanged.

Co-authored-by: mbot <3754f8729004d95654c46dbab3129e4ab9ef05cc2534e2a3fbfc155983bd637b@buzz.block.builderlab.xyz>
Signed-off-by: Bradley Axen <baxen@squareup.com>
@baxen
baxen requested a review from a team as a code owner November 7, 2026 00:56
@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-07T00:58:39.858458Z 132387c PR opened
ℹ️ 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.

@kalvinnchau kalvinnchau left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🤖 LGTM. The sidebar hunks are an exact inverse of the #2853 sidebar changes. Nothing still references useChannelDraft, draftMarker or data-channel-draft, and no browser spec still uses an "X Draft" row name. The reply-line cue and the shared draft-places logic are untouched.

@baxen
baxen merged commit ee1db65 into main Nov 7, 2026
65 of 68 checks passed
@baxen
baxen deleted the mbot/remove-draft-indicator branch November 7, 2026 01:29
tellaho added a commit that referenced this pull request Nov 7, 2026
Integrate the mainline sidebar geometry correction while retaining the dialog focus changes.

Co-authored-by: Carl <acda9e433d19dcd0e6b6840f7f4b98f3a56f1fab98049d444c087019e6d36560@feedback.communities.buzz.xyz>

* origin/main:
  fix(sidebar): give Drafts & sent the page rows' icon box (#2946)
  fix(sidebar): drop the draft pencil from channel and DM rows (#2943)
  feat(channels): create #general for the owner of an empty community (#2904)
  feat(agents): move local teams to the relay and show sync state (#2846)
  Preserve legacy emoji avatars during agent import (#2849)
  feat(communities): skip join consent covered by a Builderlab account (#2912)
  fix(mentions): keep @mentions tagged when punctuation or quotes follow the name (#2713)
  fix(sidebar): align Drafts & sent row with channel rows (#2733)
  test(navigation): split the plugin-settings return-path journey (#2800)
  fix(messages): let Escape close Forward and return focus to ⋯ (#2807)
  fix(messages): say older messages can load once Buzz reconnects, instead of an inert Load older button (#2810)
  fix(navigation): say when the open page's plugin is turned off, and open it in Manage plugins (#2817)
  fix(settings): reopen plugin details on Back and Forward (#2825)
  fix(agents): show agent card pictures without a backdrop (#2828)
  feat(agents): team instructions history and agent/team config tools (#2848)
  test(plugin-manager): use an immutable git socket fixture (#2665)
  fix(attention): show the attention toggle when an agent has nothing yet (#2907)

Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
kalvinnchau added a commit that referenced this pull request Nov 7, 2026
…2906)

## Problem

Every write to a view key now rescans every saved draft. Since #2853
added draft markers, `draft-places` subscribes to all view writes in the
community. On each write it clears its cache, and every message row
(`useThreadDraft`) re-reads it. The first reader then runs
`listDraftViews`, which:
- walks every localStorage key;
- `JSON.parse`s each draft;
- projects each rich composer document to text.

Writes come from each composer keystroke (the draft save) and from
scroll-place saves, among others. A keystroke in a draft that already
has text never changes where drafts wait, so all of that work is thrown
away. The Drafts & sent list (`useDrafts`, mounted for the sidebar
badge) also re-reads every draft on writes to keys that are not drafts.

## Change

- `subscribeView` listeners receive the key that changed. `writeView`
passes it, as does `clearView` with one key and the cross-window
`storage` event. Scope-wide clears, focus and attachment changes still
pass nothing, which means "anything may have changed".
- `draft-places` skips the rescan, and does not notify, when the changed
key cannot change where drafts wait:
  - a key that is not a draft;
- a draft whose "counts as a draft" answer (same `draftCounts` rule) is
the same as in the cached list.

Anything doubtful falls back to the full rescan: a forgotten,
unreadable, malformed or oversized key.
- `useDrafts` ignores writes to keys that are not drafts.
- The 8 MB draft cutoff is now one exported constant,
`MAX_DRAFT_VIEW_LENGTH`, shared by `listDraftViews` and the new check.

## No behavior change

The cached list is only kept when one key changed and that key's
membership is provably unchanged, so the list equals what a full rescan
would return.
- **Cap:** a draft beyond the 500-entry cap is never in the list, so
writes to it still rescan, as before.
- **Other windows:** the storage event names the key, and the check
reads current shared localStorage, so the result is the same however
events arrive.
- **Drafts & sent:** `readDrafts` depends only on draft keys, attachment
counts and its activity record. The activity record is a separate
localStorage key, not a view key.

New tests in `draft-places.test.tsx`:
- writes to keys that aren't drafts, and keystrokes in a thread draft,
don't rescan;
- empty, clear and refill writes still update the marker;
- a cross-window storage event still marks a draft.

The first test fails without the change.

## Evidence

Main `7817418db` (after #2943 removed the sidebar draft marker) vs this
change. This PR is rebased onto `3884917e5`; the commits in between
don't touch drafts. 4 Linux and 4 macOS boxes each ran 6 interleaved
rounds. The table shows the mean of per-box medians, with the per-box Δ
range in parentheses.

| metric | Linux: main | Linux: this PR | Linux Δ % | macOS: main |
macOS: this PR | macOS Δ % |
|---|---|---|---|---|---|---|
| typing, 100 saved drafts: script | 386.2 ms | 350.3 ms | −9.3%
(−11.5..−4.5) | 297.8 ms | 269.2 ms | −9.6% (−12.3..−7.9) |
| typing, 100 saved drafts: busy | 755.9 ms | 725.0 ms | −4.1%
(−5.3..−1.6) | 546.1 ms | 509.1 ms | −6.8% (−8.6..−4.9) |
| typing, 100 saved drafts: key-to-paint | 36.8 ms | 36.3 ms | −1.2%
(−2.8..+0.4) | 24.2 ms | 21.3 ms | −11.9% (−14.8..−8.6) |
| typing, no saved drafts: script | 298.3 ms | 297.0 ms | −0.4% (noise)
| 232.9 ms | 231.7 ms | −0.5% (noise) |
| mention typing, 100 saved drafts: script | 2384.8 ms | 2358.7 ms |
−1.1% | 1460.6 ms | 1439.4 ms | −1.5% |
| channel switch: script | 505.3 ms | 510.0 ms | +0.9% (noise) | 295.3
ms | 296.2 ms | +0.3% (noise) |

The seeded drafts add about 30% script to plain typing on main (298.3 →
386.2 ms on Linux, 232.9 → 297.8 ms on macOS); this change removes about
a third of that. Most of the rest is the Drafts & sent list re-reading
every draft on each draft keystroke, which this PR leaves unchanged.

Lower is better. The typing benchmark (an Event Timing harness on the
browser fixture) runs a production build in Chromium at 4× CPU
throttling and types 12 keys in the channel composer per phase, 2 phases
per run. Before typing, 100 copies of the composer's own saved draft are
seeded into other channels. Key-to-paint is the Event Timing keydown
duration averaged over every key; keys under 16 ms count as 0. Builds
are interleaved per round; each box's median is taken, then the mean of
box medians per OS. With no saved drafts the change is within noise, as
expected.

Checks:
- vitest for `draft-places`, `view-state` and `drafts-sent` passes (89
tests).
- `tsc` and `biome` pass.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants