diff --git a/packages/frontend/src/App.tsx b/packages/frontend/src/App.tsx index 0ddf15b..7f36ea0 100644 --- a/packages/frontend/src/App.tsx +++ b/packages/frontend/src/App.tsx @@ -71,6 +71,7 @@ export default function RekordboxReader() { const { playlists, setPlaylists, loading: xmlLoading } = useXmlParser(); const [selectedSong, setSelectedSong] = useState(null); const [isDatabaseInitialized, setIsDatabaseInitialized] = useState(false); + const [isSwitchingPlaylist, setIsSwitchingPlaylist] = useState(false); // Memoized song selection handler to prevent unnecessary re-renders const handleSongSelect = useCallback((song: Song) => { @@ -153,7 +154,17 @@ export default function RekordboxReader() { } }, [currentPlaylist, playlists, navigate, xmlLoading]); + // Reset switching state when songs are loaded + useEffect(() => { + if (songs.length > 0 && isSwitchingPlaylist) { + setIsSwitchingPlaylist(false); + } + }, [songs.length, isSwitchingPlaylist]); + const handlePlaylistSelect = (name: string) => { + // Set switching state immediately for visual feedback + setIsSwitchingPlaylist(true); + // Clear selected song immediately to prevent stale state setSelectedSong(null); @@ -549,6 +560,7 @@ export default function RekordboxReader() { onLoadMore={loadNextPage} onSearch={searchSongs} searchQuery={searchQuery} + isSwitchingPlaylist={isSwitchingPlaylist} /> diff --git a/packages/frontend/src/components/PaginatedSongList.tsx b/packages/frontend/src/components/PaginatedSongList.tsx index 45642e3..53a0ff5 100644 --- a/packages/frontend/src/components/PaginatedSongList.tsx +++ b/packages/frontend/src/components/PaginatedSongList.tsx @@ -39,6 +39,7 @@ interface PaginatedSongListProps { onSearch: (query: string) => void; searchQuery: string; depth?: number; + isSwitchingPlaylist?: boolean; // New prop to indicate playlist switching } // Memoized song item component to prevent unnecessary re-renders @@ -118,7 +119,8 @@ export const PaginatedSongList: React.FC = memo(({ onLoadMore, onSearch, searchQuery, - depth = 0 + depth = 0, + isSwitchingPlaylist = false }) => { const [selectedSongs, setSelectedSongs] = useState>(new Set()); const [localSearchQuery, setLocalSearchQuery] = useState(searchQuery); @@ -427,12 +429,21 @@ export const PaginatedSongList: React.FC = memo(({ )} - {/* No results message */} + {/* No results message or playlist switching indicator */} {!loading && songs.length === 0 && ( - - - {searchQuery ? 'No songs found matching your search' : 'No songs available'} - + + {isSwitchingPlaylist ? ( + <> + + + Switching playlist... + + + ) : ( + + {searchQuery ? 'No songs found matching your search' : 'No songs available'} + + )} )} diff --git a/packages/frontend/src/hooks/usePaginatedSongs.ts b/packages/frontend/src/hooks/usePaginatedSongs.ts index f267cf1..e0bc952 100644 --- a/packages/frontend/src/hooks/usePaginatedSongs.ts +++ b/packages/frontend/src/hooks/usePaginatedSongs.ts @@ -146,9 +146,11 @@ export const usePaginatedSongs = (options: UsePaginatedSongsOptions = {}) => { currentSearchQueryRef.current = searchQuery; previousPlaylistRef.current = playlistName; - // Batch all state updates together to reduce re-renders + // Clear songs IMMEDIATELY for instant visual feedback + setSongs([]); + + // Batch remaining state updates together to reduce re-renders React.startTransition(() => { - setSongs([]); setHasMore(true); setCurrentPage(1); setSearchQuery(initialSearch);