112 lines
2.7 kB
1
package state
2
3
import (
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
14
func (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
}
113