Monorepo for Tangled tangled.org

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

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

oppi.li 8d7b6bf6 24822eb5

verified
Changed files
+208 -201
appview
+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
+26 -15
appview/pages/pages.go
··· 444 444 return p.executeProfile("user/overview", w, params) 445 445 } 446 446 447 - Profile *db.Profile 447 + type ProfileReposParams struct { 448 + LoggedInUser *oauth.User 449 + Repos []db.Repo 450 + Card *ProfileCard 451 + Active string 448 452 } 449 453 450 - func (p *Pages) ProfileHomePage(w io.Writer, params ProfileHomePageParams) error { 451 - return p.execute("user/profile", 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) 452 457 } 453 458 454 - type ReposPageParams struct { 459 + type ProfileStarredParams struct { 455 460 LoggedInUser *oauth.User 456 461 Repos []db.Repo 457 - Card ProfileCard 462 + Card *ProfileCard 463 + Active string 458 464 } 459 465 460 - func (p *Pages) ReposPage(w io.Writer, params ReposPageParams) error { 461 - return p.execute("user/repos", w, params) 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 { ··· 469 476 Profile *db.Profile 470 477 } 471 478 472 - type FollowersPageParams struct { 479 + type ProfileFollowersParams struct { 473 480 LoggedInUser *oauth.User 474 481 Followers []FollowCard 475 - Card ProfileCard 482 + Card *ProfileCard 483 + Active string 476 484 } 477 485 478 - func (p *Pages) FollowersPage(w io.Writer, params FollowersPageParams) error { 479 - return p.execute("user/followers", w, params) 486 + func (p *Pages) ProfileFollowers(w io.Writer, params ProfileFollowersParams) error { 487 + params.Active = "overview" 488 + return p.executeProfile("user/followers", w, params) 480 489 } 481 490 482 - type FollowingPageParams struct { 491 + type ProfileFollowingParams struct { 483 492 LoggedInUser *oauth.User 484 493 Following []FollowCard 485 - Card ProfileCard 494 + Card *ProfileCard 495 + Active string 486 496 } 487 497 488 - func (p *Pages) FollowingPage(w io.Writer, params FollowingPageParams) error { 489 - return p.execute("user/following", w, params) 498 + func (p *Pages) ProfileFollowing(w io.Writer, params ProfileFollowingParams) error { 499 + params.Active = "overview" 500 + return p.executeProfile("user/following", w, params) 490 501 } 491 502 492 503 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 }}
+146 -134
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) ··· 74 65 followStatus = db.GetFollowStatus(s.db, loggedInUser.Did, did) 75 66 } 76 67 77 - return &ProfilePageParams{ 78 - Id: ident, 79 - LoggedInUser: loggedInUser, 80 - Card: pages.ProfileCard{ 81 - UserDid: did, 82 - UserHandle: ident.Handle.String(), 83 - Profile: profile, 84 - FollowStatus: followStatus, 85 - FollowersCount: followStats.Followers, 86 - FollowingCount: followStats.Following, 87 - }, 68 + now := time.Now() 69 + startOfYear := time.Date(now.Year(), 1, 1, 0, 0, 0, 0, time.UTC) 70 + punchcard, err := db.MakePunchcard( 71 + s.db, 72 + db.FilterEq("did", did), 73 + db.FilterGte("date", startOfYear.Format(time.DateOnly)), 74 + db.FilterLte("date", now.Format(time.DateOnly)), 75 + ) 76 + if err != nil { 77 + return nil, fmt.Errorf("failed to get punchcard for %s: %w", did, err) 88 78 } 79 + 80 + return &pages.ProfileCard{ 81 + UserDid: did, 82 + UserHandle: ident.Handle.String(), 83 + Profile: profile, 84 + FollowStatus: followStatus, 85 + FollowersCount: followStats.Followers, 86 + FollowingCount: followStats.Following, 87 + Punchcard: punchcard, 88 + }, nil 89 89 } 90 90 91 - func (s *State) profileHomePage(w http.ResponseWriter, r *http.Request) { 92 - pageWithProfile := s.profilePage(w, r) 93 - if pageWithProfile == nil { 91 + func (s *State) profileOverview(w http.ResponseWriter, r *http.Request) { 92 + l := s.logger.With("handler", "profileHomePage") 93 + 94 + profile, err := s.profile(r) 95 + if err != nil { 96 + l.Error("failed to build profile card", "err", err) 97 + s.pages.Error500(w) 94 98 return 95 99 } 100 + l = l.With("profileDid", profile.UserDid, "profileHandle", profile.UserHandle) 96 101 97 - id := pageWithProfile.Id 98 102 repos, err := db.GetRepos( 99 103 s.db, 100 104 0, 101 - db.FilterEq("did", id.DID), 105 + db.FilterEq("did", profile.UserDid), 102 106 ) 103 107 if err != nil { 104 - log.Printf("getting repos for %s: %s", id.DID, err) 108 + l.Error("failed to fetch repos", "err", err) 105 109 } 106 110 107 - profile := pageWithProfile.Card.Profile 108 111 // filter out ones that are pinned 109 112 pinnedRepos := []db.Repo{} 110 113 for i, r := range repos { 111 114 // if this is a pinned repo, add it 112 - if slices.Contains(profile.PinnedRepos[:], r.RepoAt()) { 115 + if slices.Contains(profile.Profile.PinnedRepos[:], r.RepoAt()) { 113 116 pinnedRepos = append(pinnedRepos, r) 114 117 } 115 118 116 119 // if there are no saved pins, add the first 4 repos 117 - if profile.IsPinnedReposEmpty() && i < 4 { 120 + if profile.Profile.IsPinnedReposEmpty() && i < 4 { 118 121 pinnedRepos = append(pinnedRepos, r) 119 122 } 120 123 } 121 124 122 - collaboratingRepos, err := db.CollaboratingIn(s.db, id.DID.String()) 125 + collaboratingRepos, err := db.CollaboratingIn(s.db, profile.UserDid) 123 126 if err != nil { 124 - log.Printf("getting collaborating repos for %s: %s", id.DID, err) 127 + l.Error("failed to fetch collaborating repos", "err", err) 125 128 } 126 129 127 130 pinnedCollaboratingRepos := []db.Repo{} 128 131 for _, r := range collaboratingRepos { 129 132 // if this is a pinned repo, add it 130 - if slices.Contains(profile.PinnedRepos[:], r.RepoAt()) { 133 + if slices.Contains(profile.Profile.PinnedRepos[:], r.RepoAt()) { 131 134 pinnedCollaboratingRepos = append(pinnedCollaboratingRepos, r) 132 135 } 133 136 } 134 137 135 - timeline, err := db.MakeProfileTimeline(s.db, id.DID.String()) 138 + timeline, err := db.MakeProfileTimeline(s.db, profile.UserDid) 136 139 if err != nil { 137 - log.Printf("failed to create profile timeline for %s: %s", id.DID, err) 140 + l.Error("failed to create timeline", "err", err) 138 141 } 139 142 140 - var didsToResolve []string 141 - for _, r := range collaboratingRepos { 142 - didsToResolve = append(didsToResolve, r.Did) 143 - } 144 - for _, byMonth := range timeline.ByMonth { 145 - for _, pe := range byMonth.PullEvents.Items { 146 - didsToResolve = append(didsToResolve, pe.Repo.Did) 147 - } 148 - for _, ie := range byMonth.IssueEvents.Items { 149 - didsToResolve = append(didsToResolve, ie.Metadata.Repo.Did) 150 - } 151 - for _, re := range byMonth.RepoEvents { 152 - didsToResolve = append(didsToResolve, re.Repo.Did) 153 - if re.Source != nil { 154 - didsToResolve = append(didsToResolve, re.Source.Did) 155 - } 156 - } 143 + s.pages.ProfileOverview(w, pages.ProfileOverviewParams{ 144 + LoggedInUser: s.oauth.GetUser(r), 145 + Card: profile, 146 + Repos: pinnedRepos, 147 + CollaboratingRepos: pinnedCollaboratingRepos, 148 + ProfileTimeline: timeline, 149 + }) 150 + } 151 + 152 + func (s *State) reposPage(w http.ResponseWriter, r *http.Request) { 153 + l := s.logger.With("handler", "reposPage") 154 + 155 + profile, err := s.profile(r) 156 + if err != nil { 157 + l.Error("failed to build profile card", "err", err) 158 + s.pages.Error500(w) 159 + return 157 160 } 161 + l = l.With("profileDid", profile.UserDid, "profileHandle", profile.UserHandle) 158 162 159 - now := time.Now() 160 - startOfYear := time.Date(now.Year(), 1, 1, 0, 0, 0, 0, time.UTC) 161 - punchcard, err := db.MakePunchcard( 163 + repos, err := db.GetRepos( 162 164 s.db, 163 - db.FilterEq("did", id.DID), 164 - db.FilterGte("date", startOfYear.Format(time.DateOnly)), 165 - db.FilterLte("date", now.Format(time.DateOnly)), 165 + 0, 166 + db.FilterEq("did", profile.UserDid), 166 167 ) 167 168 if err != nil { 168 - log.Println("failed to get punchcard for did", "did", id.DID, "err", err) 169 + l.Error("failed to get repos", "err", err) 170 + s.pages.Error500(w) 171 + return 169 172 } 170 173 171 - s.pages.ProfileHomePage(w, pages.ProfileHomePageParams{ 172 - LoggedInUser: pageWithProfile.LoggedInUser, 173 - Repos: pinnedRepos, 174 - CollaboratingRepos: pinnedCollaboratingRepos, 175 - Card: pageWithProfile.Card, 176 - Punchcard: punchcard, 177 - ProfileTimeline: timeline, 174 + err = s.pages.ProfileRepos(w, pages.ProfileReposParams{ 175 + LoggedInUser: s.oauth.GetUser(r), 176 + Repos: repos, 177 + Card: profile, 178 178 }) 179 179 } 180 180 181 - func (s *State) reposPage(w http.ResponseWriter, r *http.Request) { 182 - pageWithProfile := s.profilePage(w, r) 183 - if pageWithProfile == nil { 181 + func (s *State) starredPage(w http.ResponseWriter, r *http.Request) { 182 + l := s.logger.With("handler", "starredPage") 183 + 184 + profile, err := s.profile(r) 185 + if err != nil { 186 + l.Error("failed to build profile card", "err", err) 187 + s.pages.Error500(w) 188 + return 189 + } 190 + l = l.With("profileDid", profile.UserDid, "profileHandle", profile.UserHandle) 191 + 192 + stars, err := db.GetStars(s.db, 0, db.FilterEq("starred_by_did", profile.UserDid)) 193 + if err != nil { 194 + l.Error("failed to get stars", "err", err) 195 + s.pages.Error500(w) 184 196 return 185 197 } 198 + var repoAts []string 199 + for _, s := range stars { 200 + repoAts = append(repoAts, string(s.RepoAt)) 201 + } 186 202 187 - id := pageWithProfile.Id 188 203 repos, err := db.GetRepos( 189 204 s.db, 190 205 0, 191 - db.FilterEq("did", id.DID), 206 + db.FilterIn("at_uri", repoAts), 192 207 ) 193 208 if err != nil { 194 - log.Printf("getting repos for %s: %s", id.DID, err) 209 + l.Error("failed to get repos", "err", err) 210 + s.pages.Error500(w) 211 + return 195 212 } 196 213 197 - s.pages.ReposPage(w, pages.ReposPageParams{ 198 - LoggedInUser: pageWithProfile.LoggedInUser, 214 + err = s.pages.ProfileStarred(w, pages.ProfileStarredParams{ 215 + LoggedInUser: s.oauth.GetUser(r), 199 216 Repos: repos, 200 - Card: pageWithProfile.Card, 217 + Card: profile, 201 218 }) 202 219 } 203 220 204 221 type FollowsPageParams struct { 205 - LoggedInUser *oauth.User 206 - Follows []pages.FollowCard 207 - Card pages.ProfileCard 222 + Follows []pages.FollowCard 223 + Card *pages.ProfileCard 208 224 } 209 225 210 - 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) { 211 - pageWithProfile := s.profilePage(w, r) 212 - if pageWithProfile == nil { 213 - return FollowsPageParams{}, nil 226 + func (s *State) followPage( 227 + r *http.Request, 228 + fetchFollows func(db.Execer, string) ([]db.Follow, error), 229 + extractDid func(db.Follow) string, 230 + ) (*FollowsPageParams, error) { 231 + l := s.logger.With("handler", "reposPage") 232 + 233 + profile, err := s.profile(r) 234 + if err != nil { 235 + return nil, err 214 236 } 237 + l = l.With("profileDid", profile.UserDid, "profileHandle", profile.UserHandle) 215 238 216 - id := pageWithProfile.Id 217 - loggedInUser := pageWithProfile.LoggedInUser 239 + loggedInUser := s.oauth.GetUser(r) 218 240 219 - follows, err := fetchFollows(s.db, id.DID.String()) 241 + follows, err := fetchFollows(s.db, profile.UserDid) 220 242 if err != nil { 221 - log.Printf("getting followers for %s: %s", id.DID, err) 222 - return FollowsPageParams{}, err 243 + l.Error("failed to fetch follows", "err", err) 244 + return nil, err 223 245 } 224 246 225 247 if len(follows) == 0 { 226 - return FollowsPageParams{ 227 - LoggedInUser: loggedInUser, 228 - Follows: []pages.FollowCard{}, 229 - Card: pageWithProfile.Card, 230 - }, nil 248 + return nil, nil 231 249 } 232 250 233 251 followDids := make([]string, 0, len(follows)) ··· 237 255 238 256 profiles, err := db.GetProfiles(s.db, db.FilterIn("did", followDids)) 239 257 if err != nil { 240 - log.Printf("getting profile for %s: %s", followDids, err) 241 - return FollowsPageParams{}, err 258 + l.Error("failed to get profiles", "followDids", followDids, "err", err) 259 + return nil, err 242 260 } 243 261 244 262 followStatsMap, err := db.GetFollowerFollowingCounts(s.db, followDids) ··· 246 264 log.Printf("getting follow counts for %s: %s", followDids, err) 247 265 } 248 266 249 - var loggedInUserFollowing map[string]struct{} 267 + loggedInUserFollowing := make(map[string]struct{}) 250 268 if loggedInUser != nil { 251 269 following, err := db.GetFollowing(s.db, loggedInUser.Did) 252 270 if err != nil { 253 - return FollowsPageParams{}, err 271 + l.Error("failed to get follow list", "err", err, "loggedInUser", loggedInUser.Did) 272 + return nil, err 254 273 } 255 - if len(following) > 0 { 256 - loggedInUserFollowing = make(map[string]struct{}, len(following)) 257 - for _, follow := range following { 258 - loggedInUserFollowing[follow.SubjectDid] = struct{}{} 259 - } 274 + loggedInUserFollowing = make(map[string]struct{}, len(following)) 275 + for _, follow := range following { 276 + loggedInUserFollowing[follow.SubjectDid] = struct{}{} 260 277 } 261 278 } 262 279 263 - followCards := make([]pages.FollowCard, 0, len(follows)) 264 - for _, did := range followDids { 265 - followStats, exists := followStatsMap[did] 266 - if !exists { 267 - followStats = db.FollowStats{} 268 - } 280 + followCards := make([]pages.FollowCard, len(follows)) 281 + for i, did := range followDids { 282 + followStats := followStatsMap[did] 269 283 followStatus := db.IsNotFollowing 270 - if loggedInUserFollowing != nil { 271 - if _, exists := loggedInUserFollowing[did]; exists { 272 - followStatus = db.IsFollowing 273 - } else if loggedInUser.Did == did { 274 - followStatus = db.IsSelf 275 - } 284 + if _, exists := loggedInUserFollowing[did]; exists { 285 + followStatus = db.IsFollowing 286 + } else if loggedInUser.Did == did { 287 + followStatus = db.IsSelf 276 288 } 289 + 277 290 var profile *db.Profile 278 291 if p, exists := profiles[did]; exists { 279 292 profile = p ··· 281 294 profile = &db.Profile{} 282 295 profile.Did = did 283 296 } 284 - followCards = append(followCards, pages.FollowCard{ 297 + followCards[i] = pages.FollowCard{ 285 298 UserDid: did, 286 299 FollowStatus: followStatus, 287 300 FollowersCount: followStats.Followers, 288 301 FollowingCount: followStats.Following, 289 302 Profile: profile, 290 - }) 303 + } 291 304 } 292 305 293 - return FollowsPageParams{ 294 - LoggedInUser: loggedInUser, 295 - Follows: followCards, 296 - Card: pageWithProfile.Card, 306 + return &FollowsPageParams{ 307 + Follows: followCards, 308 + Card: profile, 297 309 }, nil 298 310 } 299 311 300 312 func (s *State) followersPage(w http.ResponseWriter, r *http.Request) { 301 - followPage, err := s.followPage(w, r, db.GetFollowers, func(f db.Follow) string { return f.UserDid }) 313 + followPage, err := s.followPage(r, db.GetFollowers, func(f db.Follow) string { return f.UserDid }) 302 314 if err != nil { 303 315 s.pages.Notice(w, "all-followers", "Failed to load followers") 304 316 return 305 317 } 306 318 307 - s.pages.FollowersPage(w, pages.FollowersPageParams{ 308 - LoggedInUser: followPage.LoggedInUser, 319 + s.pages.ProfileFollowers(w, pages.ProfileFollowersParams{ 320 + LoggedInUser: s.oauth.GetUser(r), 309 321 Followers: followPage.Follows, 310 322 Card: followPage.Card, 311 323 }) 312 324 } 313 325 314 326 func (s *State) followingPage(w http.ResponseWriter, r *http.Request) { 315 - followPage, err := s.followPage(w, r, db.GetFollowing, func(f db.Follow) string { return f.SubjectDid }) 327 + followPage, err := s.followPage(r, db.GetFollowing, func(f db.Follow) string { return f.SubjectDid }) 316 328 if err != nil { 317 329 s.pages.Notice(w, "all-following", "Failed to load following") 318 330 return 319 331 } 320 332 321 - s.pages.FollowingPage(w, pages.FollowingPageParams{ 322 - LoggedInUser: followPage.LoggedInUser, 333 + s.pages.ProfileFollowing(w, pages.ProfileFollowingParams{ 334 + LoggedInUser: s.oauth.GetUser(r), 323 335 Following: followPage.Follows, 324 336 Card: followPage.Card, 325 337 })