From 6fec81deb9a4870658a2dbebfd7968a3aa1cdc47 Mon Sep 17 00:00:00 2001 From: yusing Date: Mon, 15 Dec 2025 12:28:03 +0800 Subject: [PATCH] feat(favicon): add variant support for favicons - Introduced a new Variant field in GetFavIconRequest to specify icon variants (light/dark). - Updated GetFavIconFromAlias function to handle the variant when fetching favicons. - Added WithVariant method in IconURL to manage icon variants effectively. --- internal/api/v1/favicon.go | 12 +++++++----- internal/homepage/icon_url.go | 31 ++++++++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/internal/api/v1/favicon.go b/internal/api/v1/favicon.go index 78be1666..aa4a284b 100644 --- a/internal/api/v1/favicon.go +++ b/internal/api/v1/favicon.go @@ -13,8 +13,9 @@ import ( ) type GetFavIconRequest struct { - URL string `form:"url" binding:"required_without=Alias"` - Alias string `form:"alias" binding:"required_without=URL"` + URL string `form:"url" binding:"required_without=Alias"` + Alias string `form:"alias" binding:"required_without=URL"` + Variant homepage.IconVariant `form:"variant" binding:"omitempty,oneof=light dark"` } // @name GetFavIconRequest // @x-id "favicon" @@ -56,7 +57,7 @@ func FavIcon(c *gin.Context) { } // try with alias - result, err := GetFavIconFromAlias(c.Request.Context(), request.Alias) + result, err := GetFavIconFromAlias(c.Request.Context(), request.Alias, request.Variant) if err != nil { homepage.GinFetchError(c, result.StatusCode, err) return @@ -65,7 +66,7 @@ func FavIcon(c *gin.Context) { } //go:linkname GetFavIconFromAlias v1.GetFavIconFromAlias -func GetFavIconFromAlias(ctx context.Context, alias string) (homepage.FetchResult, error) { +func GetFavIconFromAlias(ctx context.Context, alias string, variant homepage.IconVariant) (homepage.FetchResult, error) { // try with route.Icon r, ok := routes.HTTP.Get(alias) if !ok { @@ -81,7 +82,8 @@ func GetFavIconFromAlias(ctx context.Context, alias string) (homepage.FetchResul if hp.Icon.IconSource == homepage.IconSourceRelative { result, err = homepage.FindIcon(ctx, r, *hp.Icon.FullURL) } else { - result, err = homepage.FetchFavIconFromURL(ctx, hp.Icon) + icon := hp.Icon.WithVariant(variant) + result, err = homepage.FetchFavIconFromURL(ctx, icon) } } else { // try extract from "link[rel=icon]" diff --git a/internal/homepage/icon_url.go b/internal/homepage/icon_url.go index b07463df..04f273aa 100644 --- a/internal/homepage/icon_url.go +++ b/internal/homepage/icon_url.go @@ -23,7 +23,8 @@ type ( IsDark bool `json:"is_dark"` } - IconSource string + IconSource string + IconVariant string ) const ( @@ -33,6 +34,12 @@ const ( IconSourceSelfhSt IconSource = "@selfhst" ) +const ( + IconVariantNone IconVariant = "" + IconVariantLight IconVariant = "light" + IconVariantDark IconVariant = "dark" +) + var ErrInvalidIconURL = gperr.New("invalid icon url") func NewIconURL(source IconSource, refOrName, format string) *IconURL { @@ -76,6 +83,28 @@ func (u *IconURL) HasIcon() bool { return HasIcon(u) } +func (u *IconURL) WithVariant(variant IconVariant) *IconURL { + var extra *IconExtra + if u.Extra != nil { + extra = &IconExtra{ + Key: u.Extra.Key, + Ref: u.Extra.Ref, + FileType: u.Extra.FileType, + } + switch variant { + case IconVariantLight: + extra.IsLight = true + case IconVariantDark: + extra.IsDark = true + } + } + return &IconURL{ + IconSource: u.IconSource, + FullURL: u.FullURL, + Extra: extra, + } +} + // Parse implements strutils.Parser. func (u *IconURL) Parse(v string) error { return u.parse(v, true)