Repository navigation
Add rich composer formatting and spoiler rendering - #203
Conversation
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>
|
On Wes’s behalf — Brain implemented and verified this conflict resolution. Merged
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>
|
On Wes’s behalf — Brain resolved the next main-branch conflict at Merged #202 ( 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. |
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>
…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]>
…-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
…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>
## 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**   **Dark theme**   **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.   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.  | 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]>
Authored and opened by Brain on Wes’s behalf.
Summary
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
1b100e4aNot 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.ba22d04crepairs the packed conversation assertion: explicitly accept the persisted version-1 document envelope while retaining exact text and both recipient spans. No production behavior change.1b100e4aadds 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.conversation+message-navigationfiles 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.Previous repair validation (
79ae265f)Integrated main
2cbe1b0cbefore repairs; its merge tree matched the failed hosted run. That repair head was79ae265f393417d2cc7d1abc4d3e8cf95340f16e.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.composer-bold,composer-formats,composer-links,mention-edit).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
Remaining gates
CI requiredplusDCO Checkat the final uninstrumented repair head, and obtain one required approving/code-owner review. GitHub currently reportsREVIEW_REQUIRED; no approval or merge is claimed.