diff --git a/TODO b/TODO deleted file mode 100644 index 6a6d774..0000000 --- a/TODO +++ /dev/null @@ -1,3 +0,0 @@ -- list feels by user -- pipe feels into less -- list global feels diff --git a/app/browse.go b/app/browse.go new file mode 100644 index 0000000..f13b0b6 --- /dev/null +++ b/app/browse.go @@ -0,0 +1,83 @@ +package app + +import ( + "fmt" + "strconv" + + "git.sr.ht/~rockorager/vaxis" + "git.tilde.town/nbsp/neofeels/ttbp" + "git.tilde.town/nbsp/neofeels/ui" +) + +type Browse struct { + title string + list ui.List + help string + posts []ttbp.Post +} + +func NewBrowse() *Browse { + users := ttbp.GetUsers() + posts := []ttbp.Post{} + for _, user := range users { + posts = append(posts, ttbp.GetPostsForUser(user.Name)...) + } + posts = ttbp.SortPostsByRecent(posts) + list := []string{} + for _, post := range posts { + list = append(list, fmt.Sprintf( + "~%-15s %s (%d words)", + post.Author, + post.LastEdited.Format("2006-01-02 15:04"), + post.Words, + )) + } + + return &Browse{ + title, + ui.NewList(list), + "↑↓/kj move ↵ enter q return", + posts, + } +} + +func (browse *Browse) 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": + browse.list.Down() + case "Up", "k": + browse.list.Up() + case "End", "Shift+g": + browse.list.End() + case "Home", "g": + browse.list.Home() + case "0", "1", "2", "3", "4", "5", "6", "7", "8", "9": + i, _ := strconv.Atoi(key.String()) + browse.list.SetIndex(i) + case "q", "h", "Left": + ui.ViewChange <- NewMainMenu() + case "Enter", "l", "Right": + showPost(state, browse.posts[browse.list.Index()]) + } + processed = true + } + browse.Draw(state) + return +} + +func (browse *Browse) Draw(state *ui.State) { + win := state.Window() + win.New(win.Width/2-10, win.Height/2-8, 20, 5).Print(vaxis.Segment{Text: browse.title}) + browse.list.Draw(vaxis.Window{ + Vx: win.Vx, + Parent: nil, + Column: win.Width/2 - 25, + Row: win.Height/2 - 2, + Width: 50, + Height: 10, + }) + win.New(win.Width/2-15, win.Height/2+9, 30, 1).Print(vaxis.Segment{Text: browse.help}) +} diff --git a/app/menu.go b/app/menu.go index cf0c43d..1e076e2 100644 --- a/app/menu.go +++ b/app/menu.go @@ -31,7 +31,7 @@ func NewMainMenu() *MainMenu { "record some feels", "manage your feels", "check out your neighbors", - "browse global feels", // TODO + "browse global feels", "visit your subscriptions", // TODO "scribble some graffiti", // TODO "change your settings", @@ -66,6 +66,8 @@ func (menu *MainMenu) Event(state *ui.State, event vaxis.Event) (processed bool) ui.ViewChange <- NewManagement() case 2: ui.ViewChange <- NewNeighbors() + case 3: + ui.ViewChange <- NewBrowse() case 6: ui.ViewChange <- NewConfig() case 7: diff --git a/ttbp/ttbp.go b/ttbp/ttbp.go index 794a021..4834a84 100644 --- a/ttbp/ttbp.go +++ b/ttbp/ttbp.go @@ -82,9 +82,10 @@ func SortUsersByRecent(users []User) []User { } type Post struct { - Date time.Time - Words int - Author string + Date time.Time + LastEdited time.Time + Words int + Author string } func GetPostsForUser(user string) (posts []Post) { @@ -100,23 +101,39 @@ func GetPostsForUser(user string) (posts []Post) { 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() + + // get number of words in file scanner := bufio.NewScanner(file) scanner.Split(bufio.ScanWords) - + count := 0 for scanner.Scan() { count++ } - } - posts = append([]Post{Post{ - Author: user, - Date: fileDate, - Words: count, - }}, posts...) + // get modtime of file + stat, err := file.Stat() + if err != nil { + continue + } + + posts = append([]Post{Post{ + Author: user, + Date: fileDate, + LastEdited: stat.ModTime(), + Words: count, + }}, posts...) + } } return } + +// SortUsersByRecent sorts posts, putting the posts that were most recently +// edited first in the list. +func SortPostsByRecent(posts []Post) []Post { + sort.Slice(posts, func(i, j int) bool { + return posts[i].LastEdited.After(posts[j].LastEdited) + }) + return posts +}