This commit is contained in:
afkarxyz
2026-03-25 20:44:31 +07:00
parent f8ef1180f6
commit 5ebd28982b
13 changed files with 423 additions and 26 deletions
+45 -2
View File
@@ -100,7 +100,31 @@ export function ArtistInfo({ artistInfo, albumList, trackList, searchQuery, sort
const [downloadingGalleryIndex, setDownloadingGalleryIndex] = useState<number | null>(null);
const [downloadingAllGallery, setDownloadingAllGallery] = useState(false);
const [activeTab, setActiveTab] = useState<"albums" | "tracks" | "gallery">("albums");
const [activeAlbumFilter, setActiveAlbumFilter] = useState<string>("all");
const displayedAlbumCount = artistInfo.total_albums || albumList.length;
const albumFilterCounts = useMemo(() => {
const counts = new Map<string, number>();
counts.set("all", (albumList || []).length);
for (const album of albumList || []) {
const type = (album.album_type || "").trim().toLowerCase();
if (!type)
continue;
counts.set(type, (counts.get(type) || 0) + 1);
}
return counts;
}, [albumList]);
const albumFilters = useMemo(() => {
const uniqueTypes = Array.from(new Set((albumList || [])
.map((album) => (album.album_type || "").trim().toLowerCase())
.filter(Boolean)));
return ["all", ...uniqueTypes];
}, [albumList]);
const filteredAlbums = useMemo(() => {
if (activeAlbumFilter === "all") {
return albumList || [];
}
return (albumList || []).filter((album) => (album.album_type || "").trim().toLowerCase() === activeAlbumFilter);
}, [albumList, activeAlbumFilter]);
const filteredAlbumGroups = useMemo(() => {
const albumTypeMap = new Map(albumList.map(a => [a.name, a.album_type]));
const albumGroups = trackList.reduce((acc, track) => {
@@ -127,6 +151,17 @@ export function ArtistInfo({ artistInfo, albumList, trackList, searchQuery, sort
return dateB.localeCompare(dateA);
});
}, [trackList, albumList]);
const formatAlbumFilterLabel = (value: string) => {
const count = albumFilterCounts.get(value) || 0;
if (value === "all")
return `All (${count})`;
const label = value
.split(/[_\s]+/)
.filter(Boolean)
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
.join(" ");
return `${label} (${count})`;
};
const handleDownloadHeader = async () => {
if (!artistInfo.header)
return;
@@ -461,8 +496,13 @@ export function ArtistInfo({ artistInfo, albumList, trackList, searchQuery, sort
</Button>)}
</div>
</div>
{albumFilters.length > 1 && (<div className="flex flex-wrap gap-2">
{albumFilters.map((filter) => (<Button key={filter} size="sm" variant={activeAlbumFilter === filter ? "default" : "outline"} onClick={() => setActiveAlbumFilter(filter)}>
{formatAlbumFilterLabel(filter)}
</Button>))}
</div>)}
<div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-4">
{albumList.map((album) => {
{filteredAlbums.map((album) => {
const albumTracks = trackList.filter(t => t.album_name === album.name);
const tracksWithId = albumTracks.filter(t => t.spotify_id);
const isSelected = tracksWithId.length > 0 && tracksWithId.every(t => selectedTracks.includes(t.spotify_id!));
@@ -495,6 +535,9 @@ export function ArtistInfo({ artistInfo, albumList, trackList, searchQuery, sort
</div>);
})}
</div>
{filteredAlbums.length === 0 && (<div className="rounded-lg border border-dashed border-border p-6 text-sm text-muted-foreground">
No releases found for the selected discography filter.
</div>)}
</div>)}
{activeTab === "tracks" && trackList.length > 0 && (<div className="space-y-4">
@@ -564,7 +607,7 @@ export function ArtistInfo({ artistInfo, albumList, trackList, searchQuery, sort
</Button>
</TooltipTrigger>
<TooltipContent>
<p>Download All Covers</p>
<p>Download All Separate Covers</p>
</TooltipContent>
</Tooltip>)}
{downloadedTracks.size > 0 && (<Button onClick={onOpenFolder} size="sm" variant="outline">