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

@ -85,7 +85,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<button v-tooltip="i18n.ts.useCw" class="_button" :class="[$style.footerButton, { [$style.footerButtonActive]: useCw }]" @click="useCw = !useCw"><i class="ti ti-eye-off"></i></button>
<button v-tooltip="i18n.ts.mention" class="_button" :class="$style.footerButton" @click="insertMention"><i class="ti ti-at"></i></button>
<button v-tooltip="i18n.ts.hashtags" class="_button" :class="[$style.footerButton, { [$style.footerButtonActive]: withHashtags }]" @click="withHashtags = !withHashtags"><i class="ti ti-hash"></i></button>
<button v-if="postFormActions.length > 0" v-tooltip="i18n.ts.plugin" class="_button" :class="$style.footerButton" @click="showActions"><i class="ti ti-plug"></i></button>
<button v-if="postFormActions.length > 0" v-tooltip="i18n.ts.plugins" class="_button" :class="$style.footerButton" @click="showActions"><i class="ti ti-plug"></i></button>
<button v-tooltip="i18n.ts.emoji" :class="['_button', $style.footerButton]" @click="insertEmoji"><i class="ti ti-mood-happy"></i></button>
<button v-if="showAddMfmFunction" v-tooltip="i18n.ts.addMfmFunction" :class="['_button', $style.footerButton]" @click="insertMfmFunction"><i class="ti ti-palette"></i></button>
</div>
@ -109,7 +109,7 @@ import { toASCII } from 'punycode/';
import MkNoteSimple from '@/components/MkNoteSimple.vue';
import MkNotePreview from '@/components/MkNotePreview.vue';
import XPostFormAttaches from '@/components/MkPostFormAttaches.vue';
import MkPollEditor from '@/components/MkPollEditor.vue';
import MkPollEditor, { type PollEditorModelValue } from '@/components/MkPollEditor.vue';
import { host, url } from '@/config.js';
import { erase, unique } from '@/scripts/array.js';
import { extractMentions } from '@/scripts/extract-mentions.js';
@ -140,13 +140,13 @@ const props = withDefaults(defineProps<{
renote?: Misskey.entities.Note;
channel?: Misskey.entities.Channel; // TODO
mention?: Misskey.entities.User;
specified?: Misskey.entities.User;
specified?: Misskey.entities.UserDetailed;
initialText?: string;
initialCw?: string;
initialVisibility?: (typeof Misskey.noteVisibilities)[number];
initialFiles?: Misskey.entities.DriveFile[];
initialLocalOnly?: boolean;
initialVisibleUsers?: Misskey.entities.User[];
initialVisibleUsers?: Misskey.entities.UserDetailed[];
initialNote?: Misskey.entities.Note;
instant?: boolean;
fixed?: boolean;
@ -179,12 +179,7 @@ const posting = ref(false);
const posted = ref(false);
const text = ref(props.initialText ?? '');
const files = ref(props.initialFiles ?? []);
const poll = ref<{
choices: string[];
multiple: boolean;
expiresAt: string | null;
expiredAfter: string | null;
} | null>(null);
const poll = ref<PollEditorModelValue | null>(null);
const useCw = ref<boolean>(!!props.initialCw);
const showPreview = ref(defaultStore.state.showPreview);
watch(showPreview, () => defaultStore.set('showPreview', showPreview.value));
@ -337,7 +332,7 @@ if (props.reply && ['home', 'followers', 'specified'].includes(props.reply.visib
if (visibility.value === 'specified') {
if (props.reply.visibleUserIds) {
misskeyApi('users/show', {
userIds: props.reply.visibleUserIds.filter(uid => uid !== $i.id && uid !== props.reply.userId),
userIds: props.reply.visibleUserIds.filter(uid => uid !== $i.id && uid !== props.reply?.userId),
}).then(users => {
users.forEach(pushVisibleUser);
});
@ -539,7 +534,7 @@ async function toggleReactionAcceptance() {
reactionAcceptance.value = select.result;
}
function pushVisibleUser(user) {
function pushVisibleUser(user: Misskey.entities.UserDetailed) {
if (!visibleUsers.value.some(u => u.username === user.username && u.host === user.host)) {
visibleUsers.value.push(user);
}
@ -581,10 +576,12 @@ function onCompositionEnd(ev: CompositionEvent) {
async function onPaste(ev: ClipboardEvent) {
if (props.mock) return;
if (!ev.clipboardData) return;
for (const { item, i } of Array.from(ev.clipboardData.items, (item, i) => ({ item, i }))) {
for (const { item, i } of Array.from(ev.clipboardData.items, (data, x) => ({ item: data, i: x }))) {
if (item.kind === 'file') {
const file = item.getAsFile();
if (!file) continue;
const lio = file.name.lastIndexOf('.');
const ext = lio >= 0 ? file.name.slice(lio) : '';
const formatted = `${formatTimeString(new Date(file.lastModified), defaultStore.state.pastedFileName).replace(/{{number}}/g, `${i + 1}`)}${ext}`;
@ -606,7 +603,7 @@ async function onPaste(ev: ClipboardEvent) {
return;
}
quoteId.value = paste.substring(url.length).match(/^\/notes\/(.+?)\/?$/)[1];
quoteId.value = paste.substring(url.length).match(/^\/notes\/(.+?)\/?$/)?.[1] ?? null;
});
}
}
@ -637,26 +634,26 @@ function onDragover(ev) {
}
}
function onDragenter(ev) {
function onDragenter() {
draghover.value = true;
}
function onDragleave(ev) {
function onDragleave() {
draghover.value = false;
}
function onDrop(ev): void {
function onDrop(ev: DragEvent): void {
draghover.value = false;
//
if (ev.dataTransfer.files.length > 0) {
if (ev.dataTransfer && ev.dataTransfer.files.length > 0) {
ev.preventDefault();
for (const x of Array.from(ev.dataTransfer.files)) upload(x);
return;
}
//#region
const driveFile = ev.dataTransfer.getData(_DATA_TRANSFER_DRIVE_FILE_);
const driveFile = ev.dataTransfer?.getData(_DATA_TRANSFER_DRIVE_FILE_);
if (driveFile != null && driveFile !== '') {
const file = JSON.parse(driveFile);
files.value.push(file);
@ -704,11 +701,14 @@ async function post(ev?: MouseEvent) {
}
if (ev) {
const el = ev.currentTarget ?? ev.target;
const rect = el.getBoundingClientRect();
const x = rect.left + (el.offsetWidth / 2);
const y = rect.top + (el.offsetHeight / 2);
os.popup(MkRippleEffect, { x, y }, {}, 'end');
const el = (ev.currentTarget ?? ev.target) as HTMLElement | null;
if (el) {
const rect = el.getBoundingClientRect();
const x = rect.left + (el.offsetWidth / 2);
const y = rect.top + (el.offsetHeight / 2);
os.popup(MkRippleEffect, { x, y }, {}, 'end');
}
}
if (props.mock) return;
@ -777,18 +777,18 @@ async function post(ev?: MouseEvent) {
if (notePostInterruptors.length > 0) {
for (const interruptor of notePostInterruptors) {
try {
postData = await interruptor.handler(deepClone(postData));
postData = await interruptor.handler(deepClone(postData)) as typeof postData;
} catch (err) {
console.error(err);
}
}
}
let token = undefined;
let token: string | undefined = undefined;
if (postAccount.value) {
const storedAccounts = await getAccounts();
token = storedAccounts.find(x => x.id === postAccount.value.id)?.token;
token = storedAccounts.find(x => x.id === postAccount.value?.id)?.token;
}
posting.value = true;
@ -802,7 +802,7 @@ async function post(ev?: MouseEvent) {
deleteDraft();
emit('posted');
if (postData.text && postData.text !== '') {
const hashtags_ = mfm.parse(postData.text).filter(x => x.type === 'hashtag').map(x => x.props.hashtag);
const hashtags_ = mfm.parse(postData.text).map(x => x.type === 'hashtag' && x.props.hashtag).filter(x => x) as string[];
const history = JSON.parse(miLocalStorage.getItem('hashtags') ?? '[]') as string[];
miLocalStorage.setItem('hashtags', JSON.stringify(unique(hashtags_.concat(history))));
}
@ -870,7 +870,7 @@ function insertMention() {
});
}
function insertEmoji(ev: MouseEvent): void {
async function insertEmoji(ev: MouseEvent) {
os.openEmojiPicker(
(ev.currentTarget ?? ev.target) as HTMLElement,
{ asReactionPicker: false },
@ -879,6 +879,7 @@ function insertEmoji(ev: MouseEvent): void {
}
async function insertMfmFunction(ev: MouseEvent) {
if (textareaEl.value == null) return;
mfmFunctionPicker(
ev.currentTarget ?? ev.target,
textareaEl.value,
@ -886,14 +887,15 @@ async function insertMfmFunction(ev: MouseEvent) {
);
}
function showActions(ev) {
function showActions(ev: MouseEvent) {
os.popupMenu(postFormActions.map(action => ({
text: action.title,
action: () => {
action.handler({
text: text.value,
cw: cw.value,
}, (key, value) => {
}, (key, value: any) => {
if (typeof key !== 'string') return;
if (key === 'text') { text.value = value; }
if (key === 'cw') { useCw.value = value !== null; cw.value = value; }
});
@ -954,19 +956,19 @@ onMounted(() => {
if (props.initialNote) {
const init = props.initialNote;
text.value = init.text ? init.text : '';
files.value = init.files;
cw.value = init.cw;
files.value = init.files ?? [];
cw.value = init.cw ?? null;
useCw.value = init.cw != null;
if (init.poll) {
poll.value = {
choices: init.poll.choices.map(x => x.text),
multiple: init.poll.multiple,
expiresAt: init.poll.expiresAt,
expiredAfter: init.poll.expiredAfter,
expiresAt: init.poll.expiresAt ? (new Date(init.poll.expiresAt)).getTime() : null,
expiredAfter: null,
};
}
visibility.value = init.visibility;
localOnly.value = init.localOnly;
localOnly.value = init.localOnly ?? false;
quoteId.value = init.renote ? init.renote.id : null;
}