mirror of
https://github.com/frappe/books.git
synced 2024-11-10 07:40:55 +00:00
incr: add mods to shortcut class
This commit is contained in:
parent
384bc28ccd
commit
67f8879551
@ -55,7 +55,7 @@ import { checkForUpdates } from './utils/ipcCalls';
|
||||
import { updateConfigFiles } from './utils/misc';
|
||||
import { Search } from './utils/search';
|
||||
import { routeTo, systemLanguage } from './utils/ui';
|
||||
import { Shortcuts, useKeys } from './utils/vueUtils';
|
||||
import { getModKeyCode, Shortcuts, useKeys } from './utils/vueUtils';
|
||||
|
||||
export default {
|
||||
name: 'App',
|
||||
@ -69,6 +69,7 @@ export default {
|
||||
companyName: '',
|
||||
searcher: null,
|
||||
shortcuts: null,
|
||||
modKey: '',
|
||||
};
|
||||
},
|
||||
provide() {
|
||||
@ -76,6 +77,7 @@ export default {
|
||||
languageDirection: computed(() => this.languageDirection),
|
||||
searcher: computed(() => this.searcher),
|
||||
shortcuts: computed(() => this.shortcuts),
|
||||
modKey: computed(() => this.modKey),
|
||||
keys: computed(() => this.keys),
|
||||
};
|
||||
},
|
||||
@ -86,6 +88,7 @@ export default {
|
||||
WindowsTitleBar,
|
||||
},
|
||||
async mounted() {
|
||||
this.modKey = getModKeyCode(this.platform);
|
||||
this.shortcuts = new Shortcuts(this.keys);
|
||||
const lastSelectedFilePath = fyo.config.get(
|
||||
ConfigKeys.LastSelectedFilePath,
|
||||
|
@ -5,7 +5,7 @@
|
||||
<feather-icon name="search" class="w-4 h-4 me-1 text-gray-800" />
|
||||
<p>{{ t`Search` }}</p>
|
||||
<div class="text-gray-500 px-1 ms-4 text-sm">
|
||||
{{ modKey('k') }}
|
||||
{{ modKeyText('k') }}
|
||||
</div>
|
||||
</Button>
|
||||
</div>
|
||||
@ -195,7 +195,6 @@ import { getBgTextColorClass } from 'src/utils/colors';
|
||||
import { openLink } from 'src/utils/ipcCalls';
|
||||
import { docsPathMap } from 'src/utils/misc';
|
||||
import { getGroupLabelMap, searchGroups } from 'src/utils/search';
|
||||
import { getModKeyCode } from 'src/utils/vueUtils';
|
||||
import { nextTick } from 'vue';
|
||||
import Button from './Button.vue';
|
||||
import Modal from './Modal.vue';
|
||||
@ -212,7 +211,7 @@ export default {
|
||||
allowedLimits: [50, 100, 500, -1],
|
||||
};
|
||||
},
|
||||
inject: ['searcher', 'shortcuts'],
|
||||
inject: ['searcher', 'shortcuts', 'modKey'],
|
||||
components: { Modal, Button },
|
||||
async mounted() {
|
||||
if (fyo.store.isDevelopment) {
|
||||
@ -233,18 +232,20 @@ export default {
|
||||
openLink('https://docs.frappebooks.com/' + docsPathMap.Search);
|
||||
},
|
||||
getShortcuts() {
|
||||
const modKey = getModKeyCode(this.platform);
|
||||
const ifOpen = (cb) => () => this.openModal && cb();
|
||||
const ifClose = (cb) => () => !this.openModal && cb();
|
||||
|
||||
const shortcuts = [
|
||||
{ shortcut: ['KeyK', modKey], callback: ifClose(() => this.open()) },
|
||||
{
|
||||
shortcut: ['KeyK', this.modKey],
|
||||
callback: ifClose(() => this.open()),
|
||||
},
|
||||
{ shortcut: ['Escape'], callback: ifOpen(() => this.close()) },
|
||||
];
|
||||
|
||||
for (const i in searchGroups) {
|
||||
shortcuts.push({
|
||||
shortcut: [modKey, `Digit${Number(i) + 1}`],
|
||||
shortcut: [this.modKey, `Digit${Number(i) + 1}`],
|
||||
callback: ifOpen(() => {
|
||||
const group = searchGroups[i];
|
||||
const value = this.searcher.filters.groupFilters[group];
|
||||
@ -261,15 +262,15 @@ export default {
|
||||
},
|
||||
setShortcuts() {
|
||||
for (const { shortcut, callback } of this.getShortcuts()) {
|
||||
this.shortcuts.set(shortcut, callback);
|
||||
this.shortcuts.meta.set(shortcut, callback);
|
||||
}
|
||||
},
|
||||
deleteShortcuts() {
|
||||
for (const { shortcut } of this.getShortcuts()) {
|
||||
this.shortcuts.delete(shortcut);
|
||||
this.shortcuts.meta.delete(shortcut);
|
||||
}
|
||||
},
|
||||
modKey(key) {
|
||||
modKeyText(key) {
|
||||
key = key.toUpperCase();
|
||||
if (this.platform === 'Mac') {
|
||||
return `⌘ ${key}`;
|
||||
|
@ -131,6 +131,7 @@ export default {
|
||||
DropdownWithActions,
|
||||
},
|
||||
emits: ['close'],
|
||||
inject: ['shortcuts'],
|
||||
provide() {
|
||||
return {
|
||||
schemaName: this.schemaName,
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { onMounted, onUnmounted, Ref, ref, watch } from 'vue';
|
||||
import { onMounted, onUnmounted, reactive, ref, unref, watch } from 'vue';
|
||||
|
||||
interface Keys {
|
||||
pressed: Set<string>;
|
||||
interface ModMap {
|
||||
alt: boolean;
|
||||
ctrl: boolean;
|
||||
meta: boolean;
|
||||
@ -9,11 +8,23 @@ interface Keys {
|
||||
repeat: boolean;
|
||||
}
|
||||
|
||||
export class Shortcuts {
|
||||
keys: Ref<Keys>;
|
||||
shortcuts: Map<string, Function>;
|
||||
type Mod = keyof ModMap;
|
||||
|
||||
constructor(keys?: Ref<Keys>) {
|
||||
interface Keys extends ModMap {
|
||||
pressed: Set<string>;
|
||||
}
|
||||
|
||||
type ShortcutFunction = () => void;
|
||||
|
||||
const mods: Readonly<Mod[]> = ['alt', 'ctrl', 'meta', 'repeat', 'shift'];
|
||||
|
||||
export class Shortcuts {
|
||||
keys: Keys;
|
||||
shortcuts: Map<string, ShortcutFunction>;
|
||||
modMap: Partial<Record<Mod, boolean>>;
|
||||
|
||||
constructor(keys?: Keys) {
|
||||
this.modMap = {};
|
||||
this.keys = keys ?? useKeys();
|
||||
this.shortcuts = new Map();
|
||||
|
||||
@ -23,17 +34,22 @@ export class Shortcuts {
|
||||
}
|
||||
|
||||
#trigger(keys: Keys) {
|
||||
const key = Array.from(keys.pressed).sort().join('+');
|
||||
const key = this.getKey(Array.from(keys.pressed), keys);
|
||||
this.shortcuts.get(key)?.();
|
||||
}
|
||||
|
||||
has(shortcut: string[]) {
|
||||
const key = shortcut.sort().join('+');
|
||||
const key = this.getKey(shortcut);
|
||||
return this.shortcuts.has(key);
|
||||
}
|
||||
|
||||
set(shortcut: string[], callback: Function, removeIfSet: boolean = true) {
|
||||
const key = shortcut.sort().join('+');
|
||||
set(
|
||||
shortcut: string[],
|
||||
callback: ShortcutFunction,
|
||||
removeIfSet: boolean = true
|
||||
) {
|
||||
const key = this.getKey(shortcut);
|
||||
|
||||
if (removeIfSet) {
|
||||
this.shortcuts.delete(key);
|
||||
}
|
||||
@ -46,13 +62,59 @@ export class Shortcuts {
|
||||
}
|
||||
|
||||
delete(shortcut: string[]) {
|
||||
const key = shortcut.sort().join('+');
|
||||
const key = this.getKey(shortcut);
|
||||
this.shortcuts.delete(key);
|
||||
}
|
||||
|
||||
getKey(shortcut: string[], modMap?: Partial<ModMap>): string {
|
||||
const _modMap = modMap || this.modMap;
|
||||
this.modMap = {};
|
||||
|
||||
const shortcutString = shortcut.sort().join('+');
|
||||
const modString = mods.filter((k) => _modMap[k]).join('+');
|
||||
if (shortcutString && modString) {
|
||||
return modString + '+' + shortcutString;
|
||||
}
|
||||
|
||||
if (!modString) {
|
||||
return shortcutString;
|
||||
}
|
||||
|
||||
if (!shortcutString) {
|
||||
return modString;
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
get alt() {
|
||||
this.modMap['alt'] = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
get ctrl() {
|
||||
this.modMap['ctrl'] = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
get meta() {
|
||||
this.modMap['meta'] = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
get shift() {
|
||||
this.modMap['shift'] = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
get repeat() {
|
||||
this.modMap['repeat'] = true;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
export function useKeys() {
|
||||
const keys: Ref<Keys> = ref({
|
||||
const keys: Keys = reactive({
|
||||
pressed: new Set<string>(),
|
||||
alt: false,
|
||||
ctrl: false,
|
||||
@ -62,20 +124,20 @@ export function useKeys() {
|
||||
});
|
||||
|
||||
const keydownListener = (e: KeyboardEvent) => {
|
||||
keys.value.pressed.add(e.code);
|
||||
keys.value.alt = e.altKey;
|
||||
keys.value.ctrl = e.ctrlKey;
|
||||
keys.value.meta = e.metaKey;
|
||||
keys.value.shift = e.shiftKey;
|
||||
keys.value.repeat = e.repeat;
|
||||
keys.pressed.add(e.code);
|
||||
keys.alt = e.altKey;
|
||||
keys.ctrl = e.ctrlKey;
|
||||
keys.meta = e.metaKey;
|
||||
keys.shift = e.shiftKey;
|
||||
keys.repeat = e.repeat;
|
||||
};
|
||||
|
||||
const keyupListener = (e: KeyboardEvent) => {
|
||||
keys.value.pressed.delete(e.code);
|
||||
keys.pressed.delete(e.code);
|
||||
|
||||
// Key up won't trigger on macOS for other keys.
|
||||
if (e.code === 'MetaLeft') {
|
||||
keys.value.pressed.clear();
|
||||
keys.pressed.clear();
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user