feat: add many keyboard shortcuts
This commit is contained in:
@@ -110,7 +110,10 @@ const handleWindowKeyDown = async (event: KeyboardEvent) => {
|
|||||||
if (event.defaultPrevented) return;
|
if (event.defaultPrevented) return;
|
||||||
if (event.ctrlKey || event.metaKey || event.altKey) return;
|
if (event.ctrlKey || event.metaKey || event.altKey) return;
|
||||||
|
|
||||||
if (document.activeElement === document.body) {
|
const isInteractive = document.activeElement?.closest('input, textarea, button, a, select, [contenteditable="true"]');
|
||||||
|
if (isInteractive) return;
|
||||||
|
|
||||||
|
if (!isInteractive) {
|
||||||
const isPrintable = event.key.length === 1;
|
const isPrintable = event.key.length === 1;
|
||||||
|
|
||||||
if (isPrintable) {
|
if (isPrintable) {
|
||||||
|
|||||||
@@ -6,7 +6,8 @@ import type { ModelWithProvider, ProviderWithModels } from '~/composables/useMod
|
|||||||
import { sortByReleaseDate } from '~/utils/sort';
|
import { sortByReleaseDate } from '~/utils/sort';
|
||||||
|
|
||||||
const { openDialog } = useDialog();
|
const { openDialog } = useDialog();
|
||||||
const { allModels } = await useModels();
|
const { allModels } = useModels();
|
||||||
|
const { addShortcut } = useKeyboardShortcuts();
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
providers: ProviderWithModels[];
|
providers: ProviderWithModels[];
|
||||||
@@ -213,6 +214,14 @@ const handleSearchKeyDown = (event: KeyboardEvent) => {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const unbindShortcut = addShortcut(['ctrl', 'shift', 'm'], () => {
|
||||||
|
toggleDropdown();
|
||||||
|
});
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
unbindShortcut();
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|||||||
@@ -14,11 +14,6 @@ export const useKeyboardShortcuts = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleKeyDown = (event: KeyboardEvent) => {
|
const handleKeyDown = (event: KeyboardEvent) => {
|
||||||
const isInput = ['INPUT', 'TEXTAREA'].includes((event.target as HTMLElement).tagName);
|
|
||||||
if (isInput && !event.ctrlKey && !event.metaKey && event.key !== 'Escape') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const keys: string[] = [];
|
const keys: string[] = [];
|
||||||
if (event.ctrlKey) keys.push('ctrl');
|
if (event.ctrlKey) keys.push('ctrl');
|
||||||
if (event.metaKey) keys.push('meta');
|
if (event.metaKey) keys.push('meta');
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ const { sendMessage, regenerateMessage } = useChat(route.params.id as string);
|
|||||||
const { getAgent } = useAgents();
|
const { getAgent } = useAgents();
|
||||||
const { open: sidebarOpen, openSidebar } = useSidebar();
|
const { open: sidebarOpen, openSidebar } = useSidebar();
|
||||||
const { providers, allModels } = useModels();
|
const { providers, allModels } = useModels();
|
||||||
|
const { addShortcut } = useKeyboardShortcuts();
|
||||||
|
|
||||||
const agent = getAgent(route.params.id as string);
|
const agent = getAgent(route.params.id as string);
|
||||||
|
|
||||||
@@ -257,6 +258,52 @@ const activeGeneration = computed(() => {
|
|||||||
|
|
||||||
const { scrollToBottom } = useAutoScroll(chatPaneWrapper);
|
const { scrollToBottom } = useAutoScroll(chatPaneWrapper);
|
||||||
|
|
||||||
|
addShortcut(['ctrl', 'alt', 'n'], () => {
|
||||||
|
return navigateTo(`/agent/${route.params.id}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
addShortcut(['ctrl', 'shift', 'enter'], () => {
|
||||||
|
const lastMessage = topic.value?.messages?.at(-1);
|
||||||
|
if (lastMessage) {
|
||||||
|
handleRegenerate(lastMessage);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
addShortcut(['ctrl', 'shift', 'backspace'], () => {
|
||||||
|
const lastMessage = topic.value?.messages?.at(-1);
|
||||||
|
if (lastMessage) {
|
||||||
|
handleDelete(lastMessage);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
addShortcut(['ctrl', 'c'], () => {
|
||||||
|
if (activeGeneration.value === null) return;
|
||||||
|
|
||||||
|
handleCancel();
|
||||||
|
})
|
||||||
|
|
||||||
|
addShortcut(['alt', '['], async () => {
|
||||||
|
console.log("left");
|
||||||
|
|
||||||
|
const lastMessage = topic.value?.messages?.at(-1);
|
||||||
|
if (lastMessage && lastMessage.children.length > 0) {
|
||||||
|
await triplit.update('messages', lastMessage.id, {
|
||||||
|
focusedIndex: Math.max(0, lastMessage.focusedIndex! - 1)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
addShortcut(['alt', ']'], async () => {
|
||||||
|
console.log("right");
|
||||||
|
|
||||||
|
const lastMessage = topic.value?.messages?.at(-1);
|
||||||
|
if (lastMessage && lastMessage.children.length > 0) {
|
||||||
|
await triplit.update('messages', lastMessage.id, {
|
||||||
|
focusedIndex: Math.min(lastMessage.children.length, lastMessage.focusedIndex! + 1)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
scrollToBottom('instant');
|
scrollToBottom('instant');
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user