Documentation
¶
Index ¶
- Constants
- Variables
- func ComputeCategoryXP(gameType string, modeStats []store.ModeStat) int
- func ComputeDailyStreak(dates []time.Time, now time.Time) int
- func ContentWidth(termWidth int) int
- func InitModeXP(categories []game.Category)
- func LevelFromXP(xp int) int
- func RenderBanner(b ProfileBanner, width int) string
- func RenderCard(c Card, titleColor color.Color) string
- func RenderCardGrid(cards []Card, width int) string
- func RenderView(banner ProfileBanner, cards []Card, width int) string
- func StaticHeight(cards []Card) int
- func TruncateToDate(t time.Time) time.Time
- func ViewportHeight(availableHeight int) int
- func XPForLevel(level int) int
- type Card
- type ModeKey
- type ProfileBanner
Constants ¶
const ( CardInnerWidth = 30 // CardHeight is the rendered height of a single stats card in lines. // 7 inner lines (title + 4 stats + blank + XP bar) + 2 border lines = 9. CardHeight = 9 )
const CardFullWidth = CardInnerWidth + 4 // 34
CardFullWidth is the rendered width of a single card including border + padding.
Variables ¶
var ModeXP map[ModeKey]int
ModeXP maps each mode to its base XP award per completion.
Functions ¶
func ComputeCategoryXP ¶
ComputeCategoryXP calculates total XP for a game category by summing XP across all modes. Daily victories earn 2x XP.
func ComputeDailyStreak ¶
ComputeDailyStreak calculates the length of the current daily completion streak. The streak is "alive" if the most recent completion is today or yesterday (giving the player until end of day to extend it).
func ContentWidth ¶
ContentWidth returns the inner content width for the stats panel. It snaps to the widest whole-card grid that fits the available panel space. The result never exceeds terminal width minus panel chrome.
func InitModeXP ¶
InitModeXP builds the ModeXP map from the provided game categories. Must be called once at startup before any stats operations.
func LevelFromXP ¶
LevelFromXP returns the level for the given total XP. Uses the inverse of XPForLevel: level = floor((xp / 5) ^ (1/1.6))
func RenderBanner ¶
func RenderBanner(b ProfileBanner, width int) string
RenderBanner renders the profile summary banner.
func RenderCard ¶
RenderCard renders a single stats card. The titleColor determines the foreground color used for the category name heading.
func RenderCardGrid ¶
RenderCardGrid renders just the card grid (no banner). This is the content placed inside the scrollable viewport.
func RenderView ¶
func RenderView(banner ProfileBanner, cards []Card, width int) string
RenderView renders the full stats view (banner + card grid) as a single string. Used only by tests and the empty-state path.
func StaticHeight ¶
StaticHeight returns the total lines consumed by non-scrollable parts of the stats view: panel chrome + banner (when cards exist).
func TruncateToDate ¶
TruncateToDate strips the time component, returning midnight local time.
func ViewportHeight ¶
ViewportHeight computes the viewport height for the card grid. Shows at most 2.5 card rows and at least 1 full card row, clamped to the available terminal height minus the static chrome.
func XPForLevel ¶
XPForLevel returns the total XP required to reach the given level. Formula: ceil(5 * level^1.6)
Types ¶
type Card ¶
type Card struct {
GameType string
Level int
PreferredMode string
Victories int
Attempts int
DailyPlayed int
CurrentXP int
NextLevelXP int
}
Card holds the computed stats for a single game category.
func BuildCards ¶
func BuildCards(catStats []store.CategoryStat, modeStats []store.ModeStat) []Card
BuildCards constructs a Card for each category the player has interacted with. Categories with zero attempts are excluded.
type ProfileBanner ¶
ProfileBanner holds the summary data shown above the card grid.
func BuildProfileBanner ¶
func BuildProfileBanner( catStats []store.CategoryStat, modeStats []store.ModeStat, streakDates []time.Time, currentDaily bool, ) ProfileBanner
BuildProfileBanner constructs the summary banner shown above the card grid.