From 98d2d041d6725e65243cbb010beed378f676d2e5 Mon Sep 17 00:00:00 2001 From: Martin Date: Sun, 9 Jun 2024 21:46:39 +0200 Subject: [PATCH] Add details editing --- pages/messaging.go | 17 ++++++- pages/report.go | 14 +++--- pages/taskEditor.go | 98 +++++++++++++++++++++++--------------- taskwarrior/models.go | 9 ++++ test/taskchampion.sqlite3 | Bin 225280 -> 245760 bytes 5 files changed, 92 insertions(+), 46 deletions(-) diff --git a/pages/messaging.go b/pages/messaging.go index fb705ae..289c0e5 100644 --- a/pages/messaging.go +++ b/pages/messaging.go @@ -1,6 +1,11 @@ package pages -import tea "github.com/charmbracelet/bubbletea" +import ( + "tasksquire/taskwarrior" + "time" + + tea "github.com/charmbracelet/bubbletea" +) type UpdatedTasksMsg struct{} @@ -67,3 +72,13 @@ func changeMode(mode mode) tea.Cmd { } type changeModeMsg mode + +type taskMsg taskwarrior.Tasks + +type tickMsg time.Time + +func doTick() tea.Cmd { + return tea.Tick(time.Second, func(t time.Time) tea.Msg { + return tickMsg(t) + }) +} diff --git a/pages/report.go b/pages/report.go index 5471c8d..a9d6b31 100644 --- a/pages/report.go +++ b/pages/report.go @@ -60,7 +60,7 @@ func (p *ReportPage) SetSize(width int, height int) { } func (p *ReportPage) Init() tea.Cmd { - return p.getTasks() + return tea.Batch(p.getTasks(), doTick()) } func (p *ReportPage) Update(msg tea.Msg) (tea.Model, tea.Cmd) { @@ -69,7 +69,11 @@ func (p *ReportPage) Update(msg tea.Msg) (tea.Model, tea.Cmd) { case tea.WindowSizeMsg: p.SetSize(msg.Width, msg.Height) // case BackMsg: - case TaskMsg: + case tickMsg: + cmds = append(cmds, p.getTasks()) + cmds = append(cmds, doTick()) + return p, tea.Batch(cmds...) + case taskMsg: p.tasks = taskwarrior.Tasks(msg) p.populateTaskTable(p.tasks) case UpdateReportMsg: @@ -99,7 +103,7 @@ func (p *ReportPage) Update(msg tea.Msg) (tea.Model, tea.Cmd) { p.common.PushPage(p) return p.subpage, nil case key.Matches(msg, p.common.Keymap.Add): - p.subpage = NewTaskEditorPage(p.common, taskwarrior.Task{}) + p.subpage = NewTaskEditorPage(p.common, taskwarrior.NewTask()) p.subpage.Init() p.common.PushPage(p) return p.subpage, nil @@ -212,8 +216,6 @@ func (p *ReportPage) getTasks() tea.Cmd { filters = append(filters, "project:"+p.activeProject) } tasks := p.common.TW.GetTasks(p.activeReport, filters...) - return TaskMsg(tasks) + return taskMsg(tasks) } } - -type TaskMsg taskwarrior.Tasks diff --git a/pages/taskEditor.go b/pages/taskEditor.go index 5581556..fba7185 100644 --- a/pages/taskEditor.go +++ b/pages/taskEditor.go @@ -11,9 +11,9 @@ import ( "github.com/charmbracelet/bubbles/key" "github.com/charmbracelet/bubbles/list" + "github.com/charmbracelet/bubbles/textarea" "github.com/charmbracelet/bubbles/viewport" tea "github.com/charmbracelet/bubbletea" - "github.com/charmbracelet/glamour" "github.com/charmbracelet/huh" "github.com/charmbracelet/lipgloss" ) @@ -215,8 +215,11 @@ func (p *TaskEditorPage) Update(msg tea.Msg) (tea.Model, tea.Cmd) { } case key.Matches(msg, p.common.Keymap.Ok): model, cmd := p.areas[p.area].Update(msg) - p.areas[p.area] = model.(area) - return p, tea.Batch(cmd, nextField()) + if p.area != 3 { + p.areas[p.area] = model.(area) + return p, tea.Batch(cmd, nextField()) + } + return p, cmd } } @@ -732,27 +735,38 @@ func (t *timeEdit) View() string { } type detailsEdit struct { - com *common.Common - renderer *glamour.TermRenderer - vp viewport.Model + com *common.Common + vp viewport.Model + ta textarea.Model + details string + // renderer *glamour.TermRenderer } func NewDetailsEdit(com *common.Common, task *taskwarrior.Task) *detailsEdit { - renderer, err := glamour.NewTermRenderer( - // glamour.WithStandardStyle("light"), - glamour.WithAutoStyle(), - glamour.WithWordWrap(40), - ) - if err != nil { - slog.Error(err.Error()) - return nil - } + // renderer, err := glamour.NewTermRenderer( + // // glamour.WithStandardStyle("light"), + // glamour.WithAutoStyle(), + // glamour.WithWordWrap(40), + // ) + // if err != nil { + // slog.Error(err.Error()) + // return nil + // } vp := viewport.New(40, 30) + ta := textarea.New() + ta.SetWidth(40) + ta.SetHeight(30) + ta.ShowLineNumbers = false + ta.Focus() + if task.Udas["details"] != nil { + ta.SetValue(task.Udas["details"].(string)) + } d := detailsEdit{ - com: com, - renderer: renderer, - vp: vp, + com: com, + // renderer: renderer, + vp: vp, + ta: ta, } return &d @@ -762,7 +776,7 @@ func (d *detailsEdit) SetCursor(c int) { } func (d *detailsEdit) Init() tea.Cmd { - return nil + return textarea.Blink } func (d *detailsEdit) Update(msg tea.Msg) (tea.Model, tea.Cmd) { @@ -772,32 +786,34 @@ func (d *detailsEdit) Update(msg tea.Msg) (tea.Model, tea.Cmd) { case prevFieldMsg: return d, prevArea() default: - var cmd tea.Cmd - d.vp, cmd = d.vp.Update(msg) - return d, cmd + var vpCmd, taCmd tea.Cmd + d.vp, vpCmd = d.vp.Update(msg) + d.ta, taCmd = d.ta.Update(msg) + return d, tea.Batch(vpCmd, taCmd) } } func (d *detailsEdit) View() string { - dtls := ` - # Cool Details! - ## Things I need - - [ ] A thing - - [x] Done thing - - ## People - - pe1 - - pe2 - ` + return d.ta.View() + // dtls := ` + // # Cool Details! + // ## Things I need + // - [ ] A thing + // - [x] Done thing - details, err := d.renderer.Render(dtls) - if err != nil { - slog.Error(err.Error()) - return "Could not parse markdown" - } + // ## People + // - pe1 + // - pe2 + // ` - d.vp.SetContent(details) - return d.vp.View() + // details, err := d.renderer.Render(dtls) + // if err != nil { + // slog.Error(err.Error()) + // return "Could not parse markdown" + // } + + // d.vp.SetContent(details) + // return d.vp.View() } // func (p *TaskEditorPage) SetSize(width, height int) { @@ -956,6 +972,10 @@ func (p *TaskEditorPage) updateTasksCmd() tea.Msg { // p.common.TW.AddTaskAnnotation(p.task.Uuid, *p.areas[0].(*taskEdit).newAnnotation) } + if _, ok := p.task.Udas["details"]; ok || p.areas[3].(*detailsEdit).ta.Value() != "" { + p.task.Udas["details"] = p.areas[3].(*detailsEdit).ta.Value() + } + p.common.TW.ImportTask(&p.task) return UpdatedTasksMsg{} } diff --git a/taskwarrior/models.go b/taskwarrior/models.go index 7efd877..482f0a7 100644 --- a/taskwarrior/models.go +++ b/taskwarrior/models.go @@ -68,6 +68,15 @@ type Task struct { Udas map[string]any `json:"-"` } +// TODO: fix pointer receiver +func NewTask() Task { + return Task{ + Tags: make([]string, 0), + Depends: make([]string, 0), + Udas: make(map[string]any), + } +} + func (t *Task) GetString(fieldWFormat string) string { field, format, _ := strings.Cut(fieldWFormat, ".") diff --git a/test/taskchampion.sqlite3 b/test/taskchampion.sqlite3 index 8cd282e94ee5c3e8a908cbc72d375d4f4c9a7660..0195efd419f53f6720d8cc616997b052e05f93fe 100644 GIT binary patch delta 12352 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 E0Ht}5tpET3 delta 1001 zcmb7DT}V@57(VBF&;Pb_Hn*uWvw57#$c5Y7rjcHBRgq>tDNhOEZvu?r1R#x zmP|#I4p@$xPbvMWaNQYUbYzP0LKJBahdtVZ_+bRKT2<3H2S4V~PhUK#oIS4@V3lBs zZ;i>?qv1TZPy{M!WUz(8V#F^-oDtb{a?376{WU#$O%Hu>B$pqfB<2mpJz*!9H}Wgl zWvMiMlzvKn;UGW8kAX*5t!R$MmjFCsccON13lr_@zzGigbR|CJLLRN-xf{Qg!R_4J z(hzTq#~Rd?sz2h7g#3X(X(_(LfsbTv8QerNW1980hwd`U72sPYFy|Pr!XdRt{YQ2r zh)1(fI!=mU$LCyVDV~zRL3iVvH1u9btRKiGC8KzHn)c`pCpwA*v4(n1u(;Oq!l1DU zkcqD%P`v(7C=@6qG_mIPw$25G23Q;>V0-=U{RG?9(h$RyOHjU6v{}Y8Jb3laOmt)> zyMQv$S17r}JY#ASo^k=!%}+u=vC~(WRmsF5I-4n=PcY=rnCQTcU?di7443p%LtW&v zT&wRfv`o54C!;LnTmE2Ei}3VL(j0KG20yld4Ih)i%9fOtL_)uN7Zq^Q^RF`S3VM^AReYiS~OJsKUPDP^{jEJ2`kI^vOd$a<|Q6q&wBiv6z%973Xb$VP;@4EGe^mo{X_ zr(GzQ7-$*3%YoDM$6&CP2Zy<}E#A@=Z#VW;iN{QkHNQ-OC=7(l)NY;l;2y%~GSD-Y g{BJCSYkBx^!wO6_q;W~i*FkBme*a