graffiti!

trunk
nbsp 2025-01-08 03:14:15 +02:00
parent 64ce7e3777
commit c71a473d55
No known key found for this signature in database
GPG Key ID: 7184AC1C9835CE48
4 changed files with 101 additions and 1 deletions

92
app/graffiti.go 100644
View File

@ -0,0 +1,92 @@
package app
import (
"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()
case "Enter", "l", "Right":
if ttbp.GraffitiFree() {
os.Create(ttbp.PathWallLock)
editGraffiti(state)
os.Remove(ttbp.PathWallLock)
}
ui.ViewChange <- NewMainMenu()
}
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) {
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)
}
}
}

View File

@ -34,7 +34,7 @@ func NewMainMenu() *MainMenu {
"check out your neighbors", "check out your neighbors",
"browse global feels", "browse global feels",
"visit your subscriptions", "visit your subscriptions",
"scribble some graffiti", // TODO "scribble some graffiti",
"change your settings", "change your settings",
"see credits", "see credits",
"read documentation", "read documentation",
@ -71,6 +71,8 @@ func (menu *MainMenu) Event(state *ui.State, event vaxis.Event) (processed bool)
ui.ViewChange <- NewBrowse() ui.ViewChange <- NewBrowse()
case 4: case 4:
ui.ViewChange <- NewSubscriptions() ui.ViewChange <- NewSubscriptions()
case 5:
ui.ViewChange <- NewGraffiti()
case 6: case 6:
ui.ViewChange <- NewConfig() ui.ViewChange <- NewConfig()
case 7: case 7:

View File

@ -47,6 +47,7 @@ press ↵ to set up an account, or Ctrl+c to quit. you can always come back late
os.WriteFile(path.Join(ttbp.PathUserConfig, "footer.txt"), footer, 0644) os.WriteFile(path.Join(ttbp.PathUserConfig, "footer.txt"), footer, 0644)
os.WriteFile(path.Join(ttbp.PathUserConfig, "style.css"), style, 0644) os.WriteFile(path.Join(ttbp.PathUserConfig, "style.css"), style, 0644)
config.Default.Write() config.Default.Write()
// TODO: edit users.txt
} }
func main() { func main() {

View File

@ -331,3 +331,8 @@ func writeEntry(post Post) string {
buf.String(), dateString, buf.String(), dateString,
) )
} }
func GraffitiFree() bool {
_, err := os.Stat(PathWallLock)
return os.IsNotExist(err)
}