ui

package
v0.22.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 20, 2026 License: MIT Imports: 21 Imported by: 0

Documentation

Overview

Package ui provides terminal user interface components for golazo.

Package ui provides rendering functions for the terminal user interface.

Index

Constants

View Source
const (
	DefaultDialogMaxWidth  = 104
	DefaultDialogMaxHeight = 39
)

Dialog sizing constants (30% larger for better readability).

View Source
const (
	CardSymbolYellow = "▪" // Small square for yellow cards
	CardSymbolRed    = "■" // Filled square for red cards
)

Card symbols - consistent across all views

View Source
const ReplayLinkIndicator = "[▶REPLAY]"

ReplayLinkIndicator is the visual indicator for replay links.

View Source
const ReplayLinkIndicatorAlt = "[replay]"

ReplayLinkIndicatorAlt is an alternative ASCII indicator for terminals without emoji.

View Source
const SpinnerTickInterval = 70 * time.Millisecond

SpinnerTickInterval is the unified tick rate for all spinners (70ms ≈ 14 fps). This balances smooth animation with keyboard responsiveness.

Variables

This section is empty.

Functions

func AdaptiveGradientColors added in v0.16.0

func AdaptiveGradientColors() (startHex, endHex string)

AdaptiveGradientColors returns the appropriate gradient start/end hex colors based on the terminal background (light or dark). This is a convenience wrapper around design.AdaptiveGradientColors.

func CreateGoalLinkDisplay added in v0.10.0

func CreateGoalLinkDisplay(goalText, replayURL string) string

CreateGoalLinkDisplay creates a display string for a goal with replay link. Returns the text with hyperlink if available, or plain text if not. If the terminal doesn't support hyperlinks OR no URL is provided, returns the original goalText unchanged (no visible difference).

func DialogBadge added in v0.18.0

func DialogBadge(value string) string

DialogBadge wraps a value with a subtle background.

func DialogBadgeHighlight added in v0.18.0

func DialogBadgeHighlight(value string) string

DialogBadgeHighlight wraps a value with a highlighted background.

func DialogSize added in v0.18.0

func DialogSize(screenWidth, screenHeight, contentWidth, contentHeight int) (width, height int)

DialogSize calculates appropriate dialog dimensions based on content and screen size.

func FilterInputStyles added in v0.3.0

func FilterInputStyles() (cursorStyle, promptStyle lipgloss.Style)

FilterInputStyles returns cursor and prompt styles for list filter input. Cursor: neon cyan (solid color), Prompt: neon red to match theme.

func Hyperlink(text, url string) string

Hyperlink creates a terminal hyperlink using OSC 8 escape sequences. Falls back to plain text with URL suffix if terminal doesn't support OSC 8.

func HyperlinkWithFallback added in v0.10.0

func HyperlinkWithFallback(text, url, fallbackIndicator string) string

HyperlinkWithFallback creates a hyperlink with a visible fallback indicator. If OSC 8 is supported, returns a clickable link. Otherwise, returns text with a link indicator like [📹].

func IsValidReplayURL added in v0.12.0

func IsValidReplayURL(url string) bool

IsValidReplayURL validates that a URL is a valid HTTP/HTTPS URL and not a marker. Returns true only for valid http:// or https:// URLs. Filters out empty strings, "__NOT_FOUND__" markers, and invalid URL schemes.

func MakeGoalLinkKey added in v0.10.0

func MakeGoalLinkKey(matchID, minute int) string

MakeGoalLinkKey creates a key for the goal links map.

func NewMatchListDelegate

func NewMatchListDelegate() list.DefaultDelegate

NewMatchListDelegate creates a custom list delegate for match items. Height is set to 3 to accommodate title + 2-line description (with KO time). Uses Neon Gradient styling: red title, cyan description on selection.

func OpenURL added in v0.10.0

func OpenURL(url string) error

