59 lines
1.7 KiB
TypeScript
59 lines
1.7 KiB
TypeScript
'use client'
|
|
|
|
import type { Track } from './music-provider'
|
|
import { useOffline } from '@/lib/stores/offline'
|
|
import { Download, Loader2, CheckCircle, Clock } from 'lucide-react'
|
|
|
|
interface DownloadButtonProps {
|
|
track: Track
|
|
className?: string
|
|
size?: 'sm' | 'md'
|
|
}
|
|
|
|
export function DownloadButton({ track, className = '', size = 'sm' }: DownloadButtonProps) {
|
|
const { offlineIds, download, remove, getStatus } = useOffline()
|
|
const isOffline = offlineIds.has(track.id)
|
|
const status = getStatus(track.id)
|
|
|
|
const iconSize = size === 'sm' ? 'h-4 w-4' : 'h-5 w-5'
|
|
const padding = size === 'sm' ? 'p-1.5' : 'p-2'
|
|
|
|
if (isOffline) {
|
|
return (
|
|
<button
|
|
onClick={(e) => { e.stopPropagation(); remove(track.id) }}
|
|
className={`${padding} rounded-full hover:bg-muted/50 transition-colors text-green-500 ${className}`}
|
|
title="Downloaded — tap to remove"
|
|
>
|
|
<CheckCircle className={iconSize} />
|
|
</button>
|
|
)
|
|
}
|
|
|
|
if (status === 'downloading') {
|
|
return (
|
|
<span className={`${padding} text-muted-foreground ${className}`} title="Downloading...">
|
|
<Loader2 className={`${iconSize} animate-spin`} />
|
|
</span>
|
|
)
|
|
}
|
|
|
|
if (status === 'queued') {
|
|
return (
|
|
<span className={`${padding} text-muted-foreground ${className}`} title="Queued for download">
|
|
<Clock className={iconSize} />
|
|
</span>
|
|
)
|
|
}
|
|
|
|
return (
|
|
<button
|
|
onClick={(e) => { e.stopPropagation(); download(track) }}
|
|
className={`${padding} rounded-full hover:bg-muted/50 transition-colors text-muted-foreground hover:text-foreground ${className}`}
|
|
title="Download for offline"
|
|
>
|
|
<Download className={iconSize} />
|
|
</button>
|
|
)
|
|
}
|