Skip to content

Commit

Permalink
feat(tui): Add bind 'sn' to schedule a task "now"
Browse files Browse the repository at this point in the history
  • Loading branch information
ja-he committed Jan 9, 2023
1 parent d4cc982 commit 5a79eda
Show file tree
Hide file tree
Showing 2 changed files with 142 additions and 0 deletions.
38 changes: 38 additions & 0 deletions internal/control/cli/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,41 @@ func NewController(
var backlogSetCurrentToBottommost func()
var getBacklogBottomScrollOffset func() int
var offsetCurrentTask func(tl []*model.Task, setToNext bool) bool
scheduleTask := func(when time.Time) {
if currentTask == nil {
return
}
scheduledTask := currentTask
prev, next, parentage, err := backlog.Pop(scheduledTask)
if err != nil {
log.Error().
Err(err).
Interface("task", currentTask).
Interface("backlog", backlog).
Msg("could not find task")
} else {
currentTask = func() *model.Task {
switch {
case prev != nil:
return prev
case next != nil:
return prev
case len(parentage) > 0:
return parentage[0]
default:
return nil
}
}()
namePrefix := ""
for _, parent := range parentage {
namePrefix = parent.Name + ": " + namePrefix
}
newEvents := scheduledTask.ToEvent(time.Now(), namePrefix)
for _, newEvent := range newEvents {
controller.data.GetCurrentDay().AddEvent(newEvent)
}
}
}
tasksInputTree, err := input.ConstructInputTree(
map[string]action.Action{
"<c-u>": action.NewSimple(func() string { return "scroll up" }, func() {
Expand Down Expand Up @@ -407,6 +442,9 @@ func NewController(
"G": action.NewSimple(func() string { return "scroll to bottom" }, func() {
backlogSetCurrentToBottommost()
}),
"sn": action.NewSimple(func() string { return "schedule now" }, func() {
scheduleTask(time.Now())
}),
"l": action.NewSimple(func() string { return "step into subtasks" }, func() {
if currentTask == nil {
return
Expand Down
104 changes: 104 additions & 0 deletions internal/model/backlog.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,110 @@ func BacklogFromReader(r io.Reader, categoryGetter func(string) Category) (*Back
return b, nil
}

// Pop the given task out from wherever it is in this backlog, returning
// that location (by surrounding tasks and parentage).
func (b *Backlog) Pop(task *Task) (prev *Task, next *Task, parentage []*Task, err error) {
var indexAmongTasks int
prev, next, parentage, indexAmongTasks, err = b.Locate(task)
if err != nil {
return
}
parentTasks := func() *[]*Task {
if len(parentage) > 0 {
return &parentage[0].Subtasks
} else {
return &b.Tasks
}
}()

b.Mtx.Lock()
defer b.Mtx.Unlock()
*parentTasks = append((*parentTasks)[:indexAmongTasks], (*parentTasks)[indexAmongTasks+1:]...)
return
}

// Locate the given task, i.e. give its neighbors and parentage.
// Returns an error when the task cannot be found.
func (b *Backlog) Locate(task *Task) (prev *Task, next *Task, parentage []*Task, index int, err error) {

var locateRecursive func(t *Task, l []*Task, p []*Task) (prev *Task, next *Task, parentage []*Task, index int, err error)
locateRecursive = func(t *Task, l []*Task, p []*Task) (prev *Task, next *Task, parentage []*Task, index int, err error) {
for i, currentTask := range l {
if currentTask == t {
if i > 0 {
prev = l[i-1]
}
if i < len(l)-1 {
next = l[i+1]
}
parentage = p
index = i
err = nil
return
}
maybePrev, maybeNext, maybeParentage, maybeIndex, maybeErr := locateRecursive(t, currentTask.Subtasks, append([]*Task{currentTask}, p...))
if maybeErr == nil {
prev, next, parentage, index, err = maybePrev, maybeNext, maybeParentage, maybeIndex, maybeErr
return
}
}

return nil, nil, nil, -1, fmt.Errorf("not found")
}

b.Mtx.RLock()
defer b.Mtx.RUnlock()
return locateRecursive(task, b.Tasks, nil)
}

func (t *Task) toEvent(startTime time.Time, namePrefix string) Event {
return Event{
Start: *NewTimestampFromGotime(startTime),
End: *NewTimestampFromGotime(
func() time.Time {
return startTime.Add(t.getDurationNormalized())
}(),
),
Name: namePrefix + t.Name,
Cat: t.Category,
}
}

// ToEvent convernts a task (including potential subtasks) to the corresponding
// set of events (subtasks becoming events during the main event, recursively).
func (t *Task) ToEvent(startTime time.Time, namePrefix string) []*Event {
e := t.toEvent(startTime, namePrefix)
result := []*Event{&e}
subtaskStartTime := startTime
for _, subtask := range t.Subtasks {
subtaskEvents := subtask.ToEvent(subtaskStartTime, namePrefix+t.Name+": ")
result = append(result, subtaskEvents...)
subtaskStartTime = subtaskStartTime.Add(subtask.getDurationNormalized())
}
return result
}

func sumDurationNormalized(tasks []*Task) time.Duration {
sum := time.Duration(0)
for _, t := range tasks {
sum = sum + t.getDurationNormalized()
}
return sum
}

func (t *Task) getDurationNormalized() time.Duration {
if t.Duration == nil {
subtaskDur := sumDurationNormalized(t.Subtasks)
if subtaskDur == 0 {
return 1 * time.Hour
} else {
return subtaskDur
}
} else {
return *t.Duration
}
}

type ByDeadline []*Task

func (a ByDeadline) Len() int { return len(a) }
Expand Down

0 comments on commit 5a79eda

Please sign in to comment.