neighbors
This commit is contained in:
		
							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:
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										82
									
								
								app/neighbors.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								app/neighbors.go
									
									
									
									
									
										Normal 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
									
									
									
									
									
								
							
							
						
						
									
										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=
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										81
									
								
								ttbp/ttbp.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								ttbp/ttbp.go
									
									
									
									
									
										Normal 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
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user