diff --git a/app/api/music/playlist/[id]/route.ts b/app/api/music/playlist/[id]/route.ts index 0982ac7..2276fcd 100644 --- a/app/api/music/playlist/[id]/route.ts +++ b/app/api/music/playlist/[id]/route.ts @@ -35,18 +35,23 @@ export async function GET( const pl = data.playlist if (!pl) return NextResponse.json({ error: 'Playlist not found' }, { status: 404 }) - const songs = (pl.entry || []).map((s) => ({ - id: s.id, - title: s.title, - artist: s.artist, - album: s.album, - albumId: s.albumId, - duration: s.duration, - track: s.track, - year: s.year, - coverArt: s.coverArt, - suffix: s.suffix, - })) + // Dedup by title+artist, keeping first occurrence + const seen = new Set() + const songs = (pl.entry || []).reduce>((acc, s) => { + const key = `${s.title.toLowerCase().trim()}|||${s.artist.toLowerCase().trim()}` + if (!seen.has(key)) { + seen.add(key) + acc.push({ + id: s.id, title: s.title, artist: s.artist, album: s.album, + albumId: s.albumId, duration: s.duration, track: s.track, + year: s.year, coverArt: s.coverArt, suffix: s.suffix, + }) + } + return acc + }, []) return NextResponse.json({ id: pl.id, diff --git a/app/music/page.tsx b/app/music/page.tsx index 0dbe702..fec2453 100644 --- a/app/music/page.tsx +++ b/app/music/page.tsx @@ -1,6 +1,7 @@ 'use client' -import { useState, useEffect, useRef } from 'react' +import { useState, useEffect, useRef, Suspense } from 'react' +import { useSearchParams } from 'next/navigation' import { Button } from '@/components/ui/button' import { Badge } from '@/components/ui/badge' import { JefflixLogo } from '@/components/jefflix-logo' @@ -33,9 +34,18 @@ interface SlskdFile { } export default function MusicPage() { + return ( + + + + ) +} + +function MusicPageInner() { + const searchParams = useSearchParams() const { state } = useMusicPlayer() const { offlineIds, download: downloadTrack } = useOffline() - const [query, setQuery] = useState('') + const [query, setQuery] = useState(() => searchParams.get('q') || '') const [debouncedQuery, setDebouncedQuery] = useState('') const [songs, setSongs] = useState([]) const [searching, setSearching] = useState(false) diff --git a/components/music/full-screen-player.tsx b/components/music/full-screen-player.tsx index c65c1c7..1f4970f 100644 --- a/components/music/full-screen-player.tsx +++ b/components/music/full-screen-player.tsx @@ -1,6 +1,7 @@ 'use client' import { useState, useEffect } from 'react' +import { useRouter } from 'next/navigation' import { Drawer } from 'vaul' import { useMusicPlayer } from './music-provider' import { DownloadButton } from './download-button' @@ -21,6 +22,7 @@ import { VolumeX, ChevronDown, Speaker, + Shuffle, } from 'lucide-react' function formatTime(secs: number) { @@ -31,7 +33,8 @@ function formatTime(secs: number) { } export function FullScreenPlayer() { - const { state, togglePlay, seek, setVolume, nextTrack, prevTrack, setFullScreen, outputDevices, currentOutputId, setOutputDevice } = useMusicPlayer() + const { state, togglePlay, seek, setVolume, nextTrack, prevTrack, setFullScreen, toggleShuffle, outputDevices, currentOutputId, setOutputDevice } = useMusicPlayer() + const router = useRouter() const [lyrics, setLyrics] = useState(null) const [syncedLyrics, setSyncedLyrics] = useState(null) const [loadingLyrics, setLoadingLyrics] = useState(false) @@ -109,7 +112,15 @@ export function FullScreenPlayer() { {/* Title / Artist */}

{track.title}

-

{track.artist}

+

{track.album}

@@ -130,6 +141,13 @@ export function FullScreenPlayer() { {/* Controls */}
+ diff --git a/components/music/mini-player.tsx b/components/music/mini-player.tsx index d7f0029..11030c3 100644 --- a/components/music/mini-player.tsx +++ b/components/music/mini-player.tsx @@ -5,7 +5,7 @@ import { useMusicPlayer } from './music-provider' import { FullScreenPlayer } from './full-screen-player' import { QueueView } from './queue-view' import { Slider } from '@/components/ui/slider' -import { Play, Pause, SkipBack, SkipForward, ListMusic } from 'lucide-react' +import { Play, Pause, SkipBack, SkipForward, ListMusic, Shuffle } from 'lucide-react' function formatTime(secs: number) { if (!secs || !isFinite(secs)) return '0:00' @@ -15,7 +15,7 @@ function formatTime(secs: number) { } export function MiniPlayer() { - const { state, togglePlay, seek, nextTrack, prevTrack, setFullScreen } = useMusicPlayer() + const { state, togglePlay, seek, nextTrack, prevTrack, setFullScreen, toggleShuffle } = useMusicPlayer() const [queueOpen, setQueueOpen] = useState(false) if (!state.currentTrack) return null @@ -69,6 +69,13 @@ export function MiniPlayer() { {/* Controls */}
+ + +
+ )} + {/* Play button / track number */}