/* eslint-disable @typescript-eslint/no-unused-vars */ 'use client'; import { useState, useEffect } from 'react'; import { ScrollArea, ScrollBar } from '@/components/ui/scroll-area'; import { Separator } from '@/components/ui/separator'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; import { Tabs, TabsContent } from '@/components/ui/tabs'; import { AlbumArtwork } from '@/app/components/album-artwork'; import { getNavidromeAPI, Album } from '@/lib/navidrome'; import { useAudioPlayer } from '@/app/components/AudioPlayerContext'; import { Shuffle, Search } from 'lucide-react'; import Loading from '@/app/components/loading'; export default function AlbumsPage() { const { shuffleAllAlbums } = useAudioPlayer(); const [albums, setAlbums] = useState([]); const [filteredAlbums, setFilteredAlbums] = useState([]); const [currentPage, setCurrentPage] = useState(0); const [isLoadingAlbums, setIsLoadingAlbums] = useState(false); const [hasMoreAlbums, setHasMoreAlbums] = useState(true); const [searchQuery, setSearchQuery] = useState(''); const [sortBy, setSortBy] = useState<'alphabeticalByName' | 'newest' | 'alphabeticalByArtist'>('alphabeticalByName'); const albumsPerPage = 84; const api = getNavidromeAPI(); const loadAlbums = async (page: number, append: boolean = false) => { if (!api) { console.error('Navidrome API not available'); return; } try { setIsLoadingAlbums(true); const offset = page * albumsPerPage; const newAlbums = await api.getAlbums(sortBy, albumsPerPage, offset); if (append) { setAlbums(prev => [...prev, ...newAlbums]); } else { setAlbums(newAlbums); } setHasMoreAlbums(newAlbums.length === albumsPerPage); } catch (error) { console.error('Failed to load albums:', error); } finally { setIsLoadingAlbums(false); } }; useEffect(() => { setCurrentPage(0); loadAlbums(0); // eslint-disable-next-line react-hooks/exhaustive-deps }, [sortBy]); // Filter albums based on search query useEffect(() => { let filtered = [...albums]; if (searchQuery) { filtered = filtered.filter(album => album.name.toLowerCase().includes(searchQuery.toLowerCase()) || album.artist.toLowerCase().includes(searchQuery.toLowerCase()) ); } setFilteredAlbums(filtered); }, [albums, searchQuery]); // Infinite scroll handler useEffect(() => { const handleScroll = (e: Event) => { const target = e.target as HTMLElement; if (!target || isLoadingAlbums || !hasMoreAlbums || searchQuery) return; const { scrollTop, scrollHeight, clientHeight } = target; const threshold = 200; // Load more when 200px from bottom if (scrollHeight - scrollTop - clientHeight < threshold) { loadMore(); } }; const scrollArea = document.querySelector('[data-radix-scroll-area-viewport]'); if (scrollArea) { scrollArea.addEventListener('scroll', handleScroll); return () => scrollArea.removeEventListener('scroll', handleScroll); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [isLoadingAlbums, hasMoreAlbums, currentPage, searchQuery]); const loadMore = () => { if (isLoadingAlbums || !hasMoreAlbums || searchQuery) return; const nextPage = currentPage + 1; setCurrentPage(nextPage); loadAlbums(nextPage, true); }; if (isLoadingAlbums && albums.length === 0) { return ; } return (

Albums

{searchQuery ? `${filteredAlbums.length} albums found` : `Browse all albums (${albums.length} loaded)`}

{/* Search and Filter Controls */}
setSearchQuery(e.target.value)} className="pl-10" />
{filteredAlbums.map((album) => ( ))}
{!searchQuery && hasMoreAlbums && (
)} {!searchQuery && !hasMoreAlbums && albums.length > 0 && (

All albums loaded ({albums.length} total)

)}
); }