From c7b5a2af1965599f856ff3879ff710f2bca72f11 Mon Sep 17 00:00:00 2001 From: logikonline Date: Mon, 16 Mar 2026 01:12:04 -0400 Subject: [PATCH] feat(socialcard): use display names and custom branding on social cards Replace GitCaddy logo with custom brand name (from Owner Display Name setting) when set. Use user/org display names instead of usernames in repo full name. Use DisplayTitle instead of repo name when available. Adds drawBrandOrLogo helper to render either custom text or default logo. Improves branding consistency with pages landing page settings. --- modules/socialcard/socialcard.go | 41 ++++++++++++++++++-------------- routers/web/repo/socialcard.go | 13 +++++++--- 2 files changed, 33 insertions(+), 21 deletions(-) diff --git a/modules/socialcard/socialcard.go b/modules/socialcard/socialcard.go index feac7819ec..0f19c10558 100644 --- a/modules/socialcard/socialcard.go +++ b/modules/socialcard/socialcard.go @@ -132,6 +132,7 @@ type CardData struct { LanguageColor string // hex color like "#3572A5" RepoAvatarURL string RepoFullName string + BrandName string // replaces the GitCaddy logo when set (from repo Owner Display Name setting) SolidColor string // hex color for "solid" style BgImage image.Image // pre-loaded background image for "image" style UnsplashAuthor string // attribution text for Unsplash images @@ -264,12 +265,8 @@ func (r *Renderer) renderPresetCard(data CardData, theme Theme) ([]byte, error) } drawText(img, xCursor, metaY, data.RepoFullName, faces.meta, theme.SubtextColor) - // GitCaddy logo (bottom right) - logoBounds := r.logo.Bounds() - logoX := CardWidth - rightPad - logoBounds.Dx() - logoY := CardHeight - 40 - logoBounds.Dy() - draw.Draw(img, image.Rect(logoX, logoY, logoX+logoBounds.Dx(), logoY+logoBounds.Dy()), - r.logo, logoBounds.Min, draw.Over) + // Brand name or GitCaddy logo (bottom right) + r.drawBrandOrLogo(img, data.BrandName, faces.meta, theme.SubtextColor, CardWidth-rightPad, CardHeight-40) return encodePNG(img) } @@ -353,12 +350,8 @@ func (r *Renderer) renderSolidCard(data CardData) ([]byte, error) { repoW := measureText(data.RepoFullName, faces.meta) drawText(img, (w-repoW)/2, metaY, data.RepoFullName, faces.meta, theme.SubtextColor) - // GitCaddy logo (bottom right) - logoBounds := r.logo.Bounds() - logoX := w - pad - logoBounds.Dx() - logoY := h - 40 - logoBounds.Dy() - draw.Draw(img, image.Rect(logoX, logoY, logoX+logoBounds.Dx(), logoY+logoBounds.Dy()), - r.logo, logoBounds.Min, draw.Over) + // Brand name or GitCaddy logo (bottom right) + r.drawBrandOrLogo(img, data.BrandName, faces.meta, theme.SubtextColor, w-pad, h-40) // Unsplash attribution (lower-left of image area) if data.UnsplashAuthor != "" { @@ -458,16 +451,28 @@ func (r *Renderer) renderImageCard(data CardData) ([]byte, error) { yBottom -= 60 } - // GitCaddy logo (bottom right) - logoBounds := r.logo.Bounds() - logoX := w - pad - logoBounds.Dx() - logoY := h - pad + 10 - logoBounds.Dy() - draw.Draw(img, image.Rect(logoX, logoY, logoX+logoBounds.Dx(), logoY+logoBounds.Dy()), - r.logo, logoBounds.Min, draw.Over) + // Brand name or GitCaddy logo (bottom right) + subtextC := color.RGBA{R: 170, G: 170, B: 170, A: 255} + r.drawBrandOrLogo(img, data.BrandName, faces.meta, subtextC, w-pad, h-pad+10) return encodePNG(img) } +// drawBrandOrLogo draws either the custom brand name text or the default GitCaddy logo +// at the bottom-right of the card. rightX is the right edge, baselineY is the text baseline. +func (r *Renderer) drawBrandOrLogo(img *image.RGBA, brandName string, face font.Face, textColor color.RGBA, rightX, baselineY int) { + if brandName != "" { + textW := measureText(brandName, face) + drawText(img, rightX-textW, baselineY, brandName, face, textColor) + } else { + logoBounds := r.logo.Bounds() + logoX := rightX - logoBounds.Dx() + logoY := baselineY - logoBounds.Dy() + draw.Draw(img, image.Rect(logoX, logoY, logoX+logoBounds.Dx(), logoY+logoBounds.Dy()), + r.logo, logoBounds.Min, draw.Over) + } +} + // fontFaces holds pre-created font faces for a single render. type fontFaces struct { title font.Face diff --git a/routers/web/repo/socialcard.go b/routers/web/repo/socialcard.go index d471b22ad3..89d7bc3d85 100644 --- a/routers/web/repo/socialcard.go +++ b/routers/web/repo/socialcard.go @@ -31,16 +31,23 @@ func SocialPreview(ctx *context.Context) { title = repo.Name } - repoFullName := repo.FullName() - if repo.OwnerDisplayName != "" { - repoFullName = repo.OwnerDisplayName + "/" + repo.Name + // Use display names for the repo full name shown on the card + ownerName := repo.OwnerName + if repo.Owner != nil { + ownerName = repo.Owner.DisplayName() } + repoName := repo.Name + if repo.DisplayTitle != "" { + repoName = repo.DisplayTitle + } + repoFullName := ownerName + " / " + repoName data := socialcard.CardData{ Title: title, Description: repo.Description, RepoAvatarURL: repo.AvatarLink(ctx), RepoFullName: repoFullName, + BrandName: repo.OwnerDisplayName, // replaces the GitCaddy logo when set SolidColor: repo.SocialCardColor, UnsplashAuthor: repo.SocialCardUnsplashAuthor, }