feat: mute CRDT sync chrome and move bold onto ⌘B - #78
Merged
Conversation
Two small chrome/keymap locks from #77. Offline chrome: CRDT sync status no longer reuses the red `.zed-save-error` alert. `crdtSyncChrome()` maps the transport status to a muted `.zed-titlebar__sync` mark placed to the LEFT of Publish — no border, no fill, `role="status"`. A CRDT edit is already durable in IndexedDB, so a 2-second reconnect blip is not an alarm. The red block stays exactly as it was for real legacy failures (session expired / conflict), which is why it is now gated on `!CRDT_ENABLED`. Also closes the #75 residual: `loading` and `syncing` used to collapse into "Saved", so a note still waiting on the WebSocket claimed to be saved while it was in fact read-only and unconfirmed. They now read "Syncing…". Shortcuts: ⌘B / Ctrl+B toggles `**bold**` in the editor, and the sidebar toggle moves to ⌘⇧B. The window-level keydown had to stop matching plain meta+b entirely rather than yield to the editor — it listens on `window`, so a CodeMirror keymap's preventDefault would not have stopped it from also firing. ⌘\ and ⌘N are unchanged. `toggleStrikethrough`'s wrap/unwrap/caret logic is extracted to `toggleInlineMark(view, mark)` now that bold is a second real caller, and picks up the unit tests strikethrough never had (both marks run the same table, including the single-undo-step guarantee).
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
23 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PR-A of #77. Two small, independently reviewable locks: the Offline indicator stops looking like a hard error, and ⌘B becomes bold.
Offline chrome
.zed-save-errorpaints a red bordered alert box. On the CRDT path that fires for a transient WebSocket reconnect — a state where nothing is wrong, because the edit is already durable in IndexedDB and will flush. That is alarm fatigue for a non-event.New
crdtSyncChrome()(lib/crdt/sync-chrome.ts) maps transport status to a muted.zed-titlebar__syncmark placed to the left of Publish: no border, no fill,var(--c-text-muted),role="status"rather thanrole="alert". Copy and tooltip are unchanged ("Offline" / saved on this device), and Retry is offered only where a manual flush means something.loading/syncing.zed-titlebar__syncoffline.zed-titlebar__syncsyncedauth/conflict/generic.zed-save-errorThe red block is now gated on
!CRDT_ENABLED— real failures on the legacy whole-document path keep their strong chrome, deliberately.This also closes the #75 residual.
loadingandsyncingboth used to collapse into"saved", so a note still waiting on the WebSocket read "Saved" while it was actually read-only and unconfirmed. They now read "Syncing…".⌘B bold / ⌘⇧B sidebar
⌘B / Ctrl+B toggles
**bold**— wrap a selection, unwrap when the markers are inside or just outside it, and on an empty caret insert****with the caret centered. Oneinputhistory event, so ⌘Z undoes it in a single step. It is a plainview.dispatch, soyCollabcarries it intoY.Texton the CRDT path for free.The sidebar moves to ⌘⇧B. Note the window-level keydown had to stop matching plain
meta+bentirely rather than merely lose priority: it listens onwindow, and a CodeMirror keymap'spreventDefault()does not stop propagation, so leaving it would have toggled the sidebar and bolded on every press.⌘\and⌘Nare untouched.On macOS
defaultKeymapbinds emacs-styleCtrl-btocursorCharLeft; our binding isMod-b= Cmd there, so they do not collide. On Linux/WindowsMod-b=Ctrl-b, whichdefaultKeymapdoes not bind. Bound atPrec.highanyway, matchingagentnoteStrikethroughKeymap.Shared toggle helper
toggleStrikethrough's wrap/unwrap/caret logic moved totoggleInlineMark(view, mark)now that bold is a second real caller — an abstraction with two concrete users, not a speculative one. Strikethrough's behavior is unchanged by construction (same function, same constant), and it picks up the unit tests it never had: both marks run the same table.Tests
pnpm vitest run— 259 passed (was 239; +20).lib/editor/toggle-mark.test.ts— wrap, unwrap-from-inside, unwrap-from-outside, empty-caret insert, multi-range, single-undo-step, round-trip, read-only refusal; run against both**and~~.lib/crdt/sync-chrome.test.ts—syncedrenders nothing;offlinelabels Offline + retry and keeps the "Saved on this device" copy;loading/syncingread "Syncing…" and never "Saved".pnpm exec tsc --noEmitclean.pnpm buildgreen.pnpm lintreports 9 errors / 6 warnings — all pre-existing. Verified by running eslint against a clean checkout ofmain: byte-identical counts. They arereact-hooks/refsandreact-hooks/set-state-in-effectfindings inagentnote-app.tsx,codemirror-editor.tsx, andpublish-panel.tsxfrom a newereslint-config-next. This PR adds none and fixes none (out of scope).Manual QA
Run with
NEXT_PUBLIC_AGENTNOTE_CRDT=1.**word**. ⌘B again → unwrapped. ⌘Z once → back in a single step.****with the caret between the pairs.NEXT_PUBLIC_AGENTNOTE_CRDT=0, two tabs, force a 409 → redzed-save-errorstill appears with Use server / Overwrite.activeId, so the app does not sit on a permanent "Syncing…").Refs #77. PR-B (wiki-style
[[links + tags) follows and depends on nothing here.🤖 Generated with Claude Code