Monorepo for Tangled
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

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