/* * SPDX-FileCopyrightText: syuilo and misskey-project * SPDX-License-Identifier: AGPL-3.0-only */ import { defineAsyncComponent, reactive, watch } from 'vue'; import type { Reactive } from 'vue'; import { throttle } from 'throttle-debounce'; import type { FormWithDefault, GetFormResultType } from '@/utility/form.js'; import * as os from '@/os.js'; import { deepClone } from '@/utility/clone.js'; export type Widget

> = { id: string; data: Partial

; }; export type WidgetComponentProps

> = { widget?: Widget

; }; export type WidgetComponentEmits

> = { (ev: 'updateProps', props: P); }; export type WidgetComponentExpose = { name: string; id: string | null; configure: () => void; }; export const useWidgetPropsManager = ( name: string, propsDef: F, props: Readonly>>, emit: WidgetComponentEmits>, ): { widgetProps: Reactive>; save: () => void; configure: () => void; } => { const widgetProps = reactive>((props.widget ? deepClone(props.widget.data) : {}) as GetFormResultType); const mergeProps = () => { for (const prop of Object.keys(propsDef)) { if (typeof widgetProps[prop] === 'undefined') { widgetProps[prop] = propsDef[prop].default; } } }; watch(widgetProps, () => { mergeProps(); }, { deep: true, immediate: true }); const save = throttle(3000, () => { emit('updateProps', widgetProps as GetFormResultType); }); const configure = async () => { const form = deepClone(propsDef); for (const item of Object.keys(form)) { form[item].default = widgetProps[item]; } const res = await new Promise<{ canceled: false; result: GetFormResultType; } | { canceled: true; }>((resolve) => { const { dispose } = os.popup(defineAsyncComponent(() => import('@/components/MkWidgetSettingsDialog.vue')), { widgetName: name, form: form, currentSettings: widgetProps, }, { saved: (newProps: GetFormResultType) => { resolve({ canceled: false, result: newProps }); }, canceled: () => { resolve({ canceled: true }); }, closed: () => { dispose(); }, }); }); if (res.canceled) { return; } for (const key of Object.keys(res.result)) { widgetProps[key] = res.result[key]; } save(); }; return { widgetProps, save, configure, }; };