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/tid"
16)
17
18func (s *State) Star(w http.ResponseWriter, r *http.Request) {
19 currentUser := s.oauth.GetUser(r)
20
21 subject := r.URL.Query().Get("subject")
22 if subject == "" {
23 log.Println("invalid form")
24 return
25 }
26
27 subjectUri, err := syntax.ParseATURI(subject)
28 if err != nil {
29 log.Println("invalid form")
30 return
31 }
32
33 client, err := s.oauth.AuthorizedClient(r)
34 if err != nil {
35 log.Println("failed to authorize client", err)
36 return
37 }
38
39 switch r.Method {
40 case http.MethodPost:
41 createdAt := time.Now().Format(time.RFC3339)
42 rkey := tid.TID()
43 resp, err := client.RepoPutRecord(r.Context(), &comatproto.RepoPutRecord_Input{
44 Collection: tangled.FeedStarNSID,
45 Repo: currentUser.Did,
46 Rkey: rkey,
47 Record: &lexutil.LexiconTypeDecoder{
48 Val: &tangled.FeedStar{
49 Subject: subjectUri.String(),
50 CreatedAt: createdAt,
51 }},
52 })
53 if err != nil {
54 log.Println("failed to create atproto record", err)
55 return
56 }
57 log.Println("created atproto record: ", resp.Uri)
58
59 star := &models.Star{
60 StarredByDid: currentUser.Did,
61 RepoAt: subjectUri,
62 Rkey: rkey,
63 }
64
65 err = db.AddStar(s.db, star)
66 if err != nil {
67 log.Println("failed to star", err)
68 return
69 }
70
71 starCount, err := db.GetStarCount(s.db, subjectUri)
72 if err != nil {
73 log.Println("failed to get star count for ", subjectUri)
74 }
75
76 s.notifier.NewStar(r.Context(), star)
77
78 s.pages.RepoStarFragment(w, pages.RepoStarFragmentParams{
79 IsStarred: true,
80 RepoAt: subjectUri,
81 Stats: models.RepoStats{
82 StarCount: starCount,
83 },
84 })
85
86 return
87 case http.MethodDelete:
88 // find the record in the db
89 star, err := db.GetStar(s.db, currentUser.Did, subjectUri)
90 if err != nil {
91 log.Println("failed to get star relationship")
92 return
93 }
94
95 _, err = client.RepoDeleteRecord(r.Context(), &comatproto.RepoDeleteRecord_Input{
96 Collection: tangled.FeedStarNSID,
97 Repo: currentUser.Did,
98 Rkey: star.Rkey,
99 })
100
101 if err != nil {
102 log.Println("failed to unstar")
103 return
104 }
105
106 err = db.DeleteStarByRkey(s.db, currentUser.Did, star.Rkey)
107 if err != nil {
108 log.Println("failed to delete star from DB")
109 // this is not an issue, the firehose event might have already done this
110 }
111
112 starCount, err := db.GetStarCount(s.db, subjectUri)
113 if err != nil {
114 log.Println("failed to get star count for ", subjectUri)
115 return
116 }
117
118 s.notifier.DeleteStar(r.Context(), star)
119
120 s.pages.RepoStarFragment(w, pages.RepoStarFragmentParams{
121 IsStarred: false,
122 RepoAt: subjectUri,
123 Stats: models.RepoStats{
124 StarCount: starCount,
125 },
126 })
127
128 return
129 }
130
131}