forked from tangled.org/core
Monorepo for Tangled — https://tangled.org

appview: state: dedup profile pages

- rename existing ProfilePage to ProfileHomePage

Signed-off-by: dusk <y.bera003.06@protonmail.com>

authored by ptr.pet and committed by Tangled 4e5b1f20 5b6b7aea

Changed files
+112 -124
appview
pages
state
+2 -2
appview/pages/pages.go
··· 408 408 return p.execute("repo/fork", w, params) 409 409 } 410 410 411 - type ProfilePageParams struct { 411 + type ProfileHomePageParams struct { 412 412 LoggedInUser *oauth.User 413 413 Repos []db.Repo 414 414 CollaboratingRepos []db.Repo ··· 427 427 Profile *db.Profile 428 428 } 429 429 430 - func (p *Pages) ProfilePage(w io.Writer, params ProfilePageParams) error { 430 + func (p *Pages) ProfileHomePage(w io.Writer, params ProfileHomePageParams) error { 431 431 return p.execute("user/profile", w, params) 432 432 } 433 433
+110 -122
appview/state/profile.go
··· 2 2 3 3 import ( 4 4 "context" 5 - "errors" 6 5 "fmt" 7 6 "log" 8 7 "net/http" ··· 26 25 tabVal := r.URL.Query().Get("tab") 27 26 switch tabVal { 28 27 case "": 29 - s.profilePage(w, r) 28 + s.profileHomePage(w, r) 30 29 case "repos": 31 30 s.reposPage(w, r) 32 31 case "followers": ··· 36 35 } 37 36 } 38 37 39 - func (s *State) profilePage(w http.ResponseWriter, r *http.Request) { 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 45 didOrHandle := chi.URLParam(r, "user") 41 46 if didOrHandle == "" { 42 - http.Error(w, "Bad request", http.StatusBadRequest) 43 - return 47 + http.Error(w, "bad request", http.StatusBadRequest) 48 + return nil 44 49 } 45 50 46 51 ident, ok := r.Context().Value("resolvedId").(identity.Identity) 47 52 if !ok { 48 - s.pages.Error404(w) 49 - return 53 + log.Printf("malformed middleware") 54 + w.WriteHeader(http.StatusInternalServerError) 55 + return nil 50 56 } 57 + did := ident.DID.String() 51 58 52 - profile, err := db.GetProfile(s.db, ident.DID.String()) 59 + profile, err := db.GetProfile(s.db, did) 53 60 if err != nil { 54 - log.Printf("getting profile data for %s: %s", ident.DID.String(), err) 61 + log.Printf("getting profile data for %s: %s", did, err) 62 + s.pages.Error500(w) 63 + return nil 64 + } 65 + 66 + followersCount, followingCount, err := db.GetFollowerFollowingCount(s.db, did) 67 + if err != nil { 68 + log.Printf("getting follow stats for %s: %s", did, err) 69 + } 70 + 71 + loggedInUser := s.oauth.GetUser(r) 72 + followStatus := db.IsNotFollowing 73 + if loggedInUser != nil { 74 + followStatus = db.GetFollowStatus(s.db, loggedInUser.Did, did) 75 + } 76 + 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: followersCount, 86 + FollowingCount: followingCount, 87 + }, 88 + } 89 + } 90 + 91 + func (s *State) profileHomePage(w http.ResponseWriter, r *http.Request) { 92 + pageWithProfile := s.profilePage(w, r) 93 + if pageWithProfile == nil { 94 + return 55 95 } 56 96 97 + id := pageWithProfile.Id 57 98 repos, err := db.GetRepos( 58 99 s.db, 59 100 0, 60 - db.FilterEq("did", ident.DID.String()), 101 + db.FilterEq("did", id.DID), 61 102 ) 62 103 if err != nil { 63 - log.Printf("getting repos for %s: %s", ident.DID.String(), err) 104 + log.Printf("getting repos for %s: %s", id.DID, err) 64 105 } 65 106 107 + profile := pageWithProfile.Card.Profile 66 108 // filter out ones that are pinned 67 109 pinnedRepos := []db.Repo{} 68 110 for i, r := range repos { ··· 77 119 } 78 120 } 79 121 80 - collaboratingRepos, err := db.CollaboratingIn(s.db, ident.DID.String()) 122 + collaboratingRepos, err := db.CollaboratingIn(s.db, id.DID.String()) 81 123 if err != nil { 82 - log.Printf("getting collaborating repos for %s: %s", ident.DID.String(), err) 124 + log.Printf("getting collaborating repos for %s: %s", id.DID, err) 83 125 } 84 126 85 127 pinnedCollaboratingRepos := []db.Repo{} ··· 90 132 } 91 133 } 92 134 93 - timeline, err := db.MakeProfileTimeline(s.db, ident.DID.String()) 135 + timeline, err := db.MakeProfileTimeline(s.db, id.DID.String()) 94 136 if err != nil { 95 - log.Printf("failed to create profile timeline for %s: %s", ident.DID.String(), err) 137 + log.Printf("failed to create profile timeline for %s: %s", id.DID, err) 96 138 } 97 139 98 - followers, following, err := db.GetFollowerFollowingCount(s.db, ident.DID.String()) 99 - if err != nil { 100 - log.Printf("getting follow stats repos for %s: %s", ident.DID.String(), err) 140 + var didsToResolve []string 141 + for _, r := range collaboratingRepos { 142 + didsToResolve = append(didsToResolve, r.Did) 101 143 } 102 - 103 - loggedInUser := s.oauth.GetUser(r) 104 - followStatus := db.IsNotFollowing 105 - if loggedInUser != nil { 106 - followStatus = db.GetFollowStatus(s.db, loggedInUser.Did, ident.DID.String()) 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 + } 107 157 } 108 158 109 159 now := time.Now() 110 160 startOfYear := time.Date(now.Year(), 1, 1, 0, 0, 0, 0, time.UTC) 111 161 punchcard, err := db.MakePunchcard( 112 162 s.db, 113 - db.FilterEq("did", ident.DID.String()), 163 + db.FilterEq("did", id.DID), 114 164 db.FilterGte("date", startOfYear.Format(time.DateOnly)), 115 165 db.FilterLte("date", now.Format(time.DateOnly)), 116 166 ) 117 167 if err != nil { 118 - log.Println("failed to get punchcard for did", "did", ident.DID.String(), "err", err) 168 + log.Println("failed to get punchcard for did", "did", id.DID, "err", err) 119 169 } 120 170 121 - s.pages.ProfilePage(w, pages.ProfilePageParams{ 122 - LoggedInUser: loggedInUser, 171 + s.pages.ProfileHomePage(w, pages.ProfileHomePageParams{ 172 + LoggedInUser: pageWithProfile.LoggedInUser, 123 173 Repos: pinnedRepos, 124 174 CollaboratingRepos: pinnedCollaboratingRepos, 125 - Card: pages.ProfileCard{ 126 - UserDid: ident.DID.String(), 127 - UserHandle: ident.Handle.String(), 128 - Profile: profile, 129 - FollowStatus: followStatus, 130 - FollowersCount: followers, 131 - FollowingCount: following, 132 - }, 133 - Punchcard: punchcard, 134 - ProfileTimeline: timeline, 175 + Card: pageWithProfile.Card, 176 + Punchcard: punchcard, 177 + ProfileTimeline: timeline, 135 178 }) 136 179 } 137 180 138 181 func (s *State) reposPage(w http.ResponseWriter, r *http.Request) { 139 - ident, ok := r.Context().Value("resolvedId").(identity.Identity) 140 - if !ok { 141 - s.pages.Error404(w) 182 + pageWithProfile := s.profilePage(w, r) 183 + if pageWithProfile == nil { 142 184 return 143 185 } 144 186 145 - profile, err := db.GetProfile(s.db, ident.DID.String()) 146 - if err != nil { 147 - log.Printf("getting profile data for %s: %s", ident.DID.String(), err) 148 - } 149 - 187 + id := pageWithProfile.Id 150 188 repos, err := db.GetRepos( 151 189 s.db, 152 190 0, 153 - db.FilterEq("did", ident.DID.String()), 191 + db.FilterEq("did", id.DID), 154 192 ) 155 193 if err != nil { 156 - log.Printf("getting repos for %s: %s", ident.DID.String(), err) 157 - } 158 - 159 - loggedInUser := s.oauth.GetUser(r) 160 - followStatus := db.IsNotFollowing 161 - if loggedInUser != nil { 162 - followStatus = db.GetFollowStatus(s.db, loggedInUser.Did, ident.DID.String()) 163 - } 164 - 165 - followers, following, err := db.GetFollowerFollowingCount(s.db, ident.DID.String()) 166 - if err != nil { 167 - log.Printf("getting follow stats repos for %s: %s", ident.DID.String(), err) 194 + log.Printf("getting repos for %s: %s", id.DID, err) 168 195 } 169 196 170 197 s.pages.ReposPage(w, pages.ReposPageParams{ 171 - LoggedInUser: loggedInUser, 198 + LoggedInUser: pageWithProfile.LoggedInUser, 172 199 Repos: repos, 173 - Card: pages.ProfileCard{ 174 - UserDid: ident.DID.String(), 175 - UserHandle: ident.Handle.String(), 176 - Profile: profile, 177 - FollowStatus: followStatus, 178 - FollowersCount: followers, 179 - FollowingCount: following, 180 - }, 200 + Card: pageWithProfile.Card, 181 201 }) 182 202 } 183 203 ··· 188 208 } 189 209 190 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) { 191 - ident, ok := r.Context().Value("resolvedId").(identity.Identity) 192 - if !ok { 193 - s.pages.Error404(w) 194 - return FollowsPageParams{}, errors.New("identity not found") 195 - } 196 - did := ident.DID.String() 197 - 198 - profile, err := db.GetProfile(s.db, did) 199 - if err != nil { 200 - log.Printf("getting profile data for %s: %s", did, err) 201 - return FollowsPageParams{}, err 202 - } 203 - 204 - loggedInUser := s.oauth.GetUser(r) 205 - 206 - follows, err := fetchFollows(s.db, did) 207 - if err != nil { 208 - log.Printf("getting followers for %s: %s", did, err) 209 - return FollowsPageParams{}, err 210 - } 211 - 212 - var loggedInUserFollowing map[string]struct{} 213 - if loggedInUser != nil { 214 - following, err := db.GetFollowing(s.db, loggedInUser.Did) 215 - if err != nil { 216 - return FollowsPageParams{}, err 217 - } 218 - if len(following) > 0 { 219 - loggedInUserFollowing = make(map[string]struct{}, len(following)) 220 - for _, follow := range following { 221 - loggedInUserFollowing[follow.SubjectDid] = struct{}{} 222 - } 223 - } 211 + pageWithProfile := s.profilePage(w, r) 212 + if pageWithProfile == nil { 213 + return FollowsPageParams{}, nil 224 214 } 225 215 226 - followStatus := db.IsNotFollowing 227 - if loggedInUser != nil { 228 - followStatus = db.GetFollowStatus(s.db, loggedInUser.Did, did) 229 - } 216 + id := pageWithProfile.Id 217 + loggedInUser := pageWithProfile.LoggedInUser 230 218 231 - followersCount, followingCount, err := db.GetFollowerFollowingCount(s.db, did) 219 + follows, err := fetchFollows(s.db, id.DID.String()) 232 220 if err != nil { 233 - log.Printf("getting follow stats followers for %s: %s", did, err) 221 + log.Printf("getting followers for %s: %s", id.DID, err) 234 222 return FollowsPageParams{}, err 235 223 } 236 224 ··· 238 226 return FollowsPageParams{ 239 227 LoggedInUser: loggedInUser, 240 228 Follows: []pages.FollowCard{}, 241 - Card: pages.ProfileCard{ 242 - UserDid: did, 243 - UserHandle: ident.Handle.String(), 244 - Profile: profile, 245 - FollowStatus: followStatus, 246 - FollowersCount: followersCount, 247 - FollowingCount: followingCount, 248 - }, 229 + Card: pageWithProfile.Card, 249 230 }, nil 250 231 } 251 232 ··· 258 239 if err != nil { 259 240 log.Printf("getting profile for %s: %s", followDids, err) 260 241 return FollowsPageParams{}, err 242 + } 243 + 244 + var loggedInUserFollowing map[string]struct{} 245 + if loggedInUser != nil { 246 + following, err := db.GetFollowing(s.db, loggedInUser.Did) 247 + if err != nil { 248 + return FollowsPageParams{}, err 249 + } 250 + if len(following) > 0 { 251 + loggedInUserFollowing = make(map[string]struct{}, len(following)) 252 + for _, follow := range following { 253 + loggedInUserFollowing[follow.SubjectDid] = struct{}{} 254 + } 255 + } 261 256 } 262 257 263 258 followCards := make([]pages.FollowCard, 0, len(follows)) ··· 293 288 return FollowsPageParams{ 294 289 LoggedInUser: loggedInUser, 295 290 Follows: followCards, 296 - Card: pages.ProfileCard{ 297 - UserDid: did, 298 - UserHandle: ident.Handle.String(), 299 - Profile: profile, 300 - FollowStatus: followStatus, 301 - FollowersCount: followersCount, 302 - FollowingCount: followingCount, 303 - }, 291 + Card: pageWithProfile.Card, 304 292 }, nil 305 293 } 306 294