package app import ( "bufio" "fmt" "os" "os/exec" "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 Graffiti struct { title string content string help string } func NewGraffiti() *Graffiti { var content string if ttbp.GraffitiFree() { content = `the graffiti wall is a world-writeable text file. anyone can scribble on it; anyone can move or delete things. please be considerate of your neighbors when writing on it. no one will be able to visit the wall while you are here, so don't worry about overwriting someone else's work. anything you do to the wall will be recorded if you save the file, and you can cancel your changes by exiting without saving.` } else { content = "sorry, but someone's there right now. try again in a few!" } return &Graffiti{ title, content, "↵ enter q return", } } func (graffiti *Graffiti) 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": close(ui.Quit) case "q", "h", "Left": ui.ViewChange <- NewMainMenu(5) case "Enter", "l", "Right": if ttbp.GraffitiFree() { os.Create(ttbp.PathWallLock) editGraffiti(state) os.Remove(ttbp.PathWallLock) } ui.ViewChange <- NewMainMenu(5) } processed = true } win := state.Window() win.New(win.Width/2-10, win.Height/2-8, 20, 5).Print(vaxis.Segment{Text: graffiti.title}) win.New(win.Width/2-40, win.Height/2-2, 80, 9).Print(vaxis.Segment{Text: graffiti.content}) win.New(win.Width/2-9, win.Height/2+8, 18, 1).Print(vaxis.Segment{Text: graffiti.help}) return } func editGraffiti(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() err := vt.Start(exec.Command(os.ExpandEnv(os.Getenv("EDITOR")), ttbp.PathWall)) 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) } } }