add tui
This commit is contained in:
@@ -0,0 +1,165 @@
|
||||
package tui
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"charm.land/bubbles/v2/textinput"
|
||||
tea "charm.land/bubbletea/v2"
|
||||
)
|
||||
|
||||
type State int
|
||||
|
||||
const (
|
||||
StateForm State = iota
|
||||
StateGenerating
|
||||
StateDone
|
||||
StateError
|
||||
)
|
||||
|
||||
type genResultMsg struct {
|
||||
result GenerateResult
|
||||
}
|
||||
|
||||
type spinnerState struct {
|
||||
frame int
|
||||
}
|
||||
|
||||
func (s *spinnerState) View() string {
|
||||
frames := []string{"⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"}
|
||||
return frames[s.frame%len(frames)]
|
||||
}
|
||||
|
||||
type Model struct {
|
||||
state State
|
||||
form FormModel
|
||||
result GenerateResult
|
||||
spinner spinnerState
|
||||
width int
|
||||
height int
|
||||
}
|
||||
|
||||
func New() Model {
|
||||
return Model{
|
||||
state: StateForm,
|
||||
form: NewForm(),
|
||||
}
|
||||
}
|
||||
|
||||
func (m Model) Init() tea.Cmd {
|
||||
return textinput.Blink
|
||||
}
|
||||
|
||||
func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
switch msg := msg.(type) {
|
||||
case tea.WindowSizeMsg:
|
||||
m.width = msg.Width
|
||||
m.height = msg.Height
|
||||
m.form.SetSize(msg.Width, msg.Height)
|
||||
return m, nil
|
||||
|
||||
case tea.KeyPressMsg:
|
||||
if isQuit(msg) && m.state != StateGenerating {
|
||||
return m, tea.Quit
|
||||
}
|
||||
|
||||
switch m.state {
|
||||
case StateForm:
|
||||
if isSubmit(msg) && m.form.focusIndex == fieldGenerateBtn {
|
||||
cfg, err := m.form.ToConfig()
|
||||
if err != nil {
|
||||
m.form.SetError(err.Error())
|
||||
return m, nil
|
||||
}
|
||||
m.state = StateGenerating
|
||||
return m, func() tea.Msg {
|
||||
return genResultMsg{result: Generate(cfg)}
|
||||
}
|
||||
}
|
||||
if isSubmit(msg) && m.form.focusIndex == fieldCancelBtn {
|
||||
return m, tea.Quit
|
||||
}
|
||||
var cmd tea.Cmd
|
||||
m.form, cmd = m.form.Update(msg)
|
||||
return m, cmd
|
||||
|
||||
case StateDone, StateError:
|
||||
return m, tea.Quit
|
||||
}
|
||||
|
||||
case genResultMsg:
|
||||
m.result = msg.result
|
||||
if m.result.Error != nil {
|
||||
m.state = StateError
|
||||
} else {
|
||||
m.state = StateDone
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
if m.state == StateForm {
|
||||
var cmd tea.Cmd
|
||||
m.form, cmd = m.form.Update(msg)
|
||||
return m, cmd
|
||||
}
|
||||
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (m Model) View() tea.View {
|
||||
var content string
|
||||
|
||||
switch m.state {
|
||||
case StateForm:
|
||||
content = m.form.View()
|
||||
case StateGenerating:
|
||||
content = m.renderGenerating()
|
||||
case StateDone:
|
||||
content = m.renderDone()
|
||||
case StateError:
|
||||
content = m.renderError()
|
||||
}
|
||||
|
||||
v := tea.NewView(content)
|
||||
v.AltScreen = true
|
||||
return v
|
||||
}
|
||||
|
||||
func (m Model) renderGenerating() string {
|
||||
var b strings.Builder
|
||||
b.WriteString(titleStyle.Render("dirmd"))
|
||||
b.WriteString("\n\n")
|
||||
b.WriteString(fmt.Sprintf(" %s Generating...\n", m.spinner.View()))
|
||||
b.WriteString("\n")
|
||||
b.WriteString(footerStyle.Render("Please wait."))
|
||||
return appBorder.Render(b.String())
|
||||
}
|
||||
|
||||
func (m Model) renderDone() string {
|
||||
var b strings.Builder
|
||||
b.WriteString(titleStyle.Render("dirmd"))
|
||||
b.WriteString("\n\n")
|
||||
b.WriteString(successStyle.Render("✓ Done"))
|
||||
b.WriteString("\n\n")
|
||||
for _, f := range m.result.Files {
|
||||
b.WriteString(fmt.Sprintf(" %s\n", f))
|
||||
}
|
||||
if m.result.Uploaded {
|
||||
b.WriteString(successStyle.Render("\n Uploaded to Proton Drive"))
|
||||
}
|
||||
b.WriteString("\n\n")
|
||||
b.WriteString(footerStyle.Render("Press any key to exit."))
|
||||
return appBorder.Render(b.String())
|
||||
}
|
||||
|
||||
func (m Model) renderError() string {
|
||||
var b strings.Builder
|
||||
b.WriteString(titleStyle.Render("dirmd"))
|
||||
b.WriteString("\n\n")
|
||||
b.WriteString(errorStyle.Render("✗ Error"))
|
||||
b.WriteString("\n\n")
|
||||
b.WriteString(fmt.Sprintf(" %s\n", m.result.Error.Error()))
|
||||
b.WriteString("\n")
|
||||
b.WriteString(footerStyle.Render("Press any key to exit."))
|
||||
return appBorder.Render(b.String())
|
||||
}
|
||||
Reference in New Issue
Block a user