From 42833cd9219cb8f5abd1756aa1c57b024b125710 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=82=BF=E3=83=BC=E3=83=93=E3=83=B3?= Date: Wed, 15 Mar 2023 10:44:24 +0900 Subject: [PATCH] Fix #10261 (#10323) --- packages/frontend/src/pages/page.vue | 13 ++++++++++++- packages/frontend/src/plugin.ts | 17 ++++++++++++++++- packages/frontend/src/store.ts | 7 ++++++- 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/packages/frontend/src/pages/page.vue b/packages/frontend/src/pages/page.vue index 202244b34c..b26255ce61 100644 --- a/packages/frontend/src/pages/page.vue +++ b/packages/frontend/src/pages/page.vue @@ -75,6 +75,8 @@ import MkPagination from '@/components/MkPagination.vue'; import MkPagePreview from '@/components/MkPagePreview.vue'; import { i18n } from '@/i18n'; import { definePageMetadata } from '@/scripts/page-metadata'; +import { pageViewInterruptors } from '@/store'; +import { deepClone } from '@/scripts/clone'; const props = defineProps<{ pageName: string; @@ -97,8 +99,17 @@ function fetchPage() { os.api('pages/show', { name: props.pageName, username: props.username, - }).then(_page => { + }).then(async _page => { page = _page; + + // plugin + if (pageViewInterruptors.length > 0) { + let result = deepClone(_page); + for (const interruptor of pageViewInterruptors) { + result = await interruptor.handler(result); + } + page = result; + } }).catch(err => { error = err; }); diff --git a/packages/frontend/src/plugin.ts b/packages/frontend/src/plugin.ts index a1a36480fd..9b6b01780c 100644 --- a/packages/frontend/src/plugin.ts +++ b/packages/frontend/src/plugin.ts @@ -1,7 +1,7 @@ import { Interpreter, Parser, utils, values } from '@syuilo/aiscript'; import { createAiScriptEnv } from '@/scripts/aiscript/api'; import { inputText } from '@/os'; -import { Plugin, noteActions, notePostInterruptors, noteViewInterruptors, postFormActions, userActions } from '@/store'; +import { Plugin, noteActions, notePostInterruptors, noteViewInterruptors, postFormActions, userActions, pageViewInterruptors } from '@/store'; const parser = new Parser(); const pluginContexts = new Map(); @@ -80,6 +80,9 @@ function createPluginEnv(opts: { plugin: Plugin; storageKey: string }): Record { registerNotePostInterruptor({ pluginId: opts.plugin.id, handler }); }), + 'Plugin:register_page_view_interruptor': values.FN_NATIVE(([handler]) => { + registerPageViewInterruptor({ pluginId: opts.plugin.id, handler }); + }), 'Plugin:open_url': values.FN_NATIVE(([url]) => { utils.assertString(url); window.open(url.value, '_blank'); @@ -156,3 +159,15 @@ function registerNotePostInterruptor({ pluginId, handler }): void { }, }); } + +function registerPageViewInterruptor({ pluginId, handler }): void { + pageViewInterruptors.push({ + handler: async (page) => { + const pluginContext = pluginContexts.get(pluginId); + if (!pluginContext) { + return; + } + return utils.valToJs(await pluginContext.execFn(handler, [utils.jsToVal(page)])); + }, + }); +} diff --git a/packages/frontend/src/store.ts b/packages/frontend/src/store.ts index a68386fa4f..3d87234f41 100644 --- a/packages/frontend/src/store.ts +++ b/packages/frontend/src/store.ts @@ -24,11 +24,16 @@ interface NotePostInterruptor { handler: (note: FIXME) => unknown; } +interface PageViewInterruptor { + handler: (page: Page) => unknown; +} + export const postFormActions: PostFormAction[] = []; export const userActions: UserAction[] = []; export const noteActions: NoteAction[] = []; export const noteViewInterruptors: NoteViewInterruptor[] = []; export const notePostInterruptors: NotePostInterruptor[] = []; +export const pageViewInterruptors: PageViewInterruptor[] = []; // TODO: それぞれいちいちwhereとかdefaultというキーを付けなきゃいけないの冗長なのでなんとかする(ただ型定義が面倒になりそう) // あと、現行の定義の仕方なら「whereが何であるかに関わらずキー名の重複不可」という制約を付けられるメリットもあるからそのメリットを引き継ぐ方法も考えないといけない @@ -318,7 +323,7 @@ interface Watcher { import { miLocalStorage } from './local-storage'; import lightTheme from '@/themes/l-light.json5'; import darkTheme from '@/themes/d-green-lime.json5'; -import { Note, UserDetailed } from 'misskey-js/built/entities'; +import { Note, UserDetailed, Page } from 'misskey-js/built/entities'; export class ColdDeviceStorage { public static default = {