neighbors

trunk
nbsp 2025-01-06 23:53:29 +02:00
parent 5c0455b7b9
commit 45367a2b24
No known key found for this signature in database
GPG Key ID: 7184AC1C9835CE48
5 changed files with 170 additions and 2 deletions

View File

@ -30,7 +30,7 @@ func NewMainMenu() *MainMenu {
ui.NewList([]string{ ui.NewList([]string{
"record some feels", "record some feels",
"manage your feels", "manage your feels",
"check out your neighbors", // TODO "check out your neighbors",
"browse global feels", // TODO "browse global feels", // TODO
"visit your subscriptions", // TODO "visit your subscriptions", // TODO
"scribble some graffiti", // TODO "scribble some graffiti", // TODO
@ -64,6 +64,8 @@ func (menu *MainMenu) Event(state *ui.State, event vaxis.Event) (processed bool)
newFeels(state) newFeels(state)
case 1: case 1:
ui.ViewChange <- NewManagement() ui.ViewChange <- NewManagement()
case 2:
ui.ViewChange <- NewNeighbors()
case 6: case 6:
ui.ViewChange <- NewConfig() ui.ViewChange <- NewConfig()
case 7: case 7:

82
app/neighbors.go 100644
View File

@ -0,0 +1,82 @@
package app
import (
"fmt"
"strconv"
"git.sr.ht/~rockorager/vaxis"
"git.tilde.town/nbsp/neofeels/ttbp"
"git.tilde.town/nbsp/neofeels/ui"
"github.com/dustin/go-humanize"
)
type Neighbors struct {
title string
list ui.List
help string
neighbors []ttbp.User
}
func NewNeighbors() *Neighbors {
users := ttbp.SortUsersByRecent(ttbp.GetUsers())
list := []string{}
for _, user := range users {
publishDir := ""
if user.Publishing {
publishDir = fmt.Sprintf("%s%s/%s", ttbp.PathLive, user.Name, user.PublishDir)
}
list = append(list, fmt.Sprintf(
"~%-14s %-15s %-46s",
user.Name,
"("+humanize.Time(user.LastPublished)+")",
publishDir,
))
}
return &Neighbors{
title,
ui.NewList(list),
"↑↓/kj move ↵ enter q return",
users,
}
}
func (neighbors *Neighbors) 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 "Down", "j":
neighbors.list.Down()
case "Up", "k":
neighbors.list.Up()
case "End", "Shift+g":
neighbors.list.End()
case "Home", "g":
neighbors.list.Home()
case "0", "1", "2", "3", "4", "5", "6", "7", "8", "9":
i, _ := strconv.Atoi(key.String())
neighbors.list.SetIndex(i)
case "q", "h", "Left":
ui.ViewChange <- NewMainMenu()
case "Enter", "l", "Right":
}
processed = true
}
neighbors.Draw(state)
return
}
func (neighbors *Neighbors) Draw(state *ui.State) {
win := state.Window()
win.New(win.Width/2-10, win.Height/2-8, 20, 5).Print(vaxis.Segment{Text: neighbors.title})
neighbors.list.Draw(vaxis.Window{
Vx: win.Vx,
Parent: nil,
Column: win.Width/2 - 40,
Row: win.Height/2 - 2,
Width: 80,
Height: 10,
})
win.New(win.Width/2-15, win.Height/2+9, 30, 1).Print(vaxis.Segment{Text: neighbors.help})
}

1
go.mod
View File

@ -7,6 +7,7 @@ require git.sr.ht/~rockorager/vaxis v0.11.0
require ( require (
github.com/containerd/console v1.0.3 // indirect github.com/containerd/console v1.0.3 // indirect
github.com/creack/pty v1.1.18 // indirect github.com/creack/pty v1.1.18 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/mattn/go-runewidth v0.0.14 // indirect github.com/mattn/go-runewidth v0.0.14 // indirect
github.com/mattn/go-sixel v0.0.5 // indirect github.com/mattn/go-sixel v0.0.5 // indirect
github.com/rivo/uniseg v0.4.4 // indirect github.com/rivo/uniseg v0.4.4 // indirect

2
go.sum
View File

@ -6,6 +6,8 @@ github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-sixel v0.0.5 h1:55w2FR5ncuhKhXrM5ly1eiqMQfZsnAHIpYNGZX03Cv8= github.com/mattn/go-sixel v0.0.5 h1:55w2FR5ncuhKhXrM5ly1eiqMQfZsnAHIpYNGZX03Cv8=

81
ttbp/ttbp.go 100644
View File

@ -0,0 +1,81 @@
package ttbp
import (
"encoding/json"
"os"
"path"
"sort"
"time"
"git.tilde.town/nbsp/neofeels/config"
)
var (
PathVar = "/var/global/ttbp"
PathVarWWW = path.Join(PathVar, "www")
PathLive = "https://tilde.town/~"
PathUserFile = path.Join(PathVar, "users.txt")
PathGraff = path.Join(PathVar, "graffiti")
PathWall = path.Join(PathGraff, "wall.txt")
PathWallLock = path.Join(PathGraff, ".lock")
)
type User struct {
Name string
Publishing bool
PublishDir string
LastPublished time.Time
}
// GetUsers gets all users with a valid ttbp config, with their name, publishing
// settings, and date of last publish, if any.
func GetUsers() (users []User) {
userDirs, _ := os.ReadDir("/home")
for _, user := range userDirs {
if !user.IsDir() {
continue
}
if file, err := os.Open(path.Join("/home", user.Name(), ".ttbp/config/ttbprc")); err == nil {
defer file.Close()
// get user config
var config config.Config
decoder := json.NewDecoder(file)
err = decoder.Decode(&config)
if err != nil {
continue
}
// get last published file
entries, err := os.ReadDir(path.Join("/home", user.Name(), ".ttbp/entries"))
if err != nil {
continue
}
var lastPublished time.Time = *new(time.Time)
if len(entries) > 0 {
info, err := entries[len(entries)-1].Info()
if err != nil {
continue
}
lastPublished = info.ModTime()
}
users = append(users, User{
Name: user.Name(),
Publishing: config.Publishing,
PublishDir: config.PublishDir,
LastPublished: lastPublished,
})
}
}
return users
}
// SortUsersByRecent sorts users, putting the users with the most recent
// published feels at the beginning.
func SortUsersByRecent(users []User) []User {
sort.Slice(users, func(i, j int) bool {
return users[i].LastPublished.After(users[j].LastPublished)
})
return users
}