diff --git a/packages/client/src/components/MkButton.vue b/packages/client/src/components/MkButton.vue index a0ff747afc..ab62fd166c 100644 --- a/packages/client/src/components/MkButton.vue +++ b/packages/client/src/components/MkButton.vue @@ -16,7 +16,7 @@ v-else class="bghgjjyj _button" :class="{ inline, primary, gradate, danger, rounded, full, mini }" - :to="to" + :to="to!" @mousedown="onMousedown" > <div ref="ripples" class="ripples"></div> @@ -36,6 +36,7 @@ const props = defineProps<{ gradate?: boolean; rounded?: boolean; inline?: boolean; + // FIXME: if `link`, `to` is necessary link?: boolean; to?: string; autofocus?: boolean; diff --git a/packages/client/src/components/MkChartTooltip.vue b/packages/client/src/components/MkChartTooltip.vue index 659dc6d399..678a3ccdaa 100644 --- a/packages/client/src/components/MkChartTooltip.vue +++ b/packages/client/src/components/MkChartTooltip.vue @@ -28,11 +28,11 @@ </template> <script lang="ts" setup> -import {} from "vue"; +import type { Ref } from "vue"; import MkTooltip from "./MkTooltip.vue"; const props = defineProps<{ - showing: boolean; + showing: Ref<boolean>; x: number; y: number; title?: string; diff --git a/packages/client/src/components/MkDialog.vue b/packages/client/src/components/MkDialog.vue index 0b9d2cac36..c1f8f581a7 100644 --- a/packages/client/src/components/MkDialog.vue +++ b/packages/client/src/components/MkDialog.vue @@ -104,7 +104,7 @@ </MkInput> <MkTextarea v-if="input && input.type === 'paragraph'" - v-model="inputValue" + v-model="(inputValue as string)" autofocus type="paragraph" :placeholder="input.placeholder || undefined" @@ -204,7 +204,16 @@ import { i18n } from "@/i18n"; import iconify from "@/scripts/icon"; interface Input { - type: HTMLInputElement["type"]; + type?: + | "text" + | "number" + | "password" + | "email" + | "url" + | "date" + | "time" + | "search" + | "paragraph"; placeholder?: string | null; autocomplete?: string; default: string | number | null; @@ -237,8 +246,8 @@ const props = withDefaults( | "question" | "waiting" | "search"; - title: string; - text?: string; + title?: string | null; + text?: string | null; isPlaintext?: boolean; input?: Input; select?: Select; @@ -246,7 +255,7 @@ const props = withDefaults( actions?: { text: string; primary?: boolean; - callback: (...args: any[]) => void; + callback: () => void; }[]; showOkButton?: boolean; showCancelButton?: boolean; @@ -268,7 +277,10 @@ const props = withDefaults( ); const emit = defineEmits<{ - (ev: "done", v: { canceled: boolean; result: any }): void; + ( + ev: "done", + v: { canceled: boolean; result?: string | number | boolean | null }, + ): void; (ev: "closed"): void; }>(); @@ -306,7 +318,7 @@ const okButtonDisabled = computed<boolean>(() => { const inputEl = ref<typeof MkInput>(); -function done(canceled: boolean, result?) { +function done(canceled: boolean, result?: string | number | boolean | null) { emit("done", { canceled, result }); modal.value?.close(null); } @@ -342,12 +354,12 @@ function onInputKeydown(evt: KeyboardEvent) { } } -function formatDateToYYYYMMDD(date) { - const year = date.getFullYear(); - const month = ("0" + (date.getMonth() + 1)).slice(-2); - const day = ("0" + (date.getDate() + 1)).slice(-2); - return `${year}-${month}-${day}`; -} +// function formatDateToYYYYMMDD(date) { +// const year = date.getFullYear(); +// const month = ("0" + (date.getMonth() + 1)).slice(-2); +// const day = ("0" + (date.getDate() + 1)).slice(-2); +// return `${year}-${month}-${day}`; +// } /** * Appends a new search parameter to the value in the input field. @@ -355,18 +367,18 @@ function formatDateToYYYYMMDD(date) { * begin typing a new criteria. * @param value The value to append. */ -function appendFilter(value: string) { - return ( - [ - typeof inputValue.value === "string" - ? inputValue.value.trim() - : inputValue.value, - value, - ] - .join(" ") - .trim() + " " - ); -} +// function appendFilter(value: string) { +// return ( +// [ +// typeof inputValue.value === "string" +// ? inputValue.value.trim() +// : inputValue.value, +// value, +// ] +// .join(" ") +// .trim() + " " +// ); +// } onMounted(() => { document.addEventListener("keydown", onKeydown); diff --git a/packages/client/src/components/MkDrive.vue b/packages/client/src/components/MkDrive.vue index 0273e0b40e..ad2f620f6c 100644 --- a/packages/client/src/components/MkDrive.vue +++ b/packages/client/src/components/MkDrive.vue @@ -253,7 +253,7 @@ function onStreamDriveFolderDeleted(folderId: string) { removeFolder(folderId); } -function onDragover(ev: DragEvent): any { +function onDragover(ev: DragEvent) { if (!ev.dataTransfer) return; // ドラッグ元が自分自身の所有するアイテムだったら @@ -285,7 +285,7 @@ function onDragleave() { draghover.value = false; } -function onDrop(ev: DragEvent): any { +function onDrop(ev: DragEvent) { draghover.value = false; if (!ev.dataTransfer) return; @@ -493,14 +493,12 @@ function move(target?: entities.DriveFolder) { if (!target) { goRoot(); return; - } else if (typeof target === "object") { - target = target.id; } fetching.value = true; os.api("drive/folders/show", { - folderId: target, + folderId: target.id, }).then((folderToMove) => { folder.value = folderToMove; hierarchyFolders.value = []; diff --git a/packages/client/src/components/MkNotification.vue b/packages/client/src/components/MkNotification.vue index b00646cdd6..6dd1a4b721 100644 --- a/packages/client/src/components/MkNotification.vue +++ b/packages/client/src/components/MkNotification.vue @@ -12,12 +12,12 @@ :user="notification.note.user" /> <MkAvatar - v-else-if="notification.user" + v-else-if="'user' in notification" class="icon" :user="notification.user" /> <img - v-else-if="notification.icon" + v-else-if="'icon' in notification && notification.icon" class="icon" :src="notification.icon" alt="" @@ -95,7 +95,7 @@ i18n.ts._notification.pollEnded }}</span> <MkA - v-else-if="notification.user" + v-else-if="'user' in notification" v-user-preview="notification.user.id" class="name" :to="userPage(notification.user)" @@ -133,7 +133,7 @@ :plain="true" :nowrap="!full" :lang="notification.note.lang" - :custom-emojis="notification.note.renote.emojis" + :custom-emojis="notification.note.renote!.emojis" /> </MkA> <MkA @@ -212,6 +212,7 @@ style="opacity: 0.7" >{{ i18n.ts.youGotNewFollower }} <div v-if="full && !hideFollowButton"> + <!-- FIXME: Provide a UserDetailed here --> <MkFollowButton :user="notification.user" :full="true" @@ -269,7 +270,7 @@ </template> <script lang="ts" setup> -import { onMounted, onUnmounted, ref, watch } from "vue"; +import { onMounted, onUnmounted, ref, toRef, watch } from "vue"; import type { entities } from "firefish-js"; import XReactionIcon from "@/components/MkReactionIcon.vue"; import MkFollowButton from "@/components/MkFollowButton.vue"; @@ -284,6 +285,8 @@ import { useTooltip } from "@/scripts/use-tooltip"; import { defaultStore } from "@/store"; import { instance } from "@/instance"; import icon from "@/scripts/icon"; +import type { Connection } from "firefish-js/src/streaming"; +import type { Channels } from "firefish-js/src/streaming.types"; const props = withDefaults( defineProps<{ @@ -299,8 +302,8 @@ const props = withDefaults( const stream = useStream(); -const elRef = ref<HTMLElement>(null); -const reactionRef = ref(null); +const elRef = ref<HTMLElement | null>(null); +const reactionRef = ref<InstanceType<typeof XReactionIcon> | null>(null); const hideFollowButton = defaultStore.state.hideFollowButtons; const showEmojiReactions = @@ -311,7 +314,7 @@ const defaultReaction = ["⭐", "👍", "❤️"].includes(instance.defaultReact : "⭐"; let readObserver: IntersectionObserver | undefined; -let connection; +let connection: Connection<Channels["main"]> | null = null; onMounted(() => { if (!props.notification.isRead) { @@ -323,13 +326,13 @@ onMounted(() => { observer.disconnect(); }); - readObserver.observe(elRef.value); + readObserver.observe(elRef.value!); connection = stream.useChannel("main"); - connection.on("readAllNotifications", () => readObserver.disconnect()); + connection.on("readAllNotifications", () => readObserver!.disconnect()); - watch(props.notification.isRead, () => { - readObserver.disconnect(); + watch(toRef(props.notification.isRead), () => { + readObserver!.disconnect(); }); } }); @@ -344,38 +347,47 @@ const groupInviteDone = ref(false); const acceptFollowRequest = () => { followRequestDone.value = true; - os.api("following/requests/accept", { userId: props.notification.user.id }); + os.api("following/requests/accept", { + userId: (props.notification as entities.ReceiveFollowRequestNotification) + .user.id, + }); }; const rejectFollowRequest = () => { followRequestDone.value = true; - os.api("following/requests/reject", { userId: props.notification.user.id }); + os.api("following/requests/reject", { + userId: (props.notification as entities.ReceiveFollowRequestNotification) + .user.id, + }); }; const acceptGroupInvitation = () => { groupInviteDone.value = true; os.apiWithDialog("users/groups/invitations/accept", { - invitationId: props.notification.invitation.id, + invitationId: (props.notification as entities.GroupInvitedNotification) + .invitation.id, }); }; const rejectGroupInvitation = () => { groupInviteDone.value = true; os.api("users/groups/invitations/reject", { - invitationId: props.notification.invitation.id, + invitationId: (props.notification as entities.GroupInvitedNotification) + .invitation.id, }); }; useTooltip(reactionRef, (showing) => { + const n = props.notification as entities.ReactionNotification; os.popup( XReactionTooltip, { showing, - reaction: props.notification.reaction - ? props.notification.reaction.replace(/^:(\w+):$/, ":$1@.:") - : props.notification.reaction, - emojis: props.notification.note.emojis, - targetElement: reactionRef.value.$el, + reaction: n.reaction + ? n.reaction.replace(/^:(\w+):$/, ":$1@.:") + : n.reaction, + emojis: n.note.emojis, + targetElement: reactionRef.value!.$el, }, {}, "closed", diff --git a/packages/client/src/components/MkPagePreview.vue b/packages/client/src/components/MkPagePreview.vue index 034c6fed63..3a6a45745d 100644 --- a/packages/client/src/components/MkPagePreview.vue +++ b/packages/client/src/components/MkPagePreview.vue @@ -3,7 +3,7 @@ :to="`/@${page.user.username}/pages/${page.name}`" class="vhpxefrj _block" tabindex="-1" - :behavior="`${ui === 'deck' ? 'window' : null}`" + :behavior="ui === 'deck' ? 'window' : null" > <div v-if="page.eyeCatchingImage" @@ -36,9 +36,10 @@ <script lang="ts" setup> import { userName } from "@/filters/user"; import { ui } from "@/config"; +import type { entities } from "firefish-js"; defineProps<{ - page: any; + page: entities.Page; }>(); </script> diff --git a/packages/client/src/components/MkPageWindow.vue b/packages/client/src/components/MkPageWindow.vue index d237f18091..082f9f0159 100644 --- a/packages/client/src/components/MkPageWindow.vue +++ b/packages/client/src/components/MkPageWindow.vue @@ -56,23 +56,22 @@ const router = new Router(routes, props.initialPath); const pageMetadata = ref<null | ComputedRef<PageMetadata>>(); const windowEl = ref<InstanceType<typeof XWindow>>(); -const history = ref<{ path: string; key: any }[]>([ +const history = ref<{ path: string; key: string }[]>([ { path: router.getCurrentPath(), key: router.getCurrentKey(), }, ]); const buttonsLeft = computed(() => { - const buttons = []; - if (history.value.length > 1) { - buttons.push({ - icon: `${icon("ph-caret-left")}`, - onClick: back, - }); + return [ + { + icon: `${icon("ph-caret-left")}`, + onClick: back, + }, + ]; } - - return buttons; + return []; }); const buttonsRight = computed(() => { const buttons = [ @@ -114,7 +113,7 @@ const contextmenu = computed(() => [ text: i18n.ts.openInNewTab, action: () => { window.open(url + router.getCurrentPath(), "_blank"); - windowEl.value.close(); + windowEl.value!.close(); }, }, { @@ -135,17 +134,17 @@ function back() { } function close() { - windowEl.value.close(); + windowEl.value!.close(); } function expand() { mainRouter.push(router.getCurrentPath(), "forcePage"); - windowEl.value.close(); + windowEl.value!.close(); } function popout() { - _popout(router.getCurrentPath(), windowEl.value.$el); - windowEl.value.close(); + _popout(router.getCurrentPath(), windowEl.value!.$el); + windowEl.value!.close(); } defineExpose({ diff --git a/packages/client/src/components/MkPollEditor.vue b/packages/client/src/components/MkPollEditor.vue index 982a432e26..b05f80fafa 100644 --- a/packages/client/src/components/MkPollEditor.vue +++ b/packages/client/src/components/MkPollEditor.vue @@ -94,15 +94,14 @@ const props = defineProps<{ }; }>(); const emit = defineEmits<{ - ( - ev: "update:modelValue", + "update:modelValue": [ v: { - expiresAt: string; - expiredAfter: number; + expiresAt?: number; + expiredAfter?: number | null; choices: string[]; multiple: boolean; }, - ): void; + ]; }>(); const choices = ref(props.modelValue.choices); @@ -147,19 +146,19 @@ function get() { }; const calcAfter = () => { - let base = Number.parseInt(after.value); + let base = Number.parseInt(after.value.toString()); switch (unit.value) { + // biome-ignore lint/suspicious/noFallthroughSwitchClause: Fallthrough intentially case "day": base *= 24; - // fallthrough + // biome-ignore lint/suspicious/noFallthroughSwitchClause: Fallthrough intentially case "hour": base *= 60; - // fallthrough + // biome-ignore lint/suspicious/noFallthroughSwitchClause: Fallthrough intentially case "minute": base *= 60; - // fallthrough case "second": - return (base *= 1000); + return base * 1000; default: return null; } diff --git a/packages/client/src/components/MkPostForm.vue b/packages/client/src/components/MkPostForm.vue index fb4a6dc740..2735eb55a3 100644 --- a/packages/client/src/components/MkPostForm.vue +++ b/packages/client/src/components/MkPostForm.vue @@ -1136,11 +1136,11 @@ async function post() { nextTick(() => autosize.update(textareaEl.value)); }); }) - .catch((err) => { + .catch((err: { message: string; id: string }) => { posting.value = false; os.alert({ type: "error", - text: err.message + "\n" + (err as any).id, + text: `${err.message}\n${err.id}`, }); }); vibrate([10, 20, 10, 20, 10, 20, 60]); diff --git a/packages/client/src/components/MkReactionIcon.vue b/packages/client/src/components/MkReactionIcon.vue index e9d5a198cc..6608501478 100644 --- a/packages/client/src/components/MkReactionIcon.vue +++ b/packages/client/src/components/MkReactionIcon.vue @@ -9,9 +9,11 @@ </template> <script lang="ts" setup> +import type { entities } from "firefish-js"; + defineProps<{ reaction: string; - customEmojis?: any[]; // TODO + customEmojis?: entities.EmojiLite[]; noStyle?: boolean; }>(); </script> diff --git a/packages/client/src/components/MkReactionTooltip.vue b/packages/client/src/components/MkReactionTooltip.vue index 0e83226c94..1286fc4c73 100644 --- a/packages/client/src/components/MkReactionTooltip.vue +++ b/packages/client/src/components/MkReactionTooltip.vue @@ -3,6 +3,7 @@ ref="tooltip" :target-element="targetElement" :max-width="340" + :showing="showing" @closed="emit('closed')" > <div class="beeadbfb"> @@ -18,12 +19,15 @@ </template> <script lang="ts" setup> +import type { Ref } from "vue"; import MkTooltip from "./MkTooltip.vue"; import XReactionIcon from "@/components/MkReactionIcon.vue"; +import type { entities } from "firefish-js"; defineProps<{ + showing: Ref<boolean>; reaction: string; - emojis: any[]; // TODO + emojis: entities.EmojiLite[]; targetElement: HTMLElement; }>(); diff --git a/packages/client/src/components/MkReactionsViewer.details.vue b/packages/client/src/components/MkReactionsViewer.details.vue index 0d992ae431..14c2828d45 100644 --- a/packages/client/src/components/MkReactionsViewer.details.vue +++ b/packages/client/src/components/MkReactionsViewer.details.vue @@ -4,6 +4,7 @@ :target-element="targetElement" :max-width="340" @closed="emit('closed')" + :showing="showing" > <div class="bqxuuuey"> <div class="reaction"> @@ -29,15 +30,18 @@ </template> <script lang="ts" setup> +import type { Ref } from "vue"; import MkTooltip from "./MkTooltip.vue"; import XReactionIcon from "@/components/MkReactionIcon.vue"; +import type { entities } from "firefish-js"; defineProps<{ + showing: Ref<boolean>; reaction: string; - users: any[]; // TODO + users: entities.User[]; // TODO count: number; - emojis: any[]; // TODO - targetElement: HTMLElement; + emojis: entities.EmojiLite[]; // TODO + targetElement?: HTMLElement; }>(); const emit = defineEmits<{ diff --git a/packages/client/src/components/MkReactionsViewer.reaction.vue b/packages/client/src/components/MkReactionsViewer.reaction.vue index c403c7003c..89f51797ab 100644 --- a/packages/client/src/components/MkReactionsViewer.reaction.vue +++ b/packages/client/src/components/MkReactionsViewer.reaction.vue @@ -89,7 +89,7 @@ useTooltip( emojis: props.note.emojis, users, count: props.count, - targetElement: buttonRef.value, + targetElement: buttonRef.value!, }, {}, "closed", diff --git a/packages/client/src/components/MkRenoteButton.vue b/packages/client/src/components/MkRenoteButton.vue index 845298b89d..7250757da4 100644 --- a/packages/client/src/components/MkRenoteButton.vue +++ b/packages/client/src/components/MkRenoteButton.vue @@ -46,7 +46,7 @@ const buttonRef = ref<HTMLElement>(); const canRenote = computed( () => ["public", "home"].includes(props.note.visibility) || - props.note.userId === me.id, + props.note.userId === me?.id, ); useTooltip(buttonRef, async (showing) => { diff --git a/packages/client/src/components/MkTooltip.vue b/packages/client/src/components/MkTooltip.vue index 883067c51f..2ed3c1974b 100644 --- a/packages/client/src/components/MkTooltip.vue +++ b/packages/client/src/components/MkTooltip.vue @@ -5,13 +5,13 @@ @after-leave="emit('closed')" > <div - v-show="showing" + v-show="unref(showing)" ref="el" class="buebdbiu _acrylic _shadow" :style="{ zIndex, maxWidth: maxWidth + 'px' }" > <slot> - <Mfm v-if="asMfm" :text="text" /> + <Mfm v-if="asMfm" :text="text!" /> <span v-else>{{ text }}</span> </slot> </div> @@ -19,15 +19,22 @@ </template> <script lang="ts" setup> -import { nextTick, onMounted, onUnmounted, ref } from "vue"; +import { + type MaybeRef, + nextTick, + onMounted, + onUnmounted, + ref, + unref, +} from "vue"; import * as os from "@/os"; import { calcPopupPosition } from "@/scripts/popup-position"; import { defaultStore } from "@/store"; const props = withDefaults( defineProps<{ - showing: boolean; - targetElement?: HTMLElement; + showing: MaybeRef<boolean>; + targetElement?: HTMLElement | null; x?: number; y?: number; text?: string; @@ -40,6 +47,7 @@ const props = withDefaults( maxWidth: 250, direction: "top", innerMargin: 0, + targetElement: null, }, ); @@ -51,7 +59,7 @@ const el = ref<HTMLElement>(); const zIndex = os.claimZIndex("high"); function setPosition() { - const data = calcPopupPosition(el.value, { + const data = calcPopupPosition(el.value!, { anchorElement: props.targetElement, direction: props.direction, align: "center", @@ -60,12 +68,12 @@ function setPosition() { y: props.y, }); - el.value.style.transformOrigin = data.transformOrigin; - el.value.style.left = data.left + "px"; - el.value.style.top = data.top + "px"; + el.value!.style.transformOrigin = data.transformOrigin; + el.value!.style.left = `${data.left}px`; + el.value!.style.top = `${data.top}px`; } -let loopHandler; +let loopHandler: number; onMounted(() => { nextTick(() => { diff --git a/packages/client/src/components/MkUsersTooltip.vue b/packages/client/src/components/MkUsersTooltip.vue index 25af3ac121..741194221d 100644 --- a/packages/client/src/components/MkUsersTooltip.vue +++ b/packages/client/src/components/MkUsersTooltip.vue @@ -4,6 +4,7 @@ :target-element="targetElement" :max-width="250" @closed="emit('closed')" + :showing="showing" > <div class="beaffaef"> <div v-for="u in users" :key="u.id" class="user"> @@ -18,12 +19,15 @@ </template> <script lang="ts" setup> +import type { Ref } from "vue"; import MkTooltip from "./MkTooltip.vue"; +import type { entities } from "firefish-js"; defineProps<{ - users: any[]; // TODO + showing: Ref<boolean>; + users: entities.User[]; count: number; - targetElement: HTMLElement; + targetElement?: HTMLElement; }>(); const emit = defineEmits<{ diff --git a/packages/client/src/components/MkWidgets.vue b/packages/client/src/components/MkWidgets.vue index 1b1dafa522..fb8a449590 100644 --- a/packages/client/src/components/MkWidgets.vue +++ b/packages/client/src/components/MkWidgets.vue @@ -85,7 +85,7 @@ import icon from "@/scripts/icon"; interface Widget { name: string; id: string; - data: Record<string, any>; + data: Record<string, unknown>; } const props = defineProps<{ @@ -137,12 +137,12 @@ function onContextmenu(widget: Widget, ev: MouseEvent) { return isLink(el.parentElement); } }; - if (isLink(ev.target)) return; + if (isLink(ev.target as HTMLElement)) return; if ( ["INPUT", "TEXTAREA", "IMG", "VIDEO", "CANVAS"].includes( - ev.target.tagName, + (ev.target as HTMLElement).tagName, ) || - ev.target.attributes.contenteditable + (ev.target as HTMLElement).getAttribute("contentEditable") ) return; if (window.getSelection()?.toString() !== "") return; diff --git a/packages/client/src/components/global/MkA.vue b/packages/client/src/components/global/MkA.vue index b85774dced..fbe5472a24 100644 --- a/packages/client/src/components/global/MkA.vue +++ b/packages/client/src/components/global/MkA.vue @@ -22,7 +22,7 @@ import icon from "@/scripts/icon"; const props = withDefaults( defineProps<{ - to?: string; + to: string; activeClass?: null | string; behavior?: null | "window" | "browser" | "modalWindow"; }>(), diff --git a/packages/client/src/os.ts b/packages/client/src/os.ts index 04c658ec89..ac1227b827 100644 --- a/packages/client/src/os.ts +++ b/packages/client/src/os.ts @@ -210,11 +210,13 @@ interface VueComponentConstructor<P, E> { emits?: E; } +type NonArrayAble<A> = A extends Array<unknown> ? never : A; + export async function popup<Props, Emits>( component: VueComponentConstructor<Props, Emits>, - props: Props & Record<string, unknown>, - events: Partial<Emits> = {}, - disposeEvent?: string, + props: Props, + events: Partial<NonArrayAble<NonNullable<Emits>>> = {}, + disposeEvent?: keyof Partial<NonArrayAble<NonNullable<Emits>>>, ) { markRaw(component); @@ -227,7 +229,7 @@ export async function popup<Props, Emits>( }; const state = { component, - props, + props: props as Record<string, unknown>, events: disposeEvent ? { ...events, diff --git a/packages/firefish-js/src/entities.ts b/packages/firefish-js/src/entities.ts index a8a15f2290..5858dacb43 100644 --- a/packages/firefish-js/src/entities.ts +++ b/packages/firefish-js/src/entities.ts @@ -20,6 +20,16 @@ export type UserLite = { movedToUri: any; emojis: EmojiLite[]; instance?: InstanceLite; + avatarColor: null; + emojiModPerm: "unauthorized" | "add" | "mod" | "full"; + isAdmin?: boolean; + isModerator?: boolean; + isBot?: boolean; + isLocked: boolean; + isIndexable: boolean; + isCat?: boolean; + speakAsCat?: boolean; + driveCapacityOverrideMb: number | null, }; export type UserDetailed = UserLite & { @@ -46,7 +56,6 @@ export type UserDetailed = UserLite & { isCat: boolean; isFollowed: boolean; isFollowing: boolean; - isLocked: boolean; isModerator: boolean; isMuted: boolean; isRenoteMuted: boolean; @@ -228,7 +237,10 @@ export interface RenoteNotification extends BaseNotification { type: "renote"; user: User; userId: User["id"]; - note: Note; + note: Note & { + renote: Note, + renoteId: string, + }; } export interface QuoteNotification extends BaseNotification { type: "quote";