feat: enhance FullScreenPlayer layout and responsiveness with improved styling for controls and lyrics display
This commit is contained in:
@@ -311,29 +311,33 @@ export const FullScreenPlayer: React.FC<FullScreenPlayerProps> = ({ isOpen, onCl
|
|||||||
{/* Main Content */}
|
{/* Main Content */}
|
||||||
<div className="flex-1 flex flex-col lg:flex-row gap-4 lg:gap-8 p-4 lg:p-6 pt-0 overflow-hidden min-h-0">
|
<div className="flex-1 flex flex-col lg:flex-row gap-4 lg:gap-8 p-4 lg:p-6 pt-0 overflow-hidden min-h-0">
|
||||||
{/* Left Side - Album Art and Controls */}
|
{/* Left Side - Album Art and Controls */}
|
||||||
<div className="flex-1 flex flex-col items-center justify-center max-w-2xl mx-auto lg:mx-0 min-h-0">
|
<div className={`flex flex-col items-center min-h-0 ${
|
||||||
|
showLyrics && lyrics.length > 0
|
||||||
|
? 'flex-1 justify-center lg:justify-start'
|
||||||
|
: 'flex-1 justify-center'
|
||||||
|
}`}>
|
||||||
{/* Album Art */}
|
{/* Album Art */}
|
||||||
<div className="relative mb-4 lg:mb-8 flex-shrink-0">
|
<div className="relative mb-4 lg:mb-6 flex-shrink-0">
|
||||||
<Image
|
<Image
|
||||||
src={currentTrack.coverArt || '/default-album.png'}
|
src={currentTrack.coverArt || '/default-album.png'}
|
||||||
alt={currentTrack.album}
|
alt={currentTrack.album}
|
||||||
width={320}
|
width={320}
|
||||||
height={320}
|
height={320}
|
||||||
className="w-64 h-64 lg:w-80 lg:h-80 rounded-lg shadow-2xl object-cover"
|
className="w-56 h-56 sm:w-64 sm:h-64 lg:w-80 lg:h-80 rounded-lg shadow-2xl object-cover"
|
||||||
priority
|
priority
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Track Info */}
|
{/* Track Info */}
|
||||||
<div className="text-center mb-4 lg:mb-8 px-4 flex-shrink-0">
|
<div className="text-center mb-4 lg:mb-6 px-4 flex-shrink-0 max-w-full">
|
||||||
<h1 className="text-xl lg:text-3xl font-bold text-foreground mb-2 line-clamp-2">
|
<h1 className="text-lg sm:text-xl lg:text-3xl font-bold text-foreground mb-2 line-clamp-2 leading-tight">
|
||||||
{currentTrack.name}
|
{currentTrack.name}
|
||||||
</h1>
|
</h1>
|
||||||
<p className="text-lg lg:text-xl text-foreground/80 mb-1 line-clamp-1">{currentTrack.artist}</p>
|
<p className="text-base sm:text-lg lg:text-xl text-foreground/80 mb-1 line-clamp-1">{currentTrack.artist}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Progress */}
|
{/* Progress */}
|
||||||
<div className="w-full max-w-md mb-4 lg:mb-6 px-4 flex-shrink-0">
|
<div className="w-full max-w-sm lg:max-w-md mb-4 lg:mb-6 px-4 flex-shrink-0">
|
||||||
<div
|
<div
|
||||||
className="h-2 bg-white/20 rounded-full cursor-pointer relative overflow-hidden"
|
className="h-2 bg-white/20 rounded-full cursor-pointer relative overflow-hidden"
|
||||||
onClick={handleSeek}
|
onClick={handleSeek}
|
||||||
@@ -350,7 +354,7 @@ export const FullScreenPlayer: React.FC<FullScreenPlayerProps> = ({ isOpen, onCl
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Controls */}
|
{/* Controls */}
|
||||||
<div className="flex items-center gap-4 lg:gap-6 mb-4 lg:mb-6 flex-shrink-0">
|
<div className="flex items-center gap-3 sm:gap-4 lg:gap-6 mb-4 lg:mb-6 flex-shrink-0">
|
||||||
<button
|
<button
|
||||||
onClick={toggleShuffle}
|
onClick={toggleShuffle}
|
||||||
className={`p-2 hover:bg-gray-700/50 rounded-full transition-colors ${
|
className={`p-2 hover:bg-gray-700/50 rounded-full transition-colors ${
|
||||||
@@ -358,41 +362,41 @@ export const FullScreenPlayer: React.FC<FullScreenPlayerProps> = ({ isOpen, onCl
|
|||||||
}`}
|
}`}
|
||||||
title={shuffle ? 'Shuffle On - Queue is shuffled' : 'Shuffle Off - Click to shuffle queue'}
|
title={shuffle ? 'Shuffle On - Queue is shuffled' : 'Shuffle Off - Click to shuffle queue'}
|
||||||
>
|
>
|
||||||
<FaShuffle className="w-5 h-5" />
|
<FaShuffle className="w-4 h-4 sm:w-5 sm:h-5" />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
onClick={playPreviousTrack}
|
onClick={playPreviousTrack}
|
||||||
className="p-2 hover:bg-gray-700/50 rounded-full transition-colors">
|
className="p-2 hover:bg-gray-700/50 rounded-full transition-colors">
|
||||||
<FaBackward className="w-5 h-5" />
|
<FaBackward className="w-4 h-4 sm:w-5 sm:h-5" />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
onClick={togglePlayPause}
|
onClick={togglePlayPause}
|
||||||
className="p-2 hover:bg-gray-700/50 rounded-full transition-colors">
|
className="p-3 hover:bg-gray-700/50 rounded-full transition-colors">
|
||||||
{isPlaying ? (
|
{isPlaying ? (
|
||||||
<FaPause className="w-10 h-10" />
|
<FaPause className="w-8 h-8 sm:w-10 sm:h-10" />
|
||||||
) : (
|
) : (
|
||||||
<FaPlay className="w-10 h-10" />
|
<FaPlay className="w-8 h-8 sm:w-10 sm:h-10" />
|
||||||
)}
|
)}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
onClick={playNextTrack}
|
onClick={playNextTrack}
|
||||||
className="p-2 hover:bg-gray-700/50 rounded-full transition-colors">
|
className="p-2 hover:bg-gray-700/50 rounded-full transition-colors">
|
||||||
<FaForward className="w-5 h-5" />
|
<FaForward className="w-4 h-4 sm:w-5 sm:h-5" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Volume and Queue */}
|
{/* Volume and Lyrics Toggle */}
|
||||||
<div className="flex items-center gap-3 flex-shrink-0">
|
<div className="flex items-center gap-3 flex-shrink-0 justify-center">
|
||||||
<button
|
<button
|
||||||
onMouseEnter={() => setShowVolumeSlider(true)}
|
onMouseEnter={() => setShowVolumeSlider(true)}
|
||||||
className="p-2 hover:bg-gray-700/50 rounded-full transition-colors">
|
className="p-2 hover:bg-gray-700/50 rounded-full transition-colors">
|
||||||
{volume === 0 ? (
|
{volume === 0 ? (
|
||||||
<FaVolumeXmark className="w-5 h-5" />
|
<FaVolumeXmark className="w-4 h-4 sm:w-5 sm:h-5" />
|
||||||
) : (
|
) : (
|
||||||
<FaVolumeHigh className="w-5 h-5" />
|
<FaVolumeHigh className="w-4 h-4 sm:w-5 sm:h-5" />
|
||||||
)}
|
)}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
@@ -404,13 +408,13 @@ export const FullScreenPlayer: React.FC<FullScreenPlayerProps> = ({ isOpen, onCl
|
|||||||
}`}
|
}`}
|
||||||
title={showLyrics ? 'Hide Lyrics' : 'Show Lyrics'}
|
title={showLyrics ? 'Hide Lyrics' : 'Show Lyrics'}
|
||||||
>
|
>
|
||||||
<FaQuoteLeft className="w-5 h-5" />
|
<FaQuoteLeft className="w-4 h-4 sm:w-5 sm:h-5" />
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{showVolumeSlider && (
|
{showVolumeSlider && (
|
||||||
<div
|
<div
|
||||||
className="w-20 lg:w-24"
|
className="w-16 sm:w-20 lg:w-24"
|
||||||
onMouseLeave={() => setShowVolumeSlider(false)}
|
onMouseLeave={() => setShowVolumeSlider(false)}
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
@@ -428,18 +432,18 @@ export const FullScreenPlayer: React.FC<FullScreenPlayerProps> = ({ isOpen, onCl
|
|||||||
|
|
||||||
{/* Right Side - Lyrics */}
|
{/* Right Side - Lyrics */}
|
||||||
{showLyrics && lyrics.length > 0 && (
|
{showLyrics && lyrics.length > 0 && (
|
||||||
<div className="flex-1 lg:max-w-md min-h-0" ref={lyricsRef}>
|
<div className="flex-1 lg:max-w-md min-h-0 flex flex-col" ref={lyricsRef}>
|
||||||
<div className="h-full flex flex-col">
|
<div className="h-full flex flex-col">
|
||||||
<ScrollArea className="flex-1 min-h-0 w-90">
|
<ScrollArea className="flex-1 min-h-0">
|
||||||
<div className="space-y-4 pr-4 px-2">
|
<div className="space-y-3 sm:space-y-4 pr-4 px-2 py-4">
|
||||||
{lyrics.map((line, index) => (
|
{lyrics.map((line, index) => (
|
||||||
<div
|
<div
|
||||||
key={index}
|
key={index}
|
||||||
data-lyric-index={index}
|
data-lyric-index={index}
|
||||||
onClick={() => handleLyricClick(line.time)}
|
onClick={() => handleLyricClick(line.time)}
|
||||||
className={`text-sm lg:text-base leading-relaxed transition-all duration-300 break-words cursor-pointer hover:text-foreground hover:scale-102 ${
|
className={`text-sm sm:text-base lg:text-base leading-relaxed transition-all duration-300 break-words cursor-pointer hover:text-foreground hover:scale-102 ${
|
||||||
index === currentLyricIndex
|
index === currentLyricIndex
|
||||||
? 'text-foreground font-semibold text-lg lg:text-xl scale-105'
|
? 'text-foreground font-semibold text-base sm:text-lg lg:text-xl scale-105'
|
||||||
: index < currentLyricIndex
|
: index < currentLyricIndex
|
||||||
? 'text-foreground/60'
|
? 'text-foreground/60'
|
||||||
: 'text-foreground/40'
|
: 'text-foreground/40'
|
||||||
@@ -448,8 +452,8 @@ export const FullScreenPlayer: React.FC<FullScreenPlayerProps> = ({ isOpen, onCl
|
|||||||
wordWrap: 'break-word',
|
wordWrap: 'break-word',
|
||||||
overflowWrap: 'break-word',
|
overflowWrap: 'break-word',
|
||||||
hyphens: 'auto',
|
hyphens: 'auto',
|
||||||
paddingBottom: '8px',
|
paddingBottom: '6px',
|
||||||
paddingLeft: '9px'
|
paddingLeft: '8px'
|
||||||
}}
|
}}
|
||||||
title={`Click to jump to ${formatTime(line.time)}`}
|
title={`Click to jump to ${formatTime(line.time)}`}
|
||||||
>
|
>
|
||||||
|
|||||||
Reference in New Issue
Block a user