mirror of
https://github.com/tiennm99/ghglance.git
synced 2026-10-11 03:13:20 +00:00
Five new cards, all derived from data FetchProductive / FetchProfile already pull, so zero additional API calls: - contributions-heatmap: 7×53 calendar grid with a 5-bucket intensity ramp mixed from each theme's Background→Accent so palettes with no dedicated heat ramp still render sensibly. - streak: current streak, longest streak with date ranges, active/total days. - contributions-by-year: one bar per active year, peak year highlighted. - productive-weekday + -all-time: 7-bar day-of-week mirror of the hour-of-day cards; FetchProductive now also fills Weekday / WeekdayAllTime histograms during the same commit-history pass. - top-starred-repos: top 5 owned non-fork repos by stargazer count; threads Stars through RepoInfo. Card count: 9 → 14. Registered in allCards grouped by recency (last-year block, then all-time block). Render test extended to cover all new files and realistic daily-series inputs.
59 lines
1.6 KiB
Go
59 lines
1.6 KiB
Go
// Package card renders Profile data into SVG cards on disk.
|
|
package card
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"github.com/tiennm99/ghstats/internal/github"
|
|
"github.com/tiennm99/ghstats/internal/theme"
|
|
)
|
|
|
|
// Card renders one SVG for a Profile under the given theme.
|
|
type Card interface {
|
|
// Filename is the on-disk basename (e.g. "profile-details.svg").
|
|
Filename() string
|
|
// SVG returns the rendered SVG bytes.
|
|
SVG(p *github.Profile, t theme.Theme) ([]byte, error)
|
|
}
|
|
|
|
// allCards is the ordered list rendered by RenderAll. Filenames are plain
|
|
// kebab-case — README authors embed them by name, not by lexicographic order.
|
|
var allCards = []Card{
|
|
profileCard{},
|
|
reposPerLanguageCard{},
|
|
mostCommitLanguageCard{},
|
|
statsCard{},
|
|
productiveCard{},
|
|
productiveWeekdayCard{},
|
|
contributionsCard{},
|
|
contributionsHeatmapCard{},
|
|
topStarredReposCard{},
|
|
streakCard{},
|
|
mostCommitLanguageAllTimeCard{},
|
|
productiveAllTimeCard{},
|
|
productiveWeekdayAllTimeCard{},
|
|
contributionsAllTimeCard{},
|
|
contributionsByYearCard{},
|
|
}
|
|
|
|
// RenderAll writes every card into outDir/<themeID>/.
|
|
func RenderAll(p *github.Profile, t theme.Theme, outDir string) error {
|
|
dir := filepath.Join(outDir, t.ID)
|
|
if err := os.MkdirAll(dir, 0o755); err != nil {
|
|
return fmt.Errorf("mkdir %s: %w", dir, err)
|
|
}
|
|
for _, c := range allCards {
|
|
data, err := c.SVG(p, t)
|
|
if err != nil {
|
|
return fmt.Errorf("render %s: %w", c.Filename(), err)
|
|
}
|
|
path := filepath.Join(dir, c.Filename())
|
|
if err := os.WriteFile(path, data, 0o644); err != nil {
|
|
return fmt.Errorf("write %s: %w", path, err)
|
|
}
|
|
}
|
|
return nil
|
|
}
|