working on tui
This commit is contained in:
+102
-29
@@ -13,10 +13,14 @@ import (
|
||||
|
||||
const (
|
||||
fieldInputDir = iota
|
||||
fieldOutputDir
|
||||
fieldOutputFile
|
||||
fieldAppend
|
||||
fieldForce
|
||||
fieldVerticalSlices
|
||||
fieldSkipFrontend
|
||||
fieldFrontendOnly
|
||||
fieldOmitTest
|
||||
fieldOmitMd
|
||||
fieldProtonDrive
|
||||
fieldDrivePath
|
||||
fieldMaxDepth
|
||||
@@ -30,15 +34,20 @@ const (
|
||||
type FormModel struct {
|
||||
focusIndex int
|
||||
inputDir textinput.Model
|
||||
outputDir textinput.Model
|
||||
outputFile textinput.Model
|
||||
drivePath textinput.Model
|
||||
maxDepth textinput.Model
|
||||
maxSize textinput.Model
|
||||
ignoreArea textarea.Model
|
||||
appendMode Checkbox
|
||||
force Checkbox
|
||||
verticalSlices Checkbox
|
||||
skipFrontend Checkbox
|
||||
frontendOnly Checkbox
|
||||
omitTest Checkbox
|
||||
omitMd Checkbox
|
||||
protonDrive Checkbox
|
||||
isDark bool
|
||||
width int
|
||||
height int
|
||||
err string
|
||||
@@ -50,10 +59,10 @@ func NewForm() FormModel {
|
||||
inputDir.SetValue(".")
|
||||
inputDir.SetWidth(40)
|
||||
|
||||
outputDir := textinput.New()
|
||||
outputDir.Placeholder = "./dirmd_output"
|
||||
outputDir.SetValue("./dirmd_output")
|
||||
outputDir.SetWidth(40)
|
||||
outputFile := textinput.New()
|
||||
outputFile.Placeholder = "./output.md"
|
||||
outputFile.SetValue("./output.md")
|
||||
outputFile.SetWidth(40)
|
||||
|
||||
drivePath := textinput.New()
|
||||
drivePath.Placeholder = "/my-files/md/"
|
||||
@@ -74,44 +83,74 @@ func NewForm() FormModel {
|
||||
|
||||
m := FormModel{
|
||||
inputDir: inputDir,
|
||||
outputDir: outputDir,
|
||||
outputFile: outputFile,
|
||||
drivePath: drivePath,
|
||||
maxDepth: maxDepth,
|
||||
maxSize: maxSize,
|
||||
ignoreArea: ignoreArea,
|
||||
appendMode: Checkbox{Label: "Append to existing file"},
|
||||
force: Checkbox{Label: "Force overwrite"},
|
||||
verticalSlices: Checkbox{Label: "Vertical slices"},
|
||||
skipFrontend: Checkbox{Label: "Skip frontend files"},
|
||||
frontendOnly: Checkbox{Label: "Frontend only"},
|
||||
omitTest: Checkbox{Label: "Omit test files"},
|
||||
omitMd: Checkbox{Label: "Omit non-README markdown"},
|
||||
protonDrive: Checkbox{Label: "Proton Drive upload"},
|
||||
focusIndex: fieldInputDir,
|
||||
isDark: true,
|
||||
}
|
||||
|
||||
m.applyStyles()
|
||||
m.focusActiveField()
|
||||
return m
|
||||
}
|
||||
|
||||
func (m *FormModel) focusActiveField() {
|
||||
func (m *FormModel) SetDark(isDark bool) {
|
||||
if m.isDark == isDark {
|
||||
return
|
||||
}
|
||||
m.isDark = isDark
|
||||
m.applyStyles()
|
||||
}
|
||||
|
||||
func (m *FormModel) applyStyles() {
|
||||
tiStyles := textinput.DefaultStyles(m.isDark)
|
||||
m.inputDir.SetStyles(tiStyles)
|
||||
m.outputFile.SetStyles(tiStyles)
|
||||
m.drivePath.SetStyles(tiStyles)
|
||||
m.maxDepth.SetStyles(tiStyles)
|
||||
m.maxSize.SetStyles(tiStyles)
|
||||
|
||||
taStyles := textarea.DefaultStyles(m.isDark)
|
||||
m.ignoreArea.SetStyles(taStyles)
|
||||
}
|
||||
|
||||
func (m *FormModel) focusActiveField() tea.Cmd {
|
||||
m.inputDir.Blur()
|
||||
m.outputDir.Blur()
|
||||
m.outputFile.Blur()
|
||||
m.drivePath.Blur()
|
||||
m.maxDepth.Blur()
|
||||
m.maxSize.Blur()
|
||||
m.ignoreArea.Blur()
|
||||
|
||||
var cmd tea.Cmd
|
||||
|
||||
switch m.focusIndex {
|
||||
case fieldInputDir:
|
||||
m.inputDir.Focus()
|
||||
case fieldOutputDir:
|
||||
m.outputDir.Focus()
|
||||
cmd = m.inputDir.Focus()
|
||||
case fieldOutputFile:
|
||||
cmd = m.outputFile.Focus()
|
||||
case fieldDrivePath:
|
||||
m.drivePath.Focus()
|
||||
cmd = m.drivePath.Focus()
|
||||
case fieldMaxDepth:
|
||||
m.maxDepth.Focus()
|
||||
cmd = m.maxDepth.Focus()
|
||||
case fieldMaxSize:
|
||||
m.maxSize.Focus()
|
||||
cmd = m.maxSize.Focus()
|
||||
case fieldIgnorePatterns:
|
||||
m.ignoreArea.Focus()
|
||||
cmd = m.ignoreArea.Focus()
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func (m FormModel) Update(msg tea.Msg) (FormModel, tea.Cmd) {
|
||||
@@ -125,10 +164,13 @@ func (m FormModel) Update(msg tea.Msg) (FormModel, tea.Cmd) {
|
||||
m.focusIndex = 0
|
||||
}
|
||||
if m.focusIndex == fieldDrivePath && !m.protonDrive.Checked {
|
||||
m.focusIndex = fieldMaxDepth
|
||||
m.focusIndex = fieldProtonDrive
|
||||
}
|
||||
m.focusActiveField()
|
||||
return m, nil
|
||||
cmd := m.focusActiveField()
|
||||
if cmd != nil {
|
||||
cmds = append(cmds, cmd)
|
||||
}
|
||||
return m, tea.Batch(cmds...)
|
||||
case isNavigateUp(k):
|
||||
m.focusIndex--
|
||||
if m.focusIndex < 0 {
|
||||
@@ -137,16 +179,27 @@ func (m FormModel) Update(msg tea.Msg) (FormModel, tea.Cmd) {
|
||||
if m.focusIndex == fieldDrivePath && !m.protonDrive.Checked {
|
||||
m.focusIndex = fieldProtonDrive
|
||||
}
|
||||
m.focusActiveField()
|
||||
return m, nil
|
||||
cmd := m.focusActiveField()
|
||||
if cmd != nil {
|
||||
cmds = append(cmds, cmd)
|
||||
}
|
||||
return m, tea.Batch(cmds...)
|
||||
case isActivate(k):
|
||||
switch m.focusIndex {
|
||||
case fieldAppend:
|
||||
m.appendMode.Toggle()
|
||||
case fieldForce:
|
||||
m.force.Toggle()
|
||||
case fieldVerticalSlices:
|
||||
m.verticalSlices.Toggle()
|
||||
case fieldSkipFrontend:
|
||||
m.skipFrontend.Toggle()
|
||||
case fieldFrontendOnly:
|
||||
m.frontendOnly.Toggle()
|
||||
case fieldOmitTest:
|
||||
m.omitTest.Toggle()
|
||||
case fieldOmitMd:
|
||||
m.omitMd.Toggle()
|
||||
case fieldProtonDrive:
|
||||
m.protonDrive.Toggle()
|
||||
case fieldGenerateBtn:
|
||||
@@ -163,9 +216,9 @@ func (m FormModel) Update(msg tea.Msg) (FormModel, tea.Cmd) {
|
||||
var cmd tea.Cmd
|
||||
m.inputDir, cmd = m.inputDir.Update(msg)
|
||||
cmds = append(cmds, cmd)
|
||||
case fieldOutputDir:
|
||||
case fieldOutputFile:
|
||||
var cmd tea.Cmd
|
||||
m.outputDir, cmd = m.outputDir.Update(msg)
|
||||
m.outputFile, cmd = m.outputFile.Update(msg)
|
||||
cmds = append(cmds, cmd)
|
||||
case fieldDrivePath:
|
||||
var cmd tea.Cmd
|
||||
@@ -196,15 +249,23 @@ func (m FormModel) View() string {
|
||||
|
||||
b.WriteString(m.renderTextField("Input directory", m.inputDir, m.focusIndex == fieldInputDir))
|
||||
b.WriteString("\n")
|
||||
b.WriteString(m.renderTextField("Output directory", m.outputDir, m.focusIndex == fieldOutputDir))
|
||||
b.WriteString(m.renderTextField("Output file", m.outputFile, m.focusIndex == fieldOutputFile))
|
||||
b.WriteString("\n\n")
|
||||
|
||||
b.WriteString(m.appendMode.Render(m.focusIndex == fieldAppend))
|
||||
b.WriteString("\n")
|
||||
b.WriteString(m.force.Render(m.focusIndex == fieldForce))
|
||||
b.WriteString("\n")
|
||||
b.WriteString(m.verticalSlices.Render(m.focusIndex == fieldVerticalSlices))
|
||||
b.WriteString("\n")
|
||||
b.WriteString(m.skipFrontend.Render(m.focusIndex == fieldSkipFrontend))
|
||||
b.WriteString("\n")
|
||||
b.WriteString(m.frontendOnly.Render(m.focusIndex == fieldFrontendOnly))
|
||||
b.WriteString("\n")
|
||||
b.WriteString(m.omitTest.Render(m.focusIndex == fieldOmitTest))
|
||||
b.WriteString("\n")
|
||||
b.WriteString(m.omitMd.Render(m.focusIndex == fieldOmitMd))
|
||||
b.WriteString("\n")
|
||||
b.WriteString(m.protonDrive.Render(m.focusIndex == fieldProtonDrive))
|
||||
b.WriteString("\n")
|
||||
|
||||
@@ -275,9 +336,9 @@ func (m FormModel) ToConfig() (*config.Config, error) {
|
||||
inputDir = "."
|
||||
}
|
||||
|
||||
outputDir := m.outputDir.Value()
|
||||
if outputDir == "" {
|
||||
return nil, fmt.Errorf("output directory required")
|
||||
outputFile := m.outputFile.Value()
|
||||
if outputFile == "" {
|
||||
return nil, fmt.Errorf("output file required")
|
||||
}
|
||||
|
||||
maxDepth, err := parseIntDefault(m.maxDepth.Value(), 20)
|
||||
@@ -301,6 +362,14 @@ func (m FormModel) ToConfig() (*config.Config, error) {
|
||||
}
|
||||
}
|
||||
|
||||
if m.skipFrontend.Checked && m.frontendOnly.Checked {
|
||||
return nil, fmt.Errorf("--skip-frontend and --frontend-only are mutually exclusive")
|
||||
}
|
||||
|
||||
if m.appendMode.Checked && m.verticalSlices.Checked {
|
||||
return nil, fmt.Errorf("--append and --vertical-slices are mutually exclusive")
|
||||
}
|
||||
|
||||
excludedExts := append([]string{}, config.DefaultExts...)
|
||||
if m.skipFrontend.Checked {
|
||||
excludedExts = append(excludedExts, config.FrontendExts...)
|
||||
@@ -311,7 +380,8 @@ func (m FormModel) ToConfig() (*config.Config, error) {
|
||||
|
||||
cfg := &config.Config{
|
||||
InputPath: inputDir,
|
||||
OutputPath: outputDir,
|
||||
OutputPath: outputFile,
|
||||
AppendMode: m.appendMode.Checked,
|
||||
Force: m.force.Checked,
|
||||
MaxSize: int64(maxSizeKB) * 1024,
|
||||
MaxDepth: maxDepth,
|
||||
@@ -321,6 +391,9 @@ func (m FormModel) ToConfig() (*config.Config, error) {
|
||||
DrivePath: m.drivePath.Value(),
|
||||
VerticalSlices: m.verticalSlices.Checked,
|
||||
SkipFrontend: m.skipFrontend.Checked,
|
||||
FrontendOnly: m.frontendOnly.Checked,
|
||||
OmitTest: m.omitTest.Checked,
|
||||
OmitMd: m.omitMd.Checked,
|
||||
}
|
||||
|
||||
return cfg, nil
|
||||
@@ -341,7 +414,7 @@ func (m *FormModel) SetSize(w, h int) {
|
||||
usable = 60
|
||||
}
|
||||
m.inputDir.SetWidth(usable)
|
||||
m.outputDir.SetWidth(usable)
|
||||
m.outputFile.SetWidth(usable)
|
||||
m.drivePath.SetWidth(usable)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user