feat(client): デバイスの種類を手動指定できるように
This commit is contained in:
		
							parent
							
								
									71a7165ed7
								
							
						
					
					
						commit
						190b47aad2
					
				
					 9 changed files with 38 additions and 7 deletions
				
			
		|  | @ -24,6 +24,7 @@ You should also include the user name that made the change. | ||||||
| 	- apRequestチャートを追加 | 	- apRequestチャートを追加 | ||||||
| 	- networkチャート廃止 | 	- networkチャート廃止 | ||||||
| - クライアント: 自インスタンス情報ページでチャートを見れるように @syuilo | - クライアント: 自インスタンス情報ページでチャートを見れるように @syuilo | ||||||
|  | - クライアント: デバイスの種類を手動指定できるように @syuilo | ||||||
| 
 | 
 | ||||||
| ### Bugfixes | ### Bugfixes | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -824,6 +824,10 @@ leaveGroupConfirm: "「{name}」から抜けますか?" | ||||||
| useDrawerReactionPickerForMobile: "モバイルデバイスのときドロワーで表示" | useDrawerReactionPickerForMobile: "モバイルデバイスのときドロワーで表示" | ||||||
| welcomeBackWithName: "おかえりなさい、{name}さん" | welcomeBackWithName: "おかえりなさい、{name}さん" | ||||||
| clickToFinishEmailVerification: "[{ok}]を押して、メールアドレスの確認を完了してください。" | clickToFinishEmailVerification: "[{ok}]を押して、メールアドレスの確認を完了してください。" | ||||||
|  | overridedDeviceKind: "デバイスタイプ" | ||||||
|  | smartphone: "スマートフォン" | ||||||
|  | tablet: "タブレット" | ||||||
|  | auto: "自動" | ||||||
| 
 | 
 | ||||||
