appview: state: dedup profile pages #504

merged
opened by ptr.pet targeting master from [deleted fork]: followers-following-list
Changed files
+94 -98
appview
pages
state
+2 -2
appview/pages/pages.go
··· 407 return p.execute("repo/fork", w, params) 408 } 409 410 - type ProfilePageParams struct { 411 LoggedInUser *oauth.User 412 Repos []db.Repo 413 CollaboratingRepos []db.Repo ··· 426 Profile *db.Profile 427 } 428 429 - func (p *Pages) ProfilePage(w io.Writer, params ProfilePageParams) error { 430 return p.execute("user/profile", w, params) 431 } 432
··· 407 return p.execute("repo/fork", w, params) 408 } 409 410 + type ProfileHomePageParams struct { 411 LoggedInUser *oauth.User 412 Repos []db.Repo 413 CollaboratingRepos []db.Repo ··· 426 Profile *db.Profile 427 } 428 429 + func (p *Pages) ProfileHomePage(w io.Writer, params ProfileHomePageParams) error { 430 return p.execute("user/profile", w, params) 431 } 432
+92 -96
appview/state/profile.go
··· 25 tabVal := r.URL.Query().Get("tab") 26 switch tabVal { 27 case "": 28 - s.profilePage(w, r) 29 case "repos": 30 s.reposPage(w, r) 31 case "followers": ··· 35 } 36 } 37 38 - func (s *State) profilePage(w http.ResponseWriter, r *http.Request) { 39 didOrHandle := chi.URLParam(r, "user") 40 if didOrHandle == "" { 41 - http.Error(w, "Bad request", http.StatusBadRequest) 42 - return 43 } 44 45 ident, ok := r.Context().Value("resolvedId").(identity.Identity) 46 if !ok { 47 - s.pages.Error404(w) 48 - return 49 } 50 51 - profile, err := db.GetProfile(s.db, ident.DID.String()) 52 if err != nil { 53 - log.Printf("getting profile data for %s: %s", ident.DID.String(), err) 54 } 55 56 repos, err := db.GetRepos( 57 s.db, 58 0, 59 - db.FilterEq("did", ident.DID.String()), 60 ) 61 if err != nil { 62 - log.Printf("getting repos for %s: %s", ident.DID.String(), err) 63 } 64 65 // filter out ones that are pinned 66 pinnedRepos := []db.Repo{} 67 for i, r := range repos { ··· 76 } 77 } 78 79 - collaboratingRepos, err := db.CollaboratingIn(s.db, ident.DID.String()) 80 if err != nil { 81 - log.Printf("getting collaborating repos for %s: %s", ident.DID.String(), err) 82 } 83 84 pinnedCollaboratingRepos := []db.Repo{} ··· 89 } 90 } 91 92 - timeline, err := db.MakeProfileTimeline(s.db, ident.DID.String()) 93 if err != nil { 94 - log.Printf("failed to create profile timeline for %s: %s", ident.DID.String(), err) 95 } 96 97 - followers, following, err := db.GetFollowerFollowingCount(s.db, ident.DID.String()) 98 - if err != nil { 99 - log.Printf("getting follow stats repos for %s: %s", ident.DID.String(), err) 100 } 101 - 102 - loggedInUser := s.oauth.GetUser(r) 103 - followStatus := db.IsNotFollowing 104 - if loggedInUser != nil { 105 - followStatus = db.GetFollowStatus(s.db, loggedInUser.Did, ident.DID.String()) 106 } 107 108 now := time.Now() 109 startOfYear := time.Date(now.Year(), 1, 1, 0, 0, 0, 0, time.UTC) 110 punchcard, err := db.MakePunchcard( 111 s.db, 112 - db.FilterEq("did", ident.DID.String()), 113 db.FilterGte("date", startOfYear.Format(time.DateOnly)), 114 db.FilterLte("date", now.Format(time.DateOnly)), 115 ) 116 if err != nil { 117 - log.Println("failed to get punchcard for did", "did", ident.DID.String(), "err", err) 118 } 119 120 - s.pages.ProfilePage(w, pages.ProfilePageParams{ 121 - LoggedInUser: loggedInUser, 122 Repos: pinnedRepos, 123 CollaboratingRepos: pinnedCollaboratingRepos, 124 - Card: pages.ProfileCard{ 125 - UserDid: ident.DID.String(), 126 - UserHandle: ident.Handle.String(), 127 - Profile: profile, 128 - FollowStatus: followStatus, 129 - FollowersCount: followers, 130 - FollowingCount: following, 131 - }, 132 - Punchcard: punchcard, 133 - ProfileTimeline: timeline, 134 }) 135 } 136 137 func (s *State) reposPage(w http.ResponseWriter, r *http.Request) { 138 - ident, ok := r.Context().Value("resolvedId").(identity.Identity) 139 - if !ok { 140 - s.pages.Error404(w) 141 return 142 } 143 144 - profile, err := db.GetProfile(s.db, ident.DID.String()) 145 - if err != nil { 146 - log.Printf("getting profile data for %s: %s", ident.DID.String(), err) 147 - } 148 - 149 repos, err := db.GetRepos( 150 s.db, 151 0, 152 - db.FilterEq("did", ident.DID.String()), 153 ) 154 if err != nil { 155 - log.Printf("getting repos for %s: %s", ident.DID.String(), err) 156 - } 157 - 158 - loggedInUser := s.oauth.GetUser(r) 159 - followStatus := db.IsNotFollowing 160 - if loggedInUser != nil { 161 - followStatus = db.GetFollowStatus(s.db, loggedInUser.Did, ident.DID.String()) 162 - } 163 - 164 - followers, following, err := db.GetFollowerFollowingCount(s.db, ident.DID.String()) 165 - if err != nil { 166 - log.Printf("getting follow stats repos for %s: %s", ident.DID.String(), err) 167 } 168 169 s.pages.ReposPage(w, pages.ReposPageParams{ 170 - LoggedInUser: loggedInUser, 171 Repos: repos, 172 - Card: pages.ProfileCard{ 173 - UserDid: ident.DID.String(), 174 - UserHandle: ident.Handle.String(), 175 - Profile: profile, 176 - FollowStatus: followStatus, 177 - FollowersCount: followers, 178 - FollowingCount: following, 179 - }, 180 }) 181 } 182 ··· 187 } 188 189 func (s *State) followPage(w http.ResponseWriter, r *http.Request, fetchFollows func(db.Execer, string) ([]db.Follow, error), extractDid func(db.Follow) string) *FollowsPageParams { 190 - ident, ok := r.Context().Value("resolvedId").(identity.Identity) 191 - if !ok { 192 - s.pages.Error404(w) 193 return nil 194 } 195 - did := ident.DID.String() 196 197 - profile, err := db.GetProfile(s.db, did) 198 - if err != nil { 199 - log.Printf("getting profile data for %s: %s", did, err) 200 - } 201 202 - loggedInUser := s.oauth.GetUser(r) 203 - 204 - follows, err := fetchFollows(s.db, did) 205 if err != nil { 206 - log.Printf("getting followers for %s: %s", did, err) 207 } 208 209 if len(follows) == 0 { ··· 221 return nil 222 } 223 224 var loggedInUserFollowing map[string]struct{} 225 if loggedInUser != nil { 226 following, err := db.GetFollowing(s.db, loggedInUser.Did) ··· 265 }) 266 } 267 268 - followStatus := db.IsNotFollowing 269 - if loggedInUser != nil { 270 - followStatus = db.GetFollowStatus(s.db, loggedInUser.Did, did) 271 - } 272 - 273 - followersCount, followingCount, err := db.GetFollowerFollowingCount(s.db, did) 274 - if err != nil { 275 - log.Printf("getting follow stats followers for %s: %s", did, err) 276 - } 277 - 278 return &FollowsPageParams{ 279 LoggedInUser: loggedInUser, 280 Follows: followCards, 281 - Card: pages.ProfileCard{ 282 - UserDid: did, 283 - UserHandle: ident.Handle.String(), 284 - Profile: profile, 285 - FollowStatus: followStatus, 286 - FollowersCount: followersCount, 287 - FollowingCount: followingCount, 288 - }, 289 } 290 } 291
··· 25 tabVal := r.URL.Query().Get("tab") 26 switch tabVal { 27 case "": 28 + s.profileHomePage(w, r) 29 case "repos": 30 s.reposPage(w, r) 31 case "followers": ··· 35 } 36 } 37 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 { 45 didOrHandle := chi.URLParam(r, "user") 46 if didOrHandle == "" { 47 + http.Error(w, "bad request", http.StatusBadRequest) 48 + return nil 49 } 50 51 ident, ok := r.Context().Value("resolvedId").(identity.Identity) 52 if !ok { 53 + log.Printf("malformed middleware") 54 + w.WriteHeader(http.StatusInternalServerError) 55 + return nil 56 } 57 + did := ident.DID.String() 58 59 + profile, err := db.GetProfile(s.db, did) 60 if err != nil { 61 + log.Printf("getting profile data for %s: %s", did, err) 62 + } 63 + 64 + followersCount, followingCount, err := db.GetFollowerFollowingCount(s.db, did) 65 + if err != nil { 66 + log.Printf("getting follow stats for %s: %s", did, err) 67 + } 68 + 69 + loggedInUser := s.oauth.GetUser(r) 70 + followStatus := db.IsNotFollowing 71 + if loggedInUser != nil { 72 + followStatus = db.GetFollowStatus(s.db, loggedInUser.Did, did) 73 + } 74 + 75 + return &ProfilePageParams{ 76 + Id: ident, 77 + LoggedInUser: loggedInUser, 78 + Card: pages.ProfileCard{ 79 + UserDid: did, 80 + UserHandle: ident.Handle.String(), 81 + Profile: profile, 82 + FollowStatus: followStatus, 83 + FollowersCount: followersCount, 84 + FollowingCount: followingCount, 85 + }, 86 + } 87 + } 88 + 89 + func (s *State) profileHomePage(w http.ResponseWriter, r *http.Request) { 90 + pageWithProfile := s.profilePage(w, r) 91 + if pageWithProfile == nil { 92 + return 93 } 94 95 + id := pageWithProfile.Id 96 repos, err := db.GetRepos( 97 s.db, 98 0, 99 + db.FilterEq("did", id.DID), 100 ) 101 if err != nil { 102 + log.Printf("getting repos for %s: %s", id.DID, err) 103 } 104 105 + profile := pageWithProfile.Card.Profile 106 // filter out ones that are pinned 107 pinnedRepos := []db.Repo{} 108 for i, r := range repos { ··· 117 } 118 } 119 120 + collaboratingRepos, err := db.CollaboratingIn(s.db, id.DID.String()) 121 if err != nil { 122 + log.Printf("getting collaborating repos for %s: %s", id.DID, err) 123 } 124 125 pinnedCollaboratingRepos := []db.Repo{} ··· 130 } 131 } 132 133 + timeline, err := db.MakeProfileTimeline(s.db, id.DID.String()) 134 if err != nil { 135 + log.Printf("failed to create profile timeline for %s: %s", id.DID, err) 136 } 137 138 + var didsToResolve []string 139 + for _, r := range collaboratingRepos { 140 + didsToResolve = append(didsToResolve, r.Did) 141 } 142 + for _, byMonth := range timeline.ByMonth { 143 + for _, pe := range byMonth.PullEvents.Items { 144 + didsToResolve = append(didsToResolve, pe.Repo.Did) 145 + } 146 + for _, ie := range byMonth.IssueEvents.Items { 147 + didsToResolve = append(didsToResolve, ie.Metadata.Repo.Did) 148 + } 149 + for _, re := range byMonth.RepoEvents { 150 + didsToResolve = append(didsToResolve, re.Repo.Did) 151 + if re.Source != nil { 152 + didsToResolve = append(didsToResolve, re.Source.Did) 153 + } 154 + } 155 } 156 157 now := time.Now() 158 startOfYear := time.Date(now.Year(), 1, 1, 0, 0, 0, 0, time.UTC) 159 punchcard, err := db.MakePunchcard( 160 s.db, 161 + db.FilterEq("did", id.DID), 162 db.FilterGte("date", startOfYear.Format(time.DateOnly)), 163 db.FilterLte("date", now.Format(time.DateOnly)), 164 ) 165 if err != nil { 166 + log.Println("failed to get punchcard for did", "did", id.DID, "err", err) 167 } 168 169 + s.pages.ProfileHomePage(w, pages.ProfileHomePageParams{ 170 + LoggedInUser: pageWithProfile.LoggedInUser, 171 Repos: pinnedRepos, 172 CollaboratingRepos: pinnedCollaboratingRepos, 173 + Card: pageWithProfile.Card, 174 + Punchcard: punchcard, 175 + ProfileTimeline: timeline, 176 }) 177 } 178 179 func (s *State) reposPage(w http.ResponseWriter, r *http.Request) { 180 + pageWithProfile := s.profilePage(w, r) 181 + if pageWithProfile == nil { 182 return 183 } 184 185 + id := pageWithProfile.Id 186 repos, err := db.GetRepos( 187 s.db, 188 0, 189 + db.FilterEq("did", id.DID), 190 ) 191 if err != nil { 192 + log.Printf("getting repos for %s: %s", id.DID, err) 193 } 194 195 s.pages.ReposPage(w, pages.ReposPageParams{ 196 + LoggedInUser: pageWithProfile.LoggedInUser, 197 Repos: repos, 198 + Card: pageWithProfile.Card, 199 }) 200 } 201 ··· 206 } 207 208 func (s *State) followPage(w http.ResponseWriter, r *http.Request, fetchFollows func(db.Execer, string) ([]db.Follow, error), extractDid func(db.Follow) string) *FollowsPageParams { 209 + pageWithProfile := s.profilePage(w, r) 210 + if pageWithProfile == nil { 211 return nil 212 } 213 214 + id := pageWithProfile.Id 215 216 + follows, err := fetchFollows(s.db, id.DID.String()) 217 if err != nil { 218 + log.Printf("getting followers for %s: %s", id.DID, err) 219 } 220 221 if len(follows) == 0 { ··· 233 return nil 234 } 235 236 + loggedInUser := pageWithProfile.LoggedInUser 237 var loggedInUserFollowing map[string]struct{} 238 if loggedInUser != nil { 239 following, err := db.GetFollowing(s.db, loggedInUser.Did) ··· 278 }) 279 } 280 281 return &FollowsPageParams{ 282 LoggedInUser: loggedInUser, 283 Follows: followCards, 284 + Card: pageWithProfile.Card, 285 } 286 } 287