mirror of
https://github.com/charmbracelet/gum.git
synced 2024-09-11 06:16:03 +03:00
feat: add timeout on confirm options & messages (#111)
Co-authored-by: Christoper Hans <4262799+ChrHan@users.noreply.github.com>
This commit is contained in:
parent
2afa42b603
commit
c1a1a73a0e
@ -17,6 +17,8 @@ func (o Options) Run() error {
|
||||
affirmative: o.Affirmative,
|
||||
negative: o.Negative,
|
||||
confirmation: o.Default,
|
||||
timeout: o.Timeout,
|
||||
hasTimeout: o.Timeout > 0,
|
||||
prompt: o.Prompt,
|
||||
selectedStyle: o.SelectedStyle.ToLipgloss(),
|
||||
unselectedStyle: o.UnselectedStyle.ToLipgloss(),
|
||||
|
@ -11,6 +11,9 @@
|
||||
package confirm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
"github.com/charmbracelet/lipgloss"
|
||||
)
|
||||
@ -20,6 +23,8 @@ type model struct {
|
||||
affirmative string
|
||||
negative string
|
||||
quitting bool
|
||||
hasTimeout bool
|
||||
timeout time.Duration
|
||||
|
||||
confirmation bool
|
||||
|
||||
@ -29,7 +34,22 @@ type model struct {
|
||||
unselectedStyle lipgloss.Style
|
||||
}
|
||||
|
||||
func (m model) Init() tea.Cmd { return nil }
|
||||
const tickInterval = time.Second
|
||||
|
||||
type tickMsg struct{}
|
||||
|
||||
func tick() tea.Cmd {
|
||||
return tea.Tick(tickInterval, func(time.Time) tea.Msg {
|
||||
return tickMsg{}
|
||||
})
|
||||
}
|
||||
|
||||
func (m model) Init() tea.Cmd {
|
||||
if m.timeout > 0 {
|
||||
return tick()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
switch msg := msg.(type) {
|
||||
@ -37,6 +57,10 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
return m, nil
|
||||
case tea.KeyMsg:
|
||||
switch msg.String() {
|
||||
case "ctrl+c", "esc", "q", "n", "N":
|
||||
m.confirmation = false
|
||||
m.quitting = true
|
||||
return m, tea.Quit
|
||||
case "left", "h", "ctrl+p", "tab",
|
||||
"right", "l", "ctrl+n", "shift+tab":
|
||||
m.confirmation = !m.confirmation
|
||||
@ -47,11 +71,15 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
m.quitting = true
|
||||
m.confirmation = true
|
||||
return m, tea.Quit
|
||||
case "ctrl+c", "esc", "q", "n", "N":
|
||||
m.confirmation = false
|
||||
}
|
||||
case tickMsg:
|
||||
if m.timeout <= 0 {
|
||||
m.quitting = true
|
||||
m.confirmation = false
|
||||
return m, tea.Quit
|
||||
}
|
||||
m.timeout -= tickInterval
|
||||
return m, tick()
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
@ -61,15 +89,26 @@ func (m model) View() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
var aff, neg string
|
||||
var aff, neg, timeout string
|
||||
|
||||
if m.hasTimeout {
|
||||
timeout = fmt.Sprintf(" (%d)", max(0, int(m.timeout.Seconds())))
|
||||
}
|
||||
|
||||
if m.confirmation {
|
||||
aff = m.selectedStyle.Render(m.affirmative)
|
||||
neg = m.unselectedStyle.Render(m.negative)
|
||||
neg = m.unselectedStyle.Render(m.negative + timeout)
|
||||
} else {
|
||||
aff = m.unselectedStyle.Render(m.affirmative)
|
||||
neg = m.selectedStyle.Render(m.negative)
|
||||
neg = m.selectedStyle.Render(m.negative + timeout)
|
||||
}
|
||||
|
||||
return lipgloss.JoinVertical(lipgloss.Center, m.promptStyle.Render(m.prompt), lipgloss.JoinHorizontal(lipgloss.Left, aff, neg))
|
||||
}
|
||||
|
||||
func max(a, b int) int {
|
||||
if a > b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
@ -1,14 +1,19 @@
|
||||
package confirm
|
||||
|
||||
import "github.com/charmbracelet/gum/style"
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/charmbracelet/gum/style"
|
||||
)
|
||||
|
||||
// Options is the customization options for the confirm command.
|
||||
type Options struct {
|
||||
Affirmative string `help:"The title of the affirmative action" default:"Yes"`
|
||||
Negative string `help:"The title of the negative action" default:"No"`
|
||||
Default bool `help:"Default confirmation action" default:"true"`
|
||||
Prompt string `arg:"" help:"Prompt to display." default:"Are you sure?"`
|
||||
PromptStyle style.Styles `embed:"" prefix:"prompt." help:"The style of the prompt" set:"defaultMargin=1 0 0 0" envprefix:"GUM_CONFIRM_PROMPT_"`
|
||||
Affirmative string `help:"The title of the affirmative action" default:"Yes"`
|
||||
Negative string `help:"The title of the negative action" default:"No"`
|
||||
Default bool `help:"Default confirmation action" default:"true"`
|
||||
Timeout time.Duration `help:"Timeout for confirmation" default:"0" env:"GUM_CONFIRM_TIMEOUT"`
|
||||
Prompt string `arg:"" help:"Prompt to display." default:"Are you sure?"`
|
||||
PromptStyle style.Styles `embed:"" prefix:"prompt." help:"The style of the prompt" set:"defaultMargin=1 0 0 0" envprefix:"GUM_CONFIRM_PROMPT_"`
|
||||
//nolint:staticcheck
|
||||
SelectedStyle style.Styles `embed:"" prefix:"selected." help:"The style of the selected action" set:"defaultBackground=212" set:"defaultForeground=230" set:"defaultPadding=0 3" set:"defaultMargin=1 1" envprefix:"GUM_CONFIRM_SELECTED_"`
|
||||
//nolint:staticcheck
|
||||
|
Loading…
Reference in New Issue
Block a user