Mirror of @tangled.org/core. Running on a Raspberry Pi Zero 2 (Please be gentle).
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

appview/pages: rework followers/following/repos pages to use profile layout

Signed-off-by: oppiliappan <me@oppi.li>

authored by

oppiliappan and committed by
Tangled
6fc9fb30 52a70a83

+217 -210
+2 -2
appview/db/repos.go
··· 310 310 311 311 slices.SortFunc(repos, func(a, b Repo) int { 312 312 if a.Created.After(b.Created) { 313 - return 1 313 + return -1 314 314 } 315 - return -1 315 + return 1 316 316 }) 317 317 318 318 return repos, nil
+30 -19
appview/pages/pages.go
··· 444 444 return p.executeProfile("user/overview", w, params) 445 445 } 446 446 447 - Profile *db.Profile 448 - } 449 - 450 - func (p *Pages) ProfileHomePage(w io.Writer, params ProfileHomePageParams) error { 451 - return p.execute("user/profile", w, params) 452 - } 453 - 454 - type ReposPageParams struct { 447 + type ProfileReposParams struct { 455 448 LoggedInUser *oauth.User 456 449 Repos []db.Repo 457 - Card ProfileCard 450 + Card *ProfileCard 451 + Active string 458 452 } 459 453 460 - func (p *Pages) ReposPage(w io.Writer, params ReposPageParams) error { 461 - return p.execute("user/repos", w, params) 454 + func (p *Pages) ProfileRepos(w io.Writer, params ProfileReposParams) error { 455 + params.Active = "repos" 456 + return p.executeProfile("user/repos", w, params) 457 + } 458 + 459 + type ProfileStarredParams struct { 460 + LoggedInUser *oauth.User 461 + Repos []db.Repo 462 + Card *ProfileCard 463 + Active string 464 + } 465 + 466 + func (p *Pages) ProfileStarred(w io.Writer, params ProfileStarredParams) error { 467 + params.Active = "starred" 468 + return p.executeProfile("user/starred", w, params) 462 469 } 463 470 464 471 type FollowCard struct { ··· 476 469 Profile *db.Profile 477 470 } 478 471 479 - type FollowersPageParams struct { 472 + type ProfileFollowersParams struct { 480 473 LoggedInUser *oauth.User 481 474 Followers []FollowCard 482 - Card ProfileCard 475 + Card *ProfileCard 476 + Active string 483 477 } 484 478 485 - func (p *Pages) FollowersPage(w io.Writer, params FollowersPageParams) error { 486 - return p.execute("user/followers", w, params) 479 + func (p *Pages) ProfileFollowers(w io.Writer, params ProfileFollowersParams) error { 480 + params.Active = "overview" 481 + return p.executeProfile("user/followers", w, params) 487 482 } 488 483 489 - type FollowingPageParams struct { 484 + type ProfileFollowingParams struct { 490 485 LoggedInUser *oauth.User 491 486 Following []FollowCard 492 - Card ProfileCard 487 + Card *ProfileCard 488 + Active string 493 489 } 494 490 495 - func (p *Pages) FollowingPage(w io.Writer, params FollowingPageParams) error { 496 - return p.execute("user/following", w, params) 491 + func (p *Pages) ProfileFollowing(w io.Writer, params ProfileFollowingParams) error { 492 + params.Active = "overview" 493 + return p.executeProfile("user/following", w, params) 497 494 } 498 495 499 496 type FollowFragmentParams struct {
+4 -16
appview/pages/templates/user/followers.html
··· 1 1 {{ define "title" }}{{ or .Card.UserHandle .Card.UserDid }} · followers {{ end }} 2 2 3 - {{ define "extrameta" }} 4 - <meta property="og:title" content="{{ or .Card.UserHandle .Card.UserDid }}'s followers" /> 5 - <meta property="og:type" content="object" /> 6 - <meta property="og:url" content="https://tangled.sh/{{ or .Card.UserHandle .Card.UserDid }}?tab=followers" /> 7 - <meta property="og:description" content="{{ or .Card.Profile.Description .Card.UserHandle .Card.UserDid }}" /> 8 - {{ end }} 9 - 10 - {{ define "content" }} 11 - <div class="grid grid-cols-1 md:grid-cols-11 gap-4"> 12 - <div class="md:col-span-3 order-1 md:order-1"> 13 - {{ template "user/fragments/profileCard" .Card }} 14 - </div> 15 - <div id="all-followers" class="md:col-span-8 order-2 md:order-2"> 16 - {{ block "followers" . }}{{ end }} 17 - </div> 18 - </div> 3 + {{ define "profileContent" }} 4 + <div id="all-followers" class="md:col-span-8 order-2 md:order-2"> 5 + {{ block "followers" . }}{{ end }} 6 + </div> 19 7 {{ end }} 20 8 21 9 {{ define "followers" }}
+4 -16
appview/pages/templates/user/following.html
··· 1 1 {{ define "title" }}{{ or .Card.UserHandle .Card.UserDid }} · following {{ end }} 2 2 3 - {{ define "extrameta" }} 4 - <meta property="og:title" content="{{ or .Card.UserHandle .Card.UserDid }}'s following" /> 5 - <meta property="og:type" content="object" /> 6 - <meta property="og:url" content="https://tangled.sh/{{ or .Card.UserHandle .Card.UserDid }}?tab=following" /> 7 - <meta property="og:description" content="{{ or .Card.Profile.Description .Card.UserHandle .Card.UserDid }}" /> 8 - {{ end }} 9 - 10 - {{ define "content" }} 11 - <div class="grid grid-cols-1 md:grid-cols-11 gap-4"> 12 - <div class="md:col-span-3 order-1 md:order-1"> 13 - {{ template "user/fragments/profileCard" .Card }} 14 - </div> 15 - <div id="all-following" class="md:col-span-8 order-2 md:order-2"> 16 - {{ block "following" . }}{{ end }} 17 - </div> 18 - </div> 3 + {{ define "profileContent" }} 4 + <div id="all-following" class="md:col-span-8 order-2 md:order-2"> 5 + {{ block "following" . }}{{ end }} 6 + </div> 19 7 {{ end }} 20 8 21 9 {{ define "following" }}
+7 -18
appview/pages/templates/user/repos.html
··· 1 1 {{ define "title" }}{{ or .Card.UserHandle .Card.UserDid }} · repos {{ end }} 2 2 3 - {{ define "extrameta" }} 4 - <meta property="og:title" content="{{ or .Card.UserHandle .Card.UserDid }}'s repos" /> 5 - <meta property="og:type" content="object" /> 6 - <meta property="og:url" content="https://tangled.sh/{{ or .Card.UserHandle .Card.UserDid }}?tab=repos" /> 7 - <meta property="og:description" content="{{ or .Card.Profile.Description .Card.UserHandle .Card.UserDid }}" /> 8 - {{ end }} 9 - 10 - {{ define "content" }} 11 - <div class="grid grid-cols-1 md:grid-cols-11 gap-4"> 12 - <div class="md:col-span-3 order-1 md:order-1"> 13 - {{ template "user/fragments/profileCard" .Card }} 14 - </div> 15 - <div id="all-repos" class="md:col-span-8 order-2 md:order-2"> 16 - {{ block "ownRepos" . }}{{ end }} 17 - </div> 18 - </div> 3 + {{ define "profileContent" }} 4 + <div id="all-repos" class="md:col-span-8 order-2 md:order-2"> 5 + {{ block "ownRepos" . }}{{ end }} 6 + </div> 19 7 {{ end }} 20 8 21 9 {{ define "ownRepos" }} 22 - <p class="text-sm font-bold p-2 dark:text-white">ALL REPOSITORIES</p> 23 10 <div id="repos" class="grid grid-cols-1 gap-4 mb-6"> 24 11 {{ range .Repos }} 25 - {{ template "user/fragments/repoCard" (list $ . false) }} 12 + <div class="border border-gray-200 dark:border-gray-700 rounded-sm"> 13 + {{ template "user/fragments/repoCard" (list $ . false) }} 14 + </div> 26 15 {{ else }} 27 16 <p class="px-6 dark:text-white">This user does not have any repos yet.</p> 28 17 {{ end }}
+19
appview/pages/templates/user/starred.html
··· 1 + {{ define "title" }}{{ or .Card.UserHandle .Card.UserDid }} · repos {{ end }} 2 + 3 + {{ define "profileContent" }} 4 + <div id="all-repos" class="md:col-span-8 order-2 md:order-2"> 5 + {{ block "starredRepos" . }}{{ end }} 6 + </div> 7 + {{ end }} 8 + 9 + {{ define "starredRepos" }} 10 + <div id="repos" class="grid grid-cols-1 gap-4 mb-6"> 11 + {{ range .Repos }} 12 + <div class="border border-gray-200 dark:border-gray-700 rounded-sm"> 13 + {{ template "user/fragments/repoCard" (list $ . true) }} 14 + </div> 15 + {{ else }} 16 + <p class="px-6 dark:text-white">This user does not have any starred repos yet.</p> 17 + {{ end }} 18 + </div> 19 + {{ end }}
+151 -139
appview/state/profile.go
··· 17 17 "github.com/gorilla/feeds" 18 18 "tangled.sh/tangled.sh/core/api/tangled" 19 19 "tangled.sh/tangled.sh/core/appview/db" 20 - "tangled.sh/tangled.sh/core/appview/oauth" 20 + // "tangled.sh/tangled.sh/core/appview/oauth" 21 21 "tangled.sh/tangled.sh/core/appview/pages" 22 22 ) 23 23 24 24 func (s *State) Profile(w http.ResponseWriter, r *http.Request) { 25 25 tabVal := r.URL.Query().Get("tab") 26 26 switch tabVal { 27 - case "": 28 - s.profileHomePage(w, r) 27 + case "", "overview": 28 + s.profileOverview(w, r) 29 29 case "repos": 30 30 s.reposPage(w, r) 31 31 case "followers": 32 32 s.followersPage(w, r) 33 33 case "following": 34 34 s.followingPage(w, r) 35 + case "starred": 36 + s.starredPage(w, r) 35 37 } 36 38 } 37 39 38 - type ProfilePageParams struct { 39 - Id identity.Identity 40 - LoggedInUser *oauth.User 41 - Card pages.ProfileCard 42 - } 43 - 44 - func (s *State) profilePage(w http.ResponseWriter, r *http.Request) *ProfilePageParams { 40 + func (s *State) profile(r *http.Request) (*pages.ProfileCard, error) { 45 41 didOrHandle := chi.URLParam(r, "user") 46 42 if didOrHandle == "" { 47 - http.Error(w, "bad request", http.StatusBadRequest) 48 - return nil 43 + return nil, fmt.Errorf("empty DID or handle") 49 44 } 50 45 51 46 ident, ok := r.Context().Value("resolvedId").(identity.Identity) 52 47 if !ok { 53 - log.Printf("malformed middleware") 54 - w.WriteHeader(http.StatusInternalServerError) 55 - return nil 48 + return nil, fmt.Errorf("failed to resolve ID") 56 49 } 57 50 did := ident.DID.String() 58 51 59 52 profile, err := db.GetProfile(s.db, did) 60 53 if err != nil { 61 - log.Printf("getting profile data for %s: %s", did, err) 62 - s.pages.Error500(w) 63 - return nil 54 + return nil, fmt.Errorf("failed to get profile: %w", err) 64 55 } 65 56 66 57 followStats, err := db.GetFollowerFollowingCount(s.db, did) 67 58 if err != nil { 68 - log.Printf("getting follow stats for %s: %s", did, err) 59 + return nil, fmt.Errorf("failed to get follower stats: %w", err) 69 60 } 70 61 71 62 loggedInUser := s.oauth.GetUser(r) ··· 65 74 followStatus = db.GetFollowStatus(s.db, loggedInUser.Did, did) 66 75 } 67 76 68 - return &ProfilePageParams{ 69 - Id: ident, 70 - LoggedInUser: loggedInUser, 71 - Card: pages.ProfileCard{ 72 - UserDid: did, 73 - UserHandle: ident.Handle.String(), 74 - Profile: profile, 75 - FollowStatus: followStatus, 76 - FollowersCount: followStats.Followers, 77 - FollowingCount: followStats.Following, 78 - }, 77 + now := time.Now() 78 + startOfYear := time.Date(now.Year(), 1, 1, 0, 0, 0, 0, time.UTC) 79 + punchcard, err := db.MakePunchcard( 80 + s.db, 81 + db.FilterEq("did", did), 82 + db.FilterGte("date", startOfYear.Format(time.DateOnly)), 83 + db.FilterLte("date", now.Format(time.DateOnly)), 84 + ) 85 + if err != nil { 86 + return nil, fmt.Errorf("failed to get punchcard for %s: %w", did, err) 79 87 } 88 + 89 + return &pages.ProfileCard{ 90 + UserDid: did, 91 + UserHandle: ident.Handle.String(), 92 + Profile: profile, 93 + FollowStatus: followStatus, 94 + FollowersCount: followStats.Followers, 95 + FollowingCount: followStats.Following, 96 + Punchcard: punchcard, 97 + }, nil 80 98 } 81 99 82 - func (s *State) profileHomePage(w http.ResponseWriter, r *http.Request) { 83 - pageWithProfile := s.profilePage(w, r) 84 - if pageWithProfile == nil { 100 + func (s *State) profileOverview(w http.ResponseWriter, r *http.Request) { 101 + l := s.logger.With("handler", "profileHomePage") 102 + 103 + profile, err := s.profile(r) 104 + if err != nil { 105 + l.Error("failed to build profile card", "err", err) 106 + s.pages.Error500(w) 85 107 return 86 108 } 109 + l = l.With("profileDid", profile.UserDid, "profileHandle", profile.UserHandle) 87 110 88 - id := pageWithProfile.Id 89 111 repos, err := db.GetRepos( 90 112 s.db, 91 113 0, 92 - db.FilterEq("did", id.DID), 114 + db.FilterEq("did", profile.UserDid), 93 115 ) 94 116 if err != nil { 95 - log.Printf("getting repos for %s: %s", id.DID, err) 117 + l.Error("failed to fetch repos", "err", err) 96 118 } 97 119 98 - profile := pageWithProfile.Card.Profile 99 120 // filter out ones that are pinned 100 121 pinnedRepos := []db.Repo{} 101 122 for i, r := range repos { 102 123 // if this is a pinned repo, add it 103 - if slices.Contains(profile.PinnedRepos[:], r.RepoAt()) { 124 + if slices.Contains(profile.Profile.PinnedRepos[:], r.RepoAt()) { 104 125 pinnedRepos = append(pinnedRepos, r) 105 126 } 106 127 107 128 // if there are no saved pins, add the first 4 repos 108 - if profile.IsPinnedReposEmpty() && i < 4 { 129 + if profile.Profile.IsPinnedReposEmpty() && i < 4 { 109 130 pinnedRepos = append(pinnedRepos, r) 110 131 } 111 132 } 112 133 113 - collaboratingRepos, err := db.CollaboratingIn(s.db, id.DID.String()) 134 + collaboratingRepos, err := db.CollaboratingIn(s.db, profile.UserDid) 114 135 if err != nil { 115 - log.Printf("getting collaborating repos for %s: %s", id.DID, err) 136 + l.Error("failed to fetch collaborating repos", "err", err) 116 137 } 117 138 118 139 pinnedCollaboratingRepos := []db.Repo{} 119 140 for _, r := range collaboratingRepos { 120 141 // if this is a pinned repo, add it 121 - if slices.Contains(profile.PinnedRepos[:], r.RepoAt()) { 142 + if slices.Contains(profile.Profile.PinnedRepos[:], r.RepoAt()) { 122 143 pinnedCollaboratingRepos = append(pinnedCollaboratingRepos, r) 123 144 } 124 145 } 125 146 126 - timeline, err := db.MakeProfileTimeline(s.db, id.DID.String()) 147 + timeline, err := db.MakeProfileTimeline(s.db, profile.UserDid) 127 148 if err != nil { 128 - log.Printf("failed to create profile timeline for %s: %s", id.DID, err) 149 + l.Error("failed to create timeline", "err", err) 129 150 } 130 151 131 - var didsToResolve []string 132 - for _, r := range collaboratingRepos { 133 - didsToResolve = append(didsToResolve, r.Did) 134 - } 135 - for _, byMonth := range timeline.ByMonth { 136 - for _, pe := range byMonth.PullEvents.Items { 137 - didsToResolve = append(didsToResolve, pe.Repo.Did) 138 - } 139 - for _, ie := range byMonth.IssueEvents.Items { 140 - didsToResolve = append(didsToResolve, ie.Metadata.Repo.Did) 141 - } 142 - for _, re := range byMonth.RepoEvents { 143 - didsToResolve = append(didsToResolve, re.Repo.Did) 144 - if re.Source != nil { 145 - didsToResolve = append(didsToResolve, re.Source.Did) 146 - } 147 - } 148 - } 149 - 150 - now := time.Now() 151 - startOfYear := time.Date(now.Year(), 1, 1, 0, 0, 0, 0, time.UTC) 152 - punchcard, err := db.MakePunchcard( 153 - s.db, 154 - db.FilterEq("did", id.DID), 155 - db.FilterGte("date", startOfYear.Format(time.DateOnly)), 156 - db.FilterLte("date", now.Format(time.DateOnly)), 157 - ) 158 - if err != nil { 159 - log.Println("failed to get punchcard for did", "did", id.DID, "err", err) 160 - } 161 - 162 - s.pages.ProfileHomePage(w, pages.ProfileHomePageParams{ 163 - LoggedInUser: pageWithProfile.LoggedInUser, 152 + s.pages.ProfileOverview(w, pages.ProfileOverviewParams{ 153 + LoggedInUser: s.oauth.GetUser(r), 154 + Card: profile, 164 155 Repos: pinnedRepos, 165 156 CollaboratingRepos: pinnedCollaboratingRepos, 166 - Card: pageWithProfile.Card, 167 - Punchcard: punchcard, 168 157 ProfileTimeline: timeline, 169 158 }) 170 159 } 171 160 172 161 func (s *State) reposPage(w http.ResponseWriter, r *http.Request) { 173 - pageWithProfile := s.profilePage(w, r) 174 - if pageWithProfile == nil { 162 + l := s.logger.With("handler", "reposPage") 163 + 164 + profile, err := s.profile(r) 165 + if err != nil { 166 + l.Error("failed to build profile card", "err", err) 167 + s.pages.Error500(w) 175 168 return 176 169 } 170 + l = l.With("profileDid", profile.UserDid, "profileHandle", profile.UserHandle) 177 171 178 - id := pageWithProfile.Id 179 172 repos, err := db.GetRepos( 180 173 s.db, 181 174 0, 182 - db.FilterEq("did", id.DID), 175 + db.FilterEq("did", profile.UserDid), 183 176 ) 184 177 if err != nil { 185 - log.Printf("getting repos for %s: %s", id.DID, err) 178 + l.Error("failed to get repos", "err", err) 179 + s.pages.Error500(w) 180 + return 186 181 } 187 182 188 - s.pages.ReposPage(w, pages.ReposPageParams{ 189 - LoggedInUser: pageWithProfile.LoggedInUser, 183 + err = s.pages.ProfileRepos(w, pages.ProfileReposParams{ 184 + LoggedInUser: s.oauth.GetUser(r), 190 185 Repos: repos, 191 - Card: pageWithProfile.Card, 186 + Card: profile, 187 + }) 188 + } 189 + 190 + func (s *State) starredPage(w http.ResponseWriter, r *http.Request) { 191 + l := s.logger.With("handler", "starredPage") 192 + 193 + profile, err := s.profile(r) 194 + if err != nil { 195 + l.Error("failed to build profile card", "err", err) 196 + s.pages.Error500(w) 197 + return 198 + } 199 + l = l.With("profileDid", profile.UserDid, "profileHandle", profile.UserHandle) 200 + 201 + stars, err := db.GetStars(s.db, 0, db.FilterEq("starred_by_did", profile.UserDid)) 202 + if err != nil { 203 + l.Error("failed to get stars", "err", err) 204 + s.pages.Error500(w) 205 + return 206 + } 207 + var repoAts []string 208 + for _, s := range stars { 209 + repoAts = append(repoAts, string(s.RepoAt)) 210 + } 211 + 212 + repos, err := db.GetRepos( 213 + s.db, 214 + 0, 215 + db.FilterIn("at_uri", repoAts), 216 + ) 217 + if err != nil { 218 + l.Error("failed to get repos", "err", err) 219 + s.pages.Error500(w) 220 + return 221 + } 222 + 223 + err = s.pages.ProfileStarred(w, pages.ProfileStarredParams{ 224 + LoggedInUser: s.oauth.GetUser(r), 225 + Repos: repos, 226 + Card: profile, 192 227 }) 193 228 } 194 229 195 230 type FollowsPageParams struct { 196 - LoggedInUser *oauth.User 197 - Follows []pages.FollowCard 198 - Card pages.ProfileCard 231 + Follows []pages.FollowCard 232 + Card *pages.ProfileCard 199 233 } 200 234 201 - func (s *State) followPage(w http.ResponseWriter, r *http.Request, fetchFollows func(db.Execer, string) ([]db.Follow, error), extractDid func(db.Follow) string) (FollowsPageParams, error) { 202 - pageWithProfile := s.profilePage(w, r) 203 - if pageWithProfile == nil { 204 - return FollowsPageParams{}, nil 205 - } 235 + func (s *State) followPage( 236 + r *http.Request, 237 + fetchFollows func(db.Execer, string) ([]db.Follow, error), 238 + extractDid func(db.Follow) string, 239 + ) (*FollowsPageParams, error) { 240 + l := s.logger.With("handler", "reposPage") 206 241 207 - id := pageWithProfile.Id 208 - loggedInUser := pageWithProfile.LoggedInUser 209 - 210 - follows, err := fetchFollows(s.db, id.DID.String()) 242 + profile, err := s.profile(r) 211 243 if err != nil { 212 - log.Printf("getting followers for %s: %s", id.DID, err) 213 - return FollowsPageParams{}, err 244 + return nil, err 245 + } 246 + l = l.With("profileDid", profile.UserDid, "profileHandle", profile.UserHandle) 247 + 248 + loggedInUser := s.oauth.GetUser(r) 249 + 250 + follows, err := fetchFollows(s.db, profile.UserDid) 251 + if err != nil { 252 + l.Error("failed to fetch follows", "err", err) 253 + return nil, err 214 254 } 215 255 216 256 if len(follows) == 0 { 217 - return FollowsPageParams{ 218 - LoggedInUser: loggedInUser, 219 - Follows: []pages.FollowCard{}, 220 - Card: pageWithProfile.Card, 221 - }, nil 257 + return nil, nil 222 258 } 223 259 224 260 followDids := make([]string, 0, len(follows)) ··· 255 237 256 238 profiles, err := db.GetProfiles(s.db, db.FilterIn("did", followDids)) 257 239 if err != nil { 258 - log.Printf("getting profile for %s: %s", followDids, err) 259 - return FollowsPageParams{}, err 240 + l.Error("failed to get profiles", "followDids", followDids, "err", err) 241 + return nil, err 260 242 } 261 243 262 244 followStatsMap, err := db.GetFollowerFollowingCounts(s.db, followDids) ··· 264 246 log.Printf("getting follow counts for %s: %s", followDids, err) 265 247 } 266 248 267 - var loggedInUserFollowing map[string]struct{} 249 + loggedInUserFollowing := make(map[string]struct{}) 268 250 if loggedInUser != nil { 269 251 following, err := db.GetFollowing(s.db, loggedInUser.Did) 270 252 if err != nil { 271 - return FollowsPageParams{}, err 253 + l.Error("failed to get follow list", "err", err, "loggedInUser", loggedInUser.Did) 254 + return nil, err 272 255 } 273 - if len(following) > 0 { 274 - loggedInUserFollowing = make(map[string]struct{}, len(following)) 275 - for _, follow := range following { 276 - loggedInUserFollowing[follow.SubjectDid] = struct{}{} 277 - } 256 + loggedInUserFollowing = make(map[string]struct{}, len(following)) 257 + for _, follow := range following { 258 + loggedInUserFollowing[follow.SubjectDid] = struct{}{} 278 259 } 279 260 } 280 261 281 - followCards := make([]pages.FollowCard, 0, len(follows)) 282 - for _, did := range followDids { 283 - followStats, exists := followStatsMap[did] 284 - if !exists { 285 - followStats = db.FollowStats{} 286 - } 262 + followCards := make([]pages.FollowCard, len(follows)) 263 + for i, did := range followDids { 264 + followStats := followStatsMap[did] 287 265 followStatus := db.IsNotFollowing 288 - if loggedInUserFollowing != nil { 289 - if _, exists := loggedInUserFollowing[did]; exists { 290 - followStatus = db.IsFollowing 291 - } else if loggedInUser.Did == did { 292 - followStatus = db.IsSelf 293 - } 266 + if _, exists := loggedInUserFollowing[did]; exists { 267 + followStatus = db.IsFollowing 268 + } else if loggedInUser.Did == did { 269 + followStatus = db.IsSelf 294 270 } 271 + 295 272 var profile *db.Profile 296 273 if p, exists := profiles[did]; exists { 297 274 profile = p ··· 294 281 profile = &db.Profile{} 295 282 profile.Did = did 296 283 } 297 - followCards = append(followCards, pages.FollowCard{ 284 + followCards[i] = pages.FollowCard{ 298 285 UserDid: did, 299 286 FollowStatus: followStatus, 300 287 FollowersCount: followStats.Followers, 301 288 FollowingCount: followStats.Following, 302 289 Profile: profile, 303 - }) 290 + } 304 291 } 305 292 306 - return FollowsPageParams{ 307 - LoggedInUser: loggedInUser, 308 - Follows: followCards, 309 - Card: pageWithProfile.Card, 293 + return &FollowsPageParams{ 294 + Follows: followCards, 295 + Card: profile, 310 296 }, nil 311 297 } 312 298 313 299 func (s *State) followersPage(w http.ResponseWriter, r *http.Request) { 314 - followPage, err := s.followPage(w, r, db.GetFollowers, func(f db.Follow) string { return f.UserDid }) 300 + followPage, err := s.followPage(r, db.GetFollowers, func(f db.Follow) string { return f.UserDid }) 315 301 if err != nil { 316 302 s.pages.Notice(w, "all-followers", "Failed to load followers") 317 303 return 318 304 } 319 305 320 - s.pages.FollowersPage(w, pages.FollowersPageParams{ 321 - LoggedInUser: followPage.LoggedInUser, 306 + s.pages.ProfileFollowers(w, pages.ProfileFollowersParams{ 307 + LoggedInUser: s.oauth.GetUser(r), 322 308 Followers: followPage.Follows, 323 309 Card: followPage.Card, 324 310 }) 325 311 } 326 312 327 313 func (s *State) followingPage(w http.ResponseWriter, r *http.Request) { 328 - followPage, err := s.followPage(w, r, db.GetFollowing, func(f db.Follow) string { return f.SubjectDid }) 314 + followPage, err := s.followPage(r, db.GetFollowing, func(f db.Follow) string { return f.SubjectDid }) 329 315 if err != nil { 330 316 s.pages.Notice(w, "all-following", "Failed to load following") 331 317 return 332 318 } 333 319 334 - s.pages.FollowingPage(w, pages.FollowingPageParams{ 335 - LoggedInUser: followPage.LoggedInUser, 320 + s.pages.ProfileFollowing(w, pages.ProfileFollowingParams{ 321 + LoggedInUser: s.oauth.GetUser(r), 336 322 Following: followPage.Follows, 337 323 Card: followPage.Card, 338 324 })