OpenURL opens a URL in the default browser. Use this as a fallback when OSC 8 hyperlinks aren't supported.

func RenderDialogFrame added in v0.18.0

func RenderDialogFrame(title, content string, width, height int) string

RenderDialogFrame wraps content in a dialog frame with title bar.

func RenderDialogFrameWithHelp added in v0.18.0

func RenderDialogFrameWithHelp(title, content, help string, width, height int) string

RenderDialogFrameWithHelp wraps content in a dialog frame with title bar and help text.

func RenderDialogTitleBar added in v0.18.0

func RenderDialogTitleBar(title string, width int) string

RenderDialogTitleBar creates a full-width title bar with background.

func RenderGradientText added in v0.6.0

func RenderGradientText(text string) string

RenderGradientText applies a gradient (cyan to red) to multi-line text. Exported wrapper for external use.

func RenderLiveMatchesListPanel

func RenderLiveMatchesListPanel(width, height int, listModel list.Model, upcomingMatches []MatchDisplay) string

RenderLiveMatchesListPanel renders the left panel using bubbletea list component.

func RenderMainMenu

func RenderMainMenu(width, height, selected int, sp spinner.Model, randomSpinner *RandomCharSpinner, loading bool, bannerType constants.StatusBannerType, animatedLogo *logo.AnimatedLogo) string

RenderMainMenu renders the main menu view with navigation options. width and height specify the terminal dimensions. selected indicates which menu item is currently selected (0-indexed). sp is the spinner model to display when loading (for other views). randomSpinner is the random character spinner for main view. loading indicates if the spinner should be shown. bannerType determines what status banner (if any) to display at the top. animatedLogo is the animated logo instance for the main view.

func RenderMatchDetails added in v0.17.0

func RenderMatchDetails(cfg MatchDetailsConfig) (headerContent, scrollableContent string)

RenderMatchDetails renders match details content, returning header and scrollable content separately. This unified function is used by both live and stats views.

func RenderMatchDetailsPanel added in v0.4.0

func RenderMatchDetailsPanel(width, height int, details *api.MatchDetails) string

RenderMatchDetailsPanel is an exported version for debug scripts.

func RenderMultiPanelViewWithList

func RenderMultiPanelViewWithList(width, height int, listModel list.Model, details *api.MatchDetails, liveUpdates []string, sp spinner.Model, loading bool, randomSpinner *RandomCharSpinner, viewLoading bool, leaguesLoaded int, totalLeagues int, pollingSpinner *RandomCharSpinner, isPolling bool, upcomingMatches []MatchDisplay, goalLinks GoalLinksMap, bannerType constants.StatusBannerType) string

RenderMultiPanelViewWithList renders the live matches view with list component.

func RenderSettingsView added in v0.3.0

func RenderSettingsView(width, height int, state *SettingsState, bannerType constants.StatusBannerType) string

RenderSettingsView renders the settings view for league customization. Uses minimal styling consistent with the rest of the app (red/cyan neon theme). bannerType determines what status banner (if any) to display at the top.

func RenderStatsListPanel

func RenderStatsListPanel(width, height int, finishedList list.Model, dateRange int, rightPanelFocused bool) string

RenderStatsListPanel renders the left panel for stats view.

func RenderStatsViewWithList

func RenderStatsViewWithList(width, height int, finishedList list.Model, details *api.MatchDetails, randomSpinner *RandomCharSpinner, viewLoading bool, dateRange int, daysLoaded int, totalDays int, goalLinks GoalLinksMap, bannerType constants.StatusBannerType, detailsViewport *viewport.Model, rightPanelFocused bool, scrollOffset int) string

RenderStatsViewWithList renders the stats view with list component.

func SpinnerStyle

func SpinnerStyle() lipgloss.Style

SpinnerStyle returns the style for the spinner.

func SpinnerTick

func SpinnerTick() tea.Cmd

