100 lines
2.1 KiB
Go
100 lines
2.1 KiB
Go
|
|
package tui
|
||
|
|
|
||
|
|
import (
|
||
|
|
"os"
|
||
|
|
|
||
|
|
tea "github.com/charmbracelet/bubbletea"
|
||
|
|
)
|
||
|
|
|
||
|
|
// ── Input View Handling ─────────────────────────────────────────────
|
||
|
|
|
||
|
|
func (a App) handleInputKey(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
|
||
|
|
key := msg.String()
|
||
|
|
|
||
|
|
switch key {
|
||
|
|
case "esc":
|
||
|
|
a.popView()
|
||
|
|
return a, nil
|
||
|
|
|
||
|
|
case "tab", "shift+tab":
|
||
|
|
// Cycle focus
|
||
|
|
if key == "tab" {
|
||
|
|
a.focusIdx = (a.focusIdx + 1) % len(a.inputs)
|
||
|
|
} else {
|
||
|
|
a.focusIdx = (a.focusIdx - 1 + len(a.inputs)) % len(a.inputs)
|
||
|
|
}
|
||
|
|
for i := range a.inputs {
|
||
|
|
if i == a.focusIdx {
|
||
|
|
a.inputs[i].Focus()
|
||
|
|
} else {
|
||
|
|
a.inputs[i].Blur()
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return a, nil
|
||
|
|
|
||
|
|
case "enter":
|
||
|
|
// If not on last field, advance
|
||
|
|
if a.focusIdx < len(a.inputs)-1 {
|
||
|
|
a.focusIdx++
|
||
|
|
for i := range a.inputs {
|
||
|
|
if i == a.focusIdx {
|
||
|
|
a.inputs[i].Focus()
|
||
|
|
} else {
|
||
|
|
a.inputs[i].Blur()
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return a, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// Submit
|
||
|
|
switch a.view {
|
||
|
|
case ViewUsersCreate:
|
||
|
|
return a.submitUserCreate()
|
||
|
|
case ViewUsersReset:
|
||
|
|
return a.submitUserReset()
|
||
|
|
case ViewSettingsEdit:
|
||
|
|
return a.saveSettings()
|
||
|
|
case ViewDNSZoneEdit:
|
||
|
|
return a.submitDNSZone()
|
||
|
|
}
|
||
|
|
return a, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// Forward key to focused input
|
||
|
|
if a.focusIdx >= 0 && a.focusIdx < len(a.inputs) {
|
||
|
|
var cmd tea.Cmd
|
||
|
|
a.inputs[a.focusIdx], cmd = a.inputs[a.focusIdx].Update(msg)
|
||
|
|
return a, cmd
|
||
|
|
}
|
||
|
|
|
||
|
|
return a, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (a App) updateInputs(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||
|
|
if a.focusIdx >= 0 && a.focusIdx < len(a.inputs) {
|
||
|
|
var cmd tea.Cmd
|
||
|
|
a.inputs[a.focusIdx], cmd = a.inputs[a.focusIdx].Update(msg)
|
||
|
|
return a, cmd
|
||
|
|
}
|
||
|
|
return a, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// ── File Helpers (used by multiple views) ────────────────────────────
|
||
|
|
|
||
|
|
func fileExists(path string) bool {
|
||
|
|
_, err := os.Stat(path)
|
||
|
|
return err == nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func readFileBytes(path string) ([]byte, error) {
|
||
|
|
return os.ReadFile(path)
|
||
|
|
}
|
||
|
|
|
||
|
|
func writeFile(path string, data []byte, perm os.FileMode) error {
|
||
|
|
return os.WriteFile(path, data, perm)
|
||
|
|
}
|
||
|
|
|
||
|
|
func renameFile(src, dst string) error {
|
||
|
|
return os.Rename(src, dst)
|
||
|
|
}
|