From d0c75d5ff19440f59d2e7c7cdfde60f77da126bc Mon Sep 17 00:00:00 2001 From: tiennm99 Date: Sat, 18 Apr 2026 23:26:48 +0700 Subject: [PATCH] refactor(card): shrink cards from 500x220 to 340x200 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two ghstats cards side-by-side at 500px overflow GitHub's README column width (~816px). Matching github-profile-summary-cards' 340x200 lets consumers place two cards per row cleanly. - Shared header() rect corner radius 8→6, title font 18→15, title anchor (25,35)→(20,30). - All card layouts reworked: * profile + stats: row padding 70→55 / 24→20, icon 14→12, value font 13→12, stats right-anchor x=475→320. * donut_chart: centre (380,120)→(250,110), outerR 70→55, innerR 38→30, legend y0 70→55, swatch 12→10, topN 6→5. * productive-time: leftAxis 50→35, topPad 60→45, barGap 2→1. * contributions: leftPad/rightPad 35→28, topPad 60→45, chartH 120→105. Visual parity with github-profile-summary-cards; two-per-row layouts in profile READMEs now fit. Also: document the one-time GitHub Marketplace publishing step in deployment-guide (no CLI flag exists — UI checkbox only). --- docs/deployment-guide.md | 7 ++++++- internal/card/contributions.go | 12 ++++++------ internal/card/donut_chart.go | 26 +++++++++++++------------- internal/card/productive.go | 12 ++++++------ internal/card/profile.go | 16 ++++++++-------- internal/card/stats.go | 20 ++++++++++---------- internal/card/svg.go | 4 ++-- 7 files changed, 51 insertions(+), 46 deletions(-) diff --git a/docs/deployment-guide.md b/docs/deployment-guide.md index 378875d1..229dc5b3 100644 --- a/docs/deployment-guide.md +++ b/docs/deployment-guide.md @@ -110,7 +110,12 @@ runs: 3. On green, GHCR push + cross-platform binary artifacts happen automatically. 4. Docker base images and third-party actions are SHA-pinned (with version comments) so mutable-tag changes upstream can't rewrite a released image. -5. Update any public Actions marketplace metadata if the major version changed. +5. **Marketplace publishing (one-time per repo):** GitHub only exposes the + "Publish this Action to the GitHub Marketplace" toggle on the Release + web UI — there is no CLI flag. Open the newly created release at + `https://github.com/tiennm99/ghstats/releases/tag/vX.Y.Z/edit`, tick the + marketplace checkbox, accept the terms, and re-publish. Subsequent + releases inherit marketplace visibility automatically. ## Rollback diff --git a/internal/card/contributions.go b/internal/card/contributions.go index 257f95fa..9f3dc0d7 100644 --- a/internal/card/contributions.go +++ b/internal/card/contributions.go @@ -37,12 +37,12 @@ type monthBucket struct { // contribution cards; only title + data differ. func renderContributions(title string, days []github.DailyContribution, t theme.Theme) []byte { const ( - width = 500 - height = 220 - leftPad = 35 - rightPad = 35 - topPad = 60 - chartH = 120 + width = 340 + height = 200 + leftPad = 28 + rightPad = 28 + topPad = 45 + chartH = 105 ) chartW := width - leftPad - rightPad diff --git a/internal/card/donut_chart.go b/internal/card/donut_chart.go index 2723cce7..0c2aaa9d 100644 --- a/internal/card/donut_chart.go +++ b/internal/card/donut_chart.go @@ -14,17 +14,17 @@ import ( // shown; smaller slices are grouped into "Other". func renderDonutCard(title string, stats []github.LangStat, t theme.Theme) []byte { const ( - width = 500 - height = 220 - topN = 6 - cx = 380 // donut centre x - cy = 120 // donut centre y - outerR = 70.0 // donut outer radius - innerR = 38.0 // donut hole - legendX = 30 - legendY0 = 70 - legendDY = 22 - swatchSz = 12 + width = 340 + height = 200 + topN = 5 + cx = 250 // donut centre x + cy = 110 // donut centre y + outerR = 55.0 // donut outer radius + innerR = 30.0 // donut hole + legendX = 20 + legendY0 = 55 + legendDY = 20 + swatchSz = 10 ) stats = collapseOther(stats, topN) @@ -50,10 +50,10 @@ func renderDonutCard(title string, stats []github.LangStat, t theme.Theme) []byt y := legendY0 + i*legendDY fmt.Fprintf(&b, ` - %s %.2f%%`, + %s %.2f%%`, legendX, y-swatchSz+2, swatchSz, swatchSz, colorOrAccent(s.Color, t.Accent), t.Background, - legendX+swatchSz+8, y, t.Text, + legendX+swatchSz+6, y, t.Text, escapeXML(s.Name), pct) } diff --git a/internal/card/productive.go b/internal/card/productive.go index dfaa93de..cc0a5bc0 100644 --- a/internal/card/productive.go +++ b/internal/card/productive.go @@ -40,13 +40,13 @@ var xTickHours = [...]int{0, 6, 12, 18, 23} // hover titles. Shared by the last-year and all-time productive-time cards. func renderProductiveTime(title string, data [24]int, t theme.Theme) []byte { const ( - width = 500 - height = 220 - leftAxis = 50 - rightPad = 25 - topPad = 60 + width = 340 + height = 200 + leftAxis = 35 + rightPad = 15 + topPad = 45 chartH = 110 - barGap = 2 + barGap = 1 ) chartW := width - leftAxis - rightPad barW := float64(chartW-barGap*23) / 24.0 diff --git a/internal/card/profile.go b/internal/card/profile.go index 8f4e83ec..d330d7a1 100644 --- a/internal/card/profile.go +++ b/internal/card/profile.go @@ -21,12 +21,12 @@ type profileRow struct { func (profileCard) SVG(p *github.Profile, t theme.Theme) ([]byte, error) { const ( - width = 500 - height = 220 - rowX = 25 - rowY0 = 70 - rowDY = 24 - iconSize = 14 + width = 340 + height = 200 + rowX = 20 + rowY0 = 60 + rowDY = 20 + iconSize = 12 maxRows = 7 ) @@ -46,9 +46,9 @@ func (profileCard) SVG(p *github.Profile, t theme.Theme) ([]byte, error) { // icon glyph: translate to row position, scale down, fill with muted. fmt.Fprintf(&b, ` %s - %s`, + %s`, rowX, float64(y-iconSize+2), scale, t.Muted, r.icon, - rowX+iconSize+10, y, t.Text, escapeXML(r.value)) + rowX+iconSize+8, y, t.Text, escapeXML(r.value)) } b.WriteString(footer) diff --git a/internal/card/stats.go b/internal/card/stats.go index e0a81832..40435eca 100644 --- a/internal/card/stats.go +++ b/internal/card/stats.go @@ -21,13 +21,13 @@ type statRow struct { func (statsCard) SVG(p *github.Profile, t theme.Theme) ([]byte, error) { const ( - width = 500 - height = 220 - rowX = 25 - rowY0 = 70 - rowDY = 24 - iconSize = 14 - valueX = 475 // right-aligned x anchor + width = 340 + height = 200 + rowX = 20 + rowY0 = 55 + rowDY = 20 + iconSize = 12 + valueX = 320 // right-aligned x anchor ) rows := []statRow{ @@ -48,10 +48,10 @@ func (statsCard) SVG(p *github.Profile, t theme.Theme) ([]byte, error) { y := rowY0 + i*rowDY fmt.Fprintf(&b, ` %s - %s - %s`, + %s + %s`, rowX, float64(y-iconSize+2), scale, t.Muted, r.icon, - rowX+iconSize+10, y, t.Text, escapeXML(r.label), + rowX+iconSize+8, y, t.Text, escapeXML(r.label), valueX, y, t.Accent, escapeXML(r.value)) } diff --git a/internal/card/svg.go b/internal/card/svg.go index 21c4c5dc..839bfb16 100644 --- a/internal/card/svg.go +++ b/internal/card/svg.go @@ -55,8 +55,8 @@ func formatInt(n int) string { // header returns the opening tag + background rect + title text. func header(width, height int, bg, stroke string, strokeOpacity float64, titleColor, title string) string { return fmt.Sprintf(` - - %s`, + + %s`, width, height, width, height, width-1, height-1, bg, stroke, strokeOpacity, titleColor, escapeXML(title))