Documentation
¶
Overview ¶
Package ui is ghab's tea model tree: a root App owning a screen stack (push/pop, back pops), plus the Home and Repo screens for M1.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type App ¶
type App struct {
// contains filtered or unexported fields
}
App is the root bubbletea model: it owns the screen stack and the shared config/theme/client every screen is built from.
func NewApp ¶
func NewApp(cfg config.Config, theme style.Theme, client *gh.Client, readmeStylePath, jumpTo string) *App
NewApp builds the root model with Home as the base of the stack. readmeStylePath is the glamour stylesheet resolved once at app startup (main.go); it threads down to every Repo screen the app ever pushes. If jumpTo is non-empty, a Repo screen ("owner/repo") or Profile screen (bare "owner") is pushed on top so the app opens straight into it (main.go's positional-arg jump).
type HomeScreen ¶
type HomeScreen struct {
// contains filtered or unexported fields
}
HomeScreen is the app's landing screen: one text input with a small grammar (BUILD.md's Home spec) -- "owner/repo" jumps into the repo, a bare "owner" opens their profile, and anything with whitespace or a leading "?" runs a repo search. Recent visits this session are listed below the input (display-only; persistence is a non-goal for genesis).
func NewHomeScreen ¶
func NewHomeScreen(cfg config.Config, theme style.Theme, client *gh.Client, readmeStylePath string) *HomeScreen
NewHomeScreen builds the Home screen.
func (*HomeScreen) Footer ¶
func (h *HomeScreen) Footer() []style.KeyHint
func (*HomeScreen) Init ¶
func (h *HomeScreen) Init() tea.Cmd
func (*HomeScreen) View ¶
func (h *HomeScreen) View(width, height int) string
type MyPRsScreen ¶
type MyPRsScreen struct {
// contains filtered or unexported fields
}
MyPRsScreen is the cross-repo "my PRs" screen (issue #11): every open PR authored by or requesting review from the signed-in user, across every repo, without leaving the terminal. Fired once when pushed -- same hard search-endpoint debounce as SearchScreen, never per keystroke. Row grammar: state bullet, repo, #num, title, age.
func NewMyPRsScreen ¶
func NewMyPRsScreen(cfg config.Config, theme style.Theme, client *gh.Client, readmeStylePath string) *MyPRsScreen
NewMyPRsScreen builds the my-PRs screen. queries is [behavior].my_prs_query (config-first: Ian narrows or widens the scope without a rebuild) -- several queries because GitHub search has no OR between qualifiers, merged and de-duplicated by gh.MyPRs.
func (*MyPRsScreen) Footer ¶
func (s *MyPRsScreen) Footer() []style.KeyHint
func (*MyPRsScreen) Init ¶
func (s *MyPRsScreen) Init() tea.Cmd
func (*MyPRsScreen) View ¶
func (s *MyPRsScreen) View(width, height int) string
type PRDetailScreen ¶
type PRDetailScreen struct {
// contains filtered or unexported fields
}
PRDetailScreen is the top-level PR-detail hop pushed from MyPRsScreen (issue #11's cross-repo entry point): a thin Screen adapter around prDetailModel, which does all the actual work and is reused as-is by the per-repo PRs tab (issuesTab, kind == issueKindPR) -- see prdetail.go's struct comment.
func NewPRDetailScreen ¶
func NewPRDetailScreen(cfg config.Config, theme style.Theme, client *gh.Client, readmeStylePath, owner, repo string, number int) *PRDetailScreen
NewPRDetailScreen builds a PR detail screen for owner/repo#number.
func (*PRDetailScreen) Footer ¶
func (s *PRDetailScreen) Footer() []style.KeyHint
func (*PRDetailScreen) Init ¶
func (s *PRDetailScreen) Init() tea.Cmd
func (*PRDetailScreen) View ¶
func (s *PRDetailScreen) View(width, height int) string
type ProfileScreen ¶
type ProfileScreen struct {
// contains filtered or unexported fields
}
ProfileScreen is the user-profile hop: a framed user card (name, bio, counts) over the user's public repos sorted by most recently updated. Enter on a repo pushes its Repo screen -- and that repo's "u" pushes its owner's profile, so the hop chains both directions through the screen stack (BUILD.md: "THIS IS THE HOP -- must be seamless").
func NewProfileScreen ¶
func NewProfileScreen(cfg config.Config, theme style.Theme, client *gh.Client, readmeStylePath, login string) *ProfileScreen
NewProfileScreen builds the profile screen for login. Fetching starts in Init.
func (*ProfileScreen) Footer ¶
func (p *ProfileScreen) Footer() []style.KeyHint
func (*ProfileScreen) Init ¶
func (p *ProfileScreen) Init() tea.Cmd
func (*ProfileScreen) View ¶
func (p *ProfileScreen) View(width, height int) string
type RepoScreen ¶
type RepoScreen struct {
// contains filtered or unexported fields
}
RepoScreen shows a repo's framed header (owner/name, description, stars, branch, topics) plus the readme/code/releases/issues/prs tab bar. Each tab is owned by its own sub-model, kept alive (not rebuilt) across tab switches so background fetches and scroll position survive.
func NewRepoScreen ¶
func NewRepoScreen(cfg config.Config, theme style.Theme, client *gh.Client, readmeStylePath, owner, repo string) *RepoScreen
NewRepoScreen builds a Repo screen for owner/repo. Fetching starts in Init. readmeStylePath is the glamour stylesheet resolved once at app startup (main.go, via config.ResolveReadmeStyle) -- "" means fall back to glamour's built-in "dark" standard style. It's reused (not re-resolved) for the releases and issues/PRs tabs' detail bodies, which render through the same glamour setup as the readme tab.
func (*RepoScreen) Footer ¶
func (r *RepoScreen) Footer() []style.KeyHint
Footer builds this screen's contextual keybind hints from the live keymap, prefixed with hints specific to whichever tab is active. "tab" (pane focus) is bubbletea's literal Tab key, not a config-remappable binding -- there's no [keys] entry for it (BUILD.md's [keys] table has no pane-focus slot), so it's hardcoded here the same way Ctrl+C-to-quit is hardcoded in app.go.
func (*RepoScreen) Init ¶
func (r *RepoScreen) Init() tea.Cmd
func (*RepoScreen) View ¶
func (r *RepoScreen) View(width, height int) string
type Screen ¶
type Screen interface {
Init() tea.Cmd
Update(msg tea.Msg) (Screen, tea.Cmd)
View(width, height int) string
// the live keymap -- never hardcoded key labels.
Footer() []style.KeyHint
}
Screen is one entry in the app's navigation stack. Each screen owns its own key handling (including when to quit or emit a pop), since screens with a focused text input need to swallow most keystrokes.
type SearchScreen ¶
type SearchScreen struct {
// contains filtered or unexported fields
}
SearchScreen shows repo search results for one query, fired once when the screen is pushed (never per keystroke -- the search rate bucket is 30 req/min, see gh.SearchRepos). Enter pushes the selected repo.
func NewSearchScreen ¶
func NewSearchScreen(cfg config.Config, theme style.Theme, client *gh.Client, readmeStylePath, query string) *SearchScreen
NewSearchScreen builds the search-results screen for query.
func (*SearchScreen) Footer ¶
func (s *SearchScreen) Footer() []style.KeyHint
func (*SearchScreen) Init ¶
func (s *SearchScreen) Init() tea.Cmd
func (*SearchScreen) View ¶
func (s *SearchScreen) View(width, height int) string