appview: state: dedup profile pages #504

merged
opened by ptr.pet targeting master from ptr.pet/core: followers-following-list
Changed files
+369 -381
.jjconflict-base-0
appview
pages
state
.jjconflict-base-1
appview
pages
state
.jjconflict-side-0
appview
pages
state
.jjconflict-side-1
appview
pages
state
.jjconflict-side-2
appview
pages
state
+2 -2
.jjconflict-base-0/appview/pages/pages.go
···
return p.execute("repo/fork", w, params)
}
-
type ProfilePageParams struct {
+
type ProfileHomePageParams struct {
LoggedInUser *oauth.User
Repos []db.Repo
CollaboratingRepos []db.Repo
···
Profile *db.Profile
}
-
func (p *Pages) ProfilePage(w io.Writer, params ProfilePageParams) error {
+
func (p *Pages) ProfileHomePage(w io.Writer, params ProfileHomePageParams) error {
return p.execute("user/profile", w, params)
}
+113 -103
.jjconflict-base-0/appview/state/profile.go
···
tabVal := r.URL.Query().Get("tab")
switch tabVal {
case "":
-
s.profilePage(w, r)
+
s.profileHomePage(w, r)
case "repos":
s.reposPage(w, r)
case "followers":
···
}
}
-
func (s *State) profilePage(w http.ResponseWriter, r *http.Request) {
+
type ProfilePageParams struct {
+
Id identity.Identity
+
LoggedInUser *oauth.User
+
Card pages.ProfileCard
+
}
+
+
func (s *State) profilePage(w http.ResponseWriter, r *http.Request) *ProfilePageParams {
didOrHandle := chi.URLParam(r, "user")
if didOrHandle == "" {
-
http.Error(w, "Bad request", http.StatusBadRequest)
-
return
+
http.Error(w, "bad request", http.StatusBadRequest)
+
return nil
}
ident, ok := r.Context().Value("resolvedId").(identity.Identity)
if !ok {
-
s.pages.Error404(w)
-
return
+
log.Printf("malformed middleware")
+
w.WriteHeader(http.StatusInternalServerError)
+
return nil
}
+
did := ident.DID.String()
-
profile, err := db.GetProfile(s.db, ident.DID.String())
+
profile, err := db.GetProfile(s.db, did)
if err != nil {
-
log.Printf("getting profile data for %s: %s", ident.DID.String(), err)
+
log.Printf("getting profile data for %s: %s", did, err)
}
+
followStats, err := db.GetFollowerFollowingCount(s.db, did)
+
if err != nil {
+
log.Printf("getting follow stats for %s: %s", did, err)
+
}
+
+
loggedInUser := s.oauth.GetUser(r)
+
followStatus := db.IsNotFollowing
+
if loggedInUser != nil {
+
followStatus = db.GetFollowStatus(s.db, loggedInUser.Did, did)
+
}
+
+
return &ProfilePageParams{
+
Id: ident,
+
LoggedInUser: loggedInUser,
+
Card: pages.ProfileCard{
+
UserDid: did,
+
UserHandle: ident.Handle.String(),
+
Profile: profile,
+
FollowStatus: followStatus,
+
FollowersCount: followStats.Followers,
+
FollowingCount: followStats.Following,
+
},
+
}
+
}
+
+
func (s *State) profileHomePage(w http.ResponseWriter, r *http.Request) {
+
pageWithProfile := s.profilePage(w, r)
+
if pageWithProfile == nil {
+
return
+
}
+
+
id := pageWithProfile.Id
repos, err := db.GetRepos(
s.db,
0,
-
db.FilterEq("did", ident.DID.String()),
+
db.FilterEq("did", id.DID),
)
if err != nil {
-
log.Printf("getting repos for %s: %s", ident.DID.String(), err)
+
log.Printf("getting repos for %s: %s", id.DID, err)
}
+
profile := pageWithProfile.Card.Profile
// filter out ones that are pinned
pinnedRepos := []db.Repo{}
for i, r := range repos {
···
}
}
-
collaboratingRepos, err := db.CollaboratingIn(s.db, ident.DID.String())
+
collaboratingRepos, err := db.CollaboratingIn(s.db, id.DID.String())
if err != nil {
-
log.Printf("getting collaborating repos for %s: %s", ident.DID.String(), err)
+
log.Printf("getting collaborating repos for %s: %s", id.DID, err)
}
pinnedCollaboratingRepos := []db.Repo{}
···
}
}
-
timeline, err := db.MakeProfileTimeline(s.db, ident.DID.String())
+
timeline, err := db.MakeProfileTimeline(s.db, id.DID.String())
if err != nil {
-
log.Printf("failed to create profile timeline for %s: %s", ident.DID.String(), err)
+
log.Printf("failed to create profile timeline for %s: %s", id.DID, err)
}
-
followers, following, err := db.GetFollowerFollowingCount(s.db, ident.DID.String())
-
if err != nil {
-
log.Printf("getting follow stats repos for %s: %s", ident.DID.String(), err)
+
var didsToResolve []string
+
for _, r := range collaboratingRepos {
+
didsToResolve = append(didsToResolve, r.Did)
}
-
-
loggedInUser := s.oauth.GetUser(r)
-
followStatus := db.IsNotFollowing
-
if loggedInUser != nil {
-
followStatus = db.GetFollowStatus(s.db, loggedInUser.Did, ident.DID.String())
+
for _, byMonth := range timeline.ByMonth {
+
for _, pe := range byMonth.PullEvents.Items {
+
didsToResolve = append(didsToResolve, pe.Repo.Did)
+
}
+
for _, ie := range byMonth.IssueEvents.Items {
+
didsToResolve = append(didsToResolve, ie.Metadata.Repo.Did)
+
}
+
for _, re := range byMonth.RepoEvents {
+
didsToResolve = append(didsToResolve, re.Repo.Did)
+
if re.Source != nil {
+
didsToResolve = append(didsToResolve, re.Source.Did)
+
}
+
}
}
now := time.Now()
startOfYear := time.Date(now.Year(), 1, 1, 0, 0, 0, 0, time.UTC)
punchcard, err := db.MakePunchcard(
s.db,
-
db.FilterEq("did", ident.DID.String()),
+
db.FilterEq("did", id.DID),
db.FilterGte("date", startOfYear.Format(time.DateOnly)),
db.FilterLte("date", now.Format(time.DateOnly)),
)
if err != nil {
-
log.Println("failed to get punchcard for did", "did", ident.DID.String(), "err", err)
+
log.Println("failed to get punchcard for did", "did", id.DID, "err", err)
}
-
s.pages.ProfilePage(w, pages.ProfilePageParams{
-
LoggedInUser: loggedInUser,
+
s.pages.ProfileHomePage(w, pages.ProfileHomePageParams{
+
LoggedInUser: pageWithProfile.LoggedInUser,
Repos: pinnedRepos,
CollaboratingRepos: pinnedCollaboratingRepos,
-
Card: pages.ProfileCard{
-
UserDid: ident.DID.String(),
-
UserHandle: ident.Handle.String(),
-
Profile: profile,
-
FollowStatus: followStatus,
-
FollowersCount: followers,
-
FollowingCount: following,
-
},
-
Punchcard: punchcard,
-
ProfileTimeline: timeline,
+
Card: pageWithProfile.Card,
+
Punchcard: punchcard,
+
ProfileTimeline: timeline,
})
}
func (s *State) reposPage(w http.ResponseWriter, r *http.Request) {
-
ident, ok := r.Context().Value("resolvedId").(identity.Identity)
-
if !ok {
-
s.pages.Error404(w)
+
pageWithProfile := s.profilePage(w, r)
+
if pageWithProfile == nil {
return
}
-
profile, err := db.GetProfile(s.db, ident.DID.String())
-
if err != nil {
-
log.Printf("getting profile data for %s: %s", ident.DID.String(), err)
-
}
-
+
id := pageWithProfile.Id
repos, err := db.GetRepos(
s.db,
0,
-
db.FilterEq("did", ident.DID.String()),
+
db.FilterEq("did", id.DID),
)
if err != nil {
-
log.Printf("getting repos for %s: %s", ident.DID.String(), err)
-
}
-
-
loggedInUser := s.oauth.GetUser(r)
-
followStatus := db.IsNotFollowing
-
if loggedInUser != nil {
-
followStatus = db.GetFollowStatus(s.db, loggedInUser.Did, ident.DID.String())
-
}
-
-
followers, following, err := db.GetFollowerFollowingCount(s.db, ident.DID.String())
-
if err != nil {
-
log.Printf("getting follow stats repos for %s: %s", ident.DID.String(), err)
+
log.Printf("getting repos for %s: %s", id.DID, err)
}
s.pages.ReposPage(w, pages.ReposPageParams{
-
LoggedInUser: loggedInUser,
+
LoggedInUser: pageWithProfile.LoggedInUser,
Repos: repos,
-
Card: pages.ProfileCard{
-
UserDid: ident.DID.String(),
-
UserHandle: ident.Handle.String(),
-
Profile: profile,
-
FollowStatus: followStatus,
-
FollowersCount: followers,
-
FollowingCount: following,
-
},
+
Card: pageWithProfile.Card,
})
}
···
}
func (s *State) followPage(w http.ResponseWriter, r *http.Request, fetchFollows func(db.Execer, string) ([]db.Follow, error), extractDid func(db.Follow) string) *FollowsPageParams {
-
ident, ok := r.Context().Value("resolvedId").(identity.Identity)
-
if !ok {
-
s.pages.Error404(w)
+
pageWithProfile := s.profilePage(w, r)
+
if pageWithProfile == nil {
return nil
}
-
did := ident.DID.String()
-
profile, err := db.GetProfile(s.db, did)
-
if err != nil {
-
log.Printf("getting profile data for %s: %s", did, err)
-
}
+
id := pageWithProfile.Id
+
loggedInUser := pageWithProfile.LoggedInUser
-
loggedInUser := s.oauth.GetUser(r)
-
-
follows, err := fetchFollows(s.db, did)
+
follows, err := fetchFollows(s.db, id.DID.String())
if err != nil {
-
log.Printf("getting followers for %s: %s", did, err)
+
log.Printf("getting followers for %s: %s", id.DID, err)
}
if len(follows) == 0 {
-
return nil
+
return &FollowsPageParams{
+
LoggedInUser: loggedInUser,
+
Follows: []pages.FollowCard{},
+
Card: pageWithProfile.Card,
+
}
}
followDids := make([]string, 0, len(follows))
···
profiles, err := db.GetProfiles(s.db, db.FilterIn("did", followDids))
if err != nil {
log.Printf("getting profile for %s: %s", followDids, err)
-
return nil
+
}
+
+
followStatsMap, err := db.GetFollowerFollowingCounts(s.db, followDids)
+
if err != nil {
+
log.Printf("getting follow counts for %s: %s", followDids, err)
}
var loggedInUserFollowing map[string]struct{}
···
followCards := make([]pages.FollowCard, 0, len(follows))
for _, did := range followDids {
-
followersCount, followingCount, err := db.GetFollowerFollowingCount(s.db, did)
-
if err != nil {
-
log.Printf("getting follow stats for %s: %s", did, err)
+
followStats, exists := followStatsMap[did]
+
if !exists {
+
followStats = db.FollowStats{}
}
followStatus := db.IsNotFollowing
if loggedInUserFollowing != nil {
···
followCards = append(followCards, pages.FollowCard{
UserDid: did,
FollowStatus: followStatus,
-
FollowersCount: followersCount,
-
FollowingCount: followingCount,
+
FollowersCount: followStats.Followers,
+
FollowingCount: followStats.Following,
Profile: profile,
})
}
-
followStatus := db.IsNotFollowing
-
if loggedInUser != nil {
-
followStatus = db.GetFollowStatus(s.db, loggedInUser.Did, did)
-
}
-
-
followersCount, followingCount, err := db.GetFollowerFollowingCount(s.db, did)
-
if err != nil {
-
log.Printf("getting follow stats followers for %s: %s", did, err)
-
}
-
return &FollowsPageParams{
LoggedInUser: loggedInUser,
Follows: followCards,
-
Card: pages.ProfileCard{
-
UserDid: did,
-
UserHandle: ident.Handle.String(),
-
Profile: profile,
-
FollowStatus: followStatus,
-
FollowersCount: followersCount,
-
FollowingCount: followingCount,
-
},
+
Card: pageWithProfile.Card,
}
}
func (s *State) followersPage(w http.ResponseWriter, r *http.Request) {
followPage := s.followPage(w, r, db.GetFollowers, func(f db.Follow) string { return f.UserDid })
+
if followPage == nil {
+
return
+
}
s.pages.FollowersPage(w, pages.FollowersPageParams{
LoggedInUser: followPage.LoggedInUser,
···
func (s *State) followingPage(w http.ResponseWriter, r *http.Request) {
followPage := s.followPage(w, r, db.GetFollowing, func(f db.Follow) string { return f.SubjectDid })
+
if followPage == nil {
+
return
+
}
s.pages.FollowingPage(w, pages.FollowingPageParams{
LoggedInUser: followPage.LoggedInUser,
+2 -2
.jjconflict-base-1/appview/pages/pages.go
···
return p.execute("repo/fork", w, params)
}
-
type ProfilePageParams struct {
+
type ProfileHomePageParams struct {
LoggedInUser *oauth.User
Repos []db.Repo
CollaboratingRepos []db.Repo
···
Profile *db.Profile
}
-
func (p *Pages) ProfilePage(w io.Writer, params ProfilePageParams) error {
+
func (p *Pages) ProfileHomePage(w io.Writer, params ProfileHomePageParams) error {
return p.execute("user/profile", w, params)
}
.jjconflict-base-0/appview/pages/templates/timeline.html .jjconflict-base-1/appview/pages/templates/timeline.html
+11 -25
.jjconflict-base-1/appview/state/profile.go
···
log.Printf("getting profile data for %s: %s", did, err)
}
-
followStats, err := db.GetFollowerFollowingCount(s.db, did)
+
followersCount, followingCount, err := db.GetFollowerFollowingCount(s.db, did)
if err != nil {
log.Printf("getting follow stats for %s: %s", did, err)
}
···
UserHandle: ident.Handle.String(),
Profile: profile,
FollowStatus: followStatus,
-
FollowersCount: followStats.Followers,
-
FollowingCount: followStats.Following,
+
FollowersCount: followersCount,
+
FollowingCount: followingCount,
},
}
}
···
}
id := pageWithProfile.Id
-
loggedInUser := pageWithProfile.LoggedInUser
follows, err := fetchFollows(s.db, id.DID.String())
if err != nil {
···
}
if len(follows) == 0 {
-
return &FollowsPageParams{
-
LoggedInUser: loggedInUser,
-
Follows: []pages.FollowCard{},
-
Card: pageWithProfile.Card,
-
}
+
return nil
}
followDids := make([]string, 0, len(follows))
···
profiles, err := db.GetProfiles(s.db, db.FilterIn("did", followDids))
if err != nil {
log.Printf("getting profile for %s: %s", followDids, err)
+
return nil
}
-
followStatsMap, err := db.GetFollowerFollowingCounts(s.db, followDids)
-
if err != nil {
-
log.Printf("getting follow counts for %s: %s", followDids, err)
-
}
-
+
loggedInUser := pageWithProfile.LoggedInUser
var loggedInUserFollowing map[string]struct{}
if loggedInUser != nil {
following, err := db.GetFollowing(s.db, loggedInUser.Did)
···
followCards := make([]pages.FollowCard, 0, len(follows))
for _, did := range followDids {
-
followStats, exists := followStatsMap[did]
-
if !exists {
-
followStats = db.FollowStats{}
+
followersCount, followingCount, err := db.GetFollowerFollowingCount(s.db, did)
+
if err != nil {
+
log.Printf("getting follow stats for %s: %s", did, err)
}
followStatus := db.IsNotFollowing
if loggedInUserFollowing != nil {
···
followCards = append(followCards, pages.FollowCard{
UserDid: did,
FollowStatus: followStatus,
-
FollowersCount: followStats.Followers,
-
FollowingCount: followStats.Following,
+
FollowersCount: followersCount,
+
FollowingCount: followingCount,
Profile: profile,
})
}
···
func (s *State) followersPage(w http.ResponseWriter, r *http.Request) {
followPage := s.followPage(w, r, db.GetFollowers, func(f db.Follow) string { return f.UserDid })
-
if followPage == nil {
-
return
-
}
s.pages.FollowersPage(w, pages.FollowersPageParams{
LoggedInUser: followPage.LoggedInUser,
···
func (s *State) followingPage(w http.ResponseWriter, r *http.Request) {
followPage := s.followPage(w, r, db.GetFollowing, func(f db.Follow) string { return f.SubjectDid })
-
if followPage == nil {
-
return
-
}
s.pages.FollowingPage(w, pages.FollowingPageParams{
LoggedInUser: followPage.LoggedInUser,
+2 -2
.jjconflict-side-0/appview/pages/pages.go
···
return p.execute("repo/fork", w, params)
}
-
type ProfilePageParams struct {
+
type ProfileHomePageParams struct {
LoggedInUser *oauth.User
Repos []db.Repo
CollaboratingRepos []db.Repo
···
Profile *db.Profile
}
-
func (p *Pages) ProfilePage(w io.Writer, params ProfilePageParams) error {
+
func (p *Pages) ProfileHomePage(w io.Writer, params ProfileHomePageParams) error {
return p.execute("user/profile", w, params)
}
+92 -96
.jjconflict-side-0/appview/state/profile.go
···
tabVal := r.URL.Query().Get("tab")
switch tabVal {
case "":
-
s.profilePage(w, r)
+
s.profileHomePage(w, r)
case "repos":
s.reposPage(w, r)
case "followers":
···
}
}
-
func (s *State) profilePage(w http.ResponseWriter, r *http.Request) {
+
type ProfilePageParams struct {
+
Id identity.Identity
+
LoggedInUser *oauth.User
+
Card pages.ProfileCard
+
}
+
+
func (s *State) profilePage(w http.ResponseWriter, r *http.Request) *ProfilePageParams {
didOrHandle := chi.URLParam(r, "user")
if didOrHandle == "" {
-
http.Error(w, "Bad request", http.StatusBadRequest)
-
return
+
http.Error(w, "bad request", http.StatusBadRequest)
+
return nil
}
ident, ok := r.Context().Value("resolvedId").(identity.Identity)
if !ok {
-
s.pages.Error404(w)
-
return
+
log.Printf("malformed middleware")
+
w.WriteHeader(http.StatusInternalServerError)
+
return nil
+
}
+
did := ident.DID.String()
+
+
profile, err := db.GetProfile(s.db, did)
+
if err != nil {
+
log.Printf("getting profile data for %s: %s", did, err)
}
-
profile, err := db.GetProfile(s.db, ident.DID.String())
+
followersCount, followingCount, err := db.GetFollowerFollowingCount(s.db, did)
if err != nil {
-
log.Printf("getting profile data for %s: %s", ident.DID.String(), err)
+
log.Printf("getting follow stats for %s: %s", did, err)
}
+
loggedInUser := s.oauth.GetUser(r)
+
followStatus := db.IsNotFollowing
+
if loggedInUser != nil {
+
followStatus = db.GetFollowStatus(s.db, loggedInUser.Did, did)
+
}
+
+
return &ProfilePageParams{
+
Id: ident,
+
LoggedInUser: loggedInUser,
+
Card: pages.ProfileCard{
+
UserDid: did,
+
UserHandle: ident.Handle.String(),
+
Profile: profile,
+
FollowStatus: followStatus,
+
FollowersCount: followersCount,
+
FollowingCount: followingCount,
+
},
+
}
+
}
+
+
func (s *State) profileHomePage(w http.ResponseWriter, r *http.Request) {
+
pageWithProfile := s.profilePage(w, r)
+
if pageWithProfile == nil {
+
return
+
}
+
+
id := pageWithProfile.Id
repos, err := db.GetRepos(
s.db,
0,
-
db.FilterEq("did", ident.DID.String()),
+
db.FilterEq("did", id.DID),
)
if err != nil {
-
log.Printf("getting repos for %s: %s", ident.DID.String(), err)
+
log.Printf("getting repos for %s: %s", id.DID, err)
}
+
profile := pageWithProfile.Card.Profile
// filter out ones that are pinned
pinnedRepos := []db.Repo{}
for i, r := range repos {
···
}
}
-
collaboratingRepos, err := db.CollaboratingIn(s.db, ident.DID.String())
+
collaboratingRepos, err := db.CollaboratingIn(s.db, id.DID.String())
if err != nil {
-
log.Printf("getting collaborating repos for %s: %s", ident.DID.String(), err)
+
log.Printf("getting collaborating repos for %s: %s", id.DID, err)
}
pinnedCollaboratingRepos := []db.Repo{}
···
}
}
-
timeline, err := db.MakeProfileTimeline(s.db, ident.DID.String())
+
timeline, err := db.MakeProfileTimeline(s.db, id.DID.String())
if err != nil {
-
log.Printf("failed to create profile timeline for %s: %s", ident.DID.String(), err)
+
log.Printf("failed to create profile timeline for %s: %s", id.DID, err)
}
-
followers, following, err := db.GetFollowerFollowingCount(s.db, ident.DID.String())
-
if err != nil {
-
log.Printf("getting follow stats repos for %s: %s", ident.DID.String(), err)
+
var didsToResolve []string
+
for _, r := range collaboratingRepos {
+
didsToResolve = append(didsToResolve, r.Did)
}
-
-
loggedInUser := s.oauth.GetUser(r)
-
followStatus := db.IsNotFollowing
-
if loggedInUser != nil {
-
followStatus = db.GetFollowStatus(s.db, loggedInUser.Did, ident.DID.String())
+
for _, byMonth := range timeline.ByMonth {
+
for _, pe := range byMonth.PullEvents.Items {
+
didsToResolve = append(didsToResolve, pe.Repo.Did)
+
}
+
for _, ie := range byMonth.IssueEvents.Items {
+
didsToResolve = append(didsToResolve, ie.Metadata.Repo.Did)
+
}
+
for _, re := range byMonth.RepoEvents {
+
didsToResolve = append(didsToResolve, re.Repo.Did)
+
if re.Source != nil {
+
didsToResolve = append(didsToResolve, re.Source.Did)
+
}
+
}
}
now := time.Now()
startOfYear := time.Date(now.Year(), 1, 1, 0, 0, 0, 0, time.UTC)
punchcard, err := db.MakePunchcard(
s.db,
-
db.FilterEq("did", ident.DID.String()),
+
db.FilterEq("did", id.DID),
db.FilterGte("date", startOfYear.Format(time.DateOnly)),
db.FilterLte("date", now.Format(time.DateOnly)),
)
if err != nil {
-
log.Println("failed to get punchcard for did", "did", ident.DID.String(), "err", err)
+
log.Println("failed to get punchcard for did", "did", id.DID, "err", err)
}
-
s.pages.ProfilePage(w, pages.ProfilePageParams{
-
LoggedInUser: loggedInUser,
+
s.pages.ProfileHomePage(w, pages.ProfileHomePageParams{
+
LoggedInUser: pageWithProfile.LoggedInUser,
Repos: pinnedRepos,
CollaboratingRepos: pinnedCollaboratingRepos,
-
Card: pages.ProfileCard{
-
UserDid: ident.DID.String(),
-
UserHandle: ident.Handle.String(),
-
Profile: profile,
-
FollowStatus: followStatus,
-
FollowersCount: followers,
-
FollowingCount: following,
-
},
-
Punchcard: punchcard,
-
ProfileTimeline: timeline,
+
Card: pageWithProfile.Card,
+
Punchcard: punchcard,
+
ProfileTimeline: timeline,
})
}
func (s *State) reposPage(w http.ResponseWriter, r *http.Request) {
-
ident, ok := r.Context().Value("resolvedId").(identity.Identity)
-
if !ok {
-
s.pages.Error404(w)
+
pageWithProfile := s.profilePage(w, r)
+
if pageWithProfile == nil {
return
}
-
profile, err := db.GetProfile(s.db, ident.DID.String())
-
if err != nil {
-
log.Printf("getting profile data for %s: %s", ident.DID.String(), err)
-
}
-
+
id := pageWithProfile.Id
repos, err := db.GetRepos(
s.db,
0,
-
db.FilterEq("did", ident.DID.String()),
+
db.FilterEq("did", id.DID),
)
if err != nil {
-
log.Printf("getting repos for %s: %s", ident.DID.String(), err)
-
}
-
-
loggedInUser := s.oauth.GetUser(r)
-
followStatus := db.IsNotFollowing
-
if loggedInUser != nil {
-
followStatus = db.GetFollowStatus(s.db, loggedInUser.Did, ident.DID.String())
-
}
-
-
followers, following, err := db.GetFollowerFollowingCount(s.db, ident.DID.String())
-
if err != nil {
-
log.Printf("getting follow stats repos for %s: %s", ident.DID.String(), err)
+
log.Printf("getting repos for %s: %s", id.DID, err)
}
s.pages.ReposPage(w, pages.ReposPageParams{
-
LoggedInUser: loggedInUser,
+
LoggedInUser: pageWithProfile.LoggedInUser,
Repos: repos,
-
Card: pages.ProfileCard{
-
UserDid: ident.DID.String(),
-
UserHandle: ident.Handle.String(),
-
Profile: profile,
-
FollowStatus: followStatus,
-
FollowersCount: followers,
-
FollowingCount: following,
-
},
+
Card: pageWithProfile.Card,
})
}
···
}
func (s *State) followPage(w http.ResponseWriter, r *http.Request, fetchFollows func(db.Execer, string) ([]db.Follow, error), extractDid func(db.Follow) string) *FollowsPageParams {
-
ident, ok := r.Context().Value("resolvedId").(identity.Identity)
-
if !ok {
-
s.pages.Error404(w)
+
pageWithProfile := s.profilePage(w, r)
+
if pageWithProfile == nil {
return nil
}
-
did := ident.DID.String()
-
profile, err := db.GetProfile(s.db, did)
-
if err != nil {
-
log.Printf("getting profile data for %s: %s", did, err)
-
}
+
id := pageWithProfile.Id
-
loggedInUser := s.oauth.GetUser(r)
-
-
follows, err := fetchFollows(s.db, did)
+
follows, err := fetchFollows(s.db, id.DID.String())
if err != nil {
-
log.Printf("getting followers for %s: %s", did, err)
+
log.Printf("getting followers for %s: %s", id.DID, err)
}
if len(follows) == 0 {
···
return nil
}
+
loggedInUser := pageWithProfile.LoggedInUser
var loggedInUserFollowing map[string]struct{}
if loggedInUser != nil {
following, err := db.GetFollowing(s.db, loggedInUser.Did)
···
})
}
-
followStatus := db.IsNotFollowing
-
if loggedInUser != nil {
-
followStatus = db.GetFollowStatus(s.db, loggedInUser.Did, did)
-
}
-
-
followersCount, followingCount, err := db.GetFollowerFollowingCount(s.db, did)
-
if err != nil {
-
log.Printf("getting follow stats followers for %s: %s", did, err)
-
}
-
return &FollowsPageParams{
LoggedInUser: loggedInUser,
Follows: followCards,
-
Card: pages.ProfileCard{
-
UserDid: did,
-
UserHandle: ident.Handle.String(),
-
Profile: profile,
-
FollowStatus: followStatus,
-
FollowersCount: followersCount,
-
FollowingCount: followingCount,
-
},
+
Card: pageWithProfile.Card,
}
}
+2 -2
.jjconflict-side-1/appview/pages/pages.go
···
return p.execute("repo/fork", w, params)
}
-
type ProfilePageParams struct {
+
type ProfileHomePageParams struct {
LoggedInUser *oauth.User
Repos []db.Repo
CollaboratingRepos []db.Repo
···
Profile *db.Profile
}
-
func (p *Pages) ProfilePage(w io.Writer, params ProfilePageParams) error {
+
func (p *Pages) ProfileHomePage(w io.Writer, params ProfileHomePageParams) error {
return p.execute("user/profile", w, params)
}
+125 -110
.jjconflict-side-1/appview/state/profile.go
···
tabVal := r.URL.Query().Get("tab")
switch tabVal {
case "":
-
s.profilePage(w, r)
+
s.profileHomePage(w, r)
case "repos":
s.reposPage(w, r)
case "followers":
···
}
}
-
func (s *State) profilePage(w http.ResponseWriter, r *http.Request) {
+
type ProfilePageParams struct {
+
Id identity.Identity
+
LoggedInUser *oauth.User
+
Card pages.ProfileCard
+
}
+
+
func (s *State) profilePage(w http.ResponseWriter, r *http.Request) *ProfilePageParams {
didOrHandle := chi.URLParam(r, "user")
if didOrHandle == "" {
-
http.Error(w, "Bad request", http.StatusBadRequest)
-
return
+
http.Error(w, "bad request", http.StatusBadRequest)
+
return nil
}
ident, ok := r.Context().Value("resolvedId").(identity.Identity)
if !ok {
-
s.pages.Error404(w)
-
return
+
log.Printf("malformed middleware")
+
w.WriteHeader(http.StatusInternalServerError)
+
return nil
+
}
+
did := ident.DID.String()
+
+
profile, err := db.GetProfile(s.db, did)
+
if err != nil {
+
log.Printf("getting profile data for %s: %s", did, err)
}
-
profile, err := db.GetProfile(s.db, ident.DID.String())
+
followStats, err := db.GetFollowerFollowingCount(s.db, did)
if err != nil {
-
log.Printf("getting profile data for %s: %s", ident.DID.String(), err)
+
log.Printf("getting follow stats for %s: %s", did, err)
+
}
+
+
loggedInUser := s.oauth.GetUser(r)
+
followStatus := db.IsNotFollowing
+
if loggedInUser != nil {
+
followStatus = db.GetFollowStatus(s.db, loggedInUser.Did, did)
}
+
return &ProfilePageParams{
+
Id: ident,
+
LoggedInUser: loggedInUser,
+
Card: pages.ProfileCard{
+
UserDid: did,
+
UserHandle: ident.Handle.String(),
+
Profile: profile,
+
FollowStatus: followStatus,
+
FollowersCount: followStats.Followers,
+
FollowingCount: followStats.Following,
+
},
+
}
+
}
+
+
func (s *State) profileHomePage(w http.ResponseWriter, r *http.Request) {
+
pageWithProfile := s.profilePage(w, r)
+
if pageWithProfile == nil {
+
return
+
}
+
+
id := pageWithProfile.Id
repos, err := db.GetRepos(
s.db,
0,
-
db.FilterEq("did", ident.DID.String()),
+
db.FilterEq("did", id.DID),
)
if err != nil {
-
log.Printf("getting repos for %s: %s", ident.DID.String(), err)
+
log.Printf("getting repos for %s: %s", id.DID, err)
}
+
profile := pageWithProfile.Card.Profile
// filter out ones that are pinned
pinnedRepos := []db.Repo{}
for i, r := range repos {
···
}
}
-
collaboratingRepos, err := db.CollaboratingIn(s.db, ident.DID.String())
+
collaboratingRepos, err := db.CollaboratingIn(s.db, id.DID.String())
if err != nil {
-
log.Printf("getting collaborating repos for %s: %s", ident.DID.String(), err)
+
log.Printf("getting collaborating repos for %s: %s", id.DID, err)
}
pinnedCollaboratingRepos := []db.Repo{}
···
}
}
-
timeline, err := db.MakeProfileTimeline(s.db, ident.DID.String())
+
timeline, err := db.MakeProfileTimeline(s.db, id.DID.String())
if err != nil {
-
log.Printf("failed to create profile timeline for %s: %s", ident.DID.String(), err)
+
log.Printf("failed to create profile timeline for %s: %s", id.DID, err)
}
-
followers, following, err := db.GetFollowerFollowingCount(s.db, ident.DID.String())
-
if err != nil {
-
log.Printf("getting follow stats repos for %s: %s", ident.DID.String(), err)
+
var didsToResolve []string
+
for _, r := range collaboratingRepos {
+
didsToResolve = append(didsToResolve, r.Did)
}
-
-
loggedInUser := s.oauth.GetUser(r)
-
followStatus := db.IsNotFollowing
-
if loggedInUser != nil {
-
followStatus = db.GetFollowStatus(s.db, loggedInUser.Did, ident.DID.String())
+
for _, byMonth := range timeline.ByMonth {
+
for _, pe := range byMonth.PullEvents.Items {
+
didsToResolve = append(didsToResolve, pe.Repo.Did)
+
}
+
for _, ie := range byMonth.IssueEvents.Items {
+
didsToResolve = append(didsToResolve, ie.Metadata.Repo.Did)
+
}
+
for _, re := range byMonth.RepoEvents {
+
didsToResolve = append(didsToResolve, re.Repo.Did)
+
if re.Source != nil {
+
didsToResolve = append(didsToResolve, re.Source.Did)
+
}
+
}
}
now := time.Now()
startOfYear := time.Date(now.Year(), 1, 1, 0, 0, 0, 0, time.UTC)
punchcard, err := db.MakePunchcard(
s.db,
-
db.FilterEq("did", ident.DID.String()),
+
db.FilterEq("did", id.DID),
db.FilterGte("date", startOfYear.Format(time.DateOnly)),
db.FilterLte("date", now.Format(time.DateOnly)),
)
if err != nil {
-
log.Println("failed to get punchcard for did", "did", ident.DID.String(), "err", err)
+
log.Println("failed to get punchcard for did", "did", id.DID, "err", err)
}
-
s.pages.ProfilePage(w, pages.ProfilePageParams{
-
LoggedInUser: loggedInUser,
+
s.pages.ProfileHomePage(w, pages.ProfileHomePageParams{
+
LoggedInUser: pageWithProfile.LoggedInUser,
Repos: pinnedRepos,
CollaboratingRepos: pinnedCollaboratingRepos,
-
Card: pages.ProfileCard{
-
UserDid: ident.DID.String(),
-
UserHandle: ident.Handle.String(),
-
Profile: profile,
-
FollowStatus: followStatus,
-
FollowersCount: followers,
-
FollowingCount: following,
-
},
-
Punchcard: punchcard,
-
ProfileTimeline: timeline,
+
Card: pageWithProfile.Card,
+
Punchcard: punchcard,
+
ProfileTimeline: timeline,
})
}
func (s *State) reposPage(w http.ResponseWriter, r *http.Request) {
-
ident, ok := r.Context().Value("resolvedId").(identity.Identity)
-
if !ok {
-
s.pages.Error404(w)
+
pageWithProfile := s.profilePage(w, r)
+
if pageWithProfile == nil {
return
}
-
profile, err := db.GetProfile(s.db, ident.DID.String())
-
if err != nil {
-
log.Printf("getting profile data for %s: %s", ident.DID.String(), err)
-
}
-
+
id := pageWithProfile.Id
repos, err := db.GetRepos(
s.db,
0,
-
db.FilterEq("did", ident.DID.String()),
+
db.FilterEq("did", id.DID),
)
if err != nil {
-
log.Printf("getting repos for %s: %s", ident.DID.String(), err)
-
}
-
-
loggedInUser := s.oauth.GetUser(r)
-
followStatus := db.IsNotFollowing
-
if loggedInUser != nil {
-
followStatus = db.GetFollowStatus(s.db, loggedInUser.Did, ident.DID.String())
-
}
-
-
followers, following, err := db.GetFollowerFollowingCount(s.db, ident.DID.String())
-
if err != nil {
-
log.Printf("getting follow stats repos for %s: %s", ident.DID.String(), err)
+
log.Printf("getting repos for %s: %s", id.DID, err)
}
s.pages.ReposPage(w, pages.ReposPageParams{
-
LoggedInUser: loggedInUser,
+
LoggedInUser: pageWithProfile.LoggedInUser,
Repos: repos,
-
Card: pages.ProfileCard{
-
UserDid: ident.DID.String(),
-
UserHandle: ident.Handle.String(),
-
Profile: profile,
-
FollowStatus: followStatus,
-
FollowersCount: followers,
-
FollowingCount: following,
-
},
+
Card: pageWithProfile.Card,
})
}
···
Card pages.ProfileCard
}
-
func (s *State) followPage(w http.ResponseWriter, r *http.Request, fetchFollows func(db.Execer, string) ([]db.Follow, error), extractDid func(db.Follow) string) *FollowsPageParams {
-
ident, ok := r.Context().Value("resolvedId").(identity.Identity)
-
if !ok {
-
s.pages.Error404(w)
-
return nil
-
}
-
did := ident.DID.String()
-
-
profile, err := db.GetProfile(s.db, did)
-
if err != nil {
-
log.Printf("getting profile data for %s: %s", did, err)
+
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) {
+
pageWithProfile := s.profilePage(w, r)
+
if pageWithProfile == nil {
+
return FollowsPageParams{}, nil
}
-
loggedInUser := s.oauth.GetUser(r)
+
id := pageWithProfile.Id
+
loggedInUser := pageWithProfile.LoggedInUser
-
follows, err := fetchFollows(s.db, did)
+
follows, err := fetchFollows(s.db, id.DID.String())
if err != nil {
-
log.Printf("getting followers for %s: %s", did, err)
+
log.Printf("getting followers for %s: %s", id.DID, err)
+
return FollowsPageParams{}, err
}
if len(follows) == 0 {
-
return nil
+
return FollowsPageParams{
+
LoggedInUser: loggedInUser,
+
Follows: []pages.FollowCard{},
+
Card: pageWithProfile.Card,
+
}, nil
}
followDids := make([]string, 0, len(follows))
···
profiles, err := db.GetProfiles(s.db, db.FilterIn("did", followDids))
if err != nil {
log.Printf("getting profile for %s: %s", followDids, err)
-
return nil
+
return FollowsPageParams{}, err
+
}
+
+
followStatsMap, err := db.GetFollowerFollowingCounts(s.db, followDids)
+
if err != nil {
+
log.Printf("getting follow counts for %s: %s", followDids, err)
+
return FollowsPageParams{}, err
}
var loggedInUserFollowing map[string]struct{}
if loggedInUser != nil {
following, err := db.GetFollowing(s.db, loggedInUser.Did)
if err != nil {
-
return nil
+
return FollowsPageParams{}, err
}
if len(following) > 0 {
loggedInUserFollowing = make(map[string]struct{}, len(following))
···
followCards := make([]pages.FollowCard, 0, len(follows))
for _, did := range followDids {
-
followersCount, followingCount, err := db.GetFollowerFollowingCount(s.db, did)
-
if err != nil {
-
log.Printf("getting follow stats for %s: %s", did, err)
+
followStats, exists := followStatsMap[did]
+
if !exists {
+
followStats = db.FollowStats{}
}
followStatus := db.IsNotFollowing
if loggedInUserFollowing != nil {
···
followCards = append(followCards, pages.FollowCard{
UserDid: did,
FollowStatus: followStatus,
-
FollowersCount: followersCount,
-
FollowingCount: followingCount,
+
FollowersCount: followStats.Followers,
+
FollowingCount: followStats.Following,
Profile: profile,
})
}
-
followStatus := db.IsNotFollowing
-
if loggedInUser != nil {
-
followStatus = db.GetFollowStatus(s.db, loggedInUser.Did, did)
-
}
-
-
followersCount, followingCount, err := db.GetFollowerFollowingCount(s.db, did)
-
if err != nil {
-
log.Printf("getting follow stats followers for %s: %s", did, err)
-
}
-
-
return &FollowsPageParams{
+
return FollowsPageParams{
LoggedInUser: loggedInUser,
Follows: followCards,
-
Card: pages.ProfileCard{
-
UserDid: did,
-
UserHandle: ident.Handle.String(),
-
Profile: profile,
-
FollowStatus: followStatus,
-
FollowersCount: followersCount,
-
FollowingCount: followingCount,
-
},
-
}
+
Card: pageWithProfile.Card,
+
}, nil
}
func (s *State) followersPage(w http.ResponseWriter, r *http.Request) {
-
followPage := s.followPage(w, r, db.GetFollowers, func(f db.Follow) string { return f.UserDid })
+
followPage, err := s.followPage(w, r, db.GetFollowers, func(f db.Follow) string { return f.UserDid })
+
if err != nil {
+
s.pages.Notice(w, "all-followers", "Failed to load followers")
+
return
+
}
s.pages.FollowersPage(w, pages.FollowersPageParams{
LoggedInUser: followPage.LoggedInUser,
···
}
func (s *State) followingPage(w http.ResponseWriter, r *http.Request) {
-
followPage := s.followPage(w, r, db.GetFollowing, func(f db.Follow) string { return f.SubjectDid })
+
followPage, err := s.followPage(w, r, db.GetFollowing, func(f db.Follow) string { return f.SubjectDid })
+
if err != nil {
+
s.pages.Notice(w, "all-following", "Failed to load following")
+
return
+
}
s.pages.FollowingPage(w, pages.FollowingPageParams{
LoggedInUser: followPage.LoggedInUser,
+2 -2
.jjconflict-side-2/appview/pages/pages.go
···
return p.execute("repo/fork", w, params)
}
-
type ProfilePageParams struct {
+
type ProfileHomePageParams struct {
LoggedInUser *oauth.User
Repos []db.Repo
CollaboratingRepos []db.Repo
···
Profile *db.Profile
}
-
func (p *Pages) ProfilePage(w io.Writer, params ProfilePageParams) error {
+
func (p *Pages) ProfileHomePage(w io.Writer, params ProfileHomePageParams) error {
return p.execute("user/profile", w, params)
}
.jjconflict-side-1/appview/pages/templates/timeline.html .jjconflict-side-2/appview/pages/templates/timeline.html
+18 -37
.jjconflict-side-2/appview/state/profile.go
···
log.Printf("getting profile data for %s: %s", did, err)
}
-
followStats, err := db.GetFollowerFollowingCount(s.db, did)
+
followersCount, followingCount, err := db.GetFollowerFollowingCount(s.db, did)
if err != nil {
log.Printf("getting follow stats for %s: %s", did, err)
}
···
UserHandle: ident.Handle.String(),
Profile: profile,
FollowStatus: followStatus,
-
FollowersCount: followStats.Followers,
-
FollowingCount: followStats.Following,
+
FollowersCount: followersCount,
+
FollowingCount: followingCount,
},
}
}
···
Card pages.ProfileCard
}
-
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) {
+
func (s *State) followPage(w http.ResponseWriter, r *http.Request, fetchFollows func(db.Execer, string) ([]db.Follow, error), extractDid func(db.Follow) string) *FollowsPageParams {
pageWithProfile := s.profilePage(w, r)
if pageWithProfile == nil {
-
return FollowsPageParams{}, nil
+
return nil
}
id := pageWithProfile.Id
-
loggedInUser := pageWithProfile.LoggedInUser
follows, err := fetchFollows(s.db, id.DID.String())
if err != nil {
log.Printf("getting followers for %s: %s", id.DID, err)
-
return FollowsPageParams{}, err
}
if len(follows) == 0 {
-
return FollowsPageParams{
-
LoggedInUser: loggedInUser,
-
Follows: []pages.FollowCard{},
-
Card: pageWithProfile.Card,
-
}, nil
+
return nil
}
followDids := make([]string, 0, len(follows))
···
profiles, err := db.GetProfiles(s.db, db.FilterIn("did", followDids))
if err != nil {
log.Printf("getting profile for %s: %s", followDids, err)
-
return FollowsPageParams{}, err
-
}
-
-
followStatsMap, err := db.GetFollowerFollowingCounts(s.db, followDids)
-
if err != nil {
-
log.Printf("getting follow counts for %s: %s", followDids, err)
-
return FollowsPageParams{}, err
+
return nil
}
+
loggedInUser := pageWithProfile.LoggedInUser
var loggedInUserFollowing map[string]struct{}
if loggedInUser != nil {
following, err := db.GetFollowing(s.db, loggedInUser.Did)
if err != nil {
-
return FollowsPageParams{}, err
+
return nil
}
if len(following) > 0 {
loggedInUserFollowing = make(map[string]struct{}, len(following))
···
followCards := make([]pages.FollowCard, 0, len(follows))
for _, did := range followDids {
-
followStats, exists := followStatsMap[did]
-
if !exists {
-
followStats = db.FollowStats{}
+
followersCount, followingCount, err := db.GetFollowerFollowingCount(s.db, did)
+
if err != nil {
+
log.Printf("getting follow stats for %s: %s", did, err)
}
followStatus := db.IsNotFollowing
if loggedInUserFollowing != nil {
···
followCards = append(followCards, pages.FollowCard{
UserDid: did,
FollowStatus: followStatus,
-
FollowersCount: followStats.Followers,
-
FollowingCount: followStats.Following,
+
FollowersCount: followersCount,
+
FollowingCount: followingCount,
Profile: profile,
})
}
-
return FollowsPageParams{
+
return &FollowsPageParams{
LoggedInUser: loggedInUser,
Follows: followCards,
Card: pageWithProfile.Card,
-
}, nil
+
}
}
func (s *State) followersPage(w http.ResponseWriter, r *http.Request) {
-
followPage, err := s.followPage(w, r, db.GetFollowers, func(f db.Follow) string { return f.UserDid })
-
if err != nil {
-
s.pages.Notice(w, "all-followers", "Failed to load followers")
-
return
-
}
+
followPage := s.followPage(w, r, db.GetFollowers, func(f db.Follow) string { return f.UserDid })
s.pages.FollowersPage(w, pages.FollowersPageParams{
LoggedInUser: followPage.LoggedInUser,
···
}
func (s *State) followingPage(w http.ResponseWriter, r *http.Request) {
-
followPage, err := s.followPage(w, r, db.GetFollowing, func(f db.Follow) string { return f.SubjectDid })
-
if err != nil {
-
s.pages.Notice(w, "all-following", "Failed to load following")
-
return
-
}
+
followPage := s.followPage(w, r, db.GetFollowing, func(f db.Follow) string { return f.SubjectDid })
s.pages.FollowingPage(w, pages.FollowingPageParams{
LoggedInUser: followPage.LoggedInUser,