wip
This commit is contained in:
		
							parent
							
								
									02701d852d
								
							
						
					
					
						commit
						cd79314f69
					
				|  | @ -376,7 +376,7 @@ export default defineComponent({ | |||
| 
 | ||||
| 		chooseUser() { | ||||
| 			this.close(); | ||||
| 			const vm = os.popup(MkUserSelect, {}); | ||||
| 			const vm = os.modal(MkUserSelect, {}); | ||||
| 			vm.$once('selected', user => { | ||||
| 				this.complete('user', user); | ||||
| 			}); | ||||
|  |  | |||
|  | @ -43,7 +43,7 @@ export default defineComponent({ | |||
| 			icon: faCog, | ||||
| 			text: this.$t('notificationSetting'), | ||||
| 			action: async () => { | ||||
| 				os.popup(await import('../notification-setting-window.vue'), { | ||||
| 				os.modal(await import('../notification-setting-window.vue'), { | ||||
| 					includingTypes: this.column.includingTypes, | ||||
| 				}).$on('ok', async ({ includingTypes }) => { | ||||
| 					this.$set(this.column, 'includingTypes', includingTypes); | ||||
|  |  | |||
|  | @ -1,46 +1,44 @@ | |||
| <template> | ||||
| <x-modal @closed="$emit('closed')" @click="onBgClick" :showing="showing"> | ||||
| 	<div class="mk-dialog" :class="{ iconOnly }"> | ||||
| 		<template v-if="type == 'signin'"> | ||||
| 			<mk-signin/> | ||||
| 		</template> | ||||
| 		<template v-else> | ||||
| 			<div class="icon" v-if="icon"> | ||||
| 				<fa :icon="icon"/> | ||||
| 			</div> | ||||
| 			<div class="icon" v-else-if="!input && !select && !user" :class="type"> | ||||
| 				<fa :icon="faCheck" v-if="type === 'success'"/> | ||||
| 				<fa :icon="faTimesCircle" v-if="type === 'error'"/> | ||||
| 				<fa :icon="faExclamationTriangle" v-if="type === 'warning'"/> | ||||
| 				<fa :icon="faInfoCircle" v-if="type === 'info'"/> | ||||
| 				<fa :icon="faQuestionCircle" v-if="type === 'question'"/> | ||||
| 				<fa :icon="faSpinner" pulse v-if="type === 'waiting'"/> | ||||
| 			</div> | ||||
| 			<header v-if="title" v-html="title"></header> | ||||
| 			<header v-if="title == null && user">{{ $t('enterUsername') }}</header> | ||||
| 			<div class="body" v-if="text" v-html="text"></div> | ||||
| 			<mk-input v-if="input" v-model:value="inputValue" autofocus :type="input.type || 'text'" :placeholder="input.placeholder" @keydown="onInputKeydown"></mk-input> | ||||
| 			<mk-input v-if="user" v-model:value="userInputValue" autofocus @keydown="onInputKeydown"><template #prefix>@</template></mk-input> | ||||
| 			<mk-select v-if="select" v-model:value="selectedValue" autofocus> | ||||
| 				<template v-if="select.items"> | ||||
| 					<option v-for="item in select.items" :value="item.value">{{ item.text }}</option> | ||||
| 				</template> | ||||
| 				<template v-else> | ||||
| 					<optgroup v-for="groupedItem in select.groupedItems" :label="groupedItem.label"> | ||||
| 						<option v-for="item in groupedItem.items" :value="item.value">{{ item.text }}</option> | ||||
| 					</optgroup> | ||||
| 				</template> | ||||
| 			</mk-select> | ||||
| 			<div class="buttons" v-if="!iconOnly && (showOkButton || showCancelButton) && !actions"> | ||||
| 				<mk-button inline @click="ok" v-if="showOkButton" primary :autofocus="!input && !select && !user" :disabled="!canOk">{{ (showCancelButton || input || select || user) ? $t('ok') : $t('gotIt') }}</mk-button> | ||||
| 				<mk-button inline @click="cancel" v-if="showCancelButton || input || select || user">{{ $t('cancel') }}</mk-button> | ||||
| 			</div> | ||||
| 			<div class="buttons" v-if="actions"> | ||||
| 				<mk-button v-for="action in actions" inline @click="() => { action.callback(); close(); }" :primary="action.primary" :key="action.text">{{ action.text }}</mk-button> | ||||
| 			</div> | ||||
| 		</template> | ||||
| 	</div> | ||||
| </x-modal> | ||||
| <div class="mk-dialog" :class="{ iconOnly }"> | ||||
| 	<template v-if="type == 'signin'"> | ||||
| 		<mk-signin/> | ||||
| 	</template> | ||||
| 	<template v-else> | ||||
| 		<div class="icon" v-if="icon"> | ||||
| 			<fa :icon="icon"/> | ||||
| 		</div> | ||||
| 		<div class="icon" v-else-if="!input && !select && !user" :class="type"> | ||||
| 			<fa :icon="faCheck" v-if="type === 'success'"/> | ||||
| 			<fa :icon="faTimesCircle" v-if="type === 'error'"/> | ||||
| 			<fa :icon="faExclamationTriangle" v-if="type === 'warning'"/> | ||||
| 			<fa :icon="faInfoCircle" v-if="type === 'info'"/> | ||||
| 			<fa :icon="faQuestionCircle" v-if="type === 'question'"/> | ||||
| 			<fa :icon="faSpinner" pulse v-if="type === 'waiting'"/> | ||||
| 		</div> | ||||
| 		<header v-if="title" v-html="title"></header> | ||||
| 		<header v-if="title == null && user">{{ $t('enterUsername') }}</header> | ||||
| 		<div class="body" v-if="text" v-html="text"></div> | ||||
| 		<mk-input v-if="input" v-model:value="inputValue" autofocus :type="input.type || 'text'" :placeholder="input.placeholder" @keydown="onInputKeydown"></mk-input> | ||||
| 		<mk-input v-if="user" v-model:value="userInputValue" autofocus @keydown="onInputKeydown"><template #prefix>@</template></mk-input> | ||||
| 		<mk-select v-if="select" v-model:value="selectedValue" autofocus> | ||||
| 			<template v-if="select.items"> | ||||
| 				<option v-for="item in select.items" :value="item.value">{{ item.text }}</option> | ||||
| 			</template> | ||||
| 			<template v-else> | ||||
| 				<optgroup v-for="groupedItem in select.groupedItems" :label="groupedItem.label"> | ||||
| 					<option v-for="item in groupedItem.items" :value="item.value">{{ item.text }}</option> | ||||
| 				</optgroup> | ||||
| 			</template> | ||||
| 		</mk-select> | ||||
| 		<div class="buttons" v-if="!iconOnly && (showOkButton || showCancelButton) && !actions"> | ||||
| 			<mk-button inline @click="ok" v-if="showOkButton" primary :autofocus="!input && !select && !user" :disabled="!canOk">{{ (showCancelButton || input || select || user) ? $t('ok') : $t('gotIt') }}</mk-button> | ||||
| 			<mk-button inline @click="cancel" v-if="showCancelButton || input || select || user">{{ $t('cancel') }}</mk-button> | ||||
| 		</div> | ||||
| 		<div class="buttons" v-if="actions"> | ||||
| 			<mk-button v-for="action in actions" inline @click="() => { action.callback(); close(); }" :primary="action.primary" :key="action.text">{{ action.text }}</mk-button> | ||||
| 		</div> | ||||
| 	</template> | ||||
| </div> | ||||
| </template> | ||||
| 
 | ||||
| <script lang="ts"> | ||||
|  | @ -52,12 +50,10 @@ import MkInput from './ui/input.vue'; | |||
| import MkSelect from './ui/select.vue'; | ||||
| import MkSignin from './signin.vue'; | ||||
| import parseAcct from '../../misc/acct/parse'; | ||||
| import XModal from './modal.vue'; | ||||
| import * as os from '@/os'; | ||||
| 
 | ||||
| export default defineComponent({ | ||||
| 	components: { | ||||
| 		XModal, | ||||
| 		MkButton, | ||||
| 		MkInput, | ||||
| 		MkSelect, | ||||
|  | @ -65,9 +61,6 @@ export default defineComponent({ | |||
| 	}, | ||||
| 
 | ||||
| 	props: { | ||||
| 		showing: { | ||||
| 			required: true | ||||
| 		}, | ||||
| 		type: { | ||||
| 			type: String, | ||||
| 			required: false, | ||||
|  | @ -118,7 +111,7 @@ export default defineComponent({ | |||
| 		}, | ||||
| 	}, | ||||
| 
 | ||||
| 	emits: ['done', 'closed'], | ||||
| 	emits: ['done'], | ||||
| 
 | ||||
| 	data() { | ||||
| 		return { | ||||
|  |  | |||
|  | @ -72,7 +72,7 @@ export default defineComponent({ | |||
| 			if (this.$store.state.device.imageNewTab) { | ||||
| 				window.open(this.image.url, '_blank'); | ||||
| 			} else { | ||||
| 				const viewer = os.popup(ImageViewer, { | ||||
| 				const viewer = os.modal(ImageViewer, { | ||||
| 					image: this.image | ||||
| 				}); | ||||
| 				this.$once('hook:beforeDestroy', () => { | ||||
|  |  | |||
|  | @ -1,55 +1,43 @@ | |||
| <template> | ||||
| <x-modal :source="source" :no-center="noCenter" @click="close()" @closed="$emit('closed')" :showing="showing"> | ||||
| 	<div class="rrevdjwt" :class="{ left: align === 'left' }" ref="items" :style="{ width: width + 'px' }"> | ||||
| 		<template v-for="(item, i) in items.filter(item => item !== undefined)"> | ||||
| 			<div v-if="item === null" class="divider" :key="i"></div> | ||||
| 			<span v-else-if="item.type === 'label'" class="label item" :key="i"> | ||||
| 				<span>{{ item.text }}</span> | ||||
| 			</span> | ||||
| 			<router-link v-else-if="item.type === 'link'" :to="item.to" @click.native="close()" :tabindex="i" class="_button item" :key="i"> | ||||
| 				<fa v-if="item.icon" :icon="item.icon" fixed-width/> | ||||
| 				<mk-avatar v-if="item.avatar" :user="item.avatar" class="avatar"/> | ||||
| 				<span>{{ item.text }}</span> | ||||
| 				<i v-if="item.indicate"><fa :icon="faCircle"/></i> | ||||
| 			</router-link> | ||||
| 			<a v-else-if="item.type === 'a'" :href="item.href" :target="item.target" :download="item.download" @click="close()" :tabindex="i" class="_button item" :key="i"> | ||||
| 				<fa v-if="item.icon" :icon="item.icon" fixed-width/> | ||||
| 				<span>{{ item.text }}</span> | ||||
| 				<i v-if="item.indicate"><fa :icon="faCircle"/></i> | ||||
| 			</a> | ||||
| 			<button v-else-if="item.type === 'user'" @click="clicked(item.action)" :tabindex="i" class="_button item" :key="i"> | ||||
| 				<mk-avatar :user="item.user" class="avatar"/><mk-user-name :user="item.user"/> | ||||
| 				<i v-if="item.indicate"><fa :icon="faCircle"/></i> | ||||
| 			</button> | ||||
| 			<button v-else @click="clicked(item.action)" :tabindex="i" class="_button item" :key="i"> | ||||
| 				<fa v-if="item.icon" :icon="item.icon" fixed-width/> | ||||
| 				<mk-avatar v-if="item.avatar" :user="item.avatar" class="avatar"/> | ||||
| 				<span>{{ item.text }}</span> | ||||
| 				<i v-if="item.indicate"><fa :icon="faCircle"/></i> | ||||
| 			</button> | ||||
| 		</template> | ||||
| 	</div> | ||||
| </x-modal> | ||||
| <div class="rrevdjwt" :class="{ left: align === 'left' }" ref="items" :style="{ width: width + 'px' }"> | ||||
| 	<template v-for="(item, i) in items.filter(item => item !== undefined)"> | ||||
| 		<div v-if="item === null" class="divider" :key="i"></div> | ||||
| 		<span v-else-if="item.type === 'label'" class="label item" :key="i"> | ||||
| 			<span>{{ item.text }}</span> | ||||
| 		</span> | ||||
| 		<router-link v-else-if="item.type === 'link'" :to="item.to" @click.native="close()" :tabindex="i" class="_button item" :key="i"> | ||||
| 			<fa v-if="item.icon" :icon="item.icon" fixed-width/> | ||||
| 			<mk-avatar v-if="item.avatar" :user="item.avatar" class="avatar"/> | ||||
| 			<span>{{ item.text }}</span> | ||||
| 			<i v-if="item.indicate"><fa :icon="faCircle"/></i> | ||||
| 		</router-link> | ||||
| 		<a v-else-if="item.type === 'a'" :href="item.href" :target="item.target" :download="item.download" @click="close()" :tabindex="i" class="_button item" :key="i"> | ||||
| 			<fa v-if="item.icon" :icon="item.icon" fixed-width/> | ||||
| 			<span>{{ item.text }}</span> | ||||
| 			<i v-if="item.indicate"><fa :icon="faCircle"/></i> | ||||
| 		</a> | ||||
| 		<button v-else-if="item.type === 'user'" @click="clicked(item.action)" :tabindex="i" class="_button item" :key="i"> | ||||
| 			<mk-avatar :user="item.user" class="avatar"/><mk-user-name :user="item.user"/> | ||||
| 			<i v-if="item.indicate"><fa :icon="faCircle"/></i> | ||||
| 		</button> | ||||
| 		<button v-else @click="clicked(item.action)" :tabindex="i" class="_button item" :key="i"> | ||||
| 			<fa v-if="item.icon" :icon="item.icon" fixed-width/> | ||||
| 			<mk-avatar v-if="item.avatar" :user="item.avatar" class="avatar"/> | ||||
| 			<span>{{ item.text }}</span> | ||||
| 			<i v-if="item.indicate"><fa :icon="faCircle"/></i> | ||||
| 		</button> | ||||
| 	</template> | ||||
| </div> | ||||
| </template> | ||||
| 
 | ||||
| <script lang="ts"> | ||||
| import { defineComponent } from 'vue'; | ||||
| import { faCircle } from '@fortawesome/free-solid-svg-icons'; | ||||
| import XModal from './modal.vue'; | ||||
| import { focusPrev, focusNext } from '@/scripts/focus'; | ||||
| import * as os from '@/os'; | ||||
| 
 | ||||
| export default defineComponent({ | ||||
| 	components: { | ||||
| 		XModal | ||||
| 	}, | ||||
| 	props: { | ||||
| 		showing: { | ||||
| 			required: true | ||||
| 		}, | ||||
| 		source: { | ||||
| 			required: true | ||||
| 		}, | ||||
| 		items: { | ||||
| 			type: Array, | ||||
| 			required: true | ||||
|  |  | |||
|  | @ -18,6 +18,9 @@ import * as os from '@/os'; | |||
| // memo: 旧popup.vueのfixedプロパティに相当するものはsource要素の祖先を辿るなどして自動で判定できるのでは | ||||
| 
 | ||||
| export default defineComponent({ | ||||
| 	provide: { | ||||
| 		modal: true | ||||
| 	}, | ||||
| 	props: { | ||||
| 		showing: { | ||||
| 			type: Boolean, | ||||
|  | @ -59,58 +62,60 @@ export default defineComponent({ | |||
| 
 | ||||
| 			const popover = this.$refs.content as any; | ||||
| 
 | ||||
| 			const rect = this.source.getBoundingClientRect(); | ||||
| 			const width = popover.offsetWidth; | ||||
| 			const height = popover.offsetHeight; | ||||
| 			new ResizeObserver((entries, observer) => { | ||||
| 				const rect = this.source.getBoundingClientRect(); | ||||
| 				const width = popover.offsetWidth; | ||||
| 				const height = popover.offsetHeight; | ||||
| 
 | ||||
| 			let left; | ||||
| 			let top; | ||||
| 				let left; | ||||
| 				let top; | ||||
| 
 | ||||
| 			if (os.isMobile && !this.noCenter) { | ||||
| 				const x = rect.left + (this.fixed ? 0 : window.pageXOffset) + (this.source.offsetWidth / 2); | ||||
| 				const y = rect.top + (this.fixed ? 0 : window.pageYOffset) + (this.source.offsetHeight / 2); | ||||
| 				left = (x - (width / 2)); | ||||
| 				top = (y - (height / 2)); | ||||
| 				popover.style.transformOrigin = 'center'; | ||||
| 			} else { | ||||
| 				const x = rect.left + (this.fixed ? 0 : window.pageXOffset) + (this.source.offsetWidth / 2); | ||||
| 				const y = rect.top + (this.fixed ? 0 : window.pageYOffset) + this.source.offsetHeight; | ||||
| 				left = (x - (width / 2)); | ||||
| 				top = y; | ||||
| 			} | ||||
| 
 | ||||
| 			if (this.fixed) { | ||||
| 				if (left + width > window.innerWidth) { | ||||
| 					left = window.innerWidth - width; | ||||
| 				if (os.isMobile && !this.noCenter) { | ||||
| 					const x = rect.left + (this.fixed ? 0 : window.pageXOffset) + (this.source.offsetWidth / 2); | ||||
| 					const y = rect.top + (this.fixed ? 0 : window.pageYOffset) + (this.source.offsetHeight / 2); | ||||
| 					left = (x - (width / 2)); | ||||
| 					top = (y - (height / 2)); | ||||
| 					popover.style.transformOrigin = 'center'; | ||||
| 				} else { | ||||
| 					const x = rect.left + (this.fixed ? 0 : window.pageXOffset) + (this.source.offsetWidth / 2); | ||||
| 					const y = rect.top + (this.fixed ? 0 : window.pageYOffset) + this.source.offsetHeight; | ||||
| 					left = (x - (width / 2)); | ||||
| 					top = y; | ||||
| 				} | ||||
| 
 | ||||
| 				if (top + height > window.innerHeight) { | ||||
| 					top = window.innerHeight - height; | ||||
| 					popover.style.transformOrigin = 'center'; | ||||
| 				} | ||||
| 			} else { | ||||
| 				if (left + width - window.pageXOffset > window.innerWidth) { | ||||
| 					left = window.innerWidth - width + window.pageXOffset; | ||||
| 					popover.style.transformOrigin = 'center'; | ||||
| 				if (this.fixed) { | ||||
| 					if (left + width > window.innerWidth) { | ||||
| 						left = window.innerWidth - width; | ||||
| 						popover.style.transformOrigin = 'center'; | ||||
| 					} | ||||
| 
 | ||||
| 					if (top + height > window.innerHeight) { | ||||
| 						top = window.innerHeight - height; | ||||
| 						popover.style.transformOrigin = 'center'; | ||||
| 					} | ||||
| 				} else { | ||||
| 					if (left + width - window.pageXOffset > window.innerWidth) { | ||||
| 						left = window.innerWidth - width + window.pageXOffset; | ||||
| 						popover.style.transformOrigin = 'center'; | ||||
| 					} | ||||
| 
 | ||||
| 					if (top + height - window.pageYOffset > window.innerHeight) { | ||||
| 						top = window.innerHeight - height + window.pageYOffset; | ||||
| 						popover.style.transformOrigin = 'center'; | ||||
| 					} | ||||
| 				} | ||||
| 
 | ||||
| 				if (top + height - window.pageYOffset > window.innerHeight) { | ||||
| 					top = window.innerHeight - height + window.pageYOffset; | ||||
| 					popover.style.transformOrigin = 'center'; | ||||
| 				if (top < 0) { | ||||
| 					top = 0; | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			if (top < 0) { | ||||
| 				top = 0; | ||||
| 			} | ||||
| 				if (left < 0) { | ||||
| 					left = 0; | ||||
| 				} | ||||
| 
 | ||||
| 			if (left < 0) { | ||||
| 				left = 0; | ||||
| 			} | ||||
| 
 | ||||
| 			popover.style.left = left + 'px'; | ||||
| 			popover.style.top = top + 'px'; | ||||
| 				popover.style.left = left + 'px'; | ||||
| 				popover.style.top = top + 'px'; | ||||
| 			}).observe(popover); | ||||
| 		}); | ||||
| 	}, | ||||
| }); | ||||
|  |  | |||
|  | @ -96,7 +96,7 @@ | |||
| </template> | ||||
| 
 | ||||
| <script lang="ts"> | ||||
| import { defineComponent } from 'vue'; | ||||
| import { defineAsyncComponent, defineComponent } from 'vue'; | ||||
| import { faSatelliteDish, faBolt, faTimes, faBullhorn, faStar, faLink, faExternalLinkSquareAlt, faPlus, faMinus, faRetweet, faReply, faReplyAll, faEllipsisH, faHome, faUnlock, faEnvelope, faThumbtack, faBan, faQuoteRight, faInfoCircle, faBiohazard, faPlug } from '@fortawesome/free-solid-svg-icons'; | ||||
| import { faCopy, faTrashAlt, faEdit, faEye, faEyeSlash } from '@fortawesome/free-regular-svg-icons'; | ||||
| import { parse } from '../../mfm/parse'; | ||||
|  | @ -108,8 +108,6 @@ import XReactionsViewer from './reactions-viewer.vue'; | |||
| import XMediaList from './media-list.vue'; | ||||
| import XCwButton from './cw-button.vue'; | ||||
| import XPoll from './poll.vue'; | ||||
| import MkUrlPreview from './url-preview.vue'; | ||||
| import MkReactionPicker from './reaction-picker.vue'; | ||||
| import { pleaseLogin } from '@/scripts/please-login'; | ||||
| import { focusPrev, focusNext } from '@/scripts/focus'; | ||||
| import { url } from '@/config'; | ||||
|  | @ -133,7 +131,7 @@ export default defineComponent({ | |||
| 		XMediaList, | ||||
| 		XCwButton, | ||||
| 		XPoll, | ||||
| 		MkUrlPreview, | ||||
| 		MkUrlPreview: defineAsyncComponent(() => import('@/components/url-preview.vue')), | ||||
| 	}, | ||||
| 
 | ||||
| 	inject: { | ||||
|  | @ -485,17 +483,17 @@ export default defineComponent({ | |||
| 		react(viaKeyboard = false) { | ||||
| 			pleaseLogin(); | ||||
| 			this.blur(); | ||||
| 			const close = os.popup(MkReactionPicker, { | ||||
| 				source: this.$refs.reactButton, | ||||
| 			os.modal(defineAsyncComponent(() => import('@/components/reaction-picker.vue')), { | ||||
| 				showFocus: viaKeyboard, | ||||
| 			}, reaction => { | ||||
| 				os.api('notes/reactions/create', { | ||||
| 					noteId: this.appearNote.id, | ||||
| 					reaction: reaction | ||||
| 				}).then(() => { | ||||
| 					close(); | ||||
| 				}); | ||||
| 			}, this.focus); | ||||
| 				this.focus(); | ||||
| 			}, { | ||||
| 				source: this.$refs.reactButton | ||||
| 			}); | ||||
| 		}, | ||||
| 
 | ||||
| 		reactDirectly(reaction) { | ||||
|  |  | |||
|  | @ -32,12 +32,11 @@ import { defineComponent } from 'vue'; | |||
| import paging from '@/scripts/paging'; | ||||
| import XNote from './note.vue'; | ||||
| import XList from './date-separated-list.vue'; | ||||
| import MkButton from './ui/button.vue'; | ||||
| import * as os from '@/os'; | ||||
| 
 | ||||
| export default defineComponent({ | ||||
| 	components: { | ||||
| 		XNote, XList, MkButton | ||||
| 		XNote, XList, | ||||
| 	}, | ||||
| 
 | ||||
| 	mixins: [ | ||||
|  | @ -83,9 +82,9 @@ export default defineComponent({ | |||
| 		updated(oldValue, newValue) { | ||||
| 			const i = this.notes.findIndex(n => n === oldValue); | ||||
| 			if (this.prop) { | ||||
| 				Vue.set(this.items[i], this.prop, newValue); | ||||
| 				this.items[i][this.prop] = newValue; | ||||
| 			} else { | ||||
| 				Vue.set(this.items, i, newValue); | ||||
| 				this.items[i] = newValue; | ||||
| 			} | ||||
| 		}, | ||||
| 
 | ||||
|  |  | |||
|  | @ -57,9 +57,6 @@ import * as os from '@/os'; | |||
| 
 | ||||
| export default defineComponent({ | ||||
| 	props: { | ||||
| 		destroy: { | ||||
| 			required: true | ||||
| 		}, | ||||
| 		x: { | ||||
| 			type: Number, | ||||
| 			required: true | ||||
|  | @ -94,7 +91,7 @@ export default defineComponent({ | |||
| 	}, | ||||
| 	mounted() { | ||||
| 		setTimeout(() => { | ||||
| 			this.destroy(); | ||||
| 			this.$emit('closed'); | ||||
| 		}, 1100); | ||||
| 	} | ||||
| }); | ||||
|  |  | |||
|  | @ -1,94 +0,0 @@ | |||
| <template> | ||||
| <x-modal @closed="$emit('closed')" @click="onBgClick" :showing="showing"> | ||||
| 	<x-post-form ref="form" class="ulveipgl" | ||||
| 		:reply="reply" | ||||
| 		:renote="renote" | ||||
| 		:mention="mention" | ||||
| 		:specified="specified" | ||||
| 		:initial-text="initialText" | ||||
| 		:initial-note="initialNote" | ||||
| 		:instant="instant" | ||||
| 		@posted="onPosted" | ||||
| 		@cancel="onCanceled" | ||||
| 	/> | ||||
| </x-modal> | ||||
| </template> | ||||
| 
 | ||||
| <script lang="ts"> | ||||
| import { defineComponent } from 'vue'; | ||||
| import XModal from './modal.vue'; | ||||
| import XPostForm from './post-form.vue'; | ||||
| import * as os from '@/os'; | ||||
| 
 | ||||
| export default defineComponent({ | ||||
| 	components: { | ||||
| 		XModal, | ||||
| 		XPostForm, | ||||
| 	}, | ||||
| 
 | ||||
| 	props: { | ||||
| 		showing: { | ||||
| 			required: true | ||||
| 		}, | ||||
| 		reply: { | ||||
| 			type: Object, | ||||
| 			required: false | ||||
| 		}, | ||||
| 		renote: { | ||||
| 			type: Object, | ||||
| 			required: false | ||||
| 		}, | ||||
| 		mention: { | ||||
| 			type: Object, | ||||
| 			required: false | ||||
| 		}, | ||||
| 		specified: { | ||||
| 			type: Object, | ||||
| 			required: false | ||||
| 		}, | ||||
| 		initialText: { | ||||
| 			type: String, | ||||
| 			required: false | ||||
| 		}, | ||||
| 		initialNote: { | ||||
| 			type: Object, | ||||
| 			required: false | ||||
| 		}, | ||||
| 		instant: { | ||||
| 			type: Boolean, | ||||
| 			required: false, | ||||
| 			default: false | ||||
| 		} | ||||
| 	}, | ||||
| 
 | ||||
| 	methods: { | ||||
| 		focus() { | ||||
| 			this.$refs.form.focus(); | ||||
| 		}, | ||||
| 
 | ||||
| 		onPosted() { | ||||
| 			this.$emit('done', 'posted'); | ||||
| 		}, | ||||
| 
 | ||||
| 		onCanceled() { | ||||
| 			this.$emit('done', 'canceled'); | ||||
| 		}, | ||||
| 
 | ||||
| 		onKeydown(e) { | ||||
| 			if (e.which === 27) { // Esc | ||||
| 				e.preventDefault(); | ||||
| 				e.stopPropagation(); | ||||
| 				this.$emit('done', 'canceled'); | ||||
| 			} | ||||
| 		}, | ||||
| 	} | ||||
| }); | ||||
| </script> | ||||
| 
 | ||||
| <style lang="scss" scoped> | ||||
| .ulveipgl { | ||||
| 	width: 100%; | ||||
| 	max-width: 500px; | ||||
| 	border-radius: var(--radius); | ||||
| } | ||||
| </style> | ||||
|  | @ -1,5 +1,5 @@ | |||
| <template> | ||||
| <div class="gafaadew" | ||||
| <div class="gafaadew" :class="{ modal }" | ||||
| 	@dragover.stop="onDragover" | ||||
| 	@dragenter="onDragenter" | ||||
| 	@dragleave="onDragleave" | ||||
|  | @ -80,6 +80,8 @@ export default defineComponent({ | |||
| 		XPollEditor: defineAsyncComponent(() => import('./poll-editor.vue')) | ||||
| 	}, | ||||
| 
 | ||||
| 	inject: ['modal'], | ||||
| 
 | ||||
| 	props: { | ||||
| 		reply: { | ||||
| 			type: Object, | ||||
|  | @ -417,7 +419,7 @@ export default defineComponent({ | |||
| 				// TODO: information dialog | ||||
| 				return; | ||||
| 			} | ||||
| 			const w = os.popup(MkVisibilityChooser, { | ||||
| 			const w = os.modal(MkVisibilityChooser, { | ||||
| 				source: this.$refs.visibilityButton, | ||||
| 				currentVisibility: this.visibility, | ||||
| 				currentLocalOnly: this.localOnly | ||||
|  | @ -433,7 +435,7 @@ export default defineComponent({ | |||
| 		}, | ||||
| 
 | ||||
| 		addVisibleUser() { | ||||
| 			const vm = os.popup(MkUserSelect, {}); | ||||
| 			const vm = os.modal(MkUserSelect, {}); | ||||
| 			vm.$once('selected', user => { | ||||
| 				this.visibleUsers.push(user); | ||||
| 			}); | ||||
|  | @ -593,18 +595,18 @@ export default defineComponent({ | |||
| 		}, | ||||
| 
 | ||||
| 		cancel() { | ||||
| 			this.$emit('cancel'); | ||||
| 			this.$emit('done'); | ||||
| 		}, | ||||
| 
 | ||||
| 		insertMention() { | ||||
| 			const vm = os.popup(MkUserSelect, {}); | ||||
| 			const vm = os.modal(MkUserSelect, {}); | ||||
| 			vm.$once('selected', user => { | ||||
| 				insertTextAtCursor(this.$refs.text, getAcct(user) + ' '); | ||||
| 			}); | ||||
| 		}, | ||||
| 
 | ||||
| 		async insertEmoji(ev) { | ||||
| 			const vm = os.popup(await import('./emoji-picker.vue'), { | ||||
| 			const vm = os.modal(await import('./emoji-picker.vue'), { | ||||
| 				source: ev.currentTarget || ev.target | ||||
| 			}).$once('chosen', emoji => { | ||||
| 				insertTextAtCursor(this.$refs.text, emoji); | ||||
|  | @ -636,6 +638,12 @@ export default defineComponent({ | |||
| 	position: relative; | ||||
| 	background: var(--panel); | ||||
| 
 | ||||
| 	&.modal { | ||||
| 		width: 100%; | ||||
| 		max-width: 500px; | ||||
| 		border-radius: var(--radius); | ||||
| 	} | ||||
| 
 | ||||
| 	> header { | ||||
| 		z-index: 1000; | ||||
| 		height: 66px; | ||||
|  |  | |||
|  | @ -1,36 +1,24 @@ | |||
| <template> | ||||
| <XModal :source="source" @closed="$emit('closed')" :showing="showing" @click="close" v-hotkey.global="keymap"> | ||||
| 	<div class="rdfaahpb"> | ||||
| 		<div class="buttons" ref="buttons" :class="{ showFocus }"> | ||||
| 			<button class="_button" v-for="(reaction, i) in rs" :key="reaction" @click="react(reaction)" :tabindex="i + 1" :title="reaction" v-particle><x-reaction-icon :reaction="reaction"/></button> | ||||
| 		</div> | ||||
| 		<input class="text" v-model.trim="text" :placeholder="$t('enterEmoji')" @keyup.enter="reactText" @input="tryReactText" v-autocomplete="{ model: 'text' }"> | ||||
| <div class="rdfaahpb"> | ||||
| 	<div class="buttons" ref="buttons" :class="{ showFocus }"> | ||||
| 		<button class="_button" v-for="(reaction, i) in rs" :key="reaction" @click="react(reaction)" :tabindex="i + 1" :title="reaction" v-particle><x-reaction-icon :reaction="reaction"/></button> | ||||
| 	</div> | ||||
| </XModal> | ||||
| 	<input class="text" v-model.trim="text" :placeholder="$t('enterEmoji')" @keyup.enter="reactText" @input="tryReactText" v-autocomplete="{ model: 'text' }"> | ||||
| </div> | ||||
| </template> | ||||
| 
 | ||||
| <script lang="ts"> | ||||
| import { defineComponent } from 'vue'; | ||||
| import { emojiRegex } from '../../misc/emoji-regex'; | ||||
| import XReactionIcon from './reaction-icon.vue'; | ||||
| import XModal from './modal.vue'; | ||||
| import * as os from '@/os'; | ||||
| 
 | ||||
| export default defineComponent({ | ||||
| 	components: { | ||||
| 		XModal, | ||||
| 		XReactionIcon, | ||||
| 	}, | ||||
| 
 | ||||
| 	props: { | ||||
| 		showing: { | ||||
| 			required: true | ||||
| 		}, | ||||
| 
 | ||||
| 		source: { | ||||
| 			required: true | ||||
| 		}, | ||||
| 
 | ||||
| 		reactions: { | ||||
| 			required: false | ||||
| 		}, | ||||
|  |  | |||
|  | @ -111,7 +111,7 @@ export default defineComponent({ | |||
| 
 | ||||
| 				this.closeDetails(); | ||||
| 				if (!this.isHovering) return; | ||||
| 				this.details = os.popup(XDetails, { | ||||
| 				this.details = os.modal(XDetails, { | ||||
| 					reaction: this.reaction, | ||||
| 					users, | ||||
| 					count: this.count, | ||||
|  |  | |||
|  | @ -276,7 +276,7 @@ export default defineComponent({ | |||
| 		}, | ||||
| 
 | ||||
| 		async addAcount() { | ||||
| 			os.popup(await import('./signin-dialog.vue')).$once('login', res => { | ||||
| 			os.modal(await import('./signin-dialog.vue')).$once('login', res => { | ||||
| 				this.$store.dispatch('addAcount', res); | ||||
| 				os.dialog({ | ||||
| 					type: 'success', | ||||
|  | @ -286,7 +286,7 @@ export default defineComponent({ | |||
| 		}, | ||||
| 
 | ||||
| 		async createAccount() { | ||||
| 			os.popup(await import('./signup-dialog.vue')).$once('signup', res => { | ||||
| 			os.modal(await import('./signup-dialog.vue')).$once('signup', res => { | ||||
| 				this.$store.dispatch('addAcount', res); | ||||
| 				this.switchAccountWithToken(res.i); | ||||
| 			}); | ||||
|  |  | |||
|  | @ -166,7 +166,7 @@ export default defineComponent({ | |||
| 					id: notification.id | ||||
| 				}); | ||||
| 
 | ||||
| 				os.popup(await import('@/components/toast.vue'), { | ||||
| 				os.modal(await import('@/components/toast.vue'), { | ||||
| 					notification | ||||
| 				}); | ||||
| 			} | ||||
|  |  | |||
|  | @ -335,7 +335,7 @@ export default defineComponent({ | |||
| 					id: notification.id | ||||
| 				}); | ||||
| 
 | ||||
| 				os.popup(await import('@/components/toast.vue'), { | ||||
| 				os.modal(await import('@/components/toast.vue'), { | ||||
| 					notification | ||||
| 				}); | ||||
| 			} | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| import { Component, defineAsyncComponent, ref } from 'vue'; | ||||
| import { Component, defineAsyncComponent, markRaw, ref } from 'vue'; | ||||
| import Stream from '@/scripts/stream'; | ||||
| import { store } from '@/store'; | ||||
| import { apiUrl } from '@/config'; | ||||
|  | @ -44,46 +44,81 @@ export function api(endpoint: string, data: Record<string, any> = {}, token?: st | |||
| 	return promise; | ||||
| } | ||||
| 
 | ||||
| export function popup(component: Component, props: Record<string, any>, callback?: Function) { | ||||
| export function popup(component: Component, props: Record<string, any>, callback?: Function, option?) { | ||||
| 	markRaw(component); | ||||
| 	const id = Math.random().toString(); // TODO: uuidとか使う
 | ||||
| 	const showing = ref(true); | ||||
| 	const popup = { | ||||
| 	const close = (...args) => { | ||||
| 		if (callback) callback(...args); | ||||
| 		showing.value = false; | ||||
| 	}; | ||||
| 	const modal = { | ||||
| 		type: 'popup', | ||||
| 		component, | ||||
| 		props: { | ||||
| 			...props, | ||||
| 			showing | ||||
| 		}, | ||||
| 		props, | ||||
| 		showing, | ||||
| 		done: (...args) => { | ||||
| 			if (callback) callback(...args); | ||||
| 			showing.value = false; | ||||
| 		}, | ||||
| 		source: option?.source, | ||||
| 		done: close, | ||||
| 		bgClick: () => close(), | ||||
| 		closed: () => { | ||||
| 			store.commit('removePopup', id); | ||||
| 		}, | ||||
| 		id, | ||||
| 	}; | ||||
| 	store.commit('addPopup', popup); | ||||
| 	return () => { | ||||
| 	store.commit('addPopup', modal); | ||||
| 	return close; | ||||
| } | ||||
| 
 | ||||
| export function modal(component: Component, props: Record<string, any>, callback?: Function, option?) { | ||||
| 	markRaw(component); | ||||
| 	const id = Math.random().toString(); // TODO: uuidとか使う
 | ||||
| 	const showing = ref(true); | ||||
| 	const close = (...args) => { | ||||
| 		if (callback) callback(...args); | ||||
| 		showing.value = false; | ||||
| 	}; | ||||
| 	const modal = { | ||||
| 		type: 'modal', | ||||
| 		component, | ||||
| 		props, | ||||
| 		showing, | ||||
| 		source: option?.source, | ||||
| 		done: close, | ||||
| 		bgClick: () => close(), | ||||
| 		closed: () => { | ||||
| 			store.commit('removePopup', id); | ||||
| 		}, | ||||
| 		id, | ||||
| 	}; | ||||
| 	store.commit('addPopup', modal); | ||||
| 	return close; | ||||
| } | ||||
| 
 | ||||
| export function dialog(props: Record<string, any>) { | ||||
| 	return new Promise((res, rej) => { | ||||
| 		popup(defineAsyncComponent(() => import('@/components/dialog.vue')), props, res); | ||||
| 		modal(defineAsyncComponent(() => import('@/components/dialog.vue')), props, result => { | ||||
| 			if (result) { | ||||
| 				res(result); | ||||
| 			} else { | ||||
| 				res({ canceled: true }); | ||||
| 			} | ||||
| 		}); | ||||
| 	}); | ||||
| } | ||||
| 
 | ||||
| export function menu(props: Record<string, any>) { | ||||
| 	const source = props.source; // TODO: sourceはpropsの外に出して追加の引数として受け取るようにする
 | ||||
| 	return new Promise((res, rej) => { | ||||
| 		popup(defineAsyncComponent(() => import('@/components/menu.vue')), props, res); | ||||
| 		modal(defineAsyncComponent(() => import('@/components/menu.vue')), props, res, { | ||||
| 			position: 'source', | ||||
| 			source | ||||
| 		}); | ||||
| 	}); | ||||
| } | ||||
| 
 | ||||
| export function post(props: Record<string, any>) { | ||||
| 	return new Promise((res, rej) => { | ||||
| 		popup(defineAsyncComponent(() => import('@/components/post-form-dialog.vue')), props, res); | ||||
| 		modal(defineAsyncComponent(() => import('@/components/post-form.vue')), props, res); | ||||
| 	}); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -54,13 +54,13 @@ export default defineComponent({ | |||
| 
 | ||||
| 	methods: { | ||||
| 		signin() { | ||||
| 			os.popup(XSigninDialog, { | ||||
| 			os.modal(XSigninDialog, { | ||||
| 				autoSet: true | ||||
| 			}); | ||||
| 		}, | ||||
| 
 | ||||
| 		signup() { | ||||
| 			os.popup(XSignupDialog, { | ||||
| 			os.modal(XSignupDialog, { | ||||
| 				autoSet: true | ||||
| 			}); | ||||
| 		} | ||||
|  |  | |||
|  | @ -125,7 +125,7 @@ export default defineComponent({ | |||
| 		}, | ||||
| 
 | ||||
| 		info(instance) { | ||||
| 			os.popup(MkInstanceInfo, { | ||||
| 			os.modal(MkInstanceInfo, { | ||||
| 				instance: instance | ||||
| 			}); | ||||
| 		} | ||||
|  |  | |||
|  | @ -550,7 +550,7 @@ export default defineComponent({ | |||
| 					host: q | ||||
| 				}); | ||||
| 			} | ||||
| 			os.popup(MkInstanceInfo, { | ||||
| 			os.modal(MkInstanceInfo, { | ||||
| 				instance: instance | ||||
| 			}); | ||||
| 		}, | ||||
|  |  | |||
|  | @ -439,7 +439,7 @@ export default defineComponent({ | |||
| 		}, | ||||
| 
 | ||||
| 		showFollowing() { | ||||
| 			os.popup(MkUsersDialog, { | ||||
| 			os.modal(MkUsersDialog, { | ||||
| 				title: this.$t('instanceFollowing'), | ||||
| 				pagination: { | ||||
| 					endpoint: 'federation/following', | ||||
|  | @ -453,7 +453,7 @@ export default defineComponent({ | |||
| 		}, | ||||
| 
 | ||||
| 		showFollowers() { | ||||
| 			os.popup(MkUsersDialog, { | ||||
| 			os.modal(MkUsersDialog, { | ||||
| 				title: this.$t('instanceFollowers'), | ||||
| 				pagination: { | ||||
| 					endpoint: 'federation/followers', | ||||
|  | @ -467,7 +467,7 @@ export default defineComponent({ | |||
| 		}, | ||||
| 
 | ||||
| 		showUsers() { | ||||
| 			os.popup(MkUsersDialog, { | ||||
| 			os.modal(MkUsersDialog, { | ||||
| 				title: this.$t('instanceUsers'), | ||||
| 				pagination: { | ||||
| 					endpoint: 'federation/users', | ||||
|  |  | |||
|  | @ -452,7 +452,7 @@ export default defineComponent({ | |||
| 		}, | ||||
| 
 | ||||
| 		addPinUser() { | ||||
| 			os.popup(MkUserSelect, {}).$once('selected', user => { | ||||
| 			os.modal(MkUserSelect, {}).$once('selected', user => { | ||||
| 				this.pinnedUsers = this.pinnedUsers.trim(); | ||||
| 				this.pinnedUsers += '\n@' + getAcct(user); | ||||
| 				this.pinnedUsers = this.pinnedUsers.trim(); | ||||
|  | @ -460,7 +460,7 @@ export default defineComponent({ | |||
| 		}, | ||||
| 
 | ||||
| 		chooseProxyAccount() { | ||||
| 			os.popup(MkUserSelect, {}).$once('selected', user => { | ||||
| 			os.modal(MkUserSelect, {}).$once('selected', user => { | ||||
| 				this.proxyAccount = user; | ||||
| 				this.proxyAccountId = user.id; | ||||
| 				this.save(true); | ||||
|  |  | |||
|  | @ -180,7 +180,7 @@ export default defineComponent({ | |||
| 		}, | ||||
| 
 | ||||
| 		searchUser() { | ||||
| 			os.popup(MkUserSelect, {}).$once('selected', user => { | ||||
| 			os.modal(MkUserSelect, {}).$once('selected', user => { | ||||
| 				this.show(user); | ||||
| 			}); | ||||
| 		}, | ||||
|  |  | |||
|  | @ -132,7 +132,7 @@ export default defineComponent({ | |||
| 		}, | ||||
| 
 | ||||
| 		async startUser() { | ||||
| 			os.popup(MkUserSelect, {}).$once('selected', user => { | ||||
| 			os.modal(MkUserSelect, {}).$once('selected', user => { | ||||
| 				this.$router.push(`/my/messaging/${getAcct(user)}`); | ||||
| 			}); | ||||
| 		}, | ||||
|  |  | |||
|  | @ -220,7 +220,7 @@ export default defineComponent({ | |||
| 		}, | ||||
| 
 | ||||
| 		async insertEmoji(ev) { | ||||
| 			const vm = os.popup(await import('@/components/emoji-picker.vue'), { | ||||
| 			const vm = os.modal(await import('@/components/emoji-picker.vue'), { | ||||
| 				source: ev.currentTarget || ev.target | ||||
| 			}).$once('chosen', emoji => { | ||||
| 				insertTextAtCursor(this.$refs.text, emoji); | ||||
|  |  | |||
|  | @ -177,7 +177,7 @@ export default defineComponent({ | |||
| 		}, | ||||
| 
 | ||||
| 		addUser() { | ||||
| 			os.popup(MkUserSelect, {}).$once('selected', user => { | ||||
| 			os.modal(MkUserSelect, {}).$once('selected', user => { | ||||
| 				this.users = this.users.trim(); | ||||
| 				this.users += '\n@' + getAcct(user); | ||||
| 				this.users = this.users.trim(); | ||||
|  |  | |||
|  | @ -89,7 +89,7 @@ export default defineComponent({ | |||
| 		}, | ||||
| 
 | ||||
| 		invite() { | ||||
| 			os.popup(MkUserSelect, {}).$once('selected', user => { | ||||
| 			os.modal(MkUserSelect, {}).$once('selected', user => { | ||||
| 				os.api('users/groups/invite', { | ||||
| 					groupId: this.group.id, | ||||
| 					userId: user.id | ||||
|  | @ -134,7 +134,7 @@ export default defineComponent({ | |||
| 		}, | ||||
| 
 | ||||
| 		transfer() { | ||||
| 			os.popup(MkUserSelect, {}).$once('selected', user => { | ||||
| 			os.modal(MkUserSelect, {}).$once('selected', user => { | ||||
| 				os.api('users/groups/transfer', { | ||||
| 					groupId: this.group.id, | ||||
| 					userId: user.id | ||||
|  |  | |||
|  | @ -88,7 +88,7 @@ export default defineComponent({ | |||
| 		}, | ||||
| 
 | ||||
| 		addUser() { | ||||
| 			os.popup(MkUserSelect, {}).$once('selected', user => { | ||||
| 			os.modal(MkUserSelect, {}).$once('selected', user => { | ||||
| 				os.api('users/lists/push', { | ||||
| 					listId: this.list.id, | ||||
| 					userId: user.id | ||||
|  |  | |||
|  | @ -26,7 +26,7 @@ export default defineComponent({ | |||
| 	}, | ||||
| 	methods: { | ||||
| 		async generateToken() { | ||||
| 			os.popup(await import('@/components/token-generate-window.vue'), { | ||||
| 			os.modal(await import('@/components/token-generate-window.vue'), { | ||||
| 			}).$on('ok', async ({ name, permissions }) => { | ||||
| 				const { token } = await os.api('miauth/gen-token', { | ||||
| 					session: null, | ||||
|  |  | |||
|  | @ -114,7 +114,7 @@ export default defineComponent({ | |||
| 		}, | ||||
| 
 | ||||
| 		async configure() { | ||||
| 			os.popup(await import('@/components/notification-setting-window.vue'), { | ||||
| 			os.modal(await import('@/components/notification-setting-window.vue'), { | ||||
| 				includingTypes: this.$store.state.i.includingNotificationTypes, | ||||
| 				showGlobalToggle: false, | ||||
| 			}).$on('ok', async ({ includingTypes: value }: any) => { | ||||
|  |  | |||
|  | @ -58,7 +58,7 @@ export default defineComponent({ | |||
| 		}, | ||||
| 
 | ||||
| 		preview(ev) { | ||||
| 			const picker = os.popup(MkReactionPicker, { | ||||
| 			const picker = os.modal(MkReactionPicker, { | ||||
| 				source: ev.currentTarget || ev.target, | ||||
| 				reactions: this.splited, | ||||
| 				showFocus: false, | ||||
|  | @ -73,7 +73,7 @@ export default defineComponent({ | |||
| 		}, | ||||
| 
 | ||||
| 		async chooseEmoji(ev) { | ||||
| 			const vm = os.popup(await import('@/components/emoji-picker.vue'), { | ||||
| 			const vm = os.modal(await import('@/components/emoji-picker.vue'), { | ||||
| 				source: ev.currentTarget || ev.target | ||||
| 			}).$once('chosen', emoji => { | ||||
| 				this.reactions += emoji; | ||||
|  |  | |||
|  | @ -118,7 +118,7 @@ export default defineComponent({ | |||
| 			} | ||||
| 
 | ||||
| 			const token = permissions == null || permissions.length === 0 ? null : await new Promise(async (res, rej) => { | ||||
| 				os.popup(await import('@/components/token-generate-window.vue'), { | ||||
| 				os.modal(await import('@/components/token-generate-window.vue'), { | ||||
| 					title: this.$t('tokenRequested'), | ||||
| 					information: this.$t('pluginTokenRequestedDescription'), | ||||
| 					initialName: name, | ||||
|  |  | |||
|  | @ -60,7 +60,7 @@ export default defineComponent({ | |||
| 			if (this.title) text += `【${this.title}】\n`; | ||||
| 			if (this.text) text += `${this.text}\n`; | ||||
| 			if (this.url) text += `${this.url}`; | ||||
| 			os.popup(PostFormDialog, { | ||||
| 			os.modal(PostFormDialog, { | ||||
| 				instant: true, | ||||
| 				initialText: text.trim() | ||||
| 			}).$once('posted', () => { | ||||
|  |  | |||
|  | @ -189,7 +189,7 @@ export default defineComponent({ | |||
| 		}, | ||||
| 
 | ||||
| 		menu() { | ||||
| 			os.popup(XUserMenu, { | ||||
| 			os.modal(XUserMenu, { | ||||
| 				source: this.$refs.menu, | ||||
| 				user: this.user | ||||
| 			}); | ||||
|  |  | |||
|  | @ -2,13 +2,17 @@ | |||
| <DeckUI v-if="deckmode"/> | ||||
| <DefaultUI v-else/> | ||||
| 
 | ||||
| <component v-for="popup in $store.state.popups" :is="popup.component" v-bind="popup.props" :key="popup.id" @done="popup.done" @closed="popup.closed"/> | ||||
| <XModal v-for="modal in $store.state.popups.filter(x => x.type === 'modal')" :key="modal.id" @closed="modal.closed" @click="modal.bgClick" :showing="modal.showing" :source="modal.source"> | ||||
| 	<component :is="modal.component" v-bind="modal.props" @done="modal.done"/> | ||||
| </XModal> | ||||
| 
 | ||||
| <component v-for="popup in $store.state.popups.filter(x => x.type === 'popup')" :key="popup.id" :is="popup.component" v-bind="popup.props" @done="popup.done" @closed="popup.closed"/> | ||||
| 
 | ||||
| <div id="wait" v-if="$store.state.pendingApiRequestsCount > 0"></div> | ||||
| </template> | ||||
| 
 | ||||
| <script lang="ts"> | ||||
| import { defineComponent } from 'vue'; | ||||
| import { defineAsyncComponent, defineComponent } from 'vue'; | ||||
| import DefaultUI from './default.vue'; | ||||
| import DeckUI from './deck.vue'; | ||||
| import { instanceName, deckmode } from '@/config'; | ||||
|  | @ -17,6 +21,7 @@ export default defineComponent({ | |||
| 	components: { | ||||
| 		DefaultUI, | ||||
| 		DeckUI, | ||||
| 		XModal: defineAsyncComponent(() => import('@/components/modal.vue')) | ||||
| 	}, | ||||
| 
 | ||||
| 	metaInfo: { | ||||
|  |  | |||
|  | @ -111,6 +111,7 @@ export const store = createStore({ | |||
| 		popups: [] as { | ||||
| 			id: any; | ||||
| 			component: any; | ||||
| 			type: 'popup' | 'modal', | ||||
| 			props: Record<string, any>; | ||||
| 		}[], | ||||
| 		fullView: false, | ||||
|  |  | |||
|  | @ -51,7 +51,7 @@ export default defineComponent({ | |||
| 
 | ||||
| 	methods: { | ||||
| 		async configure() { | ||||
| 			os.popup(await import('@/components/notification-setting-window.vue'), { | ||||
| 			os.modal(await import('@/components/notification-setting-window.vue'), { | ||||
| 				includingTypes: this.props.includingTypes, | ||||
| 			}).$on('ok', async ({ includingTypes }) => { | ||||
| 				this.props.includingTypes = includingTypes; | ||||
|  |  | |||
|  | @ -52,13 +52,13 @@ export default defineComponent({ | |||
| 
 | ||||
| 	methods: { | ||||
| 		signin() { | ||||
| 			os.popup(XSigninDialog, { | ||||
| 			os.modal(XSigninDialog, { | ||||
| 				autoSet: true | ||||
| 			}); | ||||
| 		}, | ||||
| 
 | ||||
| 		signup() { | ||||
| 			os.popup(XSignupDialog, { | ||||
| 			os.modal(XSignupDialog, { | ||||
| 				autoSet: true | ||||
| 			}); | ||||
| 		} | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue