Improve waiting dialog
This commit is contained in:
		
							parent
							
								
									85a0f696bc
								
							
						
					
					
						commit
						1df7abfbb9
					
				
					 8 changed files with 110 additions and 131 deletions
				
			
		|  | @ -44,14 +44,7 @@ export default defineComponent({ | |||
| 	}, | ||||
| 	methods: { | ||||
| 		upload() { | ||||
| 			return new Promise((ok) => { | ||||
| 				const dialog = os.dialog({ | ||||
| 					type: 'waiting', | ||||
| 					text: this.$t('uploading') + '...', | ||||
| 					showOkButton: false, | ||||
| 					showCancelButton: false, | ||||
| 					cancelableByBgClick: false | ||||
| 				}); | ||||
| 			const promise = new Promise((ok) => { | ||||
| 				const canvas = this.hpml.canvases[this.value.canvasId]; | ||||
| 				canvas.toBlob(blob => { | ||||
| 					const data = new FormData(); | ||||
|  | @ -67,11 +60,12 @@ export default defineComponent({ | |||
| 					}) | ||||
| 					.then(response => response.json()) | ||||
| 					.then(f => { | ||||
| 						dialog.close(); | ||||
| 						ok(f); | ||||
| 					}) | ||||
| 				}); | ||||
| 			}); | ||||
| 			os.promiseDialog(promise); | ||||
| 			return promise; | ||||
| 		}, | ||||
| 		async post() { | ||||
| 			this.posting = true; | ||||
|  |  | |||
|  | @ -1,8 +1,9 @@ | |||
| <template> | ||||
| <MkModal ref="modal" @click="type === 'success' ? done() : () => {}" @closed="$emit('closed')"> | ||||
| 	<div class="iuyakobc" :class="type"> | ||||
| 		<Fa class="icon" v-if="type === 'success'" :icon="faCheck"/> | ||||
| 		<Fa class="icon" v-else-if="type === 'waiting'" :icon="faSpinner" pulse/> | ||||
| <MkModal ref="modal" @click="success ? done() : () => {}" @closed="$emit('closed')"> | ||||
| 	<div class="iuyakobc" :class="{ iconOnly: (text == null) || success }"> | ||||
| 		<Fa class="icon success" v-if="success" :icon="faCheck"/> | ||||
| 		<Fa class="icon waiting" v-else :icon="faSpinner" pulse/> | ||||
| 		<div class="text" v-if="text && !success">{{ text }}<MkEllipsis/></div> | ||||
| 	</div> | ||||
| </MkModal> | ||||
| </template> | ||||
|  | @ -18,12 +19,18 @@ export default defineComponent({ | |||
| 	}, | ||||
| 
 | ||||
| 	props: { | ||||
| 		type: { | ||||
| 			required: true | ||||
| 		success: { | ||||
| 			type: Boolean, | ||||
| 			required: true, | ||||
| 		}, | ||||
| 		showing: { | ||||
| 			required: true | ||||
| 		} | ||||
| 			type: Boolean, | ||||
| 			required: true, | ||||
| 		}, | ||||
| 		text: { | ||||
| 			type: String, | ||||
| 			required: false, | ||||
| 		}, | ||||
| 	}, | ||||
| 
 | ||||
| 	emits: ['done', 'closed'], | ||||
|  | @ -57,17 +64,32 @@ export default defineComponent({ | |||
| 	text-align: center; | ||||
| 	background: var(--panel); | ||||
| 	border-radius: var(--radius); | ||||
| 	width: initial; | ||||
| 	font-size: 32px; | ||||
| 	width: 250px; | ||||
| 
 | ||||
| 	&.success { | ||||
| 		color: var(--accent); | ||||
| 	&.iconOnly { | ||||
| 		padding: 0; | ||||
| 		width: 96px; | ||||
| 		height: 96px; | ||||
| 
 | ||||
| 		> .icon { | ||||
| 			height: 100%; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	&.waiting { | ||||
| 		> .icon { | ||||
| 	> .icon { | ||||
| 		font-size: 32px; | ||||
| 
 | ||||
| 		&.success { | ||||
| 			color: var(--accent); | ||||
| 		} | ||||
| 
 | ||||
| 		&.waiting { | ||||
| 			opacity: 0.7; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	> .text { | ||||
| 		margin-top: 16px; | ||||
| 	} | ||||
| } | ||||
| </style> | ||||
|  | @ -62,17 +62,34 @@ export function api(endpoint: string, data: Record<string, any> = {}, token?: st | |||
| 	return promise; | ||||
| } | ||||
| 
 | ||||
| export function apiWithDialog(endpoint: string, data: Record<string, any> = {}, token?: string | null | undefined, onSuccess?: (res: any) => void, onFailure?: (e: Error) => void) { | ||||
| 	const showing = ref(true); | ||||
| 	const state = ref('waiting'); | ||||
| 
 | ||||
| export function apiWithDialog( | ||||
| 	endpoint: string, | ||||
| 	data: Record<string, any> = {}, | ||||
| 	token?: string | null | undefined, | ||||
| 	onSuccess?: (res: any) => void, | ||||
| 	onFailure?: (e: Error) => void, | ||||
| ) { | ||||
| 	const promise = api(endpoint, data, token); | ||||
| 	promiseDialog(promise, onSuccess, onFailure); | ||||
| 
 | ||||
| 	return promise; | ||||
| } | ||||
| 
 | ||||
| export function promiseDialog<T extends Promise<any>>( | ||||
| 	promise: T, | ||||
| 	onSuccess?: (res: any) => void, | ||||
| 	onFailure?: (e: Error) => void, | ||||
| 	text?: string, | ||||
| ): T { | ||||
| 	const showing = ref(true); | ||||
| 	const success = ref(false); | ||||
| 
 | ||||
| 	promise.then(res => { | ||||
| 		if (onSuccess) { | ||||
| 			showing.value = false; | ||||
| 			onSuccess(res); | ||||
| 		} else { | ||||
| 			state.value = 'success'; | ||||
| 			success.value = true; | ||||
| 			setTimeout(() => { | ||||
| 				showing.value = false; | ||||
| 			}, 1000); | ||||
|  | @ -89,9 +106,10 @@ export function apiWithDialog(endpoint: string, data: Record<string, any> = {}, | |||
| 		} | ||||
| 	}); | ||||
| 
 | ||||
| 	popup(defineAsyncComponent(() => import('@/components/icon-dialog.vue')), { | ||||
| 		type: state, | ||||
| 		showing: showing | ||||
| 	popup(defineAsyncComponent(() => import('@/components/waiting-dialog.vue')), { | ||||
| 		success: success, | ||||
| 		showing: showing, | ||||
| 		text: text, | ||||
| 	}, {}, 'closed'); | ||||
| 
 | ||||
| 	return promise; | ||||
|  | @ -161,8 +179,8 @@ export function success() { | |||
| 		setTimeout(() => { | ||||
| 			showing.value = false; | ||||
| 		}, 1000); | ||||
| 		popup(defineAsyncComponent(() => import('@/components/icon-dialog.vue')), { | ||||
| 			type: 'success', | ||||
| 		popup(defineAsyncComponent(() => import('@/components/waiting-dialog.vue')), { | ||||
| 			success: true, | ||||
| 			showing: showing | ||||
| 		}, { | ||||
| 			done: () => resolve(), | ||||
|  | @ -173,8 +191,8 @@ export function success() { | |||
| export function waiting() { | ||||
| 	return new Promise((resolve, reject) => { | ||||
| 		const showing = ref(true); | ||||
| 		popup(defineAsyncComponent(() => import('@/components/icon-dialog.vue')), { | ||||
| 			type: 'waiting', | ||||
| 		popup(defineAsyncComponent(() => import('@/components/waiting-dialog.vue')), { | ||||
| 			success: false, | ||||
| 			showing: showing | ||||
| 		}, { | ||||
| 			done: () => resolve(), | ||||
|  |  | |||
|  | @ -6,26 +6,20 @@ | |||
| <script lang="ts"> | ||||
| import { defineComponent } from 'vue'; | ||||
| import * as os from '@/os'; | ||||
| import parseAcct from '../../misc/acct/parse'; | ||||
| 
 | ||||
| export default defineComponent({ | ||||
| 	created() { | ||||
| 		const acct = new URL(location.href).searchParams.get('acct'); | ||||
| 		if (acct == null) return; | ||||
| 
 | ||||
| 		/* | ||||
| 		const dialog = os.dialog({ | ||||
| 			type: 'waiting', | ||||
| 			text: this.$t('fetchingAsApObject') + '...', | ||||
| 			showOkButton: false, | ||||
| 			showCancelButton: false, | ||||
| 			cancelableByBgClick: false | ||||
| 		}); | ||||
| 		*/ | ||||
| 		let promise; | ||||
| 
 | ||||
| 		if (acct.startsWith('https://')) { | ||||
| 			os.api('ap/show', { | ||||
| 			promise = os.api('ap/show', { | ||||
| 				uri: acct | ||||
| 			}).then(res => { | ||||
| 			}); | ||||
| 			promise.then(res => { | ||||
| 				if (res.type == 'User') { | ||||
| 					this.follow(res.object); | ||||
| 				} else if (res.type === 'Note') { | ||||
|  | @ -38,30 +32,15 @@ export default defineComponent({ | |||
| 						window.close(); | ||||
| 					}); | ||||
| 				} | ||||
| 			}).catch(e => { | ||||
| 				os.dialog({ | ||||
| 					type: 'error', | ||||
| 					text: e | ||||
| 				}).then(() => { | ||||
| 					window.close(); | ||||
| 				}); | ||||
| 			}).finally(() => { | ||||
| 				//dialog.close(); | ||||
| 			}); | ||||
| 		} else { | ||||
| 			os.api('users/show', parseAcct(acct)).then(user => { | ||||
| 			promise = os.api('users/show', parseAcct(acct)); | ||||
| 			promise.then(user => { | ||||
| 				this.follow(user); | ||||
| 			}).catch(e => { | ||||
| 				os.dialog({ | ||||
| 					type: 'error', | ||||
| 					text: e | ||||
| 				}).then(() => { | ||||
| 					window.close(); | ||||
| 				}); | ||||
| 			}).finally(() => { | ||||
| 				//dialog.close(); | ||||
| 			}); | ||||
| 		} | ||||
| 
 | ||||
| 		os.promiseDialog(promise, null, null, this.$t('fetchingAsApObject')); | ||||
| 	}, | ||||
| 
 | ||||
| 	methods: { | ||||
|  | @ -77,19 +56,8 @@ export default defineComponent({ | |||
| 				return; | ||||
| 			} | ||||
| 			 | ||||
| 			os.api('following/create', { | ||||
| 			os.apiWithDialog('following/create', { | ||||
| 				userId: user.id | ||||
| 			}).then(() => { | ||||
| 				os.success().then(() => { | ||||
| 					window.close(); | ||||
| 				}); | ||||
| 			}).catch(e => { | ||||
| 				os.dialog({ | ||||
| 					type: 'error', | ||||
| 					text: e | ||||
| 				}).then(() => { | ||||
| 					window.close(); | ||||
| 				}); | ||||
| 			}); | ||||
| 		} | ||||
| 	} | ||||
|  |  | |||
|  | @ -106,24 +106,13 @@ export default defineComponent({ | |||
| 		async add(e) { | ||||
| 			const files = await selectFile(e.currentTarget || e.target, null, true); | ||||
| 
 | ||||
| 			const dialog = os.dialog({ | ||||
| 				type: 'waiting', | ||||
| 				text: this.$t('doing') + '...', | ||||
| 				showOkButton: false, | ||||
| 				showCancelButton: false, | ||||
| 				cancelableByBgClick: false | ||||
| 			}); | ||||
| 			 | ||||
| 			Promise.all(files.map(file => os.api('admin/emoji/add', { | ||||
| 			const promise = Promise.all(files.map(file => os.api('admin/emoji/add', { | ||||
| 				fileId: file.id, | ||||
| 			}))) | ||||
| 			.then(() => { | ||||
| 			}))); | ||||
| 			promise.then(() => { | ||||
| 				this.$refs.emojis.reload(); | ||||
| 				os.success(); | ||||
| 			}) | ||||
| 			.finally(() => { | ||||
| 				dialog.cancel(); | ||||
| 			}); | ||||
| 			os.promiseDialog(promise); | ||||
| 		}, | ||||
| 
 | ||||
| 		async edit(emoji) { | ||||
|  |  | |||
|  | @ -69,31 +69,15 @@ export default defineComponent({ | |||
| 			data.append('file', file); | ||||
| 			data.append('i', this.$store.state.i.token); | ||||
| 
 | ||||
| 			const dialog = os.dialog({ | ||||
| 				type: 'waiting', | ||||
| 				text: this.$t('uploading') + '...', | ||||
| 				showOkButton: false, | ||||
| 				showCancelButton: false, | ||||
| 				cancelableByBgClick: false | ||||
| 			}); | ||||
| 
 | ||||
| 			fetch(apiUrl + '/drive/files/create', { | ||||
| 			const promise = fetch(apiUrl + '/drive/files/create', { | ||||
| 				method: 'POST', | ||||
| 				body: data | ||||
| 			}) | ||||
| 			.then(response => response.json()) | ||||
| 			.then(f => { | ||||
| 				this.reqImport(f); | ||||
| 			}) | ||||
| 			.catch(e => { | ||||
| 				os.dialog({ | ||||
| 					type: 'error', | ||||
| 					text: e | ||||
| 				}); | ||||
| 			}) | ||||
| 			.finally(() => { | ||||
| 				dialog.close(); | ||||
| 			}); | ||||
| 			os.promiseDialog(promise); | ||||
| 		}, | ||||
| 
 | ||||
| 		reqImport(file) { | ||||
|  |  | |||
|  | @ -106,6 +106,14 @@ | |||
| 			</div> | ||||
| 		</div> | ||||
| 
 | ||||
| 		<div class="_card _vMargin"> | ||||
| 			<div class="_title">Waiting dialog</div> | ||||
| 			<div class="_content"> | ||||
| 				<MkButton inline @click="openWaitingDialog()">icon only</MkButton> | ||||
| 				<MkButton inline @click="openWaitingDialog('Doing')">with text</MkButton> | ||||
| 			</div> | ||||
| 		</div> | ||||
| 
 | ||||
| 		<div class="_card _vMargin"> | ||||
| 			<div class="_title">Messaging window</div> | ||||
| 			<div class="_content"> | ||||
|  | @ -224,6 +232,13 @@ export default defineComponent({ | |||
| 			os.pageWindow('/my/messaging', defineAsyncComponent(() => import('@/pages/messaging/index.vue'))); | ||||
| 		}, | ||||
| 
 | ||||
| 		openWaitingDialog(text?) { | ||||
| 			const promise = new Promise((resolve, reject) => { | ||||
| 				setTimeout(resolve, 2000); | ||||
| 			}); | ||||
| 			os.promiseDialog(promise, null, null, text); | ||||
| 		}, | ||||
| 
 | ||||
| 		resetTutorial() { | ||||
| 			this.$store.dispatch('settings/set', { key: 'tutorial', value: 0 }); | ||||
| 		}, | ||||
|  |  | |||
|  | @ -48,29 +48,18 @@ export async function search(q?: string | null | undefined) { | |||
| 	} | ||||
| 
 | ||||
| 	if (q.startsWith('https://')) { | ||||
| 		/* | ||||
| 		const dialog = os.dialog({ | ||||
| 			type: 'waiting', | ||||
| 			text: i18n.global.t('fetchingAsApObject') + '...', | ||||
| 			showOkButton: false, | ||||
| 			showCancelButton: false, | ||||
| 			cancelableByBgClick: false | ||||
| 		const promise = os.api('ap/show', { | ||||
| 			uri: q | ||||
| 		}); | ||||
| 		*/ | ||||
| 
 | ||||
| 		try { | ||||
| 			const res = await os.api('ap/show', { | ||||
| 				uri: q | ||||
| 			}); | ||||
| 			//dialog.cancel();
 | ||||
| 			if (res.type === 'User') { | ||||
| 				router.push(`/@${res.object.username}@${res.object.host}`); | ||||
| 			} else if (res.type === 'Note') { | ||||
| 				router.push(`/notes/${res.object.id}`); | ||||
| 			} | ||||
| 		} catch (e) { | ||||
| 			//dialog.cancel();
 | ||||
| 			// TODO: Show error
 | ||||
| 		os.promiseDialog(promise, null, null, i18n.global.t('fetchingAsApObject')); | ||||
| 
 | ||||
| 		const res = await promise; | ||||
| 
 | ||||
| 		if (res.type === 'User') { | ||||
| 			router.push(`/@${res.object.username}@${res.object.host}`); | ||||
| 		} else if (res.type === 'Note') { | ||||
| 			router.push(`/notes/${res.object.id}`); | ||||
| 		} | ||||
| 
 | ||||
| 		return; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue