Extract key handler and conflict resolution logic from the ~390-line
customize-shortcut-dialog-inner into testable top-level defn- functions:
- customize-key-handler: key event state machine (~70 lines)
- compute-override-plan: pure conflict resolution for reassign
- compute-reset-plan: pure conflict resolution for reset-to-default
- matches-default-binding?: canonical default-binding comparison
Add persist-user-shortcuts-batch! to core.cljs to atomically persist
multiple binding changes in a single config read-modify-write cycle,
fixing a race condition where sequential persist-user-shortcut! calls
clobbered each other (config-handler/set-config! updates state async
via save-file! promise chain, so the second call reads stale data).
Fix reset-fn! to strip conflicting bindings before restoring defaults,
preventing error notifications from goog.ui.KeyboardShortcutHandler
duplicate key registration. Auto-close the customize popup 300ms after
reset so it doesn't float over a now-empty filtered list.
Clear user overrides (persist nil) when conflict stripping leaves a
binding that matches the action's default, so actions correctly
disappear from the "Custom" filter tab.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add ARIA live regions to feedback banners (role=alert/status)
- Add role=dialog and aria-label to customize popover
- Add aria-pressed to filter pill buttons
- Remove disabled rows from tab order
- Return focus to trigger on popover close
- Add shortcut-badge-in to prefers-reduced-motion
- Remove dead shortcut-conflicts-display component
- Replace js/console.warn with lambdaisland.glogi
- Merge duplicate cond branches in key handler
- Add missing :shortcut-id to left sidebar
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When browsing Settings > Keymap, shortcut keypresses now trigger the
visual animation but skip action execution, preventing overlays like
the command palette from opening on top of the settings modal.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove preventDefault from bubble-phase blocker so goog.events.KeyHandler
can resolve character keys via keypress — fixes plain letter key recording
- Add handlers-co-active? predicate to distinguish editing-only vs
non-editing-only handler groups, preventing false blocking conflicts
between mutually exclusive runtime contexts
- Restrict cross-handler conflicts to exact key matches only — chord prefix
matches (e.g., mod+c vs mod+c mod+s) live on separate handler instances
- Exclude internal-only :shortcut.handler/misc from conflict detection
- Quote each conflicting shortcut name individually in feedback banners
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add :group-global? true to get-conflicts-by-keys call so conflicts
from other global handlers (undo, redo) are detected when recording
- Add canonicalize-binding utility for order-independent binding comparison
- Fix name-with-meta modifier order to produce canonical ctrl+alt+meta+shift
- Fix override-fn! to use canonicalized comparison when removing conflicting
bindings, preventing silent failures from modifier order mismatches
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Flatten nested for-loops in conflicts list into a single binding form
and add missing React key on section elements. Simplify keyname to
single-arity by treating esc as a modifier-like key to always ignore.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Extract use-scoped-key-handler hook to deduplicate KeyHandler lifecycle
boilerplate between filter and customize popovers
- Add bubble-phase event blocker to prevent modifier combos (Cmd+K, Cmd+C)
from triggering global actions during shortcut recording
- Clamp global-listener-refcount to zero on cleanup for React strict mode
- Log shortcut-press animation errors instead of silently swallowing them
- Remove 5 orphaned i18n keys from old UI
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace old <code> tag shortcut rendering with proper shui/shortcut key
badges, add flex-wrap layout for multiple bindings, styled status labels
for "Custom:" and "Unset", and filter platform-inactive shortcuts from
the data layer to prevent empty rows.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rewrite the shortcut customization UI from a modal dialog to an inline
popover with a state machine (idle → recording → accepted/conflict).
Add cross-context conflict awareness with amber warnings for non-blocking
conflicts across handler groups, while keeping red blocking conflicts for
same-context collisions. Redesign Esc/Backspace semantics for consistency:
Esc always closes, Backspace always removes. Add Radix tooltip on Reassign
button and polish spacing, animations, and feedback banners.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove unused `interactive?` prop from shortcut component and all call sites
- Trigger `shortcut-press!` animation when shortcuts are invoked
- Update shortcut settings UI to use `shui/shortcut` instead of raw `<code>` elements
- Fix shortcut key min-width (fit-content → 20px) for consistent sizing
- Pass raw-binding through `render-keyboard-shortcut` for data attribute matching
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(lint): make worker/frontend separation lint work on Windows
* chore: update cljs:electron-watch script to include test flag
* chore: remove dead root dependencies
* chore(deps): converge better-sqlite3 to 12.6.2 across deps packages
* chore(deps): converge fs-extra to ^11.3.0 across package roots
* fix(test): correct parameters for create-if-not-exists function
* chore(deps): converge cljs-bean to 1.9.0 across deps roots
* fix(tests): escape regex in cljs:run-test script
* chore: pin root packageManager to yarn 1.22.22
* chore(build): replace del with fs.rmSync in gulp clean
* chore(build): replace npm-run-all with npm-run-all2
* chore(security): upgrade dompurify and unify sanitizer path
* chore(observability): upgrade web sentry to 8.x
* chore: remove unused react-draggable dependencies
* chore(ci): fix windows release artifact collection
* fix(build): create static dir before gulp clean scans it
* fix: update nbb-logseq dependency to version feat-db-v33
* fix(test): move start-time initialization after clone repo
* fix(deps): update nbb dependencies and adjust test script paths to compatible with windows path delimiter
* chore(deps): remove dead meander dependency
---------
Co-authored-by: Tienson Qin <tiensonqin@gmail.com>
- Remove references to old files under logseq/ e.g.
logseq/version-files
- Remove flashcard commands and translations that applied to file graph flashcards
- Remove unused electron and frontend events
- Remove timetracking config which was for file graphs
Removed all file graph uses of :block/namespace, :block/file, :block/type and
:block/properties except for graph-parser which still uses them for db
importer.
Removed all uses of :block/format except for graph-parser and
src/main/frontend
Also remove all file graph references in publishing and
add back publishing.db tests with db graph.
Also remove file graph behavior for cmd-k and files
* enhance(ux): add/remove #Page to toggle page/block
* enhance(ux): "p t" to set tags for selected blocks
Updated "p a" to toggle displaying all properties including hidden ones.
* feat: cmd+k move blocks
* fix: block could be converted to page and create invalid nodes
Pages with block namespace parents is nonsensical and pages in
property values led to multiple validation errors. Also guard
against class and property pages as namespace parents
* fix: warn on failed cut+paste or indent/outdent of page blocks. Better to warn than silent failure which leaves user confused on
what happened.
---------
Co-authored-by: Gabriel Horner <gabriel@logseq.com>
* feat: quick add
* enhance(ux): auto open block for editing for quick add
* enhance(ux): show notification after quick add
* add migration for quick add page