perf: Streamline playlist switching flow for faster, cleaner transitions - Clear all state immediately (songs, totalSongs, totalDuration) on playlist switch - Combine switching and loading states into single spinner with dynamic text - Remove duplicate switching indicators to prevent UI flicker - Reset switching state when loading starts for immediate transition - Eliminates confusing flow: switching → old data → 0 of X → loading → new data - Now shows: switching → loading → new data (much cleaner)

This commit is contained in:
Geert Rademakes 2025-08-06 11:18:09 +02:00
parent 90bcd10ed9
commit 966240b0d1
3 changed files with 19 additions and 30 deletions

View File

@ -154,12 +154,12 @@ export default function RekordboxReader() {
}
}, [currentPlaylist, playlists, navigate, xmlLoading]);
// Reset switching state when songs are loaded
// Reset switching state when loading starts (immediate transition)
useEffect(() => {
if (songs.length > 0 && isSwitchingPlaylist) {
if (songsLoading && isSwitchingPlaylist) {
setIsSwitchingPlaylist(false);
}
}, [songs.length, isSwitchingPlaylist]);
}, [songsLoading, isSwitchingPlaylist]);
const handlePlaylistSelect = (name: string) => {
// Set switching state immediately for visual feedback

View File

@ -409,12 +409,12 @@ export const PaginatedSongList: React.FC<PaginatedSongListProps> = memo(({
<Flex direction="column" gap={2}>
{songItems}
{/* Loading indicator for infinite scroll */}
{loading && (
{/* Loading indicator for infinite scroll or playlist switching */}
{(loading || isSwitchingPlaylist) && (
<Flex justify="center" align="center" p={6} key="loading-spinner" gap={3}>
<Spinner size="md" color="blue.400" />
<Text color="gray.400" fontSize="sm">
Loading more songs...
{isSwitchingPlaylist ? 'Switching playlist...' : 'Loading more songs...'}
</Text>
</Flex>
)}
@ -440,21 +440,12 @@ export const PaginatedSongList: React.FC<PaginatedSongListProps> = memo(({
</Flex>
)}
{/* No results message or playlist switching indicator */}
{!loading && songs.length === 0 && (
{/* No results message */}
{!loading && !isSwitchingPlaylist && songs.length === 0 && (
<Flex justify="center" p={8} key="no-results" direction="column" align="center" gap={3}>
{isSwitchingPlaylist ? (
<>
<Spinner size="md" color="blue.400" />
<Text color="blue.400" fontSize="sm" fontWeight="medium">
Switching playlist...
</Text>
</>
) : (
<Text color="gray.500">
{searchQuery ? 'No songs found matching your search' : 'No songs available'}
</Text>
)}
</Flex>
)}
</Flex>

View File

@ -138,7 +138,7 @@ export const usePaginatedSongs = (options: UsePaginatedSongsOptions = {}) => {
};
}, []);
// Handle playlist changes - optimized for immediate response
// Handle playlist changes - streamlined for immediate response
useEffect(() => {
if (previousPlaylistRef.current !== playlistName) {
// Update refs immediately
@ -146,16 +146,14 @@ export const usePaginatedSongs = (options: UsePaginatedSongsOptions = {}) => {
currentSearchQueryRef.current = searchQuery;
previousPlaylistRef.current = playlistName;
// Clear songs IMMEDIATELY for instant visual feedback
// Clear all state immediately for instant visual feedback
setSongs([]);
// Batch remaining state updates together to reduce re-renders
React.startTransition(() => {
setTotalSongs(0);
setTotalDuration(undefined);
setHasMore(true);
setCurrentPage(1);
setSearchQuery(initialSearch);
setError(null);
});
// Load immediately
loadPage(1, initialSearch, playlistName);