feat: :sparkles: Handle due date
Tim Izzo tim@octree.ch
Mon, 24 Mar 2025 22:00:36 +0100
M
main.go
→
main.go
@@ -48,7 +48,7 @@ log.Fatal(err)
return model{} } else { tasks := tasklist - tasks.Sort(todo.SortCompletedDateAsc, todo.SortPriorityAsc) + tasks.Sort(todo.SortCompletedDateAsc, todo.SortDueDateAsc, todo.SortPriorityAsc) selected := make(map[int]struct{}) interfaceState := List@@ -125,7 +125,7 @@ m.tasks[m.cursor].Complete()
} case key.Matches(msg, m.keys.Sort): - m.tasks.Sort(todo.SortCompletedDateAsc, todo.SortPriorityAsc) + m.tasks.Sort(todo.SortCompletedDateAsc, todo.SortDueDateAsc, todo.SortPriorityAsc) m.selected = make(map[int]struct{}) for i, t := range m.tasks { if t.Completed {
M
style.go
→
style.go
@@ -10,11 +10,15 @@
catppuccin "github.com/catppuccin/go" ) +var DATETIME_FORMAT = "02-01-2006 15:03" +var DATE_FORMAT = "02-01-2006" + var Catppuccin catppuccin.Flavor = catppuccin.Mocha type Style struct { Task TaskStyle Priority PriorityStyle + Date DateStyle Check lipgloss.Style Context lipgloss.Style Project lipgloss.Style@@ -32,6 +36,13 @@ B lipgloss.Style
C lipgloss.Style } +type DateStyle struct { + done lipgloss.Style + today lipgloss.Style + overdue lipgloss.Style + futur lipgloss.Style +} + func NewTextStyle() Style { taskStyle := TaskStyle{@@ -45,9 +56,18 @@ B: lipgloss.NewStyle().Foreground(lipgloss.Color(Catppuccin.Peach().Hex)),
C: lipgloss.NewStyle().Foreground(lipgloss.Color(Catppuccin.Green().Hex)), } + dateBaseStyle := lipgloss.NewStyle() + dateStyle := DateStyle{ + done: dateBaseStyle.Foreground(lipgloss.Color(Catppuccin.Overlay0().Hex)), + today: dateBaseStyle.Foreground(lipgloss.Color(Catppuccin.Crust().Hex)).Background(lipgloss.Color(Catppuccin.Blue().Hex)), + overdue: dateBaseStyle.Foreground(lipgloss.Color(Catppuccin.Crust().Hex)).Background(lipgloss.Color(Catppuccin.Red().Hex)), + futur: dateBaseStyle.Foreground(lipgloss.Color(Catppuccin.Blue().Hex)), + } + style := Style{ Priority: priorityStyle, Task: taskStyle, + Date: dateStyle, Check: lipgloss.NewStyle().Foreground(lipgloss.Color(Catppuccin.Blue().Hex)), Context: lipgloss.NewStyle().Foreground(lipgloss.Color(Catppuccin.Blue().Hex)), Project: lipgloss.NewStyle().Foreground(lipgloss.Color(Catppuccin.Mauve().Hex)),@@ -64,10 +84,12 @@ checkedRegex := regexp.MustCompile(`^x (\d{4}-\d{2}-\d{2} )? ?`)
priorityRegex := regexp.MustCompile(`^\([A-Z]\) `) contextRegex := regexp.MustCompile(`@\w+`) projectRegex := regexp.MustCompile(`\+\w+`) + dueDateRegex := regexp.MustCompile(`due:\d{4}-\d{2}-\d{2}`) keyValueRegex := regexp.MustCompile(`\w+:.+`) todoText = checkedRegex.ReplaceAllString(todoText, "") todoText = priorityRegex.ReplaceAllString(todoText, "") + todoText = dueDateRegex.ReplaceAllString(todoText, "") checkString := " " if checked {@@ -76,8 +98,7 @@ }
switch task.Completed { case true: - dateStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("#6c7086")) - dateString := dateStyle.Render(task.CompletedDate.Local().Format("02-01-2006 15:03")) + dateString := s.Date.done.Render(task.CompletedDate.Local().Format(DATETIME_FORMAT)) return fmt.Sprintf("%s %s %s %s", s.Check.Render(checkString), s.getPriorityStyle(task.Priority), s.Task.Completed.Render(todoText), dateString) default: todoText = contextRegex.ReplaceAllStringFunc(todoText, func(match string) string {@@ -89,7 +110,19 @@ })
todoText = keyValueRegex.ReplaceAllStringFunc(todoText, func(match string) string { return s.KeyValue.Render(match) }) - return fmt.Sprintf("%s %s %s", s.Check.Render(checkString), s.getPriorityStyle(task.Priority), s.Task.Todo.Render(todoText)) + var dueDateString string + if task.HasDueDate() { + formatedDueDate := task.DueDate.Format(DATE_FORMAT) + switch { + case task.IsDueToday(): + dueDateString = s.Date.today.Render(formatedDueDate) + case task.IsOverdue(): + dueDateString = s.Date.overdue.Render(formatedDueDate) + default: + dueDateString = s.Date.futur.Render(formatedDueDate) + } + } + return fmt.Sprintf("%s %s %s %s", s.Check.Render(checkString), s.getPriorityStyle(task.Priority), s.Task.Todo.Render(todoText), dueDateString) } }