appview/timeline: backend only changes that allows filtereing the timeline based on who the user is following #639

merged
opened by willdot.net targeting master from willdot.net/tangled-core: feat/be-timeline-filter

This adds in just the backend changes required for filtering a users timeline based on the users that they follow.

Changed files
+46 -12
appview
+38 -10
appview/db/timeline.go
···
// 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
}
···
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
}
···
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
}
···
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
}
+8 -2
appview/state/state.go
···
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.")
···
}
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.")