diff options
| author | Paul Buetow <paul@buetow.org> | 2026-04-08 22:27:35 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-04-08 22:27:35 +0300 |
| commit | 7e786c4f755fe9ccb4537fc801dfd4470e10a473 (patch) | |
| tree | 4fd1db9a281c8bf7bfe4b9271b1b936b6dbd6e9f | |
| parent | 38b276bb3d5be12a63d9bab3fe927803e2c4315c (diff) | |
ui: split reload flow for task g
| -rw-r--r-- | internal/ui/table.go | 98 |
1 files changed, 62 insertions, 36 deletions
diff --git a/internal/ui/table.go b/internal/ui/table.go index aac685b..36078f4 100644 --- a/internal/ui/table.go +++ b/internal/ui/table.go @@ -220,6 +220,11 @@ type descriptionTempFile interface { Close() error } +type reloadData struct { + tasks []task.Task + ultraFilterIDs []int +} + // blinkInterval controls how quickly the row flashes when a task changes. // A shorter interval results in a faster blink. const blinkInterval = 150 * time.Millisecond @@ -428,70 +433,91 @@ func (m *Model) newTable(rows []atable.Row) (atable.Model, atable.Styles) { } func (m *Model) reload() error { + data, err := m.fetchTasks() + if err != nil { + return err + } + + m.processTasks(&data) + m.renderTasks(data) + return nil +} + +func (m *Model) fetchTasks() (reloadData, error) { // Always show only pending tasks by default. filters := append([]string(nil), m.filters...) filters = append(filters, "status:pending") - ultraFilterIDs := m.ultraFilteredTaskIDs() tasks, err := task.Export(filters...) if err != nil { - return err + return reloadData{}, err } task.SortTasks(tasks) + return reloadData{ + tasks: tasks, + ultraFilterIDs: m.ultraFilteredTaskIDs(), + }, nil +} - m.tasks = tasks - m.total = task.TotalTasks(tasks) - m.inProgress = task.InProgressTasks(tasks) - m.due = task.DueTasks(tasks, time.Now()) +func (m *Model) processTasks(data *reloadData) { + m.tasks = data.tasks + m.total = task.TotalTasks(data.tasks) + m.inProgress = task.InProgressTasks(data.tasks) + m.due = task.DueTasks(data.tasks, time.Now()) - // Refresh current task detail if in detail view if m.showTaskDetail { m.refreshCurrentTaskDetail() } m.computeColumnWidths() - var rows []atable.Row - m.searchMatches = nil - for i, tsk := range tasks { - rows = append(rows, m.taskToRowSearch(tsk, m.searchRegex, m.tblStyles, -1)) - if m.searchRegex != nil { - if m.searchRegex.MatchString(tsk.Project) { - m.searchMatches = append(m.searchMatches, cellMatch{row: i, col: 5}) - } - tags := strings.Join(tsk.Tags, " ") - if m.searchRegex.MatchString(tags) { - m.searchMatches = append(m.searchMatches, cellMatch{row: i, col: 6}) - } - if m.searchRegex.MatchString(tsk.Description) { - m.searchMatches = append(m.searchMatches, cellMatch{row: i, col: 8}) - } - for _, a := range tsk.Annotations { - if m.searchRegex.MatchString(a.Description) { - m.searchMatches = append(m.searchMatches, cellMatch{row: i, col: 7}) - break - } - } - } - } - if len(m.searchMatches) > 0 { - m.searchIndex = 0 - } if m.ultraSearchRegex != nil { m.ultraFiltered = m.ultraFilteredIndexes(m.ultraSearchRegex) } else { - m.rebuildUltraFiltered(ultraFilterIDs) + m.rebuildUltraFiltered(data.ultraFilterIDs) } +} +func (m *Model) renderTasks(data reloadData) { + rows := m.buildTaskRows(data.tasks) if m.tbl.Columns() == nil { m.tbl, m.tblStyles = m.newTable(rows) } else { m.tbl.SetRows(rows) - m.applyColumns() } m.reconcileUltraSelection() m.updateSelectionHighlight(-1, m.tbl.Cursor(), 0, m.tbl.ColumnCursor()) - return nil +} + +func (m *Model) buildTaskRows(tasks []task.Task) []atable.Row { + rows := make([]atable.Row, 0, len(tasks)) + m.searchMatches = nil + for i, tsk := range tasks { + rows = append(rows, m.taskToRowSearch(tsk, m.searchRegex, m.tblStyles, -1)) + if m.searchRegex == nil { + continue + } + if m.searchRegex.MatchString(tsk.Project) { + m.searchMatches = append(m.searchMatches, cellMatch{row: i, col: 5}) + } + tags := strings.Join(tsk.Tags, " ") + if m.searchRegex.MatchString(tags) { + m.searchMatches = append(m.searchMatches, cellMatch{row: i, col: 6}) + } + if m.searchRegex.MatchString(tsk.Description) { + m.searchMatches = append(m.searchMatches, cellMatch{row: i, col: 8}) + } + for _, a := range tsk.Annotations { + if m.searchRegex.MatchString(a.Description) { + m.searchMatches = append(m.searchMatches, cellMatch{row: i, col: 7}) + break + } + } + } + if len(m.searchMatches) > 0 { + m.searchIndex = 0 + } + return rows } func (m *Model) reloadAndReport() bool { |
