summaryrefslogtreecommitdiff
path: root/apps/web/app/reader/_components/entry-list-item.tsx
diff options
context:
space:
mode:
authorFuwn <[email protected]>2026-02-08 00:11:57 -0800
committerFuwn <[email protected]>2026-02-08 00:11:57 -0800
commit6398c56662c9c078db411f382bfac0f3b0803a07 (patch)
treef8e67acbb1ebe6c9bc90d84b13ebeaad3d7c7ae6 /apps/web/app/reader/_components/entry-list-item.tsx
parentfeat: add appearance option to toggle folders above/below ungrouped feeds in ... (diff)
downloadasa.news-6398c56662c9c078db411f382bfac0f3b0803a07.tar.xz
asa.news-6398c56662c9c078db411f382bfac0f3b0803a07.zip
feat: add option to show favicons next to feed names in entry list
Diffstat (limited to 'apps/web/app/reader/_components/entry-list-item.tsx')
-rw-r--r--apps/web/app/reader/_components/entry-list-item.tsx23
1 files changed, 23 insertions, 0 deletions
diff --git a/apps/web/app/reader/_components/entry-list-item.tsx b/apps/web/app/reader/_components/entry-list-item.tsx
index 1669658..7473037 100644
--- a/apps/web/app/reader/_components/entry-list-item.tsx
+++ b/apps/web/app/reader/_components/entry-list-item.tsx
@@ -6,6 +6,15 @@ import { useUserInterfaceStore } from "@/lib/stores/user-interface-store"
import type { TimelineEntry } from "@/lib/types/timeline"
import type { VirtualItem } from "@tanstack/react-virtual"
+function getEntryFaviconUrl(entryUrl: string): string | null {
+ try {
+ const hostname = new URL(entryUrl).hostname
+ return `https://www.google.com/s2/favicons?domain=${hostname}&sz=16`
+ } catch {
+ return null
+ }
+}
+
interface EntryListItemProperties {
entry: TimelineEntry
isSelected: boolean
@@ -35,6 +44,11 @@ export function EntryListItem({
const showEntryImages = useUserInterfaceStore(
(state) => state.showEntryImages
)
+ const showEntryFavicons = useUserInterfaceStore(
+ (state) => state.showEntryFavicons
+ )
+
+ const faviconUrl = showEntryFavicons ? getEntryFaviconUrl(entry.entryUrl) : null
const formattedTimestamp = entry.publishedAt
? timeDisplayFormat === "absolute"
@@ -64,6 +78,9 @@ export function EntryListItem({
>
{viewMode === "compact" && (
<div className="flex items-center gap-2 py-2.5">
+ {faviconUrl && (
+ <img src={faviconUrl} alt="" width={16} height={16} className="shrink-0" loading="lazy" />
+ )}
<span className="shrink-0 text-text-dim">{displayTitle}</span>
{entry.enclosureUrl && (
<span className="shrink-0 text-text-dim" title="podcast episode">&#9835;</span>
@@ -79,6 +96,9 @@ export function EntryListItem({
<div className="py-2.5">
<div className="truncate text-text-primary">{entry.entryTitle}</div>
<div className="mt-0.5 flex items-center gap-2 text-text-dim">
+ {faviconUrl && (
+ <img src={faviconUrl} alt="" width={16} height={16} className="shrink-0" loading="lazy" />
+ )}
<span>{displayTitle}</span>
{entry.enclosureUrl && (
<span title="podcast episode">&#9835;</span>
@@ -107,6 +127,9 @@ export function EntryListItem({
</p>
)}
<div className="mt-1 flex items-center gap-2 text-text-dim">
+ {faviconUrl && (
+ <img src={faviconUrl} alt="" width={16} height={16} className="shrink-0" loading="lazy" />
+ )}
<span>{displayTitle}</span>
{entry.enclosureUrl && (
<span title="podcast episode">&#9835;</span>