diff options
| author | misskey-release-bot[bot] <157398866+misskey-release-bot[bot]@users.noreply.github.com> | 2026-03-05 10:56:50 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-03-05 10:56:50 +0000 |
| commit | fe3dd8edb5f30104cd0a7ed755eb254feda2922d (patch) | |
| tree | af6cf5fa4ca75302ac2de5db742cead00bc13d21 /packages/frontend/src/widgets/widget.ts | |
| parent | Merge pull request #16998 from misskey-dev/develop (diff) | |
| parent | Release: 2026.3.0 (diff) | |
| download | misskey-fe3dd8edb5f30104cd0a7ed755eb254feda2922d.tar.gz misskey-fe3dd8edb5f30104cd0a7ed755eb254feda2922d.tar.bz2 misskey-fe3dd8edb5f30104cd0a7ed755eb254feda2922d.zip | |
Merge pull request #17217 from misskey-dev/develop
Release: 2026.3.0
Diffstat (limited to 'packages/frontend/src/widgets/widget.ts')
| -rw-r--r-- | packages/frontend/src/widgets/widget.ts | 69 |
1 files changed, 50 insertions, 19 deletions
diff --git a/packages/frontend/src/widgets/widget.ts b/packages/frontend/src/widgets/widget.ts index c5ca7ac26c..bfb724ff72 100644 --- a/packages/frontend/src/widgets/widget.ts +++ b/packages/frontend/src/widgets/widget.ts @@ -3,12 +3,14 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -import { reactive, watch } from 'vue'; -import type { Reactive } from 'vue'; +import { defineAsyncComponent, reactive, watch } from 'vue'; import { throttle } from 'throttle-debounce'; +import type { Reactive } from 'vue'; import type { FormWithDefault, GetFormResultType } from '@/utility/form.js'; +import { getDefaultFormValues } from '@/utility/form.js'; import * as os from '@/os.js'; import { deepClone } from '@/utility/clone.js'; +import type { WidgetName } from './index.js'; export type Widget<P extends Record<string, unknown>> = { id: string; @@ -20,7 +22,7 @@ export type WidgetComponentProps<P extends Record<string, unknown>> = { }; export type WidgetComponentEmits<P extends Record<string, unknown>> = { - (ev: 'updateProps', props: P); + (ev: 'updateProps', props: P): void; }; export type WidgetComponentExpose = { @@ -30,7 +32,7 @@ export type WidgetComponentExpose = { }; export const useWidgetPropsManager = <F extends FormWithDefault>( - name: string, + name: WidgetName, propsDef: F, props: Readonly<WidgetComponentProps<GetFormResultType<F>>>, emit: WidgetComponentEmits<GetFormResultType<F>>, @@ -39,19 +41,23 @@ export const useWidgetPropsManager = <F extends FormWithDefault>( save: () => void; configure: () => void; } => { - const widgetProps = reactive<GetFormResultType<F>>((props.widget ? deepClone(props.widget.data) : {}) as GetFormResultType<F>); - - const mergeProps = () => { - for (const prop of Object.keys(propsDef)) { - if (typeof widgetProps[prop] === 'undefined') { - widgetProps[prop] = propsDef[prop].default; + const widgetProps = reactive((() => { + const np = getDefaultFormValues(propsDef); + if (props.widget?.data != null) { + for (const key of Object.keys(props.widget.data) as (keyof F)[]) { + np[key] = props.widget.data[key] as GetFormResultType<F>[typeof key]; } } - }; + return np; + })()); - watch(widgetProps, () => { - mergeProps(); - }, { deep: true, immediate: true }); + watch(() => props.widget?.data, (to) => { + if (to != null) { + for (const key of Object.keys(propsDef)) { + (widgetProps as any)[key] = to[key]; + } + } + }, { deep: true }); const save = throttle(3000, () => { emit('updateProps', widgetProps as GetFormResultType<F>); @@ -60,13 +66,38 @@ export const useWidgetPropsManager = <F extends FormWithDefault>( const configure = async () => { const form = deepClone(propsDef); for (const item of Object.keys(form)) { - form[item].default = widgetProps[item]; + form[item].default = (widgetProps as any)[item]; + } + + const res = await new Promise<{ + canceled: false; + result: GetFormResultType<F>; + } | { + canceled: true; + }>((resolve) => { + const { dispose } = os.popup(defineAsyncComponent(() => import('@/components/MkWidgetSettingsDialog.vue')), { + widgetName: name, + form: form, + currentSettings: widgetProps, + }, { + saved: (newProps) => { + resolve({ canceled: false, result: newProps as GetFormResultType<F> }); + }, + canceled: () => { + resolve({ canceled: true }); + }, + closed: () => { + dispose(); + }, + }); + }); + + if (res.canceled) { + return; } - const { canceled, result } = await os.form(name, form); - if (canceled) return; - for (const key of Object.keys(result)) { - widgetProps[key] = result[key]; + for (const key of Object.keys(res.result)) { + (widgetProps as any)[key] = res.result[key]; } save(); |