feat: implement responsive album layout for mobile and desktop views, add debugging configurations for Next.js
This commit is contained in:
@@ -13,6 +13,7 @@ import { Separator } from '@/components/ui/separator';
|
||||
import { ScrollArea } from '@/components/ui/scroll-area';
|
||||
import { getNavidromeAPI } from '@/lib/navidrome';
|
||||
import { useFavoriteAlbums } from '@/hooks/use-favorite-albums';
|
||||
import { useIsMobile } from '@/hooks/use-mobile';
|
||||
|
||||
export default function AlbumPage() {
|
||||
const { id } = useParams();
|
||||
@@ -24,6 +25,7 @@ export default function AlbumPage() {
|
||||
const { getAlbum, starItem, unstarItem } = useNavidrome();
|
||||
const { playTrack, addAlbumToQueue, playAlbum, playAlbumFromTrack, currentTrack } = useAudioPlayer();
|
||||
const { isFavoriteAlbum, toggleFavoriteAlbum } = useFavoriteAlbums();
|
||||
const isMobile = useIsMobile();
|
||||
const api = getNavidromeAPI();
|
||||
|
||||
useEffect(() => {
|
||||
@@ -128,34 +130,82 @@ export default function AlbumPage() {
|
||||
<>
|
||||
<div className="h-full px-4 py-6 lg:px-8">
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-start gap-6">
|
||||
<Image
|
||||
src={coverArtUrl}
|
||||
alt={album.name}
|
||||
width={300}
|
||||
height={300}
|
||||
className="rounded-md"
|
||||
/>
|
||||
<div className="space-y-2">
|
||||
<div className="flex items-center space-x-4">
|
||||
<p className="text-3xl font-semibold tracking-tight">{album.name}</p>
|
||||
<Button onClick={handleStar} variant="ghost" title={isStarred ? "Unstar album" : "Star album"}>
|
||||
<Heart className={isStarred ? 'text-primary' : 'text-gray-500'} fill={isStarred ? 'var(--primary)' : ""}/>
|
||||
</Button>
|
||||
{isMobile ? (
|
||||
/* Mobile Layout */
|
||||
<div className="space-y-6">
|
||||
{/* Album Cover - Centered */}
|
||||
<div className="flex justify-center">
|
||||
<Image
|
||||
src={coverArtUrl}
|
||||
alt={album.name}
|
||||
width={280}
|
||||
height={280}
|
||||
className="rounded-md shadow-lg"
|
||||
/>
|
||||
</div>
|
||||
<Link href={`/artist/${album.artistId}`}>
|
||||
<p className="text-xl text-primary mt-0 mb-4 underline">{album.artist}</p>
|
||||
</Link>
|
||||
<Button className="px-5" onClick={() => playAlbum(album.id)}>
|
||||
Play
|
||||
</Button>
|
||||
<div className="text-sm text-muted-foreground">
|
||||
<p>{album.genre} • {album.year}</p>
|
||||
<p>{album.songCount} songs, {formatDuration(album.duration)}</p>
|
||||
|
||||
{/* Album Info and Controls */}
|
||||
<div className="flex justify-between items-start gap-4">
|
||||
{/* Left side - Album Info */}
|
||||
<div className="flex-1 space-y-1">
|
||||
<h1 className="text-2xl font-bold text-left">{album.name}</h1>
|
||||
<Link href={`/artist/${album.artistId}`}>
|
||||
<p className="text-lg text-primary underline text-left">{album.artist}</p>
|
||||
</Link>
|
||||
<p className="text-sm text-muted-foreground text-left">{album.genre} • {album.year}</p>
|
||||
<p className="text-sm text-muted-foreground text-left">{album.songCount} songs, {formatDuration(album.duration)}</p>
|
||||
</div>
|
||||
|
||||
{/* Right side - Controls */}
|
||||
<div className="flex flex-col items-center gap-3">
|
||||
<Button
|
||||
className="w-12 h-12 rounded-full p-0"
|
||||
onClick={() => playAlbum(album.id)}
|
||||
title="Play Album"
|
||||
>
|
||||
<Play className="w-6 h-6" />
|
||||
</Button>
|
||||
<Button
|
||||
onClick={handleStar}
|
||||
variant="ghost"
|
||||
className="w-12 h-12 rounded-full p-0"
|
||||
title={isStarred ? "Unstar album" : "Star album"}
|
||||
>
|
||||
<Heart className={`w-6 h-6 ${isStarred ? 'text-primary' : 'text-gray-500'}`} fill={isStarred ? 'var(--primary)' : ""}/>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
/* Desktop Layout */
|
||||
<div className="flex items-start gap-6">
|
||||
<Image
|
||||
src={coverArtUrl}
|
||||
alt={album.name}
|
||||
width={300}
|
||||
height={300}
|
||||
className="rounded-md"
|
||||
/>
|
||||
<div className="space-y-2">
|
||||
<div className="flex items-center space-x-4">
|
||||
<p className="text-3xl font-semibold tracking-tight">{album.name}</p>
|
||||
<Button onClick={handleStar} variant="ghost" title={isStarred ? "Unstar album" : "Star album"}>
|
||||
<Heart className={isStarred ? 'text-primary' : 'text-gray-500'} fill={isStarred ? 'var(--primary)' : ""}/>
|
||||
</Button>
|
||||
</div>
|
||||
<Link href={`/artist/${album.artistId}`}>
|
||||
<p className="text-xl text-primary mt-0 mb-4 underline">{album.artist}</p>
|
||||
</Link>
|
||||
<Button className="px-5" onClick={() => playAlbum(album.id)}>
|
||||
Play
|
||||
</Button>
|
||||
<div className="text-sm text-muted-foreground">
|
||||
<p>{album.genre} • {album.year}</p>
|
||||
<p>{album.songCount} songs, {formatDuration(album.duration)}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className="space-y-4">
|
||||
<Separator />
|
||||
|
||||
|
||||
Reference in New Issue
Block a user