diff --git a/packages/frontend/src/App.tsx b/packages/frontend/src/App.tsx index 6e16b9f..7df6c84 100644 --- a/packages/frontend/src/App.tsx +++ b/packages/frontend/src/App.tsx @@ -130,7 +130,8 @@ const RekordboxReader: React.FC = () => { loadNextPage, searchSongs, searchQuery, - refresh + refresh, + switchPlaylistImmediately } = usePaginatedSongs({ pageSize: 100, playlistName: currentPlaylist }); // Export library to XML @@ -209,6 +210,10 @@ const RekordboxReader: React.FC = () => { // Clear selected song immediately to prevent stale state setSelectedSong(null); + // Kick off data load immediately to avoid delay before backend call + const target = name || "All Songs"; + switchPlaylistImmediately(target); + // Navigate immediately without any delays if (name === "All Songs") { navigate("/", { replace: true }); diff --git a/packages/frontend/src/hooks/usePaginatedSongs.ts b/packages/frontend/src/hooks/usePaginatedSongs.ts index 88f8a95..1f4f45c 100644 --- a/packages/frontend/src/hooks/usePaginatedSongs.ts +++ b/packages/frontend/src/hooks/usePaginatedSongs.ts @@ -1,4 +1,4 @@ -import { useState, useEffect, useCallback, useRef } from 'react'; +import { useState, useEffect, useLayoutEffect, useCallback, useRef } from 'react'; import { api, type SongsResponse } from '../services/api'; import type { Song } from '../types/interfaces'; @@ -139,7 +139,7 @@ export const usePaginatedSongs = (options: UsePaginatedSongsOptions = {}) => { }, []); // Handle playlist changes - streamlined for immediate response - useEffect(() => { + useLayoutEffect(() => { if (previousPlaylistRef.current !== playlistName) { // Update refs immediately currentPlaylistRef.current = playlistName; @@ -160,6 +160,25 @@ export const usePaginatedSongs = (options: UsePaginatedSongsOptions = {}) => { } }, [playlistName, initialSearch, loadPage]); + // Imperative method to switch playlist and start loading immediately + const switchPlaylistImmediately = useCallback((targetPlaylistName: string) => { + // Update refs immediately so effect does not double-trigger + currentPlaylistRef.current = targetPlaylistName; + previousPlaylistRef.current = targetPlaylistName; + currentSearchQueryRef.current = searchQuery; + + // Clear state for instant visual feedback + setSongs([]); + setTotalSongs(0); + setTotalDuration(undefined); + setHasMore(true); + setCurrentPage(1); + setError(null); + + // Start loading right away + loadPage(1, initialSearch, targetPlaylistName); + }, [initialSearch, loadPage, searchQuery]); + return { songs, loading, @@ -174,5 +193,6 @@ export const usePaginatedSongs = (options: UsePaginatedSongsOptions = {}) => { searchSongs, reset, refresh: () => loadPage(1) + , switchPlaylistImmediately }; }; \ No newline at end of file