parent
							
								
									de3b365563
								
							
						
					
					
						commit
						66b07578c5
					
				
					 6 changed files with 138 additions and 88 deletions
				
			
		|  | @ -556,6 +556,12 @@ testEmail: "配信テスト" | |||
| wordMute: "ワードミュート" | ||||
| userSaysSomething: "{name}が何かを言いました" | ||||
| makeActive: "アクティブにする" | ||||
| display: "表示" | ||||
| 
 | ||||
| _sidebar: | ||||
|   full: "フル" | ||||
|   icon: "アイコン" | ||||
|   hide: "隠す" | ||||
| 
 | ||||
| _wordMute: | ||||
|   muteWords: "ミュートするワード" | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| <template> | ||||
| <div class="mk-app" v-hotkey.global="keymap"> | ||||
| 	<header class="header"> | ||||
| 	<header class="header" ref="header"> | ||||
| 		<div class="title" ref="title"> | ||||
| 			<transition :name="$store.state.device.animation ? 'header' : ''" mode="out-in" appear> | ||||
| 				<button class="_button back" v-if="canBack" @click="back()"><fa :icon="faChevronLeft"/></button> | ||||
|  | @ -31,7 +31,7 @@ | |||
| 		</div> | ||||
| 	</header> | ||||
| 
 | ||||
| 	<x-sidebar ref="nav"/> | ||||
| 	<x-sidebar ref="nav" @change-view-mode="calcHeaderWidth"/> | ||||
| 
 | ||||
| 	<div class="contents" ref="contents" :class="{ wallpaper }"> | ||||
| 		<main ref="main"> | ||||
|  | @ -77,7 +77,7 @@ | |||
| 		</template> | ||||
| 	</div> | ||||
| 
 | ||||
| 	<div class="buttons"> | ||||
| 	<div class="buttons" :class="{ navHidden }"> | ||||
| 		<button class="button nav _button" @click="showNav" ref="navButton"><fa :icon="faBars"/><i v-if="navIndicated"><fa :icon="faCircle"/></i></button> | ||||
| 		<button v-if="$route.name === 'index'" class="button home _button" @click="top()"><fa :icon="faHome"/></button> | ||||
| 		<button v-else class="button home _button" @click="$router.push('/')"><fa :icon="faHome"/></button> | ||||
|  | @ -85,7 +85,7 @@ | |||
| 		<button v-if="$store.getters.isSignedIn" class="button post _buttonPrimary" @click="post()"><fa :icon="faPencilAlt"/></button> | ||||
| 	</div> | ||||
| 
 | ||||
| 	<button v-if="$store.getters.isSignedIn" class="post _buttonPrimary" @click="post()"><fa :icon="faPencilAlt"/></button> | ||||
| 	<button v-if="$store.getters.isSignedIn" class="post _buttonPrimary" :class="{ navHidden }" @click="post()"><fa :icon="faPencilAlt"/></button> | ||||
| 
 | ||||
