From b66764deb706f2ac2d6f494395ba9c4bea7ebb76 Mon Sep 17 00:00:00 2001 From: Will Andrews Date: Tue, 7 Oct 2025 14:42:30 +0100 Subject: [PATCH] appview/db: allow filtering timeline to following-only --- appview/db/timeline.go | 48 +++++++++++++++++++++++++++++++++--------- appview/state/state.go | 10 +++++++-- 2 files changed, 46 insertions(+), 12 deletions(-) diff --git a/appview/db/timeline.go b/appview/db/timeline.go index c74b1e4e..46439c77 100644 --- a/appview/db/timeline.go +++ b/appview/db/timeline.go @@ -9,20 +9,33 @@ import ( // TODO: this gathers heterogenous events from different sources and aggregates // them in code; if we did this entirely in sql, we could order and limit and paginate easily -func MakeTimeline(e Execer, limit int, loggedInUserDid string) ([]models.TimelineEvent, error) { +func MakeTimeline(e Execer, limit int, loggedInUserDid string, limitToUsersIsFollowing bool) ([]models.TimelineEvent, error) { var events []models.TimelineEvent - repos, err := getTimelineRepos(e, limit, loggedInUserDid) + var userIsFollowing []string + if limitToUsersIsFollowing { + following, err := GetFollowing(e, loggedInUserDid) + if err != nil { + return nil, err + } + + userIsFollowing = make([]string, 0, len(following)) + for _, follow := range following { + userIsFollowing = append(userIsFollowing, follow.SubjectDid) + } + } + + repos, err := getTimelineRepos(e, limit, loggedInUserDid, userIsFollowing) if err != nil { return nil, err } - stars, err := getTimelineStars(e, limit, loggedInUserDid) + stars, err := getTimelineStars(e, limit, loggedInUserDid, userIsFollowing) if err != nil { return nil, err } - follows, err := getTimelineFollows(e, limit, loggedInUserDid) + follows, err := getTimelineFollows(e, limit, loggedInUserDid, userIsFollowing) if err != nil { return nil, err } @@ -70,8 +83,13 @@ func getRepoStarInfo(repo *models.Repo, starStatuses map[string]bool) (bool, int return isStarred, starCount } -func getTimelineRepos(e Execer, limit int, loggedInUserDid string) ([]models.TimelineEvent, error) { - repos, err := GetRepos(e, limit) +func getTimelineRepos(e Execer, limit int, loggedInUserDid string, userIsFollowing []string) ([]models.TimelineEvent, error) { + filters := make([]filter, 0) + if userIsFollowing != nil { + filters = append(filters, FilterIn("did", userIsFollowing)) + } + + repos, err := GetRepos(e, limit, filters...) if err != nil { return nil, err } @@ -125,8 +143,13 @@ func getTimelineRepos(e Execer, limit int, loggedInUserDid string) ([]models.Tim return events, nil } -func getTimelineStars(e Execer, limit int, loggedInUserDid string) ([]models.TimelineEvent, error) { - stars, err := GetStars(e, limit) +func getTimelineStars(e Execer, limit int, loggedInUserDid string, userIsFollowing []string) ([]models.TimelineEvent, error) { + filters := make([]filter, 0) + if userIsFollowing != nil { + filters = append(filters, FilterIn("starred_by_did", userIsFollowing)) + } + + stars, err := GetStars(e, limit, filters...) if err != nil { return nil, err } @@ -166,8 +189,13 @@ func getTimelineStars(e Execer, limit int, loggedInUserDid string) ([]models.Tim return events, nil } -func getTimelineFollows(e Execer, limit int, loggedInUserDid string) ([]models.TimelineEvent, error) { - follows, err := GetFollows(e, limit) +func getTimelineFollows(e Execer, limit int, loggedInUserDid string, userIsFollowing []string) ([]models.TimelineEvent, error) { + filters := make([]filter, 0) + if userIsFollowing != nil { + filters = append(filters, FilterIn("user_did", userIsFollowing)) + } + + follows, err := GetFollows(e, limit, filters...) if err != nil { return nil, err } diff --git a/appview/state/state.go b/appview/state/state.go index fa5624aa..38a29964 100644 --- a/appview/state/state.go +++ b/appview/state/state.go @@ -258,11 +258,14 @@ func (s *State) HomeOrTimeline(w http.ResponseWriter, r *http.Request) { func (s *State) Timeline(w http.ResponseWriter, r *http.Request) { user := s.oauth.GetUser(r) + // TODO: set this flag based on the UI + filtered := false + var userDid string if user != nil { userDid = user.Did } - timeline, err := db.MakeTimeline(s.db, 50, userDid) + timeline, err := db.MakeTimeline(s.db, 50, userDid, filtered) if err != nil { log.Println(err) s.pages.Notice(w, "timeline", "Uh oh! Failed to load timeline.") @@ -326,7 +329,10 @@ func (s *State) UpgradeBanner(w http.ResponseWriter, r *http.Request) { } func (s *State) Home(w http.ResponseWriter, r *http.Request) { - timeline, err := db.MakeTimeline(s.db, 5, "") + // TODO: set this flag based on the UI + filtered := false + + timeline, err := db.MakeTimeline(s.db, 5, "", filtered) if err != nil { log.Println(err) s.pages.Notice(w, "timeline", "Uh oh! Failed to load timeline.") -- 2.43.0