fix: Make playlist folders start collapsed by default - Change default state from expanded to collapsed for better UX
This commit is contained in:
parent
7fb8614130
commit
2e32a3c3b6
@ -120,6 +120,7 @@ export const PaginatedSongList: React.FC<PaginatedSongListProps> = memo(({
|
|||||||
const [localSearchQuery, setLocalSearchQuery] = useState(searchQuery);
|
const [localSearchQuery, setLocalSearchQuery] = useState(searchQuery);
|
||||||
const observerRef = useRef<IntersectionObserver | null>(null);
|
const observerRef = useRef<IntersectionObserver | null>(null);
|
||||||
const loadingRef = useRef<HTMLDivElement>(null);
|
const loadingRef = useRef<HTMLDivElement>(null);
|
||||||
|
const scrollContainerRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
// Debounce search to prevent excessive API calls
|
// Debounce search to prevent excessive API calls
|
||||||
const debouncedSearchQuery = useDebounce(localSearchQuery, 300);
|
const debouncedSearchQuery = useDebounce(localSearchQuery, 300);
|
||||||
@ -233,7 +234,10 @@ export const PaginatedSongList: React.FC<PaginatedSongListProps> = memo(({
|
|||||||
onLoadMore();
|
onLoadMore();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ threshold: 0.1 }
|
{
|
||||||
|
threshold: 0.1,
|
||||||
|
rootMargin: '100px' // Start loading when 100px away from the bottom
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
observerRef.current.observe(loadingRef.current);
|
observerRef.current.observe(loadingRef.current);
|
||||||
@ -338,23 +342,29 @@ export const PaginatedSongList: React.FC<PaginatedSongListProps> = memo(({
|
|||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{/* Scrollable Song List */}
|
{/* Scrollable Song List */}
|
||||||
<Box flex={1} overflowY="auto" mt={2}>
|
<Box
|
||||||
|
ref={scrollContainerRef}
|
||||||
|
flex={1}
|
||||||
|
overflowY="auto"
|
||||||
|
mt={2}
|
||||||
|
id="song-list-container"
|
||||||
|
>
|
||||||
<Flex direction="column" gap={2}>
|
<Flex direction="column" gap={2}>
|
||||||
{songItems}
|
{songItems}
|
||||||
|
|
||||||
{/* Loading indicator for infinite scroll */}
|
{/* Loading indicator for infinite scroll */}
|
||||||
{loading && (
|
{loading && (
|
||||||
<Flex justify="center" p={4}>
|
<Flex justify="center" p={4} key="loading-spinner">
|
||||||
<Spinner size="md" color="blue.400" />
|
<Spinner size="md" color="blue.400" />
|
||||||
</Flex>
|
</Flex>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Intersection observer target */}
|
{/* Intersection observer target */}
|
||||||
<div ref={loadingRef} style={{ height: '20px' }} />
|
<div ref={loadingRef} style={{ height: '20px' }} key="intersection-target" />
|
||||||
|
|
||||||
{/* End of results message */}
|
{/* End of results message */}
|
||||||
{!hasMore && songs.length > 0 && (
|
{!hasMore && songs.length > 0 && (
|
||||||
<Flex justify="center" p={4}>
|
<Flex justify="center" p={4} key="end-message">
|
||||||
<Text color="gray.500" fontSize="sm">
|
<Text color="gray.500" fontSize="sm">
|
||||||
No more songs to load
|
No more songs to load
|
||||||
</Text>
|
</Text>
|
||||||
@ -363,7 +373,7 @@ export const PaginatedSongList: React.FC<PaginatedSongListProps> = memo(({
|
|||||||
|
|
||||||
{/* No results message */}
|
{/* No results message */}
|
||||||
{!loading && songs.length === 0 && (
|
{!loading && songs.length === 0 && (
|
||||||
<Flex justify="center" p={8}>
|
<Flex justify="center" p={8} key="no-results">
|
||||||
<Text color="gray.500">
|
<Text color="gray.500">
|
||||||
{searchQuery ? 'No songs found matching your search' : 'No songs available'}
|
{searchQuery ? 'No songs found matching your search' : 'No songs available'}
|
||||||
</Text>
|
</Text>
|
||||||
|
|||||||
@ -77,7 +77,7 @@ const PlaylistItem: React.FC<PlaylistItemProps> = ({
|
|||||||
onPlaylistMove,
|
onPlaylistMove,
|
||||||
allFolders,
|
allFolders,
|
||||||
}) => {
|
}) => {
|
||||||
const [isOpen, setIsOpen] = useState(true);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
const indent = level * 10;
|
const indent = level * 10;
|
||||||
|
|
||||||
if (node.type === 'folder') {
|
if (node.type === 'folder') {
|
||||||
|
|||||||
@ -100,7 +100,7 @@ export const usePaginatedSongs = (options: UsePaginatedSongsOptions = {}) => {
|
|||||||
// Search songs with debouncing
|
// Search songs with debouncing
|
||||||
const searchSongs = useCallback((query: string) => {
|
const searchSongs = useCallback((query: string) => {
|
||||||
setSearchQuery(query);
|
setSearchQuery(query);
|
||||||
setSongs([]);
|
// Don't clear songs immediately - let the new search results replace them
|
||||||
setHasMore(true);
|
setHasMore(true);
|
||||||
setCurrentPage(1);
|
setCurrentPage(1);
|
||||||
setError(null);
|
setError(null);
|
||||||
@ -134,7 +134,7 @@ export const usePaginatedSongs = (options: UsePaginatedSongsOptions = {}) => {
|
|||||||
if (currentPlaylistRef.current !== playlistName) {
|
if (currentPlaylistRef.current !== playlistName) {
|
||||||
currentPlaylistRef.current = playlistName;
|
currentPlaylistRef.current = playlistName;
|
||||||
if (!isInitialLoad) {
|
if (!isInitialLoad) {
|
||||||
setSongs([]);
|
// Don't clear songs immediately - let the new playlist results replace them
|
||||||
setHasMore(true);
|
setHasMore(true);
|
||||||
setCurrentPage(1);
|
setCurrentPage(1);
|
||||||
setSearchQuery(initialSearch);
|
setSearchQuery(initialSearch);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user