Live video on the AT Protocol
1package model
2
3import (
4 "context"
5 "fmt"
6 "time"
7
8 "github.com/bluesky-social/indigo/api/bsky"
9 "stream.place/streamplace/pkg/aqtime"
10)
11
12type Follow struct {
13 UserDID string `gorm:"primaryKey;index:user_idx;column:user_did"`
14 SubjectDID string `gorm:"primaryKey;index:subject_idx;column:subject_did"`
15 RKey string `gorm:"index;column:rkey"`
16 CreatedAt time.Time
17}
18
19func (m *DBModel) CreateFollow(ctx context.Context, userDID, rkey string, follow *bsky.GraphFollow) error {
20 at, err := aqtime.FromString(follow.CreatedAt)
21 if err != nil {
22 return fmt.Errorf("failed to parse follow createdAt: %w", err)
23 }
24 return m.DB.Save(&Follow{
25 UserDID: userDID,
26 SubjectDID: follow.Subject,
27 RKey: rkey,
28 CreatedAt: at.Time(),
29 }).Error
30}
31
32func (m *DBModel) DeleteFollow(ctx context.Context, userDID, rkey string) error {
33 res := m.DB.Where("user_did = ? AND rkey = ?", userDID, rkey).Delete(&Follow{})
34 if res.Error != nil {
35 return fmt.Errorf("failed to delete follow: %w", res.Error)
36 }
37 if res.RowsAffected == 0 {
38 return fmt.Errorf("no follow found for userDID %s and rkey %s", userDID, rkey)
39 }
40 return nil
41}
42
43func (m *DBModel) GetUserFollowing(ctx context.Context, userDID string) ([]Follow, error) {
44 var follows []Follow
45 return follows, m.DB.Where("user_did = ?", userDID).Find(&follows).Error
46}
47
48func (m *DBModel) GetUserFollowers(ctx context.Context, userDID string) ([]Follow, error) {
49 var follows []Follow
50 return follows, m.DB.Where("subject_did = ?", userDID).Find(&follows).Error
51}
52
53func (m *DBModel) GetUserFollowingUser(ctx context.Context, userDID, subjectDID string) (*Follow, error) {
54 var follow Follow
55 result := m.DB.Where("user_did = ? AND subject_did = ?", userDID, subjectDID).First(&follow)
56 if result.RowsAffected == 0 {
57 return nil, nil
58 }
59 return &follow, result.Error
60}