diff --git a/package-lock.json b/package-lock.json index ab0b0b7..b8d6d05 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,6 @@ "dependencies": { "@tailwindcss/vite": "^4.1.7", "axios": "^1.9.0", - "debug": "^4.4.1", "gsap": "^3.13.0", "pinia": "^3.0.2", "tailwindcss": "^4.1.7", @@ -22,9 +21,11 @@ "devDependencies": { "@biomejs/biome": "1.9.4", "@types/chrome": "^0.0.323", + "@types/debug": "^4.1.12", "@types/node": "^22.15.21", "@types/webextension-polyfill": "^0.12.3", "@vitejs/plugin-vue": "^5.2.1", + "debug": "^4.4.1", "typescript": "~5.6.2", "vite": "^6.0.1", "vue-tsc": "^2.1.10" @@ -1246,6 +1247,16 @@ "@types/har-format": "*" } }, + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } + }, "node_modules/@types/estree": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", @@ -1276,6 +1287,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/node": { "version": "22.15.21", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.21.tgz", @@ -1618,6 +1636,7 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "dev": true, "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -2317,6 +2336,7 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, "license": "MIT" }, "node_modules/muggle-string": { diff --git a/package.json b/package.json index 5d701a5..7032608 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,6 @@ "dependencies": { "@tailwindcss/vite": "^4.1.7", "axios": "^1.9.0", - "debug": "^4.4.1", "gsap": "^3.13.0", "pinia": "^3.0.2", "tailwindcss": "^4.1.7", @@ -34,9 +33,11 @@ "devDependencies": { "@biomejs/biome": "1.9.4", "@types/chrome": "^0.0.323", + "@types/debug": "^4.1.12", "@types/node": "^22.15.21", "@types/webextension-polyfill": "^0.12.3", "@vitejs/plugin-vue": "^5.2.1", + "debug": "^4.4.1", "typescript": "~5.6.2", "vite": "^6.0.1", "vue-tsc": "^2.1.10" diff --git a/src/App.vue b/src/App.vue index 96c4efb..1a62ced 100644 --- a/src/App.vue +++ b/src/App.vue @@ -2,6 +2,7 @@ import { useRoute, useRouter } from 'vue-router' import MiniPlayer from './components/MiniPlayer.vue' import PreferencePanel from './components/PreferencePanel.vue' +import Player from './components/Player.vue' import { ref } from 'vue' import LeftArrowIcon from './assets/icons/leftarrow.vue' @@ -77,6 +78,7 @@ watch( + diff --git a/src/components/AlbumDetailDialog.vue b/src/components/AlbumDetailDialog.vue index a40c32f..092d5ab 100644 --- a/src/components/AlbumDetailDialog.vue +++ b/src/components/AlbumDetailDialog.vue @@ -140,7 +140,15 @@ watch( const playQueue = usePlayQueueStore() async function playTheAlbum(from: number = 0) { - await playQueue.replaceQueue(album.value?.songs ?? []) + let newQueue = [] + for (const track of album.value?.songs ?? []) { + newQueue.push({ + song: track, + album: album.value + }) + } + await playQueue.replaceQueue(newQueue) + await playQueue.togglePlay(true) } function shuffle() { diff --git a/src/components/Player.vue b/src/components/Player.vue index 67b0222..6f12287 100644 --- a/src/components/Player.vue +++ b/src/components/Player.vue @@ -1,543 +1,54 @@ - \ No newline at end of file + diff --git a/src/stores/usePlayQueueStore.ts b/src/stores/usePlayQueueStore.ts index 916b4af..176f943 100644 --- a/src/stores/usePlayQueueStore.ts +++ b/src/stores/usePlayQueueStore.ts @@ -1,15 +1,15 @@ import { defineStore } from 'pinia' import { ref, computed } from 'vue' -import apis from '../apis' export const usePlayQueueStore = defineStore('queue', () => { // 内部状态 const queue = ref([]) - const isShuffle = ref(false) + const isShuffle = ref(false) const loopingMode = ref<'single' | 'all' | 'off'>('off') - const queueReplaceLock = ref(false) - const currentPlaying = ref(0) // 当前播放指针,指针在 queueOrder 中寻址(无论是否开启了随机播放) + const queueReplaceLock = ref(false) + const currentPlaying = ref(0) // 当前播放指针,指针在 queueOrder 中寻址(无论是否开启了随机播放) const queueOrder = ref([]) // 播放队列顺序 + const isPlaying = ref(false) // 暴露给外部的响应式只读引用 const queueState = computed(() => @@ -26,13 +26,16 @@ export const usePlayQueueStore = defineStore('queue', () => { const actualIndex = queueOrder.value[currentPlaying.value] return queue.value[actualIndex] || null }) + + // 获取当前是否正在播放 + const playingState = computed(() => isPlaying.value) /************ * 播放队列相关 ***********/ // 使用新队列替换老队列 // 队列替换锁开启时启用确认,确认后重置该锁 - async function replaceQueue(songs: Song[]) { + async function replaceQueue(newQueue: QueueItem[]) { if (queueReplaceLock.value) { if ( !confirm( @@ -45,27 +48,6 @@ export const usePlayQueueStore = defineStore('queue', () => { queueReplaceLock.value = false } - let newQueue: QueueItem[] = [] - - // 专辑信息缓存空间 - let albums: { [key: string]: Album } = {} - - for (let i in songs) { - // 写入新队列 - newQueue[newQueue.length] = { - song: songs[i], - album: await (async () => { - if (albums[songs[i].albumCid ?? '0']) - return albums[songs[i].albumCid ?? '0'] - else { - const album = await apis.getAlbum(songs[i].albumCid ?? '0') - albums[songs[i].albumCid ?? '0'] = album - return album - } - })(), - } - } - // 将新队列替换已有队列 queue.value = newQueue @@ -78,6 +60,17 @@ export const usePlayQueueStore = defineStore('queue', () => { loopingMode.value = 'off' } + /*********** + * 播放控制相关 + * + **********/ + // 控制播放 + const togglePlay = (turnTo?: boolean) => { + const newPlayState = turnTo ?? !isPlaying.value + if (newPlayState === isPlaying.value) return + isPlaying.value = newPlayState + } + /************ * 播放模式相关 **********/ @@ -88,6 +81,7 @@ export const usePlayQueueStore = defineStore('queue', () => { if (newShuffleState === isShuffle.value) return // 状态未改变 + // TODO: 进行洗牌 /* if (newShuffleState) { // 开启随机播放:保存当前顺序并打乱 const originalOrder = [...queueOrder.value] @@ -154,10 +148,12 @@ export const usePlayQueueStore = defineStore('queue', () => { loopMode: loopModeState, currentTrack, currentIndex: currentPlaying, + isPlaying: playingState, // 修改方法 replaceQueue, toggleShuffle, toggleLoop, + togglePlay } })