pelican/internal/ui/ui.go

162 lines
2.9 KiB
Go
Raw Normal View History

package ui
import (
"fmt"
2023-02-14 07:54:10 +00:00
"codeflow.dananglin.me.uk/apollo/canal/internal/board"
2023-04-22 19:18:47 +01:00
"github.com/gdamore/tcell/v2"
2023-04-23 00:17:34 +01:00
"github.com/rivo/tview"
)
const (
2023-04-22 19:18:47 +01:00
shiftLeft int = iota
shiftRight
)
const (
2023-04-22 19:18:47 +01:00
mainPageName string = "main"
quitPageName string = "quit"
addPageName string = "add"
)
2023-04-22 17:50:27 +01:00
type UI struct {
*tview.Application
columns []column
flex *tview.Flex
pages *tview.Pages
focusedColumn int
board board.Board
2023-04-22 19:18:47 +01:00
quit *tview.Modal
2023-04-23 00:17:34 +01:00
add *modalInput
2023-04-22 19:18:47 +01:00
}
// NewUI returns a new UI value.
func NewUI() UI {
u := UI{
Application: tview.NewApplication(),
pages: tview.NewPages(),
flex: tview.NewFlex(),
quit: tview.NewModal(),
2023-04-23 00:17:34 +01:00
add: NewModalInput(),
2023-04-22 19:18:47 +01:00
focusedColumn: 0,
}
2023-04-23 00:17:34 +01:00
u.init()
2023-04-22 19:18:47 +01:00
return u
}
2023-04-23 00:35:08 +01:00
// closeBoard closes the board.
2023-04-23 00:17:34 +01:00
func (u *UI) closeBoard() {
_ = u.board.Close()
}
2023-04-23 00:35:08 +01:00
// init initialises the UI.
2023-04-23 00:17:34 +01:00
func (u *UI) init() {
2023-04-22 19:18:47 +01:00
u.pages.AddPage(mainPageName, u.flex, true, true)
u.initQuitModal()
u.pages.AddPage(quitPageName, u.quit, false, false)
2023-04-23 00:17:34 +01:00
u.initAddInputModal()
u.pages.AddPage(addPageName, u.add, false, false)
2023-04-22 19:18:47 +01:00
u.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
2023-04-23 04:27:16 +01:00
switch event.Rune() {
case 'o':
if u.flex.HasFocus() && len(u.columns) == 0 {
u.openBoard("")
}
2023-04-22 19:18:47 +01:00
}
return event
})
u.SetRoot(u.pages, true)
}
2023-04-23 00:35:08 +01:00
// initAddInputModal initialises the add input modal.
2023-04-23 00:17:34 +01:00
func (u *UI) initAddInputModal() {
doneFunc := func(text string, success bool) {
if success {
_ = u.newCard(text, "")
}
u.pages.HidePage(addPageName)
u.setColumnFocus()
}
u.add.SetDoneFunc(doneFunc)
}
2023-04-22 19:18:47 +01:00
// initQuitModal initialises the quit modal.
func (u *UI) initQuitModal() {
quitDoneFunc := func(_ int, buttonLabel string) {
switch buttonLabel {
case "Quit":
u.shutdown()
default:
2023-04-23 00:17:34 +01:00
u.pages.SwitchToPage(mainPageName)
2023-04-22 19:18:47 +01:00
u.setColumnFocus()
}
}
u.quit.SetText("Do you want to quit the application?").
AddButtons([]string{"Quit", "Cancel"}).
SetDoneFunc(quitDoneFunc)
}
2023-04-23 00:35:08 +01:00
// newCard creates and saves a new card to the database.
2023-04-23 00:17:34 +01:00
func (u *UI) newCard(title, content string) error {
args := board.CardArgs{
NewTitle: title,
NewContent: content,
}
2023-04-23 00:17:34 +01:00
if err := u.board.CreateCard(args); err != nil {
return fmt.Errorf("unable to create card, %w", err)
}
u.refresh()
return nil
}
2023-04-23 00:35:08 +01:00
// openBoard opens the kanban board.
2023-04-22 17:50:27 +01:00
func (u *UI) openBoard(path string) error {
b, err := board.Open(path)
if err != nil {
return fmt.Errorf("unable to load board, %w", err)
}
2023-04-22 17:50:27 +01:00
u.board = b
2023-04-22 17:50:27 +01:00
if err = u.refresh(); err != nil {
return err
}
return nil
}
2023-04-23 00:35:08 +01:00
// refresh refreshes the UI.
2023-04-22 17:50:27 +01:00
func (u *UI) refresh() error {
statusList, err := u.board.StatusList()
if err != nil {
return fmt.Errorf("unable to get the status list, %w", err)
}
u.updateColumns(statusList)
2023-04-22 17:50:27 +01:00
u.setColumnFocus()
// TODO: update move status page here
return nil
}
2023-04-23 00:17:34 +01:00
// shutdown shuts down the application.
func (u *UI) shutdown() {
u.closeBoard()
u.Stop()
}