finish adding own shortcut handler

This commit is contained in:
Nitwel
2020-09-24 11:35:56 +02:00
parent fff2e81bdd
commit 3206b57918
9 changed files with 60 additions and 53 deletions

View File

@@ -34,13 +34,14 @@ export default defineComponent({
setup(props, { emit }) {
const dialog = ref<HTMLElement | null>(null);
useShortcut(
'esc',
() => {
console.log('A', dialog.value);
emit('toggle', false);
if (_active.value) {
emitToggle();
return true;
}
},
ref(document.body)
ref(document.body),
'escape'
);
const localActive = ref(false);

View File

@@ -295,11 +295,11 @@ export default defineComponent({
});
useShortcut(
'mod+a',
() => {
onToggleSelectAll(!allItemsSelected.value);
},
table
table,
'meta+a'
);
return {

View File

@@ -17,7 +17,7 @@ import { useShortcut } from '@/composables/use-shortcut';
export default defineComponent({
setup(props) {
useShortcut('mod+s', save);
useShortcut('meta+s', save);
function save() {
// ...

View File

@@ -1,19 +1,22 @@
import { onMounted, onUnmounted, Ref } from '@vue/composition-api';
import Vue from 'vue';
type ShortcutHandler = () => void;
type ShortcutHandler = (event: KeyboardEvent) => void | any | boolean;
let keysdown: string[] = [];
const keysdown: Set<string> = new Set([]);
const handlers: Record<string, ShortcutHandler[]> = {};
document.body.addEventListener('keydown', (event: KeyboardEvent) => {
console.log(event.CAPTURING_PHASE);
keysdown.push(mapKeys(event.key));
callHandlers();
if (event.repeat) return;
keysdown.add(mapKeys(event.key));
callHandlers(event);
});
document.body.addEventListener('keyup', (event: KeyboardEvent) => {
keysdown = keysdown.filter((key) => key === mapKeys(event.key));
const key = mapKeys(event.key);
keysdown.delete(key.toLowerCase());
keysdown.delete(key.toUpperCase());
});
function mapKeys(key: string) {
@@ -21,31 +24,31 @@ function mapKeys(key: string) {
Control: 'meta',
Command: 'meta',
};
return map.hasOwnProperty(key) ? map[key] : key;
}
key = map.hasOwnProperty(key) ? map[key] : key;
function callHandlers() {
Object.entries(handlers).forEach(([key, value]) => {
const rest = key.split('+').filter((keySegment) => keysdown.includes(keySegment) === false);
// strg+A strg+shift+aaaa
if (rest.length > 0) return;
value.forEach((f) => f());
});
}
function filterShortcut(shortcut: string) {
let sections = shortcut.split('+');
if (sections.find((s) => s.match(/^[A-Z]$/) !== null)) {
const filtered = sections.filter((s) => s.toLowerCase() === 'shift');
if (filtered.length % 2 === 0) {
sections.unshift('shift');
} else {
sections = sections.filter((s) => s.toLowerCase() !== 'shift');
}
return sections.join('+').toLowerCase();
if (key.match(/^[a-z]$/) !== null) {
if (keysdown.has('shift')) key = key.toUpperCase();
} else if (key.match(/^[A-Z]$/) !== null) {
if (keysdown.has('shift')) key = key.toLowerCase();
} else {
key = key.toLowerCase();
}
return shortcut.toLowerCase();
return key;
}
function callHandlers(event: KeyboardEvent) {
Object.entries(handlers).forEach(([key, value]) => {
const rest = key.split('+').filter((keySegment) => keysdown.has(keySegment) === false);
if (rest.length > 0) return;
event.preventDefault();
for (let i = 0; i < value.length; i++) {
const cancel = value[i](event);
// if the return value is true discontinue going through the queue.
if (typeof cancel === 'boolean' && cancel === true) break;
}
});
}
export default function useShortcut(
@@ -53,7 +56,7 @@ export default function useShortcut(
reference: Ref<HTMLElement | null> | Ref<Vue | null>,
...shortcuts: string[]
) {
const callback: ShortcutHandler = () => {
const callback: ShortcutHandler = (event) => {
if (reference.value === null) return;
const ref = reference.value instanceof HTMLElement ? reference.value : (reference.value.$el as HTMLElement);
@@ -62,24 +65,26 @@ export default function useShortcut(
ref.contains(document.activeElement) ||
document.activeElement === document.body
) {
handler();
return handler(event);
}
return false;
};
onMounted(() => {
shortcuts.forEach((shortcut) => {
const s = filterShortcut(shortcut);
if (handlers.hasOwnProperty(s)) {
handlers[s].unshift(callback);
if (handlers.hasOwnProperty(shortcut)) {
handlers[shortcut].unshift(callback);
} else {
handlers[s] = [callback];
handlers[shortcut] = [callback];
}
});
});
onUnmounted(() => {
shortcuts.forEach((shortcut) => {
const s = filterShortcut(shortcut);
if (handlers.hasOwnProperty(s)) {
handlers[s] = handlers[s].filter((f) => f !== callback);
if (handlers.hasOwnProperty(shortcut)) {
handlers[shortcut] = handlers[shortcut].filter((f) => f !== callback);
if (handlers[shortcut].length === 0) {
delete handlers[shortcut];
}
}
});
});

View File

@@ -225,7 +225,7 @@ export default defineComponent({
},
},
setup(props) {
const form = ref<Vue | null>(null);
const form = ref(null);
const userStore = useUserStore();
const { collection, primaryKey } = toRefs(props);
@@ -286,8 +286,8 @@ export default defineComponent({
return i18n.t('archive');
});
useShortcut('mod+s', saveAndStay, form);
useShortcut('mod+shift+s', saveAndAddNew, form);
useShortcut(saveAndStay, form, 'meta+s');
useShortcut(saveAndAddNew, form, 'meta+shift+s');
const navigationGuard: NavigationGuard = (to, from, next) => {
const hasEdits = Object.keys(edits.value).length > 0;

View File

@@ -293,7 +293,7 @@ export default defineComponent({
const { moveToDialogActive, moveToFolder, moving, selectedFolder } = useMovetoFolder();
useShortcut('mod+s', saveAndStay, form);
useShortcut(saveAndStay, form, 'meta+s');
return {
item,

View File

@@ -1,6 +1,7 @@
<template>
<v-modal
:active="active"
@toggle="cancelField"
:title="
field === '+'
? $t('creating_new_field', { collection: collectionInfo.name })

View File

@@ -293,8 +293,8 @@ export default defineComponent({
return i18n.t('archive');
});
useShortcut('mod+s', saveAndStay, form);
useShortcut('mod+shift+s', saveAndAddNew, form);
useShortcut(saveAndStay, form, 'meta+s');
useShortcut(saveAndAddNew, form, 'meta+shift+s');
return {
title,

View File

@@ -47,7 +47,7 @@ export default defineComponent({
},
setup(props) {
const textarea = ref<HTMLElement | null>(null);
useShortcut('mod+enter', postComment, textarea);
useShortcut(postComment, textarea, 'meta+enter');
const newCommentContent = ref<string | null>(null);
const saving = ref(false);