feat: add favorite albums section with loading state in MusicPage

This commit is contained in:
2025-07-02 16:49:10 +00:00
committed by GitHub
parent 387b5af5c0
commit f9dfae70d4

View File

@@ -11,9 +11,11 @@ import { useNavidromeConfig } from './components/NavidromeConfigContext';
type TimeOfDay = 'morning' | 'afternoon' | 'evening';
export default function MusicPage() {
const { albums, isLoading } = useNavidrome();
const { albums, isLoading, api, isConnected } = useNavidrome();
const [recentAlbums, setRecentAlbums] = useState<Album[]>([]);
const [newestAlbums, setNewestAlbums] = useState<Album[]>([]);
const [favoriteAlbums, setFavoriteAlbums] = useState<Album[]>([]);
const [favoritesLoading, setFavoritesLoading] = useState(true);
useEffect(() => {
if (albums.length > 0) {
@@ -25,6 +27,24 @@ export default function MusicPage() {
}
}, [albums]);
useEffect(() => {
const loadFavoriteAlbums = async () => {
if (!api || !isConnected) return;
setFavoritesLoading(true);
try {
const starredAlbums = await api.getAlbums('starred', 20); // Limit to 20 for homepage
setFavoriteAlbums(starredAlbums);
} catch (error) {
console.error('Failed to load favorite albums:', error);
} finally {
setFavoritesLoading(false);
}
};
loadFavoriteAlbums();
}, [api, isConnected]);
// Get greeting and time of day
const hour = new Date().getHours();
const greeting = hour < 12 ? 'Good morning' : 'Good afternoon';
@@ -106,6 +126,46 @@ export default function MusicPage() {
<ScrollBar orientation="horizontal" />
</ScrollArea>
</div>
{/* Favorite Albums Section */}
{favoriteAlbums.length > 0 && (
<>
<div className="mt-6 space-y-1">
<p className="text-2xl font-semibold tracking-tight">
Favorite Albums
</p>
<p className="text-sm text-muted-foreground">
Your starred albums collection.
</p>
</div>
<Separator className="my-4" />
<div className="relative">
<ScrollArea>
<div className="flex space-x-4 pb-4">
{favoritesLoading ? (
// Loading skeletons
Array.from({ length: 6 }).map((_, i) => (
<div key={i} className="w-[220px] h-[320px] bg-muted animate-pulse rounded-md flex-shrink-0" />
))
) : (
favoriteAlbums.map((album) => (
<AlbumArtwork
key={album.id}
album={album}
className="w-[220px] flex-shrink-0"
aspectRatio="square"
width={220}
height={220}
/>
))
)}
</div>
<ScrollBar orientation="horizontal" />
</ScrollArea>
</div>
</>
)}
<div className="mt-6 space-y-1">
<p className="text-2xl font-semibold tracking-tight">
Your Library