refactor(stage-tamagotchi): adjustable control island icon size (#923)
This commit is contained in:
+5
@@ -1,3 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
const props = defineProps<{ buttonStyle?: string }>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<button
|
||||
:class="[
|
||||
@@ -6,6 +10,7 @@
|
||||
'w-fit flex items-center self-end justify-center p-2',
|
||||
'rounded-xl backdrop-blur-md',
|
||||
'transition-all hover:transition-none transition-duration-300 transition-ease-out',
|
||||
props.buttonStyle,
|
||||
]"
|
||||
>
|
||||
<slot />
|
||||
|
||||
+12
-2
@@ -9,6 +9,15 @@ import { noticeWindowEventa } from '../../../../shared/eventa'
|
||||
import { useElectronEventaInvoke } from '../../../composables/electron-vueuse/use-electron-eventa-context'
|
||||
import { useControlsIslandStore } from '../../../stores/controls-island'
|
||||
|
||||
interface Props {
|
||||
iconClass?: string
|
||||
buttonStyle?: string
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
iconClass: 'size-5',
|
||||
})
|
||||
|
||||
const uiStore = useControlsIslandStore()
|
||||
const enabled = computed(() => uiStore.fadeOnHoverEnabled)
|
||||
const { t } = useI18n()
|
||||
@@ -45,12 +54,13 @@ async function handleToggle() {
|
||||
<template>
|
||||
<ControlButtonTooltip>
|
||||
<ControlButton
|
||||
:button-style="props.buttonStyle"
|
||||
:class="{ 'border-primary-300/70 shadow-[0_10px_24px_rgba(0,0,0,0.22)]': enabled }"
|
||||
@click="handleToggle"
|
||||
>
|
||||
<Transition name="fade" mode="out-in">
|
||||
<div v-if="enabled" i-ph:eye size-5 text="primary-700 dark:primary-300" />
|
||||
<div v-else i-ph:eye-slash size-5 text="neutral-800 dark:neutral-300" />
|
||||
<div v-if="enabled" i-ph:eye :class="props.iconClass" text="primary-700 dark:primary-300" />
|
||||
<div v-else i-ph:eye-slash :class="props.iconClass" text="neutral-800 dark:neutral-300" />
|
||||
</Transition>
|
||||
</ControlButton>
|
||||
|
||||
|
||||
+41
-22
@@ -2,8 +2,10 @@
|
||||
import { defineInvoke } from '@moeru/eventa'
|
||||
import { useSettingsAudioDevice } from '@proj-airi/stage-ui/stores/settings'
|
||||
import { useTheme } from '@proj-airi/ui'
|
||||
import { useWindowSize } from '@vueuse/core'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { ref } from 'vue'
|
||||
import { computed, ref } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import ControlButtonTooltip from './control-button-tooltip.vue'
|
||||
import ControlButton from './control-button.vue'
|
||||
@@ -16,6 +18,7 @@ import { useElectronEventaContext, useElectronEventaInvoke } from '../../../comp
|
||||
import { isLinux } from '../../../utils/platform'
|
||||
|
||||
const { isDark, toggleDark } = useTheme()
|
||||
const { t } = useI18n()
|
||||
|
||||
const settingsAudioDeviceStore = useSettingsAudioDevice()
|
||||
const context = useElectronEventaContext()
|
||||
@@ -23,6 +26,22 @@ const { enabled } = storeToRefs(settingsAudioDeviceStore)
|
||||
const openSettings = useElectronEventaInvoke(electronOpenSettings)
|
||||
const openChat = useElectronEventaInvoke(electronOpenChat)
|
||||
|
||||
// Responsive icon & button sizing based on window height
|
||||
const { height: windowHeight } = useWindowSize()
|
||||
// Constants: assume each icon placeholder occupies 50px and there are 7 buttons
|
||||
const ICON_PLACEHOLDER_PX = 50
|
||||
const BUTTON_COUNT = 7
|
||||
const LARGE_THRESHOLD = ICON_PLACEHOLDER_PX * BUTTON_COUNT
|
||||
|
||||
// Grouped classes for icon / border / padding and combined style class
|
||||
const adjustStyleClasses = computed(() => {
|
||||
const isLarge = windowHeight.value > LARGE_THRESHOLD
|
||||
const icon = isLarge ? 'size-5' : 'size-3'
|
||||
const border = isLarge ? 'border-2' : 'border-0'
|
||||
const padding = isLarge ? 'p-2' : 'p-0.5'
|
||||
return { icon, border, padding, button: `${border} ${padding}` }
|
||||
})
|
||||
|
||||
/**
|
||||
* This is a know issue (or expected behavior maybe) to Electron.
|
||||
* We don't use this approach on Linux because it's not working.
|
||||
@@ -44,76 +63,76 @@ function refreshWindow() {
|
||||
<div fixed bottom-2 right-2>
|
||||
<div flex flex-col gap-1>
|
||||
<ControlButtonTooltip>
|
||||
<ControlButton @click="openSettings">
|
||||
<div i-solar:settings-minimalistic-outline size-5 text="neutral-800 dark:neutral-300" />
|
||||
<ControlButton :button-style="adjustStyleClasses.button" @click="openSettings">
|
||||
<div i-solar:settings-minimalistic-outline :class="adjustStyleClasses.icon" text="neutral-800 dark:neutral-300" />
|
||||
</ControlButton>
|
||||
|
||||
<template #tooltip>
|
||||
Open settings
|
||||
{{ t('tamagotchi.stage.controls-island.open-settings') }}
|
||||
</template>
|
||||
</ControlButtonTooltip>
|
||||
|
||||
<ControlButtonTooltip>
|
||||
<ControlButton @click="openChat">
|
||||
<div i-solar:chat-line-line-duotone size-5 text="neutral-800 dark:neutral-300" />
|
||||
<ControlButton :button-style="adjustStyleClasses.button" @click="openChat">
|
||||
<div i-solar:chat-line-line-duotone :class="adjustStyleClasses.icon" text="neutral-800 dark:neutral-300" />
|
||||
</ControlButton>
|
||||
|
||||
<template #tooltip>
|
||||
Open Chat
|
||||
{{ t('tamagotchi.stage.controls-island.open-chat') }}
|
||||
</template>
|
||||
</ControlButtonTooltip>
|
||||
|
||||
<ControlButtonTooltip>
|
||||
<ControlButton @click="refreshWindow">
|
||||
<div i-solar:refresh-linear size-5 text="neutral-800 dark:neutral-300" />
|
||||
<ControlButton :button-style="adjustStyleClasses.button" @click="refreshWindow">
|
||||
<div i-solar:refresh-linear :class="adjustStyleClasses.icon" text="neutral-800 dark:neutral-300" />
|
||||
</ControlButton>
|
||||
|
||||
<template #tooltip>
|
||||
Refresh
|
||||
{{ t('tamagotchi.stage.controls-island.refresh') }}
|
||||
</template>
|
||||
</ControlButtonTooltip>
|
||||
|
||||
<ControlButtonTooltip>
|
||||
<ControlsIslandHearingConfig v-model:show="hearingDialogOpen">
|
||||
<div class="relative">
|
||||
<ControlButton>
|
||||
<ControlButton :button-style="adjustStyleClasses.button">
|
||||
<Transition name="fade" mode="out-in">
|
||||
<IndicatorMicVolume v-if="enabled" size-5 />
|
||||
<div v-else i-ph:microphone-slash size-5 text="neutral-800 dark:neutral-300" />
|
||||
<IndicatorMicVolume v-if="enabled" :class="adjustStyleClasses.icon" />
|
||||
<div v-else i-ph:microphone-slash :class="adjustStyleClasses.icon" text="neutral-800 dark:neutral-300" />
|
||||
</Transition>
|
||||
</ControlButton>
|
||||
</div>
|
||||
</ControlsIslandHearingConfig>
|
||||
|
||||
<template #tooltip>
|
||||
Open hearing controls
|
||||
{{ t('tamagotchi.stage.controls-island.open-hearing-controls') }}
|
||||
</template>
|
||||
</ControlButtonTooltip>
|
||||
|
||||
<ControlsIslandFadeOnHover />
|
||||
<ControlsIslandFadeOnHover :icon-class="adjustStyleClasses.icon" :button-style="adjustStyleClasses.button" />
|
||||
|
||||
<ControlButtonTooltip>
|
||||
<ControlButton cursor-move :class="{ 'drag-region': isLinux }" @mousedown="startDraggingWindow?.()">
|
||||
<div i-ph:arrows-out-cardinal size-5 text="neutral-800 dark:neutral-300" />
|
||||
<ControlButton :button-style="adjustStyleClasses.button" cursor-move :class="{ 'drag-region': isLinux }" @mousedown="startDraggingWindow?.()">
|
||||
<div i-ph:arrows-out-cardinal :class="adjustStyleClasses.icon" text="neutral-800 dark:neutral-300" />
|
||||
</ControlButton>
|
||||
|
||||
<template #tooltip>
|
||||
Drag to move window
|
||||
{{ t('tamagotchi.stage.controls-island.drag-to-move-window') }}
|
||||
</template>
|
||||
</ControlButtonTooltip>
|
||||
|
||||
<ControlButtonTooltip>
|
||||
<!-- Recommended to use `toggleDark()` instead of `toggleDark` -->
|
||||
<!-- See: https://vueuse.org/shared/useToggle/#usage -->
|
||||
<ControlButton @click="toggleDark()">
|
||||
<ControlButton :button-style="adjustStyleClasses.button" @click="toggleDark()">
|
||||
<Transition name="fade" mode="out-in">
|
||||
<div v-if="isDark" i-solar:moon-outline size-5 text="neutral-800 dark:neutral-300" />
|
||||
<div v-else i-solar:sun-2-outline size-5 text="neutral-800 dark:neutral-300" />
|
||||
<div v-if="isDark" i-solar:moon-outline :class="adjustStyleClasses.icon" text="neutral-800 dark:neutral-300" />
|
||||
<div v-else i-solar:sun-2-outline :class="adjustStyleClasses.icon" text="neutral-800 dark:neutral-300" />
|
||||
</Transition>
|
||||
</ControlButton>
|
||||
|
||||
<template #tooltip>
|
||||
{{ isDark ? 'Switch to light mode' : 'Switch to dark mode' }}
|
||||
{{ isDark ? t('tamagotchi.stage.controls-island.switch-to-light-mode') : t('tamagotchi.stage.controls-island.switch-to-dark-mode') }}
|
||||
</template>
|
||||
</ControlButtonTooltip>
|
||||
</div>
|
||||
|
||||
@@ -12,6 +12,14 @@ docs:
|
||||
'fade-on-hover':
|
||||
enable: Auto hide
|
||||
disable: Always show
|
||||
'open-settings': Open settings
|
||||
'open-chat': Open Chat
|
||||
'refresh': Refresh
|
||||
'open-hearing-controls': Open hearing Controls
|
||||
'drag-to-move-window': Drag to move window
|
||||
'switch-to-light-mode': Switch to light mode
|
||||
'switch-to-dark-mode': Switch to dark mode
|
||||
|
||||
notice:
|
||||
'fade-on-hover':
|
||||
title: Fade on Hover
|
||||
|
||||
@@ -8,12 +8,20 @@ docs:
|
||||
navbar:
|
||||
appearance:
|
||||
title: 外观
|
||||
'controls-island':
|
||||
'fade-on-hover':
|
||||
controls-island:
|
||||
fade-on-hover:
|
||||
enable: 悬停时隐藏
|
||||
disable: 总是显示
|
||||
open-settings: 打开设置
|
||||
open-chat: 打开聊天
|
||||
refresh: 刷新
|
||||
open-hearing-controls: 打开听力控制
|
||||
drag-to-move-window: 拖拽移动窗口
|
||||
switch-to-light: 切换到亮色模式
|
||||
switch-to-dark: 切换到暗色模式
|
||||
switch-to-dark-mode: 切换到黑暗模式
|
||||
notice:
|
||||
'fade-on-hover':
|
||||
fade-on-hover:
|
||||
title: 悬停淡出
|
||||
intro: 当光标靠近时自动让角色变淡,减少干扰又保持可见。
|
||||
opacity: 开启后,当光标靠近时, {targets} 的不透明度会降到 {value}。
|
||||
|
||||
Reference in New Issue
Block a user