Monorepo for Tangled
0
fork

Configure Feed

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

at master 128 lines 3.8 kB view raw
1package db 2 3import ( 4 "log" 5 "time" 6 7 "github.com/bluesky-social/indigo/atproto/syntax" 8 "tangled.org/core/appview/models" 9) 10 11func AddReaction(e Execer, reactedByDid string, threadAt syntax.ATURI, kind models.ReactionKind, rkey string) error { 12 query := `insert or ignore into reactions (reacted_by_did, thread_at, kind, rkey) values (?, ?, ?, ?)` 13 _, err := e.Exec(query, reactedByDid, threadAt, kind, rkey) 14 return err 15} 16 17// Get a reaction record 18func GetReaction(e Execer, reactedByDid string, threadAt syntax.ATURI, kind models.ReactionKind) (*models.Reaction, error) { 19 query := ` 20 select reacted_by_did, thread_at, created, rkey 21 from reactions 22 where reacted_by_did = ? and thread_at = ? and kind = ?` 23 row := e.QueryRow(query, reactedByDid, threadAt, kind) 24 25 var reaction models.Reaction 26 var created string 27 err := row.Scan(&reaction.ReactedByDid, &reaction.ThreadAt, &created, &reaction.Rkey) 28 if err != nil { 29 return nil, err 30 } 31 32 createdAtTime, err := time.Parse(time.RFC3339, created) 33 if err != nil { 34 log.Println("unable to determine followed at time") 35 reaction.Created = time.Now() 36 } else { 37 reaction.Created = createdAtTime 38 } 39 40 return &reaction, nil 41} 42 43// Remove a reaction 44func DeleteReaction(e Execer, reactedByDid string, threadAt syntax.ATURI, kind models.ReactionKind) error { 45 _, err := e.Exec(`delete from reactions where reacted_by_did = ? and thread_at = ? and kind = ?`, reactedByDid, threadAt, kind) 46 return err 47} 48 49// Remove a reaction 50func DeleteReactionByRkey(e Execer, reactedByDid string, rkey string) error { 51 _, err := e.Exec(`delete from reactions where reacted_by_did = ? and rkey = ?`, reactedByDid, rkey) 52 return err 53} 54 55func GetReactionCount(e Execer, threadAt syntax.ATURI) (int, error) { 56 count := 0 57 err := e.QueryRow(`select count(reacted_by_did) from reactions where thread_at = ?`, threadAt).Scan(&count) 58 if err != nil { 59 return 0, err 60 } 61 return count, nil 62} 63 64func GetReactionCountByKind(e Execer, threadAt syntax.ATURI, kind models.ReactionKind) (int, error) { 65 count := 0 66 err := e.QueryRow( 67 `select count(reacted_by_did) from reactions where thread_at = ? and kind = ?`, threadAt, kind).Scan(&count) 68 if err != nil { 69 return 0, err 70 } 71 return count, nil 72} 73 74func GetReactionMap(e Execer, userLimit int, threadAt syntax.ATURI) (map[models.ReactionKind]models.ReactionDisplayData, error) { 75 query := ` 76 select kind, reacted_by_did, 77 row_number() over (partition by kind order by created asc) as rn, 78 count(*) over (partition by kind) as total 79 from reactions 80 where thread_at = ? 81 order by kind, created asc` 82 83 rows, err := e.Query(query, threadAt) 84 if err != nil { 85 return nil, err 86 } 87 defer rows.Close() 88 89 reactionMap := map[models.ReactionKind]models.ReactionDisplayData{} 90 for _, kind := range models.OrderedReactionKinds { 91 reactionMap[kind] = models.ReactionDisplayData{Count: 0, Users: []string{}} 92 } 93 94 for rows.Next() { 95 var kind models.ReactionKind 96 var did string 97 var rn, total int 98 if err := rows.Scan(&kind, &did, &rn, &total); err != nil { 99 return nil, err 100 } 101 102 data := reactionMap[kind] 103 data.Count = total 104 if userLimit > 0 && rn <= userLimit { 105 data.Users = append(data.Users, did) 106 } 107 reactionMap[kind] = data 108 } 109 110 return reactionMap, rows.Err() 111} 112 113func GetReactionStatus(e Execer, userDid string, threadAt syntax.ATURI, kind models.ReactionKind) bool { 114 if _, err := GetReaction(e, userDid, threadAt, kind); err != nil { 115 return false 116 } else { 117 return true 118 } 119} 120 121func GetReactionStatusMap(e Execer, userDid string, threadAt syntax.ATURI) map[models.ReactionKind]bool { 122 statusMap := map[models.ReactionKind]bool{} 123 for _, kind := range models.OrderedReactionKinds { 124 count := GetReactionStatus(e, userDid, threadAt, kind) 125 statusMap[kind] = count 126 } 127 return statusMap 128}