neofeels/app/graffiti.go

106 lines
2.7 KiB
Go
Raw Permalink Normal View History

2025-01-08 01:14:15 +00:00
package app
import (
"bufio"
"fmt"
2025-01-08 01:14:15 +00:00
"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":
2025-01-09 02:54:03 +00:00
ui.ViewChange <- NewMainMenu(5)
2025-01-08 01:14:15 +00:00
case "Enter", "l", "Right":
if ttbp.GraffitiFree() {
os.Create(ttbp.PathWallLock)
editGraffiti(state)
os.Remove(ttbp.PathWallLock)
}
2025-01-09 02:54:03 +00:00
ui.ViewChange <- NewMainMenu(5)
2025-01-08 01:14:15 +00:00
}
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()
}
2025-01-08 01:14:15 +00:00
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)
}
}
}