fix types of components
This commit is contained in:
parent
ea6ef881c2
commit
e4927c9b9b
38 changed files with 319 additions and 159 deletions
|
@ -20,15 +20,10 @@ import { ref } from "vue";
|
||||||
import { instanceName, version } from "@/config";
|
import { instanceName, version } from "@/config";
|
||||||
import { instance as Instance } from "@/instance";
|
import { instance as Instance } from "@/instance";
|
||||||
import { getProxiedImageUrlNullable } from "@/scripts/media-proxy";
|
import { getProxiedImageUrlNullable } from "@/scripts/media-proxy";
|
||||||
|
import type { entities } from "firefish-js";
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
instance?: {
|
instance?: entities.InstanceLite;
|
||||||
faviconUrl?: string;
|
|
||||||
name: string;
|
|
||||||
themeColor?: string;
|
|
||||||
softwareName?: string;
|
|
||||||
softwareVersion?: string;
|
|
||||||
};
|
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const ticker = ref<HTMLElement | null>(null);
|
const ticker = ref<HTMLElement | null>(null);
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
v-vibrate="5"
|
v-vibrate="5"
|
||||||
:aria-label="accessibleLabel"
|
:aria-label="accessibleLabel"
|
||||||
class="tkcbzcuz note-container"
|
class="tkcbzcuz note-container"
|
||||||
:tabindex="!isDeleted ? '-1' : null"
|
:tabindex="!isDeleted ? '-1' : undefined"
|
||||||
:class="{ renote: isRenote }"
|
:class="{ renote: isRenote }"
|
||||||
>
|
>
|
||||||
<MkNoteSub
|
<MkNoteSub
|
||||||
|
@ -112,9 +112,9 @@
|
||||||
:note="appearNote"
|
:note="appearNote"
|
||||||
:detailed="true"
|
:detailed="true"
|
||||||
:detailed-view="detailedView"
|
:detailed-view="detailedView"
|
||||||
:parent-id="appearNote.parentId"
|
:parent-id="appearNote.id"
|
||||||
@push="(e) => router.push(notePage(e))"
|
@push="(e) => router.push(notePage(e))"
|
||||||
@focusfooter="footerEl.focus()"
|
@focusfooter="footerEl!.focus()"
|
||||||
@expanded="(e) => setPostExpanded(e)"
|
@expanded="(e) => setPostExpanded(e)"
|
||||||
></MkSubNoteContent>
|
></MkSubNoteContent>
|
||||||
<div v-if="translating || translation" class="translation">
|
<div v-if="translating || translation" class="translation">
|
||||||
|
@ -312,11 +312,17 @@ import { notePage } from "@/filters/note";
|
||||||
import { deepClone } from "@/scripts/clone";
|
import { deepClone } from "@/scripts/clone";
|
||||||
import { getNoteSummary } from "@/scripts/get-note-summary";
|
import { getNoteSummary } from "@/scripts/get-note-summary";
|
||||||
import icon from "@/scripts/icon";
|
import icon from "@/scripts/icon";
|
||||||
|
import type { NoteTranslation } from "@/types/note";
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
|
type NoteType = entities.Note & {
|
||||||
|
_featuredId_?: string;
|
||||||
|
_prId_?: string;
|
||||||
|
};
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
note: entities.Note;
|
note: NoteType;
|
||||||
pinned?: boolean;
|
pinned?: boolean;
|
||||||
detailedView?: boolean;
|
detailedView?: boolean;
|
||||||
collapsedReply?: boolean;
|
collapsedReply?: boolean;
|
||||||
|
@ -354,18 +360,18 @@ const isRenote =
|
||||||
note.value.fileIds.length === 0 &&
|
note.value.fileIds.length === 0 &&
|
||||||
note.value.poll == null;
|
note.value.poll == null;
|
||||||
|
|
||||||
const el = ref<HTMLElement>();
|
const el = ref<HTMLElement | null>(null);
|
||||||
const footerEl = ref<HTMLElement>();
|
const footerEl = ref<HTMLElement>();
|
||||||
const menuButton = ref<HTMLElement>();
|
const menuButton = ref<HTMLElement>();
|
||||||
const starButton = ref<InstanceType<typeof XStarButton>>();
|
const starButton = ref<InstanceType<typeof XStarButton>>();
|
||||||
const renoteButton = ref<InstanceType<typeof XRenoteButton>>();
|
const renoteButton = ref<InstanceType<typeof XRenoteButton> | null>(null);
|
||||||
const renoteTime = ref<HTMLElement>();
|
const renoteTime = ref<HTMLElement>();
|
||||||
const reactButton = ref<HTMLElement>();
|
const reactButton = ref<HTMLElement | null>(null);
|
||||||
const appearNote = computed(() =>
|
const appearNote = computed(() =>
|
||||||
isRenote ? (note.value.renote as entities.Note) : note.value,
|
isRenote ? (note.value.renote as NoteType) : note.value,
|
||||||
);
|
);
|
||||||
const isMyRenote = isSignedIn && me.id === note.value.userId;
|
const isMyRenote = isSignedIn && me!.id === note.value.userId;
|
||||||
const showContent = ref(false);
|
// const showContent = ref(false);
|
||||||
const isDeleted = ref(false);
|
const isDeleted = ref(false);
|
||||||
const muted = ref(
|
const muted = ref(
|
||||||
getWordSoftMute(
|
getWordSoftMute(
|
||||||
|
@ -375,7 +381,7 @@ const muted = ref(
|
||||||
defaultStore.state.mutedLangs,
|
defaultStore.state.mutedLangs,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
const translation = ref(null);
|
const translation = ref<NoteTranslation | null>(null);
|
||||||
const translating = ref(false);
|
const translating = ref(false);
|
||||||
const enableEmojiReactions = defaultStore.state.enableEmojiReactions;
|
const enableEmojiReactions = defaultStore.state.enableEmojiReactions;
|
||||||
const expandOnNoteClick = defaultStore.state.expandOnNoteClick;
|
const expandOnNoteClick = defaultStore.state.expandOnNoteClick;
|
||||||
|
@ -391,7 +397,7 @@ const isForeignLanguage: boolean =
|
||||||
return postLang !== "" && postLang !== targetLang;
|
return postLang !== "" && postLang !== targetLang;
|
||||||
})();
|
})();
|
||||||
|
|
||||||
async function translate_(noteId, targetLang: string) {
|
async function translate_(noteId: string, targetLang: string) {
|
||||||
return await os.api("notes/translate", {
|
return await os.api("notes/translate", {
|
||||||
noteId,
|
noteId,
|
||||||
targetLang,
|
targetLang,
|
||||||
|
@ -421,12 +427,13 @@ async function translate() {
|
||||||
const keymap = {
|
const keymap = {
|
||||||
r: () => reply(true),
|
r: () => reply(true),
|
||||||
"e|a|plus": () => react(true),
|
"e|a|plus": () => react(true),
|
||||||
q: () => renoteButton.value.renote(true),
|
q: () => renoteButton.value!.renote(true),
|
||||||
"up|k": focusBefore,
|
"up|k": focusBefore,
|
||||||
"down|j": focusAfter,
|
"down|j": focusAfter,
|
||||||
esc: blur,
|
esc: blur,
|
||||||
"m|o": () => menu(true),
|
"m|o": () => menu(true),
|
||||||
s: () => showContent.value !== showContent.value,
|
// FIXME: What's this?
|
||||||
|
// s: () => showContent.value !== showContent.value,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (appearNote.value.historyId == null) {
|
if (appearNote.value.historyId == null) {
|
||||||
|
@ -437,12 +444,12 @@ if (appearNote.value.historyId == null) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function reply(viaKeyboard = false): void {
|
function reply(_viaKeyboard = false): void {
|
||||||
pleaseLogin();
|
pleaseLogin();
|
||||||
os.post(
|
os.post(
|
||||||
{
|
{
|
||||||
reply: appearNote.value,
|
reply: appearNote.value,
|
||||||
animation: !viaKeyboard,
|
// animation: !viaKeyboard,
|
||||||
},
|
},
|
||||||
() => {
|
() => {
|
||||||
focus();
|
focus();
|
||||||
|
@ -450,11 +457,11 @@ function reply(viaKeyboard = false): void {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function react(viaKeyboard = false): void {
|
function react(_viaKeyboard = false): void {
|
||||||
pleaseLogin();
|
pleaseLogin();
|
||||||
blur();
|
blur();
|
||||||
reactionPicker.show(
|
reactionPicker.show(
|
||||||
reactButton.value,
|
reactButton.value!,
|
||||||
(reaction) => {
|
(reaction) => {
|
||||||
os.api("notes/reactions/create", {
|
os.api("notes/reactions/create", {
|
||||||
noteId: appearNote.value.id,
|
noteId: appearNote.value.id,
|
||||||
|
@ -467,7 +474,7 @@ function react(viaKeyboard = false): void {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function undoReact(note): void {
|
function undoReact(note: NoteType): void {
|
||||||
const oldReaction = note.myReaction;
|
const oldReaction = note.myReaction;
|
||||||
if (!oldReaction) return;
|
if (!oldReaction) return;
|
||||||
os.api("notes/reactions/delete", {
|
os.api("notes/reactions/delete", {
|
||||||
|
@ -481,16 +488,17 @@ const currentClipPage = inject<Ref<entities.Clip> | null>(
|
||||||
);
|
);
|
||||||
|
|
||||||
function onContextmenu(ev: MouseEvent): void {
|
function onContextmenu(ev: MouseEvent): void {
|
||||||
const isLink = (el: HTMLElement) => {
|
const isLink = (el: HTMLElement): boolean => {
|
||||||
if (el.tagName === "A") return true;
|
if (el.tagName === "A") return true;
|
||||||
// The Audio element's context menu is the browser default, such as for selecting playback speed.
|
// The Audio element's context menu is the browser default, such as for selecting playback speed.
|
||||||
if (el.tagName === "AUDIO") return true;
|
if (el.tagName === "AUDIO") return true;
|
||||||
if (el.parentElement) {
|
if (el.parentElement) {
|
||||||
return isLink(el.parentElement);
|
return isLink(el.parentElement);
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
};
|
};
|
||||||
if (isLink(ev.target)) return;
|
if (isLink(ev.target as HTMLElement)) return;
|
||||||
if (window.getSelection().toString() !== "") return;
|
if (window.getSelection()?.toString() !== "") return;
|
||||||
|
|
||||||
if (defaultStore.state.useReactionPickerForContextMenu) {
|
if (defaultStore.state.useReactionPickerForContextMenu) {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
|
@ -509,7 +517,7 @@ function onContextmenu(ev: MouseEvent): void {
|
||||||
os.pageWindow(notePage(appearNote.value));
|
os.pageWindow(notePage(appearNote.value));
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
notePage(appearNote.value) != location.pathname
|
notePage(appearNote.value) !== location.pathname
|
||||||
? {
|
? {
|
||||||
icon: `${icon("ph-arrows-out-simple")}`,
|
icon: `${icon("ph-arrows-out-simple")}`,
|
||||||
text: i18n.ts.showInPage,
|
text: i18n.ts.showInPage,
|
||||||
|
@ -589,11 +597,11 @@ function showRenoteMenu(viaKeyboard = false): void {
|
||||||
}
|
}
|
||||||
|
|
||||||
function focus() {
|
function focus() {
|
||||||
el.value.focus();
|
el.value!.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
function blur() {
|
function blur() {
|
||||||
el.value.blur();
|
el.value!.blur();
|
||||||
}
|
}
|
||||||
|
|
||||||
function focusBefore() {
|
function focusBefore() {
|
||||||
|
@ -605,12 +613,12 @@ function focusAfter() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function scrollIntoView() {
|
function scrollIntoView() {
|
||||||
el.value.scrollIntoView();
|
el.value!.scrollIntoView();
|
||||||
}
|
}
|
||||||
|
|
||||||
function noteClick(e) {
|
function noteClick(e) {
|
||||||
if (
|
if (
|
||||||
document.getSelection().type === "Range" ||
|
document.getSelection()?.type === "Range" ||
|
||||||
props.detailedView ||
|
props.detailedView ||
|
||||||
!expandOnNoteClick
|
!expandOnNoteClick
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
v-hotkey="keymap"
|
v-hotkey="keymap"
|
||||||
v-size="{ max: [500, 350, 300] }"
|
v-size="{ max: [500, 350, 300] }"
|
||||||
class="lxwezrsl _block"
|
class="lxwezrsl _block"
|
||||||
:tabindex="!isDeleted ? '-1' : null"
|
:tabindex="!isDeleted ? '-1' : undefined"
|
||||||
:class="{ renote: isRenote }"
|
:class="{ renote: isRenote }"
|
||||||
>
|
>
|
||||||
<MkNoteSub
|
<MkNoteSub
|
||||||
|
@ -64,7 +64,7 @@
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
</option>
|
</option>
|
||||||
<option v-if="directQuotes?.length > 0" value="quotes">
|
<option v-if="directQuotes && directQuotes.length > 0" value="quotes">
|
||||||
<!-- <i :class="icon('ph-quotes')"></i> -->
|
<!-- <i :class="icon('ph-quotes')"></i> -->
|
||||||
{{
|
{{
|
||||||
wordWithCount(
|
wordWithCount(
|
||||||
|
@ -102,7 +102,7 @@
|
||||||
:detailed-view="true"
|
:detailed-view="true"
|
||||||
:parent-id="note.id"
|
:parent-id="note.id"
|
||||||
/>
|
/>
|
||||||
<MkLoading v-else-if="tab === 'quotes' && directQuotes.length > 0" />
|
<MkLoading v-else-if="tab === 'quotes' && directQuotes && directQuotes.length > 0" />
|
||||||
|
|
||||||
<!-- <MkPagination
|
<!-- <MkPagination
|
||||||
v-if="tab === 'renotes'"
|
v-if="tab === 'renotes'"
|
||||||
|
@ -225,12 +225,12 @@ if (noteViewInterruptors.length > 0) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const el = ref<HTMLElement>();
|
const el = ref<HTMLElement | null>(null);
|
||||||
const noteEl = ref();
|
const noteEl = ref();
|
||||||
const menuButton = ref<HTMLElement>();
|
const menuButton = ref<HTMLElement>();
|
||||||
const renoteButton = ref<InstanceType<typeof XRenoteButton>>();
|
const renoteButton = ref<InstanceType<typeof XRenoteButton>>();
|
||||||
const reactButton = ref<HTMLElement>();
|
const reactButton = ref<HTMLElement>();
|
||||||
const showContent = ref(false);
|
// const showContent = ref(false);
|
||||||
const isDeleted = ref(false);
|
const isDeleted = ref(false);
|
||||||
const muted = ref(
|
const muted = ref(
|
||||||
getWordSoftMute(
|
getWordSoftMute(
|
||||||
|
@ -248,7 +248,8 @@ const directReplies = ref<null | entities.Note[]>([]);
|
||||||
const directQuotes = ref<null | entities.Note[]>([]);
|
const directQuotes = ref<null | entities.Note[]>([]);
|
||||||
const clips = ref();
|
const clips = ref();
|
||||||
const renotes = ref();
|
const renotes = ref();
|
||||||
let isScrolling;
|
const isRenote = ref(note.value.renoteId != null);
|
||||||
|
let isScrolling: boolean;
|
||||||
|
|
||||||
const reactionsCount = Object.values(props.note.reactions).reduce(
|
const reactionsCount = Object.values(props.note.reactions).reduce(
|
||||||
(x, y) => x + y,
|
(x, y) => x + y,
|
||||||
|
@ -258,10 +259,10 @@ const reactionsCount = Object.values(props.note.reactions).reduce(
|
||||||
const keymap = {
|
const keymap = {
|
||||||
r: () => reply(true),
|
r: () => reply(true),
|
||||||
"e|a|plus": () => react(true),
|
"e|a|plus": () => react(true),
|
||||||
q: () => renoteButton.value.renote(true),
|
q: () => renoteButton.value!.renote(true),
|
||||||
esc: blur,
|
esc: blur,
|
||||||
"m|o": () => menu(true),
|
"m|o": () => menu(true),
|
||||||
s: () => showContent.value !== showContent.value,
|
// s: () => showContent.value !== showContent.value,
|
||||||
};
|
};
|
||||||
|
|
||||||
useNoteCapture({
|
useNoteCapture({
|
||||||
|
@ -270,21 +271,21 @@ useNoteCapture({
|
||||||
isDeletedRef: isDeleted,
|
isDeletedRef: isDeleted,
|
||||||
});
|
});
|
||||||
|
|
||||||
function reply(viaKeyboard = false): void {
|
function reply(_viaKeyboard = false): void {
|
||||||
pleaseLogin();
|
pleaseLogin();
|
||||||
os.post({
|
os.post({
|
||||||
reply: note.value,
|
reply: note.value,
|
||||||
animation: !viaKeyboard,
|
// animation: !viaKeyboard,
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
focus();
|
focus();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function react(viaKeyboard = false): void {
|
function react(_viaKeyboard = false): void {
|
||||||
pleaseLogin();
|
pleaseLogin();
|
||||||
blur();
|
blur();
|
||||||
reactionPicker.show(
|
reactionPicker.show(
|
||||||
reactButton.value,
|
reactButton.value!,
|
||||||
(reaction) => {
|
(reaction) => {
|
||||||
os.api("notes/reactions/create", {
|
os.api("notes/reactions/create", {
|
||||||
noteId: note.value.id,
|
noteId: note.value.id,
|
||||||
|
@ -297,13 +298,13 @@ function react(viaKeyboard = false): void {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function undoReact(note): void {
|
// function undoReact(note): void {
|
||||||
const oldReaction = note.myReaction;
|
// const oldReaction = note.myReaction;
|
||||||
if (!oldReaction) return;
|
// if (!oldReaction) return;
|
||||||
os.api("notes/reactions/delete", {
|
// os.api("notes/reactions/delete", {
|
||||||
noteId: note.id,
|
// noteId: note.id,
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
|
|
||||||
function onContextmenu(ev: MouseEvent): void {
|
function onContextmenu(ev: MouseEvent): void {
|
||||||
const isLink = (el: HTMLElement) => {
|
const isLink = (el: HTMLElement) => {
|
||||||
|
@ -312,8 +313,8 @@ function onContextmenu(ev: MouseEvent): void {
|
||||||
return isLink(el.parentElement);
|
return isLink(el.parentElement);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if (isLink(ev.target)) return;
|
if (isLink(ev.target as HTMLElement)) return;
|
||||||
if (window.getSelection().toString() !== "") return;
|
if (window.getSelection()?.toString() !== "") return;
|
||||||
|
|
||||||
if (defaultStore.state.useReactionPickerForContextMenu) {
|
if (defaultStore.state.useReactionPickerForContextMenu) {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
|
@ -362,12 +363,17 @@ os.api("notes/children", {
|
||||||
limit: 30,
|
limit: 30,
|
||||||
depth: 12,
|
depth: 12,
|
||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
res = res.reduce((acc, resNote) => {
|
// biome-ignore lint/style/noParameterAssign: assign it intentially
|
||||||
if (resNote.userId == note.value.userId) {
|
res = res
|
||||||
return [...acc, resNote];
|
.filter((n) => n.userId !== note.value.userId)
|
||||||
}
|
.reverse()
|
||||||
return [resNote, ...acc];
|
.concat(res.filter((n) => n.userId === note.value.userId));
|
||||||
}, []);
|
// res = res.reduce((acc: entities.Note[], resNote) => {
|
||||||
|
// if (resNote.userId === note.value.userId) {
|
||||||
|
// return [...acc, resNote];
|
||||||
|
// }
|
||||||
|
// return [resNote, ...acc];
|
||||||
|
// }, []);
|
||||||
replies.value = res;
|
replies.value = res;
|
||||||
directReplies.value = res
|
directReplies.value = res
|
||||||
.filter((resNote) => resNote.replyId === note.value.id)
|
.filter((resNote) => resNote.replyId === note.value.id)
|
||||||
|
@ -438,7 +444,7 @@ async function onNoteUpdated(
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case "replied":
|
case "replied": {
|
||||||
const { id: createdId } = body;
|
const { id: createdId } = body;
|
||||||
const replyNote = await os.api("notes/show", {
|
const replyNote = await os.api("notes/show", {
|
||||||
noteId: createdId,
|
noteId: createdId,
|
||||||
|
@ -446,10 +452,10 @@ async function onNoteUpdated(
|
||||||
|
|
||||||
replies.value.splice(found, 0, replyNote);
|
replies.value.splice(found, 0, replyNote);
|
||||||
if (found === 0) {
|
if (found === 0) {
|
||||||
directReplies.value.push(replyNote);
|
directReplies.value!.push(replyNote);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case "deleted":
|
case "deleted":
|
||||||
if (found === 0) {
|
if (found === 0) {
|
||||||
isDeleted.value = true;
|
isDeleted.value = true;
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<template>
|
<template>
|
||||||
<div v-size="{ min: [350, 500] }" class="fefdfafb">
|
<div v-size="{ min: [350, 500] }" class="fefdfafb">
|
||||||
<MkAvatar class="avatar" :user="me" disable-link />
|
<MkAvatar class="avatar" :user="me!" disable-link />
|
||||||
<div class="main">
|
<div class="main">
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<MkUserName :user="me" />
|
<MkUserName :user="me!" />
|
||||||
</div>
|
</div>
|
||||||
<div class="body">
|
<div class="body">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
|
|
|
@ -40,7 +40,11 @@
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
import type { PagingOf } from "@/components/MkPagination.vue";
|
import type {
|
||||||
|
MkPaginationType,
|
||||||
|
PagingKeyOf,
|
||||||
|
PagingOf,
|
||||||
|
} from "@/components/MkPagination.vue";
|
||||||
import XNote from "@/components/MkNote.vue";
|
import XNote from "@/components/MkNote.vue";
|
||||||
import XList from "@/components/MkDateSeparatedList.vue";
|
import XList from "@/components/MkDateSeparatedList.vue";
|
||||||
import MkPagination from "@/components/MkPagination.vue";
|
import MkPagination from "@/components/MkPagination.vue";
|
||||||
|
@ -56,10 +60,14 @@ defineProps<{
|
||||||
disableAutoLoad?: boolean;
|
disableAutoLoad?: boolean;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const pagingComponent = ref<InstanceType<typeof MkPagination>>();
|
const pagingComponent = ref<MkPaginationType<
|
||||||
|
PagingKeyOf<entities.Note>
|
||||||
|
> | null>(null);
|
||||||
|
|
||||||
function scrollTop() {
|
function scrollTop() {
|
||||||
scroll(tlEl.value, { top: 0, behavior: "smooth" });
|
if (tlEl.value) {
|
||||||
|
scroll(tlEl.value, { top: 0, behavior: "smooth" });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
:with-ok-button="true"
|
:with-ok-button="true"
|
||||||
:ok-button-disabled="false"
|
:ok-button-disabled="false"
|
||||||
@ok="ok()"
|
@ok="ok()"
|
||||||
@close="dialog.close()"
|
@close="dialog!.close()"
|
||||||
@closed="emit('closed')"
|
@closed="emit('closed')"
|
||||||
>
|
>
|
||||||
<template #header>{{ i18n.ts.notificationSetting }}</template>
|
<template #header>{{ i18n.ts.notificationSetting }}</template>
|
||||||
|
@ -68,7 +68,7 @@ const includingTypes = computed(() => props.includingTypes || []);
|
||||||
|
|
||||||
const dialog = ref<InstanceType<typeof XModalWindow>>();
|
const dialog = ref<InstanceType<typeof XModalWindow>>();
|
||||||
|
|
||||||
const typesMap = ref<Record<(typeof notificationTypes)[number], boolean>>({});
|
const typesMap = ref({} as Record<(typeof notificationTypes)[number], boolean>);
|
||||||
const useGlobalSetting = ref(
|
const useGlobalSetting = ref(
|
||||||
(includingTypes.value === null || includingTypes.value.length === 0) &&
|
(includingTypes.value === null || includingTypes.value.length === 0) &&
|
||||||
props.showGlobalToggle,
|
props.showGlobalToggle,
|
||||||
|
@ -89,7 +89,7 @@ function ok() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
dialog.value.close();
|
dialog.value!.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
function disableAll() {
|
function disableAll() {
|
||||||
|
|
|
@ -19,9 +19,10 @@ import { onMounted, ref } from "vue";
|
||||||
import XNotification from "@/components/MkNotification.vue";
|
import XNotification from "@/components/MkNotification.vue";
|
||||||
import * as os from "@/os";
|
import * as os from "@/os";
|
||||||
import { defaultStore } from "@/store";
|
import { defaultStore } from "@/store";
|
||||||
|
import type { entities } from "firefish-js";
|
||||||
|
|
||||||
defineProps<{
|
defineProps<{
|
||||||
notification: any; // TODO
|
notification: entities.Notification;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
|
|
|
@ -44,7 +44,9 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, onMounted, onUnmounted, ref } from "vue";
|
import { computed, onMounted, onUnmounted, ref } from "vue";
|
||||||
import type { StreamTypes, entities, notificationTypes } from "firefish-js";
|
import type { StreamTypes, entities, notificationTypes } from "firefish-js";
|
||||||
import MkPagination from "@/components/MkPagination.vue";
|
import MkPagination, {
|
||||||
|
type MkPaginationType,
|
||||||
|
} from "@/components/MkPagination.vue";
|
||||||
import XNotification from "@/components/MkNotification.vue";
|
import XNotification from "@/components/MkNotification.vue";
|
||||||
import XList from "@/components/MkDateSeparatedList.vue";
|
import XList from "@/components/MkDateSeparatedList.vue";
|
||||||
import XNote from "@/components/MkNote.vue";
|
import XNote from "@/components/MkNote.vue";
|
||||||
|
@ -59,7 +61,7 @@ const props = defineProps<{
|
||||||
|
|
||||||
const stream = useStream();
|
const stream = useStream();
|
||||||
|
|
||||||
const pagingComponent = ref<InstanceType<typeof MkPagination>>();
|
const pagingComponent = ref<MkPaginationType<"i/notifications"> | null>(null);
|
||||||
|
|
||||||
const pagination = {
|
const pagination = {
|
||||||
endpoint: "i/notifications" as const,
|
endpoint: "i/notifications" as const,
|
||||||
|
|
|
@ -67,7 +67,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup generic="E extends PagingKey">
|
<script lang="ts" setup generic="E extends PagingKey">
|
||||||
import type { ComputedRef } from "vue";
|
import type { ComponentPublicInstance, ComputedRef } from "vue";
|
||||||
import { computed, isRef, onActivated, onDeactivated, ref, watch } from "vue";
|
import { computed, isRef, onActivated, onDeactivated, ref, watch } from "vue";
|
||||||
import type { Endpoints, TypeUtils } from "firefish-js";
|
import type { Endpoints, TypeUtils } from "firefish-js";
|
||||||
import * as os from "@/os";
|
import * as os from "@/os";
|
||||||
|
@ -81,8 +81,30 @@ import MkButton from "@/components/MkButton.vue";
|
||||||
import { i18n } from "@/i18n";
|
import { i18n } from "@/i18n";
|
||||||
import { defaultStore } from "@/store";
|
import { defaultStore } from "@/store";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ref type of MkPagination<E>
|
||||||
|
* Due to Vue's incomplete type support for generic components,
|
||||||
|
* we have to manually maintain this type instead of
|
||||||
|
* using `InstanceType<typeof MkPagination>`
|
||||||
|
*/
|
||||||
|
export type MkPaginationType<
|
||||||
|
E extends PagingKey,
|
||||||
|
Item = Endpoints[E]["res"][number],
|
||||||
|
> = ComponentPublicInstance & {
|
||||||
|
items: Item[];
|
||||||
|
queue: Item[];
|
||||||
|
backed: boolean;
|
||||||
|
reload: () => Promise<void>;
|
||||||
|
refresh: () => Promise<void>;
|
||||||
|
prepend: (item: Item) => Promise<void>;
|
||||||
|
append: (item: Item) => Promise<void>;
|
||||||
|
removeItem: (finder: (item: Item) => boolean) => boolean;
|
||||||
|
updateItem: (id: string, replacer: (old: Item) => Item) => boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type PagingKeyOf<T> = TypeUtils.EndpointsOf<T[]>;
|
||||||
// biome-ignore lint/suspicious/noExplicitAny: Used Intentionally
|
// biome-ignore lint/suspicious/noExplicitAny: Used Intentionally
|
||||||
export type PagingKey = TypeUtils.EndpointsOf<any[]>;
|
export type PagingKey = PagingKeyOf<any>;
|
||||||
|
|
||||||
export interface Paging<E extends PagingKey = PagingKey> {
|
export interface Paging<E extends PagingKey = PagingKey> {
|
||||||
endpoint: E;
|
endpoint: E;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<MkModal
|
<MkModal
|
||||||
ref="modal"
|
ref="modal"
|
||||||
:prefer-type="'dialog'"
|
:prefer-type="'dialog'"
|
||||||
@click="modal.close()"
|
@click="modal!.close()"
|
||||||
@closed="onModalClosed()"
|
@closed="onModalClosed()"
|
||||||
>
|
>
|
||||||
<MkPostForm
|
<MkPostForm
|
||||||
|
@ -12,8 +12,8 @@
|
||||||
autofocus
|
autofocus
|
||||||
freeze-after-posted
|
freeze-after-posted
|
||||||
@posted="onPosted"
|
@posted="onPosted"
|
||||||
@cancel="modal.close()"
|
@cancel="modal!.close()"
|
||||||
@esc="modal.close()"
|
@esc="modal!.close()"
|
||||||
/>
|
/>
|
||||||
</MkModal>
|
</MkModal>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -77,7 +77,7 @@ const hasRenotedBefore = ref(false);
|
||||||
if (isSignedIn) {
|
if (isSignedIn) {
|
||||||
os.api("notes/renotes", {
|
os.api("notes/renotes", {
|
||||||
noteId: props.note.id,
|
noteId: props.note.id,
|
||||||
userId: me.id,
|
userId: me!.id,
|
||||||
limit: 1,
|
limit: 1,
|
||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
hasRenotedBefore.value = res.length > 0;
|
hasRenotedBefore.value = res.length > 0;
|
||||||
|
@ -251,6 +251,10 @@ const renote = (viaKeyboard = false, ev?: MouseEvent) => {
|
||||||
|
|
||||||
os.popupMenu(buttonActions, buttonRef.value, { viaKeyboard });
|
os.popupMenu(buttonActions, buttonRef.value, { viaKeyboard });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
renote,
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|
|
@ -31,7 +31,6 @@
|
||||||
:text="note.cw"
|
:text="note.cw"
|
||||||
:author="note.user"
|
:author="note.user"
|
||||||
:lang="note.lang"
|
:lang="note.lang"
|
||||||
:i="me"
|
|
||||||
:custom-emojis="note.emojis"
|
:custom-emojis="note.emojis"
|
||||||
/>
|
/>
|
||||||
</p>
|
</p>
|
||||||
|
@ -63,8 +62,8 @@
|
||||||
<div
|
<div
|
||||||
class="body"
|
class="body"
|
||||||
v-bind="{
|
v-bind="{
|
||||||
'aria-hidden': note.cw && !showContent ? 'true' : null,
|
'aria-hidden': note.cw && !showContent ? 'true' : undefined,
|
||||||
tabindex: !showContent ? '-1' : null,
|
tabindex: !showContent ? '-1' : undefined,
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<span v-if="note.deletedAt" style="opacity: 0.5"
|
<span v-if="note.deletedAt" style="opacity: 0.5"
|
||||||
|
@ -103,7 +102,6 @@
|
||||||
v-if="note.text"
|
v-if="note.text"
|
||||||
:text="note.text"
|
:text="note.text"
|
||||||
:author="note.user"
|
:author="note.user"
|
||||||
:i="me"
|
|
||||||
:lang="note.lang"
|
:lang="note.lang"
|
||||||
:custom-emojis="note.emojis"
|
:custom-emojis="note.emojis"
|
||||||
/>
|
/>
|
||||||
|
@ -256,7 +254,7 @@ async function toggleMfm() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function focusFooter(ev) {
|
function focusFooter(ev) {
|
||||||
if (ev.key == "Tab" && !ev.getModifierState("Shift")) {
|
if (ev.key === "Tab" && !ev.getModifierState("Shift")) {
|
||||||
emit("focusfooter");
|
emit("focusfooter");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,10 +11,10 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #default="{ items: users }">
|
<template #default="{ items }: { items: entities.UserDetailed[] }">
|
||||||
<div class="efvhhmdq">
|
<div class="efvhhmdq">
|
||||||
<MkUserInfo
|
<MkUserInfo
|
||||||
v-for="user in users"
|
v-for="user in items"
|
||||||
:key="user.id"
|
:key="user.id"
|
||||||
class="user"
|
class="user"
|
||||||
:user="user"
|
:user="user"
|
||||||
|
@ -27,16 +27,21 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
import MkUserInfo from "@/components/MkUserInfo.vue";
|
import MkUserInfo from "@/components/MkUserInfo.vue";
|
||||||
import type { Paging } from "@/components/MkPagination.vue";
|
import type {
|
||||||
|
MkPaginationType,
|
||||||
|
PagingKeyOf,
|
||||||
|
PagingOf,
|
||||||
|
} from "@/components/MkPagination.vue";
|
||||||
import MkPagination from "@/components/MkPagination.vue";
|
import MkPagination from "@/components/MkPagination.vue";
|
||||||
import { i18n } from "@/i18n";
|
import { i18n } from "@/i18n";
|
||||||
|
import type { entities } from "firefish-js";
|
||||||
|
|
||||||
defineProps<{
|
defineProps<{
|
||||||
pagination: Paging;
|
pagination: PagingOf<entities.UserDetailed>;
|
||||||
noGap?: boolean;
|
noGap?: boolean;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const pagingComponent = ref<InstanceType<typeof MkPagination>>();
|
const pagingComponent = ref<MkPaginationType<PagingKeyOf<entities.User>>>();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|
|
@ -94,9 +94,9 @@ import { defaultStore } from "@/store";
|
||||||
import { i18n } from "@/i18n";
|
import { i18n } from "@/i18n";
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(ev: "ok", selected: entities.UserDetailed): void;
|
ok: [selected: entities.UserDetailed];
|
||||||
(ev: "cancel"): void;
|
cancel: [];
|
||||||
(ev: "closed"): void;
|
closed: [];
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const username = ref("");
|
const username = ref("");
|
||||||
|
@ -114,7 +114,7 @@ const search = () => {
|
||||||
query: username.value,
|
query: username.value,
|
||||||
origin: "local",
|
origin: "local",
|
||||||
limit: 10,
|
limit: 10,
|
||||||
detail: false,
|
detail: true,
|
||||||
}).then((_users) => {
|
}).then((_users) => {
|
||||||
users.value = _users;
|
users.value = _users;
|
||||||
});
|
});
|
||||||
|
@ -127,7 +127,7 @@ const ok = () => {
|
||||||
|
|
||||||
// 最近使ったユーザー更新
|
// 最近使ったユーザー更新
|
||||||
let recents = defaultStore.state.recentlyUsedUsers;
|
let recents = defaultStore.state.recentlyUsedUsers;
|
||||||
recents = recents.filter((x) => x !== selected.value.id);
|
recents = recents.filter((x) => x !== selected.value!.id);
|
||||||
recents.unshift(selected.value.id);
|
recents.unshift(selected.value.id);
|
||||||
defaultStore.set("recentlyUsedUsers", recents.splice(0, 16));
|
defaultStore.set("recentlyUsedUsers", recents.splice(0, 16));
|
||||||
};
|
};
|
||||||
|
|
|
@ -26,7 +26,7 @@ withDefaults(
|
||||||
text: string;
|
text: string;
|
||||||
plain?: boolean;
|
plain?: boolean;
|
||||||
nowrap?: boolean;
|
nowrap?: boolean;
|
||||||
author?: entities.User;
|
author?: entities.User | null;
|
||||||
customEmojis?: entities.EmojiLite[];
|
customEmojis?: entities.EmojiLite[];
|
||||||
isNote?: boolean;
|
isNote?: boolean;
|
||||||
advancedMfm?: boolean;
|
advancedMfm?: boolean;
|
||||||
|
|
|
@ -30,7 +30,7 @@ export default defineComponent({
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
author: {
|
author: {
|
||||||
type: Object as PropType<entities.User>,
|
type: Object as PropType<entities.User | null>,
|
||||||
default: null,
|
default: null,
|
||||||
},
|
},
|
||||||
// TODO: This variable is not used in the code and may be removed
|
// TODO: This variable is not used in the code and may be removed
|
||||||
|
|
|
@ -13,7 +13,7 @@ export const wsUrl = `${url
|
||||||
export const lang = localStorage.getItem("lang");
|
export const lang = localStorage.getItem("lang");
|
||||||
export const langs = _LANGS_;
|
export const langs = _LANGS_;
|
||||||
export const locale = JSON.parse(localStorage.getItem("locale") || "en-US");
|
export const locale = JSON.parse(localStorage.getItem("locale") || "en-US");
|
||||||
export const version = _VERSION_;
|
export const version: string = _VERSION_;
|
||||||
export const instanceName = siteName === "Firefish" ? host : siteName;
|
export const instanceName = siteName === "Firefish" ? host : siteName;
|
||||||
export const ui = localStorage.getItem("ui");
|
export const ui = localStorage.getItem("ui");
|
||||||
export const debug = localStorage.getItem("debug") === "true";
|
export const debug = localStorage.getItem("debug") === "true";
|
||||||
|
|
|
@ -22,7 +22,7 @@ const apiClient = new firefishApi.APIClient({
|
||||||
|
|
||||||
export const api = ((
|
export const api = ((
|
||||||
endpoint: string,
|
endpoint: string,
|
||||||
data: Record<string, any> = {},
|
data: Record<string, unknown> = {},
|
||||||
token?: string | null | undefined,
|
token?: string | null | undefined,
|
||||||
useToken = true,
|
useToken = true,
|
||||||
) => {
|
) => {
|
||||||
|
@ -174,13 +174,14 @@ export function promiseDialog<T>(
|
||||||
}
|
}
|
||||||
|
|
||||||
let popupIdCount = 0;
|
let popupIdCount = 0;
|
||||||
export const popups = ref<
|
|
||||||
{
|
type PopupType = {
|
||||||
id: number;
|
id: number;
|
||||||
component: Component;
|
component: Component;
|
||||||
props: Record<string, unknown>;
|
props: Record<string, unknown>;
|
||||||
}[]
|
events: Record<string, unknown>;
|
||||||
>([]);
|
};
|
||||||
|
export const popups = ref<PopupType[]>([]);
|
||||||
|
|
||||||
const zIndexes = {
|
const zIndexes = {
|
||||||
low: 1000000,
|
low: 1000000,
|
||||||
|
@ -922,18 +923,27 @@ export function contextMenu(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function post(props: Record<string, any> = {}) {
|
export function post(
|
||||||
return new Promise((resolve, reject) => {
|
props: InstanceType<typeof MkPostFormDialog>["$props"] = {},
|
||||||
|
onClosed?: () => void,
|
||||||
|
) {
|
||||||
|
return new Promise<void>((resolve, reject) => {
|
||||||
// NOTE: MkPostFormDialogをdynamic importするとiOSでテキストエリアに自動フォーカスできない
|
// NOTE: MkPostFormDialogをdynamic importするとiOSでテキストエリアに自動フォーカスできない
|
||||||
// NOTE: ただ、dynamic importしない場合、MkPostFormDialogインスタンスが使いまわされ、
|
// NOTE: ただ、dynamic importしない場合、MkPostFormDialogインスタンスが使いまわされ、
|
||||||
// Vueが渡されたコンポーネントに内部的に__propsというプロパティを生やす影響で、
|
// Vueが渡されたコンポーネントに内部的に__propsというプロパティを生やす影響で、
|
||||||
// 複数のpost formを開いたときに場合によってはエラーになる
|
// 複数のpost formを開いたときに場合によってはエラーになる
|
||||||
// もちろん複数のpost formを開けること自体Misskeyサイドのバグなのだが
|
// もちろん複数のpost formを開けること自体Misskeyサイドのバグなのだが
|
||||||
let dispose;
|
// NOTE: Text area cannot be auto-focused on iOS when dynamically importing MkPostFormDialog
|
||||||
|
// NOTE: However, if you do not dynamically import, the MkPostFormDialog instance will be reused,
|
||||||
|
// Due to the effect that Vue internally creates a property called __props on the passed component,
|
||||||
|
// Sometimes an error occurs when opening multiple post forms
|
||||||
|
// Of course, opening multiple post forms is itself a bug on Misskey's side.
|
||||||
|
let dispose: () => void;
|
||||||
popup(MkPostFormDialog, props, {
|
popup(MkPostFormDialog, props, {
|
||||||
closed: () => {
|
closed: () => {
|
||||||
resolve();
|
resolve();
|
||||||
dispose();
|
dispose();
|
||||||
|
onClosed?.();
|
||||||
},
|
},
|
||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
dispose = res.dispose;
|
dispose = res.dispose;
|
||||||
|
|
|
@ -176,6 +176,7 @@
|
||||||
import { computed, onMounted, ref, watch } from "vue";
|
import { computed, onMounted, ref, watch } from "vue";
|
||||||
import { Virtual } from "swiper/modules";
|
import { Virtual } from "swiper/modules";
|
||||||
import { Swiper, SwiperSlide } from "swiper/vue";
|
import { Swiper, SwiperSlide } from "swiper/vue";
|
||||||
|
import type { Swiper as SwiperType } from "swiper/types";
|
||||||
import XEmojis from "./about.emojis.vue";
|
import XEmojis from "./about.emojis.vue";
|
||||||
import XFederation from "./about.federation.vue";
|
import XFederation from "./about.federation.vue";
|
||||||
import { host, version } from "@/config";
|
import { host, version } from "@/config";
|
||||||
|
@ -294,19 +295,19 @@ watch(iconSrc, (newValue, oldValue) => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let swiperRef = null;
|
let swiperRef: SwiperType | null = null;
|
||||||
|
|
||||||
function setSwiperRef(swiper) {
|
function setSwiperRef(swiper: SwiperType) {
|
||||||
swiperRef = swiper;
|
swiperRef = swiper;
|
||||||
syncSlide(tabs.indexOf(tab.value));
|
syncSlide(tabs.indexOf(tab.value));
|
||||||
}
|
}
|
||||||
|
|
||||||
function onSlideChange() {
|
function onSlideChange() {
|
||||||
tab.value = tabs[swiperRef.activeIndex];
|
tab.value = tabs[swiperRef!.activeIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
function syncSlide(index) {
|
function syncSlide(index: number) {
|
||||||
swiperRef.slideTo(index);
|
swiperRef!.slideTo(index);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -94,14 +94,16 @@
|
||||||
import { computed, ref } from "vue";
|
import { computed, ref } from "vue";
|
||||||
|
|
||||||
import MkSelect from "@/components/form/select.vue";
|
import MkSelect from "@/components/form/select.vue";
|
||||||
import MkPagination from "@/components/MkPagination.vue";
|
import MkPagination, {
|
||||||
|
type MkPaginationType,
|
||||||
|
} from "@/components/MkPagination.vue";
|
||||||
import XAbuseReport from "@/components/MkAbuseReport.vue";
|
import XAbuseReport from "@/components/MkAbuseReport.vue";
|
||||||
import { i18n } from "@/i18n";
|
import { i18n } from "@/i18n";
|
||||||
import { definePageMetadata } from "@/scripts/page-metadata";
|
import { definePageMetadata } from "@/scripts/page-metadata";
|
||||||
import icon from "@/scripts/icon";
|
import icon from "@/scripts/icon";
|
||||||
import type { entities } from "firefish-js";
|
import type { entities } from "firefish-js";
|
||||||
|
|
||||||
const reports = ref<InstanceType<typeof MkPagination>>();
|
const reports = ref<MkPaginationType<typeof pagination.endpoint> | null>(null);
|
||||||
|
|
||||||
const state = ref("unresolved");
|
const state = ref("unresolved");
|
||||||
const reporterOrigin = ref<entities.OriginType>("combined");
|
const reporterOrigin = ref<entities.OriginType>("combined");
|
||||||
|
|
|
@ -153,7 +153,9 @@
|
||||||
import { computed, defineAsyncComponent, ref } from "vue";
|
import { computed, defineAsyncComponent, ref } from "vue";
|
||||||
import MkButton from "@/components/MkButton.vue";
|
import MkButton from "@/components/MkButton.vue";
|
||||||
import MkInput from "@/components/form/input.vue";
|
import MkInput from "@/components/form/input.vue";
|
||||||
import MkPagination from "@/components/MkPagination.vue";
|
import MkPagination, {
|
||||||
|
type MkPaginationType,
|
||||||
|
} from "@/components/MkPagination.vue";
|
||||||
import MkSwitch from "@/components/form/switch.vue";
|
import MkSwitch from "@/components/form/switch.vue";
|
||||||
import FormSplit from "@/components/form/split.vue";
|
import FormSplit from "@/components/form/split.vue";
|
||||||
import { selectFile, selectFiles } from "@/scripts/select-file";
|
import { selectFile, selectFiles } from "@/scripts/select-file";
|
||||||
|
@ -162,7 +164,8 @@ import { i18n } from "@/i18n";
|
||||||
import { definePageMetadata } from "@/scripts/page-metadata";
|
import { definePageMetadata } from "@/scripts/page-metadata";
|
||||||
import icon from "@/scripts/icon";
|
import icon from "@/scripts/icon";
|
||||||
|
|
||||||
const emojisPaginationComponent = ref<InstanceType<typeof MkPagination>>();
|
const emojisPaginationComponent =
|
||||||
|
ref<MkPaginationType<"admin/emoji/list"> | null>(null);
|
||||||
|
|
||||||
const tab = ref("local");
|
const tab = ref("local");
|
||||||
const query = ref(null);
|
const query = ref(null);
|
||||||
|
|
|
@ -126,7 +126,9 @@
|
||||||
import { computed, ref } from "vue";
|
import { computed, ref } from "vue";
|
||||||
import MkInput from "@/components/form/input.vue";
|
import MkInput from "@/components/form/input.vue";
|
||||||
import MkSelect from "@/components/form/select.vue";
|
import MkSelect from "@/components/form/select.vue";
|
||||||
import MkPagination from "@/components/MkPagination.vue";
|
import MkPagination, {
|
||||||
|
type MkPaginationType,
|
||||||
|
} from "@/components/MkPagination.vue";
|
||||||
import * as os from "@/os";
|
import * as os from "@/os";
|
||||||
import { lookupUser } from "@/scripts/lookup-user";
|
import { lookupUser } from "@/scripts/lookup-user";
|
||||||
import { i18n } from "@/i18n";
|
import { i18n } from "@/i18n";
|
||||||
|
@ -134,7 +136,9 @@ import { definePageMetadata } from "@/scripts/page-metadata";
|
||||||
import MkUserCardMini from "@/components/MkUserCardMini.vue";
|
import MkUserCardMini from "@/components/MkUserCardMini.vue";
|
||||||
import icon from "@/scripts/icon";
|
import icon from "@/scripts/icon";
|
||||||
|
|
||||||
const paginationComponent = ref<InstanceType<typeof MkPagination>>();
|
const paginationComponent = ref<MkPaginationType<
|
||||||
|
typeof pagination.endpoint
|
||||||
|
> | null>(null);
|
||||||
|
|
||||||
const sort = ref("+createdAt");
|
const sort = ref("+createdAt");
|
||||||
const state = ref("all");
|
const state = ref("all");
|
||||||
|
|
|
@ -54,6 +54,7 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, ref } from "vue";
|
import { computed, ref } from "vue";
|
||||||
import MkPagination from "@/components/MkPagination.vue";
|
import MkPagination from "@/components/MkPagination.vue";
|
||||||
|
import type { MkPaginationType } from "@/components/MkPagination.vue";
|
||||||
import MkButton from "@/components/MkButton.vue";
|
import MkButton from "@/components/MkButton.vue";
|
||||||
import * as os from "@/os";
|
import * as os from "@/os";
|
||||||
import { i18n } from "@/i18n";
|
import { i18n } from "@/i18n";
|
||||||
|
@ -66,7 +67,7 @@ const pagination = {
|
||||||
limit: 10,
|
limit: 10,
|
||||||
};
|
};
|
||||||
|
|
||||||
const paginationEl = ref<InstanceType<typeof MkPagination>>();
|
const paginationEl = ref<MkPaginationType<"announcements"> | null>(null);
|
||||||
function read(id: string) {
|
function read(id: string) {
|
||||||
if (!paginationEl.value) return;
|
if (!paginationEl.value) return;
|
||||||
paginationEl.value.updateItem(id, (announcement) => {
|
paginationEl.value.updateItem(id, (announcement) => {
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
import MkPagination from "@/components/MkPagination.vue";
|
import MkPagination from "@/components/MkPagination.vue";
|
||||||
|
import type { MkPaginationType } from "@/components/MkPagination.vue";
|
||||||
import XNote from "@/components/MkNote.vue";
|
import XNote from "@/components/MkNote.vue";
|
||||||
import XList from "@/components/MkDateSeparatedList.vue";
|
import XList from "@/components/MkDateSeparatedList.vue";
|
||||||
import { i18n } from "@/i18n";
|
import { i18n } from "@/i18n";
|
||||||
|
@ -48,7 +49,9 @@ const pagination = {
|
||||||
limit: 10,
|
limit: 10,
|
||||||
};
|
};
|
||||||
|
|
||||||
const pagingComponent = ref<InstanceType<typeof MkPagination>>();
|
const pagingComponent = ref<MkPaginationType<
|
||||||
|
typeof pagination.endpoint
|
||||||
|
> | null>(null);
|
||||||
|
|
||||||
definePageMetadata({
|
definePageMetadata({
|
||||||
title: i18n.ts.favorites,
|
title: i18n.ts.favorites,
|
||||||
|
|
|
@ -66,14 +66,17 @@
|
||||||
import { computed, ref } from "vue";
|
import { computed, ref } from "vue";
|
||||||
import { acct } from "firefish-js";
|
import { acct } from "firefish-js";
|
||||||
import MkPagination from "@/components/MkPagination.vue";
|
import MkPagination from "@/components/MkPagination.vue";
|
||||||
|
import type { MkPaginationType } from "@/components/MkPagination.vue";
|
||||||
import { userPage } from "@/filters/user";
|
import { userPage } from "@/filters/user";
|
||||||
import * as os from "@/os";
|
// import * as os from "@/os";
|
||||||
import { i18n } from "@/i18n";
|
import { i18n } from "@/i18n";
|
||||||
import { definePageMetadata } from "@/scripts/page-metadata";
|
import { definePageMetadata } from "@/scripts/page-metadata";
|
||||||
import { me } from "@/me";
|
import { me } from "@/me";
|
||||||
import icon from "@/scripts/icon";
|
import icon from "@/scripts/icon";
|
||||||
|
|
||||||
const paginationComponent = ref<InstanceType<typeof MkPagination>>();
|
const paginationComponent = ref<MkPaginationType<
|
||||||
|
typeof pagination.endpoint
|
||||||
|
> | null>(null);
|
||||||
|
|
||||||
const pagination = {
|
const pagination = {
|
||||||
endpoint: "following/requests/sent" as const,
|
endpoint: "following/requests/sent" as const,
|
||||||
|
|
|
@ -85,6 +85,7 @@
|
||||||
import { computed, ref } from "vue";
|
import { computed, ref } from "vue";
|
||||||
import { acct } from "firefish-js";
|
import { acct } from "firefish-js";
|
||||||
import MkPagination from "@/components/MkPagination.vue";
|
import MkPagination from "@/components/MkPagination.vue";
|
||||||
|
import type { MkPaginationType } from "@/components/MkPagination.vue";
|
||||||
import { userPage } from "@/filters/user";
|
import { userPage } from "@/filters/user";
|
||||||
import * as os from "@/os";
|
import * as os from "@/os";
|
||||||
import { i18n } from "@/i18n";
|
import { i18n } from "@/i18n";
|
||||||
|
@ -92,7 +93,9 @@ import { definePageMetadata } from "@/scripts/page-metadata";
|
||||||
import { me } from "@/me";
|
import { me } from "@/me";
|
||||||
import icon from "@/scripts/icon";
|
import icon from "@/scripts/icon";
|
||||||
|
|
||||||
const paginationComponent = ref<InstanceType<typeof MkPagination>>();
|
const paginationComponent = ref<MkPaginationType<
|
||||||
|
typeof pagination.endpoint
|
||||||
|
> | null>(null);
|
||||||
|
|
||||||
const pagination = {
|
const pagination = {
|
||||||
endpoint: "following/requests/list" as const,
|
endpoint: "following/requests/list" as const,
|
||||||
|
@ -102,13 +105,13 @@ const pagination = {
|
||||||
|
|
||||||
function accept(user) {
|
function accept(user) {
|
||||||
os.api("following/requests/accept", { userId: user.id }).then(() => {
|
os.api("following/requests/accept", { userId: user.id }).then(() => {
|
||||||
paginationComponent.value.reload();
|
paginationComponent.value!.reload();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function reject(user) {
|
function reject(user) {
|
||||||
os.api("following/requests/reject", { userId: user.id }).then(() => {
|
os.api("following/requests/reject", { userId: user.id }).then(() => {
|
||||||
paginationComponent.value.reload();
|
paginationComponent.value!.reload();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -110,7 +110,7 @@ import { acct } from "firefish-js";
|
||||||
import XMessage from "./messaging-room.message.vue";
|
import XMessage from "./messaging-room.message.vue";
|
||||||
import XForm from "./messaging-room.form.vue";
|
import XForm from "./messaging-room.form.vue";
|
||||||
import XList from "@/components/MkDateSeparatedList.vue";
|
import XList from "@/components/MkDateSeparatedList.vue";
|
||||||
import type { Paging } from "@/components/MkPagination.vue";
|
import type { MkPaginationType, Paging } from "@/components/MkPagination.vue";
|
||||||
import MkPagination from "@/components/MkPagination.vue";
|
import MkPagination from "@/components/MkPagination.vue";
|
||||||
import {
|
import {
|
||||||
isBottomVisible,
|
isBottomVisible,
|
||||||
|
@ -136,7 +136,9 @@ const stream = useStream();
|
||||||
|
|
||||||
const rootEl = ref<HTMLDivElement>();
|
const rootEl = ref<HTMLDivElement>();
|
||||||
const formEl = ref<InstanceType<typeof XForm>>();
|
const formEl = ref<InstanceType<typeof XForm>>();
|
||||||
const pagingComponent = ref<InstanceType<typeof MkPagination>>();
|
const pagingComponent = ref<MkPaginationType<"messaging/messages"> | null>(
|
||||||
|
null,
|
||||||
|
);
|
||||||
|
|
||||||
const fetching = ref(true);
|
const fetching = ref(true);
|
||||||
const user = ref<entities.UserDetailed | null>(null);
|
const user = ref<entities.UserDetailed | null>(null);
|
||||||
|
|
|
@ -54,7 +54,7 @@
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, onActivated, onDeactivated, ref } from "vue";
|
import { computed, onActivated, onDeactivated, ref } from "vue";
|
||||||
import MkPagination from "@/components/MkPagination.vue";
|
import MkPagination, { MkPaginationType } from "@/components/MkPagination.vue";
|
||||||
import MkButton from "@/components/MkButton.vue";
|
import MkButton from "@/components/MkButton.vue";
|
||||||
import MkInfo from "@/components/MkInfo.vue";
|
import MkInfo from "@/components/MkInfo.vue";
|
||||||
import { i18n } from "@/i18n";
|
import { i18n } from "@/i18n";
|
||||||
|
@ -70,7 +70,7 @@ const headerActions = computed(() => []);
|
||||||
|
|
||||||
const headerTabs = computed(() => []);
|
const headerTabs = computed(() => []);
|
||||||
|
|
||||||
const list = ref<typeof MkPagination | null>(null);
|
const list = ref<MkPaginationType<typeof pagination.endpoint> | null>(null);
|
||||||
|
|
||||||
let isCached = false;
|
let isCached = false;
|
||||||
let refreshTimer: number | null = null;
|
let refreshTimer: number | null = null;
|
||||||
|
|
|
@ -40,7 +40,9 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, ref } from "vue";
|
import { computed, ref } from "vue";
|
||||||
|
|
||||||
import MkPagination from "@/components/MkPagination.vue";
|
import MkPagination, {
|
||||||
|
type MkPaginationType,
|
||||||
|
} from "@/components/MkPagination.vue";
|
||||||
import MkInfo from "@/components/MkInfo.vue";
|
import MkInfo from "@/components/MkInfo.vue";
|
||||||
import * as os from "@/os";
|
import * as os from "@/os";
|
||||||
import { i18n } from "@/i18n";
|
import { i18n } from "@/i18n";
|
||||||
|
@ -52,7 +54,9 @@ const pagination = {
|
||||||
limit: 10,
|
limit: 10,
|
||||||
};
|
};
|
||||||
|
|
||||||
const pagingComponent = ref<InstanceType<typeof MkPagination>>();
|
const pagingComponent = ref<MkPaginationType<
|
||||||
|
typeof pagination.endpoint
|
||||||
|
> | null>(null);
|
||||||
|
|
||||||
async function create() {
|
async function create() {
|
||||||
const { canceled, result } = await os.form(i18n.ts.createNewClip, {
|
const { canceled, result } = await os.form(i18n.ts.createNewClip, {
|
||||||
|
|
|
@ -44,7 +44,9 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, ref } from "vue";
|
import { computed, ref } from "vue";
|
||||||
|
|
||||||
import MkPagination from "@/components/MkPagination.vue";
|
import MkPagination, {
|
||||||
|
type MkPaginationType,
|
||||||
|
} from "@/components/MkPagination.vue";
|
||||||
import MkButton from "@/components/MkButton.vue";
|
import MkButton from "@/components/MkButton.vue";
|
||||||
import MkAvatars from "@/components/MkAvatars.vue";
|
import MkAvatars from "@/components/MkAvatars.vue";
|
||||||
import MkInfo from "@/components/MkInfo.vue";
|
import MkInfo from "@/components/MkInfo.vue";
|
||||||
|
@ -53,7 +55,9 @@ import { i18n } from "@/i18n";
|
||||||
import { definePageMetadata } from "@/scripts/page-metadata";
|
import { definePageMetadata } from "@/scripts/page-metadata";
|
||||||
import icon from "@/scripts/icon";
|
import icon from "@/scripts/icon";
|
||||||
|
|
||||||
const pagingComponent = ref<InstanceType<typeof MkPagination>>();
|
const pagingComponent = ref<MkPaginationType<
|
||||||
|
typeof pagination.endpoint
|
||||||
|
> | null>(null);
|
||||||
|
|
||||||
const pagination = {
|
const pagination = {
|
||||||
endpoint: "users/lists/list" as const,
|
endpoint: "users/lists/list" as const,
|
||||||
|
|
|
@ -34,7 +34,9 @@
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, onMounted, ref } from "vue";
|
import { computed, onMounted, ref } from "vue";
|
||||||
import MkPagination from "@/components/MkPagination.vue";
|
import MkPagination, {
|
||||||
|
type MkPaginationType,
|
||||||
|
} from "@/components/MkPagination.vue";
|
||||||
import { api } from "@/os";
|
import { api } from "@/os";
|
||||||
import XList from "@/components/MkDateSeparatedList.vue";
|
import XList from "@/components/MkDateSeparatedList.vue";
|
||||||
import XNote from "@/components/MkNote.vue";
|
import XNote from "@/components/MkNote.vue";
|
||||||
|
@ -43,7 +45,9 @@ import { definePageMetadata } from "@/scripts/page-metadata";
|
||||||
import icon from "@/scripts/icon";
|
import icon from "@/scripts/icon";
|
||||||
import type { entities } from "firefish-js";
|
import type { entities } from "firefish-js";
|
||||||
|
|
||||||
const pagingComponent = ref<InstanceType<typeof MkPagination>>();
|
const pagingComponent = ref<MkPaginationType<
|
||||||
|
typeof pagination.endpoint
|
||||||
|
> | null>(null);
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
noteId: string;
|
noteId: string;
|
||||||
|
|
|
@ -89,8 +89,9 @@ const usersPagination = {
|
||||||
endpoint: "users/search" as const,
|
endpoint: "users/search" as const,
|
||||||
limit: 10,
|
limit: 10,
|
||||||
params: computed(() => ({
|
params: computed(() => ({
|
||||||
query: props.query,
|
// FIXME: query is necessary for user search
|
||||||
origin: "combined",
|
query: props.query!,
|
||||||
|
origin: "combined" as const,
|
||||||
})),
|
})),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -13,16 +13,17 @@ import { getUserMenu } from "@/scripts/get-user-menu";
|
||||||
import icon from "@/scripts/icon";
|
import icon from "@/scripts/icon";
|
||||||
import { useRouter } from "@/router";
|
import { useRouter } from "@/router";
|
||||||
import { notePage } from "@/filters/note";
|
import { notePage } from "@/filters/note";
|
||||||
|
import type { NoteTranslation } from "@/types/note";
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
export function getNoteMenu(props: {
|
export function getNoteMenu(props: {
|
||||||
note: entities.Note;
|
note: entities.Note;
|
||||||
menuButton: Ref<HTMLElement | undefined>;
|
menuButton: Ref<HTMLElement | undefined>;
|
||||||
translation: Ref<any>;
|
translation: Ref<NoteTranslation | null>;
|
||||||
translating: Ref<boolean>;
|
translating: Ref<boolean>;
|
||||||
isDeleted: Ref<boolean>;
|
isDeleted: Ref<boolean>;
|
||||||
currentClipPage?: Ref<entities.Clip>;
|
currentClipPage?: Ref<entities.Clip> | null;
|
||||||
}) {
|
}) {
|
||||||
const isRenote =
|
const isRenote =
|
||||||
props.note.renote != null &&
|
props.note.renote != null &&
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { isSignedIn, me } from "@/me";
|
||||||
import * as os from "@/os";
|
import * as os from "@/os";
|
||||||
|
|
||||||
export function useNoteCapture(props: {
|
export function useNoteCapture(props: {
|
||||||
rootEl: Ref<HTMLElement>;
|
rootEl: Ref<HTMLElement | null>;
|
||||||
note: Ref<entities.Note>;
|
note: Ref<entities.Note>;
|
||||||
isDeletedRef: Ref<boolean>;
|
isDeletedRef: Ref<boolean>;
|
||||||
}) {
|
}) {
|
||||||
|
|
|
@ -3,11 +3,24 @@ import { isSignedIn } from "./me";
|
||||||
import { Storage } from "./pizzax";
|
import { Storage } from "./pizzax";
|
||||||
import type { NoteVisibility } from "@/types/note";
|
import type { NoteVisibility } from "@/types/note";
|
||||||
|
|
||||||
export const postFormActions = [];
|
export const postFormActions: {
|
||||||
export const userActions = [];
|
title: string;
|
||||||
export const noteActions = [];
|
handler: (note: entities.Note) => void | Promise<void>;
|
||||||
export const noteViewInterruptors = [];
|
}[] = [];
|
||||||
export const notePostInterruptors = [];
|
export const userActions: {
|
||||||
|
title: string;
|
||||||
|
handler: (note: entities.Note) => void | Promise<void>;
|
||||||
|
}[] = [];
|
||||||
|
export const noteActions: {
|
||||||
|
title: string;
|
||||||
|
handler: (note: entities.Note) => void | Promise<void>;
|
||||||
|
}[] = [];
|
||||||
|
export const noteViewInterruptors: {
|
||||||
|
handler: (note: entities.Note) => Promise<entities.Note>;
|
||||||
|
}[] = [];
|
||||||
|
export const notePostInterruptors: {
|
||||||
|
handler: (note: entities.Note) => Promise<entities.Note>;
|
||||||
|
}[] = [];
|
||||||
|
|
||||||
const menuOptions = [
|
const menuOptions = [
|
||||||
"notifications",
|
"notifications",
|
||||||
|
@ -453,6 +466,7 @@ import darkTheme from "@/themes/d-rosepine.json5";
|
||||||
* Storage for configuration information that does not need to be constantly loaded into memory (non-reactive)
|
* Storage for configuration information that does not need to be constantly loaded into memory (non-reactive)
|
||||||
*/
|
*/
|
||||||
import lightTheme from "@/themes/l-rosepinedawn.json5";
|
import lightTheme from "@/themes/l-rosepinedawn.json5";
|
||||||
|
import { entities } from "firefish-js";
|
||||||
|
|
||||||
export class ColdDeviceStorage {
|
export class ColdDeviceStorage {
|
||||||
public static default = {
|
public static default = {
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
import type { noteVisibilities } from "firefish-js";
|
import type { noteVisibilities } from "firefish-js";
|
||||||
|
|
||||||
export type NoteVisibility = (typeof noteVisibilities)[number] | "private";
|
export type NoteVisibility = (typeof noteVisibilities)[number] | "private";
|
||||||
|
|
||||||
|
export type NoteTranslation = {
|
||||||
|
sourceLang: string;
|
||||||
|
text: string;
|
||||||
|
};
|
||||||
|
|
|
@ -36,6 +36,7 @@ import type {
|
||||||
UserDetailed,
|
UserDetailed,
|
||||||
UserGroup,
|
UserGroup,
|
||||||
UserList,
|
UserList,
|
||||||
|
UserLite,
|
||||||
UserSorting,
|
UserSorting,
|
||||||
} from "./entities";
|
} from "./entities";
|
||||||
|
|
||||||
|
@ -686,7 +687,14 @@ export type Endpoints = {
|
||||||
res: Note[];
|
res: Note[];
|
||||||
};
|
};
|
||||||
"notes/clips": { req: TODO; res: TODO };
|
"notes/clips": { req: TODO; res: TODO };
|
||||||
"notes/conversation": { req: TODO; res: TODO };
|
"notes/conversation": {
|
||||||
|
req: {
|
||||||
|
noteId: string;
|
||||||
|
limit?: number;
|
||||||
|
offset?: number;
|
||||||
|
};
|
||||||
|
res: Note[];
|
||||||
|
};
|
||||||
"notes/create": {
|
"notes/create": {
|
||||||
req: NoteSubmitReq;
|
req: NoteSubmitReq;
|
||||||
res: { createdNote: Note };
|
res: { createdNote: Note };
|
||||||
|
@ -789,7 +797,24 @@ export type Endpoints = {
|
||||||
res: Note[];
|
res: Note[];
|
||||||
};
|
};
|
||||||
"notes/search-by-tag": { req: TODO; res: TODO };
|
"notes/search-by-tag": { req: TODO; res: TODO };
|
||||||
"notes/search": { req: TODO; res: TODO };
|
"notes/search": {
|
||||||
|
req: {
|
||||||
|
query: string;
|
||||||
|
sinceId?: string;
|
||||||
|
untilId?: string;
|
||||||
|
sinceDate?: number;
|
||||||
|
untilDate?: number;
|
||||||
|
limit?: number;
|
||||||
|
offset?: number;
|
||||||
|
host?: string;
|
||||||
|
userId?: string;
|
||||||
|
withFiles?: boolean;
|
||||||
|
searchCwAndAlt?: boolean;
|
||||||
|
channelId?: string;
|
||||||
|
order?: "chronological" | "relevancy";
|
||||||
|
};
|
||||||
|
res: Note[];
|
||||||
|
};
|
||||||
"notes/show": { req: { noteId: Note["id"] }; res: Note };
|
"notes/show": { req: { noteId: Note["id"] }; res: Note };
|
||||||
"notes/state": { req: TODO; res: TODO };
|
"notes/state": { req: TODO; res: TODO };
|
||||||
"notes/timeline": {
|
"notes/timeline": {
|
||||||
|
@ -802,6 +827,16 @@ export type Endpoints = {
|
||||||
};
|
};
|
||||||
res: Note[];
|
res: Note[];
|
||||||
};
|
};
|
||||||
|
"notes/translate": {
|
||||||
|
req: {
|
||||||
|
noteId: string;
|
||||||
|
targetLang: string;
|
||||||
|
};
|
||||||
|
res: {
|
||||||
|
sourceLang: string;
|
||||||
|
text: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
"notes/unrenote": { req: { noteId: Note["id"] }; res: null };
|
"notes/unrenote": { req: { noteId: Note["id"] }; res: null };
|
||||||
"notes/user-list-timeline": {
|
"notes/user-list-timeline": {
|
||||||
req: {
|
req: {
|
||||||
|
@ -972,7 +1007,16 @@ export type Endpoints = {
|
||||||
"users/relation": { req: TODO; res: TODO };
|
"users/relation": { req: TODO; res: TODO };
|
||||||
"users/report-abuse": { req: TODO; res: TODO };
|
"users/report-abuse": { req: TODO; res: TODO };
|
||||||
"users/search-by-username-and-host": { req: TODO; res: TODO };
|
"users/search-by-username-and-host": { req: TODO; res: TODO };
|
||||||
"users/search": { req: TODO; res: TODO };
|
"users/search": {
|
||||||
|
req: {
|
||||||
|
query: string;
|
||||||
|
offset?: number;
|
||||||
|
limit?: number;
|
||||||
|
origin?: "local" | "remote" | "combined";
|
||||||
|
detail?: true; // FIXME: when false, returns UserLite
|
||||||
|
};
|
||||||
|
res: UserDetailed[];
|
||||||
|
};
|
||||||
"users/show": {
|
"users/show": {
|
||||||
req: ShowUserReq | { userIds: User["id"][] };
|
req: ShowUserReq | { userIds: User["id"][] };
|
||||||
res: {
|
res: {
|
||||||
|
|
|
@ -19,14 +19,7 @@ export type UserLite = {
|
||||||
alsoKnownAs: string[];
|
alsoKnownAs: string[];
|
||||||
movedToUri: any;
|
movedToUri: any;
|
||||||
emojis: EmojiLite[];
|
emojis: EmojiLite[];
|
||||||
instance?: {
|
instance?: InstanceLite;
|
||||||
name: Instance["name"];
|
|
||||||
softwareName: Instance["softwareName"];
|
|
||||||
softwareVersion: Instance["softwareVersion"];
|
|
||||||
iconUrl: Instance["iconUrl"];
|
|
||||||
faviconUrl: Instance["faviconUrl"];
|
|
||||||
themeColor: Instance["themeColor"];
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export type UserDetailed = UserLite & {
|
export type UserDetailed = UserLite & {
|
||||||
|
@ -556,6 +549,15 @@ export type Blocking = {
|
||||||
blockee: UserDetailed;
|
blockee: UserDetailed;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type InstanceLite = {
|
||||||
|
name: Instance["name"];
|
||||||
|
softwareName: Instance["softwareName"];
|
||||||
|
softwareVersion: Instance["softwareVersion"];
|
||||||
|
iconUrl: Instance["iconUrl"];
|
||||||
|
faviconUrl: Instance["faviconUrl"];
|
||||||
|
themeColor: Instance["themeColor"];
|
||||||
|
};
|
||||||
|
|
||||||
export type Instance = {
|
export type Instance = {
|
||||||
id: ID;
|
id: ID;
|
||||||
caughtAt: DateString;
|
caughtAt: DateString;
|
||||||
|
|
Loading…
Reference in a new issue