Skip to content

Add rich composer formatting and spoiler rendering - #203

Merged
wesbillman merged 8 commits into
mainfrom
brain/composer-formatting
Sep 24, 2026
Merged

wesbillman merged 8 commits into
mainfrom
brain/composer-formatting

Conversation

@wesbillman

@wesbillman wesbillman commented Sep 24, 2026 •

Copy link
Copy Markdown
Collaborator

Authored and opened by Brain on Wes’s behalf.

Summary

  • Restore the original Buzz formatting toolbar layout and show/hide motion with shared Phosphor controls and reduced-motion support.
  • Give ProseMirror sole ownership of editable document, selection, composition and undo/redo. Persist a validated versioned document alongside the derived text/recipient projection; serialize Markdown only for send/copy. Retain legacy drafts, explicit mention provenance and existing outbox/plugin ownership.
  • Enable bold, italic, strike, inline code, link editing, quote/code blocks, bullet/ordered lists and spoilers. Add lightweight CSS spoiler dust with keyboard reveal and inert hidden descendants.

The editing-core replacement was explicitly approved after the layout-only prototype. This is one coherent foundation/formatting change, not a parser/transport rewrite. Unsupported authored Markdown remains source text; live typed-fence conversion, syntax highlighting and a particle engine are out of scope.

Origin: composer-formatting conversation

Current status — diagnostic head 1b100e4a

Not merge-ready. Published head: 1b100e4a81205e45436654d4710660d1926b3d2f. Hosted run 35955575437 was queued at the post-push check; final-head CI and DCO are pending, with required approving/code-owner review still outstanding.

  • ba22d04c repairs the packed conversation assertion: explicitly accept the persisted version-1 document envelope while retaining exact text and both recipient spans. No production behavior change.
  • 1b100e4a adds bounded, passive test-only scroll-writer diagnostics to the existing navigation journey. Its real wheel, settling and same-ID/Y <4px assertions remain unchanged. No cases, retries, timeouts or exclusions added/removed.
  • The 58px Linux WebKit displacement remains unresolved, already present during opening. Existing traces do not identify its writer. Diagnostics preserve native arguments, but synchronous geometry observation can alter layout timing: an instrumented pass does not establish a fix. No speculative navigation production change was made.
  • Full affected conversation + message-navigation files passed locally in both engines: 28/28, 56.0s (macOS, pinned tools, zero retries, final pre-commit bytes). Prior uninstrumented run also passed; neither clears the Linux failure. Diagnostic attachments contain actual native writer records in both local engines.
  • Required push hooks at this head passed TypeScript, 257 files / 2,675 Vitest tests, design types and guards. Bounded diagnostic review required passive listeners; that correction is included. No hook bypass, force-push, approval or merge.

Previous repair validation (79ae265f)

Integrated main 2cbe1b0c before repairs; its merge tree matched the failed hosted run. That repair head was 79ae265f393417d2cc7d1abc4d3e8cf95340f16e.

  • Required commit/push hooks passed: formatting/lint/icons, TypeScript, 257 Vitest files / 2,675 tests, design types and all design guards. Dependency changes select the full Vitest suite.
  • All five CI-affected browser files passed together in Chromium and WebKit: 62/62 (settings, completion-work, emoji, product-ui, typeahead), CI selection, zero retries. Run was on the final clean-equivalent repair bytes before commit; hooks made no further edits.
  • At the clean committed head, all four formatting/mention browser files passed: 20/20 (composer-bold, composer-formats, composer-links, mention-edit).
  • Standalone CLI integration passed 3/3, including building/installing a scaffold with the packed author API and preserving an installed revision after failed build. Controlled Settings close-completion tests cover ordinary focus handoff and early input focus.
  • Bounded independent source/dependency review found no concrete repair blocker. This is not GitHub/code-owner approval.
  • These are local macOS results. Hosted Linux run 35953773111 is failed: JavaScript (2,675 tests), Rust/Node integration, measurements (7 cases), Chromium shard 2 and DCO passed. Three browser shards failed: conversation draft equality in both engines and a 58px ordinary-reading anchor shift in WebKit exact-thread navigation. Repair investigation remains active; this PR is not merge-ready.

