bugfix: proper handling of timeouts and default selections

This commit is contained in:
Dieter Eickstaedt 2022-11-21 15:09:10 +01:00
parent d3a7325dc8
commit 65087b31ea
2 changed files with 46 additions and 24 deletions

View file

@ -19,32 +19,32 @@ func (o Options) Run() error {
var ( var (
options []string options []string
selectedOption selectionType selectedOption selectionType
theDefault bool
) )
// set options // set options
options = append(options, o.Affirmative) options = append(options, o.Affirmative)
if o.Negative != "" { options = append(options, o.Negative)
options = append(options, o.Negative) options = append(options, o.Canceled)
}
if o.Canceled != "" && o.WithCancel {
options = append(options, o.Canceled)
}
// what is default // what is default
theDefault = o.Default
if !o.Default && o.Negative != "" { if !o.Default && o.Negative != "" {
selectedOption = Negative selectedOption = Negative
} else { } else {
selectedOption = Confirmed selectedOption = Confirmed
theDefault = true
} }
m, err := tea.NewProgram(model{ m, err := tea.NewProgram(model{
options: options, options: options,
selectedOption: selectedOption, selectedOption: selectedOption,
timeout: o.Timeout, timeout: o.Timeout,
hasTimeout: o.Timeout > 0, hasTimeout: o.Timeout > 0,
prompt: o.Prompt, prompt: o.Prompt,
selectedStyle: o.SelectedStyle.ToLipgloss(), defaultSelection: theDefault,
unselectedStyle: o.UnselectedStyle.ToLipgloss(), selectedStyle: o.SelectedStyle.ToLipgloss(),
promptStyle: o.PromptStyle.ToLipgloss(), unselectedStyle: o.UnselectedStyle.ToLipgloss(),
promptStyle: o.PromptStyle.ToLipgloss(),
}, tea.WithOutput(os.Stderr)).Run() }, tea.WithOutput(os.Stderr)).Run()
if err != nil { if err != nil {
@ -57,7 +57,6 @@ func (o Options) Run() error {
case Negative: case Negative:
os.Exit(1) os.Exit(1)
case Cancel: case Cancel:
os.Exit(CtrlC) os.Exit(CtrlC)
} }

View file

@ -34,7 +34,8 @@ type model struct {
hasTimeout bool hasTimeout bool
timeout time.Duration timeout time.Duration
selectedOption selectionType selectedOption selectionType
defaultSelection bool
// styles // styles
promptStyle lipgloss.Style promptStyle lipgloss.Style
@ -60,16 +61,26 @@ func (m model) Init() tea.Cmd {
} }
func (m *model) NextOption() { func (m *model) NextOption() {
m.selectedOption++ for {
if (int)(m.selectedOption) >= len(m.options) { m.selectedOption++
m.selectedOption = 0 if (int)(m.selectedOption) >= len(m.options) {
m.selectedOption = 0
}
if m.options[m.selectedOption] != "" {
break
}
} }
} }
func (m *model) PrevOption() { func (m *model) PrevOption() {
m.selectedOption-- for {
if (int)(m.selectedOption) < 0 { m.selectedOption--
m.selectedOption = selectionType(len(m.options) - 1) if (int)(m.selectedOption) < 0 {
m.selectedOption = selectionType(len(m.options) - 1)
}
if m.options[m.selectedOption] != "" {
break
}
} }
} }
@ -104,7 +115,11 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
case tickMsg: case tickMsg:
if m.timeout <= 0 { if m.timeout <= 0 {
m.quitting = true m.quitting = true
m.selectedOption = Negative if !m.defaultSelection && m.options[Negative] != "" {
m.selectedOption = Negative
} else {
m.selectedOption = Confirmed
}
return m, tea.Quit return m, tea.Quit
} }
m.timeout -= tickInterval m.timeout -= tickInterval
@ -126,10 +141,18 @@ func (m model) View() string {
var renderedOptions []string var renderedOptions []string
for i, value := range m.options { for i, value := range m.options {
if m.options[i] == "" {
continue
}
if m.hasTimeout {
if (m.defaultSelection && i == (int)(Confirmed)) || (!m.defaultSelection && i == (int)(Negative)) {
value = value + timeout
}
}
if (int)(m.selectedOption) == i { if (int)(m.selectedOption) == i {
renderedOptions = append(renderedOptions, m.selectedStyle.Render(value)) renderedOptions = append(renderedOptions, m.selectedStyle.Render(value))
} else { } else {
renderedOptions = append(renderedOptions, m.unselectedStyle.Render(value+timeout)) renderedOptions = append(renderedOptions, m.unselectedStyle.Render(value))
} }
} }