Documentation
¶
Overview ¶
Package ui provides terminal user interface components for golazo.
Package ui provides rendering functions for the terminal user interface.
Index ¶
- Constants
- func AdaptiveGradientColors() (startHex, endHex string)
- func CreateGoalLinkDisplay(goalText, replayURL string) string
- func DialogBadge(value string) string
- func DialogBadgeHighlight(value string) string
- func DialogSize(screenWidth, screenHeight, contentWidth, contentHeight int) (width, height int)
- func FilterInputStyles() (cursorStyle, promptStyle lipgloss.Style)
- func Hyperlink(text, url string) string
- func HyperlinkWithFallback(text, url, fallbackIndicator string) string
- func IsValidReplayURL(url string) bool
- func MakeGoalLinkKey(matchID, minute int) string
- func NewMatchListDelegate() list.DefaultDelegate
- func OpenURL(url string) error
- func RenderDialogFrame(title, content string, width, height int) string
- func RenderDialogFrameWithHelp(title, content, help string, width, height int) string
- func RenderDialogTitleBar(title string, width int) string
- func RenderGradientText(text string) string
- func RenderLiveMatchesListPanel(width, height int, listModel list.Model, upcomingMatches []MatchDisplay) string
- func RenderMainMenu(width, height, selected int, sp spinner.Model, ...) string
- func RenderMatchDetails(cfg MatchDetailsConfig) (headerContent, scrollableContent string)
- func RenderMatchDetailsPanel(width, height int, details *api.MatchDetails) string
- func RenderMultiPanelViewWithList(width, height int, listModel list.Model, details *api.MatchDetails, ...) string
- func RenderSettingsView(width, height int, state *SettingsState, bannerType constants.StatusBannerType) string
- func RenderStatsListPanel(width, height int, finishedList list.Model, dateRange int, ...) string
- func RenderStatsViewWithList(width, height int, finishedList list.Model, details *api.MatchDetails, ...) string
- func SpinnerStyle() lipgloss.Style
- func SpinnerTick() tea.Cmd
- func ToMatchListItems(matches []MatchDisplay) []list.Item
- func Truncate(text string, width int) string
- type Dialog
- type DialogAction
- type DialogActionClose
- type DialogOverlay
- func (o *DialogOverlay) CloseDialog(dialogID string)
- func (o *DialogOverlay) CloseFrontDialog()
- func (o *DialogOverlay) ContainsDialog(dialogID string) bool
- func (o *DialogOverlay) FrontDialog() Dialog
- func (o *DialogOverlay) HasDialogs() bool
- func (o *DialogOverlay) OpenDialog(dialog Dialog)
- func (o *DialogOverlay) Update(msg tea.Msg) DialogAction
- func (o *DialogOverlay) View(width, height int) string
- type FormationsDialog
- type GoalLinksMap
- type LeagueListDelegate
- type LeagueListItem
- type MatchDetailsConfig
- type MatchDisplay
- type MatchListItem
- type RandomCharSpinner
- type SettingsState
- type StandingsDialog
- type StatisticsDialog
- type TickMsg
Constants ¶
const ( DefaultDialogMaxWidth = 104 DefaultDialogMaxHeight = 39 )
Dialog sizing constants (30% larger for better readability).
const ( CardSymbolYellow = "▪" // Small square for yellow cards CardSymbolRed = "■" // Filled square for red cards )
Card symbols - consistent across all views
const ReplayLinkIndicator = "[▶REPLAY]"
ReplayLinkIndicator is the visual indicator for replay links.
const ReplayLinkIndicatorAlt = "[replay]"
ReplayLinkIndicatorAlt is an alternative ASCII indicator for terminals without emoji.
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
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
DialogBadge wraps a value with a subtle background.
func DialogBadgeHighlight ¶ added in v0.18.0
DialogBadgeHighlight wraps a value with a highlighted background.
func DialogSize ¶ added in v0.18.0
DialogSize calculates appropriate dialog dimensions based on content and screen size.
func FilterInputStyles ¶ added in v0.3.0
FilterInputStyles returns cursor and prompt styles for list filter input. Cursor: neon cyan (solid color), Prompt: neon red to match theme.
func Hyperlink ¶ added in v0.10.0
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
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
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
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
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
RenderDialogFrame wraps content in a dialog frame with title bar.
func RenderDialogFrameWithHelp ¶ added in v0.18.0
RenderDialogFrameWithHelp wraps content in a dialog frame with title bar and help text.
func RenderDialogTitleBar ¶ added in v0.18.0
RenderDialogTitleBar creates a full-width title bar with background.
func RenderGradientText ¶ added in v0.6.0
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 ¶
SpinnerStyle returns the style for the spinner.
func SpinnerTick ¶
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.
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
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.
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 ¶
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.