round22: Startseite kompakter, Ping-Zeitstempel-Bug behoben, echte Favicon-Deduplizierung per Bildinhalt, automatischer Favicon-Abgleich aus Icon-Datenbank + Nachruest-Button

This commit is contained in:
2026-07-23 20:58:58 +02:00
parent 6a66128172
commit b098007742
8 changed files with 181 additions and 49 deletions

View File

@@ -79,3 +79,32 @@ export async function searchIconDb(query: string, limit = 24): Promise<IconSearc
const matches = names.filter((n) => n.includes(q)).slice(0, limit);
return matches.map((name) => ({ name, url: `${CDN_BASE}/${name}.png` }));
}
/**
* Sucht den besten Treffer in der Icon-Datenbank für einen Dienst-/
* Software-Namen ("Plex", "Pi-hole", "Adguard Home") - für den Fall, dass
* der Scanner selbst kein Favicon gefunden hat (siehe networkScanner.ts).
* Bewusst konservativ: nur ein Treffer, wenn der normalisierte Name exakt
* (oder nach Entfernen von Bindestrichen) übereinstimmt - eine reine
* Teilstring-Suche würde bei kurzen/generischen Namen zu viele falsche
* Zuordnungen liefern (z. B. "nas" -> "nas4free" wäre noch plausibel, aber
* "web" könnte alles Mögliche treffen).
*/
export async function findBestIconMatch(name: string): Promise<string | null> {
const normalized = name
.toLowerCase()
.trim()
.replace(/[^a-z0-9]+/g, "-")
.replace(/^-+|-+$/g, "");
if (normalized.length < 2) return null;
const names = await getIconNames();
const nameSet = new Set(names);
if (nameSet.has(normalized)) return `${CDN_BASE}/${normalized}.png`;
const collapsed = normalized.replace(/-/g, "");
const exactCollapsed = names.find((n) => n.replace(/-/g, "") === collapsed);
if (exactCollapsed) return `${CDN_BASE}/${exactCollapsed}.png`;
return null;
}