Fix feed favicon handling and DRYUnverified
d1ec121 parent: 0438036 modified
internal/tmpl/article_detail.html +1 -1 | @@ -16,7 +16,7 @@ | ||
| 16 | 16 | {{if .Article.Published.Valid}}<span>{{.Article.Published.Time.Format "Jan 2, 2006 15:04"}}</span>{{end}} |
| 17 | 17 | {{if .Feed}} |
| 18 | 18 | <a href="/articles?feed={{.Feed.FeedURL}}" class="inline-flex items-center gap-1 hover:text-spot-green transition"> |
| 19 | - {{if .Feed.FaviconURL.Valid}}<img src="{{.Feed.FaviconURL.String}}" class="w-4 h-4 rounded">{{end}} | |
| 19 | + {{if .Feed}}{{template "favicon" dict "src" .Feed.FaviconURL.String "size" "w-4 h-4"}}{{end}} | |
| 20 | 20 | {{if .Feed.Title.Valid}}{{.Feed.Title.String}}{{else}}{{.Feed.FeedURL}}{{end}} |
| 21 | 21 | </a> |
| 22 | 22 | {{end}} |
| @@ -16,7 +16,7 @@ | |||
| 16 | {{if .Article.Published.Valid}}<span>{{.Article.Published.Time.Format "Jan 2, 2006 15:04"}}</span>{{end}} | 16 | {{if .Article.Published.Valid}}<span>{{.Article.Published.Time.Format "Jan 2, 2006 15:04"}}</span>{{end}} |
| 17 | {{if .Feed}} | 17 | {{if .Feed}} |
| 18 | <a href="/articles?feed={{.Feed.FeedURL}}" class="inline-flex items-center gap-1 hover:text-spot-green transition"> | 18 | <a href="/articles?feed={{.Feed.FeedURL}}" class="inline-flex items-center gap-1 hover:text-spot-green transition"> |
| 19 | - {{if .Feed.FaviconURL.Valid}}<img src="{{.Feed.FaviconURL.String}}" class="w-4 h-4 rounded">{{end}} | 19 | + {{if .Feed}}{{template "favicon" dict "src" .Feed.FaviconURL.String "size" "w-4 h-4"}}{{end}} |
| 20 | {{if .Feed.Title.Valid}}{{.Feed.Title.String}}{{else}}{{.Feed.FeedURL}}{{end}} | 20 | {{if .Feed.Title.Valid}}{{.Feed.Title.String}}{{else}}{{.Feed.FeedURL}}{{end}} |
| 21 | </a> | 21 | </a> |
| 22 | {{end}} | 22 | {{end}} |
modified
internal/tmpl/articles.html +1 -1 | @@ -8,7 +8,7 @@ | ||
| 8 | 8 | </div> |
| 9 | 9 | <div class="flex items-center justify-between"> |
| 10 | 10 | <div class="flex items-center gap-3"> |
| 11 | - {{if .Feed.FaviconURL.Valid}}<img src="{{.Feed.FaviconURL.String}}" class="w-8 h-8 rounded shrink-0" loading="lazy">{{end}} | |
| 11 | + {{template "favicon" dict "src" .Feed.FaviconURL.String "size" "w-8 h-8"}} | |
| 12 | 12 | <div> |
| 13 | 13 | <h1 class="text-2xl font-bold text-spot-text">{{if .Feed.Title.Valid}}{{.Feed.Title.String}}{{else}}{{.Feed.FeedURL}}{{end}}</h1> |
| 14 | 14 | {{if .Feed.SiteURL.Valid}}<a href="{{.Feed.SiteURL.String}}" target="_blank" rel="noopener noreferrer" class="text-xs text-spot-secondary hover:text-spot-green transition">{{.Feed.SiteURL.String}}</a>{{end}} |
| @@ -8,7 +8,7 @@ | |||
| 8 | </div> | 8 | </div> |
| 9 | <div class="flex items-center justify-between"> | 9 | <div class="flex items-center justify-between"> |
| 10 | <div class="flex items-center gap-3"> | 10 | <div class="flex items-center gap-3"> |
| 11 | - {{if .Feed.FaviconURL.Valid}}<img src="{{.Feed.FaviconURL.String}}" class="w-8 h-8 rounded shrink-0" loading="lazy">{{end}} | 11 | + {{template "favicon" dict "src" .Feed.FaviconURL.String "size" "w-8 h-8"}} |
| 12 | <div> | 12 | <div> |
| 13 | <h1 class="text-2xl font-bold text-spot-text">{{if .Feed.Title.Valid}}{{.Feed.Title.String}}{{else}}{{.Feed.FeedURL}}{{end}}</h1> | 13 | <h1 class="text-2xl font-bold text-spot-text">{{if .Feed.Title.Valid}}{{.Feed.Title.String}}{{else}}{{.Feed.FeedURL}}{{end}}</h1> |
| 14 | {{if .Feed.SiteURL.Valid}}<a href="{{.Feed.SiteURL.String}}" target="_blank" rel="noopener noreferrer" class="text-xs text-spot-secondary hover:text-spot-green transition">{{.Feed.SiteURL.String}}</a>{{end}} | 14 | {{if .Feed.SiteURL.Valid}}<a href="{{.Feed.SiteURL.String}}" target="_blank" rel="noopener noreferrer" class="text-xs text-spot-secondary hover:text-spot-green transition">{{.Feed.SiteURL.String}}</a>{{end}} |
modified
internal/tmpl/partials/article-card.html +1 -1 | @@ -7,7 +7,7 @@ | ||
| 7 | 7 | <a href="/articles/{{.ID}}" class="font-bold text-spot-text hover:text-spot-green transition text-lg leading-tight">{{.Title}}</a> |
| 8 | 8 | </div> |
| 9 | 9 | <div class="text-sm text-spot-secondary mt-1 flex items-center gap-2"> |
| 10 | - {{if .FeedFaviconURL.Valid}}<img src="{{.FeedFaviconURL.String}}" class="w-4 h-4 rounded shrink-0" loading="lazy">{{end}} | |
| 10 | + {{template "favicon" dict "src" .FeedFaviconURL.String "size" "w-4 h-4"}} | |
| 11 | 11 | {{if .Author.Valid}}{{if .Author.String}}<span>{{.Author.String}}</span>{{end}}{{end}} |
| 12 | 12 | {{if .Published.Valid}}<span>{{.Published.Time.Format "Jan 2, 2006 15:04"}}</span>{{end}} |
| 13 | 13 | <span class="text-spot-muted"><a href="/articles?feed={{.FeedURL}}" class="hover:text-spot-green transition">{{if .FeedTitle}}{{.FeedTitle}}{{else}}{{.FeedURL}}{{end}}</a></span> |
| @@ -7,7 +7,7 @@ | |||
| 7 | <a href="/articles/{{.ID}}" class="font-bold text-spot-text hover:text-spot-green transition text-lg leading-tight">{{.Title}}</a> | 7 | <a href="/articles/{{.ID}}" class="font-bold text-spot-text hover:text-spot-green transition text-lg leading-tight">{{.Title}}</a> |
| 8 | </div> | 8 | </div> |
| 9 | <div class="text-sm text-spot-secondary mt-1 flex items-center gap-2"> | 9 | <div class="text-sm text-spot-secondary mt-1 flex items-center gap-2"> |
| 10 | - {{if .FeedFaviconURL.Valid}}<img src="{{.FeedFaviconURL.String}}" class="w-4 h-4 rounded shrink-0" loading="lazy">{{end}} | 10 | + {{template "favicon" dict "src" .FeedFaviconURL.String "size" "w-4 h-4"}} |
| 11 | {{if .Author.Valid}}{{if .Author.String}}<span>{{.Author.String}}</span>{{end}}{{end}} | 11 | {{if .Author.Valid}}{{if .Author.String}}<span>{{.Author.String}}</span>{{end}}{{end}} |
| 12 | {{if .Published.Valid}}<span>{{.Published.Time.Format "Jan 2, 2006 15:04"}}</span>{{end}} | 12 | {{if .Published.Valid}}<span>{{.Published.Time.Format "Jan 2, 2006 15:04"}}</span>{{end}} |
| 13 | <span class="text-spot-muted"><a href="/articles?feed={{.FeedURL}}" class="hover:text-spot-green transition">{{if .FeedTitle}}{{.FeedTitle}}{{else}}{{.FeedURL}}{{end}}</a></span> | 13 | <span class="text-spot-muted"><a href="/articles?feed={{.FeedURL}}" class="hover:text-spot-green transition">{{if .FeedTitle}}{{.FeedTitle}}{{else}}{{.FeedURL}}{{end}}</a></span> |
added
internal/tmpl/partials/favicon.html +8 -0 | new file mode 100644 | ||
| @@ -0,0 +1,8 @@ | ||
| 1 | +{{define "favicon"}} | |
| 2 | +{{if .src}} | |
| 3 | +<img src="{{.src}}" class="{{.size}} rounded shrink-0" loading="lazy" onerror="this.classList.add('hidden');this.nextElementSibling.classList.remove('hidden')"> | |
| 4 | +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" class="{{.size}} shrink-0 hidden"><circle cx="12" cy="12" r="10"/><path d="M2 12h20M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg> | |
| 5 | +{{else}} | |
| 6 | +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" class="{{.size}} shrink-0"><circle cx="12" cy="12" r="10"/><path d="M2 12h20M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg> | |
| 7 | +{{end}} | |
| 8 | +{{end}} | |
| \ No newline at end of file | ||
| new file mode 100644 | |||
| @@ -0,0 +1,8 @@ | |||
| 1 | +{{define "favicon"}} | ||
| 2 | +{{if .src}} | ||
| 3 | +<img src="{{.src}}" class="{{.size}} rounded shrink-0" loading="lazy" onerror="this.classList.add('hidden');this.nextElementSibling.classList.remove('hidden')"> | ||
| 4 | +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" class="{{.size}} shrink-0 hidden"><circle cx="12" cy="12" r="10"/><path d="M2 12h20M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg> | ||
| 5 | +{{else}} | ||
| 6 | +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" class="{{.size}} shrink-0"><circle cx="12" cy="12" r="10"/><path d="M2 12h20M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg> | ||
| 7 | +{{end}} | ||
| 8 | +{{end}} | ||
| \ No newline at end of file | \ No newline at end of file | ||
modified
internal/tmpl/partials/feed-item.html +1 -1 | @@ -1,7 +1,7 @@ | ||
| 1 | 1 | {{define "feed-item.html"}} |
| 2 | 2 | <div class="feed-item px-5 py-4 flex items-center justify-between gap-3 hover:bg-spot-hover-50 transition rounded-xl"> |
| 3 | 3 | <a href="/articles?feed={{.FeedURL}}" class="min-w-0 flex-1 flex items-center gap-3"> |
| 4 | - {{if .FaviconURL.Valid}}<img src="{{.FaviconURL.String}}" class="w-5 h-5 rounded shrink-0" loading="lazy">{{else}}<span class="shrink-0 w-5 h-5 flex items-center justify-center text-spot-muted"><svg class="w-5 h-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">{{template "icon-globe"}}</svg></span>{{end}} | |
| 4 | + {{template "favicon" dict "src" .FaviconURL.String "size" "w-5 h-5"}} | |
| 5 | 5 | <div class="min-w-0 flex-1"> |
| 6 | 6 | <div class="flex items-center gap-2 flex-wrap"> |
| 7 | 7 | <span class="font-bold text-spot-text truncate">{{if .FeedTitle}}{{.FeedTitle}}{{else}}{{.FeedURL}}{{end}}</span> |
| @@ -1,7 +1,7 @@ | |||
| 1 | {{define "feed-item.html"}} | 1 | {{define "feed-item.html"}} |
| 2 | <div class="feed-item px-5 py-4 flex items-center justify-between gap-3 hover:bg-spot-hover-50 transition rounded-xl"> | 2 | <div class="feed-item px-5 py-4 flex items-center justify-between gap-3 hover:bg-spot-hover-50 transition rounded-xl"> |
| 3 | <a href="/articles?feed={{.FeedURL}}" class="min-w-0 flex-1 flex items-center gap-3"> | 3 | <a href="/articles?feed={{.FeedURL}}" class="min-w-0 flex-1 flex items-center gap-3"> |
| 4 | - {{if .FaviconURL.Valid}}<img src="{{.FaviconURL.String}}" class="w-5 h-5 rounded shrink-0" loading="lazy">{{else}}<span class="shrink-0 w-5 h-5 flex items-center justify-center text-spot-muted"><svg class="w-5 h-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">{{template "icon-globe"}}</svg></span>{{end}} | 4 | + {{template "favicon" dict "src" .FaviconURL.String "size" "w-5 h-5"}} |
| 5 | <div class="min-w-0 flex-1"> | 5 | <div class="min-w-0 flex-1"> |
| 6 | <div class="flex items-center gap-2 flex-wrap"> | 6 | <div class="flex items-center gap-2 flex-wrap"> |
| 7 | <span class="font-bold text-spot-text truncate">{{if .FeedTitle}}{{.FeedTitle}}{{else}}{{.FeedURL}}{{end}}</span> | 7 | <span class="font-bold text-spot-text truncate">{{if .FeedTitle}}{{.FeedTitle}}{{else}}{{.FeedURL}}{{end}}</span> |
modified
internal/tmpl/partials/recommendation-card.html +1 -1 | @@ -2,7 +2,7 @@ | ||
| 2 | 2 | <div class="recommendation-card bg-spot-surface rounded-xl p-3 hover:bg-spot-hover-50 transition"> |
| 3 | 3 | <div class="flex items-center justify-between gap-2"> |
| 4 | 4 | <a href="/articles?feed={{.feed_url}}" class="min-w-0 flex items-center gap-2 flex-1"> |
| 5 | - {{if .favicon_url}}<img src="{{.favicon_url}}" class="w-4 h-4 rounded shrink-0" loading="lazy">{{end}} | |
| 5 | + {{template "favicon" dict "src" .favicon_url "size" "w-4 h-4"}} | |
| 6 | 6 | <div class="min-w-0"> |
| 7 | 7 | <div class="font-bold text-sm text-spot-text truncate">{{if .title}}{{.title}}{{else}}{{.feed_url}}{{end}}</div> |
| 8 | 8 | {{if .description}}<p class="text-xs text-spot-secondary truncate mt-0.5">{{.description}}</p>{{end}} |
| @@ -2,7 +2,7 @@ | |||
| 2 | <div class="recommendation-card bg-spot-surface rounded-xl p-3 hover:bg-spot-hover-50 transition"> | 2 | <div class="recommendation-card bg-spot-surface rounded-xl p-3 hover:bg-spot-hover-50 transition"> |
| 3 | <div class="flex items-center justify-between gap-2"> | 3 | <div class="flex items-center justify-between gap-2"> |
| 4 | <a href="/articles?feed={{.feed_url}}" class="min-w-0 flex items-center gap-2 flex-1"> | 4 | <a href="/articles?feed={{.feed_url}}" class="min-w-0 flex items-center gap-2 flex-1"> |
| 5 | - {{if .favicon_url}}<img src="{{.favicon_url}}" class="w-4 h-4 rounded shrink-0" loading="lazy">{{end}} | 5 | + {{template "favicon" dict "src" .favicon_url "size" "w-4 h-4"}} |
| 6 | <div class="min-w-0"> | 6 | <div class="min-w-0"> |
| 7 | <div class="font-bold text-sm text-spot-text truncate">{{if .title}}{{.title}}{{else}}{{.feed_url}}{{end}}</div> | 7 | <div class="font-bold text-sm text-spot-text truncate">{{if .title}}{{.title}}{{else}}{{.feed_url}}{{end}}</div> |
| 8 | {{if .description}}<p class="text-xs text-spot-secondary truncate mt-0.5">{{.description}}</p>{{end}} | 8 | {{if .description}}<p class="text-xs text-spot-secondary truncate mt-0.5">{{.description}}</p>{{end}} |
modified
internal/tmpl/profile.html +1 -1 | @@ -26,7 +26,7 @@ | ||
| 26 | 26 | <div class="bg-spot-surface rounded-xl divide-y divide-spot-divider mb-6"> |
| 27 | 27 | {{range .Subscriptions}} |
| 28 | 28 | <a href="/articles?feed={{.FeedURL}}" class="flex items-center gap-3 px-5 py-3 hover:bg-spot-hover-50 transition first:rounded-t-xl last:rounded-b-xl"> |
| 29 | - {{if .FaviconURL.Valid}}<img src="{{.FaviconURL.String}}" class="w-5 h-5 rounded shrink-0" loading="lazy">{{else}}<span class="shrink-0 w-5 h-5 flex items-center justify-center text-spot-muted"><svg class="w-5 h-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">{{template "icon-globe"}}</svg></span>{{end}} | |
| 29 | + {{template "favicon" dict "src" .FaviconURL.String "size" "w-5 h-5"}} | |
| 30 | 30 | <div class="min-w-0 flex-1"> |
| 31 | 31 | <div class="flex items-center gap-2 flex-wrap"> |
| 32 | 32 | <span class="font-bold text-spot-text truncate">{{if .FeedTitle}}{{.FeedTitle}}{{else}}{{.FeedURL}}{{end}}</span> |
| @@ -26,7 +26,7 @@ | |||
| 26 | <div class="bg-spot-surface rounded-xl divide-y divide-spot-divider mb-6"> | 26 | <div class="bg-spot-surface rounded-xl divide-y divide-spot-divider mb-6"> |
| 27 | {{range .Subscriptions}} | 27 | {{range .Subscriptions}} |
| 28 | <a href="/articles?feed={{.FeedURL}}" class="flex items-center gap-3 px-5 py-3 hover:bg-spot-hover-50 transition first:rounded-t-xl last:rounded-b-xl"> | 28 | <a href="/articles?feed={{.FeedURL}}" class="flex items-center gap-3 px-5 py-3 hover:bg-spot-hover-50 transition first:rounded-t-xl last:rounded-b-xl"> |
| 29 | - {{if .FaviconURL.Valid}}<img src="{{.FaviconURL.String}}" class="w-5 h-5 rounded shrink-0" loading="lazy">{{else}}<span class="shrink-0 w-5 h-5 flex items-center justify-center text-spot-muted"><svg class="w-5 h-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">{{template "icon-globe"}}</svg></span>{{end}} | 29 | + {{template "favicon" dict "src" .FaviconURL.String "size" "w-5 h-5"}} |
| 30 | <div class="min-w-0 flex-1"> | 30 | <div class="min-w-0 flex-1"> |
| 31 | <div class="flex items-center gap-2 flex-wrap"> | 31 | <div class="flex items-center gap-2 flex-wrap"> |
| 32 | <span class="font-bold text-spot-text truncate">{{if .FeedTitle}}{{.FeedTitle}}{{else}}{{.FeedURL}}{{end}}</span> | 32 | <span class="font-bold text-spot-text truncate">{{if .FeedTitle}}{{.FeedTitle}}{{else}}{{.FeedURL}}{{end}}</span> |