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