From a8abb03d1785791ab40e57ab49c87640914532c9 Mon Sep 17 00:00:00 2001 From: かっこかり <67428053+kakkokari-gtyih@users.noreply.github.com> Date: Sun, 6 Jul 2025 19:36:11 +0900 Subject: refactor(frontend): Formまわりの型強化 (#16260) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor(frontend): Formまわりの型強化 * fix * avoid non-null assertion and add null check for safety * refactor * avoid non-null assertion and add null check for safety * Update clip.vue --------- Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com> --- packages/frontend/src/widgets/WidgetActivity.vue | 14 +++-- packages/frontend/src/widgets/WidgetAichan.vue | 8 ++- packages/frontend/src/widgets/WidgetAiscript.vue | 10 ++-- .../frontend/src/widgets/WidgetAiscriptApp.vue | 10 ++-- .../src/widgets/WidgetBirthdayFollowings.vue | 8 +-- packages/frontend/src/widgets/WidgetButton.vue | 12 ++-- packages/frontend/src/widgets/WidgetCalendar.vue | 6 +- packages/frontend/src/widgets/WidgetChat.vue | 6 +- packages/frontend/src/widgets/WidgetClicker.vue | 6 +- packages/frontend/src/widgets/WidgetClock.vue | 70 +++++++++++++--------- .../frontend/src/widgets/WidgetDigitalClock.vue | 14 ++--- packages/frontend/src/widgets/WidgetFederation.vue | 8 +-- .../frontend/src/widgets/WidgetInstanceCloud.vue | 6 +- .../frontend/src/widgets/WidgetInstanceInfo.vue | 6 +- packages/frontend/src/widgets/WidgetJobQueue.vue | 8 +-- packages/frontend/src/widgets/WidgetMemo.vue | 10 ++-- .../frontend/src/widgets/WidgetNotifications.vue | 13 ++-- .../frontend/src/widgets/WidgetOnlineUsers.vue | 8 +-- packages/frontend/src/widgets/WidgetPhotos.vue | 8 +-- packages/frontend/src/widgets/WidgetPostForm.vue | 4 +- packages/frontend/src/widgets/WidgetProfile.vue | 10 ++-- packages/frontend/src/widgets/WidgetRss.vue | 12 ++-- packages/frontend/src/widgets/WidgetRssTicker.vue | 20 +++---- packages/frontend/src/widgets/WidgetSlideshow.vue | 19 +++--- packages/frontend/src/widgets/WidgetTimeline.vue | 50 +++++++++++----- packages/frontend/src/widgets/WidgetTrends.vue | 6 +- packages/frontend/src/widgets/WidgetUnixClock.vue | 19 +++--- packages/frontend/src/widgets/WidgetUserList.vue | 16 ++--- .../frontend/src/widgets/server-metric/cpu-mem.vue | 2 +- .../frontend/src/widgets/server-metric/cpu.vue | 2 +- .../frontend/src/widgets/server-metric/index.vue | 12 ++-- .../frontend/src/widgets/server-metric/mem.vue | 2 +- .../frontend/src/widgets/server-metric/net.vue | 2 +- packages/frontend/src/widgets/widget.ts | 12 ++-- 34 files changed, 233 insertions(+), 186 deletions(-) (limited to 'packages/frontend/src/widgets') diff --git a/packages/frontend/src/widgets/WidgetActivity.vue b/packages/frontend/src/widgets/WidgetActivity.vue index db03d1406c..9625abb4d1 100644 --- a/packages/frontend/src/widgets/WidgetActivity.vue +++ b/packages/frontend/src/widgets/WidgetActivity.vue @@ -25,29 +25,31 @@ import { useWidgetPropsManager } from './widget.js'; import type { WidgetComponentProps, WidgetComponentEmits, WidgetComponentExpose } from './widget.js'; import XCalendar from './WidgetActivity.calendar.vue'; import XChart from './WidgetActivity.chart.vue'; -import type { GetFormResultType } from '@/utility/form.js'; +import type { FormWithDefault, GetFormResultType } from '@/utility/form.js'; import { misskeyApiGet } from '@/utility/misskey-api.js'; import MkContainer from '@/components/MkContainer.vue'; -import { $i } from '@/i.js'; +import { ensureSignin } from '@/i.js'; import { i18n } from '@/i18n.js'; +const $i = ensureSignin(); + const name = 'activity'; const widgetPropsDef = { showHeader: { - type: 'boolean' as const, + type: 'boolean', default: true, }, transparent: { - type: 'boolean' as const, + type: 'boolean', default: false, }, view: { - type: 'number' as const, + type: 'number', default: 0, hidden: true, }, -}; +} satisfies FormWithDefault; type WidgetProps = GetFormResultType; diff --git a/packages/frontend/src/widgets/WidgetAichan.vue b/packages/frontend/src/widgets/WidgetAichan.vue index 2bc7facc88..3951de1d84 100644 --- a/packages/frontend/src/widgets/WidgetAichan.vue +++ b/packages/frontend/src/widgets/WidgetAichan.vue @@ -13,16 +13,16 @@ SPDX-License-Identifier: AGPL-3.0-only import { onMounted, onUnmounted, useTemplateRef } from 'vue'; import { useWidgetPropsManager } from './widget.js'; import type { WidgetComponentProps, WidgetComponentEmits, WidgetComponentExpose } from './widget.js'; -import type { GetFormResultType } from '@/utility/form.js'; +import type { FormWithDefault, GetFormResultType } from '@/utility/form.js'; const name = 'ai'; const widgetPropsDef = { transparent: { - type: 'boolean' as const, + type: 'boolean', default: false, }, -}; +} satisfies FormWithDefault; type WidgetProps = GetFormResultType; @@ -42,6 +42,8 @@ const touched = () => { }; const onMousemove = (ev: MouseEvent) => { + if (!live2d.value || !live2d.value.contentWindow) return; + const iframeRect = live2d.value.getBoundingClientRect(); live2d.value.contentWindow.postMessage({ type: 'moveCursor', diff --git a/packages/frontend/src/widgets/WidgetAiscript.vue b/packages/frontend/src/widgets/WidgetAiscript.vue index da71dcad29..a2d964718e 100644 --- a/packages/frontend/src/widgets/WidgetAiscript.vue +++ b/packages/frontend/src/widgets/WidgetAiscript.vue @@ -23,7 +23,7 @@ import { ref } from 'vue'; import { Interpreter, Parser, utils } from '@syuilo/aiscript'; import { useWidgetPropsManager } from './widget.js'; import type { WidgetComponentEmits, WidgetComponentExpose, WidgetComponentProps } from './widget.js'; -import type { GetFormResultType } from '@/utility/form.js'; +import type { FormWithDefault, GetFormResultType } from '@/utility/form.js'; import * as os from '@/os.js'; import MkContainer from '@/components/MkContainer.vue'; import { aiScriptReadline, createAiScriptEnv } from '@/aiscript/api.js'; @@ -35,16 +35,16 @@ const name = 'aiscript'; const widgetPropsDef = { showHeader: { - type: 'boolean' as const, + type: 'boolean', default: true, }, script: { - type: 'string' as const, + type: 'string', multiline: true, default: '(1 + 1)', hidden: true, }, -}; +} satisfies FormWithDefault; type WidgetProps = GetFormResultType; @@ -106,7 +106,7 @@ const run = async () => { } catch (err) { os.alert({ type: 'error', - text: err, + text: err instanceof Error ? err.message : String(err), }); } }; diff --git a/packages/frontend/src/widgets/WidgetAiscriptApp.vue b/packages/frontend/src/widgets/WidgetAiscriptApp.vue index 429b0e0ffb..fdd4eaae06 100644 --- a/packages/frontend/src/widgets/WidgetAiscriptApp.vue +++ b/packages/frontend/src/widgets/WidgetAiscriptApp.vue @@ -18,7 +18,7 @@ import type { Ref } from 'vue'; import { Interpreter, Parser } from '@syuilo/aiscript'; import { useWidgetPropsManager } from './widget.js'; import type { WidgetComponentEmits, WidgetComponentExpose, WidgetComponentProps } from './widget.js'; -import type { GetFormResultType } from '@/utility/form.js'; +import type { FormWithDefault, GetFormResultType } from '@/utility/form.js'; import * as os from '@/os.js'; import { aiScriptReadline, createAiScriptEnv } from '@/aiscript/api.js'; import { $i } from '@/i.js'; @@ -31,15 +31,15 @@ const name = 'aiscriptApp'; const widgetPropsDef = { script: { - type: 'string' as const, + type: 'string', multiline: true, default: '', }, showHeader: { - type: 'boolean' as const, + type: 'boolean', default: true, }, -}; +} satisfies FormWithDefault; type WidgetProps = GetFormResultType; @@ -92,7 +92,7 @@ async function run() { os.alert({ type: 'error', title: 'AiScript Error', - text: err.message, + text: err instanceof Error ? err.message : String(err), }); } } diff --git a/packages/frontend/src/widgets/WidgetBirthdayFollowings.vue b/packages/frontend/src/widgets/WidgetBirthdayFollowings.vue index 4790f143cb..d1991cd70a 100644 --- a/packages/frontend/src/widgets/WidgetBirthdayFollowings.vue +++ b/packages/frontend/src/widgets/WidgetBirthdayFollowings.vue @@ -12,7 +12,7 @@ SPDX-License-Identifier: AGPL-3.0-only
- +
@@ -27,7 +27,7 @@ import * as Misskey from 'misskey-js'; import { useInterval } from '@@/js/use-interval.js'; import { useWidgetPropsManager } from './widget.js'; import type { WidgetComponentEmits, WidgetComponentExpose, WidgetComponentProps } from './widget.js'; -import type { GetFormResultType } from '@/utility/form.js'; +import type { FormWithDefault, GetFormResultType } from '@/utility/form.js'; import MkContainer from '@/components/MkContainer.vue'; import { misskeyApi } from '@/utility/misskey-api.js'; import { i18n } from '@/i18n.js'; @@ -37,10 +37,10 @@ const name = i18n.ts._widgets.birthdayFollowings; const widgetPropsDef = { showHeader: { - type: 'boolean' as const, + type: 'boolean', default: true, }, -}; +} satisfies FormWithDefault; type WidgetProps = GetFormResultType; diff --git a/packages/frontend/src/widgets/WidgetButton.vue b/packages/frontend/src/widgets/WidgetButton.vue index 4afe735a22..e88a960f87 100644 --- a/packages/frontend/src/widgets/WidgetButton.vue +++ b/packages/frontend/src/widgets/WidgetButton.vue @@ -15,7 +15,7 @@ SPDX-License-Identifier: AGPL-3.0-only import { Interpreter, Parser } from '@syuilo/aiscript'; import { useWidgetPropsManager } from './widget.js'; import type { WidgetComponentEmits, WidgetComponentExpose, WidgetComponentProps } from './widget.js'; -import type { GetFormResultType } from '@/utility/form.js'; +import type { FormWithDefault, GetFormResultType } from '@/utility/form.js'; import * as os from '@/os.js'; import { aiScriptReadline, createAiScriptEnv } from '@/aiscript/api.js'; import { $i } from '@/i.js'; @@ -25,19 +25,19 @@ const name = 'button'; const widgetPropsDef = { label: { - type: 'string' as const, + type: 'string', default: 'BUTTON', }, colored: { - type: 'boolean' as const, + type: 'boolean', default: true, }, script: { - type: 'string' as const, + type: 'string', multiline: true, default: 'Mk:dialog("hello" "world")', }, -}; +} satisfies FormWithDefault; type WidgetProps = GetFormResultType; @@ -81,7 +81,7 @@ const run = async () => { } catch (err) { os.alert({ type: 'error', - text: err, + text: err instanceof Error ? err.message : String(err), }); } }; diff --git a/packages/frontend/src/widgets/WidgetCalendar.vue b/packages/frontend/src/widgets/WidgetCalendar.vue index 54f78469b2..12c0a66c5c 100644 --- a/packages/frontend/src/widgets/WidgetCalendar.vue +++ b/packages/frontend/src/widgets/WidgetCalendar.vue @@ -41,7 +41,7 @@ SPDX-License-Identifier: AGPL-3.0-only import { ref } from 'vue'; import { useWidgetPropsManager } from './widget.js'; import type { WidgetComponentEmits, WidgetComponentExpose, WidgetComponentProps } from './widget.js'; -import type { GetFormResultType } from '@/utility/form.js'; +import type { FormWithDefault, GetFormResultType } from '@/utility/form.js'; import { i18n } from '@/i18n.js'; import { useInterval } from '@@/js/use-interval.js'; @@ -49,10 +49,10 @@ const name = 'calendar'; const widgetPropsDef = { transparent: { - type: 'boolean' as const, + type: 'boolean', default: false, }, -}; +} satisfies FormWithDefault; type WidgetProps = GetFormResultType; diff --git a/packages/frontend/src/widgets/WidgetChat.vue b/packages/frontend/src/widgets/WidgetChat.vue index 43b2a6e522..8fee7f00f6 100644 --- a/packages/frontend/src/widgets/WidgetChat.vue +++ b/packages/frontend/src/widgets/WidgetChat.vue @@ -19,7 +19,7 @@ SPDX-License-Identifier: AGPL-3.0-only import { } from 'vue'; import { useWidgetPropsManager } from './widget.js'; import type { WidgetComponentEmits, WidgetComponentExpose, WidgetComponentProps } from './widget.js'; -import type { GetFormResultType } from '@/utility/form.js'; +import type { FormWithDefault, GetFormResultType } from '@/utility/form.js'; import MkContainer from '@/components/MkContainer.vue'; import { i18n } from '@/i18n.js'; import MkChatHistories from '@/components/MkChatHistories.vue'; @@ -28,10 +28,10 @@ const name = 'chat'; const widgetPropsDef = { showHeader: { - type: 'boolean' as const, + type: 'boolean', default: true, }, -}; +} satisfies FormWithDefault; type WidgetProps = GetFormResultType; diff --git a/packages/frontend/src/widgets/WidgetClicker.vue b/packages/frontend/src/widgets/WidgetClicker.vue index 87ffd3d732..282a1a6d93 100644 --- a/packages/frontend/src/widgets/WidgetClicker.vue +++ b/packages/frontend/src/widgets/WidgetClicker.vue @@ -14,7 +14,7 @@ SPDX-License-Identifier: AGPL-3.0-only