2023-07-27 14:31:52 +09:00
|
|
|
/*
|
|
|
|
* SPDX-FileCopyrightText: syuilo and other misskey contributors
|
|
|
|
* SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
*/
|
|
|
|
|
2022-01-08 20:30:01 +09:00
|
|
|
import { reactive, watch } from 'vue';
|
|
|
|
import { throttle } from 'throttle-debounce';
|
2023-09-19 16:37:43 +09:00
|
|
|
import { Form, GetFormResultType } from '@/scripts/form.js';
|
|
|
|
import * as os from '@/os.js';
|
|
|
|
import { deepClone } from '@/scripts/clone.js';
|
2022-01-08 20:30:01 +09:00
|
|
|
|
|
|
|
export type Widget<P extends Record<string, unknown>> = {
|
|
|
|
id: string;
|
|
|
|
data: Partial<P>;
|
|
|
|
};
|
|
|
|
|
|
|
|
export type WidgetComponentProps<P extends Record<string, unknown>> = {
|
|
|
|
widget?: Widget<P>;
|
|
|
|
};
|
|
|
|
|
|
|
|
export type WidgetComponentEmits<P extends Record<string, unknown>> = {
|
2022-05-25 16:43:12 +09:00
|
|
|
(ev: 'updateProps', props: P);
|
2022-01-08 20:30:01 +09:00
|
|
|
};
|
|
|
|
|
|
|
|
export type WidgetComponentExpose = {
|
|
|
|
name: string;
|
|
|
|
id: string | null;
|
|
|
|
configure: () => void;
|
|
|
|
};
|
|
|
|
|
|
|
|
export const useWidgetPropsManager = <F extends Form & Record<string, { default: any; }>>(
|
|
|
|
name: string,
|
|
|
|
propsDef: F,
|
|
|
|
props: Readonly<WidgetComponentProps<GetFormResultType<F>>>,
|
|
|
|
emit: WidgetComponentEmits<GetFormResultType<F>>,
|
|
|
|
): {
|
|
|
|
widgetProps: GetFormResultType<F>;
|
|
|
|
save: () => void;
|
|
|
|
configure: () => void;
|
|
|
|
} => {
|
2022-11-17 09:31:07 +09:00
|
|
|
const widgetProps = reactive(props.widget ? deepClone(props.widget.data) : {});
|
2022-01-08 20:30:01 +09:00
|
|
|
|
|
|
|
const mergeProps = () => {
|
|
|
|
for (const prop of Object.keys(propsDef)) {
|
2022-07-04 23:39:04 +09:00
|
|
|
if (typeof widgetProps[prop] === 'undefined') {
|
|
|
|
widgetProps[prop] = propsDef[prop].default;
|
|
|
|
}
|
2022-01-08 20:30:01 +09:00
|
|
|
}
|
|
|
|
};
|
|
|
|
watch(widgetProps, () => {
|
|
|
|
mergeProps();
|
2022-11-17 09:31:07 +09:00
|
|
|
}, { deep: true, immediate: true });
|
2022-01-08 20:30:01 +09:00
|
|
|
|
|
|
|
const save = throttle(3000, () => {
|
2022-06-10 14:36:55 +09:00
|
|
|
emit('updateProps', widgetProps);
|
2022-01-08 20:30:01 +09:00
|
|
|
});
|
|
|
|
|
|
|
|
const configure = async () => {
|
2022-11-17 09:31:07 +09:00
|
|
|
const form = deepClone(propsDef);
|
2022-01-08 20:30:01 +09:00
|
|
|
for (const item of Object.keys(form)) {
|
|
|
|
form[item].default = widgetProps[item];
|
|
|
|
}
|
|
|
|
const { canceled, result } = await os.form(name, form);
|
|
|
|
if (canceled) return;
|
|
|
|
|
|
|
|
for (const key of Object.keys(result)) {
|
|
|
|
widgetProps[key] = result[key];
|
|
|
|
}
|
|
|
|
|
|
|
|
save();
|
|
|
|
};
|
|
|
|
|
|
|
|
return {
|
|
|
|
widgetProps,
|
|
|
|
save,
|
|
|
|
configure,
|
|
|
|
};
|
|
|
|
};
|