feat(favicon): per-feed icon from the last sender's domain

Resolve each feed's most recent sender domain and serve its favicon at
GET /favicon/:feedId, falling back to the project icon. Icons are fetched
in the background on ingestion (direct /favicon.ico then a DuckDuckGo
fallback), cached base64 in KV keyed by domain with a 1-week TTL so the
fetch only fires when absent. Exposed via RSS <image> / Atom <icon>/<logo>
and rendered in the admin feed list, plus a landing-page feature card.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Julien Herr
2026-05-23 14:05:14 +02:00
parent d299c8891d
commit eb12f21894
19 changed files with 592 additions and 30 deletions
+20
View File
@@ -24,6 +24,26 @@
color: var(--color-text-primary);
}
/* Per-feed favicon (list + table views) */
.feed-icon {
width: 20px;
height: 20px;
border-radius: 4px;
object-fit: contain;
vertical-align: middle;
flex-shrink: 0;
}
.feed-title .feed-icon {
margin-right: var(--spacing-xs);
}
.feed-title-cell {
display: flex;
align-items: flex-start;
gap: var(--spacing-sm);
}
.feed-description {
font-size: var(--font-size-md);
color: var(--color-text-secondary);