taskPane modified as a Component (type)

This commit is contained in:
Anis Ahmad
2020-06-10 23:50:13 +06:00
parent ea141f5013
commit 19666900a2
6 changed files with 146 additions and 119 deletions

View File

@@ -11,15 +11,14 @@ import (
)
var (
app *tview.Application
newTask *tview.InputField
taskList *tview.List
projectDetailPane *tview.Flex
taskPane, taskDetailPane *tview.Flex
layout, contents *tview.Flex
app *tview.Application
projectDetailPane *tview.Flex
taskDetailPane *tview.Flex
layout, contents *tview.Flex
statusBar *StatusBar
projectPane *ProjectPane
taskPane *TaskPane
db *storm.DB
projectRepo repository.ProjectRepository
@@ -44,7 +43,8 @@ func main() {
statusBar = makeStatusBar(app)
projectPane = NewProjectPane(projectRepo)
prepareTaskPane()
// prepareTaskPane()
taskPane = NewTaskPane(projectRepo, taskRepo)
prepareProjectDetail()
prepareDetailPane()
@@ -75,7 +75,7 @@ func setKeyboardShortcuts() *tview.Application {
case projectPane.HasFocus():
event = projectPane.handleShortcuts(event)
case taskPane.HasFocus():
event = handleTaskPaneShortcuts(event)
event = taskPane.handleShortcuts(event)
case taskDetailPane.HasFocus():
event = handleDetailPaneShortcuts(event)
}
@@ -88,7 +88,7 @@ func setKeyboardShortcuts() *tview.Application {
app.SetFocus(taskPane)
case 'f':
// @TODO : Remove
//statusBar.showForSeconds(reflect.TypeOf(app.GetFocus()).String(), 5)
// statusBar.showForSeconds(reflect.TypeOf(app.GetFocus()).String(), 5)
statusBar.showForSeconds(projectPane.activeProject.Title, 5)
}

View File

@@ -13,8 +13,6 @@ func prepareProjectDetail() {
deleteBtn.SetBackgroundColor(tcell.ColorRed)
projectDetailPane = tview.NewFlex().SetDirection(tview.FlexRow).
// AddItem(activeProjectName, 1, 1, false).
// AddItem(makeHorizontalLine(tcell.RuneS3, tcell.ColorGray), 1, 1, false).
AddItem(deleteBtn, 3, 1, false).
AddItem(blankCell, 1, 1, false).
AddItem(clearBtn, 3, 1, false).
@@ -26,9 +24,9 @@ func prepareProjectDetail() {
// @TODO - Move to tasks pane
func clearCompletedTasks() {
count := 0
for i, task := range tasks {
if task.Completed && taskRepo.Delete(&tasks[i]) == nil {
taskList.RemoveItem(i)
for i, task := range taskPane.tasks {
if task.Completed && taskRepo.Delete(&taskPane.tasks[i]) == nil {
taskPane.list.RemoveItem(i)
count++
}
}

View File

@@ -4,7 +4,6 @@ import (
"fmt"
"strings"
"github.com/asdine/storm/v3"
"github.com/gdamore/tcell"
"github.com/rivo/tview"
@@ -119,24 +118,25 @@ func (pane *ProjectPane) handleShortcuts(event *tcell.EventKey) *tcell.EventKey
func (pane *ProjectPane) activateProject(idx int) {
pane.activeProject = &pane.projects[idx]
loadProjectTasks()
taskPane.LoadProjectTasks(*pane.activeProject)
removeThirdCol()
projectDetailPane.SetTitle("[::b]" + pane.activeProject.Title)
contents.AddItem(projectDetailPane, 25, 0, false)
app.SetFocus(taskPane)
}
func (pane *ProjectPane) removeActivateProject() {
if pane.activeProject != nil && pane.repo.Delete(pane.activeProject) == nil {
// @TODO - Move to tasks pane
for i := range tasks {
_ = taskRepo.Delete(&tasks[i])
for i := range taskPane.tasks {
_ = taskRepo.Delete(&taskPane.tasks[i])
}
taskPane.ClearList()
statusBar.showForSeconds("[lime]Removed Project: "+pane.activeProject.Title, 5)
removeThirdCol()
taskList.Clear()
pane.loadListItems(true)
}
@@ -153,17 +153,6 @@ func (pane *ProjectPane) loadListItems(focus bool) {
}
}
// @TODO - Should be broken down into respective pane
func loadProjectTasks() {
taskList.Clear()
app.SetFocus(taskPane)
var err error
if tasks, err = taskRepo.GetAllByProject(*projectPane.activeProject); err != nil && err != storm.ErrNotFound {
statusBar.showForSeconds("[red::]Error: "+err.Error(), 5)
}
for i, task := range tasks {
addTaskToList(task, i)
}
func (pane *ProjectPane) GetActiveProject() *model.Project {
return pane.activeProject
}

View File

@@ -72,7 +72,7 @@ func makeDateRow() *tview.Flex {
case tcell.KeyEnter:
setTaskDate(parseDateInputOrCurrent(taskDate.GetText()).Unix(), true)
case tcell.KeyEsc:
setTaskDate(currentTask.DueDate, false)
setTaskDate(taskPane.activeTask.DueDate, false)
}
app.SetFocus(taskDetailPane)
})
@@ -101,7 +101,7 @@ func makeDateRow() *tview.Flex {
}
func setStatusToggle() {
if currentTask.Completed {
if taskPane.activeTask.Completed {
taskStatusToggle.SetLabel("Resume").SetBackgroundColor(tcell.ColorMaroon)
} else {
taskStatusToggle.SetLabel("Complete").SetBackgroundColor(tcell.ColorDarkGreen)
@@ -109,19 +109,19 @@ func setStatusToggle() {
}
func toggleActiveTaskStatus() {
status := !currentTask.Completed
if taskRepo.UpdateField(currentTask, "Completed", status) == nil {
currentTask.Completed = status
loadTask(currentTaskIdx)
taskList.SetItemText(currentTaskIdx, makeTaskListingTitle(*currentTask), "")
status := !taskPane.activeTask.Completed
if taskRepo.UpdateField(taskPane.activeTask, "Completed", status) == nil {
taskPane.activeTask.Completed = status
taskPane.ActivateTask(taskPane.list.GetCurrentItem())
taskPane.list.SetItemText(taskPane.list.GetCurrentItem(), makeTaskListingTitle(*taskPane.activeTask), "")
}
}
// Display Task date in detail pane, and update date if asked to
func setTaskDate(unixDate int64, update bool) {
if update {
currentTask.DueDate = unixDate
if err := taskRepo.UpdateField(currentTask, "DueDate", unixDate); err != nil {
taskPane.activeTask.DueDate = unixDate
if err := taskRepo.UpdateField(taskPane.activeTask, "DueDate", unixDate); err != nil {
statusBar.showForSeconds("Could not update due date: "+err.Error(), 5)
return
}
@@ -160,8 +160,8 @@ func prepareDetailsEditor() {
taskDetailView.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
switch event.Key() {
case tcell.KeyEsc:
currentTask.Details = taskDetailView.Buf.String()
err := taskRepo.Update(currentTask)
taskPane.activeTask.Details = taskDetailView.Buf.String()
err := taskRepo.Update(taskPane.activeTask)
if err == nil {
statusBar.showForSeconds("[lime]Saved task detail", 5)
} else {

View File

@@ -2,107 +2,122 @@ package main
import (
"fmt"
"time"
"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"
)
var (
tasks []model.Task
currentTask *model.Task
currentTaskIdx int
)
type TaskPane struct {
*tview.Flex
list *tview.List
tasks []model.Task
activeTask *model.Task
func prepareTaskPane() {
taskList = tview.NewList().ShowSecondaryText(false)
taskList.SetDoneFunc(func() {
newTask *tview.InputField
projectRepo repository.ProjectRepository
taskRepo repository.TaskRepository
}
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,
}
pane.list.SetDoneFunc(func() {
app.SetFocus(projectPane)
})
newTask = makeLightTextInput("+[New Task]").
SetDoneFunc(func(key tcell.Key) {
switch key {
case tcell.KeyEnter:
if len(newTask.GetText()) < 3 {
statusBar.showForSeconds("[red::]Task title should be at least 3 character", 5)
return
}
task, err := taskRepo.Create(*projectPane.activeProject, newTask.GetText(), "", "", 0)
if err != nil {
statusBar.showForSeconds("[red::]Could not create Task:"+err.Error(), 5)
}
tasks = append(tasks, task)
addTaskToList(task, len(tasks)-1)
newTask.SetText("")
case tcell.KeyEsc:
app.SetFocus(taskPane)
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.activeProject, name, "", "", 0)
if err != nil {
statusBar.showForSeconds("[red::]Could not create Task:"+err.Error(), 5)
}
taskPane = tview.NewFlex().SetDirection(tview.FlexRow).
AddItem(taskList, 0, 1, true).
AddItem(newTask, 1, 0, false)
pane.tasks = append(pane.tasks, task)
pane.addTaskToList(len(pane.tasks) - 1)
pane.newTask.SetText("")
case tcell.KeyEsc:
app.SetFocus(pane)
}
taskPane.SetBorder(true).SetTitle("[::u]T[::-]asks")
})
pane.
AddItem(pane.list, 0, 1, true).
AddItem(pane.newTask, 1, 0, false)
pane.SetBorder(true).SetTitle("[::u]T[::-]asks")
return &pane
}
func addTaskToList(task model.Task, i int) *tview.List {
return taskList.AddItem(makeTaskListingTitle(task), "", 0, func(taskidx int) func() {
return func() { loadTask(taskidx) }
func (pane *TaskPane) ClearList() {
pane.list.Clear()
pane.tasks = nil
}
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 loadTask(idx int) {
removeThirdCol()
currentTaskIdx = idx
currentTask = &tasks[currentTaskIdx]
func (pane *TaskPane) handleShortcuts(event *tcell.EventKey) *tcell.EventKey {
switch event.Rune() {
case 'n':
app.SetFocus(pane.newTask)
}
taskName.SetText(fmt.Sprintf("[%s::b]# %s", getTaskTitleColor(*currentTask), currentTask.Title))
taskDetailView.Buf = makeBufferFromString(currentTask.Details)
return event
}
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)
}
}
func (pane *TaskPane) ActivateTask(idx int) {
removeThirdCol()
pane.activeTask = &pane.tasks[idx]
taskName.SetText(fmt.Sprintf("[%s::b]# %s", getTaskTitleColor(*pane.activeTask), pane.activeTask.Title))
taskDetailView.Buf = makeBufferFromString(pane.activeTask.Details)
taskDetailView.SetColorscheme(colorscheme)
taskDetailView.Start()
setTaskDate(currentTask.DueDate, false)
setTaskDate(pane.activeTask.DueDate, false)
setStatusToggle()
contents.AddItem(taskDetailPane, 0, 3, false)
deactivateEditor()
}
func removeThirdCol() {
contents.RemoveItem(taskDetailPane)
contents.RemoveItem(projectDetailPane)
}
func getTaskTitleColor(task model.Task) string {
colorName := "olive"
if task.Completed {
colorName = "lime"
} else if task.DueDate != 0 && task.DueDate < time.Now().Truncate(24*time.Hour).Unix() {
colorName = "red"
}
return colorName
}
func makeTaskListingTitle(task model.Task) string {
checkbox := "[ []"
if task.Completed {
checkbox = "[x[]"
}
return fmt.Sprintf("[%s]%s %s", getTaskTitleColor(task), checkbox, task.Title)
}
func handleTaskPaneShortcuts(event *tcell.EventKey) *tcell.EventKey {
switch event.Rune() {
case 'n':
app.SetFocus(newTask)
}
return event
}

View File

@@ -8,6 +8,7 @@ import (
"github.com/gdamore/tcell"
"github.com/rivo/tview"
"github.com/ajaxray/geek-life/model"
"github.com/ajaxray/geek-life/util"
)
@@ -64,3 +65,27 @@ func yetToImplement(feature string) func() {
message := fmt.Sprintf("[yellow]%s is yet to implement. Please Check in next version.", feature)
return func() { statusBar.showForSeconds(message, 5) }
}
func removeThirdCol() {
contents.RemoveItem(taskDetailPane)
contents.RemoveItem(projectDetailPane)
}
func getTaskTitleColor(task model.Task) string {
colorName := "olive"
if task.Completed {
colorName = "lime"
} else if task.DueDate != 0 && task.DueDate < time.Now().Truncate(24*time.Hour).Unix() {
colorName = "red"
}
return colorName
}
func makeTaskListingTitle(task model.Task) string {
checkbox := "[ []"
if task.Completed {
checkbox = "[x[]"
}
return fmt.Sprintf("[%s]%s %s", getTaskTitleColor(task), checkbox, task.Title)
}