- Restoring focus to previous (taskPane) panel after closing modal (works only when invoked with shortcut)
- `projectPane.RemoveActivateProject()` and `taskPane.ClearCompletedTasks()` do comply with `func()`. So no need to wrap within `func() {}`
- Fixed issue - Project dosen't exit with Ctrl+C once (maybe because of re-running `.Run()` in `AskYesNo()`).
- When focusing back to tasklist from task detail, re-showing projectDetail pane
159 lines
3.8 KiB
Go
159 lines
3.8 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"unicode"
|
|
|
|
"github.com/asdine/storm/v3"
|
|
"github.com/gdamore/tcell/v2"
|
|
"github.com/rivo/tview"
|
|
flag "github.com/spf13/pflag"
|
|
|
|
"github.com/ajaxray/geek-life/model"
|
|
"github.com/ajaxray/geek-life/repository"
|
|
repo "github.com/ajaxray/geek-life/repository/storm"
|
|
"github.com/ajaxray/geek-life/util"
|
|
)
|
|
|
|
var (
|
|
app *tview.Application
|
|
layout, contents *tview.Flex
|
|
|
|
statusBar *StatusBar
|
|
projectPane *ProjectPane
|
|
taskPane *TaskPane
|
|
taskDetailPane *TaskDetailPane
|
|
projectDetailPane *ProjectDetailPane
|
|
|
|
db *storm.DB
|
|
projectRepo repository.ProjectRepository
|
|
taskRepo repository.TaskRepository
|
|
|
|
// Flag variables
|
|
dbFile string
|
|
)
|
|
|
|
func init() {
|
|
flag.StringVarP(&dbFile, "db-file", "d", "", "Specify DB file path manually.")
|
|
}
|
|
|
|
func main() {
|
|
app = tview.NewApplication()
|
|
flag.Parse()
|
|
|
|
db = util.ConnectStorm(dbFile)
|
|
defer func() {
|
|
if err := db.Close(); err != nil {
|
|
util.LogIfError(err, "Error in closing storm Db")
|
|
}
|
|
}()
|
|
|
|
if flag.NArg() > 0 && flag.Arg(0) == "migrate" {
|
|
migrate(db)
|
|
fmt.Println("Database migrated successfully!")
|
|
} else {
|
|
projectRepo = repo.NewProjectRepository(db)
|
|
taskRepo = repo.NewTaskRepository(db)
|
|
|
|
layout = tview.NewFlex().SetDirection(tview.FlexRow).
|
|
AddItem(makeTitleBar(), 2, 1, false).
|
|
AddItem(prepareContentPages(), 0, 2, true).
|
|
AddItem(prepareStatusBar(app), 1, 1, false)
|
|
|
|
setKeyboardShortcuts()
|
|
|
|
if err := app.SetRoot(layout, true).EnableMouse(true).Run(); err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
func migrate(database *storm.DB) {
|
|
util.FatalIfError(database.ReIndex(&model.Project{}), "Error in migrating Projects")
|
|
util.FatalIfError(database.ReIndex(&model.Task{}), "Error in migrating Tasks")
|
|
|
|
fmt.Println("Migration completed. Start geek-life normally.")
|
|
os.Exit(0)
|
|
}
|
|
|
|
func setKeyboardShortcuts() *tview.Application {
|
|
return app.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
|
|
if ignoreKeyEvt() {
|
|
return event
|
|
}
|
|
|
|
// Global shortcuts
|
|
switch unicode.ToLower(event.Rune()) {
|
|
case 'p':
|
|
app.SetFocus(projectPane)
|
|
contents.RemoveItem(taskDetailPane)
|
|
return nil
|
|
case 'q':
|
|
case 't':
|
|
app.SetFocus(taskPane)
|
|
contents.RemoveItem(taskDetailPane)
|
|
return nil
|
|
}
|
|
|
|
// Handle based on current focus. Handlers may modify event
|
|
switch {
|
|
case projectPane.HasFocus():
|
|
event = projectPane.handleShortcuts(event)
|
|
case taskPane.HasFocus():
|
|
event = taskPane.handleShortcuts(event)
|
|
if event != nil && projectDetailPane.isShowing() {
|
|
event = projectDetailPane.handleShortcuts(event)
|
|
}
|
|
case taskDetailPane.HasFocus():
|
|
event = taskDetailPane.handleShortcuts(event)
|
|
}
|
|
|
|
return event
|
|
})
|
|
}
|
|
|
|
func prepareContentPages() *tview.Flex {
|
|
projectPane = NewProjectPane(projectRepo)
|
|
taskPane = NewTaskPane(projectRepo, taskRepo)
|
|
projectDetailPane = NewProjectDetailPane()
|
|
taskDetailPane = NewTaskDetailPane(taskRepo)
|
|
|
|
contents = tview.NewFlex().
|
|
AddItem(projectPane, 25, 1, true).
|
|
AddItem(taskPane, 0, 2, false)
|
|
|
|
return contents
|
|
|
|
}
|
|
|
|
func makeTitleBar() *tview.Flex {
|
|
titleText := tview.NewTextView().SetText("[lime::b]Geek-life [::-]- Task Manager for geeks!").SetDynamicColors(true)
|
|
versionInfo := tview.NewTextView().SetText("[::d]Version: 0.1.2").SetTextAlign(tview.AlignRight).SetDynamicColors(true)
|
|
|
|
return tview.NewFlex().
|
|
AddItem(titleText, 0, 2, false).
|
|
AddItem(versionInfo, 0, 1, false)
|
|
}
|
|
|
|
func AskYesNo(text string, f func()) {
|
|
|
|
activePane := app.GetFocus()
|
|
modal := tview.NewModal().
|
|
SetText(text).
|
|
AddButtons([]string{"Yes", "No"}).
|
|
SetDoneFunc(func(buttonIndex int, buttonLabel string) {
|
|
if buttonLabel == "Yes" {
|
|
f()
|
|
}
|
|
app.SetRoot(layout, true).EnableMouse(true)
|
|
app.SetFocus(activePane)
|
|
})
|
|
|
|
pages := tview.NewPages().
|
|
AddPage("background", layout, true, true).
|
|
AddPage("modal", modal, true, true)
|
|
_ = app.SetRoot(pages, true).EnableMouse(true)
|
|
}
|