feat: Add keyboard shortcuts for global search functionality

This commit is contained in:
KickCashew 2024-06-02 20:52:46 +08:00
parent d08a3817d1
commit cc345423c3
4 changed files with 91 additions and 0 deletions

View File

@ -4,6 +4,7 @@ import { NConfigProvider, darkTheme } from 'naive-ui';
import { useAppStore } from './store/modules/app';
import { useThemeStore } from './store/modules/theme';
import { naiveDateLocales, naiveLocales } from './locales/naive';
import { useKeyboardShortcuts } from './utils/keyboard-shortcut';
defineOptions({
name: 'App'
@ -21,6 +22,8 @@ const naiveLocale = computed(() => {
const naiveDateLocale = computed(() => {
return naiveDateLocales[appStore.locale];
});
useKeyboardShortcuts();
</script>
<template>

View File

@ -1,11 +1,34 @@
<script lang="ts" setup>
import { useBoolean } from '@sa/hooks';
import { onMounted, onUnmounted } from 'vue';
import { $t } from '@/locales';
import { useEventBus } from '@/utils/event-bus';
import { useAppStore } from '@/store/modules/app';
import SearchModal from './components/search-modal.vue';
defineOptions({ name: 'GlobalSearch' });
const { bool: show, toggle } = useBoolean();
const eventBus = useEventBus();
const appStore = useAppStore();
const checkShow = () => {
if (show.value) return;
if (appStore.themeDrawerVisible) {
appStore.closeThemeDrawer();
}
toggle();
};
onMounted(() => {
eventBus.on('searchShortcutKey', checkShow);
});
onUnmounted(() => {
eventBus.off('searchShortcutKey', checkShow);
});
</script>
<template>

34
src/utils/event-bus.ts Normal file
View File

@ -0,0 +1,34 @@
import { reactive } from 'vue';
type EventCallback = (...args: any[]) => void;
interface EventBus {
on(event: string, callback: EventCallback): void;
off(event: string, callback: EventCallback): void;
emit(event: string, ...args: any[]): void;
}
const eventBus = reactive<{
events: { [key: string]: EventCallback[] };
}>({
events: {}
});
export const useEventBus = (): EventBus => {
return {
on(event: string, callback: EventCallback) {
if (!eventBus.events[event]) {
eventBus.events[event] = [];
}
eventBus.events[event].push(callback);
},
off(event: string, callback: EventCallback) {
if (!eventBus.events[event]) return;
eventBus.events[event] = eventBus.events[event].filter(cb => cb !== callback);
},
emit(event: string, ...args: any[]) {
if (!eventBus.events[event]) return;
eventBus.events[event].forEach(callback => callback(...args));
}
};
};

View File

@ -0,0 +1,31 @@
import { onMounted, onUnmounted } from 'vue';
import { useEventBus } from '@/utils/event-bus';
type ShortcutHandler = (event: KeyboardEvent) => void;
const useKeyboardShortcuts = () => {
const eventBus = useEventBus();
const shortcuts: { [key: string]: ShortcutHandler } = {
k: (event: KeyboardEvent) => {
event.preventDefault();
eventBus.emit('searchShortcutKey');
}
};
const handleKeyDown = (event: KeyboardEvent) => {
if (event.ctrlKey && shortcuts[event.key]) {
shortcuts[event.key](event);
}
};
onMounted(() => {
window.addEventListener('keydown', handleKeyDown);
});
onUnmounted(() => {
window.removeEventListener('keydown', handleKeyDown);
});
};
export { useKeyboardShortcuts };