Add basic terminal user interface

This commit is contained in:
Olli 2025-10-16 07:59:16 +02:00
commit 5956331a28
9 changed files with 878 additions and 0 deletions

115
tui/modal.go Normal file
View file

@ -0,0 +1,115 @@
package tui
import (
"github.com/rivo/tview"
"suruatoel.xyz/timefiles/lib"
)
type ProActModal struct {
*tview.Flex
app *TUI
projectInput *tview.InputField
activityInput *tview.InputField
form *tview.Form
closeFunc func(project string, activity string, success bool)
}
func NewProActModal(app *TUI, title string) *ProActModal {
modal := ProActModal{
Flex: tview.NewFlex(),
app: app,
}
modal.projectInput = tview.NewInputField().SetLabel("Project:")
modal.activityInput = tview.NewInputField().SetLabel("Activity: ")
modal.form = tview.NewForm().
AddFormItem(modal.projectInput).
AddFormItem(modal.activityInput).
AddButton("set", func() {
if modal.closeFunc != nil {
modal.closeFunc(modal.projectInput.GetText(), modal.activityInput.GetText(), true)
}
}).
AddButton("cancel", func() {
if modal.closeFunc != nil {
modal.closeFunc(modal.projectInput.GetText(), modal.activityInput.GetText(), false)
}
}).
SetCancelFunc(func() {
if modal.closeFunc != nil {
modal.closeFunc(modal.projectInput.GetText(), modal.activityInput.GetText(), false)
}
})
modal.form.SetTitle(title).SetBorder(true).SetBorderPadding(0, 0, 0, 0)
modal.form.
SetButtonsAlign(tview.AlignCenter).
SetButtonBackgroundColor(tview.Styles.PrimitiveBackgroundColor).
SetButtonTextColor(tview.Styles.PrimaryTextColor).
SetBackgroundColor(tview.Styles.ContrastBackgroundColor)
inner := tview.NewFlex().
SetDirection(tview.FlexRow).
AddItem(modal.form, 0, 1, true)
width, height := 60, 7
modal.AddItem(nil, 0, 1, false).
AddItem(tview.NewFlex().SetDirection(tview.FlexRow).
AddItem(nil, 0, 1, false).
AddItem(inner, height, 1, true).
AddItem(nil, 0, 1, false), width, 1, true).
AddItem(nil, 0, 1, false)
modal.assignHandlers()
return &modal
}
func (modal *ProActModal) Focus(delegate func(p tview.Primitive)) {
modal.form.SetFocus(0)
delegate(modal.form)
}
func (modal *ProActModal) SetCloseFunc(closeFunc func(project string, activity string, success bool)) *ProActModal {
modal.closeFunc = closeFunc
return modal
}
func (modal *ProActModal) SetValues(project *lib.Project, activity *lib.Activity) {
projectTitle := ""
if project != nil {
projectTitle = project.Title
}
modal.form.GetFormItem(0).(*tview.InputField).SetText(projectTitle)
activityTitle := ""
if activity != nil {
activityTitle = activity.Title
}
modal.form.GetFormItem(1).(*tview.InputField).SetText(activityTitle)
}
func (modal *ProActModal) assignHandlers() {
modal.projectInput.SetAutocompleteFunc(func(currentText string) (entries []string) {
if len(currentText) == 0 {
return
}
for _, project := range modal.app.timeApp.SearchProjects(currentText) {
entries = append(entries, project.Title)
}
return
})
modal.activityInput.SetAutocompleteFunc(func(currentText string) (entries []string) {
project := modal.projectInput.GetText()
if project == "" || currentText == "" {
return
}
for _, activity := range modal.app.timeApp.SearchActivities(project, currentText) {
entries = append(entries, activity.Title)
}
return
})
}