feat: v0.8.0 详情页架构重构、皮肤系统、侧边栏交互升级、底层模块拆分

- 详情页统一 DetailLayout 组件(常驻头部 + 独立滚动 + 紧凑态动画)
- 歌曲/评论 tab 切换(懒加载 + 保活),专辑模糊搜索
- 皮肤系统 skins.ts(19 语义色 + 14 预设 + 自定义皮肤 + 壁纸)
- 设置页皮肤模块(外观/主题色/皮肤编辑器/壁纸选择)
- 可折叠侧边栏 + TopBar + 折叠态歌单浮层(高度不越 PlayerBar)
- 首页扩展至 6 区块 + 通用卡片组件 + 虚拟歌曲列表
- audio.rs 拆为 8 模块,api.ts 拆为 api/ 目录,player store 拆为 4 store
- 修复播放竞态、seek 暂停、评论提前加载、紧凑态卡死等
This commit is contained in:
2026-06-26 21:05:51 +08:00
parent dcfada6940
commit 263e9b31d9
74 changed files with 5843 additions and 2449 deletions
+9 -6
View File
@@ -3,10 +3,10 @@
class="fixed bottom-0 left-0 right-0 z-50 select-none backdrop-blur-xl"
:style="playerBarBgStyle"
>
<div v-if="player.dominantColor"
<div v-if="ui.dominantColor"
class="absolute inset-0 pointer-events-none transition-opacity duration-300"
:class="drawerActive ? 'opacity-100' : 'opacity-0'"
:style="{ backgroundColor: player.dominantColor }"
:style="{ backgroundColor: ui.dominantColor }"
>
<div class="absolute inset-0 bg-black/60"></div>
</div>
@@ -24,10 +24,10 @@
<div class="flex items-center px-6 h-16 relative z-10">
<div class="flex items-center gap-3 w-56 min-w-0">
<div v-if="getCoverUrl(player.currentSong)" class="w-10 h-10 rounded-md overflow-hidden flex-shrink-0 cursor-pointer hover:scale-105 transition-transform" @click="player.toggleRoamDrawer()" title="全屏展示">
<div v-if="getCoverUrl(player.currentSong)" class="w-10 h-10 rounded-md overflow-hidden flex-shrink-0 cursor-pointer hover:scale-105 transition-transform" @click="ui.toggleRoamDrawer()" title="全屏展示">
<img :src="getCoverUrl(player.currentSong)" class="w-full h-full object-cover" />
</div>
<div v-else class="w-10 h-10 rounded-md flex-shrink-0 flex items-center justify-center cursor-pointer hover:scale-105 transition-transform" @click="player.toggleRoamDrawer()" title="全屏展示"
<div v-else class="w-10 h-10 rounded-md flex-shrink-0 flex items-center justify-center cursor-pointer hover:scale-105 transition-transform" @click="ui.toggleRoamDrawer()" title="全屏展示"
:class="drawerActive ? 'bg-white/10' : 'bg-muted'">
<IconMusic class="w-[18px] h-[18px]" :class="drawerActive ? 'text-white/50' : 'text-content-3'" />
</div>
@@ -213,7 +213,9 @@
<script setup lang="ts">
import { ref, computed, watch, onBeforeUnmount, onMounted, nextTick } from 'vue';
import { usePlayerStore, PlayMode } from '../stores/player';
import { usePlayerStore } from '../stores/player';
import type { PlayMode } from '../types/song';
import { useUiStore } from '../stores/ui';
import { useSettingsStore } from '../stores/settings';
import { useDownload } from '../composables/useDownload';
import { formatTime } from '../utils/format';
@@ -246,9 +248,10 @@ import { hexToRgba } from '../utils/color';
const router = useRouter();
const player = usePlayerStore();
const ui = useUiStore();
const settings = useSettingsStore();
const download = useDownload();
const drawerActive = computed(() => player.showRoamDrawer && !!player.dominantColor);
const drawerActive = computed(() => ui.showRoamDrawer && !!ui.dominantColor);
// PlayerBar 背景:有壁纸时用 --c-bg 高不透明度(与遮罩层同色系,视觉融合),
// 无壁纸时用 surface 色