package main import ( "os" "github.com/gdamore/tcell/v2" "github.com/navidys/tvxwidgets" "github.com/rivo/tview" ) type UIState struct { Page string Error string Success string } func AppUI(app *tview.Application, currentFrame **tview.Frame, state *UIState, device *Device) *tview.Frame { list := tview.NewList() list.AddItem("CPkg Tools", "Create and unpack cpkg files for distribution", 'c', func() { newFrame := PackageUI(app, currentFrame, state, device) *currentFrame = newFrame state.Page = "package" app.SetRoot(newFrame, true) }) list.AddItem("Upload to Cardputer", "Creates a package and uploads it to the connected Cardputer", 'u', func() { if !device.Connected { SetError(state, "No cardputer connected") return } else { SetError(state, "") } newFrame := UploadToolsUI(app, currentFrame, state, device) *currentFrame = newFrame state.Page = "upload-tools" app.SetRoot(newFrame, true) }) list.AddItem("Live Refresh", "Monitors for changes and automatically uploads to the Cardputer (WIP)", 'l', nil) frame := tview.NewFrame(list) frame.SetBorders(0, 0, 0, 0, 0, 0) frame.AddText("Parchment - v0.0.1", true, tview.AlignLeft, tcell.ColorWhite) frame.AddText("Waiting for cardputer...", false, tview.AlignLeft, tcell.ColorWhite) return frame } func SetError(state *UIState, text string) { state.Success = "" state.Error = text } func SetSuccess(state *UIState, text string) { state.Error = "" state.Success = text } func UploadToolsUI(app *tview.Application, currentFrame **tview.Frame, state *UIState, device *Device) *tview.Frame { list := tview.NewList() list.AddItem("Upload Package", "Uploads a chosen .cpkg file to the connected Cardputer", 'u', nil) list.AddItem("Sync Project", "Automatically packages and uploads the current project", 's', nil) list.AddItem("Back", "Go back to the home page", 'b', func() { newFrame := AppUI(app, currentFrame, state, device) *currentFrame = newFrame state.Page = "home" app.SetRoot(newFrame, true) }) frame := tview.NewFrame(list) frame.SetBorders(0, 0, 0, 0, 0, 0) frame.AddText("Upload Tools", true, tview.AlignLeft, tcell.ColorWhite) return frame } func UploadUI(app *tview.Application, currentFrame **tview.Frame, state *UIState, device *Device) *tview.Frame { list := tview.NewFlex() list.SetDirection(tview.FlexRow) progress := tvxwidgets.NewPercentageModeGauge() progress.SetValue(0) progress.SetMaxValue(100) progress.SetBorder(true) progress.SetTitle("Upload Progress") list.AddItem(progress, 0, 1, false) go func() { // check if a package.json file exists and load it fsys := os.DirFS(".") pkgData, err := loadPackageJSON(fsys) if err != nil { // if the package.json file does not exist, show an error modal modal := tview.NewModal() modal.SetText("Failed to load package.json") modal.AddButtons([]string{"OK"}) modal.SetDoneFunc(func(buttonIndex int, buttonLabel string) { newFrame := AppUI(app, currentFrame, state, device) *currentFrame = newFrame state.Page = "home" app.SetRoot(newFrame, true) }) app.SetRoot(modal, true) return } if pkgData == nil { // if the package.json file is empty, show an error modal modal := tview.NewModal() modal.SetText("Failed to load package.json") modal.AddButtons([]string{"OK"}) modal.SetDoneFunc(func(buttonIndex int, buttonLabel string) { newFrame := AppUI(app, currentFrame, state, device) *currentFrame = newFrame state.Page = "home" app.SetRoot(newFrame, true) }) app.SetRoot(modal, true) return } }() return tview.NewFrame(list) } func PackageUI(app *tview.Application, currentFrame **tview.Frame, state *UIState, device *Device) *tview.Frame { list := tview.NewList() list.AddItem("Create Package", "Creates a .cpkg file in the running directory", 'c', func() { fsys := os.DirFS(".") pkgData, err := loadPackageJSON(fsys) if err != nil { SetError(state, "Failed to load package.json") return } if pkgData == nil { SetError(state, "Failed to load package.json") return } pkg, err := createCpkg(fsys, pkgData) if err != nil { SetError(state, err.Error()) } else { SetSuccess(state, "Created file "+pkg.packageName+".cpkg") } }) list.AddItem("Unpack Package", "Unpacks a chosen .cpkg file into a subdirectory", 'u', nil) list.AddItem("Back", "Go back to the home page", 'b', func() { newFrame := AppUI(app, currentFrame, state, device) *currentFrame = newFrame state.Page = "home" app.SetRoot(newFrame, true) }) frame := tview.NewFrame(list) frame.SetBorders(0, 0, 0, 0, 0, 0) frame.AddText("Package Tools", true, tview.AlignLeft, tcell.ColorWhite) frame.AddText("Waiting for cardputer...", false, tview.AlignLeft, tcell.ColorWhite) return frame } func UpdateDeviceStatus(app *tview.Application, frame *tview.Frame, state *UIState, status string, color tcell.Color) { app.QueueUpdateDraw(func() { frame.Clear() switch state.Page { case "home": frame.AddText("Parchment - v0.0.1", true, tview.AlignLeft, tcell.ColorWhite) case "package": frame.AddText("Package Tools", true, tview.AlignLeft, tcell.ColorWhite) case "upload": frame.AddText("Uploading to Cardputer - Do not disconnect the cardputer until the upload is complete", true, tview.AlignLeft, tcell.ColorWhite) case "upload-tools": frame.AddText("Upload Tools", true, tview.AlignLeft, tcell.ColorWhite) } if state.Error != "" { frame.AddText(state.Error, false, tview.AlignRight, tcell.ColorRed) } if state.Success != "" { frame.AddText(state.Success, false, tview.AlignRight, tcell.ColorGreen) } frame.AddText(status, false, tview.AlignLeft, color) }) }