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