Monorepo for Tangled
1package state
2
3import (
4 "log"
5 "net/http"
6 "time"
7
8 comatproto "github.com/bluesky-social/indigo/api/atproto"
9 "github.com/bluesky-social/indigo/atproto/syntax"
10 lexutil "github.com/bluesky-social/indigo/lex/util"
11 "tangled.org/core/api/tangled"
12 "tangled.org/core/appview/db"
13 "tangled.org/core/appview/models"
14 "tangled.org/core/appview/pages"
15 "tangled.org/core/orm"
16 "tangled.org/core/tid"
17)
18
19func (s *State) Star(w http.ResponseWriter, r *http.Request) {
20 currentUser := s.oauth.GetMultiAccountUser(r)
21
22 subject := r.URL.Query().Get("subject")
23 if subject == "" {
24 log.Println("invalid form")
25 return
26 }
27
28 subjectUri, err := syntax.ParseATURI(subject)
29 if err != nil {
30 log.Println("invalid form")
31 return
32 }
33
34 client, err := s.oauth.AuthorizedClient(r)
35 if err != nil {
36 log.Println("failed to authorize client", err)
37 return
38 }
39
40 switch r.Method {
41 case http.MethodPost:
42 createdAt := time.Now().Format(time.RFC3339)
43 rkey := tid.TID()
44
45 starRecord := &tangled.FeedStar{
46 CreatedAt: createdAt,
47 }
48 repo, err := db.GetRepo(s.db, orm.FilterEq("at_uri", subjectUri.String()))
49 repoHasDid := err == nil && repo.RepoDid != ""
50 if repoHasDid {
51 starRecord.SubjectDid = &repo.RepoDid
52 } else {
53 s := subjectUri.String()
54 starRecord.Subject = &s
55 }
56
57 resp, err := comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
58 Collection: tangled.FeedStarNSID,
59 Repo: currentUser.Active.Did,
60 Rkey: rkey,
61 Record: &lexutil.LexiconTypeDecoder{Val: starRecord},
62 })
63 if err != nil {
64 log.Println("failed to create atproto record", err)
65 return
66 }
67 log.Println("created atproto record: ", resp.Uri)
68
69 star := &models.Star{
70 Did: currentUser.Active.Did,
71 RepoAt: subjectUri,
72 Rkey: rkey,
73 }
74 if repoHasDid {
75 star.SubjectDid = repo.RepoDid
76 }
77
78 err = db.AddStar(s.db, star)
79 if err != nil {
80 log.Println("failed to star", err)
81 return
82 }
83
84 starCount, err := db.GetStarCount(s.db, subjectUri)
85 if err != nil {
86 log.Println("failed to get star count for ", subjectUri)
87 }
88
89 s.notifier.NewStar(r.Context(), star)
90
91 s.pages.StarBtnFragment(w, pages.StarBtnFragmentParams{
92 IsStarred: true,
93 SubjectAt: subjectUri,
94 StarCount: starCount,
95 })
96
97 return
98 case http.MethodDelete:
99 // find the record in the db
100 star, err := db.GetStar(s.db, currentUser.Active.Did, subjectUri)
101 if err != nil {
102 log.Println("failed to get star relationship")
103 return
104 }
105
106 _, err = comatproto.RepoDeleteRecord(r.Context(), client, &comatproto.RepoDeleteRecord_Input{
107 Collection: tangled.FeedStarNSID,
108 Repo: currentUser.Active.Did,
109 Rkey: star.Rkey,
110 })
111
112 if err != nil {
113 log.Println("failed to unstar")
114 return
115 }
116
117 err = db.DeleteStarByRkey(s.db, currentUser.Active.Did, star.Rkey)
118 if err != nil {
119 log.Println("failed to delete star from DB")
120 // this is not an issue, the firehose event might have already done this
121 }
122
123 starCount, err := db.GetStarCount(s.db, subjectUri)
124 if err != nil {
125 log.Println("failed to get star count for ", subjectUri)
126 return
127 }
128
129 s.notifier.DeleteStar(r.Context(), star)
130
131 s.pages.StarBtnFragment(w, pages.StarBtnFragmentParams{
132 IsStarred: false,
133 SubjectAt: subjectUri,
134 StarCount: starCount,
135 })
136
137 return
138 }
139
140}