diff --git a/CHANGELOG.md b/CHANGELOG.md index db7f3138e..c5eea9651 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ You should also include the user name that made the change. - apRequestチャートを追加 - networkチャート廃止 - クライアント: 自インスタンス情報ページでチャートを見れるように @syuilo +- クライアント: デバイスの種類を手動指定できるように @syuilo ### Bugfixes diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index ee23f2c5c..ac8d4951a 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -824,6 +824,10 @@ leaveGroupConfirm: "「{name}」から抜けますか?" useDrawerReactionPickerForMobile: "モバイルデバイスのときドロワーで表示" welcomeBackWithName: "おかえりなさい、{name}さん" clickToFinishEmailVerification: "[{ok}]を押して、メールアドレスの確認を完了してください。" +overridedDeviceKind: "デバイスタイプ" +smartphone: "スマートフォン" +tablet: "タブレット" +auto: "自動" _emailUnavailable: used: "既に使用されています" diff --git a/packages/client/src/components/emoji-picker.vue b/packages/client/src/components/emoji-picker.vue index 6999ad651..3e1208979 100644 --- a/packages/client/src/components/emoji-picker.vue +++ b/packages/client/src/components/emoji-picker.vue @@ -81,7 +81,7 @@ import { getStaticImageUrl } from '@/scripts/get-static-image-url'; import Ripple from '@/components/ripple.vue'; import * as os from '@/os'; import { isTouchUsing } from '@/scripts/touch'; -import { isMobile } from '@/scripts/is-mobile'; +import { deviceKind } from '@/scripts/device-kind'; import { emojiCategories, instance } from '@/instance'; import XSection from './emoji-picker.section.vue'; import { i18n } from '@/i18n'; @@ -263,7 +263,7 @@ watch(q, () => { }); function focus() { - if (!isMobile && !isTouchUsing) { + if (!['smartphone', 'tablet'].includes(deviceKind) && !isTouchUsing) { search.value?.focus({ preventScroll: true }); diff --git a/packages/client/src/components/ui/modal.vue b/packages/client/src/components/ui/modal.vue index 3c3bb5c22..b42c0e4d4 100644 --- a/packages/client/src/components/ui/modal.vue +++ b/packages/client/src/components/ui/modal.vue @@ -14,6 +14,7 @@ import { nextTick, onMounted, computed, ref, watch, provide } from 'vue'; import * as os from '@/os'; import { isTouchUsing } from '@/scripts/touch'; import { defaultStore } from '@/store'; +import { deviceKind } from '@/scripts/device-kind'; function getFixedContainer(el: Element | null): Element | null { if (el == null || el.tagName === 'BODY') return null; @@ -62,7 +63,7 @@ const content = ref(); const zIndex = os.claimZIndex(props.zPriority); const type = computed(() => { if (props.preferType === 'auto') { - if (!defaultStore.state.disableDrawer && isTouchUsing && window.innerWidth < 500 && window.innerHeight < 1000) { + if (!defaultStore.state.disableDrawer && isTouchUsing && deviceKind === 'smartphone') { return 'drawer'; } else { return props.src != null ? 'popup' : 'dialog'; diff --git a/packages/client/src/init.ts b/packages/client/src/init.ts index 994177468..b7fc8b1d1 100644 --- a/packages/client/src/init.ts +++ b/packages/client/src/init.ts @@ -32,7 +32,7 @@ import { defaultStore, ColdDeviceStorage } from '@/store'; import { fetchInstance, instance } from '@/instance'; import { makeHotkey } from '@/scripts/hotkey'; import { search } from '@/scripts/search'; -import { isMobile } from '@/scripts/is-mobile'; +import { deviceKind } from '@/scripts/device-kind'; import { initializeSw } from '@/scripts/initialize-sw'; import { reloadChannel } from '@/scripts/unison-reload'; import { reactionPicker } from '@/scripts/reaction-picker'; @@ -92,7 +92,7 @@ window.addEventListener('resize', () => { //#endregion // If mobile, insert the viewport meta tag -if (isMobile || window.innerWidth <= 1024) { +if (['smartphone', 'tablet'].includes(deviceKind)) { const viewport = document.getElementsByName('viewport').item(0); viewport.setAttribute('content', `${viewport.getAttribute('content')},minimum-scale=1,maximum-scale=1,user-scalable=no`); diff --git a/packages/client/src/pages/settings/general.vue b/packages/client/src/pages/settings/general.vue index 2e159e56a..c8f6f5832 100644 --- a/packages/client/src/pages/settings/general.vue +++ b/packages/client/src/pages/settings/general.vue @@ -12,6 +12,14 @@ + + + + + + + + {{ $ts.showFixedPostForm }} @@ -127,6 +135,7 @@ export default defineComponent({ }, computed: { + overridedDeviceKind: defaultStore.makeGetterSetter('overridedDeviceKind'), serverDisconnectedBehavior: defaultStore.makeGetterSetter('serverDisconnectedBehavior'), reduceAnimation: defaultStore.makeGetterSetter('animation', v => !v, v => !v), useBlurEffectForModal: defaultStore.makeGetterSetter('useBlurEffectForModal'), @@ -193,6 +202,10 @@ export default defineComponent({ instanceTicker() { this.reloadAsk(); }, + + overridedDeviceKind() { + this.reloadAsk(); + }, }, methods: { diff --git a/packages/client/src/scripts/device-kind.ts b/packages/client/src/scripts/device-kind.ts new file mode 100644 index 000000000..544cac060 --- /dev/null +++ b/packages/client/src/scripts/device-kind.ts @@ -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'; diff --git a/packages/client/src/scripts/is-mobile.ts b/packages/client/src/scripts/is-mobile.ts deleted file mode 100644 index 60cb59f91..000000000 --- a/packages/client/src/scripts/is-mobile.ts +++ /dev/null @@ -1,2 +0,0 @@ -const ua = navigator.userAgent.toLowerCase(); -export const isMobile = /mobile|iphone|ipad|android/.test(ua); diff --git a/packages/client/src/store.ts b/packages/client/src/store.ts index b80fc8bbe..0e71060cd 100644 --- a/packages/client/src/store.ts +++ b/packages/client/src/store.ts @@ -106,6 +106,10 @@ export const defaultStore = markRaw(new Storage('base', { } }, + overridedDeviceKind: { + where: 'device', + default: null as null | 'smartphone' | 'tablet' | 'desktop', + }, serverDisconnectedBehavior: { where: 'device', default: 'quiet' as 'quiet' | 'reload' | 'dialog'