tangled
alpha
login
or
join now
back
round
5
view raw
appview: state: dedup profile pages
#504
merged
opened by
ptr.pet
4 months ago
targeting
master
from
[deleted fork]
: followers-following-list
rename existing ProfilePage to ProfileHomePage
Signed-off-by: dusk
y.bera003.06@protonmail.com
options
unified
split
Changed files
+112
-124
appview
pages
pages.go
state
profile.go
+2
-2
appview/pages/pages.go
···
408
408
return p.execute("repo/fork", w, params)
409
409
}
410
410
411
411
-
type ProfilePageParams struct {
411
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
430
-
func (p *Pages) ProfilePage(w io.Writer, params ProfilePageParams) error {
430
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
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
29
-
s.profilePage(w, r)
28
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
39
-
func (s *State) profilePage(w http.ResponseWriter, r *http.Request) {
38
38
+
type ProfilePageParams struct {
39
39
+
Id identity.Identity
40
40
+
LoggedInUser *oauth.User
41
41
+
Card pages.ProfileCard
42
42
+
}
43
43
+
44
44
+
func (s *State) profilePage(w http.ResponseWriter, r *http.Request) *ProfilePageParams {
40
45
didOrHandle := chi.URLParam(r, "user")
41
46
if didOrHandle == "" {
42
42
-
http.Error(w, "Bad request", http.StatusBadRequest)
43
43
-
return
47
47
+
http.Error(w, "bad request", http.StatusBadRequest)
48
48
+
return nil
44
49
}
45
50
46
51
ident, ok := r.Context().Value("resolvedId").(identity.Identity)
47
52
if !ok {
48
48
-
s.pages.Error404(w)
49
49
-
return
53
53
+
log.Printf("malformed middleware")
54
54
+
w.WriteHeader(http.StatusInternalServerError)
55
55
+
return nil
50
56
}
57
57
+
did := ident.DID.String()
51
58
52
52
-
profile, err := db.GetProfile(s.db, ident.DID.String())
59
59
+
profile, err := db.GetProfile(s.db, did)
53
60
if err != nil {
54
54
-
log.Printf("getting profile data for %s: %s", ident.DID.String(), err)
61
61
+
log.Printf("getting profile data for %s: %s", did, err)
62
62
+
s.pages.Error500(w)
63
63
+
return nil
64
64
+
}
65
65
+
66
66
+
followersCount, followingCount, err := db.GetFollowerFollowingCount(s.db, did)
67
67
+
if err != nil {
68
68
+
log.Printf("getting follow stats for %s: %s", did, err)
55
69
}
56
70
71
71
+
loggedInUser := s.oauth.GetUser(r)
72
72
+
followStatus := db.IsNotFollowing
73
73
+
if loggedInUser != nil {
74
74
+
followStatus = db.GetFollowStatus(s.db, loggedInUser.Did, did)
75
75
+
}
76
76
+
77
77
+
return &ProfilePageParams{
78
78
+
Id: ident,
79
79
+
LoggedInUser: loggedInUser,
80
80
+
Card: pages.ProfileCard{
81
81
+
UserDid: did,
82
82
+
UserHandle: ident.Handle.String(),
83
83
+
Profile: profile,
84
84
+
FollowStatus: followStatus,
85
85
+
FollowersCount: followersCount,
86
86
+
FollowingCount: followingCount,
87
87
+
},
88
88
+
}
89
89
+
}
90
90
+
91
91
+
func (s *State) profileHomePage(w http.ResponseWriter, r *http.Request) {
92
92
+
pageWithProfile := s.profilePage(w, r)
93
93
+
if pageWithProfile == nil {
94
94
+
return
95
95
+
}
96
96
+
97
97
+
id := pageWithProfile.Id
57
98
repos, err := db.GetRepos(
58
99
s.db,
59
100
0,
60
60
-
db.FilterEq("did", ident.DID.String()),
101
101
+
db.FilterEq("did", id.DID),
61
102
)
62
103
if err != nil {
63
63
-
log.Printf("getting repos for %s: %s", ident.DID.String(), err)
104
104
+
log.Printf("getting repos for %s: %s", id.DID, err)
64
105
}
65
106
107
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
80
-
collaboratingRepos, err := db.CollaboratingIn(s.db, ident.DID.String())
122
122
+
collaboratingRepos, err := db.CollaboratingIn(s.db, id.DID.String())
81
123
if err != nil {
82
82
-
log.Printf("getting collaborating repos for %s: %s", ident.DID.String(), err)
124
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
93
-
timeline, err := db.MakeProfileTimeline(s.db, ident.DID.String())
135
135
+
timeline, err := db.MakeProfileTimeline(s.db, id.DID.String())
94
136
if err != nil {
95
95
-
log.Printf("failed to create profile timeline for %s: %s", ident.DID.String(), err)
137
137
+
log.Printf("failed to create profile timeline for %s: %s", id.DID, err)
96
138
}
97
139
98
98
-
followers, following, err := db.GetFollowerFollowingCount(s.db, ident.DID.String())
99
99
-
if err != nil {
100
100
-
log.Printf("getting follow stats repos for %s: %s", ident.DID.String(), err)
140
140
+
var didsToResolve []string
141
141
+
for _, r := range collaboratingRepos {
142
142
+
didsToResolve = append(didsToResolve, r.Did)
101
143
}
102
102
-
103
103
-
loggedInUser := s.oauth.GetUser(r)
104
104
-
followStatus := db.IsNotFollowing
105
105
-
if loggedInUser != nil {
106
106
-
followStatus = db.GetFollowStatus(s.db, loggedInUser.Did, ident.DID.String())
144
144
+
for _, byMonth := range timeline.ByMonth {
145
145
+
for _, pe := range byMonth.PullEvents.Items {
146
146
+
didsToResolve = append(didsToResolve, pe.Repo.Did)
147
147
+
}
148
148
+
for _, ie := range byMonth.IssueEvents.Items {
149
149
+
didsToResolve = append(didsToResolve, ie.Metadata.Repo.Did)
150
150
+
}
151
151
+
for _, re := range byMonth.RepoEvents {
152
152
+
didsToResolve = append(didsToResolve, re.Repo.Did)
153
153
+
if re.Source != nil {
154
154
+
didsToResolve = append(didsToResolve, re.Source.Did)
155
155
+
}
156
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
113
-
db.FilterEq("did", ident.DID.String()),
163
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
118
-
log.Println("failed to get punchcard for did", "did", ident.DID.String(), "err", err)
168
168
+
log.Println("failed to get punchcard for did", "did", id.DID, "err", err)
119
169
}
120
170
121
121
-
s.pages.ProfilePage(w, pages.ProfilePageParams{
122
122
-
LoggedInUser: loggedInUser,
171
171
+
s.pages.ProfileHomePage(w, pages.ProfileHomePageParams{
172
172
+
LoggedInUser: pageWithProfile.LoggedInUser,
123
173
Repos: pinnedRepos,
124
174
CollaboratingRepos: pinnedCollaboratingRepos,
125
125
-
Card: pages.ProfileCard{
126
126
-
UserDid: ident.DID.String(),
127
127
-
UserHandle: ident.Handle.String(),
128
128
-
Profile: profile,
129
129
-
FollowStatus: followStatus,
130
130
-
FollowersCount: followers,
131
131
-
FollowingCount: following,
132
132
-
},
133
133
-
Punchcard: punchcard,
134
134
-
ProfileTimeline: timeline,
175
175
+
Card: pageWithProfile.Card,
176
176
+
Punchcard: punchcard,
177
177
+
ProfileTimeline: timeline,
135
178
})
136
179
}
137
180
138
181
func (s *State) reposPage(w http.ResponseWriter, r *http.Request) {
139
139
-
ident, ok := r.Context().Value("resolvedId").(identity.Identity)
140
140
-
if !ok {
141
141
-
s.pages.Error404(w)
182
182
+
pageWithProfile := s.profilePage(w, r)
183
183
+
if pageWithProfile == nil {
142
184
return
143
185
}
144
186
145
145
-
profile, err := db.GetProfile(s.db, ident.DID.String())
146
146
-
if err != nil {
147
147
-
log.Printf("getting profile data for %s: %s", ident.DID.String(), err)
148
148
-
}
149
149
-
187
187
+
id := pageWithProfile.Id
150
188
repos, err := db.GetRepos(
151
189
s.db,
152
190
0,
153
153
-
db.FilterEq("did", ident.DID.String()),
191
191
+
db.FilterEq("did", id.DID),
154
192
)
155
193
if err != nil {
156
156
-
log.Printf("getting repos for %s: %s", ident.DID.String(), err)
157
157
-
}
158
158
-
159
159
-
loggedInUser := s.oauth.GetUser(r)
160
160
-
followStatus := db.IsNotFollowing
161
161
-
if loggedInUser != nil {
162
162
-
followStatus = db.GetFollowStatus(s.db, loggedInUser.Did, ident.DID.String())
163
163
-
}
164
164
-
165
165
-
followers, following, err := db.GetFollowerFollowingCount(s.db, ident.DID.String())
166
166
-
if err != nil {
167
167
-
log.Printf("getting follow stats repos for %s: %s", ident.DID.String(), err)
194
194
+
log.Printf("getting repos for %s: %s", id.DID, err)
168
195
}
169
196
170
197
s.pages.ReposPage(w, pages.ReposPageParams{
171
171
-
LoggedInUser: loggedInUser,
198
198
+
LoggedInUser: pageWithProfile.LoggedInUser,
172
199
Repos: repos,
173
173
-
Card: pages.ProfileCard{
174
174
-
UserDid: ident.DID.String(),
175
175
-
UserHandle: ident.Handle.String(),
176
176
-
Profile: profile,
177
177
-
FollowStatus: followStatus,
178
178
-
FollowersCount: followers,
179
179
-
FollowingCount: following,
180
180
-
},
200
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
191
-
ident, ok := r.Context().Value("resolvedId").(identity.Identity)
192
192
-
if !ok {
193
193
-
s.pages.Error404(w)
194
194
-
return FollowsPageParams{}, errors.New("identity not found")
211
211
+
pageWithProfile := s.profilePage(w, r)
212
212
+
if pageWithProfile == nil {
213
213
+
return FollowsPageParams{}, nil
195
214
}
196
196
-
did := ident.DID.String()
197
215
198
198
-
profile, err := db.GetProfile(s.db, did)
199
199
-
if err != nil {
200
200
-
log.Printf("getting profile data for %s: %s", did, err)
201
201
-
return FollowsPageParams{}, err
202
202
-
}
216
216
+
id := pageWithProfile.Id
217
217
+
loggedInUser := pageWithProfile.LoggedInUser
203
218
204
204
-
loggedInUser := s.oauth.GetUser(r)
205
205
-
206
206
-
follows, err := fetchFollows(s.db, did)
219
219
+
follows, err := fetchFollows(s.db, id.DID.String())
207
220
if err != nil {
208
208
-
log.Printf("getting followers for %s: %s", did, err)
209
209
-
return FollowsPageParams{}, err
210
210
-
}
211
211
-
212
212
-
var loggedInUserFollowing map[string]struct{}
213
213
-
if loggedInUser != nil {
214
214
-
following, err := db.GetFollowing(s.db, loggedInUser.Did)
215
215
-
if err != nil {
216
216
-
return FollowsPageParams{}, err
217
217
-
}
218
218
-
if len(following) > 0 {
219
219
-
loggedInUserFollowing = make(map[string]struct{}, len(following))
220
220
-
for _, follow := range following {
221
221
-
loggedInUserFollowing[follow.SubjectDid] = struct{}{}
222
222
-
}
223
223
-
}
224
224
-
}
225
225
-
226
226
-
followStatus := db.IsNotFollowing
227
227
-
if loggedInUser != nil {
228
228
-
followStatus = db.GetFollowStatus(s.db, loggedInUser.Did, did)
229
229
-
}
230
230
-
231
231
-
followersCount, followingCount, err := db.GetFollowerFollowingCount(s.db, did)
232
232
-
if err != nil {
233
233
-
log.Printf("getting follow stats followers for %s: %s", did, err)
221
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
241
-
Card: pages.ProfileCard{
242
242
-
UserDid: did,
243
243
-
UserHandle: ident.Handle.String(),
244
244
-
Profile: profile,
245
245
-
FollowStatus: followStatus,
246
246
-
FollowersCount: followersCount,
247
247
-
FollowingCount: followingCount,
248
248
-
},
229
229
+
Card: pageWithProfile.Card,
249
230
}, nil
250
231
}
251
232
···
260
241
return FollowsPageParams{}, err
261
242
}
262
243
244
244
+
var loggedInUserFollowing map[string]struct{}
245
245
+
if loggedInUser != nil {
246
246
+
following, err := db.GetFollowing(s.db, loggedInUser.Did)
247
247
+
if err != nil {
248
248
+
return FollowsPageParams{}, err
249
249
+
}
250
250
+
if len(following) > 0 {
251
251
+
loggedInUserFollowing = make(map[string]struct{}, len(following))
252
252
+
for _, follow := range following {
253
253
+
loggedInUserFollowing[follow.SubjectDid] = struct{}{}
254
254
+
}
255
255
+
}
256
256
+
}
257
257
+
263
258
followCards := make([]pages.FollowCard, 0, len(follows))
264
259
for _, did := range followDids {
265
260
followersCount, followingCount, err := db.GetFollowerFollowingCount(s.db, did)
···
293
288
return FollowsPageParams{
294
289
LoggedInUser: loggedInUser,
295
290
Follows: followCards,
296
296
-
Card: pages.ProfileCard{
297
297
-
UserDid: did,
298
298
-
UserHandle: ident.Handle.String(),
299
299
-
Profile: profile,
300
300
-
FollowStatus: followStatus,
301
301
-
FollowersCount: followersCount,
302
302
-
FollowingCount: followingCount,
303
303
-
},
291
291
+
Card: pageWithProfile.Card,
304
292
}, nil
305
293
}
306
294