+2
-2
appview/pages/pages.go
+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
+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