From ee39b88b002f16411d5ea75bab4a0af807f5288c Mon Sep 17 00:00:00 2001 From: nico Date: Thu, 5 Mar 2026 14:14:46 +0800 Subject: [PATCH] feat(music-player): add minimize feature with floating icon and centered controls Layout Changes: - Center all control buttons (shuffle, prev, play/pause, next, repeat) - Center progress bar alongside controls - Keep volume control + close button on the right - Song info remains on the left New Feature - Minimize Player: - Add isMinimized state to track player visibility - Replace close button with minimize functionality - Show floating music icon when minimized (bottom-right corner) - Click floating icon to restore player bar - Floating icon has hover scale animation for better UX UI/UX Improvements: - Better visual hierarchy with centered controls - Floating icon uses blue bg with white music icon - Smooth transitions between states - Icon scales on hover for interactive feedback - Persistent player state (song continues playing when minimized) Files changed: - src/app/darmasaba/_com/FixedPlayerBar.tsx: Complete redesign Co-authored-by: Qwen-Coder --- src/app/darmasaba/_com/FixedPlayerBar.tsx | 192 +++++++++++++--------- 1 file changed, 118 insertions(+), 74 deletions(-) diff --git a/src/app/darmasaba/_com/FixedPlayerBar.tsx b/src/app/darmasaba/_com/FixedPlayerBar.tsx index 306cd89f..a9ae76d1 100644 --- a/src/app/darmasaba/_com/FixedPlayerBar.tsx +++ b/src/app/darmasaba/_com/FixedPlayerBar.tsx @@ -12,6 +12,7 @@ import { } from '@mantine/core'; import { IconArrowsShuffle, + IconMusic, IconPlayerPauseFilled, IconPlayerPlayFilled, IconPlayerSkipBackFilled, @@ -45,7 +46,7 @@ export default function FixedPlayerBar() { } = useMusic(); const [showVolume, setShowVolume] = useState(false); - const [isPlayerVisible, setIsPlayerVisible] = useState(true); + const [isMinimized, setIsMinimized] = useState(false); // Format time const formatTime = (seconds: number) => { @@ -69,12 +70,52 @@ export default function FixedPlayerBar() { toggleShuffle(); }; - // Handle close player - const handleClosePlayer = () => { - setIsPlayerVisible(false); + // Handle minimize player (show floating icon) + const handleMinimizePlayer = () => { + setIsMinimized(true); }; - if (!currentSong || !isPlayerVisible) { + // Handle restore player from floating icon + const handleRestorePlayer = () => { + setIsMinimized(false); + }; + + // If minimized, show floating icon instead of player bar + if (isMinimized) { + return ( + <> + {/* Floating Music Icon - Shows when player is minimized */} + { + e.currentTarget.style.transform = 'scale(1.1)'; + }} + onMouseLeave={(e) => { + e.currentTarget.style.transform = 'scale(1)'; + }} + > + + + + {/* Spacer to prevent content from being hidden behind player */} + + + ); + } + + if (!currentSong) { return null; } @@ -94,7 +135,7 @@ export default function FixedPlayerBar() { }} > - {/* Song Info */} + {/* Song Info - Left */} - {/* Controls */} - - - - + {/* Controls + Progress - Center */} + + {/* Control Buttons */} + + + + - - - + + + - - {isPlaying ? ( - - ) : ( - - )} - + + {isPlaying ? ( + + ) : ( + + )} + - - - + + + - - {isRepeat ? : } - + + {isRepeat ? : } + + + + {/* Progress Bar - Desktop */} + + formatTime(value)} + /> + - {/* Progress Bar - Desktop */} - - formatTime(value)} - /> - - - {/* Right Controls */} - + {/* Right Controls - Volume + Close */} + setShowVolume(true)} onMouseLeave={() => setShowVolume(false)} @@ -241,8 +285,8 @@ export default function FixedPlayerBar() { variant="subtle" color="gray" size="lg" - onClick={handleClosePlayer} - title="Close player" + onClick={handleMinimizePlayer} + title="Minimize player" >