Merge branch 'develop' into feat-1714

This commit is contained in:
かっこかり
2024-07-04 18:32:08 +09:00
committed by GitHub
116 changed files with 6003 additions and 4791 deletions

View File

@@ -117,11 +117,13 @@ export function promiseDialog<T extends Promise<any>>(
});
// NOTE: dynamic importすると挙動がおかしくなる(showingの変更が伝播しない)
popup(MkWaitingDialog, {
const { dispose } = popup(MkWaitingDialog, {
success: success,
showing: showing,
text: text,
}, {}, 'closed');
}, {
closed: () => dispose(),
});
return promise;
}
@@ -167,12 +169,11 @@ type EmitsExtractor<T> = {
[K in keyof T as K extends `onVnode${string}` ? never : K extends `on${infer E}` ? Uncapitalize<E> : K extends string ? never : K]: T[K];
};
export async function popup<T extends Component>(
export function popup<T extends Component>(
component: T,
props: ComponentProps<T>,
events: ComponentEmit<T> = {} as ComponentEmit<T>,
disposeEvent?: keyof ComponentEmit<T>,
): Promise<{ dispose: () => void }> {
): { dispose: () => void } {
if (embedPage) return { dispose: () => {} };
markRaw(component);
@@ -181,16 +182,13 @@ export async function popup<T extends Component>(
const dispose = () => {
// このsetTimeoutが無いと挙動がおかしくなる(autocompleteが閉じなくなる)。Vueのバグ
window.setTimeout(() => {
popups.value = popups.value.filter(popup => popup.id !== id);
popups.value = popups.value.filter(p => p.id !== id);
}, 0);
};
const state = {
component,
props,
events: disposeEvent ? {
...events,
[disposeEvent]: dispose,
} : events,
events,
id,
};
@@ -202,15 +200,19 @@ export async function popup<T extends Component>(
}
export function pageWindow(path: string) {
popup(MkPageWindow, {
const { dispose } = popup(MkPageWindow, {
initialPath: path,
}, {}, 'closed');
}, {
closed: () => dispose(),
});
}
export function toast(message: string) {
popup(MkToast, {
const { dispose } = popup(MkToast, {
message,
}, {}, 'closed');
}, {
closed: () => dispose(),
});
}
export function alert(props: {
@@ -219,11 +221,12 @@ export function alert(props: {
text?: string;
}): Promise<void> {
return new Promise(resolve => {
popup(MkDialog, props, {
const { dispose } = popup(MkDialog, props, {
done: () => {
resolve();
},
}, 'closed');
closed: () => dispose(),
});
});
}
@@ -235,14 +238,15 @@ export function confirm(props: {
cancelText?: string;
}): Promise<{ canceled: boolean }> {
return new Promise(resolve => {
popup(MkDialog, {
const { dispose } = popup(MkDialog, {
...props,
showCancelButton: true,
}, {
done: result => {
resolve(result ? result : { canceled: true });
},
}, 'closed');
closed: () => dispose(),
});
});
}
@@ -264,7 +268,7 @@ export function actions<T extends {
canceled: false; result: T[number]['value'];
}> {
return new Promise(resolve => {
popup(MkDialog, {
const { dispose } = popup(MkDialog, {
...props,
actions: props.actions.map(a => ({
text: a.text,
@@ -278,7 +282,8 @@ export function actions<T extends {
done: result => {
resolve(result ? result : { canceled: true });
},
}, 'closed');
closed: () => dispose(),
});
});
}
@@ -326,7 +331,7 @@ export function inputText(props: {
canceled: false; result: string | null;
}> {
return new Promise(resolve => {
popup(MkDialog, {
const { dispose } = popup(MkDialog, {
title: props.title,
text: props.text,
input: {
@@ -341,7 +346,8 @@ export function inputText(props: {
done: result => {
resolve(result ? result : { canceled: true });
},
}, 'closed');
closed: () => dispose(),
});
});
}
@@ -380,7 +386,7 @@ export function inputNumber(props: {
canceled: false; result: number | null;
}> {
return new Promise(resolve => {
popup(MkDialog, {
const { dispose } = popup(MkDialog, {
title: props.title,
text: props.text,
input: {
@@ -393,7 +399,8 @@ export function inputNumber(props: {
done: result => {
resolve(result ? result : { canceled: true });
},
}, 'closed');
closed: () => dispose(),
});
});
}
@@ -408,7 +415,7 @@ export function inputDate(props: {
canceled: false; result: Date;
}> {
return new Promise(resolve => {
popup(MkDialog, {
const { dispose } = popup(MkDialog, {
title: props.title,
text: props.text,
input: {
@@ -420,7 +427,8 @@ export function inputDate(props: {
done: result => {
resolve(result ? { result: new Date(result.result), canceled: false } : { result: undefined, canceled: true });
},
}, 'closed');
closed: () => dispose(),
});
});
}
@@ -430,11 +438,12 @@ export function authenticateDialog(): Promise<{
canceled: false; result: { password: string; token: string | null; };
}> {
return new Promise(resolve => {
popup(MkPasswordDialog, {}, {
const { dispose } = popup(MkPasswordDialog, {}, {
done: result => {
resolve(result ? { canceled: false, result } : { canceled: true, result: undefined });
},
}, 'closed');
closed: () => dispose(),
});
});
}
@@ -479,7 +488,7 @@ export function select<C = any>(props: {
canceled: false; result: C | null;
}> {
return new Promise(resolve => {
popup(MkDialog, {
const { dispose } = popup(MkDialog, {
title: props.title,
text: props.text,
select: {
@@ -490,7 +499,8 @@ export function select<C = any>(props: {
done: result => {
resolve(result ? result : { canceled: true });
},
}, 'closed');
closed: () => dispose(),
});
});
}
@@ -500,53 +510,57 @@ export function success(): Promise<void> {
window.setTimeout(() => {
showing.value = false;
}, 1000);
popup(MkWaitingDialog, {
const { dispose } = popup(MkWaitingDialog, {
success: true,
showing: showing,
}, {
done: () => resolve(),
}, 'closed');
closed: () => dispose(),
});
});
}
export function waiting(): Promise<void> {
return new Promise(resolve => {
const showing = ref(true);
popup(MkWaitingDialog, {
const { dispose } = popup(MkWaitingDialog, {
success: false,
showing: showing,
}, {
done: () => resolve(),
}, 'closed');
closed: () => dispose(),
});
});
}
export function form<F extends Form>(title: string, f: F): Promise<{ canceled: true, result?: undefined } | { canceled?: false, result: GetFormResultType<F> }> {
return new Promise(resolve => {
popup(defineAsyncComponent(() => import('@/components/MkFormDialog.vue')), { title, form: f }, {
const { dispose } = popup(defineAsyncComponent(() => import('@/components/MkFormDialog.vue')), { title, form: f }, {
done: result => {
resolve(result);
},
}, 'closed');
closed: () => dispose(),
});
});
}
export async function selectUser(opts: { includeSelf?: boolean; localOnly?: boolean; } = {}): Promise<Misskey.entities.UserDetailed> {
return new Promise(resolve => {
popup(defineAsyncComponent(() => import('@/components/MkUserSelectDialog.vue')), {
const { dispose } = popup(defineAsyncComponent(() => import('@/components/MkUserSelectDialog.vue')), {
includeSelf: opts.includeSelf,
localOnly: opts.localOnly,
}, {
ok: user => {
resolve(user);
},
}, 'closed');
closed: () => dispose(),
});
});
}
export async function selectDriveFile(multiple: boolean): Promise<Misskey.entities.DriveFile[]> {
return new Promise(resolve => {
popup(defineAsyncComponent(() => import('@/components/MkDriveSelectDialog.vue')), {
const { dispose } = popup(defineAsyncComponent(() => import('@/components/MkDriveSelectDialog.vue')), {
type: 'file',
multiple,
}, {
@@ -555,13 +569,14 @@ export async function selectDriveFile(multiple: boolean): Promise<Misskey.entiti
resolve(files);
}
},
}, 'closed');
closed: () => dispose(),
});
});
}
export async function selectDriveFolder(multiple: boolean): Promise<Misskey.entities.DriveFolder[]> {
return new Promise(resolve => {
popup(defineAsyncComponent(() => import('@/components/MkDriveSelectDialog.vue')), {
const { dispose } = popup(defineAsyncComponent(() => import('@/components/MkDriveSelectDialog.vue')), {
type: 'folder',
multiple,
}, {
@@ -570,20 +585,22 @@ export async function selectDriveFolder(multiple: boolean): Promise<Misskey.enti
resolve(folders);
}
},
}, 'closed');
closed: () => dispose(),
});
});
}
export async function pickEmoji(src: HTMLElement, opts: ComponentProps<typeof MkEmojiPickerDialog>): Promise<string> {
return new Promise(resolve => {
popup(MkEmojiPickerDialog, {
const { dispose } = popup(MkEmojiPickerDialog, {
src,
...opts,
}, {
done: emoji => {
resolve(emoji);
},
}, 'closed');
closed: () => dispose(),
});
});
}
@@ -592,7 +609,7 @@ export async function cropImage(image: Misskey.entities.DriveFile, options: {
uploadFolder?: string | null;
}): Promise<Misskey.entities.DriveFile> {
return new Promise(resolve => {
popup(defineAsyncComponent(() => import('@/components/MkCropperDialog.vue')), {
const { dispose } = popup(defineAsyncComponent(() => import('@/components/MkCropperDialog.vue')), {
file: image,
aspectRatio: options.aspectRatio,
uploadFolder: options.uploadFolder,
@@ -600,7 +617,8 @@ export async function cropImage(image: Misskey.entities.DriveFile, options: {
ok: x => {
resolve(x);
},
}, 'closed');
closed: () => dispose(),
});
});
}
@@ -611,8 +629,7 @@ export function popupMenu(items: MenuItem[], src?: HTMLElement | EventTarget | n
onClosing?: () => void;
}): Promise<void> {
return new Promise(resolve => {
let dispose;
popup(MkPopupMenu, {
const { dispose } = popup(MkPopupMenu, {
items,
src,
width: options?.width,
@@ -626,8 +643,6 @@ export function popupMenu(items: MenuItem[], src?: HTMLElement | EventTarget | n
closing: () => {
if (options?.onClosing) options.onClosing();
},
}).then(res => {
dispose = res.dispose;
});
});
}
@@ -637,8 +652,7 @@ export function contextMenu(items: MenuItem[], ev: MouseEvent): Promise<void> {
ev.preventDefault();
return new Promise(resolve => {
let dispose;
popup(MkContextMenu, {
const { dispose } = popup(MkContextMenu, {
items,
ev,
}, {
@@ -646,8 +660,6 @@ export function contextMenu(items: MenuItem[], ev: MouseEvent): Promise<void> {
resolve();
dispose();
},
}).then(res => {
dispose = res.dispose;
});
});
}
@@ -661,14 +673,11 @@ export function post(props: Record<string, any> = {}): Promise<void> {
// Vueが渡されたコンポーネントに内部的に__propsというプロパティを生やす影響で、
// 複数のpost formを開いたときに場合によってはエラーになる
// もちろん複数のpost formを開けること自体Misskeyサイドのバグなのだが
let dispose;
popup(MkPostFormDialog, props, {
const { dispose } = popup(MkPostFormDialog, props, {
closed: () => {
resolve();
dispose();
},
}).then(res => {
dispose = res.dispose;
});
});
}