resolve.go

 1package screens
 2
 3import (
 4	"charm.land/bubbles/v2/key"
 5	tea "charm.land/bubbletea/v2"
 6
 7	"git.secluded.site/keld/internal/ui"
 8)
 9
10// ResolveFunc is called by the resolve screen to build the next set
11// of screens based on the selections made so far. It returns the
12// screens to append to the session, or nil if no additional screens
13// are needed (the session will complete immediately).
14type ResolveFunc func() []ui.Screen
15
16// resolvedMsg carries the result of an async resolve.
17type resolvedMsg struct {
18	screens []ui.Screen
19}
20
21// Resolve is a transparent Screen adapter that sits between the
22// menu/preset screens and the command-specific screens. It calls an
23// injected function to build the next screens, extends the session
24// via [ui.ExtendMsg], and immediately advances via [ui.DoneCmd].
25//
26// The user never sees this screen — it completes within a single
27// Update cycle.
28type Resolve struct {
29	fn ResolveFunc
30}
31
32// NewResolve creates a resolve screen with the given builder function.
33func NewResolve(fn ResolveFunc) *Resolve {
34	return &Resolve{fn: fn}
35}
36
37// Init triggers the async resolve.
38func (r *Resolve) Init() tea.Cmd {
39	return func() tea.Msg {
40		screens := r.fn()
41		return resolvedMsg{screens: screens}
42	}
43}
44
45// Update handles the resolve result.
46func (r *Resolve) Update(msg tea.Msg) (ui.Screen, tea.Cmd) {
47	switch msg := msg.(type) {
48	case resolvedMsg:
49		if len(msg.screens) == 0 {
50			return r, ui.DoneCmd
51		}
52		return r, tea.Sequence(
53			func() tea.Msg { return ui.ExtendMsg{Screens: msg.screens} },
54			ui.DoneCmd,
55		)
56	case tea.KeyPressMsg:
57		if msg.Code == tea.KeyEscape {
58			return r, ui.BackCmd
59		}
60	}
61	return r, nil
62}
63
64// View is intentionally empty — this screen should not be visible.
65func (r *Resolve) View() string { return "" }
66
67// Title returns empty — this screen has no visible title.
68func (r *Resolve) Title() string { return "" }
69
70// KeyBindings returns no bindings.
71func (r *Resolve) KeyBindings() []key.Binding { return nil }
72
73// Selection returns empty — this screen has no user-visible selection.
74func (r *Resolve) Selection() string { return "" }