Skip to content

Commit

Permalink
improve(frontend): hotkeyの改修 (misskey-dev#234)
Browse files Browse the repository at this point in the history
  • Loading branch information
taiyme authored Jun 21, 2024
1 parent a1bd8a1 commit 678be14
Show file tree
Hide file tree
Showing 13 changed files with 253 additions and 189 deletions.
27 changes: 14 additions & 13 deletions packages/frontend/src/boot/main-boot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ import { useStream } from '@/stream.js';
import * as sound from '@/scripts/sound.js';
import { $i, signout, updateAccount } from '@/account.js';
import { ColdDeviceStorage, defaultStore } from '@/store.js';
import { makeHotkey } from '@/scripts/hotkey.js';
import { reactionPicker } from '@/scripts/reaction-picker.js';
import { miLocalStorage } from '@/local-storage.js';
import { claimAchievement, claimedAchievements } from '@/scripts/achievements.js';
import { initializeSw } from '@/scripts/initialize-sw.js';
import { deckStore } from '@/ui/deck/deck-store.js';
import { emojiPicker } from '@/scripts/emoji-picker.js';
import { mainRouter } from '@/router/main.js';
import { type Keymap, makeHotkey } from '@/scripts/tms/hotkey.js';

export async function mainBoot() {
const { isClientUpdated } = await common(() => createApp(
Expand Down Expand Up @@ -66,14 +66,6 @@ export async function mainBoot() {
});
}

const hotkeys = {
'd': (): void => {
defaultStore.set('darkMode', !defaultStore.state.darkMode);
},
's': (): void => {
mainRouter.push('/search');
},
};
try {
if (defaultStore.state.enableSeasonalScreenEffect) {
const month = new Date().getMonth() + 1;
Expand Down Expand Up @@ -102,9 +94,6 @@ export async function mainBoot() {
}

if ($i) {
// only add post shortcuts if logged in
hotkeys['p|n'] = post;

defaultStore.loaded.then(() => {
if (defaultStore.state.accountSetupWizard !== -1) {
popup(defineAsyncComponent(() => import('@/components/MkUserSetupDialog.vue')), {}, {}, 'closed');
Expand Down Expand Up @@ -308,7 +297,19 @@ export async function mainBoot() {
}

// shortcut
document.addEventListener('keydown', makeHotkey(hotkeys), { passive: false });
const keymap = {
'p|n': () => {
if ($i == null) return;
post();
},
'd': () => {
defaultStore.set('darkMode', !defaultStore.state.darkMode);
},
's': () => {
mainRouter.push('/search');
},
} as const satisfies Keymap;
document.addEventListener('keydown', makeHotkey(keymap), { passive: false });

initializeSw();
}
47 changes: 30 additions & 17 deletions packages/frontend/src/components/MkMediaAudio.vue
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ import { i18n } from '@/i18n.js';
import { popupMenu } from '@/os.js';
import { defaultStore } from '@/store.js';
import { getMediaMenu } from '@/scripts/tms/get-media-menu.js';
import { type Keymap } from '@/scripts/tms/hotkey.js';
import { useReactiveDriveFile } from '@/scripts/tms/use-reactive-drive-file.js';
import bytes from '@/filters/bytes.js';
import { hms } from '@/filters/hms.js';
Expand Down Expand Up @@ -184,32 +185,44 @@ const showAudioMenu = (ev: MouseEvent) => {
};

const keymap = {
'up': () => {
if (hasFocus() && audioEl.value) {
volume.value = Math.min(volume.value + 0.1, 1);
}
'up': {
allowRepeat: true,
callback: () => {
if (hasFocus() && audioEl.value) {
volume.value = Math.min(volume.value + 0.1, 1);
}
},
},
'down': () => {
if (hasFocus() && audioEl.value) {
volume.value = Math.max(volume.value - 0.1, 0);
}
'down': {
allowRepeat: true,
callback: () => {
if (hasFocus() && audioEl.value) {
volume.value = Math.max(volume.value - 0.1, 0);
}
},
},
'left': () => {
if (hasFocus() && audioEl.value) {
audioEl.value.currentTime = Math.max(audioEl.value.currentTime - 5, 0);
}
'left': {
allowRepeat: true,
callback: () => {
if (hasFocus() && audioEl.value) {
audioEl.value.currentTime = Math.max(audioEl.value.currentTime - 5, 0);
}
},
},
'right': () => {
if (hasFocus() && audioEl.value) {
audioEl.value.currentTime = Math.min(audioEl.value.currentTime + 5, audioEl.value.duration);
}
'right': {
allowRepeat: true,
callback: () => {
if (hasFocus() && audioEl.value) {
audioEl.value.currentTime = Math.min(audioEl.value.currentTime + 5, audioEl.value.duration);
}
},
},
'space': () => {
if (hasFocus()) {
togglePlayPause();
}
},
};
} as const satisfies Keymap;

// PlayerElもしくはその子要素にフォーカスがあるかどうか
function hasFocus() {
Expand Down
47 changes: 30 additions & 17 deletions packages/frontend/src/components/MkMediaVideo.vue
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ import { defaultStore } from '@/store.js';
import { isFullscreenNotSupported } from '@/scripts/device-kind.js';
import hasAudio from '@/scripts/media-has-audio.js';
import { getMediaMenu } from '@/scripts/tms/get-media-menu.js';
import { type Keymap } from '@/scripts/tms/hotkey.js';
import { useReactiveDriveFile } from '@/scripts/tms/use-reactive-drive-file.js';
import bytes from '@/filters/bytes.js';
import { hms } from '@/filters/hms.js';
Expand Down Expand Up @@ -247,32 +248,44 @@ const showVideoMenu = (ev: MouseEvent) => {
};

const keymap = {
'up': () => {
if (hasFocus() && videoEl.value) {
volume.value = Math.min(volume.value + 0.1, 1);
}
'up': {
allowRepeat: true,
callback: () => {
if (hasFocus() && videoEl.value) {
volume.value = Math.min(volume.value + 0.1, 1);
}
},
},
'down': () => {
if (hasFocus() && videoEl.value) {
volume.value = Math.max(volume.value - 0.1, 0);
}
'down': {
allowRepeat: true,
callback: () => {
if (hasFocus() && videoEl.value) {
volume.value = Math.max(volume.value - 0.1, 0);
}
},
},
'left': () => {
if (hasFocus() && videoEl.value) {
videoEl.value.currentTime = Math.max(videoEl.value.currentTime - 5, 0);
}
'left': {
allowRepeat: true,
callback: () => {
if (hasFocus() && videoEl.value) {
videoEl.value.currentTime = Math.max(videoEl.value.currentTime - 5, 0);
}
},
},
'right': () => {
if (hasFocus() && videoEl.value) {
videoEl.value.currentTime = Math.min(videoEl.value.currentTime + 5, videoEl.value.duration);
}
'right': {
allowRepeat: true,
callback: () => {
if (hasFocus() && videoEl.value) {
videoEl.value.currentTime = Math.min(videoEl.value.currentTime + 5, videoEl.value.duration);
}
},
},
'space': () => {
if (hasFocus()) {
togglePlayPause();
}
},
};
} as const satisfies Keymap;

// PlayerElもしくはその子要素にフォーカスがあるかどうか
function hasFocus() {
Expand Down
18 changes: 14 additions & 4 deletions packages/frontend/src/components/MkMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ import { i18n } from '@/i18n.js';
import { isTouchUsing } from '@/scripts/touch.js';
import { focusParent, isFocusable } from '@/scripts/tms/focus.js';
import { getNodeOrNull } from '@/scripts/tms/get-or-null.js';
import { type Keymap } from '@/scripts/tms/hotkey.js';

const childrenCache = new WeakMap<MenuParent, MenuItem[]>();
</script>
Expand Down Expand Up @@ -139,10 +140,19 @@ const items2 = ref<InnerMenuItem[]>();
const child = shallowRef<InstanceType<typeof XChild>>();

const keymap = {
'up|k|shift+tab': () => focusUp(),
'down|j|tab': () => focusDown(),
'esc': () => close(false),
};
'up|k|shift+tab': {
allowRepeat: true,
callback: () => focusUp(),
},
'down|j|tab': {
allowRepeat: true,
callback: () => focusDown(),
},
'esc': {
allowRepeat: true,
callback: () => close(false),
},
} as const satisfies Keymap;

const childShowingItem = ref<MenuItem | null>();

Expand Down
8 changes: 6 additions & 2 deletions packages/frontend/src/components/MkModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import * as os from '@/os.js';
import { isTouchUsing } from '@/scripts/touch.js';
import { defaultStore } from '@/store.js';
import { deviceKind } from '@/scripts/device-kind.js';
import { type Keymap } from '@/scripts/tms/hotkey.js';

function getFixedContainer(el: Element | null): Element | null {
if (el == null || el.tagName === 'BODY') return null;
Expand Down Expand Up @@ -154,8 +155,11 @@ if (type.value === 'drawer') {
}

const keymap = {
'esc': () => emit('esc'),
};
'esc': {
allowRepeat: true,
callback: () => emit('esc'),
},
} as const satisfies Keymap;

const MARGIN = 16;
const SCROLLBAR_THICKNESS = 16;
Expand Down
18 changes: 14 additions & 4 deletions packages/frontend/src/components/MkNote.vue
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ import { shouldCollapsed } from '@/scripts/collapsed.js';
import { isEnabledUrlPreview } from '@/instance.js';
import { focusPrev, focusNext } from '@/scripts/tms/focus.js';
import { getAppearNote } from '@/scripts/tms/get-appear-note.js';
import { type Keymap } from '@/scripts/tms/hotkey.js';
import { isQuote, isRenote } from '@/scripts/tms/is-renote.js';
import { tmsStore } from '@/tms/store.js';

Expand Down Expand Up @@ -326,10 +327,19 @@ const keymap = {
collapsed.value = !collapsed.value;
}
},
'esc': () => blur(),
'up|k|shift+tab': () => focusBefore(),
'down|j|tab': () => focusAfter(),
};
'esc': {
allowRepeat: true,
callback: () => blur(),
},
'up|k|shift+tab': {
allowRepeat: true,
callback: () => focusBefore(),
},
'down|j|tab': {
allowRepeat: true,
callback: () => focusAfter(),
},
} as const satisfies Keymap;

provide('react', (reaction: string) => {
misskeyApi('notes/reactions/create', {
Expand Down
8 changes: 6 additions & 2 deletions packages/frontend/src/components/MkNoteDetailed.vue
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ import MkReactionIcon from '@/components/MkReactionIcon.vue';
import MkButton from '@/components/MkButton.vue';
import { isEnabledUrlPreview } from '@/instance.js';
import { getAppearNote } from '@/scripts/tms/get-appear-note.js';
import { type Keymap } from '@/scripts/tms/hotkey.js';
import { isQuote, isRenote } from '@/scripts/tms/is-renote.js';
import { tmsStore } from '@/tms/store.js';

Expand Down Expand Up @@ -308,8 +309,11 @@ const keymap = {
showContent.value = !showContent.value;
}
},
'esc': () => blur(),
};
'esc': {
allowRepeat: true,
callback: () => blur(),
},
} as const satisfies Keymap;

provide('react', (reaction: string) => {
misskeyApi('notes/reactions/create', {
Expand Down
2 changes: 1 addition & 1 deletion packages/frontend/src/directives/hotkey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/

import { Directive } from 'vue';
import { makeHotkey } from '../scripts/hotkey.js';
import { makeHotkey } from '@/scripts/tms/hotkey.js';

export default {
mounted(el, binding) {
Expand Down
5 changes: 1 addition & 4 deletions packages/frontend/src/pages/antenna-timeline.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkStickyContainer>
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
<MkSpacer :contentMax="800">
<div ref="rootEl" v-hotkey.global="keymap">
<div ref="rootEl">
<div v-if="queue > 0" :class="$style.new"><button class="_buttonPrimary" :class="$style.newButton" @click="top()">{{ i18n.ts.newNoteRecived }}</button></div>
<div :class="$style.tl">
<MkTimeline
Expand Down Expand Up @@ -44,9 +44,6 @@ const antenna = ref<Misskey.entities.Antenna | null>(null);
const queue = ref(0);
const rootEl = shallowRef<HTMLElement>();
const tlEl = shallowRef<InstanceType<typeof MkTimeline>>();
const keymap = computed(() => ({
't': focus,
}));

function queueUpdated(q) {
queue.value = q;
Expand Down
5 changes: 1 addition & 4 deletions packages/frontend/src/pages/timeline.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<template #header><MkPageHeader v-model:tab="src" :actions="headerActions" :tabs="$i ? headerTabs : headerTabsWhenNotLogin" :displayMyAvatar="true"/></template>
<MkSpacer :contentMax="800">
<MkHorizontalSwipe v-model:tab="src" :tabs="$i ? headerTabs : headerTabsWhenNotLogin">
<div :key="src" ref="rootEl" v-hotkey.global="keymap">
<div :key="src" ref="rootEl">
<MkInfo v-if="['home', 'local', 'social', 'global'].includes(src) && !defaultStore.reactiveState.timelineTutorials.value[src]" style="margin-bottom: var(--margin);" closable @close="closeTutorial()">
{{ i18n.ts._timelineDescription[src] }}
</MkInfo>
Expand Down Expand Up @@ -58,9 +58,6 @@ provide('shouldOmitHeaderTitle', true);

const isLocalTimelineAvailable = ($i == null && instance.policies.ltlAvailable) || ($i != null && $i.policies.ltlAvailable);
const isGlobalTimelineAvailable = ($i == null && instance.policies.gtlAvailable) || ($i != null && $i.policies.gtlAvailable);
const keymap = {
't': focus,
};

const tlComponent = shallowRef<InstanceType<typeof MkTimeline>>();
const rootEl = shallowRef<HTMLElement>();
Expand Down
Loading

0 comments on commit 678be14

Please sign in to comment.