ai generated solutions to our ai generated problems
This commit is contained in:
+57
-1
@@ -1903,6 +1903,8 @@ function SongOfDayCard({ onRetry, songOfDay }) {
|
|||||||
const audioRef = useRef(null)
|
const audioRef = useRef(null)
|
||||||
const [isPreviewPlaying, setIsPreviewPlaying] = useState(false)
|
const [isPreviewPlaying, setIsPreviewPlaying] = useState(false)
|
||||||
const [previewError, setPreviewError] = useState('')
|
const [previewError, setPreviewError] = useState('')
|
||||||
|
const [previewVolume, setPreviewVolume] = useState(0.18)
|
||||||
|
const [isPreviewMuted, setIsPreviewMuted] = useState(false)
|
||||||
const message =
|
const message =
|
||||||
songOfDay.status === 'error'
|
songOfDay.status === 'error'
|
||||||
? songOfDay.error
|
? songOfDay.error
|
||||||
@@ -1913,6 +1915,29 @@ function SongOfDayCard({ onRetry, songOfDay }) {
|
|||||||
setPreviewError('')
|
setPreviewError('')
|
||||||
}, [track?.id, track?.preview_url])
|
}, [track?.id, track?.preview_url])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const audio = audioRef.current
|
||||||
|
if (!audio) return
|
||||||
|
audio.volume = previewVolume
|
||||||
|
audio.muted = isPreviewMuted
|
||||||
|
}, [isPreviewMuted, previewVolume, track?.preview_url])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const audio = audioRef.current
|
||||||
|
if (!track?.preview_url || !audio) return
|
||||||
|
|
||||||
|
audio.volume = previewVolume
|
||||||
|
audio.muted = isPreviewMuted
|
||||||
|
audio.play()
|
||||||
|
.then(() => {
|
||||||
|
setIsPreviewPlaying(true)
|
||||||
|
setPreviewError('')
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
setIsPreviewPlaying(false)
|
||||||
|
})
|
||||||
|
}, [isPreviewMuted, previewVolume, track?.preview_url])
|
||||||
|
|
||||||
function togglePreview() {
|
function togglePreview() {
|
||||||
const audio = audioRef.current
|
const audio = audioRef.current
|
||||||
if (!audio) return
|
if (!audio) return
|
||||||
@@ -1950,6 +1975,7 @@ function SongOfDayCard({ onRetry, songOfDay }) {
|
|||||||
<p className="mt-1 text-xs font-semibold text-fury-cyan">{previewError}</p>
|
<p className="mt-1 text-xs font-semibold text-fury-cyan">{previewError}</p>
|
||||||
) : null}
|
) : null}
|
||||||
{track.preview_url ? (
|
{track.preview_url ? (
|
||||||
|
<>
|
||||||
<audio
|
<audio
|
||||||
onEnded={() => setIsPreviewPlaying(false)}
|
onEnded={() => setIsPreviewPlaying(false)}
|
||||||
onError={() => {
|
onError={() => {
|
||||||
@@ -1958,11 +1984,31 @@ function SongOfDayCard({ onRetry, songOfDay }) {
|
|||||||
}}
|
}}
|
||||||
onPause={() => setIsPreviewPlaying(false)}
|
onPause={() => setIsPreviewPlaying(false)}
|
||||||
onPlay={() => setIsPreviewPlaying(true)}
|
onPlay={() => setIsPreviewPlaying(true)}
|
||||||
preload="none"
|
preload="auto"
|
||||||
ref={audioRef}
|
ref={audioRef}
|
||||||
src={track.preview_url}
|
src={track.preview_url}
|
||||||
/>
|
/>
|
||||||
|
<label className="mt-2 flex max-w-44 items-center gap-2 text-xs font-semibold text-text-soft">
|
||||||
|
<span>Vol</span>
|
||||||
|
<input
|
||||||
|
aria-label="Preview volume"
|
||||||
|
className="h-2 min-w-0 flex-1 accent-fury-cyan"
|
||||||
|
max="1"
|
||||||
|
min="0"
|
||||||
|
onChange={(event) => {
|
||||||
|
setPreviewVolume(Number(event.target.value))
|
||||||
|
if (Number(event.target.value) > 0) setIsPreviewMuted(false)
|
||||||
|
}}
|
||||||
|
step="0.01"
|
||||||
|
type="range"
|
||||||
|
value={previewVolume}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
</>
|
||||||
) : null}
|
) : null}
|
||||||
|
<p className="mt-2 text-[11px] font-semibold uppercase tracking-wide text-text-soft">
|
||||||
|
Song data by Last.fm{track.preview_provider ? ` · Previews by ${track.preview_provider}` : ''}
|
||||||
|
</p>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<p className="mt-1 text-sm font-semibold text-text-soft">
|
<p className="mt-1 text-sm font-semibold text-text-soft">
|
||||||
@@ -1979,6 +2025,16 @@ function SongOfDayCard({ onRetry, songOfDay }) {
|
|||||||
{isPreviewPlaying ? 'Pause' : 'Preview'}
|
{isPreviewPlaying ? 'Pause' : 'Preview'}
|
||||||
</button>
|
</button>
|
||||||
) : null}
|
) : null}
|
||||||
|
{track?.preview_url ? (
|
||||||
|
<button
|
||||||
|
aria-pressed={isPreviewMuted}
|
||||||
|
className="shrink-0 rounded-md border border-border px-3 py-2 text-sm font-semibold text-text-soft transition hover:border-ring hover:bg-surface hover:text-text"
|
||||||
|
onClick={() => setIsPreviewMuted((value) => !value)}
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
{isPreviewMuted ? 'Unmute' : 'Mute'}
|
||||||
|
</button>
|
||||||
|
) : null}
|
||||||
{track?.url ? (
|
{track?.url ? (
|
||||||
<a
|
<a
|
||||||
className="shrink-0 rounded-md border border-ring px-3 py-2 text-sm font-semibold text-fury-cyan transition hover:bg-surface hover:text-text"
|
className="shrink-0 rounded-md border border-ring px-3 py-2 text-sm font-semibold text-fury-cyan transition hover:bg-surface hover:text-text"
|
||||||
|
|||||||
Reference in New Issue
Block a user