refactor(stage-tamagotchi): adjustable control island icon size (#923)

This commit is contained in:
leafyy
2026-01-09 17:35:49 +08:00
committed by GitHub
parent 125a934d27
commit a0700303d8
5 changed files with 77 additions and 27 deletions
@@ -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 />
@@ -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>
@@ -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}。