feat: add support for saving post by shortcut keys (#4510)

#### What type of PR is this?
/area editor
/area console


#### What this PR does / why we need it:
1. mac: 在编辑器中添加command+s保存文章
2. windows: 在编辑器中添加ctrl+s保存文章
#### Which issue(s) this PR fixes:

Fixes https://github.com/halo-dev/halo/issues/4340

#### Does this PR introduce a user-facing change?

```release-note
Console 端支持通过快捷键保存文章
```
pull/4533/head
Hilary Liu 2023-09-01 10:30:12 +08:00 committed by GitHub
parent 1892dce64b
commit 178c0704c8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 30 additions and 4 deletions

View File

@ -1,4 +1,5 @@
<script lang="ts" setup>
import { isMac } from "@/utils/device";
import { VButton } from "@halo-dev/components";
import { useMagicKeys } from "@vueuse/core";
import { computed, useAttrs, watchEffect } from "vue";
@ -19,8 +20,6 @@ const emit = defineEmits<{
(event: "submit"): void;
}>();
const isMac = /macintosh|mac os x/i.test(navigator.userAgent);
const attrs = useAttrs();
const buttonText = computed(() => {

View File

@ -0,0 +1,21 @@
import { isMac } from "@/utils/device";
import { useEventListener } from "@vueuse/core";
import { useDebounceFn } from "@vueuse/shared";
import { nextTick } from "vue";
export function useSaveKeybinding(fn: () => void) {
const debouncedFn = useDebounceFn(() => {
fn();
}, 300);
useEventListener(window, "keydown", (e: KeyboardEvent) => {
if (isMac ? e.metaKey : e.ctrlKey) {
if (e.key === "s") {
e.preventDefault();
nextTick(() => {
debouncedFn();
});
}
}
});
}

View File

@ -34,6 +34,7 @@ import {
useOverlayScrollbars,
type UseOverlayScrollbarsParams,
} from "overlayscrollbars-vue";
import { isMac } from "@/utils/device";
const route = useRoute();
const router = useRouter();
@ -70,8 +71,6 @@ const handleLogout = () => {
// Global Search
const globalSearchVisible = ref(false);
const isMac = /macintosh|mac os x/i.test(navigator.userAgent);
const handleGlobalSearchKeybinding = (e: KeyboardEvent) => {
const { key, ctrlKey, metaKey } = e;
if (key === "k" && ((ctrlKey && !isMac) || metaKey)) {

View File

@ -38,6 +38,7 @@ import { contentAnnotations } from "@/constants/annotations";
import { usePageUpdateMutate } from "./composables/use-page-update-mutate";
import { useAutoSaveContent } from "@/composables/use-auto-save-content";
import { useContentSnapshot } from "@/composables/use-content-snapshot";
import { useSaveKeybinding } from "@/composables/use-save-keybinding";
const router = useRouter();
const { t } = useI18n();
@ -365,6 +366,8 @@ const handlePreview = async () => {
previewModal.value = true;
previewPending.value = false;
};
useSaveKeybinding(handleSave);
</script>
<template>

View File

@ -38,6 +38,7 @@ import { usePostUpdateMutate } from "./composables/use-post-update-mutate";
import { contentAnnotations } from "@/constants/annotations";
import { useAutoSaveContent } from "@/composables/use-auto-save-content";
import { useContentSnapshot } from "@/composables/use-content-snapshot";
import { useSaveKeybinding } from "@/composables/use-save-keybinding";
const router = useRouter();
const { t } = useI18n();
@ -381,6 +382,8 @@ const handlePreview = async () => {
previewModal.value = true;
previewPending.value = false;
};
useSaveKeybinding(handleSave);
</script>
<template>

View File

@ -0,0 +1 @@
export const isMac = /macintosh|mac os x/i.test(navigator.userAgent);