appview: allow timeline db queries to be filterable by users follows #626

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

Signed-off-by: Will Andrews did:plc:dadhhalkfcq3gucaq25hjqon

Changed files
+57 -12
appview
db
pages
templates
timeline
fragments
+38 -10
appview/db/timeline.go
··· 9 10 // TODO: this gathers heterogenous events from different sources and aggregates 11 // them in code; if we did this entirely in sql, we could order and limit and paginate easily 12 - func MakeTimeline(e Execer, limit int, loggedInUserDid string) ([]models.TimelineEvent, error) { 13 var events []models.TimelineEvent 14 15 - repos, err := getTimelineRepos(e, limit, loggedInUserDid) 16 if err != nil { 17 return nil, err 18 } 19 20 - stars, err := getTimelineStars(e, limit, loggedInUserDid) 21 if err != nil { 22 return nil, err 23 } 24 25 - follows, err := getTimelineFollows(e, limit, loggedInUserDid) 26 if err != nil { 27 return nil, err 28 } ··· 70 return isStarred, starCount 71 } 72 73 - func getTimelineRepos(e Execer, limit int, loggedInUserDid string) ([]models.TimelineEvent, error) { 74 - repos, err := GetRepos(e, limit) 75 if err != nil { 76 return nil, err 77 } ··· 125 return events, nil 126 } 127 128 - func getTimelineStars(e Execer, limit int, loggedInUserDid string) ([]models.TimelineEvent, error) { 129 - stars, err := GetStars(e, limit) 130 if err != nil { 131 return nil, err 132 } ··· 166 return events, nil 167 } 168 169 - func getTimelineFollows(e Execer, limit int, loggedInUserDid string) ([]models.TimelineEvent, error) { 170 - follows, err := GetFollows(e, limit) 171 if err != nil { 172 return nil, err 173 }
··· 9 10 // TODO: this gathers heterogenous events from different sources and aggregates 11 // them in code; if we did this entirely in sql, we could order and limit and paginate easily 12 + func MakeTimeline(e Execer, limit int, loggedInUserDid string, limitToUsersIsFollowing bool) ([]models.TimelineEvent, error) { 13 var events []models.TimelineEvent 14 15 + var userIsFollowing []string 16 + if limitToUsersIsFollowing { 17 + following, err := GetFollowing(e, loggedInUserDid) 18 + if err != nil { 19 + return nil, err 20 + } 21 + 22 + userIsFollowing = make([]string, 0, len(following)) 23 + for _, follow := range following { 24 + userIsFollowing = append(userIsFollowing, follow.SubjectDid) 25 + } 26 + } 27 + 28 + repos, err := getTimelineRepos(e, limit, loggedInUserDid, userIsFollowing) 29 if err != nil { 30 return nil, err 31 } 32 33 + stars, err := getTimelineStars(e, limit, loggedInUserDid, userIsFollowing) 34 if err != nil { 35 return nil, err 36 } 37 38 + follows, err := getTimelineFollows(e, limit, loggedInUserDid, userIsFollowing) 39 if err != nil { 40 return nil, err 41 } ··· 83 return isStarred, starCount 84 } 85 86 + func getTimelineRepos(e Execer, limit int, loggedInUserDid string, userIsFollowing []string) ([]models.TimelineEvent, error) { 87 + filters := make([]filter, 0) 88 + if userIsFollowing != nil { 89 + filters = append(filters, FilterIn("did", userIsFollowing)) 90 + } 91 + 92 + repos, err := GetRepos(e, limit, filters...) 93 if err != nil { 94 return nil, err 95 } ··· 143 return events, nil 144 } 145 146 + func getTimelineStars(e Execer, limit int, loggedInUserDid string, userIsFollowing []string) ([]models.TimelineEvent, error) { 147 + filters := make([]filter, 0) 148 + if userIsFollowing != nil { 149 + filters = append(filters, FilterIn("starred_by_did", userIsFollowing)) 150 + } 151 + 152 + stars, err := GetStars(e, limit, filters...) 153 if err != nil { 154 return nil, err 155 } ··· 189 return events, nil 190 } 191 192 + func getTimelineFollows(e Execer, limit int, loggedInUserDid string, userIsFollowing []string) ([]models.TimelineEvent, error) { 193 + filters := make([]filter, 0) 194 + if userIsFollowing != nil { 195 + filters = append(filters, FilterIn("user_did", userIsFollowing)) 196 + } 197 + 198 + follows, err := GetFollows(e, limit, filters...) 199 if err != nil { 200 return nil, err 201 }
+1
appview/pages/pages.go
··· 307 Timeline []models.TimelineEvent 308 Repos []models.Repo 309 GfiLabel *models.LabelDefinition 310 } 311 312 func (p *Pages) Timeline(w io.Writer, params TimelineParams) error {
··· 307 Timeline []models.TimelineEvent 308 Repos []models.Repo 309 GfiLabel *models.LabelDefinition 310 + Filtered bool 311 } 312 313 func (p *Pages) Timeline(w io.Writer, params TimelineParams) error {
+18 -2
appview/pages/templates/timeline/fragments/timeline.html
··· 1 {{ define "timeline/fragments/timeline" }} 2 <div class="py-4"> 3 - <div class="px-6 pb-4"> 4 - <p class="text-xl font-bold dark:text-white">Timeline</p> 5 </div> 6 7 <div class="flex flex-col gap-4">
··· 1 {{ define "timeline/fragments/timeline" }} 2 <div class="py-4"> 3 + 4 + <div class="flex gap-2 px-6 pb-4"> 5 + <div> 6 + <p class="text-xl font-bold dark:text-white">Timeline</p> 7 + </div> 8 + {{ if .LoggedInUser }} 9 + <div> 10 + {{ if .Filtered }} 11 + <a href="/timeline" class="hover:underline text-sm"> 12 + Show All 13 + </a> 14 + {{ else }} 15 + <a href="/timeline?filtered=true" class="hover:underline text-sm"> 16 + Show following only 17 + </a> 18 + {{ end }} 19 + </div> 20 + {{ end }} 21 </div> 22 23 <div class="flex flex-col gap-4">