fix(cache): fetch favicon from DuckDuckGo when not cached on disk
- commit
- 3a5873005f370911b1da55413c5c2107801f9fe7
- author
- bnema · · 2025-12-18 19:34 UTC
- committer
- bnema · · 2025-12-18 19:36 UTC
- parent
- c46672e
- signature
- unsigned
1 file · +29 -0
M internal/ui/cache/favicon_cache.go +29 -0
| @@ -79,6 +79,7 @@ func NewFaviconCache(faviconDB *webkit.FaviconDatabase) *FaviconCache { | |||
| 79 | 79 | } | |
| 80 | 80 | ||
| 81 | 81 | // Set stores a favicon texture for the given domain. | |
| 82 | + | // Also queues a disk write if the favicon is not already cached on disk. | |
| 82 | 83 | func (fc *FaviconCache) Set(domain string, texture *gdk.Texture) { | |
| 83 | 84 | if domain == "" || texture == nil { | |
| 84 | 85 | return | |
| @@ -86,6 +87,34 @@ func (fc *FaviconCache) Set(domain string, texture *gdk.Texture) { | |||
| 86 | 87 | fc.mu.Lock() | |
| 87 | 88 | fc.cache[domain] = texture | |
| 88 | 89 | fc.mu.Unlock() | |
| 90 | + | ||
| 91 | + | // Also save to disk if not already cached | |
| 92 | + | fc.ensureDiskCache(domain) | |
| 93 | + | } | |
| 94 | + | ||
| 95 | + | // ensureDiskCache fetches favicon from DuckDuckGo and saves to disk if not already cached. | |
| 96 | + | func (fc *FaviconCache) ensureDiskCache(domain string) { | |
| 97 | + | if fc.diskCacheDir == "" || domain == "" { | |
| 98 | + | return | |
| 99 | + | } | |
| 100 | + | ||
| 101 | + | // Check if already on disk | |
| 102 | + | filename := domainurl.SanitizeDomainForFilename(domain) | |
| 103 | + | path := filepath.Join(fc.diskCacheDir, filename) | |
| 104 | + | if _, err := os.Stat(path); err == nil { | |
| 105 | + | return // Already cached | |
| 106 | + | } | |
| 107 | + | ||
| 108 | + | // Fetch from DuckDuckGo in background and save to disk | |
| 109 | + | go func() { | |
| 110 | + | ctx, cancel := context.WithTimeout(context.Background(), faviconFetchTimeout) | |
| 111 | + | defer cancel() | |
| 112 | + | ||
| 113 | + | _, rawData := fc.fetchFromExternal(ctx, domain) | |
| 114 | + | if len(rawData) > 0 { | |
| 115 | + | fc.queueDiskWrite(domain, rawData) | |
| 116 | + | } | |
| 117 | + | }() | |
| 89 | 118 | } | |
| 90 | 119 | ||
| 91 | 120 | // SetByURL stores a favicon texture for the domain extracted from the URL. | |
| @@ -79,6 +79,7 @@ func NewFaviconCache(faviconDB *webkit.FaviconDatabase) *FaviconCache { | |||||
| 79 | } | 79 | } | ||
| 80 | 80 | ||||
| 81 | // Set stores a favicon texture for the given domain. | 81 | // Set stores a favicon texture for the given domain. | ||
| 82 | + | // Also queues a disk write if the favicon is not already cached on disk. | |||
| 82 | func (fc *FaviconCache) Set(domain string, texture *gdk.Texture) { | 83 | func (fc *FaviconCache) Set(domain string, texture *gdk.Texture) { | ||
| 83 | if domain == "" || texture == nil { | 84 | if domain == "" || texture == nil { | ||
| 84 | return | 85 | return | ||
| @@ -86,6 +87,34 @@ func (fc *FaviconCache) Set(domain string, texture *gdk.Texture) { | |||||
| 86 | fc.mu.Lock() | 87 | fc.mu.Lock() | ||
| 87 | fc.cache[domain] = texture | 88 | fc.cache[domain] = texture | ||
| 88 | fc.mu.Unlock() | 89 | fc.mu.Unlock() | ||
| 90 | + | ||||
| 91 | + | // Also save to disk if not already cached | |||
| 92 | + | fc.ensureDiskCache(domain) | |||
| 93 | + | } | |||
| 94 | + | ||||
| 95 | + | // ensureDiskCache fetches favicon from DuckDuckGo and saves to disk if not already cached. | |||
| 96 | + | func (fc *FaviconCache) ensureDiskCache(domain string) { | |||
| 97 | + | if fc.diskCacheDir == "" || domain == "" { | |||
| 98 | + | return | |||
| 99 | + | } | |||
| 100 | + | ||||
| 101 | + | // Check if already on disk | |||
| 102 | + | filename := domainurl.SanitizeDomainForFilename(domain) | |||
| 103 | + | path := filepath.Join(fc.diskCacheDir, filename) | |||
| 104 | + | if _, err := os.Stat(path); err == nil { | |||
| 105 | + | return // Already cached | |||
| 106 | + | } | |||
| 107 | + | ||||
| 108 | + | // Fetch from DuckDuckGo in background and save to disk | |||
| 109 | + | go func() { | |||
| 110 | + | ctx, cancel := context.WithTimeout(context.Background(), faviconFetchTimeout) | |||
| 111 | + | defer cancel() | |||
| 112 | + | ||||
| 113 | + | _, rawData := fc.fetchFromExternal(ctx, domain) | |||
| 114 | + | if len(rawData) > 0 { | |||
| 115 | + | fc.queueDiskWrite(domain, rawData) | |||
| 116 | + | } | |||
| 117 | + | }() | |||
| 89 | } | 118 | } | ||
| 90 | 119 | ||||
| 91 | // SetByURL stores a favicon texture for the domain extracted from the URL. | 120 | // SetByURL stores a favicon texture for the domain extracted from the URL. | ||