排行榜
-- {currentPlaylistTitle} -
- {songs[0]?.platform ?歌单列表
- {loadingUserPlaylists ? ( -- -
{selectedUserPlaylist.name}
- {selectedUserPlaylist.description && ( -{selectedUserPlaylist.description}
- )} -选择一个歌单查看详情
-diff --git a/src/app/music/MusicClient.tsx b/src/app/music/MusicClient.tsx index a202f18..00243b1 100644 --- a/src/app/music/MusicClient.tsx +++ b/src/app/music/MusicClient.tsx @@ -24,10 +24,10 @@ function getApiErrorMessage(error: unknown, fallback: string): string { return fallback; } -type MusicSource = 'wy' | 'tx' | 'kw' | 'kg' | 'mg'; -type MusicQuality = '128k' | '320k' | 'flac' | 'flac24bit'; +export type MusicSource = 'wy' | 'tx' | 'kw' | 'kg' | 'mg'; +export type MusicQuality = '128k' | '320k' | 'flac' | 'flac24bit'; -interface Song { +export interface Song { id: string; name: string; artist: string; @@ -53,7 +53,7 @@ interface LyricLine { translation?: string; } -interface Playlist { +export interface Playlist { id: string; name: string; pic?: string; @@ -77,7 +77,7 @@ interface DbRecord { songmid?: string; } -function MusicLoadingIndicator({ +export function MusicLoadingIndicator({ text, size = 'md', className = '', @@ -1300,6 +1300,79 @@ export default function MusicClient({ children: _children }: { children?: React. }); }; + + const handlePlayAllCurrentSongsWith = async (targetSongs: Song[], title: string) => { + setLoadingCurrentPlayAll(true); + + try { + if (targetSongs.length === 0) { + setToast({ message: '当前列表为空', type: 'error', onClose: () => setToast(null) }); + return; + } + + await fetch('/api/music/v2/history', { method: 'DELETE' }); + const baseTime = Date.now(); + const recordsToAdd = targetSongs.map((song, i) => ({ + song: { + songId: song.id, + source: song.platform, + songmid: song.songmid, + name: song.name, + artist: song.artist, + album: song.album, + cover: song.pic, + durationSec: song.duration || 0, + durationText: song.durationText, + }, + playProgressSec: 0, + lastPlayedAt: baseTime + i, + playCount: 1, + lastQuality: quality, + createdAt: baseTime + i, + })); + await fetch('/api/music/v2/history', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ records: recordsToAdd }), + }); + const newRecords: PlayRecord[] = targetSongs.map((song, i) => ({ + platform: song.platform, + id: song.id, + playTime: 0, + duration: song.duration || 0, + timestamp: baseTime + i, + })); + setPlayRecords(newRecords); + setPlaylist(targetSongs); + setPlaylistIndex(0); + await playSong(targetSongs[0], 0); + setToast({ message: `已开始播放 ${title}`, type: 'success', onClose: () => setToast(null) }); + } catch (error) { + console.error('播放全部失败:', error); + setToast({ message: '播放全部失败', type: 'error', onClose: () => setToast(null) }); + } finally { + setLoadingCurrentPlayAll(false); + } + }; + + const addSongToQueue = async (song: Song) => { + if (!currentSong && playlist.length === 0 && playRecords.length === 0) { + await playSong(song, -1); + return; + } + const platform = song.platform || currentSource; + const exists = playlist.some((item) => item.id === song.id && item.platform === platform); + if (exists) { + setToast({ message: '歌曲已在播放列表中', type: 'info', onClose: () => setToast(null) }); + return; + } + const record: PlayRecord = { platform, id: song.id, playTime: 0, duration: song.duration || 0, timestamp: Date.now() }; + setPlayRecords((prev) => [...prev, record]); + setPlaylist((prev) => [...prev, { ...song, platform }]); + saveHistoryRecordSafely(record, { ...song, platform }, 0, song.duration || 0); + setToast({ message: '已添加到稍后播放', type: 'success', onClose: () => setToast(null) }); + }; + // 播放歌曲 const playSong = async (song: Song, index: number) => { beginResolving(); @@ -2285,6 +2358,48 @@ export default function MusicClient({ children: _children }: { children?: React. }; }, []); + + useEffect(() => { + const handlePlaySongEvent = (event: Event) => { + const detail = (event as CustomEvent<{ song: Song; index?: number }>).detail; + if (detail?.song) void playSong(detail.song, detail.index ?? -1); + }; + + const handlePlayAllEvent = (event: Event) => { + const detail = (event as CustomEvent<{ songs: Song[]; title?: string }>).detail; + if (!detail?.songs?.length) return; + setSongs(detail.songs); + setCurrentPlaylistTitle(detail.title || '当前列表'); + setActiveSearchKeyword(''); + void handlePlayAllCurrentSongsWith(detail.songs, detail.title || '当前列表'); + }; + + const handleAddToPlaylistEvent = (event: Event) => { + const detail = (event as CustomEvent<{ song: Song }>).detail; + if (detail?.song) { + setSongToAddToPlaylist(detail.song); + setShowAddToPlaylistModal(true); + } + }; + + const handlePlayLaterEvent = (event: Event) => { + const detail = (event as CustomEvent<{ song: Song }>).detail; + if (!detail?.song) return; + void addSongToQueue(detail.song); + }; + + window.addEventListener('music:play-song', handlePlaySongEvent); + window.addEventListener('music:play-all', handlePlayAllEvent); + window.addEventListener('music:add-to-playlist', handleAddToPlaylistEvent); + window.addEventListener('music:play-later', handlePlayLaterEvent); + return () => { + window.removeEventListener('music:play-song', handlePlaySongEvent); + window.removeEventListener('music:play-all', handlePlayAllEvent); + window.removeEventListener('music:add-to-playlist', handleAddToPlaylistEvent); + window.removeEventListener('music:play-later', handlePlayLaterEvent); + }; + }, [songs, playlist, playRecords, currentSong, quality, currentSource]); + return (
{selectedUserPlaylist.description}
- )} -选择一个歌单查看详情
-