package main import ( "fmt" "github.com/asdine/storm/v3" "github.com/gdamore/tcell" "github.com/rivo/tview" "github.com/ajaxray/geek-life/model" "github.com/ajaxray/geek-life/repository" ) // TaskPane displays tasks of current TaskList or Project type TaskPane struct { *tview.Flex list *tview.List tasks []model.Task activeTask *model.Task newTask *tview.InputField projectRepo repository.ProjectRepository taskRepo repository.TaskRepository hint *tview.TextView } // NewTaskPane initializes and configures a TaskPane func NewTaskPane(projectRepo repository.ProjectRepository, taskRepo repository.TaskRepository) *TaskPane { pane := TaskPane{ Flex: tview.NewFlex().SetDirection(tview.FlexRow), list: tview.NewList().ShowSecondaryText(false), newTask: makeLightTextInput("+[New Task]"), projectRepo: projectRepo, taskRepo: taskRepo, hint: tview.NewTextView().SetTextColor(tcell.ColorYellow).SetTextAlign(tview.AlignCenter), } pane.list.SetDoneFunc(func() { app.SetFocus(projectPane) }) pane.newTask.SetDoneFunc(func(key tcell.Key) { switch key { case tcell.KeyEnter: name := pane.newTask.GetText() if len(name) < 3 { statusBar.showForSeconds("[red::]Task title should be at least 3 character", 5) return } task, err := taskRepo.Create(*projectPane.GetActiveProject(), name, "", "", 0) if err != nil { statusBar.showForSeconds("[red::]Could not create Task:"+err.Error(), 5) return } pane.tasks = append(pane.tasks, task) pane.addTaskToList(len(pane.tasks) - 1) pane.newTask.SetText("") statusBar.showForSeconds("[yellow::]Task created. Add another task or press Esc.", 5) case tcell.KeyEsc: app.SetFocus(pane) } }) pane. AddItem(pane.list, 0, 1, true). AddItem(pane.hint, 0, 1, false) pane.SetBorder(true).SetTitle("[::u]T[::-]asks") pane.setHintMessage() return &pane } // ClearList removes all items from TaskPane func (pane *TaskPane) ClearList() { pane.list.Clear() pane.tasks = nil pane.RemoveItem(pane.newTask) } // SetList Sets a list of tasks to be displayed func (pane *TaskPane) SetList(tasks []model.Task) { pane.ClearList() pane.tasks = tasks for i := range pane.tasks { pane.addTaskToList(i) } } func (pane *TaskPane) addTaskToList(i int) *tview.List { return pane.list.AddItem(makeTaskListingTitle(pane.tasks[i]), "", 0, func(taskidx int) func() { return func() { taskPane.ActivateTask(taskidx) } }(i)) } func (pane *TaskPane) handleShortcuts(event *tcell.EventKey) *tcell.EventKey { switch event.Rune() { case 'n': app.SetFocus(pane.newTask) } return event } // LoadProjectTasks loads tasks of a project in taskPane func (pane *TaskPane) LoadProjectTasks(project model.Project) { var tasks []model.Task var err error if tasks, err = taskRepo.GetAllByProject(project); err != nil && err != storm.ErrNotFound { statusBar.showForSeconds("[red::]Error: "+err.Error(), 5) } else { pane.SetList(tasks) } pane.RemoveItem(pane.hint) pane.AddItem(pane.newTask, 1, 0, false) } // ActivateTask marks a task as currently active and loads in TaskDetailPane func (pane *TaskPane) ActivateTask(idx int) { removeThirdCol() pane.activeTask = &pane.tasks[idx] taskDetailPane.SetTask(pane.activeTask) contents.AddItem(taskDetailPane, 0, 3, false) } // ClearCompletedTasks removes tasks from current list that are in completed state func (pane *TaskPane) ClearCompletedTasks() { count := 0 for i, task := range pane.tasks { if task.Completed && pane.taskRepo.Delete(&pane.tasks[i]) == nil { pane.list.RemoveItem(i) count++ } } statusBar.showForSeconds(fmt.Sprintf("[yellow]%d tasks cleared!", count), 5) } func (pane TaskPane) setHintMessage() { if len(projectPane.projects) == 0 { pane.hint.SetText("Welcome to the organized life!\n------------------------------\n Create TaskList/Project at the bottom of Projects pane.\n (Press p,n)") } else { pane.hint.SetText("Select a TaskList/Project to load tasks.\nPress p,n to create new Project.") } }