diff --git a/packages/client/src/components/abuse-report-window.vue b/packages/client/src/components/abuse-report-window.vue
index 700ce30bb2..d6d229bc8d 100644
--- a/packages/client/src/components/abuse-report-window.vue
+++ b/packages/client/src/components/abuse-report-window.vue
@@ -61,7 +61,7 @@ export default defineComponent({
 				userId: this.user.id,
 				comment: this.comment,
 			}, undefined, res => {
-				os.dialog({
+				os.alert({
 					type: 'success',
 					text: this.$ts.abuseReported
 				});
diff --git a/packages/client/src/components/drive.file.vue b/packages/client/src/components/drive.file.vue
index c191127e8c..7e510e4f5d 100644
--- a/packages/client/src/components/drive.file.vue
+++ b/packages/client/src/components/drive.file.vue
@@ -138,13 +138,11 @@ export default defineComponent({
 		},
 
 		rename() {
-			os.dialog({
+			os.inputText({
 				title: this.$ts.renameFile,
-				input: {
-					placeholder: this.$ts.inputNewFileName,
-					default: this.file.name,
-					allowEmpty: false
-				}
+				placeholder: this.$ts.inputNewFileName,
+				default: this.file.name,
+				allowEmpty: false
 			}).then(({ canceled, result: name }) => {
 				if (canceled) return;
 				os.api('drive/files/update', {
@@ -191,10 +189,9 @@ export default defineComponent({
 		},
 
 		async deleteFile() {
-			const { canceled } = await os.dialog({
+			const { canceled } = await os.confirm({
 				type: 'warning',
 				text: this.$t('driveFileDeleteConfirm', { name: this.file.name }),
-				showCancelButton: true
 			});
 			if (canceled) return;
 
diff --git a/packages/client/src/components/drive.folder.vue b/packages/client/src/components/drive.folder.vue
index 91e27cc8a1..95690b7e61 100644
--- a/packages/client/src/components/drive.folder.vue
+++ b/packages/client/src/components/drive.folder.vue
@@ -151,13 +151,13 @@ export default defineComponent({
 				}).catch(err => {
 					switch (err) {
 						case 'detected-circular-definition':
-							os.dialog({
+							os.alert({
 								title: this.$ts.unableToProcess,
 								text: this.$ts.circularReferenceFolder
 							});
 							break;
 						default:
-							os.dialog({
+							os.alert({
 								type: 'error',
 								text: this.$ts.somethingHappened
 							});
@@ -191,12 +191,10 @@ export default defineComponent({
 		},
 
 		rename() {
-			os.dialog({
+			os.inputText({
 				title: this.$ts.renameFolder,
-				input: {
-					placeholder: this.$ts.inputNewFolderName,
-					default: this.folder.name
-				}
+				placeholder: this.$ts.inputNewFolderName,
+				default: this.folder.name
 			}).then(({ canceled, result: name }) => {
 				if (canceled) return;
 				os.api('drive/folders/update', {
@@ -216,14 +214,14 @@ export default defineComponent({
 			}).catch(err => {
 				switch(err.id) {
 					case 'b0fc8a17-963c-405d-bfbc-859a487295e1':
-						os.dialog({
+						os.alert({
 							type: 'error',
 							title: this.$ts.unableToDelete,
 							text: this.$ts.hasChildFilesOrFolders
 						});
 						break;
 					default:
-						os.dialog({
+						os.alert({
 							type: 'error',
 							text: this.$ts.unableToDelete
 						});
diff --git a/packages/client/src/components/drive.vue b/packages/client/src/components/drive.vue
index 2b72a0a1c6..a785751ad2 100644
--- a/packages/client/src/components/drive.vue
+++ b/packages/client/src/components/drive.vue
@@ -274,13 +274,13 @@ export default defineComponent({
 				}).catch(err => {
 					switch (err) {
 						case 'detected-circular-definition':
-							os.dialog({
+							os.alert({
 								title: this.$ts.unableToProcess,
 								text: this.$ts.circularReferenceFolder
 							});
 							break;
 						default:
-							os.dialog({
+							os.alert({
 								type: 'error',
 								text: this.$ts.somethingHappened
 							});
@@ -295,11 +295,10 @@ export default defineComponent({
 		},
 
 		urlUpload() {
-			os.dialog({
+			os.inputText({
 				title: this.$ts.uploadFromUrl,
-				input: {
-					placeholder: this.$ts.uploadFromUrlDescription
-				}
+				type: 'url',
+				placeholder: this.$ts.uploadFromUrlDescription
 			}).then(({ canceled, result: url }) => {
 				if (canceled) return;
 				os.api('drive/files/upload-from-url', {
@@ -307,7 +306,7 @@ export default defineComponent({
 					folderId: this.folder ? this.folder.id : undefined
 				});
 
-				os.dialog({
+				os.alert({
 					title: this.$ts.uploadFromUrlRequested,
 					text: this.$ts.uploadFromUrlMayTakeTime
 				});
@@ -315,11 +314,9 @@ export default defineComponent({
 		},
 
 		createFolder() {
-			os.dialog({
+			os.inputText({
 				title: this.$ts.createFolder,
-				input: {
-					placeholder: this.$ts.folderName
-				}
+				placeholder: this.$ts.folderName
 			}).then(({ canceled, result: name }) => {
 				if (canceled) return;
 				os.api('drive/folders/create', {
@@ -332,12 +329,10 @@ export default defineComponent({
 		},
 
 		renameFolder(folder) {
-			os.dialog({
+			os.inputText({
 				title: this.$ts.renameFolder,
-				input: {
-					placeholder: this.$ts.inputNewFolderName,
-					default: folder.name
-				}
+				placeholder: this.$ts.inputNewFolderName,
+				default: folder.name
 			}).then(({ canceled, result: name }) => {
 				if (canceled) return;
 				os.api('drive/folders/update', {
@@ -359,14 +354,14 @@ export default defineComponent({
 			}).catch(err => {
 				switch(err.id) {
 					case 'b0fc8a17-963c-405d-bfbc-859a487295e1':
-						os.dialog({
+						os.alert({
 							type: 'error',
 							title: this.$ts.unableToDelete,
 							text: this.$ts.hasChildFilesOrFolders
 						});
 						break;
 					default:
-						os.dialog({
+						os.alert({
 							type: 'error',
 							text: this.$ts.unableToDelete
 						});
diff --git a/packages/client/src/components/follow-button.vue b/packages/client/src/components/follow-button.vue
index a96899027f..ab19c64768 100644
--- a/packages/client/src/components/follow-button.vue
+++ b/packages/client/src/components/follow-button.vue
@@ -94,10 +94,9 @@ export default defineComponent({
 
 			try {
 				if (this.isFollowing) {
-					const { canceled } = await os.dialog({
+					const { canceled } = await os.confirm({
 						type: 'warning',
 						text: this.$t('unfollowConfirm', { name: this.user.name || this.user.username }),
-						showCancelButton: true
 					});
 
 					if (canceled) return;
diff --git a/packages/client/src/components/note-detailed.vue b/packages/client/src/components/note-detailed.vue
index 3b5b12a60a..55e0fb8614 100644
--- a/packages/client/src/components/note-detailed.vue
+++ b/packages/client/src/components/note-detailed.vue
@@ -456,18 +456,18 @@ export default defineComponent({
 			os.apiWithDialog('notes/create', {
 				renoteId: this.appearNote.id
 			}, undefined, (res: any) => {
-				os.dialog({
+				os.alert({
 					type: 'success',
 					text: this.$ts.renoted,
 				});
 			}, (e: Error) => {
 				if (e.id === 'b5c90186-4ab0-49c8-9bba-a1f76c282ba4') {
-					os.dialog({
+					os.alert({
 						type: 'error',
 						text: this.$ts.cantRenote,
 					});
 				} else if (e.id === 'fd4cc33e-2a37-48dd-99cc-9b806eb2031a') {
-					os.dialog({
+					os.alert({
 						type: 'error',
 						text: this.$ts.cantReRenote,
 					});
@@ -508,18 +508,18 @@ export default defineComponent({
 			os.apiWithDialog('notes/favorites/create', {
 				noteId: this.appearNote.id
 			}, undefined, (res: any) => {
-				os.dialog({
+				os.alert({
 					type: 'success',
 					text: this.$ts.favorited,
 				});
 			}, (e: Error) => {
 				if (e.id === 'a402c12b-34dd-41d2-97d8-4d2ffd96a1a6') {
-					os.dialog({
+					os.alert({
 						type: 'error',
 						text: this.$ts.alreadyFavorited,
 					});
 				} else if (e.id === '6dd26674-e060-4816-909a-45ba3f4da458') {
-					os.dialog({
+					os.alert({
 						type: 'error',
 						text: this.$ts.cantFavorite,
 					});
@@ -528,10 +528,9 @@ export default defineComponent({
 		},
 
 		del() {
-			os.dialog({
+			os.confirm({
 				type: 'warning',
 				text: this.$ts.noteDeleteConfirm,
-				showCancelButton: true
 			}).then(({ canceled }) => {
 				if (canceled) return;
 
@@ -542,10 +541,9 @@ export default defineComponent({
 		},
 
 		delEdit() {
-			os.dialog({
+			os.confirm({
 				type: 'warning',
 				text: this.$ts.deleteAndEditConfirm,
-				showCancelButton: true
 			}).then(({ canceled }) => {
 				if (canceled) return;
 
@@ -781,7 +779,7 @@ export default defineComponent({
 				noteId: this.appearNote.id
 			}, undefined, null, e => {
 				if (e.id === '72dab508-c64d-498f-8740-a8eec1ba385a') {
-					os.dialog({
+					os.alert({
 						type: 'error',
 						text: this.$ts.pinLimitExceeded
 					});
@@ -828,9 +826,8 @@ export default defineComponent({
 		},
 
 		async promote() {
-			const { canceled, result: days } = await os.dialog({
+			const { canceled, result: days } = await os.inputNumber({
 				title: this.$ts.numberOfDays,
-				input: { type: 'number' }
 			});
 
 			if (canceled) return;
diff --git a/packages/client/src/components/note.vue b/packages/client/src/components/note.vue
index 2ab769db43..a948ca2e49 100644
--- a/packages/client/src/components/note.vue
+++ b/packages/client/src/components/note.vue
@@ -432,18 +432,18 @@ export default defineComponent({
 			os.apiWithDialog('notes/create', {
 				renoteId: this.appearNote.id
 			}, undefined, (res: any) => {
-				os.dialog({
+				os.alert({
 					type: 'success',
 					text: this.$ts.renoted,
 				});
 			}, (e: Error) => {
 				if (e.id === 'b5c90186-4ab0-49c8-9bba-a1f76c282ba4') {
-					os.dialog({
+					os.alert({
 						type: 'error',
 						text: this.$ts.cantRenote,
 					});
 				} else if (e.id === 'fd4cc33e-2a37-48dd-99cc-9b806eb2031a') {
-					os.dialog({
+					os.alert({
 						type: 'error',
 						text: this.$ts.cantReRenote,
 					});
@@ -484,18 +484,18 @@ export default defineComponent({
 			os.apiWithDialog('notes/favorites/create', {
 				noteId: this.appearNote.id
 			}, undefined, (res: any) => {
-				os.dialog({
+				os.alert({
 					type: 'success',
 					text: this.$ts.favorited,
 				});
 			}, (e: Error) => {
 				if (e.id === 'a402c12b-34dd-41d2-97d8-4d2ffd96a1a6') {
-					os.dialog({
+					os.alert({
 						type: 'error',
 						text: this.$ts.alreadyFavorited,
 					});
 				} else if (e.id === '6dd26674-e060-4816-909a-45ba3f4da458') {
-					os.dialog({
+					os.alert({
 						type: 'error',
 						text: this.$ts.cantFavorite,
 					});
@@ -504,10 +504,9 @@ export default defineComponent({
 		},
 
 		del() {
-			os.dialog({
+			os.confirm({
 				type: 'warning',
 				text: this.$ts.noteDeleteConfirm,
-				showCancelButton: true
 			}).then(({ canceled }) => {
 				if (canceled) return;
 
@@ -518,10 +517,9 @@ export default defineComponent({
 		},
 
 		delEdit() {
-			os.dialog({
+			os.confirm({
 				type: 'warning',
 				text: this.$ts.deleteAndEditConfirm,
-				showCancelButton: true
 			}).then(({ canceled }) => {
 				if (canceled) return;
 
@@ -757,7 +755,7 @@ export default defineComponent({
 				noteId: this.appearNote.id
 			}, undefined, null, e => {
 				if (e.id === '72dab508-c64d-498f-8740-a8eec1ba385a') {
-					os.dialog({
+					os.alert({
 						type: 'error',
 						text: this.$ts.pinLimitExceeded
 					});
@@ -804,9 +802,8 @@ export default defineComponent({
 		},
 
 		async promote() {
-			const { canceled, result: days } = await os.dialog({
+			const { canceled, result: days } = await os.inputNumber({
 				title: this.$ts.numberOfDays,
-				input: { type: 'number' }
 			});
 
 			if (canceled) return;
diff --git a/packages/client/src/components/page/page.button.vue b/packages/client/src/components/page/page.button.vue
index 51da84bd49..d6fa42bd59 100644
--- a/packages/client/src/components/page/page.button.vue
+++ b/packages/client/src/components/page/page.button.vue
@@ -29,7 +29,7 @@ export default defineComponent({
 		click() {
 			if (this.block.action === 'dialog') {
 				this.hpml.eval();
-				os.dialog({
+				os.alert({
 					text: this.hpml.interpolate(this.block.content)
 				});
 			} else if (this.block.action === 'resetRandom') {
@@ -44,7 +44,7 @@ export default defineComponent({
 					} : {})
 				});
 
-				os.dialog({
+				os.alert({
 					type: 'success',
 					text: this.hpml.interpolate(this.block.message)
 				});
diff --git a/packages/client/src/components/page/page.vue b/packages/client/src/components/page/page.vue
index 6d1c419a40..cd81b16c55 100644
--- a/packages/client/src/components/page/page.vue
+++ b/packages/client/src/components/page/page.vue
@@ -40,7 +40,7 @@ export default defineComponent({
 						ast = parse(props.page.script);
 					} catch (e) {
 						console.error(e);
-						/*os.dialog({
+						/*os.alert({
 							type: 'error',
 							text: 'Syntax error :('
 						});*/
@@ -50,7 +50,7 @@ export default defineComponent({
 						hpml.eval();
 					}).catch(e => {
 						console.error(e);
-						/*os.dialog({
+						/*os.alert({
 							type: 'error',
 							text: e
 						});*/
diff --git a/packages/client/src/components/post-form-attaches.vue b/packages/client/src/components/post-form-attaches.vue
index dff0dec21e..23ccd54dd8 100644
--- a/packages/client/src/components/post-form-attaches.vue
+++ b/packages/client/src/components/post-form-attaches.vue
@@ -73,11 +73,9 @@ export default defineComponent({
 			});
 		},
 		async rename(file) {
-			const { canceled, result } = await os.dialog({
+			const { canceled, result } = await os.inputText({
 				title: this.$ts.enterFileName,
-				input: {
-					default: file.name
-				},
+				default: file.name,
 				allowEmpty: false
 			});
 			if (canceled) return;
diff --git a/packages/client/src/components/post-form.vue b/packages/client/src/components/post-form.vue
index 882a71a371..88b88e17eb 100644
--- a/packages/client/src/components/post-form.vue
+++ b/packages/client/src/components/post-form.vue
@@ -554,10 +554,9 @@ export default defineComponent({
 			if (!this.renote && !this.quoteId && paste.startsWith(url + '/notes/')) {
 				e.preventDefault();
 
-				os.dialog({
+				os.confirm({
 					type: 'info',
 					text: this.$ts.quoteQuestion,
-					showCancelButton: true
 				}).then(({ canceled }) => {
 					if (canceled) {
 						insertTextAtCursor(this.$refs.text, paste);
@@ -676,7 +675,7 @@ export default defineComponent({
 				});
 			}).catch(err => {
 				this.posting = false;
-				os.dialog({
+				os.alert({
 					type: 'error',
 					text: err.message + '\n' + (err as any).id,
 				});
diff --git a/packages/client/src/components/sample.vue b/packages/client/src/components/sample.vue
index ba6c682c44..03ad6a9838 100644
--- a/packages/client/src/components/sample.vue
+++ b/packages/client/src/components/sample.vue
@@ -57,7 +57,7 @@ export default defineComponent({
 
 	methods: {
 		async openDialog() {
-			os.dialog({
+			os.alert({
 				type: 'warning',
 				title: 'Oh my Aichan',
 				text: 'Lorem ipsum dolor sit amet, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.',
diff --git a/packages/client/src/components/signin.vue b/packages/client/src/components/signin.vue
index 68bbd5368e..ef299090fa 100644
--- a/packages/client/src/components/signin.vue
+++ b/packages/client/src/components/signin.vue
@@ -150,7 +150,7 @@ export default defineComponent({
 				return this.onLogin(res);
 			}).catch(err => {
 				if (err === null) return;
-				os.dialog({
+				os.alert({
 					type: 'error',
 					text: this.$ts.signinFailed
 				});
@@ -190,7 +190,7 @@ export default defineComponent({
 		loginFailed(err) {
 			switch (err.id) {
 				case '6cc579cc-885d-43d8-95c2-b8c7fc963280': {
-					os.dialog({
+					os.alert({
 						type: 'error',
 						title: this.$ts.loginFailed,
 						text: this.$ts.noSuchUser
@@ -202,7 +202,7 @@ export default defineComponent({
 					break;
 				}
 				default: {
-					os.dialog({
+					os.alert({
 						type: 'error',
 						title: this.$ts.loginFailed,
 						text: JSON.stringify(err)
diff --git a/packages/client/src/components/signup.vue b/packages/client/src/components/signup.vue
index 621f30486f..0572fdaa7a 100644
--- a/packages/client/src/components/signup.vue
+++ b/packages/client/src/components/signup.vue
@@ -220,7 +220,7 @@ export default defineComponent({
 				'g-recaptcha-response': this.reCaptchaResponse,
 			}).then(() => {
 				if (this.meta.emailRequiredForSignup) {
-					os.dialog({
+					os.alert({
 						type: 'success',
 						title: this.$ts._signup.almostThere,
 						text: this.$t('_signup.emailSent', { email: this.email }),
@@ -243,7 +243,7 @@ export default defineComponent({
 				this.$refs.hcaptcha?.reset?.();
 				this.$refs.recaptcha?.reset?.();
 
-				os.dialog({
+				os.alert({
 					type: 'error',
 					text: this.$ts.somethingHappened
 				});
diff --git a/packages/client/src/os.ts b/packages/client/src/os.ts
index a570ffc9ed..4f547ba5a5 100644
--- a/packages/client/src/os.ts
+++ b/packages/client/src/os.ts
@@ -214,13 +214,141 @@ export function modalPageWindow(path: string) {
 	}, {}, 'closed');
 }
 
-export function dialog(props: {
-	type: 'error' | 'info' | 'success' | 'warning' | 'waiting';
+export function alert(props: {
+	type?: 'error' | 'info' | 'success' | 'warning' | 'waiting' | 'question';
 	title?: string | null;
 	text?: string | null;
-}) {
+}): Promise<void> {
 	return new Promise((resolve, reject) => {
 		popup(import('@/components/dialog.vue'), props, {
+			done: result => {
+				resolve();
+			},
+		}, 'closed');
+	});
+}
+
+export function confirm(props: {
+	type: 'error' | 'info' | 'success' | 'warning' | 'waiting' | 'question';
+	title?: string | null;
+	text?: string | null;
+}): Promise<{ canceled: boolean }> {
+	return new Promise((resolve, reject) => {
+		popup(import('@/components/dialog.vue'), {
+			...props,
+			showCancelButton: true,
+		}, {
+			done: result => {
+				resolve(result ? result : { canceled: true });
+			},
+		}, 'closed');
+	});
+}
+
+export function inputText(props: {
+	type?: 'text' | 'email' | 'password' | 'url';
+	title?: string | null;
+	text?: string | null;
+	placeholder?: string | null;
+	default?: string | null;
+}): Promise<{ canceled: true; result: undefined; } | {
+	canceled: false; result: string;
+}> {
+	return new Promise((resolve, reject) => {
+		popup(import('@/components/dialog.vue'), {
+			title: props.title,
+			text: props.text,
+			input: {
+				type: props.type,
+				placeholder: props.placeholder,
+				default: props.default,
+			}
+		}, {
+			done: result => {
+				resolve(result ? result : { canceled: true });
+			},
+		}, 'closed');
+	});
+}
+
+export function inputNumber(props: {
+	title?: string | null;
+	text?: string | null;
+	placeholder?: string | null;
+	default?: number | null;
+}): Promise<{ canceled: true; result: undefined; } | {
+	canceled: false; result: number;
+}> {
+	return new Promise((resolve, reject) => {
+		popup(import('@/components/dialog.vue'), {
+			title: props.title,
+			text: props.text,
+			input: {
+				type: 'number',
+				placeholder: props.placeholder,
+				default: props.default,
+			}
+		}, {
+			done: result => {
+				resolve(result ? result : { canceled: true });
+			},
+		}, 'closed');
+	});
+}
+
+export function inputDate(props: {
+	title?: string | null;
+	text?: string | null;
+	placeholder?: string | null;
+	default?: Date | null;
+}): Promise<{ canceled: true; result: undefined; } | {
+	canceled: false; result: Date;
+}> {
+	return new Promise((resolve, reject) => {
+		popup(import('@/components/dialog.vue'), {
+			title: props.title,
+			text: props.text,
+			input: {
+				type: 'date',
+				placeholder: props.placeholder,
+				default: props.default,
+			}
+		}, {
+			done: result => {
+				resolve(result ? { result: new Date(result.result), canceled: false } : { canceled: true });
+			},
+		}, 'closed');
+	});
+}
+
+export function select(props: {
+	title?: string | null;
+	text?: string | null;
+	default?: string | null;
+	items?: {
+		value: string;
+		text: string;
+	}[];
+	groupedItems?: {
+		label: string;
+		items: {
+			value: string;
+			text: string;
+		}[];
+	}[];
+}): Promise<{ canceled: true; result: undefined; } | {
+	canceled: false; result: string;
+}> {
+	return new Promise((resolve, reject) => {
+		popup(import('@/components/dialog.vue'), {
+			title: props.title,
+			text: props.text,
+			select: {
+				items: props.items,
+				groupedItems: props.groupedItems,
+				default: props.default,
+			}
+		}, {
 			done: result => {
 				resolve(result ? result : { canceled: true });
 			},
diff --git a/packages/client/src/pages/admin/ads.vue b/packages/client/src/pages/admin/ads.vue
index df6c9d5d00..5652080cd7 100644
--- a/packages/client/src/pages/admin/ads.vue
+++ b/packages/client/src/pages/admin/ads.vue
@@ -101,10 +101,9 @@ export default defineComponent({
 		},
 
 		remove(ad) {
-			os.dialog({
+			os.confirm({
 				type: 'warning',
 				text: this.$t('removeAreYouSure', { x: ad.url }),
-				showCancelButton: true
 			}).then(({ canceled }) => {
 				if (canceled) return;
 				this.ads = this.ads.filter(x => x != ad);
diff --git a/packages/client/src/pages/admin/announcements.vue b/packages/client/src/pages/admin/announcements.vue
index a64008967f..301b0f9f5f 100644
--- a/packages/client/src/pages/admin/announcements.vue
+++ b/packages/client/src/pages/admin/announcements.vue
@@ -76,10 +76,9 @@ export default defineComponent({
 		},
 
 		remove(announcement) {
-			os.dialog({
+			os.confirm({
 				type: 'warning',
 				text: this.$t('removeAreYouSure', { x: announcement.title }),
-				showCancelButton: true
 			}).then(({ canceled }) => {
 				if (canceled) return;
 				this.announcements = this.announcements.filter(x => x != announcement);
@@ -90,24 +89,24 @@ export default defineComponent({
 		save(announcement) {
 			if (announcement.id == null) {
 				os.api('admin/announcements/create', announcement).then(() => {
-					os.dialog({
+					os.alert({
 						type: 'success',
 						text: this.$ts.saved
 					});
 				}).catch(e => {
-					os.dialog({
+					os.alert({
 						type: 'error',
 						text: e
 					});
 				});
 			} else {
 				os.api('admin/announcements/update', announcement).then(() => {
-					os.dialog({
+					os.alert({
 						type: 'success',
 						text: this.$ts.saved
 					});
 				}).catch(e => {
-					os.dialog({
+					os.alert({
 						type: 'error',
 						text: e
 					});
diff --git a/packages/client/src/pages/admin/email-settings.vue b/packages/client/src/pages/admin/email-settings.vue
index 3733f53a23..aad971830e 100644
--- a/packages/client/src/pages/admin/email-settings.vue
+++ b/packages/client/src/pages/admin/email-settings.vue
@@ -96,11 +96,10 @@ export default defineComponent({
 		},
 
 		async testEmail() {
-			const { canceled, result: destination } = await os.dialog({
+			const { canceled, result: destination } = await os.inputText({
 				title: this.$ts.destination,
-				input: {
-					placeholder: this.$instance.maintainerEmail
-				}
+				type: 'email',
+				placeholder: this.$instance.maintainerEmail
 			});
 			if (canceled) return;
 			os.apiWithDialog('admin/send-email', {
diff --git a/packages/client/src/pages/admin/emoji-edit-dialog.vue b/packages/client/src/pages/admin/emoji-edit-dialog.vue
index e612855105..dcc5a9cbee 100644
--- a/packages/client/src/pages/admin/emoji-edit-dialog.vue
+++ b/packages/client/src/pages/admin/emoji-edit-dialog.vue
@@ -89,10 +89,9 @@ export default defineComponent({
 		},
 
 		async del() {
-			const { canceled } = await os.dialog({
+			const { canceled } = await os.confirm({
 				type: 'warning',
 				text: this.$t('removeAreYouSure', { x: this.emoji.name }),
-				showCancelButton: true
 			});
 			if (canceled) return;
 
diff --git a/packages/client/src/pages/admin/file-dialog.vue b/packages/client/src/pages/admin/file-dialog.vue
index 016a012ea5..0d36276553 100644
--- a/packages/client/src/pages/admin/file-dialog.vue
+++ b/packages/client/src/pages/admin/file-dialog.vue
@@ -86,10 +86,9 @@ export default defineComponent({
 		},
 
 		async del() {
-			const { canceled } = await os.dialog({
+			const { canceled } = await os.confirm({
 				type: 'warning',
 				text: this.$t('removeAreYouSure', { x: this.file.name }),
-				showCancelButton: true
 			});
 			if (canceled) return;
 
diff --git a/packages/client/src/pages/admin/files.vue b/packages/client/src/pages/admin/files.vue
index e291d97bbc..30bef13356 100644
--- a/packages/client/src/pages/admin/files.vue
+++ b/packages/client/src/pages/admin/files.vue
@@ -124,10 +124,9 @@ export default defineComponent({
 
 	methods: {
 		clear() {
-			os.dialog({
+			os.confirm({
 				type: 'warning',
 				text: this.$ts.clearCachedFilesConfirm,
-				showCancelButton: true
 			}).then(({ canceled }) => {
 				if (canceled) return;
 
@@ -146,7 +145,7 @@ export default defineComponent({
 				this.show(file);
 			}).catch(e => {
 				if (e.code === 'NO_SUCH_FILE') {
-					os.dialog({
+					os.alert({
 						type: 'error',
 						text: this.$ts.notFound
 					});
diff --git a/packages/client/src/pages/admin/index.vue b/packages/client/src/pages/admin/index.vue
index d3f9406db7..24ca2f65f2 100644
--- a/packages/client/src/pages/admin/index.vue
+++ b/packages/client/src/pages/admin/index.vue
@@ -281,12 +281,12 @@ export default defineComponent({
 
 		const invite = () => {
 			os.api('admin/invite').then(x => {
-				os.dialog({
+				os.alert({
 					type: 'info',
 					text: x.code
 				});
 			}).catch(e => {
-				os.dialog({
+				os.alert({
 					type: 'error',
 					text: e
 				});
diff --git a/packages/client/src/pages/admin/queue.vue b/packages/client/src/pages/admin/queue.vue
index 896298840c..0886216c7b 100644
--- a/packages/client/src/pages/admin/queue.vue
+++ b/packages/client/src/pages/admin/queue.vue
@@ -57,11 +57,10 @@ export default defineComponent({
 
 	methods: {
 		clear() {
-			os.dialog({
+			os.confirm({
 				type: 'warning',
 				title: this.$ts.clearQueueConfirmTitle,
 				text: this.$ts.clearQueueConfirmText,
-				showCancelButton: true
 			}).then(({ canceled }) => {
 				if (canceled) return;
 
diff --git a/packages/client/src/pages/admin/relays.vue b/packages/client/src/pages/admin/relays.vue
index fd0ce97d57..f4cfc2a885 100644
--- a/packages/client/src/pages/admin/relays.vue
+++ b/packages/client/src/pages/admin/relays.vue
@@ -53,11 +53,10 @@ export default defineComponent({
 
 	methods: {
 		async addRelay() {
-			const { canceled, result: inbox } = await os.dialog({
+			const { canceled, result: inbox } = await os.inputText({
 				title: this.$ts.addRelay,
-				input: {
-					placeholder: this.$ts.inboxUrl
-				}
+				type: 'url',
+				placeholder: this.$ts.inboxUrl
 			});
 			if (canceled) return;
 			os.api('admin/relays/add', {
@@ -65,7 +64,7 @@ export default defineComponent({
 			}).then((relay: any) => {
 				this.refresh();
 			}).catch((e: any) => {
-				os.dialog({
+				os.alert({
 					type: 'error',
 					text: e.message || e
 				});
@@ -78,7 +77,7 @@ export default defineComponent({
 			}).then(() => {
 				this.refresh();
 			}).catch((e: any) => {
-				os.dialog({
+				os.alert({
 					type: 'error',
 					text: e.message || e
 				});
diff --git a/packages/client/src/pages/admin/users.vue b/packages/client/src/pages/admin/users.vue
index f4a2ffa6d2..3c43c7aa36 100644
--- a/packages/client/src/pages/admin/users.vue
+++ b/packages/client/src/pages/admin/users.vue
@@ -150,15 +150,14 @@ export default defineComponent({
 		},
 
 		async addUser() {
-			const { canceled: canceled1, result: username } = await os.dialog({
+			const { canceled: canceled1, result: username } = await os.inputText({
 				title: this.$ts.username,
-				input: true
 			});
 			if (canceled1) return;
 
-			const { canceled: canceled2, result: password } = await os.dialog({
+			const { canceled: canceled2, result: password } = await os.inputText({
 				title: this.$ts.password,
-				input: { type: 'password' }
+				type: 'password'
 			});
 			if (canceled2) return;
 
diff --git a/packages/client/src/pages/advanced-theme-editor.vue b/packages/client/src/pages/advanced-theme-editor.vue
index eebfc21b3f..122c7821b7 100644
--- a/packages/client/src/pages/advanced-theme-editor.vue
+++ b/packages/client/src/pages/advanced-theme-editor.vue
@@ -175,10 +175,9 @@ export default defineComponent({
 		},
 
 		async confirm(): Promise<boolean> {
-			const { canceled } = await os.dialog({
+			const { canceled } = await os.confirm({
 				type: 'warning',
 				text: this.$ts.leaveConfirm,
-				showCancelButton: true
 			});
 			return !canceled;
 		},
@@ -192,9 +191,8 @@ export default defineComponent({
 		},
 	
 		async del(i: number) {
-			const { canceled } = await os.dialog({ 
+			const { canceled } = await os.confirm({ 
 				type: 'warning',
-				showCancelButton: true,
 				text: this.$t('_theme.deleteConstantConfirm', { const: this.theme[i][0] }),
 			});
 			if (canceled) return;
@@ -202,9 +200,8 @@ export default defineComponent({
 		},
 	
 		async addConst() {
-			const { canceled, result } = await os.dialog({
+			const { canceled, result } = await os.inputText({
 				title: this.$ts._theme.inputConstantName,
-				input: true
 			});
 			if (canceled) return;
 			this.theme.push([ '$' + result, '#000000']);
@@ -213,7 +210,7 @@ export default defineComponent({
 		save() {
 			const theme = convertToMisskeyTheme(this.theme, this.name, this.description, this.author, this.baseTheme);
 			addTheme(theme);
-			os.dialog({
+			os.alert({
 				type: 'success',
 				text: this.$t('_theme.installed', { name: theme.name })
 			});
@@ -225,7 +222,7 @@ export default defineComponent({
 			try {
 				applyTheme(theme, false);
 			} catch (e) {
-				os.dialog({
+				os.alert({
 					type: 'error',
 					text: e.message
 				});
@@ -246,7 +243,7 @@ export default defineComponent({
 				this.theme = convertToViewModel(theme);
 				this.themeToImport = '';
 			} catch (e) {
-				os.dialog({
+				os.alert({
 					type: 'error',
 					text: e.message
 				});
diff --git a/packages/client/src/pages/antenna-timeline.vue b/packages/client/src/pages/antenna-timeline.vue
index f7f6990fa8..a874ca6025 100644
--- a/packages/client/src/pages/antenna-timeline.vue
+++ b/packages/client/src/pages/antenna-timeline.vue
@@ -93,15 +93,12 @@ export default defineComponent({
 		},
 
 		async timetravel() {
-			const { canceled, result: date } = await os.dialog({
+			const { canceled, result: date } = await os.inputDate({
 				title: this.$ts.date,
-				input: {
-					type: 'date'
-				}
 			});
 			if (canceled) return;
 
-			this.$refs.tl.timetravel(new Date(date));
+			this.$refs.tl.timetravel(date);
 		},
 
 		settings() {
diff --git a/packages/client/src/pages/clip.vue b/packages/client/src/pages/clip.vue
index 510a73ce68..dc7abf36b4 100644
--- a/packages/client/src/pages/clip.vue
+++ b/packages/client/src/pages/clip.vue
@@ -114,10 +114,9 @@ export default defineComponent({
 				text: this.$ts.delete,
 				danger: true,
 				action: async () => {
-					const { canceled } = await os.dialog({
+					const { canceled } = await os.confirm({
 						type: 'warning',
 						text: this.$t('deleteAreYouSure', { x: this.clip.name }),
-						showCancelButton: true
 					});
 					if (canceled) return;
 
diff --git a/packages/client/src/pages/follow.vue b/packages/client/src/pages/follow.vue
index e8eaad73bf..d8a6824dca 100644
--- a/packages/client/src/pages/follow.vue
+++ b/packages/client/src/pages/follow.vue
@@ -25,7 +25,7 @@ export default defineComponent({
 				} else if (res.type === 'Note') {
 					this.$router.push(`/notes/${res.object.id}`);
 				} else {
-					os.dialog({
+					os.alert({
 						type: 'error',
 						text: 'Not a user'
 					}).then(() => {
@@ -45,10 +45,9 @@ export default defineComponent({
 
 	methods: {
 		async follow(user) {
-			const { canceled } = await os.dialog({
+			const { canceled } = await os.confirm({
 				type: 'question',
 				text: this.$t('followConfirm', { name: user.name || user.username }),
-				showCancelButton: true
 			});
 
 			if (canceled) {
diff --git a/packages/client/src/pages/gallery/edit.vue b/packages/client/src/pages/gallery/edit.vue
index 1ee3a9390b..b34928713d 100644
--- a/packages/client/src/pages/gallery/edit.vue
+++ b/packages/client/src/pages/gallery/edit.vue
@@ -126,10 +126,9 @@ export default defineComponent({
 		},
 
 		async del() {
-			const { canceled } = await os.dialog({
+			const { canceled } = await os.confirm({
 				type: 'warning',
 				text: this.$ts.deleteConfirm,
-				showCancelButton: true
 			});
 			if (canceled) return;
 			await os.apiWithDialog('gallery/posts/delete', {
diff --git a/packages/client/src/pages/gallery/post.vue b/packages/client/src/pages/gallery/post.vue
index 255954def0..531ecda8de 100644
--- a/packages/client/src/pages/gallery/post.vue
+++ b/packages/client/src/pages/gallery/post.vue
@@ -148,9 +148,8 @@ export default defineComponent({
 		},
 
 		async unlike() {
-			const confirm = await os.dialog({
+			const confirm = await os.confirm({
 				type: 'warning',
-				showCancelButton: true,
 				text: this.$ts.unlikeConfirm,
 			});
 			if (confirm.canceled) return;
diff --git a/packages/client/src/pages/messaging/index.vue b/packages/client/src/pages/messaging/index.vue
index 896c3927ce..d0a02aa443 100644
--- a/packages/client/src/pages/messaging/index.vue
+++ b/packages/client/src/pages/messaging/index.vue
@@ -140,22 +140,18 @@ export default defineComponent({
 			const groups1 = await os.api('users/groups/owned');
 			const groups2 = await os.api('users/groups/joined');
 			if (groups1.length === 0 && groups2.length === 0) {
-				os.dialog({
+				os.alert({
 					type: 'warning',
 					title: this.$ts.youHaveNoGroups,
 					text: this.$ts.joinOrCreateGroup,
 				});
 				return;
 			}
-			const { canceled, result: group } = await os.dialog({
-				type: null,
+			const { canceled, result: group } = await os.select({
 				title: this.$ts.group,
-				select: {
-					items: groups1.concat(groups2).map(group => ({
-						value: group, text: group.name
-					}))
-				},
-				showCancelButton: true
+				items: groups1.concat(groups2).map(group => ({
+					value: group, text: group.name
+				}))
 			});
 			if (canceled) return;
 			this.$router.push(`/my/messaging/group/${group.id}`);
diff --git a/packages/client/src/pages/messaging/messaging-room.form.vue b/packages/client/src/pages/messaging/messaging-room.form.vue
index aafed2632d..d378fc186b 100644
--- a/packages/client/src/pages/messaging/messaging-room.form.vue
+++ b/packages/client/src/pages/messaging/messaging-room.form.vue
@@ -95,20 +95,11 @@ export default defineComponent({
 					const lio = file.name.lastIndexOf('.');
 					const ext = lio >= 0 ? file.name.slice(lio) : '';
 					const formatted = `${formatTimeString(new Date(file.lastModified), this.$store.state.pastedFileName).replace(/{{number}}/g, '1')}${ext}`;
-					const name = this.$store.state.pasteDialog
-						? await os.dialog({
-							title: this.$ts.enterFileName,
-							input: {
-								default: formatted
-							},
-							allowEmpty: false
-						}).then(({ canceled, result }) => canceled ? false : result)
-						: formatted;
-					if (name) this.upload(file, name);
+					if (formatted) this.upload(file, formatted);
 				}
 			} else {
 				if (items[0].kind == 'file') {
-					os.dialog({
+					os.alert({
 						type: 'error',
 						text: this.$ts.onlyOneFileCanBeAttached
 					});
@@ -133,7 +124,7 @@ export default defineComponent({
 				return;
 			} else if (e.dataTransfer.files.length > 1) {
 				e.preventDefault();
-				os.dialog({
+				os.alert({
 					type: 'error',
 					text: this.$ts.onlyOneFileCanBeAttached
 				});
diff --git a/packages/client/src/pages/messaging/messaging-room.vue b/packages/client/src/pages/messaging/messaging-room.vue
index 3a19b12762..d71e415c8f 100644
--- a/packages/client/src/pages/messaging/messaging-room.vue
+++ b/packages/client/src/pages/messaging/messaging-room.vue
@@ -182,7 +182,7 @@ const Component = defineComponent({
 				this.form.upload(e.dataTransfer.files[0]);
 				return;
 			} else if (e.dataTransfer.files.length > 1) {
-				os.dialog({
+				os.alert({
 					type: 'error',
 					text: this.$ts.onlyOneFileCanBeAttached
 				});
diff --git a/packages/client/src/pages/my-antennas/editor.vue b/packages/client/src/pages/my-antennas/editor.vue
index 5ad3d50486..bf3ed25b42 100644
--- a/packages/client/src/pages/my-antennas/editor.vue
+++ b/packages/client/src/pages/my-antennas/editor.vue
@@ -150,10 +150,9 @@ export default defineComponent({
 		},
 
 		async deleteAntenna() {
-			const { canceled } = await os.dialog({
+			const { canceled } = await os.confirm({
 				type: 'warning',
 				text: this.$t('removeAreYouSure', { x: this.antenna.name }),
-				showCancelButton: true
 			});
 			if (canceled) return;
 
diff --git a/packages/client/src/pages/my-groups/group.vue b/packages/client/src/pages/my-groups/group.vue
index 9548c374d2..b79e1cb49c 100644
--- a/packages/client/src/pages/my-groups/group.vue
+++ b/packages/client/src/pages/my-groups/group.vue
@@ -106,11 +106,9 @@ export default defineComponent({
 		},
 
 		async renameGroup() {
-			const { canceled, result: name } = await os.dialog({
+			const { canceled, result: name } = await os.inputText({
 				title: this.$ts.groupName,
-				input: {
-					default: this.group.name
-				}
+				default: this.group.name
 			});
 			if (canceled) return;
 
@@ -132,10 +130,9 @@ export default defineComponent({
 		},
 
 		async deleteGroup() {
-			const { canceled } = await os.dialog({
+			const { canceled } = await os.confirm({
 				type: 'warning',
 				text: this.$t('removeAreYouSure', { x: this.group.name }),
-				showCancelButton: true
 			});
 			if (canceled) return;
 
diff --git a/packages/client/src/pages/my-groups/index.vue b/packages/client/src/pages/my-groups/index.vue
index 77e7d6088e..1c66eb14dd 100644
--- a/packages/client/src/pages/my-groups/index.vue
+++ b/packages/client/src/pages/my-groups/index.vue
@@ -88,9 +88,8 @@ export default defineComponent({
 
 	methods: {
 		async create() {
-			const { canceled, result: name } = await os.dialog({
+			const { canceled, result: name } = await os.inputText({
 				title: this.$ts.groupName,
-				input: true
 			});
 			if (canceled) return;
 			await os.api('users/groups/create', { name: name });
diff --git a/packages/client/src/pages/my-lists/index.vue b/packages/client/src/pages/my-lists/index.vue
index adb59db665..a1b0fee317 100644
--- a/packages/client/src/pages/my-lists/index.vue
+++ b/packages/client/src/pages/my-lists/index.vue
@@ -46,9 +46,8 @@ export default defineComponent({
 
 	methods: {
 		async create() {
-			const { canceled, result: name } = await os.dialog({
+			const { canceled, result: name } = await os.inputText({
 				title: this.$ts.enterListName,
-				input: true
 			});
 			if (canceled) return;
 			await os.api('users/lists/create', { name: name });
diff --git a/packages/client/src/pages/my-lists/list.vue b/packages/client/src/pages/my-lists/list.vue
index f2a02cadc9..fd986b4097 100644
--- a/packages/client/src/pages/my-lists/list.vue
+++ b/packages/client/src/pages/my-lists/list.vue
@@ -100,11 +100,9 @@ export default defineComponent({
 		},
 
 		async renameList() {
-			const { canceled, result: name } = await os.dialog({
+			const { canceled, result: name } = await os.inputText({
 				title: this.$ts.enterListName,
-				input: {
-					default: this.list.name
-				}
+				default: this.list.name
 			});
 			if (canceled) return;
 
@@ -117,10 +115,9 @@ export default defineComponent({
 		},
 
 		async deleteList() {
-			const { canceled } = await os.dialog({
+			const { canceled } = await os.confirm({
 				type: 'warning',
 				text: this.$t('removeAreYouSure', { x: this.list.name }),
-				showCancelButton: true
 			});
 			if (canceled) return;
 
diff --git a/packages/client/src/pages/page-editor/els/page-editor.el.if.vue b/packages/client/src/pages/page-editor/els/page-editor.el.if.vue
index f76d59abe3..9a49de846e 100644
--- a/packages/client/src/pages/page-editor/els/page-editor.el.if.vue
+++ b/packages/client/src/pages/page-editor/els/page-editor.el.if.vue
@@ -60,13 +60,9 @@ export default defineComponent({
 
 	methods: {
 		async add() {
-			const { canceled, result: type } = await os.dialog({
-				type: null,
+			const { canceled, result: type } = await os.select({
 				title: this.$ts._pages.chooseBlock,
-				select: {
-					groupedItems: this.getPageBlockList()
-				},
-				showCancelButton: true
+				groupedItems: this.getPageBlockList()
 			});
 			if (canceled) return;
 
diff --git a/packages/client/src/pages/page-editor/els/page-editor.el.section.vue b/packages/client/src/pages/page-editor/els/page-editor.el.section.vue
index 16e32d8400..6be31a39cb 100644
--- a/packages/client/src/pages/page-editor/els/page-editor.el.section.vue
+++ b/packages/client/src/pages/page-editor/els/page-editor.el.section.vue
@@ -57,26 +57,18 @@ export default defineComponent({
 
 	methods: {
 		async rename() {
-			const { canceled, result: title } = await os.dialog({
+			const { canceled, result: title } = await os.inputText({
 				title: 'Enter title',
-				input: {
-					type: 'text',
-					default: this.value.title
-				},
-				showCancelButton: true
+				default: this.value.title
 			});
 			if (canceled) return;
 			this.value.title = title;
 		},
 
 		async add() {
-			const { canceled, result: type } = await os.dialog({
-				type: null,
+			const { canceled, result: type } = await os.select({
 				title: this.$ts._pages.chooseBlock,
-				select: {
-					groupedItems: this.getPageBlockList()
-				},
-				showCancelButton: true
+				groupedItems: this.getPageBlockList()
 			});
 			if (canceled) return;
 
diff --git a/packages/client/src/pages/page-editor/page-editor.script-block.vue b/packages/client/src/pages/page-editor/page-editor.script-block.vue
index 07958c902b..610c33ad8b 100644
--- a/packages/client/src/pages/page-editor/page-editor.script-block.vue
+++ b/packages/client/src/pages/page-editor/page-editor.script-block.vue
@@ -212,13 +212,9 @@ export default defineComponent({
 
 	methods: {
 		async changeType() {
-			const { canceled, result: type } = await os.dialog({
-				type: null,
+			const { canceled, result: type } = await os.select({
 				title: this.$ts._pages.selectType,
-				select: {
-					groupedItems: this.getScriptBlockList(this.getExpectedType ? this.getExpectedType() : null)
-				},
-				showCancelButton: true
+				groupedItems: this.getScriptBlockList(this.getExpectedType ? this.getExpectedType() : null)
 			});
 			if (canceled) return;
 			this.modelValue.type = type;
diff --git a/packages/client/src/pages/page-editor/page-editor.vue b/packages/client/src/pages/page-editor/page-editor.vue
index 684b1f8c75..31b1dddef5 100644
--- a/packages/client/src/pages/page-editor/page-editor.vue
+++ b/packages/client/src/pages/page-editor/page-editor.vue
@@ -272,14 +272,14 @@ export default defineComponent({
 			const onError = err => {
 				if (err.id == '3d81ceae-475f-4600-b2a8-2bc116157532') {
 					if (err.info.param == 'name') {
-						os.dialog({
+						os.alert({
 							type: 'error',
 							title: this.$ts._pages.invalidNameTitle,
 							text: this.$ts._pages.invalidNameText
 						});
 					}
 				} else if (err.code == 'NAME_ALREADY_EXISTS') {
-					os.dialog({
+					os.alert({
 						type: 'error',
 						text: this.$ts._pages.nameAlreadyExists
 					});
@@ -291,7 +291,7 @@ export default defineComponent({
 				os.api('pages/update', options)
 				.then(page => {
 					this.currentName = this.name.trim();
-					os.dialog({
+					os.alert({
 						type: 'success',
 						text: this.$ts._pages.updated
 					});
@@ -301,7 +301,7 @@ export default defineComponent({
 				.then(page => {
 					this.pageId = page.id;
 					this.currentName = this.name.trim();
-					os.dialog({
+					os.alert({
 						type: 'success',
 						text: this.$ts._pages.created
 					});
@@ -311,16 +311,15 @@ export default defineComponent({
 		},
 
 		del() {
-			os.dialog({
+			os.confirm({
 				type: 'warning',
 				text: this.$t('removeAreYouSure', { x: this.title.trim() }),
-				showCancelButton: true
 			}).then(({ canceled }) => {
 				if (canceled) return;
 				os.api('pages/delete', {
 					pageId: this.pageId,
 				}).then(() => {
-					os.dialog({
+					os.alert({
 						type: 'success',
 						text: this.$ts._pages.deleted
 					});
@@ -335,7 +334,7 @@ export default defineComponent({
 			os.api('pages/create', this.getSaveOptions()).then(page => {
 				this.pageId = page.id;
 				this.currentName = this.name.trim();
-				os.dialog({
+				os.alert({
 					type: 'success',
 					text: this.$ts._pages.created
 				});
@@ -344,13 +343,10 @@ export default defineComponent({
 		},
 
 		async add() {
-			const { canceled, result: type } = await os.dialog({
+			const { canceled, result: type } = await os.select({
 				type: null,
 				title: this.$ts._pages.chooseBlock,
-				select: {
-					groupedItems: this.getPageBlockList()
-				},
-				showCancelButton: true
+				groupedItems: this.getPageBlockList()
 			});
 			if (canceled) return;
 
@@ -359,19 +355,15 @@ export default defineComponent({
 		},
 
 		async addVariable() {
-			let { canceled, result: name } = await os.dialog({
+			let { canceled, result: name } = await os.inputText({
 				title: this.$ts._pages.enterVariableName,
-				input: {
-					type: 'text',
-				},
-				showCancelButton: true
 			});
 			if (canceled) return;
 
 			name = name.trim();
 
 			if (this.hpml.isUsedName(name)) {
-				os.dialog({
+				os.alert({
 					type: 'error',
 					text: this.$ts._pages.variableNameIsAlreadyUsed
 				});
diff --git a/packages/client/src/pages/page.vue b/packages/client/src/pages/page.vue
index 1eff1a98cb..5cc56e443b 100644
--- a/packages/client/src/pages/page.vue
+++ b/packages/client/src/pages/page.vue
@@ -168,9 +168,8 @@ export default defineComponent({
 		},
 
 		async unlike() {
-			const confirm = await os.dialog({
+			const confirm = await os.confirm({
 				type: 'warning',
-				showCancelButton: true,
 				text: this.$ts.unlikeConfirm,
 			});
 			if (confirm.canceled) return;
diff --git a/packages/client/src/pages/room/room.vue b/packages/client/src/pages/room/room.vue
index 1671bcd587..926a681e88 100644
--- a/packages/client/src/pages/room/room.vue
+++ b/packages/client/src/pages/room/room.vue
@@ -137,10 +137,9 @@ export default defineComponent({
 
 	beforeRouteLeave(to, from, next) {
 		if (this.changed) {
-			os.dialog({
+			os.confirm({
 				type: 'warning',
 				text: this.$ts.leaveConfirm,
-				showCancelButton: true
 			}).then(({ canceled }) => {
 				if (canceled) {
 					next(false);
@@ -167,15 +166,11 @@ export default defineComponent({
 		},
 
 		async add() {
-			const { canceled, result: id } = await os.dialog({
-				type: null,
+			const { canceled, result: id } = await os.select({
 				title: this.$ts._rooms.addFurniture,
-				select: {
-					items: storeItems.map(item => ({
-						value: item.id, text: this.$t('_rooms._furnitures.' + item.id)
-					}))
-				},
-				showCancelButton: true
+				items: storeItems.map(item => ({
+					value: item.id, text: this.$t('_rooms._furnitures.' + item.id)
+				}))
 			});
 			if (canceled) return;
 			room.addFurniture(id);
@@ -196,7 +191,7 @@ export default defineComponent({
 				this.changed = false;
 				os.success();
 			}).catch((e: any) => {
-				os.dialog({
+				os.alert({
 					type: 'error',
 					text: e.message
 				});
@@ -204,10 +199,9 @@ export default defineComponent({
 		},
 
 		clear() {
-			os.dialog({
+			os.confirm({
 				type: 'warning',
 				text: this.$ts._rooms.clearConfirm,
-				showCancelButton: true
 			}).then(({ canceled }) => {
 				if (canceled) return;
 				room.removeAllFurnitures();
diff --git a/packages/client/src/pages/scratchpad.vue b/packages/client/src/pages/scratchpad.vue
index c26658cbc4..65f6fa07d5 100644
--- a/packages/client/src/pages/scratchpad.vue
+++ b/packages/client/src/pages/scratchpad.vue
@@ -74,9 +74,8 @@ export default defineComponent({
 			}), {
 				in: (q) => {
 					return new Promise(ok => {
-						os.dialog({
+						os.inputText({
 							title: q,
-							input: {}
 						}).then(({ canceled, result: a }) => {
 							ok(a);
 						});
@@ -105,7 +104,7 @@ export default defineComponent({
 			try {
 				ast = parse(this.code);
 			} catch (e) {
-				os.dialog({
+				os.alert({
 					type: 'error',
 					text: 'Syntax error :('
 				});
@@ -114,7 +113,7 @@ export default defineComponent({
 			try {
 				await aiscript.exec(ast);
 			} catch (e) {
-				os.dialog({
+				os.alert({
 					type: 'error',
 					text: e
 				});
diff --git a/packages/client/src/pages/settings/2fa.vue b/packages/client/src/pages/settings/2fa.vue
index dce217559a..67c8b626ee 100644
--- a/packages/client/src/pages/settings/2fa.vue
+++ b/packages/client/src/pages/settings/2fa.vue
@@ -105,11 +105,9 @@ export default defineComponent({
 
 	methods: {
 		register() {
-			os.dialog({
+			os.inputText({
 				title: this.$ts.password,
-				input: {
-					type: 'password'
-				}
+				type: 'password'
 			}).then(({ canceled, result: password }) => {
 				if (canceled) return;
 				os.api('i/2fa/register', {
@@ -121,11 +119,9 @@ export default defineComponent({
 		},
 
 		unregister() {
-			os.dialog({
+			os.inputText({
 				title: this.$ts.password,
-				input: {
-					type: 'password'
-				}
+				type: 'password'
 			}).then(({ canceled, result: password }) => {
 				if (canceled) return;
 				os.api('i/2fa/unregister', {
@@ -147,7 +143,7 @@ export default defineComponent({
 				os.success();
 				this.$i.twoFactorEnabled = true;
 			}).catch(e => {
-				os.dialog({
+				os.alert({
 					type: 'error',
 					text: e
 				});
@@ -171,11 +167,9 @@ export default defineComponent({
 		},
 
 		unregisterKey(key) {
-			os.dialog({
+			os.inputText({
 				title: this.$ts.password,
-				input: {
-					type: 'password'
-				}
+				type: 'password'
 			}).then(({ canceled, result: password }) => {
 				if (canceled) return;
 				return os.api('i/2fa/remove-key', {
@@ -191,11 +185,9 @@ export default defineComponent({
 		},
 
 		addSecurityKey() {
-			os.dialog({
+			os.inputText({
 				title: this.$ts.password,
-				input: {
-					type: 'password'
-				}
+				type: 'password'
 			}).then(({ canceled, result: password }) => {
 				if (canceled) return;
 				os.api('i/2fa/register-key', {
diff --git a/packages/client/src/pages/settings/api.vue b/packages/client/src/pages/settings/api.vue
index 1def0189ec..b6bff51c7f 100644
--- a/packages/client/src/pages/settings/api.vue
+++ b/packages/client/src/pages/settings/api.vue
@@ -52,7 +52,7 @@ export default defineComponent({
 						permission: permissions,
 					});
 
-					os.dialog({
+					os.alert({
 						type: 'success',
 						title: this.$ts.token,
 						text: token
diff --git a/packages/client/src/pages/settings/custom-css.vue b/packages/client/src/pages/settings/custom-css.vue
index 8c878fb084..155956923c 100644
--- a/packages/client/src/pages/settings/custom-css.vue
+++ b/packages/client/src/pages/settings/custom-css.vue
@@ -59,10 +59,9 @@ export default defineComponent({
 		async apply() {
 			localStorage.setItem('customCss', this.localCustomCss);
 
-			const { canceled } = await os.dialog({
+			const { canceled } = await os.confirm({
 				type: 'info',
 				text: this.$ts.reloadToApplySetting,
-				showCancelButton: true
 			});
 			if (canceled) return;
 
diff --git a/packages/client/src/pages/settings/deck.vue b/packages/client/src/pages/settings/deck.vue
index a96c6cd685..bc82b0ca84 100644
--- a/packages/client/src/pages/settings/deck.vue
+++ b/packages/client/src/pages/settings/deck.vue
@@ -75,10 +75,9 @@ export default defineComponent({
 
 	watch: {
 		async navWindow() {
-			const { canceled } = await os.dialog({
+			const { canceled } = await os.confirm({
 				type: 'info',
 				text: this.$ts.reloadToApplySetting,
-				showCancelButton: true
 			});
 			if (canceled) return;
 
@@ -92,11 +91,9 @@ export default defineComponent({
 
 	methods: {
 		async setProfile() {
-			const { canceled, result: name } = await os.dialog({
+			const { canceled, result: name } = await os.inputText({
 				title: this.$ts._deck.profile,
-				input: {
-					allowEmpty: false
-				}
+				allowEmpty: false
 			});
 			if (canceled) return;
 			this.profile = name;
diff --git a/packages/client/src/pages/settings/delete-account.vue b/packages/client/src/pages/settings/delete-account.vue
index 77dc0fe2a8..d5ad648939 100644
--- a/packages/client/src/pages/settings/delete-account.vue
+++ b/packages/client/src/pages/settings/delete-account.vue
@@ -46,19 +46,16 @@ export default defineComponent({
 	methods: {
 		async deleteAccount() {
 			{
-				const { canceled } = await os.dialog({
+				const { canceled } = await os.confirm({
 					type: 'warning',
 					text: this.$ts.deleteAccountConfirm,
-					showCancelButton: true
 				});
 				if (canceled) return;
 			}
 
-			const { canceled, result: password } = await os.dialog({
+			const { canceled, result: password } = await os.inputText({
 				title: this.$ts.password,
-				input: {
-					type: 'password'
-				}
+				type: 'password'
 			});
 			if (canceled) return;
 
@@ -66,7 +63,7 @@ export default defineComponent({
 				password: password
 			});
 
-			await os.dialog({
+			await os.alert({
 				title: this.$ts._accountDelete.started,
 			});
 
diff --git a/packages/client/src/pages/settings/email-address.vue b/packages/client/src/pages/settings/email-address.vue
index 476d0c0e17..c2c56ed0a8 100644
--- a/packages/client/src/pages/settings/email-address.vue
+++ b/packages/client/src/pages/settings/email-address.vue
@@ -52,11 +52,9 @@ export default defineComponent({
 
 	methods: {
 		save() {
-			os.dialog({
+			os.inputText({
 				title: this.$ts.password,
-				input: {
-					type: 'password'
-				}
+				type: 'password'
 			}).then(({ canceled, result: password }) => {
 				if (canceled) return;
 				os.apiWithDialog('i/update-email', {
diff --git a/packages/client/src/pages/settings/general.vue b/packages/client/src/pages/settings/general.vue
index 8e3dcc3e41..e0fcf70102 100644
--- a/packages/client/src/pages/settings/general.vue
+++ b/packages/client/src/pages/settings/general.vue
@@ -209,10 +209,9 @@ export default defineComponent({
 
 	methods: {
 		async reloadAsk() {
-			const { canceled } = await os.dialog({
+			const { canceled } = await os.confirm({
 				type: 'info',
 				text: this.$ts.reloadToApplySetting,
-				showCancelButton: true
 			});
 			if (canceled) return;
 
diff --git a/packages/client/src/pages/settings/import-export.vue b/packages/client/src/pages/settings/import-export.vue
index 8923483b98..4cc92adfb3 100644
--- a/packages/client/src/pages/settings/import-export.vue
+++ b/packages/client/src/pages/settings/import-export.vue
@@ -67,12 +67,12 @@ export default defineComponent({
 				target === 'muting' ? 'i/export-mute' :
 				null, {})
 			.then(() => {
-				os.dialog({
+				os.alert({
 					type: 'info',
 					text: this.$ts.exportRequested
 				});
 			}).catch((e: any) => {
-				os.dialog({
+				os.alert({
 					type: 'error',
 					text: e.message
 				});
@@ -90,12 +90,12 @@ export default defineComponent({
 				null, {
 					fileId: file.id
 			}).then(() => {
-				os.dialog({
+				os.alert({
 					type: 'info',
 					text: this.$ts.importRequested
 				});
 			}).catch((e: any) => {
-				os.dialog({
+				os.alert({
 					type: 'error',
 					text: e.message
 				});
diff --git a/packages/client/src/pages/settings/menu.vue b/packages/client/src/pages/settings/menu.vue
index e40740a3a4..6027910e03 100644
--- a/packages/client/src/pages/settings/menu.vue
+++ b/packages/client/src/pages/settings/menu.vue
@@ -76,17 +76,13 @@ export default defineComponent({
 	methods: {
 		async addItem() {
 			const menu = Object.keys(this.menuDef).filter(k => !this.$store.state.menu.includes(k));
-			const { canceled, result: item } = await os.dialog({
-				type: null,
+			const { canceled, result: item } = await os.select({
 				title: this.$ts.addItem,
-				select: {
-					items: [...menu.map(k => ({
-						value: k, text: this.$ts[this.menuDef[k].title]
-					})), ...[{
-						value: '-', text: this.$ts.divider
-					}]]
-				},
-				showCancelButton: true
+				items: [...menu.map(k => ({
+					value: k, text: this.$ts[this.menuDef[k].title]
+				})), ...[{
+					value: '-', text: this.$ts.divider
+				}]]
 			});
 			if (canceled) return;
 			this.items = [...this.splited, item].join('\n');
@@ -103,7 +99,7 @@ export default defineComponent({
 		},
 
 		async reloadAsk() {
-			const { canceled } = await os.dialog({
+			const { canceled } = await os.confirm({
 				type: 'info',
 				text: this.$ts.reloadToApplySetting,
 				showCancelButton: true
diff --git a/packages/client/src/pages/settings/plugin.install.vue b/packages/client/src/pages/settings/plugin.install.vue
index 9958f98f58..d79979bc2d 100644
--- a/packages/client/src/pages/settings/plugin.install.vue
+++ b/packages/client/src/pages/settings/plugin.install.vue
@@ -76,7 +76,7 @@ export default defineComponent({
 			try {
 				ast = parse(this.code);
 			} catch (e) {
-				os.dialog({
+				os.alert({
 					type: 'error',
 					text: 'Syntax error :('
 				});
@@ -84,7 +84,7 @@ export default defineComponent({
 			}
 			const meta = AiScript.collectMetadata(ast);
 			if (meta == null) {
-				os.dialog({
+				os.alert({
 					type: 'error',
 					text: 'No metadata found :('
 				});
@@ -92,7 +92,7 @@ export default defineComponent({
 			}
 			const data = meta.get(null);
 			if (data == null) {
-				os.dialog({
+				os.alert({
 					type: 'error',
 					text: 'No metadata found :('
 				});
@@ -100,7 +100,7 @@ export default defineComponent({
 			}
 			const { name, version, author, description, permissions, config } = data;
 			if (name == null || version == null || author == null) {
-				os.dialog({
+				os.alert({
 					type: 'error',
 					text: 'Required property not found :('
 				});
diff --git a/packages/client/src/pages/settings/profile.vue b/packages/client/src/pages/settings/profile.vue
index a7ddc6d178..e7d0d9b418 100644
--- a/packages/client/src/pages/settings/profile.vue
+++ b/packages/client/src/pages/settings/profile.vue
@@ -221,7 +221,7 @@ export default defineComponent({
 			}).then(i => {
 				os.success();
 			}).catch(err => {
-				os.dialog({
+				os.alert({
 					type: 'error',
 					text: err.id
 				});
diff --git a/packages/client/src/pages/settings/reaction.vue b/packages/client/src/pages/settings/reaction.vue
index 905a3e4957..8878b4149f 100644
--- a/packages/client/src/pages/settings/reaction.vue
+++ b/packages/client/src/pages/settings/reaction.vue
@@ -111,10 +111,9 @@ export default defineComponent({
 		},
 
 		async setDefault() {
-			const { canceled } = await os.dialog({
+			const { canceled } = await os.confirm({
 				type: 'warning',
 				text: this.$ts.resetAreYouSure,
-				showCancelButton: true
 			});
 			if (canceled) return;
 
diff --git a/packages/client/src/pages/settings/registry.value.vue b/packages/client/src/pages/settings/registry.value.vue
index 36f989dbc5..6604cf056b 100644
--- a/packages/client/src/pages/settings/registry.value.vue
+++ b/packages/client/src/pages/settings/registry.value.vue
@@ -110,17 +110,16 @@ export default defineComponent({
 			try {
 				JSON5.parse(this.valueForEditor);
 			} catch (e) {
-				os.dialog({
+				os.alert({
 					type: 'error',
 					text: this.$ts.invalidValue
 				});
 				return;
 			}
 
-			os.dialog({
+			os.confirm({
 				type: 'warning',
 				text: this.$ts.saveConfirm,
-				showCancelButton: true
 			}).then(({ canceled }) => {
 				if (canceled) return;
 				os.apiWithDialog('i/registry/set', {
@@ -132,10 +131,9 @@ export default defineComponent({
 		},
 
 		del() {
-			os.dialog({
+			os.confirm({
 				type: 'warning',
 				text: this.$ts.deleteConfirm,
-				showCancelButton: true
 			}).then(({ canceled }) => {
 				if (canceled) return;
 				os.apiWithDialog('i/registry/remove', {
diff --git a/packages/client/src/pages/settings/security.vue b/packages/client/src/pages/settings/security.vue
index 4d81bf1b9e..879fd83f70 100644
--- a/packages/client/src/pages/settings/security.vue
+++ b/packages/client/src/pages/settings/security.vue
@@ -64,32 +64,26 @@ export default defineComponent({
 
 	methods: {
 		async change() {
-			const { canceled: canceled1, result: currentPassword } = await os.dialog({
+			const { canceled: canceled1, result: currentPassword } = await os.inputText({
 				title: this.$ts.currentPassword,
-				input: {
-					type: 'password'
-				}
+				type: 'password'
 			});
 			if (canceled1) return;
 
-			const { canceled: canceled2, result: newPassword } = await os.dialog({
+			const { canceled: canceled2, result: newPassword } = await os.inputText({
 				title: this.$ts.newPassword,
-				input: {
-					type: 'password'
-				}
+				type: 'password'
 			});
 			if (canceled2) return;
 
-			const { canceled: canceled3, result: newPassword2 } = await os.dialog({
+			const { canceled: canceled3, result: newPassword2 } = await os.inputText({
 				title: this.$ts.newPasswordRetype,
-				input: {
-					type: 'password'
-				}
+				type: 'password'
 			});
 			if (canceled3) return;
 
 			if (newPassword !== newPassword2) {
-				os.dialog({
+				os.alert({
 					type: 'error',
 					text: this.$ts.retypedNotMatch
 				});
@@ -103,11 +97,9 @@ export default defineComponent({
 		},
 
 		regenerateToken() {
-			os.dialog({
+			os.inputText({
 				title: this.$ts.password,
-				input: {
-					type: 'password'
-				}
+				type: 'password'
 			}).then(({ canceled, result: password }) => {
 				if (canceled) return;
 				os.api('i/regenerate_token', {
diff --git a/packages/client/src/pages/settings/theme.install.vue b/packages/client/src/pages/settings/theme.install.vue
index 59ad3ad9b7..95c6f4c7ee 100644
--- a/packages/client/src/pages/settings/theme.install.vue
+++ b/packages/client/src/pages/settings/theme.install.vue
@@ -62,21 +62,21 @@ export default defineComponent({
 			try {
 				theme = JSON5.parse(code);
 			} catch (e) {
-				os.dialog({
+				os.alert({
 					type: 'error',
 					text: this.$ts._theme.invalid
 				});
 				return false;
 			}
 			if (!validateTheme(theme)) {
-				os.dialog({
+				os.alert({
 					type: 'error',
 					text: this.$ts._theme.invalid
 				});
 				return false;
 			}
 			if (getThemes().some(t => t.id === theme.id)) {
-				os.dialog({
+				os.alert({
 					type: 'info',
 					text: this.$ts._theme.alreadyInstalled
 				});
@@ -95,7 +95,7 @@ export default defineComponent({
 			const theme = this.parseThemeCode(code);
 			if (!theme) return;
 			await addTheme(theme);
-			os.dialog({
+			os.alert({
 				type: 'success',
 				text: this.$t('_theme.installed', { name: theme.name })
 			});
diff --git a/packages/client/src/pages/share.vue b/packages/client/src/pages/share.vue
index c0af44fdd1..488c432f22 100644
--- a/packages/client/src/pages/share.vue
+++ b/packages/client/src/pages/share.vue
@@ -154,7 +154,7 @@ export default defineComponent({
 			}
 			//#endregion
 		} catch (e) {
-			os.dialog({
+			os.alert({
 				type: 'error',
 				title: e.message,
 				text: e.name
diff --git a/packages/client/src/pages/test.vue b/packages/client/src/pages/test.vue
index 9dd9ae5e0c..d05e00d374 100644
--- a/packages/client/src/pages/test.vue
+++ b/packages/client/src/pages/test.vue
@@ -202,6 +202,7 @@ export default defineComponent({
 	methods: {
 		async showDialog() {
 			this.dialogResult = null;
+			/*
 			this.dialogResult = await os.dialog({
 				type: this.dialogType,
 				title: this.dialogTitle,
@@ -209,7 +210,7 @@ export default defineComponent({
 				showCancelButton: this.dialogCancel,
 				cancelableByBgClick: this.dialogCancelByBgClick,
 				input: this.dialogInput ? {} : null
-			});
+			});*/
 		},
 
 		async form() {
diff --git a/packages/client/src/pages/theme-editor.vue b/packages/client/src/pages/theme-editor.vue
index d1a892629b..c0bb1bd531 100644
--- a/packages/client/src/pages/theme-editor.vue
+++ b/packages/client/src/pages/theme-editor.vue
@@ -155,10 +155,9 @@ export default defineComponent({
 		},
 
 		async leaveConfirm(): Promise<boolean> {
-			const { canceled } = await os.dialog({
+			const { canceled } = await os.confirm({
 				type: 'warning',
 				text: this.$ts.leaveConfirm,
-				showCancelButton: true
 			});
 			return !canceled;
 		},
@@ -205,7 +204,7 @@ export default defineComponent({
 			try {
 				parsed = JSON5.parse(this.themeCode);
 			} catch (e) {
-				os.dialog({
+				os.alert({
 					type: 'error',
 					text: this.$ts._theme.invalid
 				});
@@ -216,11 +215,9 @@ export default defineComponent({
 		},
 
 		async saveAs() {
-			const { canceled, result: name } = await os.dialog({
+			const { canceled, result: name } = await os.inputText({
 				title: this.$ts.name,
-				input: {
-					allowEmpty: false
-				}
+				allowEmpty: false
 			});
 			if (canceled) return;
 
@@ -236,7 +233,7 @@ export default defineComponent({
 				ColdDeviceStorage.set('lightTheme', this.theme);
 			}
 			this.changed = false;
-			os.dialog({
+			os.alert({
 				type: 'success',
 				text: this.$t('_theme.installed', { name: this.theme.name })
 			});
diff --git a/packages/client/src/pages/timeline.vue b/packages/client/src/pages/timeline.vue
index 911d6f5c6a..71e8238269 100644
--- a/packages/client/src/pages/timeline.vue
+++ b/packages/client/src/pages/timeline.vue
@@ -171,15 +171,12 @@ export default defineComponent({
 		},
 
 		async timetravel() {
-			const { canceled, result: date } = await os.dialog({
+			const { canceled, result: date } = await os.inputDate({
 				title: this.$ts.date,
-				input: {
-					type: 'date'
-				}
 			});
 			if (canceled) return;
 
-			this.$refs.tl.timetravel(new Date(date));
+			this.$refs.tl.timetravel(date);
 		},
 
 		focus() {
diff --git a/packages/client/src/pages/user-info.vue b/packages/client/src/pages/user-info.vue
index b77d879a7e..28cef97db4 100644
--- a/packages/client/src/pages/user-info.vue
+++ b/packages/client/src/pages/user-info.vue
@@ -171,16 +171,15 @@ export default defineComponent({
 				userId: this.user.id,
 			});
 
-			os.dialog({
+			os.alert({
 				type: 'success',
 				text: this.$t('newPasswordIs', { password })
 			});
 		},
 
 		async toggleSilence(v) {
-			const confirm = await os.dialog({
+			const confirm = await os.confirm({
 				type: 'warning',
-				showCancelButton: true,
 				text: v ? this.$ts.silenceConfirm : this.$ts.unsilenceConfirm,
 			});
 			if (confirm.canceled) {
@@ -192,9 +191,8 @@ export default defineComponent({
 		},
 
 		async toggleSuspend(v) {
-			const confirm = await os.dialog({
+			const confirm = await os.confirm({
 				type: 'warning',
-				showCancelButton: true,
 				text: v ? this.$ts.suspendConfirm : this.$ts.unsuspendConfirm,
 			});
 			if (confirm.canceled) {
@@ -211,9 +209,8 @@ export default defineComponent({
 		},
 
 		async deleteAllFiles() {
-			const confirm = await os.dialog({
+			const confirm = await os.confirm({
 				type: 'warning',
-				showCancelButton: true,
 				text: this.$ts.deleteAllFilesConfirm,
 			});
 			if (confirm.canceled) return;
@@ -222,7 +219,7 @@ export default defineComponent({
 				os.success();
 			};
 			await process().catch(e => {
-				os.dialog({
+				os.alert({
 					type: 'error',
 					text: e.toString()
 				});
diff --git a/packages/client/src/pages/user-list-timeline.vue b/packages/client/src/pages/user-list-timeline.vue
index 2fc2476fba..a2773e2d49 100644
--- a/packages/client/src/pages/user-list-timeline.vue
+++ b/packages/client/src/pages/user-list-timeline.vue
@@ -97,15 +97,12 @@ export default defineComponent({
 		},
 
 		async timetravel() {
-			const { canceled, result: date } = await os.dialog({
+			const { canceled, result: date } = await os.inputDate({
 				title: this.$ts.date,
-				input: {
-					type: 'date'
-				}
 			});
 			if (canceled) return;
 
-			this.$refs.tl.timetravel(new Date(date));
+			this.$refs.tl.timetravel(date);
 		},
 
 		focus() {
diff --git a/packages/client/src/pages/welcome.setup.vue b/packages/client/src/pages/welcome.setup.vue
index 8c88720cf3..3dca5b3e78 100644
--- a/packages/client/src/pages/welcome.setup.vue
+++ b/packages/client/src/pages/welcome.setup.vue
@@ -57,7 +57,7 @@ export default defineComponent({
 			}).catch(() => {
 				this.submitting = false;
 
-				os.dialog({
+				os.alert({
 					type: 'error',
 					text: this.$ts.somethingHappened
 				});
diff --git a/packages/client/src/scripts/aiscript/api.ts b/packages/client/src/scripts/aiscript/api.ts
index 20c15d809e..01b8fd05fe 100644
--- a/packages/client/src/scripts/aiscript/api.ts
+++ b/packages/client/src/scripts/aiscript/api.ts
@@ -9,16 +9,15 @@ export function createAiScriptEnv(opts) {
 		USER_NAME: $i ? values.STR($i.name) : values.NULL,
 		USER_USERNAME: $i ? values.STR($i.username) : values.NULL,
 		'Mk:dialog': values.FN_NATIVE(async ([title, text, type]) => {
-			await os.dialog({
+			await os.alert({
 				type: type ? type.value : 'info',
 				title: title.value,
 				text: text.value,
 			});
 		}),
 		'Mk:confirm': values.FN_NATIVE(async ([title, text, type]) => {
-			const confirm = await os.dialog({
+			const confirm = await os.confirm({
 				type: type ? type.value : 'question',
-				showCancelButton: true,
 				title: title.value,
 				text: text.value,
 			});
diff --git a/packages/client/src/scripts/get-user-menu.ts b/packages/client/src/scripts/get-user-menu.ts
index 8d767afa25..0c04547101 100644
--- a/packages/client/src/scripts/get-user-menu.ts
+++ b/packages/client/src/scripts/get-user-menu.ts
@@ -14,21 +14,17 @@ export function getUserMenu(user) {
 		const t = i18n.locale.selectList; // なぜか後で参照すると null になるので最初にメモリに確保しておく
 		const lists = await os.api('users/lists/list');
 		if (lists.length === 0) {
-			os.dialog({
+			os.alert({
 				type: 'error',
 				text: i18n.locale.youHaveNoLists
 			});
 			return;
 		}
-		const { canceled, result: listId } = await os.dialog({
-			type: null,
+		const { canceled, result: listId } = await os.select({
 			title: t,
-			select: {
-				items: lists.map(list => ({
-					value: list.id, text: list.name
-				}))
-			},
-			showCancelButton: true
+			items: lists.map(list => ({
+				value: list.id, text: list.name
+			}))
 		});
 		if (canceled) return;
 		os.apiWithDialog('users/lists/push', {
@@ -40,21 +36,17 @@ export function getUserMenu(user) {
 	async function inviteGroup() {
 		const groups = await os.api('users/groups/owned');
 		if (groups.length === 0) {
-			os.dialog({
+			os.alert({
 				type: 'error',
 				text: i18n.locale.youHaveNoGroups
 			});
 			return;
 		}
-		const { canceled, result: groupId } = await os.dialog({
-			type: null,
+		const { canceled, result: groupId } = await os.select({
 			title: i18n.locale.group,
-			select: {
-				items: groups.map(group => ({
-					value: group.id, text: group.name
-				}))
-			},
-			showCancelButton: true
+			items: groups.map(group => ({
+				value: group.id, text: group.name
+			}))
 		});
 		if (canceled) return;
 		os.apiWithDialog('users/groups/invite', {
@@ -108,9 +100,8 @@ export function getUserMenu(user) {
 	}
 
 	async function getConfirmed(text: string): Promise<boolean> {
-		const confirm = await os.dialog({
+		const confirm = await os.confirm({
 			type: 'warning',
-			showCancelButton: true,
 			title: 'confirm',
 			text,
 		});
diff --git a/packages/client/src/scripts/hpml/evaluator.ts b/packages/client/src/scripts/hpml/evaluator.ts
index 20261d333d..6329c0860e 100644
--- a/packages/client/src/scripts/hpml/evaluator.ts
+++ b/packages/client/src/scripts/hpml/evaluator.ts
@@ -39,9 +39,8 @@ export class Hpml {
 			}), ...initAiLib(this)}, {
 				in: (q) => {
 					return new Promise(ok => {
-						os.dialog({
+						os.inputText({
 							title: q,
-							input: {}
 						}).then(({ canceled, result: a }) => {
 							ok(a);
 						});
diff --git a/packages/client/src/scripts/lookup-user.ts b/packages/client/src/scripts/lookup-user.ts
index 174fa9f879..64874f86f6 100644
--- a/packages/client/src/scripts/lookup-user.ts
+++ b/packages/client/src/scripts/lookup-user.ts
@@ -3,9 +3,8 @@ import { i18n } from '@/i18n';
 import * as os from '@/os';
 
 export async function lookupUser() {
-	const { canceled, result } = await os.dialog({
+	const { canceled, result } = await os.inputText({
 		title: i18n.locale.usernameOrUserId,
-		input: true
 	});
 	if (canceled) return;
 
@@ -18,7 +17,7 @@ export async function lookupUser() {
 	let _notFound = false;
 	const notFound = () => {
 		if (_notFound) {
-			os.dialog({
+			os.alert({
 				type: 'error',
 				text: i18n.locale.noSuchUser
 			});
diff --git a/packages/client/src/scripts/search.ts b/packages/client/src/scripts/search.ts
index b28cccfab7..a070b1121c 100644
--- a/packages/client/src/scripts/search.ts
+++ b/packages/client/src/scripts/search.ts
@@ -3,9 +3,8 @@ import { i18n } from '@/i18n';
 import { router } from '@/router';
 
 export async function search() {
-	const { canceled, result: query } = await os.dialog({
+	const { canceled, result: query } = await os.inputText({
 		title: i18n.locale.search,
-		input: true
 	});
 	if (canceled || query == null || query === '') return;
 
@@ -35,7 +34,7 @@ export async function search() {
 
 		// TODO
 		//v.$root.$emit('warp', date);
-		os.dialog({
+		os.alert({
 			icon: 'fas fa-history',
 			iconOnly: true, autoClose: true
 		});
diff --git a/packages/client/src/scripts/select-file.ts b/packages/client/src/scripts/select-file.ts
index 5fbc545b26..0c6bd7ccde 100644
--- a/packages/client/src/scripts/select-file.ts
+++ b/packages/client/src/scripts/select-file.ts
@@ -14,7 +14,7 @@ export function selectFile(src: any, label: string | null, multiple = false) {
 				Promise.all(promises).then(driveFiles => {
 					res(multiple ? driveFiles : driveFiles[0]);
 				}).catch(e => {
-					os.dialog({
+					os.alert({
 						type: 'error',
 						text: e
 					});
@@ -38,11 +38,10 @@ export function selectFile(src: any, label: string | null, multiple = false) {
 		};
 
 		const chooseFileFromUrl = () => {
-			os.dialog({
+			os.inputText({
 				title: i18n.locale.uploadFromUrl,
-				input: {
-					placeholder: i18n.locale.uploadFromUrlDescription
-				}
+				type: 'url',
+				placeholder: i18n.locale.uploadFromUrlDescription
 			}).then(({ canceled, result: url }) => {
 				if (canceled) return;
 
@@ -62,7 +61,7 @@ export function selectFile(src: any, label: string | null, multiple = false) {
 					marker
 				});
 
-				os.dialog({
+				os.alert({
 					title: i18n.locale.uploadFromUrlRequested,
 					text: i18n.locale.uploadFromUrlMayTakeTime
 				});
diff --git a/packages/client/src/scripts/show-suspended-dialog.ts b/packages/client/src/scripts/show-suspended-dialog.ts
index 3bc4800030..dcbb66933c 100644
--- a/packages/client/src/scripts/show-suspended-dialog.ts
+++ b/packages/client/src/scripts/show-suspended-dialog.ts
@@ -2,7 +2,7 @@ import * as os from '@/os';
 import { i18n } from '@/i18n';
 
 export function showSuspendedDialog() {
-	return os.dialog({
+	return os.alert({
 		type: 'error',
 		title: i18n.locale.yourAccountSuspendedTitle,
 		text: i18n.locale.yourAccountSuspendedDescription
diff --git a/packages/client/src/ui/chat/note.vue b/packages/client/src/ui/chat/note.vue
index c0b5cebd94..412f47e317 100644
--- a/packages/client/src/ui/chat/note.vue
+++ b/packages/client/src/ui/chat/note.vue
@@ -459,18 +459,18 @@ export default defineComponent({
 			os.apiWithDialog('notes/create', {
 				renoteId: this.appearNote.id
 			}, undefined, (res: any) => {
-				os.dialog({
+				os.alert({
 					type: 'success',
 					text: this.$ts.renoted,
 				});
 			}, (e: Error) => {
 				if (e.id === 'b5c90186-4ab0-49c8-9bba-a1f76c282ba4') {
-					os.dialog({
+					os.alert({
 						type: 'error',
 						text: this.$ts.cantRenote,
 					});
 				} else if (e.id === 'fd4cc33e-2a37-48dd-99cc-9b806eb2031a') {
-					os.dialog({
+					os.alert({
 						type: 'error',
 						text: this.$ts.cantReRenote,
 					});
@@ -513,18 +513,18 @@ export default defineComponent({
 			os.apiWithDialog('notes/favorites/create', {
 				noteId: this.appearNote.id
 			}, undefined, (res: any) => {
-				os.dialog({
+				os.alert({
 					type: 'success',
 					text: this.$ts.favorited,
 				});
 			}, (e: Error) => {
 				if (e.id === 'a402c12b-34dd-41d2-97d8-4d2ffd96a1a6') {
-					os.dialog({
+					os.alert({
 						type: 'error',
 						text: this.$ts.alreadyFavorited,
 					});
 				} else if (e.id === '6dd26674-e060-4816-909a-45ba3f4da458') {
-					os.dialog({
+					os.alert({
 						type: 'error',
 						text: this.$ts.cantFavorite,
 					});
@@ -533,10 +533,9 @@ export default defineComponent({
 		},
 
 		del() {
-			os.dialog({
+			os.confirm({
 				type: 'warning',
 				text: this.$ts.noteDeleteConfirm,
-				showCancelButton: true
 			}).then(({ canceled }) => {
 				if (canceled) return;
 
@@ -547,10 +546,9 @@ export default defineComponent({
 		},
 
 		delEdit() {
-			os.dialog({
+			os.confirm({
 				type: 'warning',
 				text: this.$ts.deleteAndEditConfirm,
-				showCancelButton: true
 			}).then(({ canceled }) => {
 				if (canceled) return;
 
@@ -770,7 +768,7 @@ export default defineComponent({
 				noteId: this.appearNote.id
 			}, undefined, null, e => {
 				if (e.id === '72dab508-c64d-498f-8740-a8eec1ba385a') {
-					os.dialog({
+					os.alert({
 						type: 'error',
 						text: this.$ts.pinLimitExceeded
 					});
@@ -817,9 +815,8 @@ export default defineComponent({
 		},
 
 		async promote() {
-			const { canceled, result: days } = await os.dialog({
+			const { canceled, result: days } = await os.inputNumber({
 				title: this.$ts.numberOfDays,
-				input: { type: 'number' }
 			});
 
 			if (canceled) return;
diff --git a/packages/client/src/ui/chat/pages/channel.vue b/packages/client/src/ui/chat/pages/channel.vue
index 5152af20f9..f2488347d1 100644
--- a/packages/client/src/ui/chat/pages/channel.vue
+++ b/packages/client/src/ui/chat/pages/channel.vue
@@ -155,9 +155,8 @@ export default defineComponent({
 		},
 
 		async inChannelSearch() {
-			const { canceled, result: query } = await os.dialog({
+			const { canceled, result: query } = await os.inputText({
 				title: this.$ts.inChannelSearch,
-				input: true
 			});
 			if (canceled || query == null || query === '') return;
 			router.push(`/search?q=${encodeURIComponent(query)}&channel=${this.channelId}`);
diff --git a/packages/client/src/ui/chat/post-form.vue b/packages/client/src/ui/chat/post-form.vue
index 62aa3a6aa7..1f272c3603 100644
--- a/packages/client/src/ui/chat/post-form.vue
+++ b/packages/client/src/ui/chat/post-form.vue
@@ -450,10 +450,9 @@ export default defineComponent({
 			if (!this.renote && !this.quoteId && paste.startsWith(url + '/notes/')) {
 				e.preventDefault();
 
-				os.dialog({
+				os.confirm({
 					type: 'info',
 					text: this.$ts.quoteQuestion,
-					showCancelButton: true
 				}).then(({ canceled }) => {
 					if (canceled) {
 						insertTextAtCursor(this.$refs.text, paste);
@@ -567,7 +566,7 @@ export default defineComponent({
 				});
 			}).catch(err => {
 				this.posting = false;
-				os.dialog({
+				os.alert({
 					type: 'error',
 					text: err.message + '\n' + (err as any).id,
 				});
diff --git a/packages/client/src/ui/deck.vue b/packages/client/src/ui/deck.vue
index cc8bf5a511..596d14c5cd 100644
--- a/packages/client/src/ui/deck.vue
+++ b/packages/client/src/ui/deck.vue
@@ -118,15 +118,11 @@ export default defineComponent({
 				'direct',
 			];
 
-			const { canceled, result: column } = await os.dialog({
+			const { canceled, result: column } = await os.select({
 				title: this.$ts._deck.addColumn,
-				type: null,
-				select: {
-					items: columns.map(column => ({
-						value: column, text: this.$t('_deck._columns.' + column)
-					}))
-				},
-				showCancelButton: true
+				items: columns.map(column => ({
+					value: column, text: this.$t('_deck._columns.' + column)
+				}))
 			});
 			if (canceled) return;
 
diff --git a/packages/client/src/ui/deck/antenna-column.vue b/packages/client/src/ui/deck/antenna-column.vue
index d42b8a5a10..198ebbbefa 100644
--- a/packages/client/src/ui/deck/antenna-column.vue
+++ b/packages/client/src/ui/deck/antenna-column.vue
@@ -52,16 +52,12 @@ export default defineComponent({
 	methods: {
 		async setAntenna() {
 			const antennas = await os.api('antennas/list');
-			const { canceled, result: antenna } = await os.dialog({
+			const { canceled, result: antenna } = await os.select({
 				title: this.$ts.selectAntenna,
-				type: null,
-				select: {
-					items: antennas.map(x => ({
-						value: x, text: x.name
-					})),
+				items: antennas.map(x => ({
+					value: x, text: x.name
+				})),
 				default: this.column.antennaId
-				},
-				showCancelButton: true
 			});
 			if (canceled) return;
 			updateColumn(this.column.id, {
diff --git a/packages/client/src/ui/deck/list-column.vue b/packages/client/src/ui/deck/list-column.vue
index 3ebba8032f..ab04aee4e7 100644
--- a/packages/client/src/ui/deck/list-column.vue
+++ b/packages/client/src/ui/deck/list-column.vue
@@ -52,16 +52,12 @@ export default defineComponent({
 	methods: {
 		async setList() {
 			const lists = await os.api('users/lists/list');
-			const { canceled, result: list } = await os.dialog({
+			const { canceled, result: list } = await os.select({
 				title: this.$ts.selectList,
-				type: null,
-				select: {
-					items: lists.map(x => ({
-						value: x, text: x.name
-					})),
-					default: this.column.listId
-				},
-				showCancelButton: true
+				items: lists.map(x => ({
+					value: x, text: x.name
+				})),
+				default: this.column.listId
 			});
 			if (canceled) return;
 			updateColumn(this.column.id, {
diff --git a/packages/client/src/ui/deck/tl-column.vue b/packages/client/src/ui/deck/tl-column.vue
index faf692c447..8021688334 100644
--- a/packages/client/src/ui/deck/tl-column.vue
+++ b/packages/client/src/ui/deck/tl-column.vue
@@ -69,20 +69,17 @@ export default defineComponent({
 
 	methods: {
 		async setType() {
-			const { canceled, result: src } = await os.dialog({
+			const { canceled, result: src } = await os.select({
 				title: this.$ts.timeline,
-				type: null,
-				select: {
-					items: [{
-						value: 'home', text: this.$ts._timelines.home
-					}, {
-						value: 'local', text: this.$ts._timelines.local
-					}, {
-						value: 'social', text: this.$ts._timelines.social
-					}, {
-						value: 'global', text: this.$ts._timelines.global
-					}]
-				},
+				items: [{
+					value: 'home', text: this.$ts._timelines.home
+				}, {
+					value: 'local', text: this.$ts._timelines.local
+				}, {
+					value: 'social', text: this.$ts._timelines.social
+				}, {
+					value: 'global', text: this.$ts._timelines.global
+				}]
 			});
 			if (canceled) {
 				if (this.column.tl == null) {
diff --git a/packages/client/src/widgets/aiscript.vue b/packages/client/src/widgets/aiscript.vue
index 992ec2f8a1..f2ea5e268a 100644
--- a/packages/client/src/widgets/aiscript.vue
+++ b/packages/client/src/widgets/aiscript.vue
@@ -57,9 +57,8 @@ export default defineComponent({
 			}), {
 				in: (q) => {
 					return new Promise(ok => {
-						os.dialog({
+						os.inputText({
 							title: q,
-							input: {}
 						}).then(({ canceled, result: a }) => {
 							ok(a);
 						});
@@ -88,7 +87,7 @@ export default defineComponent({
 			try {
 				ast = parse(this.props.script);
 			} catch (e) {
-				os.dialog({
+				os.alert({
 					type: 'error',
 					text: 'Syntax error :('
 				});
@@ -97,7 +96,7 @@ export default defineComponent({
 			try {
 				await aiscript.exec(ast);
 			} catch (e) {
-				os.dialog({
+				os.alert({
 					type: 'error',
 					text: e
 				});
diff --git a/packages/client/src/widgets/button.vue b/packages/client/src/widgets/button.vue
index 3417181d0c..e98570862e 100644
--- a/packages/client/src/widgets/button.vue
+++ b/packages/client/src/widgets/button.vue
@@ -50,9 +50,8 @@ export default defineComponent({
 			}), {
 				in: (q) => {
 					return new Promise(ok => {
-						os.dialog({
+						os.inputText({
 							title: q,
-							input: {}
 						}).then(({ canceled, result: a }) => {
 							ok(a);
 						});
@@ -70,7 +69,7 @@ export default defineComponent({
 			try {
 				ast = parse(this.props.script);
 			} catch (e) {
-				os.dialog({
+				os.alert({
 					type: 'error',
 					text: 'Syntax error :('
 				});
@@ -79,7 +78,7 @@ export default defineComponent({
 			try {
 				await aiscript.exec(ast);
 			} catch (e) {
-				os.dialog({
+				os.alert({
 					type: 'error',
 					text: e
 				});