Limit Gemini
This commit is contained in:
218
main.go
218
main.go
@@ -3,100 +3,204 @@ package main
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/gdamore/tcell/v2"
|
"github.com/gdamore/tcell/v2"
|
||||||
"github.com/rivo/tview"
|
"github.com/rivo/tview"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Brew represents our mock data structure
|
// --- Data Structures ---
|
||||||
|
|
||||||
type Brew struct {
|
type Brew struct {
|
||||||
Name string
|
Name string
|
||||||
Hops string
|
Hops string
|
||||||
Progress int
|
Progress int
|
||||||
|
Notes string
|
||||||
|
}
|
||||||
|
|
||||||
|
type InventoryItem struct {
|
||||||
|
Name string
|
||||||
|
Type string
|
||||||
|
Amount float64
|
||||||
|
Unit string
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
app := tview.NewApplication()
|
app := tview.NewApplication()
|
||||||
|
pages := tview.NewPages()
|
||||||
|
|
||||||
|
// Colors - Using GetColor for maximum compatibility
|
||||||
|
cyan := tcell.GetColor("cyan")
|
||||||
|
yellow := tcell.GetColor("yellow")
|
||||||
|
green := tcell.GetColor("green")
|
||||||
|
gray := tcell.GetColor("gray")
|
||||||
|
|
||||||
|
// --- Mock Data ---
|
||||||
|
|
||||||
// 1. Mock Data
|
|
||||||
brews := []Brew{
|
brews := []Brew{
|
||||||
{"Midnight Stout", "Fuggles, Goldings", 75},
|
{"Midnight Stout", "Fuggles, Goldings", 75, "Primary fermentation looking good. Smells like coffee."},
|
||||||
{"Neon IPA", "Citra, Mosaic, Galaxy", 40},
|
{"Neon IPA", "Citra, Mosaic, Galaxy", 40, "Dry hopping starts in 2 days."},
|
||||||
{"Summer Wheat", "Saaz, Hallertau", 95},
|
{"Summer Wheat", "Saaz, Hallertau", 95, "Ready for bottling/kegging."},
|
||||||
{"Pacific Pale Ale", "Cascade, Amarillo", 10},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Header with ASCII Logo (Top Right)
|
inventory := []InventoryItem{
|
||||||
// We use a TextView for the logo to allow right-alignment
|
{"Citra", "Hops", 500, "g"},
|
||||||
|
{"Pilsner Malt", "Grain", 25, "kg"},
|
||||||
|
{"US-05 SafAle", "Yeast", 4, "packets"},
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Shared UI Components ---
|
||||||
|
|
||||||
logo := tview.NewTextView().
|
logo := tview.NewTextView().
|
||||||
SetTextAlign(tview.AlignRight).
|
SetTextAlign(tview.AlignRight).
|
||||||
SetDynamicColors(true).
|
SetDynamicColors(true).
|
||||||
SetText(`[yellow]
|
SetText(`[yellow]
|
||||||
____ __ __ _
|
[##] ___ ___ ___ _ _
|
||||||
| __ ) _ __ _____ __| \/ | __ _ ___| |_ ___ _ __
|
/____\ | _ )| _ \| __| | | |
|
||||||
| _ \| '__/ _ \ \ /\ / /| |\/| |/ _` + "`" + `/ __| __/ _ \ '__|
|
| U | | _ \| /| _|| |/\| |
|
||||||
| |_) | | | __/\ V V / | | | | (_| \__ \ || __/ |
|
|______| |___/|_|_\|___||__/\__|
|
||||||
|____/|_| \___| \_/\_/ |_| |_|\__,_|___/\__\___|_|
|
|'=__='|
|
||||||
|
| | __ __ _ ___ _____ ___ ___
|
||||||
|
|______| | \/ | /_\ / __|_ _| __| _ \
|
||||||
|
| |\/| |/ _ \\__ \ | | | _|| /
|
||||||
|
|_| |_/_/ \_\___/ |_| |___|_|_\
|
||||||
`)
|
`)
|
||||||
|
|
||||||
title := tview.NewTextView().
|
viewTitle := tview.NewTextView().SetTextColor(cyan)
|
||||||
SetText(" BrewMaster v0.1.0 - Active Brews").
|
|
||||||
SetTextColor(tcell.ColorCyan)
|
|
||||||
|
|
||||||
header := tview.NewFlex().
|
header := tview.NewFlex().
|
||||||
AddItem(title, 0, 1, false).
|
AddItem(viewTitle, 0, 1, false).
|
||||||
AddItem(logo, 0, 2, false)
|
AddItem(logo, 0, 2, false)
|
||||||
|
|
||||||
// 3. Main Table (K9s Style)
|
commandBar := tview.NewInputField().
|
||||||
table := tview.NewTable().
|
SetLabelColor(yellow).
|
||||||
SetBorders(false).
|
SetFieldBackgroundColor(tcell.ColorBlack).
|
||||||
SetSelectable(true, false)
|
SetFieldTextColor(tcell.ColorWhite)
|
||||||
|
|
||||||
// Set Table Headers
|
|
||||||
headers := []string{"NAME", "HOPS", "PROGRESS", "STATUS"}
|
|
||||||
for c, h := range headers {
|
|
||||||
table.SetCell(0, c, tview.NewTableCell(fmt.Sprintf("[yellow::b]%s", h)).
|
|
||||||
SetSelectable(false))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Populate Mock Data
|
|
||||||
for r, brew := range brews {
|
|
||||||
row := r + 1
|
|
||||||
table.SetCell(row, 0, tview.NewTableCell(brew.Name).SetTextColor(tcell.ColorWhite))
|
|
||||||
table.SetCell(row, 1, tview.NewTableCell(brew.Hops).SetTextColor(tcell.ColorGray))
|
|
||||||
|
|
||||||
// Progress bar style
|
|
||||||
progressStr := fmt.Sprintf("[%d%%] ", brew.Progress)
|
|
||||||
table.SetCell(row, 2, tview.NewTableCell(progressStr).SetTextColor(tcell.ColorGreen))
|
|
||||||
|
|
||||||
status := "Fermenting"
|
|
||||||
if brew.Progress > 90 {
|
|
||||||
status = "Conditioning"
|
|
||||||
}
|
|
||||||
table.SetCell(row, 3, tview.NewTableCell(status).SetTextColor(tcell.ColorLightBlue))
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4. Footer (Help Menu)
|
|
||||||
footer := tview.NewTextView().
|
footer := tview.NewTextView().
|
||||||
SetDynamicColors(true).
|
SetDynamicColors(true).
|
||||||
SetText(" [black:gray] <Ctrl-C> Exit [white:black] [black:gray] <Enter> View Details [white:black] ")
|
SetText(" [black:gray] <:> Command [white:black] [black:gray] <Enter> Describe [white:black] [black:gray] <Ctrl-C> Exit [white:black] ")
|
||||||
|
|
||||||
// 5. Layout Assembly
|
// --- View Logic Helpers ---
|
||||||
grid := tview.NewFlex().SetDirection(tview.FlexRow).
|
|
||||||
AddItem(header, 7, 0, false).
|
// Detail View (The "Describe" screen)
|
||||||
AddItem(table, 0, 1, true).
|
detailsView := tview.NewTextView().
|
||||||
|
SetDynamicColors(true).
|
||||||
|
SetRegions(true).
|
||||||
|
SetWrap(true)
|
||||||
|
|
||||||
|
showDetails := func(content string) {
|
||||||
|
detailsView.SetText(content)
|
||||||
|
pages.SwitchToPage("details")
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Page 1: Active Brews ---
|
||||||
|
brewsTable := tview.NewTable().SetSelectable(true, false)
|
||||||
|
for r, b := range brews {
|
||||||
|
brewsTable.SetCell(r, 0, tview.NewTableCell(b.Name).SetTextColor(tcell.ColorWhite))
|
||||||
|
brewsTable.SetCell(r, 1, tview.NewTableCell(b.Hops).SetTextColor(gray))
|
||||||
|
brewsTable.SetCell(r, 2, tview.NewTableCell(fmt.Sprintf("%d%%", b.Progress)).SetTextColor(green))
|
||||||
|
}
|
||||||
|
brewsTable.SetSelectedFunc(func(row, column int) {
|
||||||
|
b := brews[row]
|
||||||
|
detailText := fmt.Sprintf("\n [yellow]NAME:[-] %s\n [yellow]HOPS:[-] %s\n [yellow]PROGRESS:[-] %d%%\n\n [yellow]NOTES:[-]\n %s\n\n [gray]Press <ESC> to return", b.Name, b.Hops, b.Progress, b.Notes)
|
||||||
|
showDetails(detailText)
|
||||||
|
})
|
||||||
|
|
||||||
|
// --- Page 2: Inventory ---
|
||||||
|
invTable := tview.NewTable().SetSelectable(true, false)
|
||||||
|
for r, item := range inventory {
|
||||||
|
invTable.SetCell(r, 0, tview.NewTableCell(item.Name))
|
||||||
|
invTable.SetCell(r, 1, tview.NewTableCell(fmt.Sprintf("%.1f %s", item.Amount, item.Unit)).SetTextColor(green))
|
||||||
|
}
|
||||||
|
invTable.SetSelectedFunc(func(row, column int) {
|
||||||
|
item := inventory[row]
|
||||||
|
detailText := fmt.Sprintf("\n [yellow]ITEM:[-] %s\n [yellow]TYPE:[-] %s\n [yellow]STOCK:[-] %.1f %s\n\n [gray]Inventory check passed. Ready for next brew.\n\n [gray]Press <ESC> to return", item.Name, item.Type, item.Amount, item.Unit)
|
||||||
|
showDetails(detailText)
|
||||||
|
})
|
||||||
|
|
||||||
|
pages.AddPage("brews", brewsTable, true, true)
|
||||||
|
pages.AddPage("inventory", invTable, true, false)
|
||||||
|
pages.AddPage("details", detailsView, true, false)
|
||||||
|
|
||||||
|
// --- Layout Setup ---
|
||||||
|
mainLayout := tview.NewFlex().SetDirection(tview.FlexRow).
|
||||||
|
AddItem(header, 9, 0, false).
|
||||||
|
AddItem(pages, 0, 1, true).
|
||||||
AddItem(footer, 1, 0, false)
|
AddItem(footer, 1, 0, false)
|
||||||
|
|
||||||
// Global Keybindings
|
root := tview.NewFlex().SetDirection(tview.FlexRow).
|
||||||
|
AddItem(mainLayout, 0, 1, true)
|
||||||
|
|
||||||
|
// --- Global Navigation ---
|
||||||
|
|
||||||
|
showCommandBar := func(label string) {
|
||||||
|
if root.GetItemCount() == 1 {
|
||||||
|
commandBar.SetLabel(label)
|
||||||
|
root.AddItem(commandBar, 1, 0, false)
|
||||||
|
app.SetFocus(commandBar)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hideCommandBar := func() {
|
||||||
|
if root.GetItemCount() > 1 {
|
||||||
|
root.RemoveItem(commandBar)
|
||||||
|
commandBar.SetText("")
|
||||||
|
_, activePage := pages.GetFrontPage()
|
||||||
|
app.SetFocus(activePage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switchTo := func(pageID string, title string) {
|
||||||
|
viewTitle.SetText(" BrewMaster v0.1.0 - " + title)
|
||||||
|
pages.SwitchToPage(pageID)
|
||||||
|
_, active := pages.GetFrontPage()
|
||||||
|
app.SetFocus(active)
|
||||||
|
}
|
||||||
|
switchTo("brews", "Active Brews")
|
||||||
|
|
||||||
|
// --- Input Handling ---
|
||||||
|
|
||||||
|
commandBar.SetDoneFunc(func(key tcell.Key) {
|
||||||
|
if key == tcell.KeyEscape {
|
||||||
|
hideCommandBar()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if key == tcell.KeyEnter {
|
||||||
|
cmd := strings.ToLower(strings.TrimSpace(commandBar.GetText()))
|
||||||
|
switch cmd {
|
||||||
|
case "q", "quit":
|
||||||
|
app.Stop()
|
||||||
|
case "i", "inv":
|
||||||
|
switchTo("inventory", "Inventory")
|
||||||
|
case "b", "brew":
|
||||||
|
switchTo("brews", "Active Brews")
|
||||||
|
}
|
||||||
|
hideCommandBar()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
app.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
|
app.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
|
||||||
if event.Key() == tcell.KeyCtrlC {
|
if app.GetFocus() != commandBar {
|
||||||
app.Stop()
|
// ESC to go back from Details to whatever was previous
|
||||||
os.Exit(0)
|
if event.Key() == tcell.KeyEscape {
|
||||||
|
currentPage, _ := pages.GetFrontPage()
|
||||||
|
if currentPage == "details" {
|
||||||
|
// Default back to brews for now
|
||||||
|
switchTo("brews", "Active Brews")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch event.Rune() {
|
||||||
|
case ':':
|
||||||
|
showCommandBar(": ")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return event
|
return event
|
||||||
})
|
})
|
||||||
|
|
||||||
if err := app.SetRoot(grid, true).EnableMouse(true).Run(); err != nil {
|
if err := app.SetRoot(root, true).Run(); err != nil {
|
||||||
panic(err)
|
fmt.Printf("Error running app: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user