What failed and changed

The earlier local checks were not the whole hosted suite. Hosted CI exposed a packed declaration dependency leak, duplicate emoji-selection ownership, selection/caret and post-token geometry regressions, and assertions still targeting the old toolbar/DOM. Its merged tree also contained main's new account-menu focus handoff, which could interrupt Settings entry.

The repair keeps serializable snapshot types at the public draft boundary, leaves selection solely with ProseMirror, preserves browser-derived replacement carets, scrolls after token portals acquire geometry, and removes the toolbar's accidental containing block. Settings retains drafts as before; its existing completion callback now preserves focus already moved into the page. Assertions retain exact selection/layout/retention contracts. The completion-position probe is positively calibrated and excludes legitimate editor caret geometry; it is a source-fixture probe in CI too, not a global zero-layout claim. No CI lanes, retries, timeouts or tolerances changed; no browser cases were added or removed by this repair.

Regression coverage and browser justification

  • New colocated document/editor cases cover selection/history, schema snapshots, serialization, marks, lists and cross-block deletion. Existing component tests exercise completion, attachments, send, recipients and draft ownership through the production editor.
  • New browser files add 6 logical cases / 12 engine cases, removing none. Browser-only boundaries: native input/deletion and caret behavior, clipboard, keyboard selection, tab indentation, storage/reload and CSS/inert/keyboard spoiler reveal. Combinatorial parsing/formatting remains in Vitest.
  • Existing link and mention browser fixtures now observe the paragraph/BR and mutation-observer boundaries rather than the removed custom editor DOM; assertions were retained.
  • Fail-then-pass regressions caught collapsed-spoiler selection exceptions, nested-list type switching, explicit stored marks, blank-line and URL spoiler disclosure, adjacent GFM table pipes, and outer spoiler emphasis. The final three outer-format regressions failed before repair and the whole 85-case renderer file passed after. Bounded independent source/log rechecks closed the reported mechanisms.

Remaining gates

  • Resolve the navigation displacement and verify hosted CI required plus DCO Check at the final uninstrumented repair head, and obtain one required approving/code-owner review. GitHub currently reports REVIEW_REQUIRED; no approval or merge is claimed.
  • Human visual acceptance of the latest dust motion and native Tauri editing remains distinct from headless Chromium/WebKit evidence. No desktop/server restart or native automation was performed for final delivery.
  • No native packaging, Windows or release certification claimed.

Brain added 2 commits September 23, 2026 21:05
Signed-off-by: Brain <1a02c72794dcd0f07058a353bc3a81f4028b8c77c92c87fce6d5c8b85970a20b@buzz.block.builderlab.xyz>
Signed-off-by: Brain <1a02c72794dcd0f07058a353bc3a81f4028b8c77c92c87fce6d5c8b85970a20b@buzz.block.builderlab.xyz>
@wesbillman
wesbillman marked this pull request as ready for review September 24, 2026 03:13
@wesbillman
wesbillman requested review from a team and comp615 as code owners September 24, 2026 03:13
Signed-off-by: Brain <1a02c72794dcd0f07058a353bc3a81f4028b8c77c92c87fce6d5c8b85970a20b@buzz.block.builderlab.xyz>
@wesbillman

Copy link
Copy Markdown
Collaborator Author

On Wes’s behalf — Brain implemented and verified this conflict resolution.

Merged e9e557c5 into the published branch without rewriting history. New head: b0520a44c58e0235f9105d6f6d8af6d3f7430077; GitHub reports MERGEABLE (required checks remain in progress).

  • Preserved Edit the latest own message with Up in the existing composer #192’s same-composer editing, draft persistence isolation, delivery/retry and attachment source. Rich draft document/selection/history are retained through an editor-owned checkpoint rather than reinstating the old history stack; edit saves use the Markdown serializer.
  • Browser verification caught and repaired native Escape interception and focus restoration before unlock. Independent bounded review caught blank structured edits being serialized as nonblank delimiters; three Enter-path regressions failed before the guard and pass afterward.
  • At the new head, required hooks passed 251 files / 2,640 tests, TypeScript, design types/guards and staged checks. The final-head edit journey passed Chromium and WebKit, covering same DOM, cancel/undo, retry/acceptance, attachments and responsive edit controls. Another 12 formatting engine cases passed before the final one-line blank guard. No browser cases were added or removed in this merge.
  • DCO passes. Remote head verified and worktree clean. The prior scrollIntoView fixture exception did not recur in this hook run; no unrelated fixture change or hook bypass was made.

