package app import ( "bufio" "fmt" "os" "os/exec" "path" "strconv" "time" "git.sr.ht/~rockorager/vaxis" "git.sr.ht/~rockorager/vaxis/widgets/term" "git.tilde.town/nbsp/neofeels/ttbp" "git.tilde.town/nbsp/neofeels/ui" ) type MainMenu struct { title string list ui.List help string } const title = ` ___ __ / _/__ ___ / /__ / _/ -_) -_) (_-< /_/ \__/\__/_/___/ neofeels 0.1.0` func NewMainMenu(index int) *MainMenu { return &MainMenu{ title, ui.NewList([]string{ "record some feels", "manage your feels", "check out your neighbors", "browse global feels", "visit your subscriptions", "scribble some graffiti", "change your settings", "see credits", "read documentation", }, index), "↑↓/kj move ↵ enter q exit", } } func (menu *MainMenu) Event(state *ui.State, event vaxis.Event) (processed bool) { if key, ok := event.(vaxis.Key); ok && key.EventType == vaxis.EventPress { switch key.String() { case "Ctrl+c", "Ctrl+d", "q": close(ui.Quit) case "Down", "j", "Ctrl+n": menu.list.Down() case "Up", "k", "Ctrl+p": menu.list.Up() case "End", "Shift+g": menu.list.End() case "Home", "g": menu.list.Home() case "0", "1", "2", "3", "4", "5", "6", "7", "8": i, _ := strconv.Atoi(key.String()) menu.list.SetIndex(i) case "Enter", "l", "Right": switch menu.list.Index() { case 0: newFeels(state) case 1: ui.ViewChange <- NewManagement(0) case 2: ui.ViewChange <- NewNeighbors(0) case 3: ui.ViewChange <- NewBrowse() case 4: ui.ViewChange <- NewSubscriptions(0) case 5: ui.ViewChange <- NewGraffiti() case 6: ui.ViewChange <- NewConfig() case 7: ui.ViewChange <- NewCredits() case 8: showManpage(state) } } processed = true } win := state.Window() win.New(win.Width/2-10, win.Height/2-8, 20, 5).Print(vaxis.Segment{Text: menu.title}) menu.list.Draw(vaxis.Window{ Vx: win.Vx, Parent: nil, Column: win.Width/2 - 14, Row: win.Height/2 - 2, Width: 28, Height: 10, }) win.New(win.Width/2-14, win.Height/2+8, 28, 1).Print(vaxis.Segment{Text: menu.help}) return } func showManpage(state *ui.State) { state.HideCursor() vt := term.New() vt.TERM = os.Getenv("TERM") vt.Attach(state.PostEvent()) vt.Focus() err := vt.Start(exec.Command("man", "neofeels")) if err != nil { panic(err) } defer vt.Close() for ev := range state.Events() { switch ev.(type) { case term.EventClosed: state.HideCursor() state.Window().Clear() return case vaxis.Redraw: vt.Draw(state.Window()) state.Render() continue } // for some reason vaxis doubles all events for Press/Release so this just ignores releases if key, ok := ev.(vaxis.Key); ok && key.EventType == vaxis.EventPress { vt.Update(ev) } } } func newFeels(state *ui.State) { // if $EDITOR isn't set, warn about it, and use nano editor := os.ExpandEnv(os.Getenv("EDITOR")) if editor == "" { editor = "nano" state.Suspend() fmt.Print("$EDITOR not found, using nano. press ↵ to continue") input := bufio.NewScanner(os.Stdin) input.Scan() state.Resume() } state.HideCursor() vt := term.New() vt.TERM = os.Getenv("TERM") vt.Attach(state.PostEvent()) vt.Focus() now := time.Now() err := vt.Start(exec.Command(editor, path.Join(ttbp.PathUserEntries, now.Format("20060102")+".txt"))) if err != nil { panic(err) } defer vt.Close() for ev := range state.Events() { switch ev.(type) { case term.EventClosed: state.HideCursor() state.Window().Clear() ttbp.NewNopub(now) ttbp.Publish() ui.ViewChange <- NewPosted() return case vaxis.Redraw: vt.Draw(state.Window()) state.Render() continue } // for some reason vaxis doubles all events for Press/Release so this just ignores releases if key, ok := ev.(vaxis.Key); ok && key.EventType == vaxis.EventPress { vt.Update(ev) } } }