summaryrefslogtreecommitdiff
path: root/apps
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
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')
-rw-r--r--apps/web/app/reader/_components/entry-list-item.tsx23
-rw-r--r--apps/web/app/reader/settings/_components/appearance-settings.tsx21
-rw-r--r--apps/web/lib/stores/user-interface-store.ts6
3 files changed, 50 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>
diff --git a/apps/web/app/reader/settings/_components/appearance-settings.tsx b/apps/web/app/reader/settings/_components/appearance-settings.tsx
index aaf499a..458d2b6 100644
--- a/apps/web/app/reader/settings/_components/appearance-settings.tsx
+++ b/apps/web/app/reader/settings/_components/appearance-settings.tsx
@@ -49,6 +49,12 @@ export function AppearanceSettings() {
const setShowReadingTime = useUserInterfaceStore(
(state) => state.setShowReadingTime
)
+ const showEntryFavicons = useUserInterfaceStore(
+ (state) => state.showEntryFavicons
+ )
+ const setShowEntryFavicons = useUserInterfaceStore(
+ (state) => state.setShowEntryFavicons
+ )
const showFoldersAboveFeeds = useUserInterfaceStore(
(state) => state.showFoldersAboveFeeds
)
@@ -126,6 +132,21 @@ export function AppearanceSettings() {
</label>
</div>
<div className="mb-6">
+ <h3 className="mb-2 text-text-primary">entry favicons</h3>
+ <p className="mb-3 text-text-dim">
+ show website icons next to feed names in the entry list
+ </p>
+ <label className="flex cursor-pointer items-center gap-2 text-text-primary">
+ <input
+ type="checkbox"
+ checked={showEntryFavicons}
+ onChange={(event) => setShowEntryFavicons(event.target.checked)}
+ className="accent-text-primary"
+ />
+ <span>show entry favicons</span>
+ </label>
+ </div>
+ <div className="mb-6">
<h3 className="mb-2 text-text-primary">focus follows interaction</h3>
<p className="mb-3 text-text-dim">
automatically move keyboard panel focus to the last pane you
diff --git a/apps/web/lib/stores/user-interface-store.ts b/apps/web/lib/stores/user-interface-store.ts
index f25152c..3d3b0b6 100644
--- a/apps/web/lib/stores/user-interface-store.ts
+++ b/apps/web/lib/stores/user-interface-store.ts
@@ -42,6 +42,7 @@ interface UserInterfaceState {
showEntryImages: boolean
showReadingTime: boolean
showFoldersAboveFeeds: boolean
+ showEntryFavicons: boolean
isShortcutsDialogOpen: boolean
expandedFolderIdentifiers: string[]
navigableEntryIdentifiers: string[]
@@ -67,6 +68,7 @@ interface UserInterfaceState {
setShowEntryImages: (show: boolean) => void
setShowReadingTime: (show: boolean) => void
setShowFoldersAboveFeeds: (show: boolean) => void
+ setShowEntryFavicons: (show: boolean) => void
setShortcutsDialogOpen: (isOpen: boolean) => void
toggleShortcutsDialog: () => void
toggleFolderExpansion: (folderIdentifier: string) => void
@@ -96,6 +98,7 @@ export const useUserInterfaceStore = create<UserInterfaceState>()(
showEntryImages: true,
showReadingTime: true,
showFoldersAboveFeeds: false,
+ showEntryFavicons: false,
isShortcutsDialogOpen: false,
expandedFolderIdentifiers: [],
navigableEntryIdentifiers: [],
@@ -145,6 +148,8 @@ export const useUserInterfaceStore = create<UserInterfaceState>()(
setShowFoldersAboveFeeds: (show) => set({ showFoldersAboveFeeds: show }),
+ setShowEntryFavicons: (show) => set({ showEntryFavicons: show }),
+
setShortcutsDialogOpen: (isOpen) =>
set({ isShortcutsDialogOpen: isOpen }),
@@ -196,6 +201,7 @@ export const useUserInterfaceStore = create<UserInterfaceState>()(
showEntryImages: state.showEntryImages,
showReadingTime: state.showReadingTime,
showFoldersAboveFeeds: state.showFoldersAboveFeeds,
+ showEntryFavicons: state.showEntryFavicons,
}),
}
)