1package state
2
3import (
4 "fmt"
5 "log"
6 "net/http"
7
8 "github.com/go-chi/chi/v5"
9 "tangled.sh/tangled.sh/core/appview/db"
10 "tangled.sh/tangled.sh/core/appview/pages"
11)
12
13func (s *State) ProfilePage(w http.ResponseWriter, r *http.Request) {
14 didOrHandle := chi.URLParam(r, "user")
15 if didOrHandle == "" {
16 http.Error(w, "Bad request", http.StatusBadRequest)
17 return
18 }
19
20 ident, err := s.resolver.ResolveIdent(r.Context(), didOrHandle)
21 if err != nil {
22 log.Printf("resolving identity: %s", err)
23 w.WriteHeader(http.StatusNotFound)
24 return
25 }
26
27 repos, err := db.GetAllReposByDid(s.db, ident.DID.String())
28 if err != nil {
29 log.Printf("getting repos for %s: %s", ident.DID.String(), err)
30 }
31
32 collaboratingRepos, err := db.CollaboratingIn(s.db, ident.DID.String())
33 if err != nil {
34 log.Printf("getting collaborating repos for %s: %s", ident.DID.String(), err)
35 }
36
37 timeline, err := db.MakeProfileTimeline(s.db, ident.DID.String())
38 if err != nil {
39 log.Printf("failed to create profile timeline for %s: %s", ident.DID.String(), err)
40 }
41
42 var didsToResolve []string
43 for _, r := range collaboratingRepos {
44 didsToResolve = append(didsToResolve, r.Did)
45 }
46 for _, evt := range timeline {
47 didsToResolve = append(didsToResolve, evt.Repo.Did)
48 }
49
50 resolvedIds := s.resolver.ResolveIdents(r.Context(), didsToResolve)
51 didHandleMap := make(map[string]string)
52 for _, identity := range resolvedIds {
53 if !identity.Handle.IsInvalidHandle() {
54 didHandleMap[identity.DID.String()] = fmt.Sprintf("@%s", identity.Handle.String())
55 } else {
56 didHandleMap[identity.DID.String()] = identity.DID.String()
57 }
58 }
59
60 followers, following, err := db.GetFollowerFollowing(s.db, ident.DID.String())
61 if err != nil {
62 log.Printf("getting follow stats repos for %s: %s", ident.DID.String(), err)
63 }
64
65 loggedInUser := s.auth.GetUser(r)
66 followStatus := db.IsNotFollowing
67 if loggedInUser != nil {
68 followStatus = db.GetFollowStatus(s.db, loggedInUser.Did, ident.DID.String())
69 }
70
71 profileAvatarUri, err := GetAvatarUri(ident.Handle.String())
72 if err != nil {
73 log.Println("failed to fetch bsky avatar", err)
74 }
75
76 s.pages.ProfilePage(w, pages.ProfilePageParams{
77 LoggedInUser: loggedInUser,
78 UserDid: ident.DID.String(),
79 UserHandle: ident.Handle.String(),
80 Repos: repos,
81 CollaboratingRepos: collaboratingRepos,
82 ProfileStats: pages.ProfileStats{
83 Followers: followers,
84 Following: following,
85 },
86 FollowStatus: db.FollowStatus(followStatus),
87 DidHandleMap: didHandleMap,
88 AvatarUri: profileAvatarUri,
89 ProfileTimeline: timeline,
90 })
91}