feat: remove useRenderFlash hook and clean up related code in Player components
This commit is contained in:
@@ -21,7 +21,6 @@ import { Playlist } from './Playlist'
|
|||||||
import { PlayerControls } from './PlayerControls'
|
import { PlayerControls } from './PlayerControls'
|
||||||
import { PlayerProgress } from './PlayerProgress'
|
import { PlayerProgress } from './PlayerProgress'
|
||||||
import { PlayerTrackInfo } from './PlayerTrackInfo'
|
import { PlayerTrackInfo } from './PlayerTrackInfo'
|
||||||
import { useRenderFlash } from '@/hooks/useRenderFlash'
|
|
||||||
|
|
||||||
export type PlayerDisplayMode = 'normal' | 'minimized' | 'maximized' | 'sidebar'
|
export type PlayerDisplayMode = 'normal' | 'minimized' | 'maximized' | 'sidebar'
|
||||||
|
|
||||||
@@ -108,7 +107,6 @@ export function Player({ className, onPlayerModeChange }: PlayerProps) {
|
|||||||
const [showPlaylist, setShowPlaylist] = useState(false)
|
const [showPlaylist, setShowPlaylist] = useState(false)
|
||||||
const [isLoading, setIsLoading] = useState(false)
|
const [isLoading, setIsLoading] = useState(false)
|
||||||
|
|
||||||
const playlistFlashClass = useRenderFlash([showPlaylist, state.playlist?.id, state.playlist?.sounds.length], 'purple')
|
|
||||||
|
|
||||||
// Load initial state
|
// Load initial state
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -359,8 +357,7 @@ export function Player({ className, onPlayerModeChange }: PlayerProps) {
|
|||||||
|
|
||||||
{/* Playlist */}
|
{/* Playlist */}
|
||||||
{showPlaylist && state.playlist && (
|
{showPlaylist && state.playlist && (
|
||||||
<div className={`mt-4 pt-4 border-t ${playlistFlashClass}`}>
|
<div className="mt-4 pt-4 border-t">
|
||||||
{/* DEBUG: Playlist - PURPLE FLASH */}
|
|
||||||
<Playlist
|
<Playlist
|
||||||
playlist={state.playlist}
|
playlist={state.playlist}
|
||||||
currentIndex={state.index}
|
currentIndex={state.index}
|
||||||
@@ -437,8 +434,7 @@ export function Player({ className, onPlayerModeChange }: PlayerProps) {
|
|||||||
|
|
||||||
{/* Playlist Sidebar */}
|
{/* Playlist Sidebar */}
|
||||||
{state.playlist && (
|
{state.playlist && (
|
||||||
<div className={`w-96 border-l bg-muted/10 backdrop-blur-sm ${playlistFlashClass}`}>
|
<div className="w-96 border-l bg-muted/10 backdrop-blur-sm">
|
||||||
{/* DEBUG: Playlist Sidebar - PURPLE FLASH */}
|
|
||||||
<div className="p-4 border-b">
|
<div className="p-4 border-b">
|
||||||
<h3 className="font-semibold">Playlist</h3>
|
<h3 className="font-semibold">Playlist</h3>
|
||||||
<p className="text-sm text-muted-foreground">
|
<p className="text-sm text-muted-foreground">
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ import {
|
|||||||
VolumeX,
|
VolumeX,
|
||||||
} from 'lucide-react'
|
} from 'lucide-react'
|
||||||
import { memo, useMemo } from 'react'
|
import { memo, useMemo } from 'react'
|
||||||
import { useRenderFlash } from '@/hooks/useRenderFlash'
|
|
||||||
|
|
||||||
interface PlayerControlsProps {
|
interface PlayerControlsProps {
|
||||||
status: PlayerState['status']
|
status: PlayerState['status']
|
||||||
@@ -55,7 +54,6 @@ export const PlayerControls = memo(function PlayerControls({
|
|||||||
}: PlayerControlsProps) {
|
}: PlayerControlsProps) {
|
||||||
const isMinimized = variant === 'minimized'
|
const isMinimized = variant === 'minimized'
|
||||||
const isMaximized = variant === 'maximized'
|
const isMaximized = variant === 'maximized'
|
||||||
const flashClass = useRenderFlash([status, mode, volume], 'green')
|
|
||||||
|
|
||||||
const modeIcon = useMemo(() => {
|
const modeIcon = useMemo(() => {
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
@@ -79,8 +77,7 @@ export const PlayerControls = memo(function PlayerControls({
|
|||||||
|
|
||||||
if (isMinimized) {
|
if (isMinimized) {
|
||||||
return (
|
return (
|
||||||
<div className={`${flashClass} flex items-center gap-1`}>
|
<div className="flex items-center gap-1">
|
||||||
{/* DEBUG: PlayerControls Minimized - GREEN FLASH */}
|
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
@@ -127,8 +124,7 @@ export const PlayerControls = memo(function PlayerControls({
|
|||||||
|
|
||||||
if (isMaximized) {
|
if (isMaximized) {
|
||||||
return (
|
return (
|
||||||
<div className={flashClass}>
|
<div>
|
||||||
{/* DEBUG: PlayerControls Maximized - GREEN FLASH */}
|
|
||||||
{/* Large Controls */}
|
{/* Large Controls */}
|
||||||
<div className="flex items-center gap-4 mb-8">
|
<div className="flex items-center gap-4 mb-8">
|
||||||
<Button
|
<Button
|
||||||
@@ -208,8 +204,7 @@ export const PlayerControls = memo(function PlayerControls({
|
|||||||
|
|
||||||
// Normal variant
|
// Normal variant
|
||||||
return (
|
return (
|
||||||
<div className={flashClass}>
|
<>
|
||||||
{/* DEBUG: PlayerControls Normal - GREEN FLASH */}
|
|
||||||
{/* Main Controls */}
|
{/* Main Controls */}
|
||||||
<div className="flex items-center justify-center gap-2 mb-4">
|
<div className="flex items-center justify-center gap-2 mb-4">
|
||||||
<Button
|
<Button
|
||||||
@@ -302,6 +297,6 @@ export const PlayerControls = memo(function PlayerControls({
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
@@ -2,7 +2,6 @@ import { Progress } from '@/components/ui/progress'
|
|||||||
import { cn } from '@/lib/utils'
|
import { cn } from '@/lib/utils'
|
||||||
import { memo, useMemo } from 'react'
|
import { memo, useMemo } from 'react'
|
||||||
import { NumberFlowDuration } from '../ui/number-flow-duration'
|
import { NumberFlowDuration } from '../ui/number-flow-duration'
|
||||||
import { useRenderFlash } from '@/hooks/useRenderFlash'
|
|
||||||
|
|
||||||
interface PlayerProgressProps {
|
interface PlayerProgressProps {
|
||||||
position: number
|
position: number
|
||||||
@@ -19,11 +18,6 @@ export const PlayerProgress = memo(function PlayerProgress({
|
|||||||
}: PlayerProgressProps) {
|
}: PlayerProgressProps) {
|
||||||
const isMaximized = variant === 'maximized'
|
const isMaximized = variant === 'maximized'
|
||||||
|
|
||||||
// Only flash when seconds actually change to avoid NumberFlow timing issues
|
|
||||||
const positionSeconds = Math.floor(position / 1000)
|
|
||||||
const durationSeconds = Math.floor(duration / 1000)
|
|
||||||
const flashClass = useRenderFlash([positionSeconds, durationSeconds], 'blue')
|
|
||||||
|
|
||||||
const progressPercentage = useMemo(() =>
|
const progressPercentage = useMemo(() =>
|
||||||
(position / (duration || 1)) * 100,
|
(position / (duration || 1)) * 100,
|
||||||
[position, duration]
|
[position, duration]
|
||||||
@@ -38,11 +32,7 @@ export const PlayerProgress = memo(function PlayerProgress({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cn(
|
<div className={isMaximized ? 'w-full max-w-md mb-8' : 'mb-4'}>
|
||||||
flashClass,
|
|
||||||
isMaximized ? 'w-full max-w-md mb-8' : 'mb-4'
|
|
||||||
)}>
|
|
||||||
{/* DEBUG: PlayerProgress - BLUE FLASH */}
|
|
||||||
<Progress
|
<Progress
|
||||||
value={progressPercentage}
|
value={progressPercentage}
|
||||||
className={cn(
|
className={cn(
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import type { PlayerState } from '@/lib/api/services/player'
|
|||||||
import { cn } from '@/lib/utils'
|
import { cn } from '@/lib/utils'
|
||||||
import { Download, ExternalLink, MoreVertical, Music } from 'lucide-react'
|
import { Download, ExternalLink, MoreVertical, Music } from 'lucide-react'
|
||||||
import { memo } from 'react'
|
import { memo } from 'react'
|
||||||
import { useRenderFlash } from '@/hooks/useRenderFlash'
|
|
||||||
|
|
||||||
interface PlayerTrackInfoProps {
|
interface PlayerTrackInfoProps {
|
||||||
currentSound: PlayerState['current_sound']
|
currentSound: PlayerState['current_sound']
|
||||||
@@ -24,11 +23,9 @@ export const PlayerTrackInfo = memo(function PlayerTrackInfo({
|
|||||||
variant = 'normal',
|
variant = 'normal',
|
||||||
}: PlayerTrackInfoProps) {
|
}: PlayerTrackInfoProps) {
|
||||||
const isMaximized = variant === 'maximized'
|
const isMaximized = variant === 'maximized'
|
||||||
const flashClass = useRenderFlash([currentSound?.id, currentSound?.name, currentSound?.thumbnail], 'red')
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={flashClass}>
|
<>
|
||||||
{/* DEBUG: PlayerTrackInfo - RED FLASH */}
|
|
||||||
{/* Album Art / Thumbnail */}
|
{/* Album Art / Thumbnail */}
|
||||||
<div className={isMaximized ? 'max-w-300 max-h-200 aspect-auto bg-muted rounded-lg flex items-center justify-center overflow-hidden mb-8' : 'mb-4'}>
|
<div className={isMaximized ? 'max-w-300 max-h-200 aspect-auto bg-muted rounded-lg flex items-center justify-center overflow-hidden mb-8' : 'mb-4'}>
|
||||||
{currentSound?.thumbnail ? (
|
{currentSound?.thumbnail ? (
|
||||||
@@ -101,6 +98,6 @@ export const PlayerTrackInfo = memo(function PlayerTrackInfo({
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
import { useEffect, useRef, useState } from 'react'
|
|
||||||
|
|
||||||
export function useRenderFlash(deps: any[], color: string = 'red', duration: number = 300) {
|
|
||||||
const [isFlashing, setIsFlashing] = useState(false)
|
|
||||||
const prevDepsRef = useRef<any[] | undefined>(undefined)
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
// Check if this is the first render
|
|
||||||
if (!prevDepsRef.current) {
|
|
||||||
prevDepsRef.current = deps
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if any dependency actually changed
|
|
||||||
const hasChanged = deps.some((dep, index) => dep !== prevDepsRef.current![index])
|
|
||||||
|
|
||||||
if (hasChanged) {
|
|
||||||
setIsFlashing(true)
|
|
||||||
const timer = setTimeout(() => {
|
|
||||||
setIsFlashing(false)
|
|
||||||
}, duration)
|
|
||||||
|
|
||||||
prevDepsRef.current = deps
|
|
||||||
return () => clearTimeout(timer)
|
|
||||||
}
|
|
||||||
|
|
||||||
prevDepsRef.current = deps
|
|
||||||
}, [...deps])
|
|
||||||
|
|
||||||
const flashClass = isFlashing
|
|
||||||
? `border-2 border-${color}-500 border-dashed animate-pulse`
|
|
||||||
: ''
|
|
||||||
|
|
||||||
return flashClass
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user