Merge remote-tracking branch 'misskey-dev/develop' into io

This commit is contained in:
まっちゃとーにゅ 2024-01-31 05:10:06 +09:00
commit 9ffa56aa1b
No known key found for this signature in database
GPG key ID: 143DE582A97FE052
200 changed files with 2833 additions and 4369 deletions

View file

@ -7,7 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<div
v-if="muted === false"
v-show="!isDeleted"
ref="el"
ref="rootEl"
v-hotkey="keymap"
:class="[$style.root, { [$style.showActionsOnlyHover]: defaultStore.state.showNoteActionsOnlyHover }]"
:tabindex="!isDeleted ? '-1' : undefined"
@ -72,16 +72,16 @@ SPDX-License-Identifier: AGPL-3.0-only
/>
<div v-if="translating || translation" :class="$style.translation">
<MkLoading v-if="translating" mini/>
<div v-else>
<div v-else-if="translation">
<b>{{ i18n.tsx.translatedFrom({ x: translation.sourceLang }) }}: </b>
<Mfm :text="translation.text" :author="appearNote.user" :nyaize="'respect'" :emojiUrls="appearNote.emojis"/>
</div>
</div>
</div>
<div v-if="appearNote.files.length > 0">
<div v-if="appearNote.files && appearNote.files.length > 0">
<MkMediaList :mediaList="appearNote.files"/>
</div>
<MkPoll v-if="appearNote.poll" :note="appearNote" :class="$style.poll"/>
<MkPoll v-if="appearNote.poll" :noteId="appearNote.id" :poll="appearNote.poll" :class="$style.poll"/>
<MkUrlPreview v-for="url in urls" :key="url" :url="url" :compact="true" :detail="false" :class="$style.urlPreview"/>
<div v-if="appearNote.renote" :class="$style.quote"><MkNoteSimple :note="appearNote.renote" :class="$style.quoteNote"/></div>
<button v-if="isLong && collapsed" :class="$style.collapsed" class="_button" @click="collapsed = false">
@ -126,7 +126,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<button v-if="defaultStore.state.showClipButtonInNoteFooter" ref="clipButton" :class="$style.footerButton" class="_button" @mousedown="clip()">
<i class="ti ti-paperclip"></i>
</button>
<button ref="menuButton" :class="$style.footerButton" class="_button" @mousedown="menu()">
<button ref="menuButton" :class="$style.footerButton" class="_button" @mousedown="showMenu()">
<i class="ti ti-dots"></i>
</button>
</footer>
@ -215,7 +215,7 @@ if (noteViewInterruptors.length > 0) {
let result: Misskey.entities.Note | null = deepClone(note.value);
for (const interruptor of noteViewInterruptors) {
try {
result = await interruptor.handler(result);
result = await interruptor.handler(result!) as Misskey.entities.Note | null;
if (result === null) {
isDeleted.value = true;
return;
@ -224,7 +224,7 @@ if (noteViewInterruptors.length > 0) {
console.error(err);
}
}
note.value = result;
note.value = result as Misskey.entities.Note;
});
}
@ -232,11 +232,11 @@ const isRenote = (
note.value.renote != null &&
note.value.text == null &&
note.value.cw == null &&
note.value.fileIds.length === 0 &&
note.value.fileIds && note.value.fileIds.length === 0 &&
note.value.poll == null
);
const el = shallowRef<HTMLElement>();
const rootEl = shallowRef<HTMLElement>();
const menuButton = shallowRef<HTMLElement>();
const renoteButton = shallowRef<HTMLElement>();
const renoteTime = shallowRef<HTMLElement>();
@ -254,8 +254,8 @@ const muted = ref(checkMute(appearNote.value, $i?.mutedWords));
const translation = ref<Misskey.entities.NotesTranslateResponse | null>(null);
const translating = ref(false);
const showTicker = (defaultStore.state.instanceTicker === 'always') || (defaultStore.state.instanceTicker === 'remote' && appearNote.value.user.instance);
const canRenote = computed(() => ['public', 'home'].includes(appearNote.value.visibility) || (appearNote.value.visibility === 'followers' && appearNote.value.userId === $i.id));
const renoteCollapsed = ref(defaultStore.state.collapseRenotes && isRenote && (($i && ($i.id === note.value.userId || $i.id === appearNote.value.userId)) || (appearNote.value.myReaction != null)));
const canRenote = computed(() => ['public', 'home'].includes(appearNote.value.visibility) || (appearNote.value.visibility === 'followers' && appearNote.value.userId === $i?.id));
const renoteCollapsed = ref(defaultStore.state.collapseRenotes && isRenote && (($i && ($i.id === note.value.userId || $i.id === appearNote.value.userId)) ?? (appearNote.value.myReaction != null)));
const hideMutedNotes = defaultStore.state.hideMutedNotes;
/* Overload FunctionLint
@ -278,11 +278,11 @@ function checkMute(noteToCheck: Misskey.entities.Note, mutedWords: Array<string
const keymap = {
'r': () => reply(true),
'e|a|plus': () => react(true),
'q': () => renoteButton.value.renote(true),
'q': () => renote(true),
'up|k|shift+tab': focusBefore,
'down|j|tab': focusAfter,
'esc': blur,
'm|o': () => menu(true),
'm|o': () => showMenu(true),
's': () => showContent.value !== showContent.value,
};
@ -299,7 +299,7 @@ if (props.mock) {
}, { deep: true });
} else {
useNoteCapture({
rootEl: el,
rootEl: rootEl,
note: appearNote,
pureNote: note,
isDeletedRef: isDeleted,
@ -345,7 +345,7 @@ function reply(viaKeyboard = false): void {
reply: appearNote.value,
channel: appearNote.value.channel,
animation: !viaKeyboard,
}, () => {
}).then(() => {
focus();
});
}
@ -364,7 +364,7 @@ function react(viaKeyboard = false): void {
noteId: appearNote.value.id,
reaction: '❤️',
});
const el = reactButton.value as HTMLElement | null | undefined;
const el = reactButton.value;
if (el) {
const rect = el.getBoundingClientRect();
const x = rect.left + (el.offsetWidth / 2);
@ -373,7 +373,7 @@ function react(viaKeyboard = false): void {
}
} else {
blur();
reactionPicker.show(reactButton.value, reaction => {
reactionPicker.show(reactButton.value ?? null, reaction => {
sound.playMisskeySfx('reaction');
if (props.mock) {
@ -394,8 +394,8 @@ function react(viaKeyboard = false): void {
}
}
function undoReact(note): void {
const oldReaction = note.myReaction;
function undoReact(targetNote: Misskey.entities.Note): void {
const oldReaction = targetNote.myReaction;
if (!oldReaction) return;
if (props.mock) {
@ -404,7 +404,7 @@ function undoReact(note): void {
}
misskeyApi('notes/reactions/delete', {
noteId: note.id,
noteId: targetNote.id,
});
}
@ -413,32 +413,34 @@ function onContextmenu(ev: MouseEvent): void {
return;
}
const isLink = (el: HTMLElement) => {
const isLink = (el: HTMLElement): boolean => {
if (el.tagName === 'A') return true;
// Audio
if (el.tagName === 'AUDIO') return true;
if (el.parentElement) {
return isLink(el.parentElement);
}
return false;
};
if (isLink(ev.target)) return;
if (window.getSelection().toString() !== '') return;
if (ev.target && isLink(ev.target as HTMLElement)) return;
if (window.getSelection()?.toString() !== '') return;
if (defaultStore.state.useReactionPickerForContextMenu) {
ev.preventDefault();
react();
} else {
const { menu, cleanup } = getNoteMenu({ note: note.value, translating, translation, menuButton, isDeleted, currentClip: currentClip?.value });
const { menu, cleanup } = getNoteMenu({ note: note.value, translating, translation, isDeleted, currentClip: currentClip?.value });
os.contextMenu(menu, ev).then(focus).finally(cleanup);
}
}
function menu(viaKeyboard = false): void {
function showMenu(viaKeyboard = false): void {
if (props.mock) {
return;
}
const { menu, cleanup } = getNoteMenu({ note: note.value, translating, translation, menuButton, isDeleted, currentClip: currentClip?.value });
const { menu, cleanup } = getNoteMenu({ note: note.value, translating, translation, isDeleted, currentClip: currentClip?.value });
os.popupMenu(menu, menuButton.value, {
viaKeyboard,
}).then(focus).finally(cleanup);
@ -485,7 +487,7 @@ function showRenoteMenu(viaKeyboard = false): void {
getCopyNoteLinkMenu(note.value, i18n.ts.copyLinkRenote),
{ type: 'divider' },
getAbuseNoteMenu(note.value, i18n.ts.reportAbuseRenote),
$i.isModerator || $i.isAdmin ? getUnrenote() : undefined,
($i?.isModerator || $i?.isAdmin) ? getUnrenote() : undefined,
], renoteTime.value, {
viaKeyboard: viaKeyboard,
});
@ -493,19 +495,19 @@ function showRenoteMenu(viaKeyboard = false): void {
}
function focus() {
el.value.focus();
rootEl.value?.focus();
}
function blur() {
el.value.blur();
rootEl.value?.blur();
}
function focusBefore() {
focusPrev(el.value);
focusPrev(rootEl.value ?? null);
}
function focusAfter() {
focusNext(el.value);
focusNext(rootEl.value ?? null);
}
function readPromo() {