From b949b6da91f63f5015bf199976d76d643bfa0eba Mon Sep 17 00:00:00 2001 From: mtvpls Date: Tue, 19 May 2026 16:15:46 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=9F=B3=E4=B9=90=E5=88=86?= =?UTF-8?q?=E9=A1=B5=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/music/page.tsx | 102 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 98 insertions(+), 4 deletions(-) diff --git a/src/app/music/page.tsx b/src/app/music/page.tsx index 7e64d59..7dc0b39 100644 --- a/src/app/music/page.tsx +++ b/src/app/music/page.tsx @@ -201,6 +201,10 @@ export default function MusicPage() { const [currentView, setCurrentView] = useState<'playlists' | 'songs' | 'myPlaylists'>('playlists'); const [currentPlaylistTitle, setCurrentPlaylistTitle] = useState(''); const [searchKeyword, setSearchKeyword] = useState(''); + const [activeSearchKeyword, setActiveSearchKeyword] = useState(''); + const [searchPage, setSearchPage] = useState(1); + const [searchHasMore, setSearchHasMore] = useState(false); + const [loadingMoreSearch, setLoadingMoreSearch] = useState(false); const [currentSong, setCurrentSong] = useState(null); const [isPlaying, setIsPlaying] = useState(false); const [currentTime, setCurrentTime] = useState(0); @@ -277,6 +281,7 @@ export default function MusicPage() { const audioRef = useRef(null); const lyricsContainerRef = useRef(null); + const searchLoadMoreRef = useRef(null); const lastSaveTimeRef = useRef(0); const restoredTimeRef = useRef(0); const songStartTimeRef = useRef(0); // 歌曲开始播放的时间戳 @@ -702,6 +707,9 @@ export default function MusicPage() { const data = await response.json(); setSongs((data.data?.list || []).map(mapSong)); setCurrentPlaylistTitle(playlistName); + setActiveSearchKeyword(''); + setSearchPage(1); + setSearchHasMore(false); setCurrentView('songs'); } catch (error) { console.error('加载歌单失败:', error); @@ -785,25 +793,68 @@ export default function MusicPage() { // 搜索歌曲 const searchSongs = async () => { - if (!searchKeyword.trim()) return; + const keyword = searchKeyword.trim(); + if (!keyword) return; setLoading(true); try { const response = await fetch( - `/api/music/v2/search?source=${currentSource}&q=${encodeURIComponent(searchKeyword)}&page=1&limit=20` + `/api/music/v2/search?source=${currentSource}&q=${encodeURIComponent(keyword)}&page=1&limit=20` ); const data = await response.json(); setSongs((data.data?.list || []).map(mapSong)); - setCurrentPlaylistTitle(`搜索: ${searchKeyword}`); + setActiveSearchKeyword(keyword); + setSearchPage(1); + setSearchHasMore(Boolean(data.data?.hasMore)); + setCurrentPlaylistTitle(`搜索: ${keyword}`); setCurrentView('songs'); } catch (error) { console.error('搜索失败:', error); setSongs([]); + setActiveSearchKeyword(''); + setSearchPage(1); + setSearchHasMore(false); } finally { setLoading(false); } }; + const loadMoreSearchSongs = async () => { + const keyword = activeSearchKeyword.trim(); + if (!keyword || loadingMoreSearch || !searchHasMore) return; + + const nextPage = searchPage + 1; + setLoadingMoreSearch(true); + try { + const response = await fetch( + `/api/music/v2/search?source=${currentSource}&q=${encodeURIComponent(keyword)}&page=${nextPage}&limit=20` + ); + const data = await response.json(); + + if (response.ok && data.success) { + const nextSongs = (data.data?.list || []).map(mapSong); + setSongs((prev) => [...prev, ...nextSongs]); + setSearchPage(nextPage); + setSearchHasMore(Boolean(data.data?.hasMore)); + } else { + setToast({ + message: data.error?.message || '加载更多失败', + type: 'error', + onClose: () => setToast(null), + }); + } + } catch (error) { + console.error('加载更多搜索结果失败:', error); + setToast({ + message: '加载更多失败', + type: 'error', + onClose: () => setToast(null), + }); + } finally { + setLoadingMoreSearch(false); + } + }; + // 打开添加到歌单弹窗 const handleAddToPlaylist = (song: Song, e: React.MouseEvent) => { e.stopPropagation(); // 阻止事件冒泡,避免触发播放 @@ -1416,6 +1467,9 @@ export default function MusicPage() { if (currentView === 'songs') { setCurrentView('playlists'); setSongs([]); + setActiveSearchKeyword(''); + setSearchPage(1); + setSearchHasMore(false); } else if (currentView === 'myPlaylists') { setCurrentView('playlists'); setSelectedUserPlaylist(null); @@ -1444,6 +1498,9 @@ export default function MusicPage() { setCurrentView('playlists'); setSongs([]); setSearchKeyword(''); + setActiveSearchKeyword(''); + setSearchPage(1); + setSearchHasMore(false); }; // 音频事件监听 @@ -1602,6 +1659,27 @@ export default function MusicPage() { } }; + useEffect(() => { + const sentinel = searchLoadMoreRef.current; + if (!sentinel || !activeSearchKeyword || !searchHasMore) return; + + const observer = new IntersectionObserver( + (entries) => { + if (entries[0]?.isIntersecting) { + loadMoreSearchSongs(); + } + }, + { + root: null, + rootMargin: '240px 0px 240px 0px', + threshold: 0, + } + ); + + observer.observe(sentinel); + return () => observer.disconnect(); + }, [activeSearchKeyword, searchHasMore, loadingMoreSearch, searchPage]); + // 进度条拖动 const handleProgressChange = (e: React.ChangeEvent) => { const newTime = (parseFloat(e.target.value) / 100) * duration; @@ -2122,9 +2200,25 @@ export default function MusicPage() { ))} + {activeSearchKeyword && ( +
+ {searchHasMore ? ( + loadingMoreSearch ? ( +
+ +
+ ) : ( +
+ 继续向下滚动加载更多 +
+ ) + ) : songs.length > 0 ? ( +
没有更多搜索结果了
+ ) : null} +
+ )} )} - {/* My Playlists View */} {currentView === 'myPlaylists' && (