SpinnerTick returns a command that generates a TickMsg after the standard interval. This is the ONLY function that should create spinner ticks - ensures single tick chain.

func ToMatchListItems

func ToMatchListItems(matches []MatchDisplay) []list.Item

ToMatchListItems converts a slice of MatchDisplay to list items.

func Truncate

func Truncate(text string, width int) string

Truncate truncates text to fit the specified width, appending "..." if truncated.

Types

type Dialog added in v0.18.0

type Dialog interface {
	// ID returns the unique identifier of the dialog.
	ID() string
	// Update processes a message and returns the updated dialog and an optional action.
	Update(msg tea.Msg) (Dialog, DialogAction)
	// View renders the dialog content within the specified dimensions.
	View(width, height int) string
}

Dialog is a component that can be displayed as an overlay on top of the UI.

type DialogAction added in v0.18.0

type DialogAction any

DialogAction represents an action returned by a dialog after handling a message.

type DialogActionClose added in v0.18.0

type DialogActionClose struct{}

DialogActionClose signals that the dialog should be closed.

type DialogOverlay added in v0.18.0

type DialogOverlay struct {
	// contains filtered or unexported fields
}

DialogOverlay manages multiple dialogs as an overlay stack.

func NewDialogOverlay added in v0.18.0

func NewDialogOverlay() *DialogOverlay

NewDialogOverlay creates a new DialogOverlay instance.

func (*DialogOverlay) CloseDialog added in v0.18.0

func (o *DialogOverlay) CloseDialog(dialogID string)

CloseDialog removes the dialog with the specified ID from the stack.

func (*DialogOverlay) CloseFrontDialog added in v0.18.0

func (o *DialogOverlay) CloseFrontDialog()

CloseFrontDialog closes the front (topmost) dialog in the stack.

func (*DialogOverlay) ContainsDialog added in v0.18.0

func (o *DialogOverlay) ContainsDialog(dialogID string) bool

ContainsDialog checks if a dialog with the specified ID exists.

func (*DialogOverlay) FrontDialog added in v0.18.0

func (o *DialogOverlay) FrontDialog() Dialog

FrontDialog returns the front (topmost) dialog, or nil if there are no dialogs.

func (*DialogOverlay) HasDialogs added in v0.18.0

func (o *DialogOverlay) HasDialogs() bool

HasDialogs checks if there are any active dialogs.

func (*DialogOverlay) OpenDialog added in v0.18.0

func (o *DialogOverlay) OpenDialog(dialog Dialog)

OpenDialog adds a new dialog to the stack.

func (*DialogOverlay) Update added in v0.18.0

func (o *DialogOverlay) Update(msg tea.Msg) DialogAction

Update handles message routing to the front dialog. Returns the action from the dialog, if any.

func (*DialogOverlay) View added in v0.18.0

func (o *DialogOverlay) View(width, height int) string

View renders the overlay with the front dialog centered.

type FormationsDialog added in v0.18.0

type FormationsDialog struct {
	// contains filtered or unexported fields
}

FormationsDialog displays the match formations for both teams.

func NewFormationsDialog added in v0.18.0

func NewFormationsDialog(
	homeTeam, awayTeam string,
	homeFormation, awayFormation string,
	homeStarting, awayStarting []api.PlayerInfo,
) *FormationsDialog

NewFormationsDialog creates a new formations dialog.

func (*FormationsDialog) ID added in v0.18.0

func (d *FormationsDialog) ID() string

ID returns the dialog identifier.

func (*FormationsDialog) Update added in v0.18.0

func (d *FormationsDialog) Update(msg tea.Msg) (Dialog, DialogAction)

Update handles input for the formations dialog.

func (*FormationsDialog) View added in v0.18.0

func (d *FormationsDialog) View(width, height int) string

View renders the formations view.

type GoalLinksMap added in v0.10.0

type GoalLinksMap map[string]string

GoalLinksMap maps goal keys (matchID:minute) to replay URLs.

