仰望星辰工作室

starmusic-pc

starmusic-pc/ frontend/src/composables/useShell.js 3.7 KB · 110 行 原始文件
1/**
2 * 应用外壳状态:极简路由 + 面板开关
3 *
4 * 桌面端不需要完整的路由库:主区域用 <component :is> 切换视图,
5 * 播放详情与播放队列是覆盖层,启动页是首启动覆盖层。
6 */
7import { ref, shallowRef, computed } from 'vue'
8
9/** 左侧导航项 */
10export const NAV_ITEMS = [
11 { key: 'search', label: '搜索', icon: 'search', desc: '搜索歌曲、歌手、专辑' },
12 { key: 'playlists', label: '我的歌单', icon: 'list-music', desc: '试听列表 / 收藏 / 自建歌单' },
13 { key: 'settings', label: '设置', icon: 'settings', desc: '音源、播放、外观与诊断' },
14 { key: 'account', label: '账号与云同步', icon: 'user', desc: '登录后同步歌单与音源' },
15 { key: 'about', label: '关于', icon: 'star', desc: '仰望星辰工作室出品' },
16]
17
18const VIEW_KEYS = NAV_ITEMS.map((v) => v.key)
19
20/** 当前主视图 */
21export const currentView = shallowRef('search')
22/** 视图切换方向:1 前进 / -1 后退,用于选择过渡动画方向 */
23export const viewDirection = ref(1)
24
25/** 播放详情(全窗口覆盖层) */
26export const nowPlayingOpen = ref(false)
27/** 播放队列抽屉 */
28export const queueOpen = ref(false)
29/** 启动页 */
30export const splashVisible = ref(true)
31/** 迷你播放器模式 */
32export const miniMode = ref(false)
33/** 侧边栏折叠(窄窗口或用户手动折叠) */
34export const sidebarCollapsed = ref(false)
35/** 歌单页要打开的目标列表 id(供侧边栏快捷入口使用) */
36export const playlistTarget = ref('default')
37
38/**
39 * 打开歌单页并定位到指定列表
40 * @param {string} listId 'default' | 'love' | 自定义歌单 id
41 */
42export function openPlaylist(listId) {
43 playlistTarget.value = listId || 'default'
44 go('playlists')
45}
46
47/**
48 * 切换主视图
49 * @param {string} key
50 */
51export function go(key) {
52 if (!VIEW_KEYS.includes(key) || key === currentView.value) {
53 // 同视图重复点击:把内容滚动回顶部,给出「已响应」的反馈
54 if (key === currentView.value) {
55 const el = document.querySelector('.view-scroll')
56 if (el) el.scrollTo({ top: 0, behavior: 'smooth' })
57 }
58 return
59 }
60 const from = VIEW_KEYS.indexOf(currentView.value)
61 const to = VIEW_KEYS.indexOf(key)
62 viewDirection.value = to >= from ? 1 : -1
63 currentView.value = key
64}
65
66/** 打开播放详情层 */
67export function openNowPlaying() {
68 nowPlayingOpen.value = true
69}
70
71/** 关闭播放详情层 */
72export function closeNowPlaying() {
73 nowPlayingOpen.value = false
74}
75
76/** 打开/关闭播放队列 */
77export function toggleQueue(force) {
78 queueOpen.value = typeof force === 'boolean' ? force : !queueOpen.value
79}
80
81/** 退出启动页 */
82export function dismissSplash() {
83 splashVisible.value = false
84}
85
86/** 当前导航项 */
87export const currentNav = computed(() => NAV_ITEMS.find((n) => n.key === currentView.value) || NAV_ITEMS[0])
88
89/**
90 * 注册 uni 路由桥:让移植过来的业务代码里的 uni.navigateTo 仍能指向正确视图
91 * 例:'/pages/play-detail/play-detail' → 打开播放详情层
92 */
93export function registerUniRouterBridge() {
94 if (typeof window === 'undefined' || !window.uni) return
95 window.uni.__registerRouter({
96 open(url) {
97 const path = String(url || '')
98 if (path.indexOf('play-detail') >= 0) return openNowPlaying()
99 if (path.indexOf('pages/index') >= 0 || path.indexOf('splash') >= 0) return go('search')
100 if (path.indexOf('my-list') >= 0) return go('playlists')
101 if (path.indexOf('setting') >= 0) return go('settings')
102 if (path.indexOf('account') >= 0) return go('account')
103 if (path.indexOf('about') >= 0) return go('about')
104 return undefined
105 },
106 back() {
107 if (nowPlayingOpen.value) closeNowPlaying()
108 },
109 })
110}