feat: update album loading to support alphabetical order and adjust layout for better responsiveness

This commit is contained in:
2025-06-19 22:58:49 +00:00
committed by GitHub
parent ddd3986f0d
commit 98b348bb34
4 changed files with 13 additions and 11 deletions

View File

@@ -26,7 +26,9 @@ export default function BrowsePage() {
try { try {
setIsLoadingAlbums(true); setIsLoadingAlbums(true);
const offset = page * albumsPerPage; const offset = page * albumsPerPage;
const newAlbums = await api.getAlbums('newest', albumsPerPage, offset);
// Use alphabeticalByName to get all albums in alphabetical order
const newAlbums = await api.getAlbums('alphabeticalByName', albumsPerPage, offset);
if (append) { if (append) {
setAlbums(prev => [...prev, ...newAlbums]); setAlbums(prev => [...prev, ...newAlbums]);
@@ -126,7 +128,7 @@ export default function BrowsePage() {
<div className="relative flex-grow"> <div className="relative flex-grow">
<ScrollArea className="h-full"> <ScrollArea className="h-full">
<div className="h-full overflow-y-auto"> <div className="h-full overflow-y-auto">
<div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6 2xl:grid-cols-7 gap-4 p-4"> <div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6 2xl:grid-cols-7 gap-4 p-4 pb-8">
{albums.map((album) => ( {albums.map((album) => (
<AlbumArtwork <AlbumArtwork
key={album.id} key={album.id}
@@ -139,7 +141,7 @@ export default function BrowsePage() {
))} ))}
</div> </div>
{hasMoreAlbums && ( {hasMoreAlbums && (
<div className="flex justify-center p-4"> <div className="flex justify-center p-4 pb-24">
<Button <Button
onClick={loadMore} onClick={loadMore}
disabled={isLoadingAlbums} disabled={isLoadingAlbums}
@@ -150,7 +152,7 @@ export default function BrowsePage() {
</div> </div>
)} )}
{!hasMoreAlbums && albums.length > 0 && ( {!hasMoreAlbums && albums.length > 0 && (
<div className="flex justify-center p-4"> <div className="flex justify-center p-4 pb-24">
<p className="text-sm text-muted-foreground"> <p className="text-sm text-muted-foreground">
All albums loaded ({albums.length} total) All albums loaded ({albums.length} total)
</p> </p>

View File

@@ -75,7 +75,7 @@ export function AlbumArtwork({
height={height} height={height}
className={cn( className={cn(
"h-auto w-auto object-cover transition-all hover:scale-105", "w-full h-full object-cover transition-all hover:scale-105",
aspectRatio === "portrait" ? "aspect-[3/4]" : "aspect-square" aspectRatio === "portrait" ? "aspect-[3/4]" : "aspect-square"
)} )}
/> />

View File

@@ -59,14 +59,14 @@ export default function MusicPage() {
{isLoading ? ( {isLoading ? (
// Loading skeletons // Loading skeletons
Array.from({ length: 6 }).map((_, i) => ( Array.from({ length: 6 }).map((_, i) => (
<div key={i} className="w-[300px] h-[300px] bg-muted animate-pulse rounded-md" /> <div key={i} className="w-[300px] h-[300px] bg-muted animate-pulse rounded-md flex-shrink-0" />
)) ))
) : ( ) : (
recentAlbums.map((album) => ( recentAlbums.map((album) => (
<AlbumArtwork <AlbumArtwork
key={album.id} key={album.id}
album={album} album={album}
className="w-[300px]" className="w-[300px] flex-shrink-0"
aspectRatio="square" aspectRatio="square"
width={300} width={300}
height={300} height={300}
@@ -92,14 +92,14 @@ export default function MusicPage() {
{isLoading ? ( {isLoading ? (
// Loading skeletons // Loading skeletons
Array.from({ length: 10 }).map((_, i) => ( Array.from({ length: 10 }).map((_, i) => (
<div key={i} className="w-[150px] h-[150px] bg-muted animate-pulse rounded-md" /> <div key={i} className="w-[150px] h-[150px] bg-muted animate-pulse rounded-md flex-shrink-0" />
)) ))
) : ( ) : (
newestAlbums.map((album) => ( newestAlbums.map((album) => (
<AlbumArtwork <AlbumArtwork
key={album.id} key={album.id}
album={album} album={album}
className="w-[150px]" className="w-[150px] flex-shrink-0"
aspectRatio="square" aspectRatio="square"
width={150} width={150}
height={150} height={150}

View File

@@ -106,7 +106,7 @@ class NavidromeAPI {
return crypto.createHash('md5').update(password + salt).digest('hex'); return crypto.createHash('md5').update(password + salt).digest('hex');
} }
private async makeRequest(endpoint: string, params: Record<string, string | number> = {}): Promise<Record<string, unknown>> { async makeRequest(endpoint: string, params: Record<string, string | number> = {}): Promise<Record<string, unknown>> {
const salt = this.generateSalt(); const salt = this.generateSalt();
const token = this.generateToken(this.config.password, salt); const token = this.generateToken(this.config.password, salt);
@@ -175,7 +175,7 @@ class NavidromeAPI {
}; };
} }
async getAlbums(type?: 'newest' | 'recent' | 'frequent' | 'random', size: number = 50, offset: number = 0): Promise<Album[]> { async getAlbums(type?: 'newest' | 'recent' | 'frequent' | 'random' | 'alphabeticalByName' | 'alphabeticalByArtist' | 'starred' | 'highest', size: number = 500, offset: number = 0): Promise<Album[]> {
const response = await this.makeRequest('getAlbumList2', { const response = await this.makeRequest('getAlbumList2', {
type: type || 'newest', type: type || 'newest',
size, size,