diff --git a/TODO b/TODO new file mode 100644 index 0000000..6a6d774 --- /dev/null +++ b/TODO @@ -0,0 +1,3 @@ +- list feels by user +- pipe feels into less +- list global feels diff --git a/app/neighbors.go b/app/neighbors.go index 50f4cb5..bb03b0e 100644 --- a/app/neighbors.go +++ b/app/neighbors.go @@ -60,6 +60,7 @@ func (neighbors *Neighbors) Event(state *ui.State, event vaxis.Event) (processed case "q", "h", "Left": ui.ViewChange <- NewMainMenu() case "Enter", "l", "Right": + ui.ViewChange <- NewUserPage(neighbors.neighbors[neighbors.list.Index()].Name) } processed = true } diff --git a/app/user.go b/app/user.go new file mode 100644 index 0000000..7f37130 --- /dev/null +++ b/app/user.go @@ -0,0 +1,112 @@ +package app + +import ( + "fmt" + "os" + "os/exec" + "path" + "strconv" + + "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 UserPage struct { + title string + list ui.List + help string + posts []ttbp.Post +} + +func NewUserPage(user string) *UserPage { + posts := ttbp.GetPostsForUser(user) + list := []string{} + for _, post := range posts { + list = append(list, fmt.Sprintf( + "%s (%d words)", + post.Date.Format("2006-01-02"), + post.Words, + )) + } + + return &UserPage{ + title, + ui.NewList(list), + "↑↓/kj move ↵ enter q return", + posts, + } +} + +func (user *UserPage) 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": + user.list.Down() + case "Up", "k": + user.list.Up() + case "End", "Shift+g": + user.list.End() + case "Home", "g": + user.list.Home() + case "0", "1", "2", "3", "4", "5", "6", "7", "8", "9": + i, _ := strconv.Atoi(key.String()) + user.list.SetIndex(i) + case "q", "h", "Left": + ui.ViewChange <- NewNeighbors() + case "Enter", "l", "Right": + showPost(state, user.posts[user.list.Index()]) + } + processed = true + } + user.Draw(state) + return +} + +func (user *UserPage) Draw(state *ui.State) { + win := state.Window() + win.New(win.Width/2-10, win.Height/2-8, 20, 5).Print(vaxis.Segment{Text: user.title}) + user.list.Draw(vaxis.Window{ + Vx: win.Vx, + Parent: nil, + Column: win.Width/2 - 14, + Row: win.Height/2 - 2, + Width: 28, + Height: 10, + }) + win.New(win.Width/2-15, win.Height/2+9, 30, 1).Print(vaxis.Segment{Text: user.help}) +} + +func showPost(state *ui.State, post ttbp.Post) { + state.HideCursor() + vt := term.New() + vt.TERM = os.Getenv("TERM") + vt.Attach(state.PostEvent()) + vt.Focus() + err := vt.Start(exec.Command("less", path.Join("/home", post.Author, ".ttbp/entries", post.Date.Format("20060102")+".txt"))) + 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) + } + } +} diff --git a/ttbp/ttbp.go b/ttbp/ttbp.go index 4f2354a..ec2a1ef 100644 --- a/ttbp/ttbp.go +++ b/ttbp/ttbp.go @@ -1,6 +1,7 @@ package ttbp import ( + "bufio" "encoding/json" "os" "path" @@ -79,3 +80,43 @@ func SortUsersByRecent(users []User) []User { }) return users } + +type Post struct { + Date time.Time + Words int + Author string +} + +func GetPostsForUser(user string) (posts []Post) { + postFiles, err := os.ReadDir(path.Join("/home", user, ".ttbp/entries")) + if err != nil { + return + } + for _, post := range postFiles { + // retrieve date of file + // assume file ends in .txt + fileDate, err := time.Parse("20060102.txt", post.Name()) + if err != nil { + continue + } + + // get number of words in file + count := 0 + if file, err := os.Open(path.Join("/home", user, ".ttbp/entries", post.Name())); err == nil { + defer file.Close() + scanner := bufio.NewScanner(file) + scanner.Split(bufio.ScanWords) + + for scanner.Scan() { + count++ + } + } + + posts = append(posts, Post{ + Author: user, + Date: fileDate, + Words: count, + }) + } + return +}