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: state: dedup profile pages

- rename existing ProfilePage to ProfileHomePage

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

authored by

dusk and committed by
Tangled
4e5b1f20 5b6b7aea

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