Merge branch 'develop' into feat-1714

This commit is contained in:
かっこかり
2024-07-11 17:06:22 +09:00
committed by GitHub
27 changed files with 414 additions and 232 deletions

View File

@@ -82,6 +82,7 @@ import type { MenuItem } from '@/types/menu.js';
import { defaultStore } from '@/store.js';
import { i18n } from '@/i18n.js';
import * as os from '@/os.js';
import { type Keymap } from '@/scripts/hotkey.js';
import bytes from '@/filters/bytes.js';
import { hms } from '@/filters/hms.js';
import MkMediaRange from '@/components/MkMediaRange.vue';
@@ -94,29 +95,41 @@ const props = defineProps<{
const inEmbedPage = inject<boolean>('EMBED_PAGE', false);
const keymap = {
'up': () => {
if (inEmbedPage) return;
if (hasFocus() && audioEl.value) {
volume.value = Math.min(volume.value + 0.1, 1);
}
'up': {
allowRepeat: true,
callback: () => {
if (inEmbedPage) return;
if (hasFocus() && audioEl.value) {
volume.value = Math.min(volume.value + 0.1, 1);
}
},
},
'down': () => {
if (inEmbedPage) return;
if (hasFocus() && audioEl.value) {
volume.value = Math.max(volume.value - 0.1, 0);
}
'down': {
allowRepeat: true,
callback: () => {
if (inEmbedPage) return;
if (hasFocus() && audioEl.value) {
volume.value = Math.max(volume.value - 0.1, 0);
}
},
},
'left': () => {
if (inEmbedPage) return;
if (hasFocus() && audioEl.value) {
audioEl.value.currentTime = Math.max(audioEl.value.currentTime - 5, 0);
}
'left': {
allowRepeat: true,
callback: () => {
if (inEmbedPage) return;
if (hasFocus() && audioEl.value) {
audioEl.value.currentTime = Math.max(audioEl.value.currentTime - 5, 0);
}
},
},
'right': () => {
if (inEmbedPage) return;
if (hasFocus() && audioEl.value) {
audioEl.value.currentTime = Math.min(audioEl.value.currentTime + 5, audioEl.value.duration);
}
'right': {
allowRepeat: true,
callback: () => {
if (inEmbedPage) return;
if (hasFocus() && audioEl.value) {
audioEl.value.currentTime = Math.min(audioEl.value.currentTime + 5, audioEl.value.duration);
}
},
},
'space': () => {
if (inEmbedPage) return;
@@ -124,7 +137,7 @@ const keymap = {
togglePlayPause();
}
},
};
} as const satisfies Keymap;
// PlayerElもしくはその子要素にフォーカスがあるかどうか
function hasFocus() {

View File

@@ -113,6 +113,7 @@ SPDX-License-Identifier: AGPL-3.0-only
import { ref, shallowRef, computed, watch, inject, onDeactivated, onActivated, onMounted } from 'vue';
import * as Misskey from 'misskey-js';
import type { MenuItem } from '@/types/menu.js';
import { type Keymap } from '@/scripts/hotkey.js';
import bytes from '@/filters/bytes.js';
import { hms } from '@/filters/hms.js';
import { defaultStore } from '@/store.js';
@@ -130,29 +131,41 @@ const props = defineProps<{
const inEmbedPage = inject<boolean>('EMBED_PAGE', false);
const keymap = {
'up': () => {
if (inEmbedPage) return;
if (hasFocus() && videoEl.value) {
volume.value = Math.min(volume.value + 0.1, 1);
}
'up': {
allowRepeat: true,
callback: () => {
if (inEmbedPage) return;
if (hasFocus() && videoEl.value) {
volume.value = Math.min(volume.value + 0.1, 1);
}
},
},
'down': () => {
if (inEmbedPage) return;
if (hasFocus() && videoEl.value) {
volume.value = Math.max(volume.value - 0.1, 0);
}
'down': {
allowRepeat: true,
callback: () => {
if (inEmbedPage) return;
if (hasFocus() && videoEl.value) {
volume.value = Math.max(volume.value - 0.1, 0);
}
},
},
'left': () => {
if (inEmbedPage) return;
if (hasFocus() && videoEl.value) {
videoEl.value.currentTime = Math.max(videoEl.value.currentTime - 5, 0);
}
'left': {
allowRepeat: true,
callback: () => {
if (inEmbedPage) return;
if (hasFocus() && videoEl.value) {
videoEl.value.currentTime = Math.max(videoEl.value.currentTime - 5, 0);
}
},
},
'right': () => {
if (inEmbedPage) return;
if (hasFocus() && videoEl.value) {
videoEl.value.currentTime = Math.min(videoEl.value.currentTime + 5, videoEl.value.duration);
}
'right': {
allowRepeat: true,
callback: () => {
if (inEmbedPage) return;
if (hasFocus() && videoEl.value) {
videoEl.value.currentTime = Math.min(videoEl.value.currentTime + 5, videoEl.value.duration);
}
},
},
'space': () => {
if (inEmbedPage) return;
@@ -160,7 +173,7 @@ const keymap = {
togglePlayPause();
}
},
};
} as const satisfies Keymap;
// PlayerElもしくはその子要素にフォーカスがあるかどうか
function hasFocus() {

View File

@@ -98,6 +98,7 @@ import { MenuItem, InnerMenuItem, MenuPending, MenuAction, MenuSwitch, MenuRadio
import * as os from '@/os.js';
import { i18n } from '@/i18n.js';
import { isTouchUsing } from '@/scripts/touch.js';
import { type Keymap } from '@/scripts/hotkey.js';
const childrenCache = new WeakMap<MenuParent, MenuItem[]>();
</script>
@@ -125,11 +126,20 @@ const items2 = ref<InnerMenuItem[]>();
const child = shallowRef<InstanceType<typeof XChild>>();
const keymap = computed(() => ({
'up|k|shift+tab': focusUp,
'down|j|tab': focusDown,
'esc': close,
}));
const keymap = {
'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>();

View File

@@ -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/hotkey.js';
function getFixedContainer(el: Element | null): Element | null {
if (el == null || el.tagName === 'BODY') return null;
@@ -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;

View File

@@ -217,6 +217,7 @@ import { showMovedDialog } from '@/scripts/show-moved-dialog.js';
import { shouldCollapsed } from '@/scripts/collapsed.js';
import { isEnabledUrlPreview } from '@/instance.js';
import { url } from '@/config.js';
import { type Keymap } from '@/scripts/hotkey.js';
const props = withDefaults(defineProps<{
note: Misskey.entities.Note;
@@ -314,15 +315,53 @@ function checkMute(noteToCheck: Misskey.entities.Note, mutedWords: Array<string
}
const keymap = {
'r': () => reply(true),
'e|a|plus': () => react(true),
'q': () => renote(true),
'up|k|shift+tab': focusBefore,
'down|j|tab': focusAfter,
'esc': blur,
'm|o': () => showMenu(true),
's': () => showContent.value !== showContent.value,
};
'r': () => {
if (renoteCollapsed.value) return;
reply();
},
'e|a|plus': () => {
if (renoteCollapsed.value) return;
react();
},
'q': () => {
if (renoteCollapsed.value) return;
renote();
},
'm': () => {
if (renoteCollapsed.value) return;
showMenu();
},
'c': () => {
if (renoteCollapsed.value) return;
if (!defaultStore.state.showClipButtonInNoteFooter) return;
clip();
},
'o': () => {
if (renoteCollapsed.value) return;
showMenu();
},
'v|enter': () => {
if (renoteCollapsed.value) {
renoteCollapsed.value = false;
} else if (appearNote.value.cw != null) {
showContent.value = !showContent.value;
} else if (isLong) {
collapsed.value = !collapsed.value;
}
},
'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', {

View File

@@ -233,6 +233,7 @@ import MkPagination, { type Paging } from '@/components/MkPagination.vue';
import MkReactionIcon from '@/components/MkReactionIcon.vue';
import MkButton from '@/components/MkButton.vue';
import { isEnabledUrlPreview } from '@/instance.js';
import { type Keymap } from '@/scripts/hotkey.js';
const props = withDefaults(defineProps<{
note: Misskey.entities.Note;
@@ -294,13 +295,24 @@ const replies = ref<Misskey.entities.Note[]>([]);
const canRenote = computed(() => ['public', 'home'].includes(appearNote.value.visibility) || appearNote.value.userId === $i?.id);
const keymap = {
'r': () => reply(true),
'e|a|plus': () => react(true),
'q': () => renote(true),
'esc': blur,
'm|o': () => showMenu(true),
's': () => showContent.value !== showContent.value,
};
'r': () => reply(),
'e|a|plus': () => react(),
'q': () => renote(),
'm': () => showMenu(),
'c': () => {
if (!defaultStore.state.showClipButtonInNoteFooter) return;
clip();
},
'v|enter': () => {
if (appearNote.value.cw != null) {
showContent.value = !showContent.value;
}
},
'esc': {
allowRepeat: true,
callback: () => blur(),
},
} as const satisfies Keymap;
provide('react', (reaction: string) => {
misskeyApi('notes/reactions/create', {