feat: add favorite albums section with loading state in MusicPage
This commit is contained in:
62
app/page.tsx
62
app/page.tsx
@@ -11,9 +11,11 @@ import { useNavidromeConfig } from './components/NavidromeConfigContext';
|
|||||||
|
|
||||||
type TimeOfDay = 'morning' | 'afternoon' | 'evening';
|
type TimeOfDay = 'morning' | 'afternoon' | 'evening';
|
||||||
export default function MusicPage() {
|
export default function MusicPage() {
|
||||||
const { albums, isLoading } = useNavidrome();
|
const { albums, isLoading, api, isConnected } = useNavidrome();
|
||||||
const [recentAlbums, setRecentAlbums] = useState<Album[]>([]);
|
const [recentAlbums, setRecentAlbums] = useState<Album[]>([]);
|
||||||
const [newestAlbums, setNewestAlbums] = useState<Album[]>([]);
|
const [newestAlbums, setNewestAlbums] = useState<Album[]>([]);
|
||||||
|
const [favoriteAlbums, setFavoriteAlbums] = useState<Album[]>([]);
|
||||||
|
const [favoritesLoading, setFavoritesLoading] = useState(true);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (albums.length > 0) {
|
if (albums.length > 0) {
|
||||||
@@ -25,6 +27,24 @@ export default function MusicPage() {
|
|||||||
}
|
}
|
||||||
}, [albums]);
|
}, [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
|
// Get greeting and time of day
|
||||||
const hour = new Date().getHours();
|
const hour = new Date().getHours();
|
||||||
const greeting = hour < 12 ? 'Good morning' : 'Good afternoon';
|
const greeting = hour < 12 ? 'Good morning' : 'Good afternoon';
|
||||||
@@ -106,6 +126,46 @@ export default function MusicPage() {
|
|||||||
<ScrollBar orientation="horizontal" />
|
<ScrollBar orientation="horizontal" />
|
||||||
</ScrollArea>
|
</ScrollArea>
|
||||||
</div>
|
</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">
|
<div className="mt-6 space-y-1">
|
||||||
<p className="text-2xl font-semibold tracking-tight">
|
<p className="text-2xl font-semibold tracking-tight">
|
||||||
Your Library
|
Your Library
|
||||||
|
|||||||
Reference in New Issue
Block a user