From 7fbcc4ec1900ac209ce48e2f3e189c98adc7cb0e Mon Sep 17 00:00:00 2001 From: Natty Date: Thu, 28 Dec 2023 00:34:52 +0100 Subject: [PATCH] Frontend: Removed dependence on Calckey note resolving and avatars --- .dev/Caddyfile | 2 +- .../frontend/calckey-js/src/api.types.ts | 2 - fe_calckey/frontend/client/src/account.ts | 5 +-- .../client/src/components/MagAvatars.vue | 4 +- .../client/src/components/MagNote.vue | 4 +- .../client/src/components/MagNoteDetailed.vue | 2 +- .../client/src/components/MagNoteSimple.vue | 2 +- .../client/src/components/MagNoteSub.vue | 2 +- .../client/src/components/MagPoll.vue | 23 +++++----- .../client/src/components/MagUserPreview.vue | 2 +- .../client/src/components/MkAbuseReport.vue | 3 +- .../src/components/MkDateSeparatedList.vue | 23 +++++++--- .../src/components/MkGalleryPostPreview.vue | 4 +- .../frontend/client/src/components/MkMenu.vue | 14 ++---- .../client/src/components/MkNotePreview.vue | 3 +- .../client/src/components/MkNotes.vue | 3 +- .../client/src/components/MkNotification.vue | 6 +-- .../client/src/components/MkPostForm.vue | 5 ++- .../src/components/MkPostFormDialog.vue | 6 +-- .../components/MkReactionsViewer.details.vue | 3 +- .../client/src/components/MkTimeline.vue | 23 +++++++--- .../client/src/components/MkUserCardMini.vue | 2 +- .../client/src/components/MkUserInfo.vue | 3 +- .../src/components/MkUserSelectDialog.vue | 6 +-- .../client/src/components/MkUsersTooltip.vue | 3 +- .../global/{MkAvatar.vue => MagAvatar.vue} | 32 +++----------- .../global/MagAvatarResolvingProxy.vue | 43 +++++++++++++++++++ .../src/components/global/MkPageHeader.vue | 4 +- .../frontend/client/src/filters/note.ts | 5 +-- fe_calckey/frontend/client/src/init.ts | 9 ++-- .../frontend/client/src/pages/admin/index.vue | 19 +++++--- .../src/pages/admin/overview.moderators.vue | 6 +-- .../client/src/pages/admin/overview.user.vue | 2 +- fe_calckey/frontend/client/src/pages/clip.vue | 4 +- .../client/src/pages/explore.featured.vue | 6 --- .../client/src/pages/follow-requests.vue | 2 +- .../client/src/pages/gallery/post.vue | 6 ++- .../client/src/pages/my-groups/group.vue | 2 +- .../client/src/pages/my-lists/list.vue | 2 +- fe_calckey/frontend/client/src/pages/page.vue | 6 ++- .../client/src/pages/settings/accounts.vue | 14 +++--- .../client/src/pages/settings/profile.vue | 2 +- .../frontend/client/src/pages/share.vue | 38 ++++++++++------ .../frontend/client/src/pages/user-info.vue | 9 ++-- .../frontend/client/src/pages/user/home.vue | 3 +- .../client/src/pages/user/index.timeline.vue | 3 +- .../client/src/pages/user/reactions.vue | 6 +-- .../client/src/scripts-mag/mag-util.ts | 6 +++ .../client/src/scripts/check-word-mute.ts | 23 ++++------ .../client/src/scripts/gen-search-query.ts | 4 +- .../client/src/scripts/get-note-summary.ts | 11 ++--- .../client/src/scripts/lookup-user.ts | 14 +++--- .../client/src/scripts/page-metadata.ts | 5 +-- .../src/ui/_common_/navbar-for-mobile.vue | 13 ++---- .../client/src/ui/_common_/navbar.vue | 8 +--- .../src/ui/_common_/statusbar-user-list.vue | 13 +++--- .../frontend/client/src/ui/visitor/header.vue | 4 +- 57 files changed, 257 insertions(+), 222 deletions(-) rename fe_calckey/frontend/client/src/components/global/{MkAvatar.vue => MagAvatar.vue} (79%) create mode 100644 fe_calckey/frontend/client/src/components/global/MagAvatarResolvingProxy.vue diff --git a/.dev/Caddyfile b/.dev/Caddyfile index db4a2d9..564725e 100644 --- a/.dev/Caddyfile +++ b/.dev/Caddyfile @@ -20,7 +20,7 @@ magnetar-dev.local { } @render_html { - not path /api* /proxy* /files* /avatar* /identicon* /streaming + not path /api* /proxy* /files* /avatar* /identicon* header Accept text/html* } diff --git a/fe_calckey/frontend/calckey-js/src/api.types.ts b/fe_calckey/frontend/calckey-js/src/api.types.ts index 420516a..6825cf4 100644 --- a/fe_calckey/frontend/calckey-js/src/api.types.ts +++ b/fe_calckey/frontend/calckey-js/src/api.types.ts @@ -853,7 +853,6 @@ export type Endpoints = { }; res: Note[]; }; - "notes/polls/recommendation": { req: TODO; res: TODO }; "notes/polls/vote": { req: { noteId: Note["id"]; choice: number }; res: null; @@ -887,7 +886,6 @@ export type Endpoints = { }; "notes/search-by-tag": { req: TODO; res: TODO }; "notes/search": { req: TODO; res: TODO }; - "notes/show": { req: { noteId: Note["id"] }; res: Note }; "notes/state": { req: TODO; res: TODO }; "notes/timeline": { req: { diff --git a/fe_calckey/frontend/client/src/account.ts b/fe_calckey/frontend/client/src/account.ts index 167e1e4..a914cbb 100644 --- a/fe_calckey/frontend/client/src/account.ts +++ b/fe_calckey/frontend/client/src/account.ts @@ -3,13 +3,12 @@ import * as misskey from "calckey-js"; import { i18n } from "./i18n"; import { del, get, set } from "@/scripts/idb-proxy"; import { apiUrl } from "@/config"; -import { waiting, api, popup, popupMenu, success, alert } from "@/os"; -import { unisonReload, reloadChannel } from "@/scripts/unison-reload"; +import { alert, api, popup, popupMenu, success, waiting } from "@/os"; +import { reloadChannel, unisonReload } from "@/scripts/unison-reload"; // TODO: 他のタブと永続化されたstateを同期 type Account = misskey.entities.MeDetailed; - const accountData = localStorage.getItem("account"); // TODO: 外部からはreadonlyに diff --git a/fe_calckey/frontend/client/src/components/MagAvatars.vue b/fe_calckey/frontend/client/src/components/MagAvatars.vue index ab5b42a..899f8e8 100644 --- a/fe_calckey/frontend/client/src/components/MagAvatars.vue +++ b/fe_calckey/frontend/client/src/components/MagAvatars.vue @@ -1,7 +1,7 @@ @@ -9,7 +9,7 @@ diff --git a/fe_calckey/frontend/client/src/components/global/MkPageHeader.vue b/fe_calckey/frontend/client/src/components/global/MkPageHeader.vue index 15eb877..d69d4be 100644 --- a/fe_calckey/frontend/client/src/components/global/MkPageHeader.vue +++ b/fe_calckey/frontend/client/src/components/global/MkPageHeader.vue @@ -18,7 +18,7 @@ > - - { +export const notePage = (note: { id: packed.PackNoteBase["id"] }) => { return `/notes/${note.id}`; }; diff --git a/fe_calckey/frontend/client/src/init.ts b/fe_calckey/frontend/client/src/init.ts index b97f2cd..c202301 100644 --- a/fe_calckey/frontend/client/src/init.ts +++ b/fe_calckey/frontend/client/src/init.ts @@ -46,7 +46,8 @@ import { getAccountFromId } from "@/scripts/get-account-from-id"; import Mfm from "./components/global/MkMisskeyFlavoredMarkdown.vue"; import MkA from "./components/global/MkA.vue"; import MkAcct from "./components/global/MkAcct.vue"; -import MkAvatar from "./components/global/MkAvatar.vue"; +import MagAvatar from "./components/global/MagAvatar.vue"; +import MagAvatarResolvingProxy from "./components/global/MagAvatarResolvingProxy.vue"; import MagEmoji from "./components/global/MagEmoji.vue"; import MkUserName from "./components/global/MkUserName.vue"; import MkEllipsis from "./components/global/MkEllipsis.vue"; @@ -67,7 +68,7 @@ function globalComponents(app: App) { app.component("Mfm", Mfm); app.component("MkA", MkA); app.component("MkAcct", MkAcct); - app.component("MkAvatar", MkAvatar); + app.component("MagAvatar", MagAvatar); app.component("MagEmoji", MagEmoji); app.component("MkUserName", MkUserName); app.component("MkEllipsis", MkEllipsis); @@ -79,6 +80,7 @@ function globalComponents(app: App) { app.component("MkPageHeader", MkPageHeader); app.component("MkSpacer", MkSpacer); app.component("MkStickyContainer", MkStickyContainer); + app.component("MagAvatarResolvingProxy", MagAvatarResolvingProxy); } declare module "@vue/runtime-core" { @@ -88,7 +90,7 @@ declare module "@vue/runtime-core" { Mfm: typeof Mfm; MkA: typeof MkA; MkAcct: typeof MkAcct; - MkAvatar: typeof MkAvatar; + MagAvatar: typeof MagAvatar; MagEmoji: typeof MagEmoji; MkUserName: typeof MkUserName; MkEllipsis: typeof MkEllipsis; @@ -100,6 +102,7 @@ declare module "@vue/runtime-core" { MkPageHeader: typeof MkPageHeader; MkSpacer: typeof MkSpacer; MkStickyContainer: typeof MkStickyContainer; + MagAvatarResolvingProxy: typeof MagAvatarResolvingProxy; } } diff --git a/fe_calckey/frontend/client/src/pages/admin/index.vue b/fe_calckey/frontend/client/src/pages/admin/index.vue index 54ae401..34f2146 100644 --- a/fe_calckey/frontend/client/src/pages/admin/index.vue +++ b/fe_calckey/frontend/client/src/pages/admin/index.vue @@ -66,6 +66,7 @@ import { definePageMetadata, provideMetadataReceiver, } from "@/scripts/page-metadata"; +import { endpoints } from "magnetar-common"; const isEmpty = (x: string | null) => x == null || x === ""; const el = ref(null); @@ -332,12 +333,18 @@ async function lookupNote() { }); if (canceled) return; - os.api( - "notes/show", - q.startsWith("http://") || q.startsWith("https://") - ? { url: q.trim() } - : { noteId: q.trim() } - ) + if (q?.startsWith("http://") || q?.startsWith("https://")) { + const obj = await os.api("ap/show", { + uri: q, + }); + if (obj.type === "Note") { + os.pageWindow(`/notes/${obj.object.id}`); + } + + return; + } + + os.magApi(endpoints.GetNoteById, {}, { id: q.trim() }) .then((note) => { os.pageWindow(`/notes/${note.id}`); }) diff --git a/fe_calckey/frontend/client/src/pages/admin/overview.moderators.vue b/fe_calckey/frontend/client/src/pages/admin/overview.moderators.vue index e0702c9..e1b1b90 100644 --- a/fe_calckey/frontend/client/src/pages/admin/overview.moderators.vue +++ b/fe_calckey/frontend/client/src/pages/admin/overview.moderators.vue @@ -12,7 +12,7 @@ class="user" :to="`/user-info/${user.id}`" > - diff --git a/fe_calckey/frontend/client/src/pages/follow-requests.vue b/fe_calckey/frontend/client/src/pages/follow-requests.vue index 0649251..1afc3b1 100644 --- a/fe_calckey/frontend/client/src/pages/follow-requests.vue +++ b/fe_calckey/frontend/client/src/pages/follow-requests.vue @@ -23,7 +23,7 @@ :key="req.id" class="user _panel" > -
- +
- -
- +
- +
@@ -34,11 +38,11 @@ import FormSuspense from "@/components/form/suspense.vue"; import FormButton from "@/components/MkButton.vue"; import * as os from "@/os"; import { - getAccounts, - addAccount as addAccounts, - removeAccount as _removeAccount, - login, $i, + addAccount as addAccounts, + getAccounts, + login, + removeAccount as _removeAccount, } from "@/account"; import { i18n } from "@/i18n"; import { definePageMetadata } from "@/scripts/page-metadata"; diff --git a/fe_calckey/frontend/client/src/pages/settings/profile.vue b/fe_calckey/frontend/client/src/pages/settings/profile.vue index 6e8d810..1f2446e 100644 --- a/fe_calckey/frontend/client/src/pages/settings/profile.vue +++ b/fe_calckey/frontend/client/src/pages/settings/profile.vue @@ -11,7 +11,7 @@ }" >
- // SPECIFICATION: https://misskey-hub.net/docs/features/share-form.html -import {} from "vue"; +import * as Misskey from "calckey-js"; import { noteVisibilities } from "calckey-js"; import * as Acct from "calckey-js/built/acct"; -import * as Misskey from "calckey-js"; import MkButton from "@/components/MkButton.vue"; import XPostForm from "@/components/MkPostForm.vue"; import * as os from "@/os"; import { mainRouter } from "@/router"; import { definePageMetadata } from "@/scripts/page-metadata"; import { i18n } from "@/i18n"; +import { endpoints, packed } from "magnetar-common"; const urlParams = new URLSearchParams(window.location.search); const localOnlyQuery = urlParams.get("localOnly"); @@ -51,9 +51,9 @@ let state = $ref("fetching" as "fetching" | "writing" | "posted"); let title = $ref(urlParams.get("title")); const text = urlParams.get("text"); const url = urlParams.get("url"); -let initialText = $ref(null as string | null); -let reply = $ref(null as Misskey.entities.Note | null); -let renote = $ref(null as Misskey.entities.Note | null); +let initialText = $ref(null); +let reply = $ref(null); +let renote = $ref(null); let visibility = $ref( noteVisibilities.includes(visibilityQuery) ? visibilityQuery : null ); @@ -114,15 +114,21 @@ async function init() { const replyId = urlParams.get("replyId"); const replyUri = urlParams.get("replyUri"); if (replyId) { - reply = await os.api("notes/show", { - noteId: replyId, - }); + reply = await os.magApi( + endpoints.GetNoteById, + { attachments: true, context: true }, + { id: replyId } + ); } else if (replyUri) { const obj = await os.api("ap/show", { uri: replyUri, }); if (obj.type === "Note") { - reply = obj.object; + reply = await os.magApi( + endpoints.GetNoteById, + { attachments: true, context: true }, + { id: obj.object.id } + ); } } //#endregion @@ -131,15 +137,21 @@ async function init() { const renoteId = urlParams.get("renoteId"); const renoteUri = urlParams.get("renoteUri"); if (renoteId) { - renote = await os.api("notes/show", { - noteId: renoteId, - }); + renote = await os.magApi( + endpoints.GetNoteById, + { attachments: true, context: true }, + { id: renoteId } + ); } else if (renoteUri) { const obj = await os.api("ap/show", { uri: renoteUri, }); if (obj.type === "Note") { - renote = obj.object; + renote = await os.magApi( + endpoints.GetNoteById, + { attachments: true, context: true }, + { id: obj.object.id } + ); } } //#endregion diff --git a/fe_calckey/frontend/client/src/pages/user-info.vue b/fe_calckey/frontend/client/src/pages/user-info.vue index 66a8423..e4b6d85 100644 --- a/fe_calckey/frontend/client/src/pages/user-info.vue +++ b/fe_calckey/frontend/client/src/pages/user-info.vue @@ -10,7 +10,7 @@
-
- import { computed, ref } from "vue"; -import * as misskey from "calckey-js"; import XNotes from "@/components/MkNotes.vue"; import MkTab from "@/components/MkTab.vue"; import { i18n } from "@/i18n"; import { packed } from "magnetar-common"; const props = defineProps<{ - user: packed.PackUserBase | misskey.entities.UserDetailed; + user: packed.PackUserBase; }>(); const include = ref(null); diff --git a/fe_calckey/frontend/client/src/pages/user/reactions.vue b/fe_calckey/frontend/client/src/pages/user/reactions.vue index 21ef38a..9b3a81a 100644 --- a/fe_calckey/frontend/client/src/pages/user/reactions.vue +++ b/fe_calckey/frontend/client/src/pages/user/reactions.vue @@ -8,7 +8,7 @@ class="item _panel _gap afdcfbfb" >
- + import { computed } from "vue"; -import * as misskey from "calckey-js"; import MkPagination from "@/components/MkPagination.vue"; import XNoteResolvingProxy from "@/components/MagNoteResolvingProxy.vue"; import MkReactionIcon from "@/components/MkReactionIcon.vue"; +import { packed } from "magnetar-common"; const props = defineProps<{ - user: misskey.entities.User; + user: packed.PackUserBase; }>(); const pagination = { diff --git a/fe_calckey/frontend/client/src/scripts-mag/mag-util.ts b/fe_calckey/frontend/client/src/scripts-mag/mag-util.ts index 1e2e38e..6fe82e4 100644 --- a/fe_calckey/frontend/client/src/scripts-mag/mag-util.ts +++ b/fe_calckey/frontend/client/src/scripts-mag/mag-util.ts @@ -131,6 +131,12 @@ export function magReactionSelf( return null; } +export function userIsMag( + user: packed.PackUserBase | Misskey.entities.User +): user is packed.PackUserBase { + return "created_at" in user; +} + export function noteIsMag( note: packed.PackNoteMaybeFull | Misskey.entities.Note ): note is packed.PackNoteMaybeFull { diff --git a/fe_calckey/frontend/client/src/scripts/check-word-mute.ts b/fe_calckey/frontend/client/src/scripts/check-word-mute.ts index 1b0f294..a6315d4 100644 --- a/fe_calckey/frontend/client/src/scripts/check-word-mute.ts +++ b/fe_calckey/frontend/client/src/scripts/check-word-mute.ts @@ -1,6 +1,4 @@ import { packed } from "magnetar-common"; -import * as Misskey from "calckey-js"; -import { magTransMap, magTransProperty } from "@/scripts-mag/mag-util"; export type Muted = { muted: boolean; @@ -11,13 +9,12 @@ export type Muted = { export type NotMuted = { muted: false; matched: string[] }; function checkWordMute( - note: packed.PackNoteMaybeFull | Misskey.entities.Note, + note: packed.PackNoteMaybeFull, mutedWords: Array ): Muted { let text = `${note.cw ?? ""} ${note.text ?? ""}`; - const attachments = magTransProperty(note, "attachments", "files"); - if (attachments) - text += ` ${attachments.map((f) => f.comment ?? "").join(" ")}`; + if (note.attachments) + text += ` ${note.attachments?.map((f) => f.comment ?? "")?.join(" ")}`; text = text.trim(); let result: Muted | NotMuted = { muted: false, matched: [] }; @@ -64,12 +61,12 @@ function checkWordMute( } export function getWordSoftMute( - note: packed.PackNoteMaybeFull | Misskey.entities.Note, + note: packed.PackNoteMaybeFull, me: Record | null | undefined, mutedWords: Array ): Muted { // 自分自身 - if (me && magTransMap(note, "user", "userId", (u) => u.id) === me.id) { + if (me && note.user.id === me.id) { return { muted: false, matched: [] }; } @@ -80,18 +77,16 @@ export function getWordSoftMute( return noteMuted; } - const renote = magTransProperty(note, "renoted_note", "renote"); - if (renote) { - let renoteMuted = checkWordMute(renote, mutedWords); + if (note.renoted_note) { + let renoteMuted = checkWordMute(note.renoted_note, mutedWords); if (renoteMuted.muted) { renoteMuted.what = note.text == null ? "renote" : "quote"; return renoteMuted; } } - const reply = magTransProperty(note, "parent_note", "reply"); - if (reply) { - let replyMuted = checkWordMute(reply, mutedWords); + if (note.parent_note) { + let replyMuted = checkWordMute(note.parent_note, mutedWords); if (replyMuted.muted) { replyMuted.what = "reply"; return replyMuted; diff --git a/fe_calckey/frontend/client/src/scripts/gen-search-query.ts b/fe_calckey/frontend/client/src/scripts/gen-search-query.ts index 95f0bf0..b89afa4 100644 --- a/fe_calckey/frontend/client/src/scripts/gen-search-query.ts +++ b/fe_calckey/frontend/client/src/scripts/gen-search-query.ts @@ -2,13 +2,13 @@ import * as Acct from "calckey-js/built/acct"; import { host as localHost } from "@/config"; export async function genSearchQuery(v: any, q: string) { - let host: string; + let host: string | null; let userId: string; if (q.split(" ").some((x) => x.startsWith("@"))) { for (const at of q .split(" ") .filter((x) => x.startsWith("@")) - .map((x) => x.substr(1))) { + .map((x) => x.substring(1))) { if (at.includes(".")) { if (at === localHost || at === ".") { host = null; diff --git a/fe_calckey/frontend/client/src/scripts/get-note-summary.ts b/fe_calckey/frontend/client/src/scripts/get-note-summary.ts index 0f1c687..4d6af6b 100644 --- a/fe_calckey/frontend/client/src/scripts/get-note-summary.ts +++ b/fe_calckey/frontend/client/src/scripts/get-note-summary.ts @@ -1,14 +1,10 @@ -import * as misskey from "calckey-js"; import { packed } from "magnetar-common"; -import { magTransProperty } from "@/scripts-mag/mag-util"; /** * 投稿を表す文字列を取得します。 * @param {*} note (packされた)投稿 */ -export const getNoteSummary = ( - note: packed.PackNoteMaybeFull | misskey.entities.Note -): string => { +export const getNoteSummary = (note: packed.PackNoteMaybeFull): string => { /* if (note.deletedAt) { return `(${i18n.ts.deletedNote})`; @@ -25,9 +21,8 @@ export const getNoteSummary = ( } // ファイルが添付されているとき - const files = magTransProperty(note, "attachments", "files"); - if ((files || []).length !== 0) { - const len = files?.length; + if ((note.attachments || []).length !== 0) { + const len = note.attachments?.length; summary += ` 📎${len !== 1 ? ` (${len})` : ""}`; } diff --git a/fe_calckey/frontend/client/src/scripts/lookup-user.ts b/fe_calckey/frontend/client/src/scripts/lookup-user.ts index 8597361..8104236 100644 --- a/fe_calckey/frontend/client/src/scripts/lookup-user.ts +++ b/fe_calckey/frontend/client/src/scripts/lookup-user.ts @@ -8,7 +8,7 @@ export async function lookupUser() { }); if (canceled) return; - const show = (user) => { + const show = (user: { id: any }) => { os.pageWindow(`/user-info/${user.id}`); }; @@ -25,12 +25,10 @@ export async function lookupUser() { _notFound = true; } }; - usernamePromise.then(show).catch((err) => { - if (err.code === "NO_SUCH_USER") { + + Promise.any([usernamePromise, idPromise]) + .then(show) + .catch(() => { notFound(); - } - }); - idPromise.then(show).catch((err) => { - notFound(); - }); + }); } diff --git a/fe_calckey/frontend/client/src/scripts/page-metadata.ts b/fe_calckey/frontend/client/src/scripts/page-metadata.ts index 39335f7..8db3bfb 100644 --- a/fe_calckey/frontend/client/src/scripts/page-metadata.ts +++ b/fe_calckey/frontend/client/src/scripts/page-metadata.ts @@ -1,4 +1,3 @@ -import * as misskey from "calckey-js"; import { ComputedRef, inject, @@ -18,8 +17,8 @@ export type PageMetadata = { title: string; subtitle?: string; icon?: string | null; - avatar?: packed.PackUserBase | misskey.entities.User | null; - userName?: packed.PackUserBase | misskey.entities.User | null; + avatar?: packed.PackUserBase | null; + userName?: packed.PackUserBase | null; bg?: string; }; diff --git a/fe_calckey/frontend/client/src/ui/_common_/navbar-for-mobile.vue b/fe_calckey/frontend/client/src/ui/_common_/navbar-for-mobile.vue index aef94e7..0e0fed7 100644 --- a/fe_calckey/frontend/client/src/ui/_common_/navbar-for-mobile.vue +++ b/fe_calckey/frontend/client/src/ui/_common_/navbar-for-mobile.vue @@ -15,7 +15,7 @@ class="item _button account" @click="openAccountMenu" > -