| 	<stream-indicator v-if="$store.getters.isSignedIn"/> | ||||
| </div> | ||||
|  | @ -124,6 +124,7 @@ export default Vue.extend({ | |||
| 			isDesktop: window.innerWidth >= DESKTOP_THRESHOLD, | ||||
| 			canBack: false, | ||||
| 			menuDef: this.$store.getters.nav({}), | ||||
| 			navHidden: false, | ||||
| 			wallpaper: localStorage.getItem('wallpaper') != null, | ||||
| 			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 | ||||
| 		}; | ||||
|  | @ -225,22 +226,15 @@ export default Vue.extend({ | |||
| 	}, | ||||
| 
 | ||||
| 	mounted() { | ||||
| 		const adjustTitlePosition = () => { | ||||
| 			const left = this.$refs.main.getBoundingClientRect().left - this.$refs.nav.$el.offsetWidth; | ||||
| 			if (left >= 0) { | ||||
| 				this.$refs.title.style.left = left + 'px'; | ||||
| 			} | ||||
| 		}; | ||||
| 
 | ||||
| 		adjustTitlePosition(); | ||||
| 		this.adjustTitlePosition(); | ||||
| 
 | ||||
| 		const ro = new ResizeObserver((entries, observer) => { | ||||
| 			adjustTitlePosition(); | ||||
| 			this.adjustTitlePosition(); | ||||
| 		}); | ||||
| 
 | ||||
| 		ro.observe(this.$refs.contents); | ||||
| 
 | ||||
| 		window.addEventListener('resize', adjustTitlePosition, { passive: true }); | ||||
| 		window.addEventListener('resize', this.adjustTitlePosition, { passive: true }); | ||||
| 
 | ||||
| 		if (!this.isDesktop) { | ||||
| 			window.addEventListener('resize', () => { | ||||
|  | @ -250,9 +244,27 @@ export default Vue.extend({ | |||
| 
 | ||||
| 		// widget follow | ||||
| 		this.attachSticky(); | ||||
| 
 | ||||
| 		this.$nextTick(() => { | ||||
| 			this.calcHeaderWidth(); | ||||
| 		}); | ||||
| 	}, | ||||
| 
 | ||||
| 	methods: { | ||||
| 		adjustTitlePosition() { | ||||
| 			const left = this.$refs.main.getBoundingClientRect().left - this.$refs.nav.$el.offsetWidth; | ||||
| 			if (left >= 0) { | ||||
| 				this.$refs.title.style.left = left + 'px'; | ||||
| 			} | ||||
| 		}, | ||||
| 
 | ||||
| 		calcHeaderWidth() { | ||||
| 			const navWidth = this.$refs.nav.$el.offsetWidth; | ||||
| 			this.navHidden = navWidth === 0; | ||||
| 			this.$refs.header.style.width = `calc(100% - ${navWidth}px)`; | ||||
| 			this.adjustTitlePosition(); | ||||
| 		}, | ||||
| 
 | ||||
| 		showNav() { | ||||
| 			this.$refs.nav.show(); | ||||
| 		}, | ||||
|  | @ -373,12 +385,8 @@ export default Vue.extend({ | |||
| <style lang="scss" scoped> | ||||
| .mk-app { | ||||
| 	$header-height: 60px; | ||||
| 	$nav-width: 250px; // TODO: どこかに集約したい | ||||
| 	$nav-icon-only-width: 80px; // TODO: どこかに集約したい | ||||
| 	$main-width: 670px; | ||||
| 	$ui-font-size: 1em; // TODO: どこかに集約したい | ||||
| 	$nav-icon-only-threshold: 1279px; // TODO: どこかに集約したい | ||||
| 	$nav-hide-threshold: 650px; // TODO: どこかに集約したい | ||||
| 	$header-sub-hide-threshold: 1090px; | ||||
| 	$left-widgets-hide-threshold: 1600px; | ||||
| 	$right-widgets-hide-threshold: 1090px; | ||||
|  | @ -399,21 +407,13 @@ export default Vue.extend({ | |||
| 		top: 0; | ||||
| 		right: 0; | ||||
| 		height: $header-height; | ||||
| 		width: calc(100% - #{$nav-width}); | ||||
| 		width: 100%; | ||||
| 		//background-color: var(--panel); | ||||
| 		-webkit-backdrop-filter: blur(32px); | ||||
| 		backdrop-filter: blur(32px); | ||||
| 		background-color: var(--header); | ||||
| 		border-bottom: solid 1px var(--divider); | ||||
| 
 | ||||
| 		@media (max-width: $nav-icon-only-threshold) { | ||||
| 			width: calc(100% - #{$nav-icon-only-width}); | ||||
| 		} | ||||
| 
 | ||||
| 		@media (max-width: $nav-hide-threshold) { | ||||
| 			width: 100%; | ||||
| 		} | ||||
| 
 | ||||
| 		> .title { | ||||
| 			position: relative; | ||||
| 			line-height: $header-height; | ||||
|  | @ -683,7 +683,7 @@ export default Vue.extend({ | |||
| 	} | ||||
| 
 | ||||
| 	> .post { | ||||
| 		display: none; | ||||
| 		display: block; | ||||
| 		position: fixed; | ||||
| 		z-index: 1000; | ||||
| 		bottom: 32px; | ||||
|  | @ -694,8 +694,8 @@ export default Vue.extend({ | |||
| 		box-shadow: 0 3px 5px -1px rgba(0, 0, 0, 0.2), 0 6px 10px 0 rgba(0, 0, 0, 0.14), 0 1px 18px 0 rgba(0, 0, 0, 0.12); | ||||
| 		font-size: 22px; | ||||
| 
 | ||||
| 		@media (min-width: ($nav-hide-threshold + 1px)) { | ||||
| 			display: block; | ||||
| 		&.navHidden { | ||||
| 			display: none; | ||||
| 		} | ||||
| 
 | ||||
| 		@media (min-width: ($header-sub-hide-threshold + 1px)) { | ||||
|  | @ -717,7 +717,7 @@ export default Vue.extend({ | |||
| 			padding: 0 16px 16px 16px; | ||||
| 		} | ||||
| 
 | ||||
| 		@media (min-width: ($nav-hide-threshold + 1px)) { | ||||
| 		&:not(.navHidden) { | ||||
| 			display: none; | ||||
| 		} | ||||
| 
 | ||||
|  |  | |||
|  | @ -9,7 +9,7 @@ | |||
| 	</transition> | ||||
| 
 | ||||
| 	<transition name="nav"> | ||||
| 		<nav class="nav" v-show="showing"> | ||||
| 		<nav class="nav" :class="{ iconOnly, hidden }" v-show="showing"> | ||||
| 			<div> | ||||
| 				<button class="item _button account" @click="openAccountMenu" v-if="$store.getters.isSignedIn"> | ||||
| 					<mk-avatar :user="$store.state.i" class="avatar"/><mk-acct class="text" :user="$store.state.i"/> | ||||
|  | @ -62,6 +62,8 @@ export default Vue.extend({ | |||
| 			menuDef: this.$store.getters.nav({ | ||||
| 				search: this.search | ||||
| 			}), | ||||
| 			iconOnly: false, | ||||
| 			hidden: 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 | ||||
| 		}; | ||||
| 	}, | ||||
|  | @ -85,9 +87,35 @@ export default Vue.extend({ | |||
| 		$route(to, from) { | ||||
| 			this.showing = false; | ||||
| 		}, | ||||
| 
 | ||||
| 		'$store.state.device.sidebarDisplay'() { | ||||
| 			this.calcViewState(); | ||||
| 		}, | ||||
| 
 | ||||
| 		iconOnly() { | ||||
| 			this.$nextTick(() => { | ||||
| 				this.$emit('change-view-mode'); | ||||
| 			}); | ||||
| 		}, | ||||
| 
 | ||||
| 		hidden() { | ||||
| 			this.$nextTick(() => { | ||||
| 				this.$emit('change-view-mode'); | ||||
| 			}); | ||||
| 		} | ||||
| 	}, | ||||
| 
 | ||||
| 	created() { | ||||
| 		window.addEventListener('resize', this.calcViewState); | ||||
| 		this.calcViewState(); | ||||
| 	}, | ||||
| 
 | ||||
| 	methods: { | ||||
| 		calcViewState() { | ||||
| 			this.iconOnly = (window.innerWidth <= 1279) || (this.$store.state.device.sidebarDisplay === 'icon'); | ||||
| 			this.hidden = (window.innerWidth <= 650) || (this.$store.state.device.sidebarDisplay === 'hide'); | ||||
| 		}, | ||||
| 
 | ||||
| 		show() { | ||||
| 			this.showing = true; | ||||
| 		}, | ||||
|  | @ -314,10 +342,8 @@ export default Vue.extend({ | |||
| 
 | ||||
| .mvcprjjd { | ||||
| 	$ui-font-size: 1em; // TODO: どこかに集約したい | ||||
| 	$nav-width: 250px; // TODO: どこかに集約したい | ||||
| 	$nav-icon-only-width: 80px; // TODO: どこかに集約したい | ||||
| 	$nav-icon-only-threshold: 1279px; // TODO: どこかに集約したい | ||||
| 	$nav-hide-threshold: 650px; // TODO: どこかに集約したい | ||||
| 	$nav-width: 250px; | ||||
| 	$nav-icon-only-width: 80px; | ||||
| 
 | ||||
| 	> .nav-back { | ||||
| 		z-index: 1001; | ||||
|  | @ -331,19 +357,66 @@ export default Vue.extend({ | |||
| 		width: $nav-width; | ||||
| 		box-sizing: border-box; | ||||
| 
 | ||||
| 		@media (max-width: $nav-icon-only-threshold) { | ||||
| 		&.iconOnly { | ||||
| 			flex: 0 0 $nav-icon-only-width; | ||||
| 			width: $nav-icon-only-width; | ||||
| 
 | ||||
| 			&:not(.hidden) { | ||||
| 				> div { | ||||
| 					width: $nav-icon-only-width; | ||||
| 
 | ||||
| 					> .divider { | ||||
| 						margin: 8px auto; | ||||
| 						width: calc(100% - 32px); | ||||
| 					} | ||||
| 
 | ||||
| 					> .item { | ||||
| 						padding-left: 0; | ||||
| 						width: 100%; | ||||
| 						text-align: center; | ||||
| 						font-size: $ui-font-size * 1.2; | ||||
| 						line-height: 3.7rem; | ||||
| 
 | ||||
| 						> [data-icon], | ||||
| 						> .avatar { | ||||
| 							margin-right: 0; | ||||
| 						} | ||||
| 
 | ||||
| 						> i { | ||||
| 							left: 10px; | ||||
| 						} | ||||
| 
 | ||||
| 						> .text { | ||||
| 							display: none; | ||||
| 						} | ||||
| 
 | ||||
| 						&:first-child { | ||||
| 							margin-bottom: 8px; | ||||
| 						} | ||||
| 
 | ||||
| 						&:last-child { | ||||
| 							margin-top: 8px; | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		@media (max-width: $nav-hide-threshold) { | ||||
| 		&.hidden { | ||||
| 			position: fixed; | ||||
| 			top: 0; | ||||
| 			left: 0; | ||||
| 			z-index: 1001; | ||||
| 
 | ||||
| 			> div { | ||||
| 				> .index, | ||||
| 				> .notifications { | ||||
| 					display: none; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		@media (min-width: $nav-hide-threshold + 1px) { | ||||
| 		&:not(.hidden) { | ||||
| 			display: block !important; | ||||
| 		} | ||||
| 
 | ||||
|  | @ -365,25 +438,6 @@ export default Vue.extend({ | |||
| 				border-top: solid 1px var(--divider); | ||||
| 			} | ||||
| 
 | ||||
| 			@media (max-width: $nav-icon-only-threshold) and (min-width: $nav-hide-threshold + 1px) { | ||||
| 				width: $nav-icon-only-width; | ||||
| 
 | ||||
| 				> .divider { | ||||
| 					margin: 8px auto; | ||||
| 					width: calc(100% - 32px); | ||||
| 				} | ||||
| 
 | ||||
| 				> .item { | ||||
| 					&:first-child { | ||||
| 						margin-bottom: 8px; | ||||
| 					} | ||||
| 
 | ||||
| 					&:last-child { | ||||
| 						margin-top: 8px; | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			> .item { | ||||
| 				position: relative; | ||||
| 				display: block; | ||||
|  | @ -452,34 +506,6 @@ export default Vue.extend({ | |||
| 					margin-top: 16px; | ||||
| 					border-top: solid 1px var(--divider); | ||||
| 				} | ||||
| 
 | ||||
| 				@media (max-width: $nav-icon-only-threshold) and (min-width: $nav-hide-threshold + 1px) { | ||||
| 					padding-left: 0; | ||||
| 					width: 100%; | ||||
| 					text-align: center; | ||||
| 					font-size: $ui-font-size * 1.2; | ||||
| 					line-height: 3.7rem; | ||||
| 
 | ||||
| 					> [data-icon], | ||||
| 					> .avatar { | ||||
| 						margin-right: 0; | ||||
| 					} | ||||
| 
 | ||||
| 					> i { | ||||
| 						left: 10px; | ||||
| 					} | ||||
| 
 | ||||
| 					> .text { | ||||
| 						display: none; | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			@media (max-width: $nav-hide-threshold) { | ||||
| 				> .index, | ||||
| 				> .notifications { | ||||
| 					display: none; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  |  | |||
|  | @ -42,6 +42,7 @@ export default Vue.extend({ | |||
| 	}, | ||||
| 	methods: { | ||||
| 		toggle() { | ||||
| 			if (this.disabled) return; | ||||
| 			this.$emit('change', this.value); | ||||
| 		} | ||||
| 	} | ||||
|  | @ -61,7 +62,10 @@ export default Vue.extend({ | |||
| 
 | ||||
| 	&.disabled { | ||||
| 		opacity: 0.6; | ||||
| 		cursor: not-allowed; | ||||
| 
 | ||||
| 		&, * { | ||||
| 			cursor: not-allowed !important; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	&.checked { | ||||
|  |  | |||
|  | @ -7,6 +7,12 @@ | |||
| 			<template #desc><button class="_textButton" @click="addItem">{{ $t('addItem') }}</button></template> | ||||
| 		</mk-textarea> | ||||
| 	</div> | ||||
| 	<div class="_content"> | ||||
| 		<div>{{ $t('display') }}</div> | ||||
| 		<mk-radio v-model="sidebarDisplay" value="full">{{ $t('_sidebar.full') }}</mk-radio> | ||||
| 		<mk-radio v-model="sidebarDisplay" value="icon">{{ $t('_sidebar.icon') }}</mk-radio> | ||||
| 		<!-- <mk-radio v-model="sidebarDisplay" value="hide" disabled>{{ $t('_sidebar.hide') }}</mk-radio>--> <!-- TODO: サイドバーを完全に隠せるようにすると、別途ハンバーガーボタンのようなものをUIに表示する必要があり面倒 --> | ||||
| 	</div> | ||||
| 	<div class="_footer"> | ||||
| 		<mk-button inline @click="save()" primary><fa :icon="faSave"/> {{ $t('save') }}</mk-button> | ||||
| 		<mk-button inline @click="reset()"><fa :icon="faRedo"/> {{ $t('default') }}</mk-button> | ||||
|  | @ -19,12 +25,14 @@ import Vue from 'vue'; | |||
| import { faListUl, faSave, faRedo } from '@fortawesome/free-solid-svg-icons'; | ||||
| import MkButton from '../../components/ui/button.vue'; | ||||
| import MkTextarea from '../../components/ui/textarea.vue'; | ||||
| import MkRadio from '../../components/ui/radio.vue'; | ||||
| import { defaultDeviceUserSettings } from '../../store'; | ||||
| 
 | ||||
| export default Vue.extend({ | ||||
| 	components: { | ||||
| 		MkButton, | ||||
| 		MkTextarea, | ||||
| 		MkRadio, | ||||
| 	}, | ||||
| 	 | ||||
| 	data() { | ||||
|  | @ -38,7 +46,12 @@ export default Vue.extend({ | |||
| 	computed: { | ||||
| 		splited(): string[] { | ||||
| 			return this.items.trim().split('\n').filter(x => x.trim() !== ''); | ||||
| 		} | ||||
| 		}, | ||||
| 
 | ||||
| 		sidebarDisplay: { | ||||
| 			get() { return this.$store.state.device.sidebarDisplay; }, | ||||
| 			set(value) { this.$store.commit('device/set', { key: 'sidebarDisplay', value }); } | ||||
| 		}, | ||||
| 	}, | ||||
| 
 | ||||
| 	created() { | ||||
|  |  | |||
|  | @ -77,6 +77,7 @@ export const defaultDeviceSettings = { | |||
| 	enableInfiniteScroll: true, | ||||
| 	fixedWidgetsPosition: false, | ||||
| 	useBlurEffectForModal: true, | ||||
| 	sidebarDisplay: 'full', // full, icon, hide
 | ||||
| 	roomGraphicsQuality: 'medium', | ||||
| 	roomUseOrthographicCamera: true, | ||||
| 	deckColumnAlign: 'left', | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue