mirror of
https://github.com/olehomelchenko/astrolabe.git
synced 2026-08-08 02:02:33 +00:00
Add global keyboard EventRouter and unify publish (M6, §01D)
One module owns the document keydown listener and dispatches the shortcut map (Cmd/Ctrl+Shift+N / +K / +S / +, / Escape), platform-aware, via the single-source focus-utils interactive-context gate. Escape and Cmd/Ctrl+S run before the gate so save works while editing; the rest are suppressed mid-typing. Publish + its toast move into services/snippet-actions so the button and Cmd/Ctrl+S behave identically. Removes the ad-hoc keydown handler from App and Monaco's Cmd+S command.
This commit is contained in:
@@ -27,6 +27,7 @@ import { openModal } from '../modals/ModalCoordinator';
|
||||
import { useAppStore } from '../stores/AppStore';
|
||||
import { confirm } from '../stores/ConfirmStore';
|
||||
import { hasInlineData } from '../stores/ExtractStore';
|
||||
import { publishActiveSnippet } from '../services/snippet-actions';
|
||||
import { notify } from '../stores/NotificationStore';
|
||||
import { usePreviewStore } from '../stores/PreviewStore';
|
||||
import { selectActiveSnippet, selectShownText, useSnippetStore } from '../stores/SnippetStore';
|
||||
@@ -152,18 +153,9 @@ function EditorToolbar() {
|
||||
(s) => s.activeSnippetId !== null && hasInlineData(s.draftText),
|
||||
);
|
||||
|
||||
const handlePublish = () => {
|
||||
if (!useSnippetStore.getState().activeSnippetId) return;
|
||||
useSnippetStore.getState().publish();
|
||||
// Success confirmation (spec §03D). Per the council's toast-copy rule
|
||||
// (docs/architecture/10 → Toast copy), the title states the action and the
|
||||
// message adds the consequence rather than paraphrasing it.
|
||||
notify({
|
||||
kind: 'success',
|
||||
title: 'Snippet published',
|
||||
message: 'Your draft is now the published version.',
|
||||
});
|
||||
};
|
||||
// Publish + its success toast live in one place (services/snippet-actions) so
|
||||
// the button and the Cmd/Ctrl+S shortcut (EventRouter) behave identically.
|
||||
const handlePublish = publishActiveSnippet;
|
||||
|
||||
const handleRevert = async () => {
|
||||
const ok = await confirm({
|
||||
@@ -275,10 +267,10 @@ export function SpecEditor() {
|
||||
}
|
||||
});
|
||||
|
||||
// Cmd/Ctrl+S publishes the current draft (spec §03D → Publish).
|
||||
editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS, () => {
|
||||
if (useSnippetStore.getState().activeSnippetId) useSnippetStore.getState().publish();
|
||||
});
|
||||
// Cmd/Ctrl+S is owned globally by the EventRouter (docs/architecture/04 →
|
||||
// "bind listeners in exactly one place"), which publishes before the
|
||||
// interactive-context gate so it works while the editor has focus. Monaco
|
||||
// binds no default for Cmd+S, so the keystroke bubbles to that one handler.
|
||||
|
||||
return () => {
|
||||
sub.dispose();
|
||||
|
||||
Reference in New Issue
Block a user