1package state
2
3import (
4 "log"
5 "net/http"
6 "time"
7
8 comatproto "github.com/bluesky-social/indigo/api/atproto"
9 lexutil "github.com/bluesky-social/indigo/lex/util"
10 tangled "tangled.sh/tangled.sh/core/api/tangled"
11 "tangled.sh/tangled.sh/core/appview"
12 "tangled.sh/tangled.sh/core/appview/db"
13 "tangled.sh/tangled.sh/core/appview/pages"
14)
15
16func (s *State) Follow(w http.ResponseWriter, r *http.Request) {
17 currentUser := s.auth.GetUser(r)
18
19 subject := r.URL.Query().Get("subject")
20 if subject == "" {
21 log.Println("invalid form")
22 return
23 }
24
25 subjectIdent, err := s.resolver.ResolveIdent(r.Context(), subject)
26 if err != nil {
27 log.Println("failed to follow, invalid did")
28 }
29
30 if currentUser.Did == subjectIdent.DID.String() {
31 log.Println("cant follow or unfollow yourself")
32 return
33 }
34
35 client, _ := s.auth.AuthorizedClient(r)
36
37 switch r.Method {
38 case http.MethodPost:
39 createdAt := time.Now().Format(time.RFC3339)
40 rkey := appview.TID()
41 resp, err := comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
42 Collection: tangled.GraphFollowNSID,
43 Repo: currentUser.Did,
44 Rkey: rkey,
45 Record: &lexutil.LexiconTypeDecoder{
46 Val: &tangled.GraphFollow{
47 Subject: subjectIdent.DID.String(),
48 CreatedAt: createdAt,
49 }},
50 })
51 if err != nil {
52 log.Println("failed to create atproto record", err)
53 return
54 }
55
56 err = db.AddFollow(s.db, currentUser.Did, subjectIdent.DID.String(), rkey)
57 if err != nil {
58 log.Println("failed to follow", err)
59 return
60 }
61
62 log.Println("created atproto record: ", resp.Uri)
63
64 s.pages.FollowFragment(w, pages.FollowFragmentParams{
65 UserDid: subjectIdent.DID.String(),
66 FollowStatus: db.IsFollowing,
67 })
68
69 return
70 case http.MethodDelete:
71 // find the record in the db
72 follow, err := db.GetFollow(s.db, currentUser.Did, subjectIdent.DID.String())
73 if err != nil {
74 log.Println("failed to get follow relationship")
75 return
76 }
77
78 _, err = comatproto.RepoDeleteRecord(r.Context(), client, &comatproto.RepoDeleteRecord_Input{
79 Collection: tangled.GraphFollowNSID,
80 Repo: currentUser.Did,
81 Rkey: follow.Rkey,
82 })
83
84 if err != nil {
85 log.Println("failed to unfollow")
86 return
87 }
88
89 err = db.DeleteFollow(s.db, currentUser.Did, subjectIdent.DID.String())
90 if err != nil {
91 log.Println("failed to delete follow from DB")
92 // this is not an issue, the firehose event might have already done this
93 }
94
95 s.pages.FollowFragment(w, pages.FollowFragmentParams{
96 UserDid: subjectIdent.DID.String(),
97 FollowStatus: db.IsNotFollowing,
98 })
99
100 return
101 }
102
103}