From 095ac9d9296ba4a0ce928c0111c9fab5894af8a8 Mon Sep 17 00:00:00 2001 From: Freeplay Date: Tue, 16 May 2023 18:18:07 -0400 Subject: [PATCH 1/2] Add loading spinners + remove unused --- .../client/src/components/MkNoteDetailed.vue | 65 ++++--------------- 1 file changed, 11 insertions(+), 54 deletions(-) diff --git a/packages/client/src/components/MkNoteDetailed.vue b/packages/client/src/components/MkNoteDetailed.vue index aff9b792cd..b1caca1609 100644 --- a/packages/client/src/components/MkNoteDetailed.vue +++ b/packages/client/src/components/MkNoteDetailed.vue @@ -10,11 +10,13 @@ :class="{ renote: isRenote }" > + +
@@ -66,31 +70,18 @@ import { reactive, ref, } from "vue"; -import * as mfm from "mfm-js"; import type * as misskey from "calckey-js"; import MkNote from "@/components/MkNote.vue"; import MkNoteSub from "@/components/MkNoteSub.vue"; -import XNoteSimple from "@/components/MkNoteSimple.vue"; -import XReactionsViewer from "@/components/MkReactionsViewer.vue"; -import XMediaList from "@/components/MkMediaList.vue"; -import XCwButton from "@/components/MkCwButton.vue"; -import XPoll from "@/components/MkPoll.vue"; import XStarButton from "@/components/MkStarButton.vue"; -import XStarButtonNoEmoji from "@/components/MkStarButtonNoEmoji.vue"; import XRenoteButton from "@/components/MkRenoteButton.vue"; -import XQuoteButton from "@/components/MkQuoteButton.vue"; -import MkUrlPreview from "@/components/MkUrlPreview.vue"; -import MkInstanceTicker from "@/components/MkInstanceTicker.vue"; -import MkVisibility from "@/components/MkVisibility.vue"; import { pleaseLogin } from "@/scripts/please-login"; import { getWordSoftMute } from "@/scripts/check-word-mute"; import { userPage } from "@/filters/user"; -import { notePage } from "@/filters/note"; import { useRouter } from "@/router"; import * as os from "@/os"; import { defaultStore, noteViewInterruptors } from "@/store"; import { reactionPicker } from "@/scripts/reaction-picker"; -import { extractUrlFromMfm } from "@/scripts/extract-url-from-mfm"; import { $i } from "@/account"; import { i18n } from "@/i18n"; import { getNoteMenu } from "@/scripts/get-note-menu"; @@ -99,15 +90,11 @@ import { deepClone } from "@/scripts/clone"; import { stream } from "@/stream"; import { NoteUpdatedEvent } from "calckey-js/built/streaming.types"; -const router = useRouter(); - const props = defineProps<{ note: misskey.entities.Note; pinned?: boolean; }>(); -const inChannel = inject("inChannel", null); - let note = $ref(deepClone(props.note)); const softMuteReasonI18nSrc = (what?: string) => { @@ -120,8 +107,6 @@ const softMuteReasonI18nSrc = (what?: string) => { return i18n.ts.userSaysSomething; }; -const enableEmojiReactions = defaultStore.state.enableEmojiReactions; - // plugin if (noteViewInterruptors.length > 0) { onMounted(async () => { @@ -155,16 +140,9 @@ const isDeleted = ref(false); const muted = ref(getWordSoftMute(note, $i, defaultStore.state.mutedWords)); const translation = ref(null); const translating = ref(false); -const urls = appearNote.text - ? extractUrlFromMfm(mfm.parse(appearNote.text)).slice(0, 5) - : null; -const showTicker = - defaultStore.state.instanceTicker === "always" || - (defaultStore.state.instanceTicker === "remote" && - appearNote.user.instance); -const conversation = ref([]); +let conversation = $ref([]); const replies = ref([]); -const directReplies = ref([]); +let directReplies = $ref([]); let isScrolling; const keymap = { @@ -260,29 +238,6 @@ function menu(viaKeyboard = false): void { ).then(focus); } -function showRenoteMenu(viaKeyboard = false): void { - if (!isMyRenote) return; - os.popupMenu( - [ - { - text: i18n.ts.unrenote, - icon: "ph-trash ph-bold ph-lg", - danger: true, - action: () => { - os.api("notes/delete", { - noteId: note.id, - }); - isDeleted.value = true; - }, - }, - ], - renoteTime.value, - { - viaKeyboard: viaKeyboard, - } - ); -} - function focus() { noteEl.focus(); } @@ -291,13 +246,14 @@ function blur() { noteEl.blur(); } +directReplies = null; os.api("notes/children", { noteId: appearNote.id, limit: 30, depth: 12, }).then((res) => { replies.value = res; - directReplies.value = res + directReplies = res .filter( (note) => note.replyId === appearNote.id || @@ -306,12 +262,13 @@ os.api("notes/children", { .reverse(); }); +conversation = null; if (appearNote.replyId) { os.api("notes/conversation", { noteId: appearNote.replyId, limit: 30, }).then((res) => { - conversation.value = res.reverse(); + conversation = res.reverse(); focus(); }); } @@ -345,7 +302,7 @@ async function onNoteUpdated(noteData: NoteUpdatedEvent): Promise { replies.value.splice(found, 0, replyNote); if (found === 0) { - directReplies.value.push(replyNote); + directReplies.push(replyNote); } break; From 8a6112ec24d581d2f6a94287ca18908719ce8029 Mon Sep 17 00:00:00 2001 From: Freeplay Date: Tue, 16 May 2023 19:28:07 -0400 Subject: [PATCH 2/2] Display waiting dialog if component takes more than a second to load --- packages/client/src/os.ts | 48 ++++++++++++++++----------------------- 1 file changed, 20 insertions(+), 28 deletions(-) diff --git a/packages/client/src/os.ts b/packages/client/src/os.ts index 922c00bea6..e0d6fa86f6 100644 --- a/packages/client/src/os.ts +++ b/packages/client/src/os.ts @@ -232,7 +232,7 @@ export async function popup( export function pageWindow(path: string) { popup( - defineAsyncComponent(() => import("@/components/MkPageWindow.vue")), + defineAsyncComponent({ loader: () => import("@/components/MkPageWindow.vue"), loadingComponent: MkWaitingDialog, delay: 1000 }), { initialPath: path, }, @@ -243,7 +243,7 @@ export function pageWindow(path: string) { export function modalPageWindow(path: string) { popup( - defineAsyncComponent(() => import("@/components/MkModalPageWindow.vue")), + defineAsyncComponent({ loader: () => import("@/components/MkModalPageWindow.vue"), loadingComponent: MkWaitingDialog, delay: 1000 }), { initialPath: path, }, @@ -313,7 +313,7 @@ export function yesno(props: { }): Promise<{ canceled: boolean }> { return new Promise((resolve, reject) => { popup( - defineAsyncComponent(() => import("@/components/MkDialog.vue")), + defineAsyncComponent({ loader: () => import("@/components/MkDialog.vue"), loadingComponent: MkWaitingDialog, delay: 1000 }), { ...props, showCancelButton: true, @@ -344,7 +344,7 @@ export function inputText(props: { > { return new Promise((resolve, reject) => { popup( - defineAsyncComponent(() => import("@/components/MkDialog.vue")), + defineAsyncComponent({ loader: () => import("@/components/MkDialog.vue"), loadingComponent: MkWaitingDialog, delay: 1000 }), { title: props.title, text: props.text, @@ -378,7 +378,7 @@ export function inputParagraph(props: { > { return new Promise((resolve, reject) => { popup( - defineAsyncComponent(() => import("@/components/MkDialog.vue")), + defineAsyncComponent({ loader: () => import("@/components/MkDialog.vue"), loadingComponent: MkWaitingDialog, delay: 1000 }), { title: props.title, text: props.text, @@ -412,7 +412,7 @@ export function inputNumber(props: { > { return new Promise((resolve, reject) => { popup( - defineAsyncComponent(() => import("@/components/MkDialog.vue")), + defineAsyncComponent({ loader: () => import("@/components/MkDialog.vue"), loadingComponent: MkWaitingDialog, delay: 1000 }), { title: props.title, text: props.text, @@ -446,7 +446,7 @@ export function inputDate(props: { > { return new Promise((resolve, reject) => { popup( - defineAsyncComponent(() => import("@/components/MkDialog.vue")), + defineAsyncComponent({ loader: () => import("@/components/MkDialog.vue"), loadingComponent: MkWaitingDialog, delay: 1000 }), { title: props.title, text: props.text, @@ -501,7 +501,7 @@ export function select( > { return new Promise((resolve, reject) => { popup( - defineAsyncComponent(() => import("@/components/MkDialog.vue")), + defineAsyncComponent({ loader: () => import("@/components/MkDialog.vue"), loadingComponent: MkWaitingDialog, delay: 1000 }), { title: props.title, text: props.text, @@ -528,7 +528,7 @@ export function success() { showing.value = false; }, 1000); popup( - defineAsyncComponent(() => import("@/components/MkWaitingDialog.vue")), + defineAsyncComponent({ loader: () => import("@/components/MkWaitingDialog.vue"), loadingComponent: MkWaitingDialog, delay: 1000 }), { success: true, showing: showing, @@ -545,7 +545,7 @@ export function waiting() { return new Promise((resolve, reject) => { const showing = ref(true); popup( - defineAsyncComponent(() => import("@/components/MkWaitingDialog.vue")), + defineAsyncComponent({ loader: () => import("@/components/MkWaitingDialog.vue"), loadingComponent: MkWaitingDialog, delay: 1000 }), { success: false, showing: showing, @@ -561,7 +561,7 @@ export function waiting() { export function form(title, form) { return new Promise((resolve, reject) => { popup( - defineAsyncComponent(() => import("@/components/MkFormDialog.vue")), + defineAsyncComponent({ loader: () => import("@/components/MkFormDialog.vue"), loadingComponent: MkWaitingDialog, delay: 1000 }), { title, form }, { done: (result) => { @@ -576,7 +576,7 @@ export function form(title, form) { export async function selectUser() { return new Promise((resolve, reject) => { popup( - defineAsyncComponent(() => import("@/components/MkUserSelectDialog.vue")), + defineAsyncComponent({ loader: () => import("@/components/MkUserSelectDialog.vue"), loadingComponent: MkWaitingDialog, delay: 1000 }), {}, { ok: (user) => { @@ -591,9 +591,7 @@ export async function selectUser() { export async function selectInstance(): Promise { return new Promise((resolve, reject) => { popup( - defineAsyncComponent( - () => import("@/components/MkInstanceSelectDialog.vue"), - ), + defineAsyncComponent({ loader: () => import("@/components/MkInstanceSelectDialog.vue"), loadingComponent: MkWaitingDialog, delay: 1000 }), {}, { ok: (instance) => { @@ -608,9 +606,7 @@ export async function selectInstance(): Promise { export async function selectDriveFile(multiple: boolean) { return new Promise((resolve, reject) => { popup( - defineAsyncComponent( - () => import("@/components/MkDriveSelectDialog.vue"), - ), + defineAsyncComponent({ loader: () => import("@/components/MkDriveSelectDialog.vue"), loadingComponent: MkWaitingDialog, delay: 1000 }), { type: "file", multiple, @@ -630,9 +626,7 @@ export async function selectDriveFile(multiple: boolean) { export async function selectDriveFolder(multiple: boolean) { return new Promise((resolve, reject) => { popup( - defineAsyncComponent( - () => import("@/components/MkDriveSelectDialog.vue"), - ), + defineAsyncComponent({ loader: () => import("@/components/MkDriveSelectDialog.vue"), loadingComponent: MkWaitingDialog, delay: 1000 }), { type: "folder", multiple, @@ -652,9 +646,7 @@ export async function selectDriveFolder(multiple: boolean) { export async function pickEmoji(src: HTMLElement | null, opts) { return new Promise((resolve, reject) => { popup( - defineAsyncComponent( - () => import("@/components/MkEmojiPickerDialog.vue"), - ), + defineAsyncComponent({ loader: () => import("@/components/MkEmojiPickerDialog.vue"), loadingComponent: MkWaitingDialog, delay: 1000 }), { src, ...opts, @@ -677,7 +669,7 @@ export async function cropImage( ): Promise { return new Promise((resolve, reject) => { popup( - defineAsyncComponent(() => import("@/components/MkCropperDialog.vue")), + defineAsyncComponent({ loader: () => import("@/components/MkCropperDialog.vue"), loadingComponent: MkWaitingDialog, delay: 1000 }), { file: image, aspectRatio: options.aspectRatio, @@ -741,7 +733,7 @@ export async function openEmojiPicker( }); openingEmojiPicker = await popup( - defineAsyncComponent(() => import("@/components/MkEmojiPickerDialog.vue")), + defineAsyncComponent({ loader: () => import("@/components/MkEmojiPickerDialog.vue"), loadingComponent: MkWaitingDialog, delay: 1000 }), { src, ...opts, @@ -774,7 +766,7 @@ export function popupMenu( return new Promise((resolve, reject) => { let dispose; popup( - defineAsyncComponent(() => import("@/components/MkPopupMenu.vue")), + defineAsyncComponent({ loader: () => import("@/components/MkPopupMenu.vue"), loadingComponent: MkWaitingDialog, delay: 1000 }), { items, src, @@ -802,7 +794,7 @@ export function contextMenu( return new Promise((resolve, reject) => { let dispose; popup( - defineAsyncComponent(() => import("@/components/MkContextMenu.vue")), + defineAsyncComponent({ loader: () => import("@/components/MkContextMenu.vue"), loadingComponent: MkWaitingDialog, delay: 1000 }), { items, ev,