Documentation
¶
Overview ¶
Package activity demonstrates per-row in-flight state: the spinner and status label a row shows while something is working on it.
It talks to demoapi over HTTP — a real handler, a real client, real request boundaries — so the timings below are the server's, not a sleep in this file's goroutine.
Three reasons a row's state changes, all of which have to look right:
**You did it.** Press "a" and pick Sync. The row starts spinning before the POST has been answered, because the screen put its Selection() into action.Set.Targets and the shell broadcast the verb's Busy label against those keys. This screen writes one extra line to get that — Targets — and no wiring at all.
Mark several rows first ("x", or "A" for all of them) and one run drives all of them: one log event, one statusbar receipt, every marked row spinning. They finish together, because a run has one outcome — retiring them as each target lands is the refinement docs/activity.md decision 11 deferred until something needed it.
**Something else did it.** demoapi fires a scheduled sync every few seconds. Nobody pressed anything, so nothing was broadcast; the row spins because Options.ActivityWhen recognises "Syncing" in the data the poll brought back. A read-only dashboard gets this and needs no actions.
**It happened while nobody was looking.** Some of the server's work finishes between two polls, so the TUI never observes it running. Those rows flash "•" instead, driven by Options.ActivityRevision over a hidden column carrying the server's revision — the only way to notice a change the sampled data carries no other evidence of.
The case worth watching for ¶
Refresh is instant server-side: it is done long before the next poll. Press it and the row keeps spinning anyway, until the poll lands. That is not a lie about the work — it is the truth about what the TUI knows. The alternative, clearing the moment the request returns, shows a tick and then a cell reading exactly as it did before the user acted, which is indistinguishable from nothing having happened.
Sync is the opposite: the server takes four seconds, so the poll catches it and the local "syncing" hands over to the data's own "Syncing" mid-flight. The action itself returns earlier than that, having streamed the job's log into the console — so the handoff really is covering a gap.
What this screen does not contain ¶
No spinner. No ticker. No re-pushing rows per frame to animate anything. The rows are pushed once per poll and the indicator is drawn over them by the component.
Index ¶
- func New(t theme.Theme) screen.Screen
- type Screen
- func (s *Screen) Actions() action.Set
- func (s *Screen) Help() []key.Binding
- func (s *Screen) HelpSections() []help.Section
- func (s *Screen) Init() tea.Cmd
- func (s *Screen) IsCapturingKeys() bool
- func (s *Screen) Layout() layout.Node
- func (s *Screen) OnEnter(any) tea.Cmd
- func (s *Screen) SetTheme(t theme.Theme)
- func (s *Screen) Title() string
- func (s *Screen) Update(msg tea.Msg) (screen.Screen, tea.Cmd)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Screen ¶
type Screen struct {
// contains filtered or unexported fields
}
Screen is a table over demoapi, plus a poll. Everything about the indicators is declared in SetTheme and Actions; nothing here drives them.
func (*Screen) Actions ¶
Actions is this screen's whole contribution to the indicators it shows for work the user starts: Targets, and a Busy label per verb.