From b03f6ee1bca1df2f918f921d90746c318f92265c Mon Sep 17 00:00:00 2001 From: Sucukdeluxe Date: Sat, 22 Aug 2026 02:54:14 +0200 Subject: [PATCH] feat(collector): show hoster icons with tooltips Render known hosters with their existing provider icons in collector package and file rows while retaining the full hoster name as a tooltip. Fall back to the compact text label if an icon cannot be loaded. --- CHANGELOG.md | 1 + .../views/collector/CollectorView.tsx | 12 ++++++++-- src/renderer/views/collector/collector.css | 3 +++ tests/collector-view.test.tsx | 23 +++++++++++++++++++ 4 files changed, 37 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a06d1d..01eacad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ All notable changes to Multi-Debrid Downloader are documented in this file. - Rebuilt the link collector as a package-oriented preview with expandable file rows, resolved metadata, availability filters, stable selection, and selected or complete transfer to Downloads. - Route pasted links, clipboard detections, text files, drag-and-drop, and DLC containers through inspection before they enter the download queue. +- Show known hosters as icons with full-name tooltips and a text fallback when an icon cannot be loaded. ## [2.0.54] - 2026-08-21 diff --git a/src/renderer/views/collector/CollectorView.tsx b/src/renderer/views/collector/CollectorView.tsx index 6af8c45..6c1f52f 100644 --- a/src/renderer/views/collector/CollectorView.tsx +++ b/src/renderer/views/collector/CollectorView.tsx @@ -58,6 +58,14 @@ function packageSize(row: CollectorWorkspacePackageRow): string { return `${row.unknownSizeCount > 0 ? "≥ " : ""}${humanSize(row.totalBytes)}`; } +function CollectorHosterLabel({ hoster }: { hoster: ReturnType }): ReactElement { + return ( + + {hoster.iconSrc ? <> { event.currentTarget.hidden = true; event.currentTarget.nextElementSibling?.removeAttribute("hidden"); }} src={hoster.iconSrc} /> : hoster.compact} + + ); +} + export function CollectorSidebar({ model, actions }: CollectorViewProps): ReactElement { return (
@@ -103,7 +111,7 @@ function CollectorPackageGroup({ row, model, actions }: { row: CollectorWorkspac actions.onPackageSelectionChange(row.id, event.target.checked)} ref={(node) => { if (node) node.indeterminate = partiallySelected; }} type="checkbox" /> {row.name}{row.totalCount} Dateien {packageSize(row)} - {row.hosters.map(formatHosterLabel).map((hoster) => {hoster.compact})} + {row.hosters.map(formatHosterLabel).map((hoster) => )} {packageStatus(row)} {packageAvailability(row)} {formatDateTime(row.addedAt)} @@ -115,7 +123,7 @@ function CollectorPackageGroup({ row, model, actions }: { row: CollectorWorkspac actions.onLinkSelectionChange(link.id, event.target.checked)} type="checkbox" /> {link.fileName} {link.fileSizeBytes === null ? "Unbekannt" : humanSize(link.fileSizeBytes)} - {hoster.compact} + {link.status === "ready" ? "Bereit" : link.status === "offline" ? "Offline" : "Ungeprüft"} {link.availability === "online" ? "Online" : link.availability === "offline" ? "Offline" : "Ungeprüft"} {formatDateTime(link.addedAt)} diff --git a/src/renderer/views/collector/collector.css b/src/renderer/views/collector/collector.css index 95fd3ca..73b5d66 100644 --- a/src/renderer/views/collector/collector.css +++ b/src/renderer/views/collector/collector.css @@ -46,6 +46,9 @@ .collector-size-cell, .collector-added-cell { font-variant-numeric: tabular-nums; white-space: nowrap; } .collector-hoster-cell { align-items: center; display: flex; gap: 5px; } .collector-hoster-cell span { color: var(--ui-text); font-weight: 600; } +.collector-hoster-label { align-items: center; display: inline-flex; justify-content: center; min-width: 18px; } +.collector-hoster-icon { display: block; height: 18px; object-fit: contain; width: 18px; } +.collector-hoster-icon[data-hoster="rapidgator"] { transform: translateY(-4px) scale(2); } .collector-status-cell, .collector-added-cell { color: var(--ui-text-muted); } .collector-availability-cell { font-weight: 600; white-space: nowrap; } .collector-availability-cell.is-online { color: var(--ui-success); } diff --git a/tests/collector-view.test.tsx b/tests/collector-view.test.tsx index ad1aad2..97069f6 100644 --- a/tests/collector-view.test.tsx +++ b/tests/collector-view.test.tsx @@ -127,6 +127,29 @@ describe("CollectorView", () => { expect(html).not.toContain(">Lokal<"); }); + it("renders known hosters as icons with their full name as tooltip", () => { + const ddownloadPackages: CollectorPackage[] = [{ + id: "package-ddownload", + name: "Archive", + addedAt: 3000, + links: [{ + id: "link-ddownload", + url: "https://ddownload.com/ntwscdw62gyb", + fileName: "Archive.part01.rar", + fileSizeBytes: 526_385_152, + hoster: "ddownload", + availability: "online", + status: "ready", + addedAt: 3000 + }] + }]; + const html = renderToStaticMarkup(); + + expect(html).toContain('class="collector-hoster-label" title="DDownload"'); + expect(html).toContain('class="collector-hoster-icon" data-hoster="ddownload" src="./provider-icons/ddownload.ico"'); + expect(html).not.toContain('title="DDownload">DD<'); + }); + it("renders collapsed packages without child rows", () => { const html = renderToStaticMarkup(); expect(html).toContain("aria-label=\"SBS14HD ausklappen\"");