Also includes the previously authorized 0.65s/0.9s spoiler timing commit. Closer motion matching to the supplied old-Buzz video is still separate follow-up, not implemented here. Hosted CI, required review and native/visual acceptance remain open; no desktop restart or native automation.

Signed-off-by: Brain <1a02c72794dcd0f07058a353bc3a81f4028b8c77c92c87fce6d5c8b85970a20b@buzz.block.builderlab.xyz>
@wesbillman

Copy link
Copy Markdown
Collaborator Author

On Wes’s behalf — Brain resolved the next main-branch conflict at 6835d26dfe16e41c71315b51918fd0f1f37b9568.

Merged #202 (fd8f0378) without rewriting published history. The sole conflict was appended CSS: retained the complete spoiler rules and exact incoming .rawDiff rules as separate top-level blocks. Composer/editor/Markdown implementation bytes are unchanged from b0520a44; auto-merged dependencies installed with the frozen lockfile.

At this head: required hooks passed 254 files / 2,661 tests, TypeScript and design types/guards. Complete diff-viewer and composer-formats browser files passed 8 cases across Chromium/WebKit, covering diff expansion/layout/focus/scroll and code/list/spoiler behavior. No new or removed browser cases. GitHub reports MERGEABLE, DCO passes, remote head verified, working tree clean. Hosted CI/review and native/visual acceptance remain separate gates; no native restart or release certification.

Brain added 4 commits September 23, 2026 21:52
Signed-off-by: Brain <1a02c72794dcd0f07058a353bc3a81f4028b8c77c92c87fce6d5c8b85970a20b@buzz.block.builderlab.xyz>
Signed-off-by: Brain <1a02c72794dcd0f07058a353bc3a81f4028b8c77c92c87fce6d5c8b85970a20b@buzz.block.builderlab.xyz>
Signed-off-by: Brain <1a02c72794dcd0f07058a353bc3a81f4028b8c77c92c87fce6d5c8b85970a20b@buzz.block.builderlab.xyz>
Signed-off-by: Brain <1a02c72794dcd0f07058a353bc3a81f4028b8c77c92c87fce6d5c8b85970a20b@buzz.block.builderlab.xyz>
@wesbillman
wesbillman merged commit ba9074d into main Sep 24, 2026
12 checks passed
@wesbillman
wesbillman deleted the brain/composer-formatting branch September 24, 2026 13:19
zrmarley added a commit that referenced this pull request Sep 24, 2026
…o-player-polish