func (GoalLinksMap) GetReplayURL added in v0.10.0

func (g GoalLinksMap) GetReplayURL(matchID, minute int) string

GetReplayURL returns the replay URL for a goal if available.

type LeagueListDelegate added in v0.13.0

type LeagueListDelegate struct {
	list.DefaultDelegate
}

LeagueListDelegate is a custom delegate that renders checkboxes separately from titles. This fixes the filter cursor positioning issue by keeping the checkbox out of the title.

func NewLeagueListDelegate added in v0.5.0

func NewLeagueListDelegate() LeagueListDelegate

NewLeagueListDelegate creates a custom list delegate for league selection. Height is set to 2 to show league name (with checkbox) and country. Uses same red/cyan neon styling as match delegate for consistency. The checkbox is rendered separately from the title to fix filter cursor positioning.

func (LeagueListDelegate) HighlightMatches added in v0.13.0

func (d LeagueListDelegate) HighlightMatches(text, filterValue string) string

HighlightMatches highlights matching text in the title using FilterMatch style.

func (LeagueListDelegate) Render added in v0.13.0

func (d LeagueListDelegate) Render(w io.Writer, m list.Model, index int, item list.Item)

Render renders a league list item with a checkbox prefix. The checkbox is rendered separately from the title to prevent filter cursor shift.

type LeagueListItem added in v0.5.0

type LeagueListItem struct {
	League   data.LeagueInfo
	Selected bool
}

LeagueListItem implements the list.Item interface for league selection.

func (LeagueListItem) Description added in v0.5.0

func (l LeagueListItem) Description() string

Description returns the country.

func (LeagueListItem) FilterValue added in v0.5.0

func (l LeagueListItem) FilterValue() string

FilterValue returns the value used for filtering (league name + country).

func (LeagueListItem) Title added in v0.5.0

func (l LeagueListItem) Title() string

Title returns the league name with selection indicator.

type MatchDetailsConfig added in v0.17.0

type MatchDetailsConfig struct {
	Width, Height int
	Details       *api.MatchDetails
	GoalLinks     GoalLinksMap

	// View-specific features
	ShowStatistics bool // Stats view only
	ShowHighlights bool // Stats view only

	// Live view state
	LiveUpdates    []string
	PollingSpinner *RandomCharSpinner
	IsPolling      bool
	Loading        bool

	// Stats view state
	Focused bool
}

MatchDetailsConfig holds all parameters for rendering match details.

type MatchDisplay

type MatchDisplay struct {
	api.Match
}

MatchDisplay wraps a match with display information for rendering.

func (MatchDisplay) Description

func (m MatchDisplay) Description() string

Description returns a formatted description for the match. Shows score, league, live time on first line; KO time on second line.

func (MatchDisplay) Title

func (m MatchDisplay) Title() string

Title returns a formatted title for the match.

type MatchListItem

type MatchListItem struct {
	Match   api.Match
	Display MatchDisplay
}

MatchListItem implements the list.Item interface for matches.

func (MatchListItem) Description

func (m MatchListItem) Description() string

Description returns the match description for the list item.

func (MatchListItem) FilterValue

func (m MatchListItem) FilterValue() string

FilterValue returns the value to use for filtering. Returns team names for searching (e.g., "Arsenal vs Chelsea").

func (MatchListItem) Title

func (m MatchListItem) Title() string

Title returns the match title for the list item.

type RandomCharSpinner

type RandomCharSpinner struct {
	// contains filtered or unexported fields
}

RandomCharSpinner is a custom spinner that displays a wave of random characters. Note: Spinners do NOT self-tick. The app manages the tick chain centrally.

func NewRandomCharSpinner

func NewRandomCharSpinner() *RandomCharSpinner

NewRandomCharSpinner creates a new random character spinner.

func (*RandomCharSpinner) SetWidth

func (r *RandomCharSpinner) SetWidth(width int)

