Merge branch 'feat/taskedit' into feat/time
This commit is contained in:
@ -8,6 +8,7 @@ import (
|
||||
"time"
|
||||
|
||||
"tasksquire/components/input"
|
||||
"tasksquire/components/picker"
|
||||
"tasksquire/components/timestampeditor"
|
||||
"tasksquire/taskwarrior"
|
||||
|
||||
@ -58,7 +59,7 @@ func NewTaskEditorPage(com *common.Common, task taskwarrior.Task) *TaskEditorPag
|
||||
tagOptions := p.common.TW.GetTags()
|
||||
|
||||
p.areas = []area{
|
||||
NewTaskEdit(p.common, &p.task),
|
||||
NewTaskEdit(p.common, &p.task, p.task.Uuid == ""),
|
||||
NewTagEdit(p.common, &p.task.Tags, tagOptions),
|
||||
NewTimeEdit(p.common, &p.task.Due, &p.task.Scheduled, &p.task.Wait, &p.task.Until),
|
||||
NewDetailsEdit(p.common, &p.task),
|
||||
@ -110,7 +111,11 @@ func (p *TaskEditorPage) SetSize(width, height int) {
|
||||
}
|
||||
|
||||
func (p *TaskEditorPage) Init() tea.Cmd {
|
||||
return nil
|
||||
var cmds []tea.Cmd
|
||||
for _, a := range p.areas {
|
||||
cmds = append(cmds, a.Init())
|
||||
}
|
||||
return tea.Batch(cmds...)
|
||||
}
|
||||
|
||||
func (p *TaskEditorPage) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
@ -257,9 +262,13 @@ func (p *TaskEditorPage) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
}
|
||||
return p, nil
|
||||
case key.Matches(msg, p.common.Keymap.Ok):
|
||||
isFiltering := p.areas[p.area].IsFiltering()
|
||||
model, cmd := p.areas[p.area].Update(msg)
|
||||
if p.area != 3 {
|
||||
p.areas[p.area] = model.(area)
|
||||
if isFiltering {
|
||||
return p, cmd
|
||||
}
|
||||
return p, tea.Batch(cmd, nextField())
|
||||
}
|
||||
return p, cmd
|
||||
@ -340,8 +349,11 @@ type area interface {
|
||||
tea.Model
|
||||
SetCursor(c int)
|
||||
GetName() string
|
||||
IsFiltering() bool
|
||||
}
|
||||
|
||||
type focusMsg struct{}
|
||||
|
||||
type areaPicker struct {
|
||||
common *common.Common
|
||||
list list.Model
|
||||
@ -413,26 +425,54 @@ func (a *areaPicker) View() string {
|
||||
return a.list.View()
|
||||
}
|
||||
|
||||
type EditableField interface {
|
||||
tea.Model
|
||||
Focus() tea.Cmd
|
||||
Blur() tea.Cmd
|
||||
}
|
||||
|
||||
type taskEdit struct {
|
||||
common *common.Common
|
||||
fields []huh.Field
|
||||
fields []EditableField
|
||||
cursor int
|
||||
|
||||
projectPicker *picker.Picker
|
||||
// newProjectName *string
|
||||
newAnnotation *string
|
||||
udaValues map[string]*string
|
||||
}
|
||||
|
||||
func NewTaskEdit(com *common.Common, task *taskwarrior.Task) *taskEdit {
|
||||
func NewTaskEdit(com *common.Common, task *taskwarrior.Task, isNew bool) *taskEdit {
|
||||
// newProject := ""
|
||||
projectOptions := append([]string{"(none)"}, com.TW.GetProjects()...)
|
||||
if task.Project == "" {
|
||||
task.Project = "(none)"
|
||||
}
|
||||
|
||||
itemProvider := func() []list.Item {
|
||||
projects := com.TW.GetProjects()
|
||||
items := []list.Item{picker.NewItem("(none)")}
|
||||
for _, proj := range projects {
|
||||
items = append(items, picker.NewItem(proj))
|
||||
}
|
||||
return items
|
||||
}
|
||||
onSelect := func(item list.Item) tea.Cmd {
|
||||
return nil
|
||||
}
|
||||
|
||||
opts := []picker.PickerOption{}
|
||||
if isNew {
|
||||
opts = append(opts, picker.WithFilterByDefault(true))
|
||||
}
|
||||
|
||||
projPicker := picker.New(com, "Project", itemProvider, onSelect, opts...)
|
||||
projPicker.SetSize(70, 8)
|
||||
projPicker.SelectItemByFilterValue(task.Project)
|
||||
projPicker.Blur()
|
||||
|
||||
defaultKeymap := huh.NewDefaultKeyMap()
|
||||
|
||||
fields := []huh.Field{
|
||||
fields := []EditableField{
|
||||
huh.NewInput().
|
||||
Title("Task").
|
||||
Value(&task.Description).
|
||||
@ -446,12 +486,7 @@ func NewTaskEdit(com *common.Common, task *taskwarrior.Task) *taskEdit {
|
||||
Prompt(": ").
|
||||
WithTheme(com.Styles.Form),
|
||||
|
||||
input.NewSelect(com).
|
||||
Options(true, input.NewOptions(projectOptions...)...).
|
||||
Title("Project").
|
||||
Value(&task.Project).
|
||||
WithKeyMap(defaultKeymap).
|
||||
WithTheme(com.Styles.Form),
|
||||
projPicker,
|
||||
|
||||
// huh.NewInput().
|
||||
// Title("New Project").
|
||||
@ -544,8 +579,9 @@ func NewTaskEdit(com *common.Common, task *taskwarrior.Task) *taskEdit {
|
||||
WithTheme(com.Styles.Form))
|
||||
|
||||
t := taskEdit{
|
||||
common: com,
|
||||
fields: fields,
|
||||
common: com,
|
||||
fields: fields,
|
||||
projectPicker: projPicker,
|
||||
|
||||
udaValues: udaValues,
|
||||
|
||||
@ -562,6 +598,13 @@ func (t *taskEdit) GetName() string {
|
||||
return "Task"
|
||||
}
|
||||
|
||||
func (t *taskEdit) IsFiltering() bool {
|
||||
if f, ok := t.fields[t.cursor].(interface{ IsFiltering() bool }); ok {
|
||||
return f.IsFiltering()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (t *taskEdit) SetCursor(c int) {
|
||||
t.fields[t.cursor].Blur()
|
||||
if c < 0 {
|
||||
@ -573,11 +616,25 @@ func (t *taskEdit) SetCursor(c int) {
|
||||
}
|
||||
|
||||
func (t *taskEdit) Init() tea.Cmd {
|
||||
return nil
|
||||
var cmds []tea.Cmd
|
||||
// Ensure focus on the active field (especially for the first one)
|
||||
if len(t.fields) > 0 {
|
||||
cmds = append(cmds, func() tea.Msg {
|
||||
return focusMsg{}
|
||||
})
|
||||
}
|
||||
for _, f := range t.fields {
|
||||
cmds = append(cmds, f.Init())
|
||||
}
|
||||
return tea.Batch(cmds...)
|
||||
}
|
||||
|
||||
func (t *taskEdit) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
switch msg.(type) {
|
||||
case focusMsg:
|
||||
if len(t.fields) > 0 {
|
||||
return t, t.fields[t.cursor].Focus()
|
||||
}
|
||||
case nextFieldMsg:
|
||||
if t.cursor == len(t.fields)-1 {
|
||||
t.fields[t.cursor].Blur()
|
||||
@ -596,7 +653,7 @@ func (t *taskEdit) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
t.fields[t.cursor].Focus()
|
||||
default:
|
||||
field, cmd := t.fields[t.cursor].Update(msg)
|
||||
t.fields[t.cursor] = field.(huh.Field)
|
||||
t.fields[t.cursor] = field.(EditableField)
|
||||
return t, cmd
|
||||
}
|
||||
|
||||
@ -659,6 +716,13 @@ func (t *tagEdit) GetName() string {
|
||||
return "Tags"
|
||||
}
|
||||
|
||||
func (t *tagEdit) IsFiltering() bool {
|
||||
if f, ok := t.fields[t.cursor].(interface{ IsFiltering() bool }); ok {
|
||||
return f.IsFiltering()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (t *tagEdit) SetCursor(c int) {
|
||||
t.fields[t.cursor].Blur()
|
||||
if c < 0 {
|
||||
@ -771,6 +835,10 @@ func (t *timeEdit) GetName() string {
|
||||
return "Dates"
|
||||
}
|
||||
|
||||
func (t *timeEdit) IsFiltering() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (t *timeEdit) SetCursor(c int) {
|
||||
if len(t.fields) == 0 {
|
||||
return
|
||||
@ -903,6 +971,10 @@ func (d *detailsEdit) GetName() string {
|
||||
return "Details"
|
||||
}
|
||||
|
||||
func (d *detailsEdit) IsFiltering() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (d *detailsEdit) SetCursor(c int) {
|
||||
}
|
||||
|
||||
@ -1070,6 +1142,8 @@ func (d *detailsEdit) View() string {
|
||||
// }
|
||||
|
||||
func (p *TaskEditorPage) updateTasksCmd() tea.Msg {
|
||||
p.task.Project = p.areas[0].(*taskEdit).projectPicker.GetValue()
|
||||
|
||||
if p.task.Project == "(none)" {
|
||||
p.task.Project = ""
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user