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 "" }