package pages import ( "log/slog" "slices" "tasksquire/common" "tasksquire/taskwarrior" "github.com/charmbracelet/bubbles/key" tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/huh" ) type ContextPickerPage struct { common *common.Common contexts taskwarrior.Contexts form *huh.Form } func NewContextPickerPage(common *common.Common) *ContextPickerPage { p := &ContextPickerPage{ common: common, contexts: common.TW.GetContexts(), } selected := common.TW.GetActiveContext().Name options := make([]string, 0) for _, c := range p.contexts { if c.Name != "none" { options = append(options, c.Name) } } slices.Sort(options) options = append([]string{"(none)"}, options...) p.form = huh.NewForm( huh.NewGroup( huh.NewSelect[string](). Key("context"). Options(huh.NewOptions(options...)...). Title("Contexts"). Description("Choose a context"). Value(&selected), ), ). WithShowHelp(false). WithShowErrors(true). WithTheme(p.common.Styles.Form) return p } func (p *ContextPickerPage) SetSize(width, height int) { p.common.SetSize(width, height) } func (p *ContextPickerPage) Init() tea.Cmd { return p.form.Init() } func (p *ContextPickerPage) Update(msg tea.Msg) (tea.Model, tea.Cmd) { var cmds []tea.Cmd switch msg := msg.(type) { case tea.WindowSizeMsg: p.SetSize(msg.Width, msg.Height) case tea.KeyMsg: switch { case key.Matches(msg, p.common.Keymap.Back): model, err := p.common.PopPage() if err != nil { slog.Error("page stack empty") return nil, tea.Quit } return model, BackCmd } } f, cmd := p.form.Update(msg) if f, ok := f.(*huh.Form); ok { p.form = f cmds = append(cmds, cmd) } if p.form.State == huh.StateCompleted { cmds = append(cmds, p.updateContextCmd) model, err := p.common.PopPage() if err != nil { slog.Error("page stack empty") return nil, tea.Quit } return model, tea.Batch(cmds...) } return p, tea.Batch(cmds...) } func (p *ContextPickerPage) View() string { return p.common.Styles.Main.Render(p.form.View()) } func (p *ContextPickerPage) updateContextCmd() tea.Msg { context := p.form.GetString("context") if context == "(none)" { context = "" } return UpdateContextMsg(p.common.TW.GetContext(context)) } type UpdateContextMsg *taskwarrior.Context