From d3aa4508e7e092df9d37004ad10e2f91e4ff4d3b Mon Sep 17 00:00:00 2001 From: logikonline Date: Sat, 31 Jan 2026 00:39:46 -0500 Subject: [PATCH] feat(socialcard): add unsplash integration and improve image cards Add Unsplash API integration documentation to README with setup instructions. Adjust image card gradient scrim to cover bottom 50% with increased opacity (240) for better text readability. Set correct OpenGraph image dimensions (1080x1350) for portrait card formats. Improve Unsplash selection UX with status messages and page reload after successful image download. --- README.md | 20 ++++++++++++++++++++ modules/socialcard/socialcard.go | 6 +++--- templates/base/head_opengraph.tmpl | 5 +++++ templates/repo/settings/media_kit.tmpl | 22 +++++++++++++--------- 4 files changed, 41 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 884e80a02b..72144cdeff 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,7 @@ The AI-native Git platform. Self-hosted, fast, and designed for the age of AI-as - [AI Features Configuration](#ai-features-configuration) - [Authentication Sources](#authentication-sources) - [Email/SMTP Setup](#emailsmtp-setup) + - [Unsplash Integration](#unsplash-integration) - [Usage](#usage) - [Repository Operations](#repository-operations) - [Project Management](#project-management) @@ -549,6 +550,25 @@ USER = your-email@gmail.com PASSWD = your-app-password ``` +### Unsplash Integration + +Enable Unsplash image search for repository social card backgrounds (Media Kit). This allows repository admins to search and select high-quality background images directly from Unsplash. + +```ini +[unsplash] +; Enable Unsplash integration for Media Kit background images +ENABLED = true +; Unsplash API access key (get one at https://unsplash.com/developers) +ACCESS_KEY = your_unsplash_access_key +``` + +To obtain an access key: +1. Create an account at [unsplash.com/developers](https://unsplash.com/developers) +2. Create a new application +3. Copy the **Access Key** (the Secret Key is not needed) + +When enabled, repository admins can search Unsplash from **Settings > Media Kit** when using the "Background Image" social card style. Attribution is handled automatically per Unsplash API guidelines. + ## Usage ### Repository Operations diff --git a/modules/socialcard/socialcard.go b/modules/socialcard/socialcard.go index e7b0e3ae98..db981a8c34 100644 --- a/modules/socialcard/socialcard.go +++ b/modules/socialcard/socialcard.go @@ -378,9 +378,9 @@ func (r *Renderer) renderImageCard(data CardData) ([]byte, error) { fillRect(img, img.Bounds(), ThemeDark.Background) } - // Strong gradient scrim over bottom 45% - scrimStartY := h * 55 / 100 - drawGradientScrim(img, scrimStartY, h, 220) + // Strong gradient scrim over bottom 50% + scrimStartY := h * 50 / 100 + drawGradientScrim(img, scrimStartY, h, 240) // White text on scrim titleColor := color.RGBA{R: 255, G: 255, B: 255, A: 255} diff --git a/templates/base/head_opengraph.tmpl b/templates/base/head_opengraph.tmpl index 89f446424b..08f177e99a 100644 --- a/templates/base/head_opengraph.tmpl +++ b/templates/base/head_opengraph.tmpl @@ -33,8 +33,13 @@ {{end}} + {{if or (eq .Repository.SocialCardTheme "solid") (eq .Repository.SocialCardTheme "image")}} + + + {{else}} + {{end}} diff --git a/templates/repo/settings/media_kit.tmpl b/templates/repo/settings/media_kit.tmpl index a6838ff263..48b1d7667d 100644 --- a/templates/repo/settings/media_kit.tmpl +++ b/templates/repo/settings/media_kit.tmpl @@ -200,6 +200,11 @@ el.style.borderColor = 'var(--color-primary)'; el.style.opacity = '0.7'; el.style.pointerEvents = 'none'; + // Show a status message + const statusEl = document.createElement('div'); + statusEl.textContent = 'Downloading image…'; + statusEl.style.cssText = 'padding:8px;color:var(--color-text);font-size:13px;'; + resultsDiv.parentNode.insertBefore(statusEl, resultsDiv.nextSibling); try { const csrf = document.querySelector('input[name="_csrf"]').value; const fd = new FormData(); @@ -209,16 +214,15 @@ fd.append('url', photo.regular); const resp = await fetch('{{.Link}}/unsplash/select', {method: 'POST', body: fd}); if (resp.ok) { - // Switch radio to "image" and update UI - const imageRadio = document.querySelector('.style-radio[value="image"]'); - if (imageRadio) { - imageRadio.checked = true; - updateButtonStyles(); - solidOpts.style.display = 'none'; - imageOpts.style.display = ''; - } - updatePreview(); + statusEl.textContent = 'Image saved! Reloading…'; + window.location.reload(); + } else { + statusEl.textContent = 'Failed to save image. Please try again.'; + statusEl.style.color = 'var(--color-error)'; } + } catch (e) { + statusEl.textContent = 'Network error. Please try again.'; + statusEl.style.color = 'var(--color-error)'; } finally { el.style.opacity = '1'; el.style.pointerEvents = '';