| _emailUnavailable: | _emailUnavailable: | ||||||
|   used: "既に使用されています" |   used: "既に使用されています" | ||||||
|  |  | ||||||
|  | @ -81,7 +81,7 @@ import { getStaticImageUrl } from '@/scripts/get-static-image-url'; | ||||||
| import Ripple from '@/components/ripple.vue'; | import Ripple from '@/components/ripple.vue'; | ||||||
| import * as os from '@/os'; | import * as os from '@/os'; | ||||||
| import { isTouchUsing } from '@/scripts/touch'; | import { isTouchUsing } from '@/scripts/touch'; | ||||||
| import { isMobile } from '@/scripts/is-mobile'; | import { deviceKind } from '@/scripts/device-kind'; | ||||||
| import { emojiCategories, instance } from '@/instance'; | import { emojiCategories, instance } from '@/instance'; | ||||||
| import XSection from './emoji-picker.section.vue'; | import XSection from './emoji-picker.section.vue'; | ||||||
| import { i18n } from '@/i18n'; | import { i18n } from '@/i18n'; | ||||||
|  | @ -263,7 +263,7 @@ watch(q, () => { | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| function focus() { | function focus() { | ||||||
| 	if (!isMobile && !isTouchUsing) { | 	if (!['smartphone', 'tablet'].includes(deviceKind) && !isTouchUsing) { | ||||||
| 		search.value?.focus({ | 		search.value?.focus({ | ||||||
| 			preventScroll: true | 			preventScroll: true | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
|  | @ -14,6 +14,7 @@ import { nextTick, onMounted, computed, ref, watch, provide } from 'vue'; | ||||||
| import * as os from '@/os'; | import * as os from '@/os'; | ||||||
| import { isTouchUsing } from '@/scripts/touch'; | import { isTouchUsing } from '@/scripts/touch'; | ||||||
| import { defaultStore } from '@/store'; | import { defaultStore } from '@/store'; | ||||||
|  | import { deviceKind } from '@/scripts/device-kind'; | ||||||
| 
 | 
 | ||||||
| function getFixedContainer(el: Element | null): Element | null { | function getFixedContainer(el: Element | null): Element | null { | ||||||
| 	if (el == null || el.tagName === 'BODY') return null; | 	if (el == null || el.tagName === 'BODY') return null; | ||||||
|  | @ -62,7 +63,7 @@ const content = ref<HTMLElement>(); | ||||||
| const zIndex = os.claimZIndex(props.zPriority); | const zIndex = os.claimZIndex(props.zPriority); | ||||||
| const type = computed(() => { | const type = computed(() => { | ||||||
| 	if (props.preferType === 'auto') { | 	if (props.preferType === 'auto') { | ||||||
| 		if (!defaultStore.state.disableDrawer && isTouchUsing && window.innerWidth < 500 && window.innerHeight < 1000) { | 		if (!defaultStore.state.disableDrawer && isTouchUsing && deviceKind === 'smartphone') { | ||||||
| 			return 'drawer'; | 			return 'drawer'; | ||||||
| 		} else { | 		} else { | ||||||
| 			return props.src != null ? 'popup' : 'dialog'; | 			return props.src != null ? 'popup' : 'dialog'; | ||||||
|  |  | ||||||
|  | @ -32,7 +32,7 @@ import { defaultStore, ColdDeviceStorage } from '@/store'; | ||||||
| import { fetchInstance, instance } from '@/instance'; | import { fetchInstance, instance } from '@/instance'; | ||||||
| import { makeHotkey } from '@/scripts/hotkey'; | import { makeHotkey } from '@/scripts/hotkey'; | ||||||
| import { search } from '@/scripts/search'; | import { search } from '@/scripts/search'; | ||||||
| import { isMobile } from '@/scripts/is-mobile'; | import { deviceKind } from '@/scripts/device-kind'; | ||||||
| import { initializeSw } from '@/scripts/initialize-sw'; | import { initializeSw } from '@/scripts/initialize-sw'; | ||||||
| import { reloadChannel } from '@/scripts/unison-reload'; | import { reloadChannel } from '@/scripts/unison-reload'; | ||||||
| import { reactionPicker } from '@/scripts/reaction-picker'; | import { reactionPicker } from '@/scripts/reaction-picker'; | ||||||
|  | @ -92,7 +92,7 @@ window.addEventListener('resize', () => { | ||||||
| //#endregion
 | //#endregion
 | ||||||
| 
 | 
 | ||||||
| // If mobile, insert the viewport meta tag
 | // If mobile, insert the viewport meta tag
 | ||||||
| if (isMobile || window.innerWidth <= 1024) { | if (['smartphone', 'tablet'].includes(deviceKind)) { | ||||||
| 	const viewport = document.getElementsByName('viewport').item(0); | 	const viewport = document.getElementsByName('viewport').item(0); | ||||||
| 	viewport.setAttribute('content', | 	viewport.setAttribute('content', | ||||||
| 		`${viewport.getAttribute('content')},minimum-scale=1,maximum-scale=1,user-scalable=no`); | 		`${viewport.getAttribute('content')},minimum-scale=1,maximum-scale=1,user-scalable=no`); | ||||||
|  |  | ||||||
|  | @ -12,6 +12,14 @@ | ||||||
| 		</template> | 		</template> | ||||||
| 	</FormSelect> | 	</FormSelect> | ||||||
| 
 | 
 | ||||||
|  | 	<FormRadios v-model="overridedDeviceKind" class="_formBlock"> | ||||||
|  | 		<template #label>{{ $ts.overridedDeviceKind }}</template> | ||||||
|  | 		<option :value="null">{{ $ts.auto }}</option> | ||||||
|  | 		<option value="smartphone"><i class="fas fa-mobile-alt"/> {{ $ts.smartphone }}</option> | ||||||
|  | 		<option value="tablet"><i class="fas fa-tablet-alt"/> {{ $ts.tablet }}</option> | ||||||
|  | 		<option value="desktop"><i class="fas fa-desktop"/> {{ $ts.desktop }}</option> | ||||||
|  | 	</FormRadios> | ||||||
|  | 
 | ||||||
| 	<FormSwitch v-model="showFixedPostForm" class="_formBlock">{{ $ts.showFixedPostForm }}</FormSwitch> | 	<FormSwitch v-model="showFixedPostForm" class="_formBlock">{{ $ts.showFixedPostForm }}</FormSwitch> | ||||||
| 
 | 
 | ||||||
| 	<FormSection> | 	<FormSection> | ||||||
|  | @ -127,6 +135,7 @@ export default defineComponent({ | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
| 	computed: { | 	computed: { | ||||||
|  | 		overridedDeviceKind: defaultStore.makeGetterSetter('overridedDeviceKind'), | ||||||
| 		serverDisconnectedBehavior: defaultStore.makeGetterSetter('serverDisconnectedBehavior'), | 		serverDisconnectedBehavior: defaultStore.makeGetterSetter('serverDisconnectedBehavior'), | ||||||
| 		reduceAnimation: defaultStore.makeGetterSetter('animation', v => !v, v => !v), | 		reduceAnimation: defaultStore.makeGetterSetter('animation', v => !v, v => !v), | ||||||
| 		useBlurEffectForModal: defaultStore.makeGetterSetter('useBlurEffectForModal'), | 		useBlurEffectForModal: defaultStore.makeGetterSetter('useBlurEffectForModal'), | ||||||
|  | @ -193,6 +202,10 @@ export default defineComponent({ | ||||||
| 		instanceTicker() { | 		instanceTicker() { | ||||||
| 			this.reloadAsk(); | 			this.reloadAsk(); | ||||||
| 		}, | 		}, | ||||||
|  | 
 | ||||||
|  | 		overridedDeviceKind() { | ||||||
|  | 			this.reloadAsk(); | ||||||
|  | 		}, | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
| 	methods: { | 	methods: { | ||||||
|  |  | ||||||
							
								
								
									
										10
									
								
								packages/client/src/scripts/device-kind.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								packages/client/src/scripts/device-kind.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,10 @@ | ||||||
|  | import { defaultStore } from '@/store'; | ||||||
|  | 
 | ||||||
|  | const ua = navigator.userAgent.toLowerCase(); | ||||||
|  | const isTablet = /ipad/.test(ua) || (/mobile|iphone|android/.test(ua) && window.innerWidth > 700); | ||||||
|  | const isSmartphone = !isTablet && /mobile|iphone|android/.test(ua); | ||||||
|  | 
 | ||||||
|  | export const deviceKind = defaultStore.state.overridedDeviceKind ? defaultStore.state.overridedDeviceKind | ||||||
|  | 	: isSmartphone ? 'smartphone' | ||||||
|  | 	: isTablet ? 'tablet' | ||||||
|  | 	: 'desktop'; | ||||||
|  | @ -1,2 +0,0 @@ | ||||||
| const ua = navigator.userAgent.toLowerCase(); |  | ||||||
| export const isMobile = /mobile|iphone|ipad|android/.test(ua); |  | ||||||
|  | @ -106,6 +106,10 @@ export const defaultStore = markRaw(new Storage('base', { | ||||||
| 		} | 		} | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
|  | 	overridedDeviceKind: { | ||||||
|  | 		where: 'device', | ||||||
|  | 		default: null as null | 'smartphone' | 'tablet' | 'desktop', | ||||||
|  | 	}, | ||||||
| 	serverDisconnectedBehavior: { | 	serverDisconnectedBehavior: { | ||||||
| 		where: 'device', | 		where: 'device', | ||||||
| 		default: 'quiet' as 'quiet' | 'reload' | 'dialog' | 		default: 'quiet' as 'quiet' | 'reload' | 'dialog' | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue