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