81 lines
2.4 KiB
JavaScript
81 lines
2.4 KiB
JavaScript
import { Play, Pause, SkipForward, Music } from 'lucide-react'
|
|
import { useMusicPlayer } from '../contexts/MusicPlayerContext'
|
|
import { hapticFeedback } from '../utils/telegram'
|
|
import './MiniPlayer.css'
|
|
|
|
export default function MiniPlayer() {
|
|
const {
|
|
currentTrack,
|
|
isPlaying,
|
|
progress,
|
|
duration,
|
|
togglePlay,
|
|
playNext,
|
|
toggleExpanded
|
|
} = useMusicPlayer()
|
|
|
|
if (!currentTrack) return null
|
|
|
|
const progressPercent = duration > 0 ? (progress / duration) * 100 : 0
|
|
|
|
const handleTogglePlay = (e) => {
|
|
e.stopPropagation()
|
|
hapticFeedback('light')
|
|
togglePlay()
|
|
}
|
|
|
|
const handleNext = (e) => {
|
|
e.stopPropagation()
|
|
hapticFeedback('light')
|
|
playNext()
|
|
}
|
|
|
|
const handleExpand = () => {
|
|
hapticFeedback('light')
|
|
toggleExpanded()
|
|
}
|
|
|
|
return (
|
|
<div className="mini-player" onClick={handleExpand}>
|
|
<div className="mini-player-progress" style={{ width: `${progressPercent}%` }} />
|
|
|
|
<div className="mini-player-content">
|
|
<div className="mini-player-cover">
|
|
{currentTrack.coverImage ? (
|
|
<img
|
|
src={currentTrack.coverImage.startsWith('http')
|
|
? currentTrack.coverImage
|
|
: (import.meta.env.VITE_API_URL || 'http://localhost:3000/api').replace('/api', '') + currentTrack.coverImage
|
|
}
|
|
alt={currentTrack.title}
|
|
onError={(e) => {
|
|
e.target.style.display = 'none'
|
|
e.target.nextElementSibling.style.display = 'flex'
|
|
}}
|
|
/>
|
|
) : null}
|
|
<div style={{ display: currentTrack.coverImage ? 'none' : 'flex' }}>
|
|
<Music size={20} />
|
|
</div>
|
|
</div>
|
|
|
|
<div className="mini-player-info">
|
|
<div className="mini-player-title">{currentTrack.title}</div>
|
|
<div className="mini-player-artist">{currentTrack.artist?.name || 'Unknown'}</div>
|
|
</div>
|
|
|
|
<div className="mini-player-controls">
|
|
<button className="mini-player-btn" onClick={handleTogglePlay}>
|
|
{isPlaying ? <Pause size={24} fill="currentColor" /> : <Play size={24} fill="currentColor" />}
|
|
</button>
|
|
<button className="mini-player-btn" onClick={handleNext}>
|
|
<SkipForward size={24} />
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
|