This commit is contained in:
syuilo 2024-09-25 12:31:04 +09:00
parent c88957c037
commit 53682f5cc6
7 changed files with 102 additions and 69 deletions

12
locales/index.d.ts vendored
View file

@ -2053,9 +2053,17 @@ export interface Locale extends ILocale {
*/ */
"native": string; "native": string;
/** /**
* *
*/ */
"disableDrawer": string; "menuStyle": string;
/**
*
*/
"drawer": string;
/**
*
*/
"popup": string;
/** /**
* *
*/ */

View file

@ -509,7 +509,9 @@ uiLanguage: "UIの表示言語"
aboutX: "{x}について" aboutX: "{x}について"
emojiStyle: "絵文字のスタイル" emojiStyle: "絵文字のスタイル"
native: "ネイティブ" native: "ネイティブ"
disableDrawer: "メニューをドロワーで表示しない" menuStyle: "メニューのスタイル"
drawer: "ドロワー"
popup: "ポップアップ"
showNoteActionsOnlyHover: "ノートのアクションをホバー時のみ表示する" showNoteActionsOnlyHover: "ノートのアクションをホバー時のみ表示する"
showReactionsCount: "ノートのリアクション数を表示する" showReactionsCount: "ノートのリアクション数を表示する"
noHistory: "履歴はありません" noHistory: "履歴はありません"

View file

@ -4,18 +4,22 @@ SPDX-License-Identifier: AGPL-3.0-only
--> -->
<template> <template>
<div role="menu" @focusin.passive.stop="() => {}"> <div
role="menu"
:class="{
[$style.root]: true,
[$style.center]: align === 'center',
[$style.big]: big,
[$style.asDrawer]: asDrawer,
}"
@focusin.passive.stop="() => {}"
>
<div <div
ref="itemsEl" ref="itemsEl"
v-hotkey="keymap" v-hotkey="keymap"
tabindex="0" tabindex="0"
class="_popup _shadow" class="_popup _shadow"
:class="{ :class="$style.menu"
[$style.root]: true,
[$style.center]: align === 'center',
[$style.big]: big,
[$style.asDrawer]: asDrawer,
}"
:style="{ :style="{
width: (width && !asDrawer) ? `${width}px` : '', width: (width && !asDrawer) ? `${width}px` : '',
maxHeight: maxHeight ? `min(${maxHeight}px, calc(100dvh - 32px))` : 'calc(100dvh - 32px)', maxHeight: maxHeight ? `min(${maxHeight}px, calc(100dvh - 32px))` : 'calc(100dvh - 32px)',
@ -300,6 +304,8 @@ async function showRadioOptions(item: MenuRadio, ev: Event) {
} }
async function showChildren(item: MenuParent, ev: Event) { async function showChildren(item: MenuParent, ev: Event) {
ev.stopPropagation();
const children: MenuItem[] = await (async () => { const children: MenuItem[] = await (async () => {
if (childrenCache.has(item)) { if (childrenCache.has(item)) {
return childrenCache.get(item)!; return childrenCache.get(item)!;
@ -421,6 +427,58 @@ onBeforeUnmount(() => {
<style lang="scss" module> <style lang="scss" module>
.root { .root {
&.center {
> .menu {
> .item {
text-align: center;
}
}
}
&.big:not(.asDrawer) {
> .menu {
> .item {
padding: 6px 20px;
font-size: 1em;
line-height: 24px;
}
}
}
&.asDrawer {
max-width: 600px;
margin: auto;
> .menu {
padding: 12px 0 max(env(safe-area-inset-bottom, 0px), 12px) 0;
width: 100%;
border-radius: 24px;
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
> .item {
font-size: 1em;
padding: 12px 24px;
&::before {
width: calc(100% - 24px);
border-radius: 12px;
}
> .icon {
margin-right: 14px;
width: 24px;
}
}
> .divider {
margin: 12px 0;
}
}
}
}
.menu {
padding: 8px 0; padding: 8px 0;
box-sizing: border-box; box-sizing: border-box;
max-width: 100vw; max-width: 100vw;
@ -431,47 +489,6 @@ onBeforeUnmount(() => {
&:focus-visible { &:focus-visible {
outline: none; outline: none;
} }
&.center {
> .item {
text-align: center;
}
}
&.big:not(.asDrawer) {
> .item {
padding: 6px 20px;
font-size: 1em;
line-height: 24px;
}
}
&.asDrawer {
padding: 12px 0 max(env(safe-area-inset-bottom, 0px), 12px) 0;
width: 100%;
border-radius: 24px;
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
> .item {
font-size: 1em;
padding: 12px 24px;
&::before {
width: calc(100% - 24px);
border-radius: 12px;
}
> .icon {
margin-right: 14px;
width: 24px;
}
}
> .divider {
margin: 12px 0;
}
}
} }
.item { .item {

View file

@ -106,7 +106,7 @@ const zIndex = os.claimZIndex(props.zPriority);
const useSendAnime = ref(false); const useSendAnime = ref(false);
const type = computed<ModalTypes>(() => { const type = computed<ModalTypes>(() => {
if (props.preferType === 'auto') { if (props.preferType === 'auto') {
if (!defaultStore.state.disableDrawer && isTouchUsing && deviceKind === 'smartphone') { if ((defaultStore.state.menuStyle === 'drawer') || (defaultStore.state.menuStyle === 'auto' && isTouchUsing && deviceKind === 'smartphone')) {
return 'drawer'; return 'drawer';
} else { } else {
return props.src != null ? 'popup' : 'dialog'; return props.src != null ? 'popup' : 'dialog';

View file

@ -17,13 +17,6 @@ SPDX-License-Identifier: AGPL-3.0-only
</template> </template>
</MkSelect> </MkSelect>
<MkRadios v-model="hemisphere">
<template #label>{{ i18n.ts.hemisphere }}</template>
<option value="N">{{ i18n.ts._hemisphere.N }}</option>
<option value="S">{{ i18n.ts._hemisphere.S }}</option>
<template #caption>{{ i18n.ts._hemisphere.caption }}</template>
</MkRadios>
<MkRadios v-model="overridedDeviceKind"> <MkRadios v-model="overridedDeviceKind">
<template #label>{{ i18n.ts.overridedDeviceKind }}</template> <template #label>{{ i18n.ts.overridedDeviceKind }}</template>
<option :value="null">{{ i18n.ts.auto }}</option> <option :value="null">{{ i18n.ts.auto }}</option>
@ -132,11 +125,18 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkSwitch v-model="squareAvatars">{{ i18n.ts.squareAvatars }}</MkSwitch> <MkSwitch v-model="squareAvatars">{{ i18n.ts.squareAvatars }}</MkSwitch>
<MkSwitch v-model="showAvatarDecorations">{{ i18n.ts.showAvatarDecorations }}</MkSwitch> <MkSwitch v-model="showAvatarDecorations">{{ i18n.ts.showAvatarDecorations }}</MkSwitch>
<MkSwitch v-model="useSystemFont">{{ i18n.ts.useSystemFont }}</MkSwitch> <MkSwitch v-model="useSystemFont">{{ i18n.ts.useSystemFont }}</MkSwitch>
<MkSwitch v-model="disableDrawer">{{ i18n.ts.disableDrawer }}</MkSwitch>
<MkSwitch v-model="forceShowAds">{{ i18n.ts.forceShowAds }}</MkSwitch> <MkSwitch v-model="forceShowAds">{{ i18n.ts.forceShowAds }}</MkSwitch>
<MkSwitch v-model="enableSeasonalScreenEffect">{{ i18n.ts.seasonalScreenEffect }}</MkSwitch> <MkSwitch v-model="enableSeasonalScreenEffect">{{ i18n.ts.seasonalScreenEffect }}</MkSwitch>
<MkSwitch v-model="useNativeUIForVideoAudioPlayer">{{ i18n.ts.useNativeUIForVideoAudioPlayer }}</MkSwitch> <MkSwitch v-model="useNativeUIForVideoAudioPlayer">{{ i18n.ts.useNativeUIForVideoAudioPlayer }}</MkSwitch>
</div> </div>
<MkSelect v-model="menuStyle">
<template #label>{{ i18n.ts.menuStyle }}</template>
<option value="auto">{{ i18n.ts.auto }}</option>
<option value="popup">{{ i18n.ts.popup }}</option>
<option value="drawer">{{ i18n.ts.drawer }}</option>
</MkSelect>
<div> <div>
<MkRadios v-model="emojiStyle"> <MkRadios v-model="emojiStyle">
<template #label>{{ i18n.ts.emojiStyle }}</template> <template #label>{{ i18n.ts.emojiStyle }}</template>
@ -225,6 +225,12 @@ SPDX-License-Identifier: AGPL-3.0-only
<template #label>{{ i18n.ts.other }}</template> <template #label>{{ i18n.ts.other }}</template>
<div class="_gaps"> <div class="_gaps">
<MkRadios v-model="hemisphere">
<template #label>{{ i18n.ts.hemisphere }}</template>
<option value="N">{{ i18n.ts._hemisphere.N }}</option>
<option value="S">{{ i18n.ts._hemisphere.S }}</option>
<template #caption>{{ i18n.ts._hemisphere.caption }}</template>
</MkRadios>
<MkFolder> <MkFolder>
<template #label>{{ i18n.ts.additionalEmojiDictionary }}</template> <template #label>{{ i18n.ts.additionalEmojiDictionary }}</template>
<div class="_buttons"> <div class="_buttons">
@ -244,6 +250,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<script lang="ts" setup> <script lang="ts" setup>
import { computed, ref, watch } from 'vue'; import { computed, ref, watch } from 'vue';
import * as Misskey from 'misskey-js'; import * as Misskey from 'misskey-js';
import { langs } from '@@/js/config.js';
import MkSwitch from '@/components/MkSwitch.vue'; import MkSwitch from '@/components/MkSwitch.vue';
import MkSelect from '@/components/MkSelect.vue'; import MkSelect from '@/components/MkSelect.vue';
import MkRadios from '@/components/MkRadios.vue'; import MkRadios from '@/components/MkRadios.vue';
@ -254,7 +261,6 @@ import FormSection from '@/components/form/section.vue';
import FormLink from '@/components/form/link.vue'; import FormLink from '@/components/form/link.vue';
import MkLink from '@/components/MkLink.vue'; import MkLink from '@/components/MkLink.vue';
import MkInfo from '@/components/MkInfo.vue'; import MkInfo from '@/components/MkInfo.vue';
import { langs } from '@@/js/config.js';
import { defaultStore } from '@/store.js'; import { defaultStore } from '@/store.js';
import * as os from '@/os.js'; import * as os from '@/os.js';
import { misskeyApi } from '@/scripts/misskey-api.js'; import { misskeyApi } from '@/scripts/misskey-api.js';
@ -287,7 +293,7 @@ const advancedMfm = computed(defaultStore.makeGetterSetter('advancedMfm'));
const showReactionsCount = computed(defaultStore.makeGetterSetter('showReactionsCount')); const showReactionsCount = computed(defaultStore.makeGetterSetter('showReactionsCount'));
const enableQuickAddMfmFunction = computed(defaultStore.makeGetterSetter('enableQuickAddMfmFunction')); const enableQuickAddMfmFunction = computed(defaultStore.makeGetterSetter('enableQuickAddMfmFunction'));
const emojiStyle = computed(defaultStore.makeGetterSetter('emojiStyle')); const emojiStyle = computed(defaultStore.makeGetterSetter('emojiStyle'));
const disableDrawer = computed(defaultStore.makeGetterSetter('disableDrawer')); const menuStyle = computed(defaultStore.makeGetterSetter('menuStyle'));
const disableShowingAnimatedImages = computed(defaultStore.makeGetterSetter('disableShowingAnimatedImages')); const disableShowingAnimatedImages = computed(defaultStore.makeGetterSetter('disableShowingAnimatedImages'));
const forceShowAds = computed(defaultStore.makeGetterSetter('forceShowAds')); const forceShowAds = computed(defaultStore.makeGetterSetter('forceShowAds'));
const loadRawImages = computed(defaultStore.makeGetterSetter('loadRawImages')); const loadRawImages = computed(defaultStore.makeGetterSetter('loadRawImages'));

View file

@ -39,6 +39,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<script lang="ts" setup> <script lang="ts" setup>
import { onMounted, onUnmounted, ref } from 'vue'; import { onMounted, onUnmounted, ref } from 'vue';
import { v4 as uuid } from 'uuid'; import { v4 as uuid } from 'uuid';
import { version, host } from '@@/js/config.js';
import FormSection from '@/components/form/section.vue'; import FormSection from '@/components/form/section.vue';
import MkButton from '@/components/MkButton.vue'; import MkButton from '@/components/MkButton.vue';
import MkInfo from '@/components/MkInfo.vue'; import MkInfo from '@/components/MkInfo.vue';
@ -49,7 +50,6 @@ import { unisonReload } from '@/scripts/unison-reload.js';
import { useStream } from '@/stream.js'; import { useStream } from '@/stream.js';
import { $i } from '@/account.js'; import { $i } from '@/account.js';
import { i18n } from '@/i18n.js'; import { i18n } from '@/i18n.js';
import { version, host } from '@@/js/config.js';
import { definePageMetadata } from '@/scripts/page-metadata.js'; import { definePageMetadata } from '@/scripts/page-metadata.js';
import { miLocalStorage } from '@/local-storage.js'; import { miLocalStorage } from '@/local-storage.js';
@ -75,7 +75,7 @@ const defaultStoreSaveKeys: (keyof typeof defaultStore['state'])[] = [
'dataSaver', 'dataSaver',
'disableShowingAnimatedImages', 'disableShowingAnimatedImages',
'emojiStyle', 'emojiStyle',
'disableDrawer', 'menuStyle',
'useBlurEffectForModal', 'useBlurEffectForModal',
'useBlurEffect', 'useBlurEffect',
'showFixedPostForm', 'showFixedPostForm',

View file

@ -5,10 +5,12 @@
import { markRaw, ref } from 'vue'; import { markRaw, ref } from 'vue';
import * as Misskey from 'misskey-js'; import * as Misskey from 'misskey-js';
import { hemisphere } from '@@/js/intl-const.js';
import lightTheme from '@@/themes/l-light.json5';
import darkTheme from '@@/themes/d-green-lime.json5';
import { miLocalStorage } from './local-storage.js'; import { miLocalStorage } from './local-storage.js';
import type { SoundType } from '@/scripts/sound.js'; import type { SoundType } from '@/scripts/sound.js';
import { Storage } from '@/pizzax.js'; import { Storage } from '@/pizzax.js';
import { hemisphere } from '@@/js/intl-const.js';
interface PostFormAction { interface PostFormAction {
title: string, title: string,
@ -250,9 +252,9 @@ export const defaultStore = markRaw(new Storage('base', {
where: 'device', where: 'device',
default: 'twemoji', // twemoji / fluentEmoji / native default: 'twemoji', // twemoji / fluentEmoji / native
}, },
disableDrawer: { menuStyle: {
where: 'device', where: 'device',
default: false, default: 'auto' as 'auto' | 'popup' | 'drawer',
}, },
useBlurEffectForModal: { useBlurEffectForModal: {
where: 'device', where: 'device',
@ -520,8 +522,6 @@ interface Watcher {
/** /**
* () * ()
*/ */
import lightTheme from '@@/themes/l-light.json5';
import darkTheme from '@@/themes/d-green-lime.json5';
export class ColdDeviceStorage { export class ColdDeviceStorage {
public static default = { public static default = {