forked from
tangled.org/core
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 subjectStr := subjectUri.String()
46 starRecord := &tangled.FeedStar{
47 CreatedAt: createdAt,
48 Subject: &subjectStr,
49 }
50 repo, err := db.GetRepo(s.db, orm.FilterEq("at_uri", subjectUri.String()))
51 if err == nil && repo.RepoDid != "" {
52 starRecord.SubjectDid = &repo.RepoDid
53 }
54
55 resp, err := comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
56 Collection: tangled.FeedStarNSID,
57 Repo: currentUser.Active.Did,
58 Rkey: rkey,
59 Record: &lexutil.LexiconTypeDecoder{Val: starRecord},
60 })
61 if err != nil {
62 log.Println("failed to create atproto record", err)
63 return
64 }
65 log.Println("created atproto record: ", resp.Uri)
66
67 star := &models.Star{
68 Did: currentUser.Active.Did,
69 RepoAt: subjectUri,
70 Rkey: rkey,
71 }
72
73 err = db.AddStar(s.db, star)
74 if err != nil {
75 log.Println("failed to star", err)
76 return
77 }
78
79 starCount, err := db.GetStarCount(s.db, subjectUri)
80 if err != nil {
81 log.Println("failed to get star count for ", subjectUri)
82 }
83
84 s.notifier.NewStar(r.Context(), star)
85
86 s.pages.StarBtnFragment(w, pages.StarBtnFragmentParams{
87 IsStarred: true,
88 SubjectAt: subjectUri,
89 StarCount: starCount,
90 })
91
92 return
93 case http.MethodDelete:
94 // find the record in the db
95 star, err := db.GetStar(s.db, currentUser.Active.Did, subjectUri)
96 if err != nil {
97 log.Println("failed to get star relationship")
98 return
99 }
100
101 _, err = comatproto.RepoDeleteRecord(r.Context(), client, &comatproto.RepoDeleteRecord_Input{
102 Collection: tangled.FeedStarNSID,
103 Repo: currentUser.Active.Did,
104 Rkey: star.Rkey,
105 })
106
107 if err != nil {
108 log.Println("failed to unstar")
109 return
110 }
111
112 err = db.DeleteStarByRkey(s.db, currentUser.Active.Did, star.Rkey)
113 if err != nil {
114 log.Println("failed to delete star from DB")
115 // this is not an issue, the firehose event might have already done this
116 }
117
118 starCount, err := db.GetStarCount(s.db, subjectUri)
119 if err != nil {
120 log.Println("failed to get star count for ", subjectUri)
121 return
122 }
123
124 s.notifier.DeleteStar(r.Context(), star)
125
126 s.pages.StarBtnFragment(w, pages.StarBtnFragmentParams{
127 IsStarred: false,
128 SubjectAt: subjectUri,
129 StarCount: starCount,
130 })
131
132 return
133 }
134
135}