From d970534d920eafab0289743bcc95523ec25f00d9 Mon Sep 17 00:00:00 2001 From: syuilo <Syuilotan@yahoo.co.jp> Date: Thu, 22 Dec 2022 09:01:58 +0900 Subject: [PATCH] enhance(client): improve ux of sound settings --- locales/ja-JP.yml | 1 + .../src/pages/settings/sounds.sound.vue | 45 +++++++++++ packages/client/src/pages/settings/sounds.vue | 80 +++---------------- packages/client/src/scripts/sound.ts | 32 ++++++++ 4 files changed, 89 insertions(+), 69 deletions(-) create mode 100644 packages/client/src/pages/settings/sounds.sound.vue diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 7737e6044e..001749468a 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -509,6 +509,7 @@ deleteAll: "å…¨ã¦å‰Šé™¤" showFixedPostForm: "タイムライン上部ã«æŠ•ç¨¿ãƒ•ã‚©ãƒ¼ãƒ を表示ã™ã‚‹" newNoteRecived: "æ–°ã—ã„ノートãŒã‚ã‚Šã¾ã™" sounds: "サウンド" +sound: "サウンド" listen: "è´ã" none: "ãªã—" showInPage: "ページã§è¡¨ç¤º" diff --git a/packages/client/src/pages/settings/sounds.sound.vue b/packages/client/src/pages/settings/sounds.sound.vue new file mode 100644 index 0000000000..62627c6333 --- /dev/null +++ b/packages/client/src/pages/settings/sounds.sound.vue @@ -0,0 +1,45 @@ +<template> +<div class="_formRoot"> + <FormSelect v-model="type"> + <template #label>{{ i18n.ts.sound }}</template> + <option v-for="x in soundsTypes" :key="x" :value="x">{{ x == null ? i18n.ts.none : x }}</option> + </FormSelect> + <FormRange v-model="volume" :min="0" :max="1" :step="0.05" :text-converter="(v) => `${Math.floor(v * 100)}%`" class="_formBlock"> + <template #label>{{ i18n.ts.volume }}</template> + </FormRange> + + <div style="display: flex; gap: var(--margin); flex-wrap: wrap;"> + <FormButton inline @click="listen"><i class="ti ti-player-play"></i> {{ i18n.ts.listen }}</FormButton> + <FormButton inline primary @click="save"><i class="ti ti-check"></i> {{ i18n.ts.save }}</FormButton> + </div> +</div> +</template> + +<script lang="ts" setup> +import { } from 'vue'; +import FormSelect from '@/components/form/select.vue'; +import FormButton from '@/components/MkButton.vue'; +import FormRange from '@/components/form/range.vue'; +import { i18n } from '@/i18n'; +import { playFile, soundsTypes } from '@/scripts/sound'; + +const props = defineProps<{ + type: string; + volume: number; +}>(); + +const emit = defineEmits<{ + (ev: 'update', result: { type: string; volume: number; }): void; +}>(); + +let type = $ref(props.type); +let volume = $ref(props.volume); + +function listen() { + playFile(type, volume); +} + +function save() { + emit('update', { type, volume }); +} +</script> diff --git a/packages/client/src/pages/settings/sounds.vue b/packages/client/src/pages/settings/sounds.vue index 2bea491e67..ef60b2c3c9 100644 --- a/packages/client/src/pages/settings/sounds.vue +++ b/packages/client/src/pages/settings/sounds.vue @@ -6,11 +6,12 @@ <FormSection> <template #label>{{ i18n.ts.sounds }}</template> - <FormLink v-for="type in Object.keys(sounds)" :key="type" style="margin-bottom: 8px;" @click="edit(type)"> - {{ $t('_sfx.' + type) }} - <template #suffix>{{ sounds[type].type || i18n.ts.none }}</template> - <template #suffixIcon><i class="ti ti-chevron-down"></i></template> - </FormLink> + <FormFolder v-for="type in Object.keys(sounds)" :key="type" style="margin-bottom: 8px;"> + <template #label>{{ $t('_sfx.' + type) }}</template> + <template #suffix>{{ sounds[type].type ?? i18n.ts.none }}</template> + + <XSound :type="sounds[type].type" :volume="sounds[type].volume" @update="(res) => updated(type, res)"/> + </FormFolder> </FormSection> <FormButton danger class="_formBlock" @click="reset()"><i class="ti ti-reload"></i> {{ i18n.ts.default }}</FormButton> @@ -19,10 +20,12 @@ <script lang="ts" setup> import { computed, ref } from 'vue'; +import XSound from './sounds.sound.vue'; import FormRange from '@/components/form/range.vue'; import FormButton from '@/components/MkButton.vue'; import FormLink from '@/components/form/link.vue'; import FormSection from '@/components/form/section.vue'; +import FormFolder from '@/components/form/folder.vue'; import * as os from '@/os'; import { ColdDeviceStorage } from '@/store'; import { playFile } from '@/scripts/sound'; @@ -50,71 +53,10 @@ const sounds = ref({ channel: ColdDeviceStorage.get('sound_channel'), }); -const soundsTypes = [ - null, - 'syuilo/up', - 'syuilo/down', - 'syuilo/pope1', - 'syuilo/pope2', - 'syuilo/waon', - 'syuilo/popo', - 'syuilo/triple', - 'syuilo/poi1', - 'syuilo/poi2', - 'syuilo/pirori', - 'syuilo/pirori-wet', - 'syuilo/pirori-square-wet', - 'syuilo/square-pico', - 'syuilo/reverved', - 'syuilo/ryukyu', - 'syuilo/kick', - 'syuilo/snare', - 'syuilo/queue-jammed', - 'aisha/1', - 'aisha/2', - 'aisha/3', - 'noizenecio/kick_gaba1', - 'noizenecio/kick_gaba2', - 'noizenecio/kick_gaba3', - 'noizenecio/kick_gaba4', - 'noizenecio/kick_gaba5', - 'noizenecio/kick_gaba6', - 'noizenecio/kick_gaba7', -]; - -async function edit(type) { - const { canceled, result } = await os.form(i18n.t('_sfx.' + type), { - type: { - type: 'enum', - enum: soundsTypes.map(x => ({ - value: x, - label: x == null ? i18n.ts.none : x, - })), - label: i18n.ts.sound, - default: sounds.value[type].type, - }, - volume: { - type: 'range', - min: 0, - max: 1, - step: 0.05, - textConverter: (v) => `${Math.floor(v * 100)}%`, - label: i18n.ts.volume, - default: sounds.value[type].volume, - }, - listen: { - type: 'button', - content: i18n.ts.listen, - action: (_, values) => { - playFile(values.type, values.volume); - }, - }, - }); - if (canceled) return; - +async function updated(type, sound) { const v = { - type: result.type, - volume: result.volume, + type: sound.type, + volume: sound.volume, }; ColdDeviceStorage.set('sound_' + type, v); diff --git a/packages/client/src/scripts/sound.ts b/packages/client/src/scripts/sound.ts index 2b8279b3df..9d1f603235 100644 --- a/packages/client/src/scripts/sound.ts +++ b/packages/client/src/scripts/sound.ts @@ -2,6 +2,38 @@ import { ColdDeviceStorage } from '@/store'; const cache = new Map<string, HTMLAudioElement>(); +export const soundsTypes = [ + null, + 'syuilo/up', + 'syuilo/down', + 'syuilo/pope1', + 'syuilo/pope2', + 'syuilo/waon', + 'syuilo/popo', + 'syuilo/triple', + 'syuilo/poi1', + 'syuilo/poi2', + 'syuilo/pirori', + 'syuilo/pirori-wet', + 'syuilo/pirori-square-wet', + 'syuilo/square-pico', + 'syuilo/reverved', + 'syuilo/ryukyu', + 'syuilo/kick', + 'syuilo/snare', + 'syuilo/queue-jammed', + 'aisha/1', + 'aisha/2', + 'aisha/3', + 'noizenecio/kick_gaba1', + 'noizenecio/kick_gaba2', + 'noizenecio/kick_gaba3', + 'noizenecio/kick_gaba4', + 'noizenecio/kick_gaba5', + 'noizenecio/kick_gaba6', + 'noizenecio/kick_gaba7', +] as const; + export function getAudio(file: string, useCache = true): HTMLAudioElement { let audio: HTMLAudioElement; if (useCache && cache.has(file)) { -- GitLab