forked from tangled.org/core
this repo has no description
1package db 2 3import ( 4 "log" 5 "time" 6 7 "github.com/bluesky-social/indigo/atproto/syntax" 8) 9 10type ReactionKind string 11 12const ( 13 Like ReactionKind = "👍" 14 Unlike ReactionKind = "👎" 15 Laugh ReactionKind = "😆" 16 Celebration ReactionKind = "🎉" 17 Confused ReactionKind = "🫤" 18 Heart ReactionKind = "❤️" 19 Rocket ReactionKind = "🚀" 20 Eyes ReactionKind = "👀" 21) 22 23func (rk ReactionKind) String() string { 24 return string(rk) 25} 26 27var OrderedReactionKinds = []ReactionKind{ 28 Like, 29 Unlike, 30 Laugh, 31 Celebration, 32 Confused, 33 Heart, 34 Rocket, 35 Eyes, 36} 37 38func ParseReactionKind(raw string) (ReactionKind, bool) { 39 k, ok := (map[string]ReactionKind{ 40 "👍": Like, 41 "👎": Unlike, 42 "😆": Laugh, 43 "🎉": Celebration, 44 "🫤": Confused, 45 "❤️": Heart, 46 "🚀": Rocket, 47 "👀": Eyes, 48 })[raw] 49 return k, ok 50} 51 52type Reaction struct { 53 ReactedByDid string 54 ThreadAt syntax.ATURI 55 Created time.Time 56 Rkey string 57 Kind ReactionKind 58} 59 60func AddReaction(e Execer, reactedByDid string, threadAt syntax.ATURI, kind ReactionKind, rkey string) error { 61 query := `insert or ignore into reactions (reacted_by_did, thread_at, kind, rkey) values (?, ?, ?, ?)` 62 _, err := e.Exec(query, reactedByDid, threadAt, kind, rkey) 63 return err 64} 65 66// Get a reaction record 67func GetReaction(e Execer, reactedByDid string, threadAt syntax.ATURI, kind ReactionKind) (*Reaction, error) { 68 query := ` 69 select reacted_by_did, thread_at, created, rkey 70 from reactions 71 where reacted_by_did = ? and thread_at = ? and kind = ?` 72 row := e.QueryRow(query, reactedByDid, threadAt, kind) 73 74 var reaction Reaction 75 var created string 76 err := row.Scan(&reaction.ReactedByDid, &reaction.ThreadAt, &created, &reaction.Rkey) 77 if err != nil { 78 return nil, err 79 } 80 81 createdAtTime, err := time.Parse(time.RFC3339, created) 82 if err != nil { 83 log.Println("unable to determine followed at time") 84 reaction.Created = time.Now() 85 } else { 86 reaction.Created = createdAtTime 87 } 88 89 return &reaction, nil 90} 91 92// Remove a reaction 93func DeleteReaction(e Execer, reactedByDid string, threadAt syntax.ATURI, kind ReactionKind) error { 94 _, err := e.Exec(`delete from reactions where reacted_by_did = ? and thread_at = ? and kind = ?`, reactedByDid, threadAt, kind) 95 return err 96} 97 98// Remove a reaction 99func DeleteReactionByRkey(e Execer, reactedByDid string, rkey string) error { 100 _, err := e.Exec(`delete from reactions where reacted_by_did = ? and rkey = ?`, reactedByDid, rkey) 101 return err 102} 103 104func GetReactionCount(e Execer, threadAt syntax.ATURI, kind ReactionKind) (int, error) { 105 count := 0 106 err := e.QueryRow( 107 `select count(reacted_by_did) from reactions where thread_at = ? and kind = ?`, threadAt, kind).Scan(&count) 108 if err != nil { 109 return 0, err 110 } 111 return count, nil 112} 113 114func GetReactionCountMap(e Execer, threadAt syntax.ATURI) (map[ReactionKind]int, error) { 115 countMap := map[ReactionKind]int{} 116 for _, kind := range OrderedReactionKinds { 117 count, err := GetReactionCount(e, threadAt, kind) 118 if err != nil { 119 return map[ReactionKind]int{}, nil 120 } 121 countMap[kind] = count 122 } 123 return countMap, nil 124} 125 126func GetReactionStatus(e Execer, userDid string, threadAt syntax.ATURI, kind ReactionKind) bool { 127 if _, err := GetReaction(e, userDid, threadAt, kind); err != nil { 128 return false 129 } else { 130 return true 131 } 132} 133 134func GetReactionStatusMap(e Execer, userDid string, threadAt syntax.ATURI) map[ReactionKind]bool { 135 statusMap := map[ReactionKind]bool{} 136 for _, kind := range OrderedReactionKinds { 137 count := GetReactionStatus(e, userDid, threadAt, kind) 138 statusMap[kind] = count 139 } 140 return statusMap 141}