优化侧栏图标显示,修复图标可能被裁切的问题(#1960)
parent
19f81cf379
commit
0acc9a553e
|
@ -2,6 +2,10 @@
|
||||||
|
|
||||||
- 新增 是否将歌词显示在状态栏 设置,默认关闭,该功能只在 MacOS 下可用(#1940)
|
- 新增 是否将歌词显示在状态栏 设置,默认关闭,该功能只在 MacOS 下可用(#1940)
|
||||||
|
|
||||||
|
### 优化
|
||||||
|
|
||||||
|
- 优化侧栏图标显示,修复图标可能被裁切的问题(#1960)
|
||||||
|
|
||||||
### 修复
|
### 修复
|
||||||
|
|
||||||
- 修复 MacOS 下点击 dock 右键菜单的退出按钮时,程序没有退出的问题(#1923)
|
- 修复 MacOS 下点击 dock 右键菜单的退出按钮时,程序没有退出的问题(#1923)
|
||||||
|
|
|
@ -1,82 +1,94 @@
|
||||||
<template>
|
<template>
|
||||||
<div :class="$style.menu">
|
<div ref="dom_menu" :class="$style.menu">
|
||||||
<ul :class="$style.list" role="toolbar">
|
<ul :class="$style.list" role="toolbar">
|
||||||
<li v-for="item in menus" :key="item.to" :class="$style.navItem" role="presentation">
|
<li v-for="item in menus" :key="item.to" :class="$style.navItem" role="presentation">
|
||||||
<router-link :class="[$style.link, {[$style.active]: $route.meta.name == item.name}]" role="tab" :aria-selected="$route.meta.name == item.name" :to="item.to" :aria-label="item.tips">
|
<router-link :class="[$style.link, {[$style.active]: $route.meta.name == item.name}]" role="tab" :aria-selected="$route.meta.name == item.name" :to="item.to" :aria-label="item.tips">
|
||||||
<div :class="$style.icon">
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" :viewBox="item.iconSize" :height="item.size" :width="item.size" space="preserve">
|
||||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" :viewBox="item.iconSize" space="preserve">
|
<use :xlink:href="item.icon" />
|
||||||
<use :xlink:href="item.icon" />
|
</svg>
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script lang="ts">
|
||||||
import { appSetting } from '@renderer/store/setting'
|
import { appSetting } from '@renderer/store/setting'
|
||||||
|
import { useI18n } from '@root/lang'
|
||||||
|
import { ref, computed } from '@common/utils/vueTools'
|
||||||
|
import { useIconSize } from '@renderer/utils/compositions/useIconSize'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'NavBar',
|
name: 'NavBar',
|
||||||
setup() {
|
setup() {
|
||||||
return {
|
const t = useI18n()
|
||||||
appSetting,
|
const dom_menu = ref<HTMLElement>()
|
||||||
}
|
const iconSize = useIconSize(dom_menu, 0.32)
|
||||||
},
|
|
||||||
computed: {
|
const menus = computed(() => {
|
||||||
menus() {
|
const size = iconSize.value
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
to: '/search',
|
to: '/search',
|
||||||
tips: this.$t('search'),
|
tips: t('search'),
|
||||||
icon: '#icon-search-2',
|
icon: '#icon-search-2',
|
||||||
iconSize: '0 0 425.2 425.2',
|
iconSize: '0 0 425.2 425.2',
|
||||||
|
size,
|
||||||
name: 'Search',
|
name: 'Search',
|
||||||
enable: true,
|
enable: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
to: '/songList/list',
|
to: '/songList/list',
|
||||||
tips: this.$t('song_list'),
|
tips: t('song_list'),
|
||||||
icon: '#icon-album',
|
icon: '#icon-album',
|
||||||
iconSize: '0 0 425.2 425.2',
|
iconSize: '0 0 425.2 425.2',
|
||||||
|
size,
|
||||||
name: 'SongList',
|
name: 'SongList',
|
||||||
enable: true,
|
enable: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
to: '/leaderboard',
|
to: '/leaderboard',
|
||||||
tips: this.$t('leaderboard'),
|
tips: t('leaderboard'),
|
||||||
icon: '#icon-leaderboard',
|
icon: '#icon-leaderboard',
|
||||||
iconSize: '0 0 425.22 425.2',
|
iconSize: '0 0 425.22 425.2',
|
||||||
|
size,
|
||||||
name: 'Leaderboard',
|
name: 'Leaderboard',
|
||||||
enable: true,
|
enable: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
to: '/list',
|
to: '/list',
|
||||||
tips: this.$t('my_list'),
|
tips: t('my_list'),
|
||||||
icon: '#icon-love',
|
icon: '#icon-love',
|
||||||
iconSize: '0 0 444.87 391.18',
|
iconSize: '0 0 444.87 391.18',
|
||||||
|
size,
|
||||||
name: 'List',
|
name: 'List',
|
||||||
enable: true,
|
enable: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
to: '/download',
|
to: '/download',
|
||||||
tips: this.$t('download'),
|
tips: t('download'),
|
||||||
icon: '#icon-download-2',
|
icon: '#icon-download-2',
|
||||||
iconSize: '0 0 425.2 425.2',
|
iconSize: '0 0 425.2 425.2',
|
||||||
enable: this.appSetting['download.enable'],
|
size,
|
||||||
|
enable: appSetting['download.enable'],
|
||||||
name: 'Download',
|
name: 'Download',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
to: '/setting',
|
to: '/setting',
|
||||||
tips: this.$t('setting'),
|
tips: t('setting'),
|
||||||
icon: '#icon-setting',
|
icon: '#icon-setting',
|
||||||
iconSize: '0 0 493.23 436.47',
|
iconSize: '0 0 493.23 436.47',
|
||||||
|
size,
|
||||||
enable: true,
|
enable: true,
|
||||||
name: 'Setting',
|
name: 'Setting',
|
||||||
},
|
},
|
||||||
].filter(m => m.enable)
|
].filter(m => m.enable)
|
||||||
},
|
})
|
||||||
|
return {
|
||||||
|
appSetting,
|
||||||
|
menus,
|
||||||
|
dom_menu,
|
||||||
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -141,7 +153,7 @@ export default {
|
||||||
transition-property: background-color, opacity;
|
transition-property: background-color, opacity;
|
||||||
color: var(--color-nav-font);
|
color: var(--color-nav-font);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: 11.5px;
|
// font-size: 11.5px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
outline: none;
|
outline: none;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -190,11 +202,11 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon {
|
// .icon {
|
||||||
// margin-bottom: 5px;
|
// // margin-bottom: 5px;
|
||||||
&> svg {
|
// &> svg {
|
||||||
width: 32%;
|
// width: 32%;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
import { type Ref, onBeforeUnmount, onMounted, ref } from '@common/utils/vueTools'
|
||||||
|
|
||||||
|
const onDomSizeChanged = (dom: HTMLElement, onChanged: (width: number, height: number) => void) => {
|
||||||
|
// 使用 ResizeObserver 监听大小变化
|
||||||
|
const resizeObserver = new ResizeObserver(entries => {
|
||||||
|
for (let entry of entries) {
|
||||||
|
const { width, height } = entry.contentRect
|
||||||
|
// console.log(dom.offsetLeft, dom.offsetTop, left, top, width, height)
|
||||||
|
onChanged(Math.trunc(width), Math.trunc(height))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
resizeObserver.observe(dom)
|
||||||
|
|
||||||
|
onChanged(dom.clientWidth, dom.clientHeight)
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
resizeObserver.disconnect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useIconSize = (parentDom: Ref<HTMLElement | undefined>, size: number) => {
|
||||||
|
const iconSize = ref('32px')
|
||||||
|
let unsub: (() => void) | null = null
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
if (!parentDom.value) return
|
||||||
|
unsub = onDomSizeChanged(parentDom.value, (width, height) => {
|
||||||
|
iconSize.value = Math.trunc(width * size) + 'px'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
unsub?.()
|
||||||
|
})
|
||||||
|
|
||||||
|
return iconSize
|
||||||
|
}
|
Loading…
Reference in New Issue