Tweak UI
This commit is contained in:
		
							parent
							
								
									c22ff4c556
								
							
						
					
					
						commit
						a88e486468
					
				
					 9 changed files with 312 additions and 61 deletions
				
			
		|  | @ -20,12 +20,16 @@ export default defineComponent({ | ||||||
| 
 | 
 | ||||||
| <style lang="scss" scoped> | <style lang="scss" scoped> | ||||||
| .rbusrurv { | .rbusrurv { | ||||||
|  | 	// 他のCSSからも参照されるので消さないように | ||||||
|  | 	--formXPadding: 32px; | ||||||
|  | 	--formYPadding: 32px; | ||||||
|  | 
 | ||||||
| 	line-height: 1.4em; | 	line-height: 1.4em; | ||||||
| 	background: var(--bg); | 	background: var(--bg); | ||||||
| 	padding: 32px; | 	padding: var(--formYPadding) var(--formXPadding); | ||||||
| 
 | 
 | ||||||
| 	&:not(.wide).max-width_400px { | 	&:not(.wide).max-width_400px { | ||||||
| 		padding: 32px 0; | 		--formXPadding: 0px; | ||||||
| 
 | 
 | ||||||
| 		> ::v-deep(*) { | 		> ::v-deep(*) { | ||||||
| 			._formPanel { | 			._formPanel { | ||||||
|  |  | ||||||
|  | @ -10,9 +10,17 @@ | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ._formLabel { | ._formLabel { | ||||||
|  | 	position: sticky; | ||||||
|  | 	top: var(--stickyTop, 0px); | ||||||
|  | 	background: var(--bg); | ||||||
|  | 	z-index: 2; | ||||||
| 	font-size: 80%; | 	font-size: 80%; | ||||||
| 	padding: 0 16px 8px 16px; | 	margin: -8px calc(var(--formXPadding) * -1) 0 calc(var(--formXPadding) * -1); | ||||||
| 	opacity: 0.8; | 	padding: 8px calc(16px + var(--formXPadding)) 8px calc(16px + var(--formXPadding)); | ||||||
|  | 	color: var(--fgTransparentWeak); | ||||||
|  | 	background: var(--X17); | ||||||
|  | 	-webkit-backdrop-filter: blur(10px); | ||||||
|  | 	backdrop-filter: blur(10px); | ||||||
| 
 | 
 | ||||||
| 	&:empty { | 	&:empty { | ||||||
| 		display: none; | 		display: none; | ||||||
|  |  | ||||||
|  | @ -93,6 +93,10 @@ export default defineComponent({ | ||||||
| 			os.pageWindow(this.to); | 			os.pageWindow(this.to); | ||||||
| 		}, | 		}, | ||||||
| 
 | 
 | ||||||
|  | 		modalWindow() { | ||||||
|  | 			os.modalPageWindow(this.to); | ||||||
|  | 		}, | ||||||
|  | 
 | ||||||
| 		popout() { | 		popout() { | ||||||
| 			popout(this.to); | 			popout(this.to); | ||||||
| 		}, | 		}, | ||||||
|  | @ -111,6 +115,8 @@ export default defineComponent({ | ||||||
| 			if (this.behavior) { | 			if (this.behavior) { | ||||||
| 				if (this.behavior === 'window') { | 				if (this.behavior === 'window') { | ||||||
| 					return this.window(); | 					return this.window(); | ||||||
|  | 				} else if (this.behavior === 'modalWindow') { | ||||||
|  | 					return this.modalWindow(); | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										211
									
								
								src/client/components/modal-page-window.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										211
									
								
								src/client/components/modal-page-window.vue
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,211 @@ | ||||||
|  | <template> | ||||||
|  | <MkModal ref="modal" @click="$emit('click')" @closed="$emit('closed')"> | ||||||
|  | 	<div class="hrmcaedk _popup _narrow_" :style="{ width: `${width}px`, height: (height ? `min(${height}px, 100%)` : '100%') }"> | ||||||
|  | 		<div class="header"> | ||||||
|  | 			<button class="_button" @click="back()" v-if="history.length > 0"><Fa :icon="faChevronLeft"/></button> | ||||||
|  | 			<button class="_button" style="pointer-events: none;" v-else><!-- マージンのバランスを取るためのダミー --></button> | ||||||
|  | 			<span class="title"> | ||||||
|  | 				<XHeader :info="pageInfo" :with-back="false"/> | ||||||
|  | 			</span> | ||||||
|  | 			<button class="_button" @click="$refs.modal.close()"><Fa :icon="faTimes"/></button> | ||||||
|  | 		</div> | ||||||
|  | 		<div class="body _flat_"> | ||||||
|  | 			<component :is="component" v-bind="props" :ref="changePage"/> | ||||||
|  | 		</div> | ||||||
|  | 	</div> | ||||||
|  | </MkModal> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <script lang="ts"> | ||||||
|  | import { defineComponent } from 'vue'; | ||||||
|  | import { faExternalLinkAlt, faExpandAlt, faLink, faChevronLeft, faColumns, faTimes } from '@fortawesome/free-solid-svg-icons'; | ||||||
|  | import MkModal from '@client/components/ui/modal.vue'; | ||||||
|  | import XHeader from '@client/ui/_common_/header.vue'; | ||||||
|  | import { popout } from '@client/scripts/popout'; | ||||||
|  | import copyToClipboard from '@client/scripts/copy-to-clipboard'; | ||||||
|  | import { resolve } from '@client/router'; | ||||||
|  | import { url } from '@client/config'; | ||||||
|  | import * as symbols from '@client/symbols'; | ||||||
|  | 
 | ||||||
|  | export default defineComponent({ | ||||||
|  | 	components: { | ||||||
|  | 		MkModal, | ||||||
|  | 		XHeader, | ||||||
|  | 	}, | ||||||
|  | 
 | ||||||
|  | 	inject: { | ||||||
|  | 		sideViewHook: { | ||||||
|  | 			default: null | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 
 | ||||||
|  | 	provide() { | ||||||
|  | 		return { | ||||||
|  | 			navHook: (path) => { | ||||||
|  | 				this.navigate(path); | ||||||
|  | 			} | ||||||
|  | 		}; | ||||||
|  | 	}, | ||||||
|  | 
 | ||||||
|  | 	props: { | ||||||
|  | 		initialPath: { | ||||||
|  | 			type: String, | ||||||
|  | 			required: true, | ||||||
|  | 		}, | ||||||
|  | 		initialComponent: { | ||||||
|  | 			type: Object, | ||||||
|  | 			required: true, | ||||||
|  | 		}, | ||||||
|  | 		initialProps: { | ||||||
|  | 			type: Object, | ||||||
|  | 			required: false, | ||||||
|  | 			default: () => {}, | ||||||
|  | 		}, | ||||||
|  | 	}, | ||||||
|  | 
 | ||||||
|  | 	emits: ['closed'], | ||||||
|  | 
 | ||||||
|  | 	data() { | ||||||
|  | 		return { | ||||||
|  | 			width: 850, | ||||||
|  | 			height: 650, | ||||||
|  | 			pageInfo: null, | ||||||
|  | 			path: this.initialPath, | ||||||
|  | 			component: this.initialComponent, | ||||||
|  | 			props: this.initialProps, | ||||||
|  | 			history: [], | ||||||
|  | 			faChevronLeft, faTimes, | ||||||
|  | 		}; | ||||||
|  | 	}, | ||||||
|  | 
 | ||||||
|  | 	computed: { | ||||||
|  | 		url(): string { | ||||||
|  | 			return url + this.path; | ||||||
|  | 		}, | ||||||
|  | 
 | ||||||
|  | 		contextmenu() { | ||||||
|  | 			return [{ | ||||||
|  | 				type: 'label', | ||||||
|  | 				text: this.path, | ||||||
|  | 			}, { | ||||||
|  | 				icon: faExpandAlt, | ||||||
|  | 				text: this.$ts.showInPage, | ||||||
|  | 				action: this.expand | ||||||
|  | 			}, this.sideViewHook ? { | ||||||
|  | 				icon: faColumns, | ||||||
|  | 				text: this.$ts.openInSideView, | ||||||
|  | 				action: () => { | ||||||
|  | 					this.sideViewHook(this.path); | ||||||
|  | 					this.$refs.window.close(); | ||||||
|  | 				} | ||||||
|  | 			} : undefined, { | ||||||
|  | 				icon: faExternalLinkAlt, | ||||||
|  | 				text: this.$ts.popout, | ||||||
|  | 				action: this.popout | ||||||
|  | 			}, null, { | ||||||
|  | 				icon: faExternalLinkAlt, | ||||||
|  | 				text: this.$ts.openInNewTab, | ||||||
|  | 				action: () => { | ||||||
|  | 					window.open(this.url, '_blank'); | ||||||
|  | 					this.$refs.window.close(); | ||||||
|  | 				} | ||||||
|  | 			}, { | ||||||
|  | 				icon: faLink, | ||||||
|  | 				text: this.$ts.copyLink, | ||||||
|  | 				action: () => { | ||||||
|  | 					copyToClipboard(this.url); | ||||||
|  | 				} | ||||||
|  | 			}]; | ||||||
|  | 		}, | ||||||
|  | 	}, | ||||||
|  | 
 | ||||||
|  | 	methods: { | ||||||
|  | 		changePage(page) { | ||||||
|  | 			if (page == null) return; | ||||||
|  | 			if (page[symbols.PAGE_INFO]) { | ||||||
|  | 				this.pageInfo = page[symbols.PAGE_INFO]; | ||||||
|  | 			} | ||||||
|  | 		}, | ||||||
|  | 
 | ||||||
|  | 		navigate(path, record = true) { | ||||||
|  | 			if (record) this.history.push(this.path); | ||||||
|  | 			this.path = path; | ||||||
|  | 			const { component, props } = resolve(path); | ||||||
|  | 			this.component = component; | ||||||
|  | 			this.props = props; | ||||||
|  | 		}, | ||||||
|  | 
 | ||||||
|  | 		back() { | ||||||
|  | 			this.navigate(this.history.pop(), false); | ||||||
|  | 		}, | ||||||
|  | 
 | ||||||
|  | 		expand() { | ||||||
|  | 			this.$router.push(this.path); | ||||||
|  | 			this.$refs.window.close(); | ||||||
|  | 		}, | ||||||
|  | 
 | ||||||
|  | 		popout() { | ||||||
|  | 			popout(this.path, this.$el); | ||||||
|  | 			this.$refs.window.close(); | ||||||
|  | 		}, | ||||||
|  | 	}, | ||||||
|  | }); | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <style lang="scss" scoped> | ||||||
|  | .hrmcaedk { | ||||||
|  | 	overflow: hidden; | ||||||
|  | 	display: flex; | ||||||
|  | 	flex-direction: column; | ||||||
|  | 	contain: content; | ||||||
|  | 
 | ||||||
|  | 	--root-margin: 24px; | ||||||
|  | 
 | ||||||
|  | 	@media (max-width: 500px) { | ||||||
|  | 		--root-margin: 16px; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	> .header { | ||||||
|  | 		$height: 54px; | ||||||
|  | 		$height-narrow: 42px; | ||||||
|  | 		display: flex; | ||||||
|  | 		flex-shrink: 0; | ||||||
|  | 		box-shadow: 0px 1px var(--divider); | ||||||
|  | 
 | ||||||
|  | 		> button { | ||||||
|  | 			height: $height; | ||||||
|  | 			width: $height; | ||||||
|  | 
 | ||||||
|  | 			@media (max-width: 500px) { | ||||||
|  | 				height: $height-narrow; | ||||||
|  | 				width: $height-narrow; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		> .title { | ||||||
|  | 			flex: 1; | ||||||
|  | 			line-height: $height; | ||||||
|  | 			padding-left: 32px; | ||||||
|  | 			font-weight: bold; | ||||||
|  | 			white-space: nowrap; | ||||||
|  | 			overflow: hidden; | ||||||
|  | 			text-overflow: ellipsis; | ||||||
|  | 			pointer-events: none; | ||||||
|  | 
 | ||||||
|  | 			@media (max-width: 500px) { | ||||||
|  | 				line-height: $height-narrow; | ||||||
|  | 				padding-left: 16px; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		> button + .title { | ||||||
|  | 			padding-left: 0; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	> .body { | ||||||
|  | 		overflow: auto; | ||||||
|  | 		background: var(--bg); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | </style> | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| <template> | <template> | ||||||
| <MkModal ref="modal" @click="$emit('click')" @closed="$emit('closed')"> | <MkModal ref="modal" @click="$emit('click')" @closed="$emit('closed')"> | ||||||
| 	<div class="ebkgoccj _popup _narrow_" @keydown="onKeydown" :style="{ width: `${width}px`, height: height ? `${height}px` : null }"> | 	<div class="ebkgoccj _popup _narrow_" @keydown="onKeydown" :style="{ width: `${width}px`, height: scroll ? (height ? `${height}px` : null) :  (height ? `min(${height}px, 100%)` : '100%') }"> | ||||||
| 		<div class="header"> | 		<div class="header"> | ||||||
| 			<button class="_button" v-if="withOkButton" @click="$emit('close')"><Fa :icon="faTimes"/></button> | 			<button class="_button" v-if="withOkButton" @click="$emit('close')"><Fa :icon="faTimes"/></button> | ||||||
| 			<span class="title"> | 			<span class="title"> | ||||||
|  | @ -61,6 +61,11 @@ export default defineComponent({ | ||||||
| 			required: false, | 			required: false, | ||||||
| 			default: true, | 			default: true, | ||||||
| 		}, | 		}, | ||||||
|  | 		scroll: { | ||||||
|  | 			type: Boolean, | ||||||
|  | 			required: false, | ||||||
|  | 			default: true, | ||||||
|  | 		}, | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
| 	emits: ['click', 'close', 'closed', 'ok'], | 	emits: ['click', 'close', 'closed', 'ok'], | ||||||
|  |  | ||||||
|  | @ -203,6 +203,15 @@ export function pageWindow(path: string) { | ||||||
| 	}, {}, 'closed'); | 	}, {}, 'closed'); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | export function modalPageWindow(path: string) { | ||||||
|  | 	const { component, props } = resolve(path); | ||||||
|  | 	popup(import('@client/components/modal-page-window.vue'), { | ||||||
|  | 		initialPath: path, | ||||||
|  | 		initialComponent: markRaw(component), | ||||||
|  | 		initialProps: props, | ||||||
|  | 	}, {}, 'closed'); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| export function dialog(props: Record<string, any>) { | export function dialog(props: Record<string, any>) { | ||||||
| 	return new Promise((resolve, reject) => { | 	return new Promise((resolve, reject) => { | ||||||
| 		popup(import('@client/components/dialog.vue'), props, { | 		popup(import('@client/components/dialog.vue'), props, { | ||||||
|  |  | ||||||
|  | @ -1,40 +1,42 @@ | ||||||
| <template> | <template> | ||||||
| <div class="vvcocwet" :class="{ wide: !narrow }" ref="el"> | <div class="vvcocwet" :class="{ wide: !narrow }" ref="el"> | ||||||
| 	<FormBase class="nav" v-if="!narrow || page == null" :force-wide="!narrow"> | 	<div class="nav" v-if="!narrow || page == null"> | ||||||
| 		<FormGroup> | 		<FormBase> | ||||||
| 			<template #label>{{ $ts.basicSettings }}</template> | 			<FormGroup> | ||||||
| 			<FormLink :active="page === 'profile'" replace to="/settings/profile"><template #icon><Fa :icon="faUser"/></template>{{ $ts.profile }}</FormLink> | 				<template #label>{{ $ts.basicSettings }}</template> | ||||||
| 			<FormLink :active="page === 'privacy'" replace to="/settings/privacy"><template #icon><Fa :icon="faLockOpen"/></template>{{ $ts.privacy }}</FormLink> | 				<FormLink :active="page === 'profile'" replace to="/settings/profile"><template #icon><Fa :icon="faUser"/></template>{{ $ts.profile }}</FormLink> | ||||||
| 			<FormLink :active="page === 'reaction'" replace to="/settings/reaction"><template #icon><Fa :icon="faLaugh"/></template>{{ $ts.reaction }}</FormLink> | 				<FormLink :active="page === 'privacy'" replace to="/settings/privacy"><template #icon><Fa :icon="faLockOpen"/></template>{{ $ts.privacy }}</FormLink> | ||||||
| 			<FormLink :active="page === 'drive'" replace to="/settings/drive"><template #icon><Fa :icon="faCloud"/></template>{{ $ts.drive }}</FormLink> | 				<FormLink :active="page === 'reaction'" replace to="/settings/reaction"><template #icon><Fa :icon="faLaugh"/></template>{{ $ts.reaction }}</FormLink> | ||||||
| 			<FormLink :active="page === 'notifications'" replace to="/settings/notifications"><template #icon><Fa :icon="faBell"/></template>{{ $ts.notifications }}</FormLink> | 				<FormLink :active="page === 'drive'" replace to="/settings/drive"><template #icon><Fa :icon="faCloud"/></template>{{ $ts.drive }}</FormLink> | ||||||
| 			<FormLink :active="page === 'email'" replace to="/settings/email"><template #icon><Fa :icon="faEnvelope"/></template>{{ $ts.email }}</FormLink> | 				<FormLink :active="page === 'notifications'" replace to="/settings/notifications"><template #icon><Fa :icon="faBell"/></template>{{ $ts.notifications }}</FormLink> | ||||||
| 			<FormLink :active="page === 'integration'" replace to="/settings/integration"><template #icon><Fa :icon="faShareAlt"/></template>{{ $ts.integration }}</FormLink> | 				<FormLink :active="page === 'email'" replace to="/settings/email"><template #icon><Fa :icon="faEnvelope"/></template>{{ $ts.email }}</FormLink> | ||||||
| 			<FormLink :active="page === 'security'" replace to="/settings/security"><template #icon><Fa :icon="faLock"/></template>{{ $ts.security }}</FormLink> | 				<FormLink :active="page === 'integration'" replace to="/settings/integration"><template #icon><Fa :icon="faShareAlt"/></template>{{ $ts.integration }}</FormLink> | ||||||
| 		</FormGroup> | 				<FormLink :active="page === 'security'" replace to="/settings/security"><template #icon><Fa :icon="faLock"/></template>{{ $ts.security }}</FormLink> | ||||||
| 		<FormGroup> | 			</FormGroup> | ||||||
| 			<template #label>{{ $ts.clientSettings }}</template> | 			<FormGroup> | ||||||
| 			<FormLink :active="page === 'general'" replace to="/settings/general"><template #icon><Fa :icon="faCogs"/></template>{{ $ts.general }}</FormLink> | 				<template #label>{{ $ts.clientSettings }}</template> | ||||||
| 			<FormLink :active="page === 'theme'" replace to="/settings/theme"><template #icon><Fa :icon="faPalette"/></template>{{ $ts.theme }}</FormLink> | 				<FormLink :active="page === 'general'" replace to="/settings/general"><template #icon><Fa :icon="faCogs"/></template>{{ $ts.general }}</FormLink> | ||||||
| 			<FormLink :active="page === 'sidebar'" replace to="/settings/sidebar"><template #icon><Fa :icon="faListUl"/></template>{{ $ts.sidebar }}</FormLink> | 				<FormLink :active="page === 'theme'" replace to="/settings/theme"><template #icon><Fa :icon="faPalette"/></template>{{ $ts.theme }}</FormLink> | ||||||
| 			<FormLink :active="page === 'sounds'" replace to="/settings/sounds"><template #icon><Fa :icon="faMusic"/></template>{{ $ts.sounds }}</FormLink> | 				<FormLink :active="page === 'sidebar'" replace to="/settings/sidebar"><template #icon><Fa :icon="faListUl"/></template>{{ $ts.sidebar }}</FormLink> | ||||||
| 			<FormLink :active="page === 'plugin'" replace to="/settings/plugin"><template #icon><Fa :icon="faPlug"/></template>{{ $ts.plugins }}</FormLink> | 				<FormLink :active="page === 'sounds'" replace to="/settings/sounds"><template #icon><Fa :icon="faMusic"/></template>{{ $ts.sounds }}</FormLink> | ||||||
| 		</FormGroup> | 				<FormLink :active="page === 'plugin'" replace to="/settings/plugin"><template #icon><Fa :icon="faPlug"/></template>{{ $ts.plugins }}</FormLink> | ||||||
| 		<FormGroup> | 			</FormGroup> | ||||||
| 			<template #label>{{ $ts.otherSettings }}</template> | 			<FormGroup> | ||||||
| 			<FormLink :active="page === 'import-export'" replace to="/settings/import-export"><template #icon><Fa :icon="faBoxes"/></template>{{ $ts.importAndExport }}</FormLink> | 				<template #label>{{ $ts.otherSettings }}</template> | ||||||
| 			<FormLink :active="page === 'mute-block'" replace to="/settings/mute-block"><template #icon><Fa :icon="faBan"/></template>{{ $ts.muteAndBlock }}</FormLink> | 				<FormLink :active="page === 'import-export'" replace to="/settings/import-export"><template #icon><Fa :icon="faBoxes"/></template>{{ $ts.importAndExport }}</FormLink> | ||||||
| 			<FormLink :active="page === 'word-mute'" replace to="/settings/word-mute"><template #icon><Fa :icon="faCommentSlash"/></template>{{ $ts.wordMute }}</FormLink> | 				<FormLink :active="page === 'mute-block'" replace to="/settings/mute-block"><template #icon><Fa :icon="faBan"/></template>{{ $ts.muteAndBlock }}</FormLink> | ||||||
| 			<FormLink :active="page === 'api'" replace to="/settings/api"><template #icon><Fa :icon="faKey"/></template>API</FormLink> | 				<FormLink :active="page === 'word-mute'" replace to="/settings/word-mute"><template #icon><Fa :icon="faCommentSlash"/></template>{{ $ts.wordMute }}</FormLink> | ||||||
| 			<FormLink :active="page === 'other'" replace to="/settings/other"><template #icon><Fa :icon="faEllipsisH"/></template>{{ $ts.other }}</FormLink> | 				<FormLink :active="page === 'api'" replace to="/settings/api"><template #icon><Fa :icon="faKey"/></template>API</FormLink> | ||||||
| 		</FormGroup> | 				<FormLink :active="page === 'other'" replace to="/settings/other"><template #icon><Fa :icon="faEllipsisH"/></template>{{ $ts.other }}</FormLink> | ||||||
| 		<FormGroup> | 			</FormGroup> | ||||||
| 			<FormButton @click="clear">{{ $ts.clearCache }}</FormButton> | 			<FormGroup> | ||||||
| 		</FormGroup> | 				<FormButton @click="clear">{{ $ts.clearCache }}</FormButton> | ||||||
| 		<FormGroup> | 			</FormGroup> | ||||||
| 			<FormButton @click="logout" danger>{{ $ts.logout }}</FormButton> | 			<FormGroup> | ||||||
| 		</FormGroup> | 				<FormButton @click="logout" danger>{{ $ts.logout }}</FormButton> | ||||||
| 	</FormBase> | 			</FormGroup> | ||||||
|  | 		</FormBase> | ||||||
|  | 	</div> | ||||||
| 	<div class="main"> | 	<div class="main"> | ||||||
| 		<component :is="component" :key="page" @info="onInfo" v-bind="pageProps"/> | 		<component :is="component" :key="page" @info="onInfo" v-bind="pageProps"/> | ||||||
| 	</div> | 	</div> | ||||||
|  | @ -64,7 +66,7 @@ export default defineComponent({ | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
| 	props: { | 	props: { | ||||||
| 		page: { | 		initialPage: { | ||||||
| 			type: String, | 			type: String, | ||||||
| 			required: false | 			required: false | ||||||
| 		} | 		} | ||||||
|  | @ -75,6 +77,7 @@ export default defineComponent({ | ||||||
| 			title: i18n.locale.settings, | 			title: i18n.locale.settings, | ||||||
| 			icon: faCog | 			icon: faCog | ||||||
| 		}); | 		}); | ||||||
|  | 		const page = ref(props.initialPage); | ||||||
| 		const narrow = ref(false); | 		const narrow = ref(false); | ||||||
| 		const view = ref(null); | 		const view = ref(null); | ||||||
| 		const el = ref(null); | 		const el = ref(null); | ||||||
|  | @ -83,8 +86,8 @@ export default defineComponent({ | ||||||
| 		}; | 		}; | ||||||
| 		const pageProps = ref({}); | 		const pageProps = ref({}); | ||||||
| 		const component = computed(() => { | 		const component = computed(() => { | ||||||
| 			if (props.page == null) return null; | 			if (page.value == null) return null; | ||||||
| 			switch (props.page) { | 			switch (page.value) { | ||||||
| 				case 'profile': return defineAsyncComponent(() => import('./profile.vue')); | 				case 'profile': return defineAsyncComponent(() => import('./profile.vue')); | ||||||
| 				case 'privacy': return defineAsyncComponent(() => import('./privacy.vue')); | 				case 'privacy': return defineAsyncComponent(() => import('./privacy.vue')); | ||||||
| 				case 'reaction': return defineAsyncComponent(() => import('./reaction.vue')); | 				case 'reaction': return defineAsyncComponent(() => import('./reaction.vue')); | ||||||
|  | @ -117,10 +120,10 @@ export default defineComponent({ | ||||||
| 				case 'registry': return defineAsyncComponent(() => import('./registry.vue')); | 				case 'registry': return defineAsyncComponent(() => import('./registry.vue')); | ||||||
| 				case 'experimental-features': return defineAsyncComponent(() => import('./experimental-features.vue')); | 				case 'experimental-features': return defineAsyncComponent(() => import('./experimental-features.vue')); | ||||||
| 			} | 			} | ||||||
| 			if (props.page.startsWith('registry/keys/system/')) { | 			if (page.value.startsWith('registry/keys/system/')) { | ||||||
| 				return defineAsyncComponent(() => import('./registry.keys.vue')); | 				return defineAsyncComponent(() => import('./registry.keys.vue')); | ||||||
| 			} | 			} | ||||||
| 			if (props.page.startsWith('registry/value/system/')) { | 			if (page.value.startsWith('registry/value/system/')) { | ||||||
| 				return defineAsyncComponent(() => import('./registry.value.vue')); | 				return defineAsyncComponent(() => import('./registry.value.vue')); | ||||||
| 			} | 			} | ||||||
| 		}); | 		}); | ||||||
|  | @ -128,12 +131,12 @@ export default defineComponent({ | ||||||
| 		watch(component, () => { | 		watch(component, () => { | ||||||
| 			pageProps.value = {}; | 			pageProps.value = {}; | ||||||
| 
 | 
 | ||||||
| 			if (props.page) { | 			if (page.value) { | ||||||
| 				if (props.page.startsWith('registry/keys/system/')) { | 				if (page.value.startsWith('registry/keys/system/')) { | ||||||
| 					pageProps.value.scope = props.page.replace('registry/keys/system/', '').split('/'); | 					pageProps.value.scope = page.value.replace('registry/keys/system/', '').split('/'); | ||||||
| 				} | 				} | ||||||
| 				if (props.page.startsWith('registry/value/system/')) { | 				if (page.value.startsWith('registry/value/system/')) { | ||||||
| 					const path = props.page.replace('registry/value/system/', '').split('/'); | 					const path = page.value.replace('registry/value/system/', '').split('/'); | ||||||
| 					pageProps.value.xKey = path.pop(); | 					pageProps.value.xKey = path.pop(); | ||||||
| 					pageProps.value.scope = path; | 					pageProps.value.scope = path; | ||||||
| 				} | 				} | ||||||
|  | @ -144,12 +147,20 @@ export default defineComponent({ | ||||||
| 			}); | 			}); | ||||||
| 		}, { immediate: true }); | 		}, { immediate: true }); | ||||||
| 
 | 
 | ||||||
|  | 		watch(() => props.initialPage, () => { | ||||||
|  | 			page.value = props.initialPage; | ||||||
|  | 		}); | ||||||
|  | 
 | ||||||
| 		onMounted(() => { | 		onMounted(() => { | ||||||
| 			narrow.value = el.value.offsetWidth < 1025; | 			narrow.value = el.value.offsetWidth < 800; | ||||||
|  | 			if (!narrow.value) { | ||||||
|  | 				page.value = 'profile'; | ||||||
|  | 			} | ||||||
| 		}); | 		}); | ||||||
| 
 | 
 | ||||||
| 		return { | 		return { | ||||||
| 			[symbols.PAGE_INFO]: INFO, | 			[symbols.PAGE_INFO]: INFO, | ||||||
|  | 			page, | ||||||
| 			narrow, | 			narrow, | ||||||
| 			view, | 			view, | ||||||
| 			el, | 			el, | ||||||
|  | @ -176,25 +187,20 @@ export default defineComponent({ | ||||||
| 		display: flex; | 		display: flex; | ||||||
| 		max-width: 1100px; | 		max-width: 1100px; | ||||||
| 		margin: 0 auto; | 		margin: 0 auto; | ||||||
|  | 		height: 100%; | ||||||
| 
 | 
 | ||||||
| 		> .nav { | 		> .nav { | ||||||
| 			width: 32%; | 			width: 32%; | ||||||
| 			box-sizing: border-box; | 			box-sizing: border-box; | ||||||
| 			border-right: solid 0.5px var(--divider); | 			border-right: solid 0.5px var(--divider); | ||||||
|  | 			overflow: auto; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		> .main { | 		> .main { | ||||||
| 			flex: 1; | 			flex: 1; | ||||||
| 			min-width: 0; | 			min-width: 0; | ||||||
|  | 			overflow: auto; | ||||||
| 			--baseContentWidth: 100%; | 			--baseContentWidth: 100%; | ||||||
| 
 |  | ||||||
| 			::v-deep(._section) { |  | ||||||
| 				padding: 0 0 32px 0; |  | ||||||
| 
 |  | ||||||
| 				& + ._section { |  | ||||||
| 					padding-top: 32px; |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -22,7 +22,7 @@ export const router = createRouter({ | ||||||
| 		{ path: '/@:user/pages/:page', component: page('page'), props: route => ({ pageName: route.params.page, username: route.params.user }) }, | 		{ path: '/@:user/pages/:page', component: page('page'), props: route => ({ pageName: route.params.page, username: route.params.user }) }, | ||||||
| 		{ path: '/@:user/pages/:pageName/view-source', component: page('page-editor/page-editor'), props: route => ({ initUser: route.params.user, initPageName: route.params.pageName }) }, | 		{ path: '/@:user/pages/:pageName/view-source', component: page('page-editor/page-editor'), props: route => ({ initUser: route.params.user, initPageName: route.params.pageName }) }, | ||||||
| 		{ path: '/@:acct/room', props: true, component: page('room/room') }, | 		{ path: '/@:acct/room', props: true, component: page('room/room') }, | ||||||
| 		{ path: '/settings/:page(.*)?', name: 'settings', component: page('settings/index'), props: route => ({ page: route.params.page || null }) }, | 		{ path: '/settings/:page(.*)?', name: 'settings', component: page('settings/index'), props: route => ({ initialPage: route.params.page || null }) }, | ||||||
| 		{ path: '/announcements', component: page('announcements') }, | 		{ path: '/announcements', component: page('announcements') }, | ||||||
| 		{ path: '/about', component: page('about') }, | 		{ path: '/about', component: page('about') }, | ||||||
| 		{ path: '/about-misskey', component: page('about-misskey') }, | 		{ path: '/about-misskey', component: page('about-misskey') }, | ||||||
|  |  | ||||||
|  | @ -27,7 +27,7 @@ | ||||||
| 		<Fa :icon="faEllipsisH" fixed-width/><span class="text">{{ $ts.more }}</span> | 		<Fa :icon="faEllipsisH" fixed-width/><span class="text">{{ $ts.more }}</span> | ||||||
| 		<i v-if="otherNavItemIndicated"><Fa :icon="faCircle"/></i> | 		<i v-if="otherNavItemIndicated"><Fa :icon="faCircle"/></i> | ||||||
| 	</button> | 	</button> | ||||||
| 	<MkA class="item" active-class="active" to="/settings"> | 	<MkA class="item" active-class="active" to="/settings" :behavior="settingsWindowed ? 'modalWindow' : null"> | ||||||
| 		<Fa :icon="faCog" fixed-width/><span class="text">{{ $ts.settings }}</span> | 		<Fa :icon="faCog" fixed-width/><span class="text">{{ $ts.settings }}</span> | ||||||
| 	</MkA> | 	</MkA> | ||||||
| </div> | </div> | ||||||
|  | @ -57,6 +57,7 @@ export default defineComponent({ | ||||||
| 			connection: null, | 			connection: null, | ||||||
| 			menuDef: sidebarDef, | 			menuDef: sidebarDef, | ||||||
| 			iconOnly: false, | 			iconOnly: false, | ||||||
|  | 			settingsWindowed: false, | ||||||
| 			faGripVertical, faChevronLeft, faComments, faHashtag, faBroadcastTower, faFireAlt, faEllipsisH, faPencilAlt, faBars, faTimes, faBell, faSearch, faUserCog, faCog, faUser, faHome, faStar, faCircle, faAt, faEnvelope, faListUl, faPlus, faUserClock, faLaugh, faUsers, faTachometerAlt, faExchangeAlt, faGlobe, faChartBar, faCloud, faServer, faProjectDiagram | 			faGripVertical, faChevronLeft, faComments, faHashtag, faBroadcastTower, faFireAlt, faEllipsisH, faPencilAlt, faBars, faTimes, faBell, faSearch, faUserCog, faCog, faUser, faHome, faStar, faCircle, faAt, faEnvelope, faListUl, faPlus, faUserClock, faLaugh, faUsers, faTachometerAlt, faExchangeAlt, faGlobe, faChartBar, faCloud, faServer, faProjectDiagram | ||||||
| 		}; | 		}; | ||||||
| 	}, | 	}, | ||||||
|  | @ -102,6 +103,7 @@ export default defineComponent({ | ||||||
| 	methods: { | 	methods: { | ||||||
| 		calcViewState() { | 		calcViewState() { | ||||||
| 			this.iconOnly = (window.innerWidth <= 1400) || (this.$store.state.sidebarDisplay === 'icon'); | 			this.iconOnly = (window.innerWidth <= 1400) || (this.$store.state.sidebarDisplay === 'icon'); | ||||||
|  | 			this.settingsWindowed = (window.innerWidth > 1400); | ||||||
| 		}, | 		}, | ||||||
| 
 | 
 | ||||||
| 		post() { | 		post() { | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue