neighbors
parent
5c0455b7b9
commit
45367a2b24
|
@ -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:
|
||||||
|
|
|
@ -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
1
go.mod
|
@ -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
2
go.sum
|
@ -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=
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
Loading…
Reference in New Issue