diff --git a/cmd/review/main.go b/cmd/review/main.go index 76d4779..0b039e2 100644 --- a/cmd/review/main.go +++ b/cmd/review/main.go @@ -2,13 +2,16 @@ package main import ( "encoding/json" + "errors" "fmt" "math/rand" "os" + "os/user" "path" "strings" "time" + tuser "git.tilde.town/tildetown/town/user" "github.com/gdamore/tcell/v2" "github.com/rivo/tview" ) @@ -103,6 +106,18 @@ func getSignups() ([]townSignup, error) { } func _main() error { + u, err := user.Current() + if err != nil { + return fmt.Errorf("that's my purse. I don't know you! %w", err) + } + isAdmin, err := tuser.IsAdmin(u) + if err != nil { + return fmt.Errorf("that's my purse. I don't know you! %w", err) + } + + if !isAdmin { + return errors.New("this command can only be run by a town admin") + } rand.Seed(time.Now().Unix()) signups, err := getSignups() @@ -112,9 +127,6 @@ func _main() error { signupIx := 0 - pages := tview.NewPages() - mainFlex := tview.NewFlex() - title := tview.NewTextView() title.SetText(getTitle()) title.SetTextAlign(tview.AlignCenter) @@ -135,12 +147,34 @@ func _main() error { legend.SetTextAlign(tview.AlignCenter) legend.SetBackgroundColor(tcell.ColorBlack) + count := tview.NewTextView() + count.SetDynamicColors(true) + updateCount := func() { + count.SetText(fmt.Sprintf("[-:-:b]%d pending signups[-:-:-]", len(signups))) + } + updateCount() + + bottomFlex := tview.NewFlex() + bottomFlex.SetDirection(tview.FlexColumn) + bottomFlex.AddItem(count, 0, 1, false) + bottomFlex.AddItem(legend, 0, 10, false) + + mainFlex := tview.NewFlex() mainFlex.SetDirection(tview.FlexRow) mainFlex.AddItem(title, 1, -1, false) mainFlex.AddItem(appView, 0, 1, true) - mainFlex.AddItem(legend, 1, -1, false) + mainFlex.AddItem(bottomFlex, 1, -1, false) + + pages := tview.NewPages() + + errorModal := tview.NewModal() + errorModal.AddButtons([]string{"damn"}) + errorModal.SetDoneFunc(func(ix int, _ string) { + pages.SwitchToPage("main") + }) pages.AddPage("main", mainFlex, true, true) + pages.AddPage("error", errorModal, false, false) // TODO page for textarea to notate app := tview.NewApplication() @@ -148,32 +182,74 @@ func _main() error { // TODO count of pending signups somewhere + // TODO replace imperative shit with signupManager + advanceSignup := func() { + if len(signups) == 0 { + appView.SetText("no signups found.") + return + } + signupIx++ + if signupIx == len(signups) { + signupIx = 0 + } + appView.SetText(signups[signupIx].Render()) + } + + removeSignup := func(signup townSignup) { + newSignups := []townSignup{} + for ix, s := range signups { + if ix != signupIx { + newSignups = append(newSignups, s) + } + } + signups = newSignups + if len(signups) > 0 { + if signupIx >= len(signups) { + signupIx = 0 + } + } + appView.SetText(signups[signupIx].Render()) + } + app.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey { switch event.Rune() { case 's': - signupIx++ - if signupIx == len(signups) { - signupIx = 0 - } - appView.SetText(signups[signupIx].Render()) + advanceSignup() case 'r': - signupIx = rand.Intn(len(signups)) - appView.SetText(signups[signupIx].Render()) + if len(signups) > 0 { + signupIx = rand.Intn(len(signups)) + appView.SetText(signups[signupIx].Render()) + } case 'A': - err := signups[signupIx].Accept() - if err != nil { - // TODO report in app - panic(fmt.Errorf("failed to approve '%s': %w", signups[signupIx].Filename, err)) + if len(signups) == 0 { + return nil + } + signup := signups[signupIx] + err := signup.Accept() + if err != nil { + errorModal.SetText(fmt.Sprintf("error! failed to approve '%s': %s", signup.Filename, err.Error())) + pages.SwitchToPage("error") + } else { + removeSignup(signup) + updateCount() } - // TODO remove from signups list case 'R': - err = signups[signupIx].Reject() - if err != nil { - // TODO report in app - panic(fmt.Errorf("failed to rejec t'%s': %w", signups[signupIx].Filename, err)) + if len(signups) == 0 { + return nil + } + signup := signups[signupIx] + err = signup.Reject() + if err != nil { + errorModal.SetText(fmt.Sprintf("error! failed to reject '%s': %s", signup.Filename, err.Error())) + pages.SwitchToPage("error") + } else { + removeSignup(signup) + updateCount() + } + case 'N': + if len(signups) == 0 { + return nil } - // TODO remove from signups list - case 'n': // TODO notate case 'Q': app.Stop()