import React, { useEffect, useState } from 'react'; import { useSearchParams } from 'react-router-dom'; import { Play, Search } from 'lucide-react'; import { search, SearchResults as ISearchResults, SubsonicSong } from '../api/subsonic'; import { usePlayerStore } from '../store/playerStore'; import AlbumRow from '../components/AlbumRow'; import ArtistRow from '../components/ArtistRow'; import { useTranslation } from 'react-i18next'; function formatDuration(s: number) { return `${Math.floor(s / 60)}:${(s % 60).toString().padStart(2, '0')}`; } export default function SearchResults() { const { t } = useTranslation(); const [params] = useSearchParams(); const query = params.get('q') ?? ''; const [results, setResults] = useState(null); const [loading, setLoading] = useState(false); const playTrack = usePlayerStore(s => s.playTrack); const currentTrack = usePlayerStore(s => s.currentTrack); useEffect(() => { if (!query.trim()) { setResults(null); return; } setLoading(true); search(query, { artistCount: 20, albumCount: 20, songCount: 50 }) .then(r => setResults(r)) .finally(() => setLoading(false)); }, [query]); const hasResults = results && (results.artists.length || results.albums.length || results.songs.length); const playSong = (song: SubsonicSong, list: SubsonicSong[]) => { playTrack({ id: song.id, title: song.title, artist: song.artist, album: song.album, albumId: song.albumId, artistId: song.artistId, duration: song.duration, coverArt: song.coverArt, year: song.year, bitRate: song.bitRate, suffix: song.suffix, userRating: song.userRating, }, list.map(s => ({ id: s.id, title: s.title, artist: s.artist, album: s.album, albumId: s.albumId, artistId: s.artistId, duration: s.duration, coverArt: s.coverArt, year: s.year, bitRate: s.bitRate, suffix: s.suffix, userRating: s.userRating, }))); }; return (

{query ? t('search.resultsFor', { query }) : t('search.title')}

{loading && (
)} {!loading && query && !hasResults && (
{t('search.noResults', { query })}
)} {!loading && results && ( <> {results.artists.length > 0 && ( )} {results.albums.length > 0 && ( )} {results.songs.length > 0 && (

{t('search.songs')}

{t('albumDetail.trackTitle')}
{t('albumDetail.trackArtist')}
{t('search.album')}
{t('albumDetail.trackFormat')}
{t('albumDetail.trackDuration')}
{results.songs.map(song => (
playSong(song, results.songs)} role="row" draggable onDragStart={e => { e.dataTransfer.effectAllowed = 'copy'; const track = { id: song.id, title: song.title, artist: song.artist, album: song.album, albumId: song.albumId, artistId: song.artistId, duration: song.duration, coverArt: song.coverArt, year: song.year, bitRate: song.bitRate, suffix: song.suffix, userRating: song.userRating, }; e.dataTransfer.setData('text/plain', JSON.stringify({ type: 'song', track })); }} >
{song.title}
{song.artist}
{song.album}
{[song.suffix?.toUpperCase(), song.bitRate ? `${song.bitRate} kbps` : ''].filter(Boolean).join(' ยท ')} {formatDuration(song.duration)}
))}
)} )}
); }