Files
lidify/frontend/features/search/components/TopResult.tsx
Your Name cc8d0f6969 Release v1.3.0: Multi-source downloads, audio analyzer resilience, mobile improvements
Major Features:
- Multi-source download system (Soulseek/Lidarr with fallback)
- Configurable enrichment speed control (1-5x)
- Mobile touch drag support for seek sliders
- iOS PWA media controls (Control Center, Lock Screen)
- Artist name alias resolution via Last.fm
- Circuit breaker pattern for audio analysis

Critical Fixes:
- Audio analyzer stability (non-ASCII, BrokenProcessPool, OOM)
- Discovery system race conditions and import failures
- Radio decade categorization using originalYear
- LastFM API response normalization
- Mood bucket infinite loop prevention

Security:
- Bull Board admin authentication
- Lidarr webhook signature verification
- JWT token expiration and refresh
- Encryption key validation on startup

Closes #2, #6, #9, #13, #21, #26, #31, #34, #35, #37, #40, #43
2026-01-06 20:07:33 -06:00

68 lines
2.4 KiB
TypeScript

import Link from "next/link";
import Image from "next/image";
import { Music } from "lucide-react";
import { api } from "@/lib/api";
import { Artist, DiscoverResult } from "../types";
import { formatListeners } from "@/lib/format";
interface TopResultProps {
libraryArtist?: Artist;
discoveryArtist?: DiscoverResult;
}
export function TopResult({ libraryArtist, discoveryArtist }: TopResultProps) {
// Prefer library artist over discovery
if (!libraryArtist && !discoveryArtist) {
return null;
}
const isLibrary = !!libraryArtist;
// Get the display name
const name = libraryArtist?.name || discoveryArtist?.name || "";
// Get the artist ID for linking - prefer MBID for consistent URLs
const artistId = isLibrary
? libraryArtist!.mbid || libraryArtist!.id
: discoveryArtist?.mbid || encodeURIComponent(name);
// Get the image URL
const imageUrl = isLibrary
? libraryArtist?.heroUrl
: discoveryArtist?.image;
return (
<section data-tv-section="search-top-result">
<h2 className="text-2xl font-bold text-white mb-6">Top result</h2>
<Link
href={`/artist/${artistId}`}
className="bg-[#121212] hover:bg-[#181818] p-6 rounded-lg transition-all flex items-center gap-6 w-full sm:w-96"
data-tv-card
data-tv-card-index={0}
tabIndex={0}
>
<div className="relative w-24 h-24 bg-[#181818] rounded-full flex items-center justify-center overflow-hidden shrink-0">
{imageUrl ? (
<Image
src={api.getCoverArtUrl(imageUrl, 300)}
alt={name}
fill
sizes="96px"
className="object-cover"
unoptimized
/>
) : (
<Music className="w-12 h-12 text-gray-600" />
)}
</div>
<div className="flex-1">
<h3 className="text-3xl font-bold text-white mb-2">
{name}
</h3>
<p className="text-sm text-white font-bold">Artist</p>
</div>
</Link>
</section>
);
}