feat: implement compact player and enhance display mode management in AppLayout and Player components

This commit is contained in:
JSC
2025-08-10 10:31:55 +02:00
parent 0c1c420fd8
commit 3084efe139
4 changed files with 307 additions and 9 deletions

View File

@@ -34,20 +34,37 @@ import { cn } from '@/lib/utils'
import { formatDuration } from '@/utils/format-duration'
import { Playlist } from './Playlist'
export type PlayerDisplayMode = 'normal' | 'minimized' | 'maximized'
export type PlayerDisplayMode = 'normal' | 'minimized' | 'maximized' | 'sidebar'
interface PlayerProps {
className?: string
onPlayerModeChange?: (mode: PlayerDisplayMode) => void
}
export function Player({ className }: PlayerProps) {
export function Player({ className, onPlayerModeChange }: PlayerProps) {
const [state, setState] = useState<PlayerState>({
status: 'stopped',
mode: 'continuous',
volume: 80,
position: 0
})
const [displayMode, setDisplayMode] = useState<PlayerDisplayMode>('normal')
const [displayMode, setDisplayMode] = useState<PlayerDisplayMode>(() => {
// Initialize from localStorage or default to 'normal'
if (typeof window !== 'undefined') {
const saved = localStorage.getItem('playerDisplayMode') as PlayerDisplayMode
return saved && ['normal', 'minimized', 'maximized', 'sidebar'].includes(saved) ? saved : 'normal'
}
return 'normal'
})
// Notify parent when display mode changes and save to localStorage
useEffect(() => {
onPlayerModeChange?.(displayMode)
// Save to localStorage
if (typeof window !== 'undefined') {
localStorage.setItem('playerDisplayMode', displayMode)
}
}, [displayMode, onPlayerModeChange])
const [showPlaylist, setShowPlaylist] = useState(false)
const [isLoading, setIsLoading] = useState(false)
const [isMuted, setIsMuted] = useState(false)
@@ -187,12 +204,18 @@ export function Player({ className }: PlayerProps) {
}
}
const expandFromSidebar = useCallback(() => {
setDisplayMode('normal')
}, [])
const getPlayerPosition = () => {
switch (displayMode) {
case 'minimized':
return 'fixed bottom-4 right-4 z-50'
case 'maximized':
return 'fixed inset-0 z-50 bg-background'
case 'sidebar':
return 'hidden' // Hidden when in sidebar mode
default:
return 'fixed bottom-4 right-4 z-50'
}
@@ -263,9 +286,9 @@ export function Player({ className }: PlayerProps) {
<Button
size="sm"
variant="ghost"
onClick={() => setDisplayMode('minimized')}
onClick={() => setDisplayMode('sidebar')}
className="h-6 w-6 p-0 hover:bg-muted"
title="Minimize"
title="Minimize to Sidebar"
>
<Minimize2 className="h-3 w-3" />
</Button>
@@ -682,6 +705,16 @@ export function Player({ className }: PlayerProps) {
</div>
)
// Expose expand function for external use
useEffect(() => {
// Store expand function globally so sidebar can access it
const windowWithExpand = window as unknown as { __expandPlayerFromSidebar?: () => void }
windowWithExpand.__expandPlayerFromSidebar = expandFromSidebar
return () => {
delete windowWithExpand.__expandPlayerFromSidebar
}
}, [expandFromSidebar])
if (!state) return null
return (