SetWidth sets the width of the spinner and resizes the display buffer.

func (*RandomCharSpinner) Tick

func (r *RandomCharSpinner) Tick()

Tick advances the spinner animation - randomizes all characters for trendy effect. Does NOT return a tick command - the app manages the tick chain.

func (*RandomCharSpinner) View

func (r *RandomCharSpinner) View() string

View renders the spinner with gradient colors.

type SettingsState added in v0.3.0

type SettingsState struct {
	List          list.Model        // List component for league navigation
	Selected      map[int]bool      // Map of league ID -> selected
	Leagues       []data.LeagueInfo // All leagues for current region
	AllLeagues    []data.LeagueInfo // All leagues across all regions
	Regions       []string          // Available regions
	CurrentRegion int               // Index of current region
	HasChanges    bool              // Whether there are unsaved changes
}

SettingsState holds the state for the settings view.

func NewSettingsState added in v0.3.0

func NewSettingsState() *SettingsState

NewSettingsState creates a new settings state with current saved preferences.

func (*SettingsState) NextRegion added in v0.13.0

func (s *SettingsState) NextRegion()

NextRegion switches to the next region (with wraparound).

func (*SettingsState) PreviousRegion added in v0.13.0

func (s *SettingsState) PreviousRegion()

PreviousRegion switches to the previous region (with wraparound).

func (*SettingsState) Save added in v0.3.0

func (s *SettingsState) Save() error

Save persists the current selection to settings.yaml.

func (*SettingsState) SelectedCount added in v0.3.0

func (s *SettingsState) SelectedCount() int

SelectedCount returns the number of selected leagues.

func (*SettingsState) Toggle added in v0.3.0

func (s *SettingsState) Toggle()

Toggle toggles the selection state of the currently highlighted league.

type StandingsDialog added in v0.18.0

type StandingsDialog struct {
	// contains filtered or unexported fields
}

StandingsDialog displays the league standings table for a match.

func NewStandingsDialog added in v0.18.0

func NewStandingsDialog(leagueName string, standings []api.LeagueTableEntry, homeTeamID, awayTeamID int) *StandingsDialog

NewStandingsDialog creates a new standings dialog.

func (*StandingsDialog) ID added in v0.18.0

func (d *StandingsDialog) ID() string

ID returns the dialog identifier.

func (*StandingsDialog) Update added in v0.18.0

func (d *StandingsDialog) Update(msg tea.Msg) (Dialog, DialogAction)

Update handles input for the standings dialog.

func (*StandingsDialog) View added in v0.18.0

func (d *StandingsDialog) View(width, height int) string

View renders the standings table.

type StatisticsDialog added in v0.18.0

type StatisticsDialog struct {
	// contains filtered or unexported fields
}

StatisticsDialog displays all match statistics in a comparison view.

func NewStatisticsDialog added in v0.18.0

func NewStatisticsDialog(homeTeam, awayTeam string, statistics []api.MatchStatistic) *StatisticsDialog

NewStatisticsDialog creates a new statistics dialog.

func (*StatisticsDialog) ID added in v0.18.0

func (d *StatisticsDialog) ID() string

ID returns the dialog identifier.

func (*StatisticsDialog) Update added in v0.18.0

func (d *StatisticsDialog) Update(msg tea.Msg) (Dialog, DialogAction)

Update handles input for the statistics dialog.

func (*StatisticsDialog) View added in v0.18.0

func (d *StatisticsDialog) View(width, height int) string

View renders the statistics comparison.

type TickMsg

type TickMsg struct{}

TickMsg is the unified message type for all spinner updates. Only ONE tick chain should exist at any time to prevent message queue flooding.

Directories

Path Synopsis
Package design provides reusable visual design components.
Package design provides reusable visual design components.
Package logo renders a GOLAZO wordmark in a stylized way.
Package logo renders a GOLAZO wordmark in a stylized way.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL