fix: audio minimize issue fixed
This commit is contained in:
@@ -43,7 +43,7 @@ function useIsMobile() {
|
|||||||
* Auto-minimizes after `MINIMIZE_DELAY` ms of inactivity on mobile.
|
* Auto-minimizes after `MINIMIZE_DELAY` ms of inactivity on mobile.
|
||||||
* Call `resetTimer()` on any user interaction to restart the countdown.
|
* Call `resetTimer()` on any user interaction to restart the countdown.
|
||||||
*/
|
*/
|
||||||
function useMobileMinimize(isMobile: boolean, hasTrack: boolean) {
|
function useAutoMinimize(hasTrack: boolean) {
|
||||||
const [minimized, setMinimized] = useState(false);
|
const [minimized, setMinimized] = useState(false);
|
||||||
const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
||||||
|
|
||||||
@@ -60,21 +60,20 @@ function useMobileMinimize(isMobile: boolean, hasTrack: boolean) {
|
|||||||
}, [clearTimer]);
|
}, [clearTimer]);
|
||||||
|
|
||||||
const resetTimer = useCallback(() => {
|
const resetTimer = useCallback(() => {
|
||||||
if (!isMobile) return;
|
|
||||||
setMinimized(false);
|
setMinimized(false);
|
||||||
startTimer();
|
startTimer();
|
||||||
}, [isMobile, startTimer]);
|
}, [startTimer]);
|
||||||
|
|
||||||
// Start timer when track begins or mobile state changes
|
// Start timer when track begins
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isMobile && hasTrack) {
|
if (hasTrack) {
|
||||||
startTimer();
|
startTimer();
|
||||||
} else {
|
} else {
|
||||||
clearTimer();
|
clearTimer();
|
||||||
setMinimized(false);
|
setMinimized(false);
|
||||||
}
|
}
|
||||||
return clearTimer;
|
return clearTimer;
|
||||||
}, [isMobile, hasTrack, startTimer, clearTimer]);
|
}, [hasTrack, startTimer, clearTimer]);
|
||||||
|
|
||||||
return { minimized, setMinimized, resetTimer } as const;
|
return { minimized, setMinimized, resetTimer } as const;
|
||||||
}
|
}
|
||||||
@@ -293,10 +292,8 @@ export function FloatingPlayer() {
|
|||||||
const playerRef = useRef<HTMLDivElement>(null);
|
const playerRef = useRef<HTMLDivElement>(null);
|
||||||
const [selectionToolbarVisible, setSelectionToolbarVisible] = useState(false);
|
const [selectionToolbarVisible, setSelectionToolbarVisible] = useState(false);
|
||||||
const isMobile = useIsMobile();
|
const isMobile = useIsMobile();
|
||||||
const { minimized, setMinimized, resetTimer } = useMobileMinimize(
|
const { minimized, setMinimized, resetTimer } =
|
||||||
isMobile,
|
useAutoMinimize(!!currentTrack);
|
||||||
!!currentTrack,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Watch for the selection toolbar appearing/disappearing in the DOM
|
// Watch for the selection toolbar appearing/disappearing in the DOM
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -343,6 +340,22 @@ export function FloatingPlayer() {
|
|||||||
const iPrevious = interact(previous);
|
const iPrevious = interact(previous);
|
||||||
const iStop = interact(stop);
|
const iStop = interact(stop);
|
||||||
|
|
||||||
|
// Minimize when clicking/tapping outside the player
|
||||||
|
useEffect(() => {
|
||||||
|
if (!currentTrack || minimized) return;
|
||||||
|
|
||||||
|
function handleOutsideClick(e: PointerEvent) {
|
||||||
|
const player = playerRef.current;
|
||||||
|
if (!player) return;
|
||||||
|
if (player.contains(e.target as Node)) return;
|
||||||
|
setMinimized(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener("pointerdown", handleOutsideClick);
|
||||||
|
return () =>
|
||||||
|
document.removeEventListener("pointerdown", handleOutsideClick);
|
||||||
|
}, [currentTrack, minimized, setMinimized]);
|
||||||
|
|
||||||
// Keyboard shortcuts when player is focused
|
// Keyboard shortcuts when player is focused
|
||||||
const handleKeyDown = useCallback(
|
const handleKeyDown = useCallback(
|
||||||
(e: React.KeyboardEvent) => {
|
(e: React.KeyboardEvent) => {
|
||||||
@@ -403,7 +416,7 @@ export function FloatingPlayer() {
|
|||||||
// ── Render ──
|
// ── Render ──
|
||||||
return (
|
return (
|
||||||
<AnimatePresence mode="popLayout">
|
<AnimatePresence mode="popLayout">
|
||||||
{isMobile && minimized ? (
|
{minimized ? (
|
||||||
<motion.button
|
<motion.button
|
||||||
key="mini-pill"
|
key="mini-pill"
|
||||||
data-audio-player
|
data-audio-player
|
||||||
@@ -636,11 +649,11 @@ export function FloatingPlayer() {
|
|||||||
</Link>
|
</Link>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Close */}
|
{/* Minimize (playing) or Close (paused) */}
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={iStop}
|
onClick={isPlaying ? () => setMinimized(true) : iStop}
|
||||||
aria-label="Close player"
|
aria-label={isPlaying ? "Minimize player" : "Close player"}
|
||||||
className="size-7 inline-flex items-center justify-center rounded-md text-white/50 hover:text-white hover:bg-white/10 transition-colors outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
className="size-7 inline-flex items-center justify-center rounded-md text-white/50 hover:text-white hover:bg-white/10 transition-colors outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
||||||
>
|
>
|
||||||
<X className="size-4" />
|
<X className="size-4" />
|
||||||
@@ -699,11 +712,11 @@ export function FloatingPlayer() {
|
|||||||
</Link>
|
</Link>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Close */}
|
{/* Minimize (playing) or Close (paused) */}
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={iStop}
|
onClick={isPlaying ? () => setMinimized(true) : iStop}
|
||||||
aria-label="Close player"
|
aria-label={isPlaying ? "Minimize player" : "Close player"}
|
||||||
className="size-8 inline-flex items-center justify-center rounded-full text-white/50 hover:text-white hover:bg-white/10 transition-colors outline-none focus-visible:ring-2 focus-visible:ring-ring shrink-0"
|
className="size-8 inline-flex items-center justify-center rounded-full text-white/50 hover:text-white hover:bg-white/10 transition-colors outline-none focus-visible:ring-2 focus-visible:ring-ring shrink-0"
|
||||||
>
|
>
|
||||||
<X className="size-4" />
|
<X className="size-4" />
|
||||||
|
|||||||
Reference in New Issue
Block a user