diff --git a/apps/admin-web/src/views/ArticleEditorView.vue b/apps/admin-web/src/views/ArticleEditorView.vue index 0af5d5e..e4bfd6b 100644 --- a/apps/admin-web/src/views/ArticleEditorView.vue +++ b/apps/admin-web/src/views/ArticleEditorView.vue @@ -2,7 +2,7 @@ import { LeftOutlined } from "@ant-design/icons-vue"; import { useMutation, useQuery, useQueryClient } from "@tanstack/vue-query"; import { message } from "ant-design-vue"; -import { computed, ref, watch } from "vue"; +import { computed, onBeforeUnmount, onMounted, ref, watch } from "vue"; import { useI18n } from "vue-i18n"; import { useRoute, useRouter } from "vue-router"; @@ -187,6 +187,20 @@ async function handleSave(): Promise { await saveArticle(); } +function handleSaveShortcut(event: KeyboardEvent): void { + if (!(event.ctrlKey || event.metaKey) || event.key.toLowerCase() !== "s") { + return; + } + + event.preventDefault(); + event.stopPropagation(); + if (event.repeat || saveDisabled.value) { + return; + } + + void handleSave(); +} + async function handlePublish(): Promise { if (editorLocked.value) { return; @@ -344,6 +358,14 @@ function serializePlatformSelection(platformIds: string[]): string { .sort() .join(","); } + +onMounted(() => { + window.addEventListener("keydown", handleSaveShortcut); +}); + +onBeforeUnmount(() => { + window.removeEventListener("keydown", handleSaveShortcut); +});