* origin/main: (38 commits)
  Fix diff content fallback, keyboard scrolling and edit selection (#205)
  Standardize form controls and field feedback across Buzz (#174)
  Keep image review downloads and external opens distinct (#144)
  Verify media review comments (#166)
  Follow system appearance (#210)
  Add rich composer formatting and spoiler rendering (#203)
  feat: show roster-backed channels and managed instances in profiles (#188)
  Add new direct message flow (#156)
  Remove Home, start in Messages, and keep Channels enabled (#194)
  fix: restore avatar presence controls and active-input sensing (#198)
  Add legacy diff messages with inline and expanded viewing (#202)
  Edit the latest own message with Up in the existing composer (#192)
  Add complete reaction toggles to the message menu (#185)
  feat: add persistent community navigation rail (#191)
  test: add margin to warm-switch performance gate (#195)
  Add composer attachments and compatible media preparation (#183)
  Add reply and copying to the shared message menu (#182)
  fix: avoid idle workspace re-renders from activity and label churn (#186)
  feat: add devtools trace capture to web profiling (#180)
  Add optional channel templates, teams and personal group defaults (#181)
  ...

Signed-off-by: Zach Marley <[email protected]>
zrmarley added a commit that referenced this pull request Sep 24, 2026
…-content-compat

* origin/main: (38 commits)
  Fix diff content fallback, keyboard scrolling and edit selection (#205)
  Standardize form controls and field feedback across Buzz (#174)
  Keep image review downloads and external opens distinct (#144)
  Verify media review comments (#166)
  Follow system appearance (#210)
  Add rich composer formatting and spoiler rendering (#203)
  feat: show roster-backed channels and managed instances in profiles (#188)
  Add new direct message flow (#156)
  Remove Home, start in Messages, and keep Channels enabled (#194)
  fix: restore avatar presence controls and active-input sensing (#198)
  Add legacy diff messages with inline and expanded viewing (#202)
  Edit the latest own message with Up in the existing composer (#192)
  Add complete reaction toggles to the message menu (#185)
  feat: add persistent community navigation rail (#191)
  test: add margin to warm-switch performance gate (#195)
  Add composer attachments and compatible media preparation (#183)
  Add reply and copying to the shared message menu (#182)
  fix: avoid idle workspace re-renders from activity and label churn (#186)
  feat: add devtools trace capture to web profiling (#180)
  Add optional channel templates, teams and personal group defaults (#181)
  ...

Signed-off-by: Zach Marley <[email protected]>

# Conflicts:
#	docs/channels.md
morgmart pushed a commit that referenced this pull request Sep 24, 2026
…rs-support

* origin/main:
  Add Messages design gallery and tighten message layout (#158)
  Fix diff content fallback, keyboard scrolling and edit selection (#205)
  Standardize form controls and field feedback across Buzz (#174)
  Keep image review downloads and external opens distinct (#144)
  Verify media review comments (#166)
  Follow system appearance (#210)
  Add rich composer formatting and spoiler rendering (#203)
  feat: show roster-backed channels and managed instances in profiles (#188)
  Add new direct message flow (#156)

Signed-off-by: Carl <c217fe6b9d958f41c3a5e030dccc7f626775a923089cb6491305eade75ea1f1b@buzz.block.builderlab.xyz>
matt2e added a commit that referenced this pull request Nov 4, 2026
## Problem

On macOS, **Correct Spelling Automatically** in the message box's
right-click **Spelling and Grammar** menu is greyed out. Spell checking
and grammar checking still work. The cause is the rich composer's
ProseMirror root, which has set `autocorrect="off"` since #203 ("Keep
spelling hints, but do not let native suggestions rewrite rich text").
Nothing in Tauri, wry or Buzz's native code changes spelling settings.
In WebKit,
`AlternativeTextController::canEnableAutomaticSpellingCorrection()`
returns false when the editable root says `autocorrect="off"`.
`WebViewImpl::validateUserInterfaceItem` then disables
`toggleAutomaticSpellingCorrection:` and shows it unchecked.

## Why an opt-in setting rather than removing the attribute

The menu item's checked state is WebKit's app-wide `TextChecker` state,
not something stored per field. WebKit saves it under
`WebAutomaticSpellingCorrectionEnabled` in the app's `NSUserDefaults`.
Until the user changes it, it follows the macOS keyboard setting for
correcting spelling automatically.

- **Removing `autocorrect="off"`** would turn correction on in the
message box for most Mac users, because that macOS setting is usually
on. It would reverse #203's choice for everyone.
- **Forcing it off natively**, by registering a default of NO, would
change every other text field in the app too, not just the composer.

So this adds a per-device opt-in that is off by default. When it is on,
the composer root gets `autocorrect="on"`, the menu item becomes
available, and WebKit remembers the choice made there as usual.

## What changed

- **Setting:** Settings › Appearance › Conversations › **Allow automatic
spelling correction**. It is off by default and saved on this device
(`localStorage`, `buzz-message-autocorrect.v1`). The description reads:
"Lets macOS correct misspelled words in messages. Turn correction on or
off from the message box’s Spelling and Grammar menu." The label is
worded as a permission because the switch only *allows* correction.
Whether WebKit actually corrects still depends on the menu item, which
follows the macOS keyboard setting.
- **Composer:** `EditableInput` sets `autocorrect="on"` on the
ProseMirror root when the preference is on and `"off"` otherwise. The
value updates live through the existing `setProps` effect and follows
other windows through the `storage` event. `spellcheck`,
`autocapitalize`, `autocomplete` and `writingsuggestions` are unchanged.
All message composers share the setting, because only `MessageComposer`
→ `RichComposerInput` uses `EditableInput`. No other input changes.
- **Platform gate:** the switch only appears where the attribute has a
verified effect: Mac WebKit, meaning the macOS desktop app (WKWebView)
and Safari on a Mac. The gate reuses the existing `macWebKit()` check:
platform `MacIntel`, no touch points, vendor `Apple Computer, Inc.`. The
switch is hidden in Chrome and other Chromium browsers on a Mac, in
Linux WebKitGTK (the Linux desktop app), on desktop-mode iPad and
everywhere else. In those places it can't be turned on, so the composer
keeps `autocorrect="off"` as before.
- **Save failure:** if the choice can't be saved, it stays active and a
"Spelling preference wasn’t saved" toast offers a retry, the same way
other Appearance preferences work.
- **Help:** `docs/buzz-help.md` has a **Spelling** entry describing the
setting "in the Mac app or Safari".

Shared owners used: `SettingsGroup`, `SwitchPreferenceRow`,
`ToastNotice`, `Button`. No new components, tokens or variants.

## Screenshots

Captured from this branch's head (`9d85550`) in Playwright WebKit 1.63
(Safari 26.6 engine). The browser reported `MacIntel` / `Apple Computer,
Inc.`, so the switch is shown. Runs were headless at 1280×800 at 2×
pixel density, using the full app shell with the browser-test fixture's
synthetic data. A temporary spec outside the repository drove the app.
It was not committed.

**Settings › Appearance › Conversations, light theme**

![Light theme, switch off (the default): the new last row in the
Conversations group reads "Allow automatic spelling correction", with
its description below and a grey switch on the
right.](https://github.com/user-attachments/assets/8724e3e4-3dcf-476a-9ec8-3c0cfdeff166)

![Light theme, switch on: the same row with the switch filled dark and
its knob on the right. Nothing else on the page
changes.](https://github.com/user-attachments/assets/59a37039-a185-4d9a-bcde-375845e93249)

**Dark theme**

![Dark theme, switch off: label, description and the switch track stay
readable on the dark
background.](https://github.com/user-attachments/assets/8e46f5d0-8eab-402b-9de3-a28d51c1ac48)

![Dark theme, switch on: the track turns light with a dark knob, so the
two states are easy to tell
apart.](https://github.com/user-attachments/assets/50f605a8-d658-47bd-9d29-85b7b6fa46dd)

**The compose box's `autocorrect` attribute**

The capture script added the dark label and blue outline; they are not
part of the app. The label is redrawn every frame from the compose box's
live `autocorrect` attribute.

![Default: the #Alpha compose box has autocorrect="off", shown in
red.](https://github.com/user-attachments/assets/af76c0be-3230-4df8-8385-fd518606aa94)

![After turning the setting on and closing Settings: the same compose
box has autocorrect="on", shown in
green.](https://github.com/user-attachments/assets/509630ee-8d58-4580-b936-d8edb3b20d49)

The other attributes read from the DOM were the same before and after:
`spellcheck="true"`, `autocapitalize="off"`, `autocomplete="off"`,
`writingsuggestions="false"`.

**The whole flow** (Playwright WebKit, 960×640, 36 s). Captions at the
top name each step and a red dot shows the pointer. Each step also
checked the attribute, so the take would have failed on a wrong value.


https://github.com/user-attachments/assets/50666188-bedd-450a-aa42-360bcafbcd28

## How it was verified

- **Vitest:** `AppearanceSettings.test.tsx` and `EditableInput.test.tsx`
both pass on `9d85550` (345 tests).
- The composer keeps `autocorrect="off"` until the device opts in, then
switches live, keeps the caret and keeps editing working. Breaking the
attribute or the effect dependency fails the test.
- The switch defaults off, saves, survives a remount and follows a
`storage` event. An unsaved choice stays active, and Retry saves that
same choice.
- A table test runs the real `macWebKit()` default against stubbed
`navigator` values. Mac WebKit shows the switch. Desktop-mode iPad
(`maxTouchPoints` 5), Chrome on Mac (vendor `Google Inc.`) and Linux
WebKitGTK (`Linux x86_64` with vendor `Apple Computer, Inc.`) hide it.
On `9d85550`, removing each check from `macWebKit()` failed exactly the
matching row (1 failed, 19 passed each time): platform → Linux
WebKitGTK, touch → iPad, vendor → Chrome on Mac.
- **Playwright WebKit** (temporary specs, not committed), using the real
app shell:
- On `9d85550` (the captures above): the switch appeared. Turning it on
set the composer to `autocorrect="on"`, which stayed after a reload, and
turning it off set it back to `"off"`.
- On `2a6205b`, before the label was reworded: Tab and Space operated
the switch, and Chromium did not show it. That run checked the row in
light and dark themes, at 1280 px and 390 px, and at 200% interface
size.
- **Native WKWebView probe:** a throwaway Swift app hosted the system
WKWebView, the same WebKit the desktop app uses. It loaded the real
compose box component from the `link-messages` test page, with the
preference set through `localStorage` before load. It then right-clicked
the compose box and read the context menu WebKit built. The probe ran on
`2a6205b`. The composer code has not changed since; the later commits
only change the Settings copy, the help text and tests.

![The real compose box in the macOS system WKWebView, with "See you
tomorow" typed. The header line shows the attribute read from the DOM:
"off" with the setting off (top) and "on" with it on
(bottom).](https://github.com/user-attachments/assets/d19c20b8-3e22-4f84-8cc9-dffbe4be5d62)

| Spelling and Grammar item | Setting off (`autocorrect="off"`) |
Setting on (`autocorrect="on"`) |
  |---|---|---|
  | Show Spelling and Grammar | enabled | enabled |
  | Check Document Now | enabled | enabled |
  | Check Grammar With Spelling | enabled, checked | enabled, checked |
| **Correct Spelling Automatically** | **disabled, unchecked** |
**enabled, checked** |

Asking WebKit directly whether `toggleAutomaticSpellingCorrection:` is
enabled gave the same answer. Both menus offered "tomorrow" as a
spelling suggestion, so spell checking works either way. The item was
checked with the setting on because the probe had no saved choice, so
WebKit followed this Mac's keyboard setting, which is on.
- typecheck and Biome passed for each commit, and `design:check` passed
on `2a6205b`. The later commits only change copy, docs and tests.
- No browser journeys were added or removed.

## Manual test on a real Mac keyboard

Synthetic key events never trigger macOS autocorrection, even in a
native text view, so this needs a person typing in the desktop app:

- [ ] Settings › Appearance › Conversations shows **Allow automatic
spelling correction**, switched off.
- [ ] With the setting off, right-click the message box › **Spelling and
Grammar**. **Correct Spelling Automatically** is greyed out, as it is on
`main`.
- [ ] Turn the setting on. Right-click the message box › **Spelling and
Grammar**. **Correct Spelling Automatically** is now clickable. Make
sure it is checked.
- [ ] Type `teh ` with the trailing space. It changes to `the`.
- [ ] Type a misspelled word and press Enter straight away to send. The
last word may go out uncorrected, because macOS corrects at the next
word boundary and Enter sends instead of inserting one. This is
expected, not a regression.
- [ ] Type `teh ` inside inline code and inside a code block. It stays
`teh`, because code sets `spellcheck="false"`.
- [ ] Uncheck **Correct Spelling Automatically** in the menu. `teh ` is
no longer corrected.
- [ ] Turn the Buzz setting off. The menu item is greyed out again and
nothing is corrected.

## Remaining gaps

- The menu state comes from the WKWebView probe, not from the built
desktop app, and no screenshot of the native menu was taken. Real
autocorrection has not been observed; see the manual test above.
- At 390 px with 200% interface size, the shared `PreferenceRow` keeps
the switch in its own column, so the label wraps. This was not
re-checked with the longer label. It is a gap in the shared row layout
and is left unchanged here.
- iOS and iPadOS Safari also honour `autocorrect`, so phone and tablet
browser users still get no correction and no setting, the same as on
`main`.
- This branch was pushed with `--no-verify` at the author's request, so
the local pre-push hooks did not run. Hosted CI is the check.

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

---------

Signed-off-by: Matt Toohey <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
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.

1 participant