···66 "log"
77 "os"
88 "strconv"
99+ "sync"
910 "time"
10111112 "github.com/bluesky-social/indigo/atproto/client"
···2425 db *db.DB
2526 atprotoService *atprotoauth.ATprotoAuthService
2627 logger *log.Logger
2828+ mu sync.RWMutex
2929+ clearedStatus map[int64]bool // tracks if a user's status has been cleared on their repo
2730}
28312932// NewPlayingNowService creates a new playing now service
···3437 db: database,
3538 atprotoService: atprotoService,
3639 logger: logger,
4040+ clearedStatus: make(map[int64]bool),
3741 }
3842}
3943···7579 Item: playView,
7680 }
77817878- var swapRecord *string
8282+ var swapRecord *comatproto.RepoGetRecord_Output
7983 swapRecord, err = p.getStatusSwapRecord(ctx, atProtoClient)
8084 if err != nil {
8185 return err
8286 }
83878888+ var swapCid *string
8989+ if swapRecord != nil {
9090+ swapCid = swapRecord.Cid
9191+ }
9292+9393+ p.logger.Printf("Publishing playing now status for user %d (DID: %s): %s - %s", userID, did, track.Artist[0].Name, track.Name)
9494+8495 // Create the record input
8596 input := comatproto.RepoPutRecord_Input{
8697 Collection: "fm.teal.alpha.actor.status",
8798 Repo: atProtoClient.AccountDID.String(),
8899 Rkey: "self", // Use "self" as the record key for current status
89100 Record: &lexutil.LexiconTypeDecoder{Val: status},
9090- SwapRecord: swapRecord,
101101+ SwapRecord: swapCid,
91102 }
9210393104 // Submit to PDS
···96107 return fmt.Errorf("failed to create playing now status for DID %s: %w", did, err)
97108 }
981099999- p.logger.Printf("Successfully published playing now status for user %d (DID: %s): %s - %s",
100100- userID, did, track.Artist[0].Name, track.Name)
110110+ // Resets clear to false since there is a song playing. The publish playing state is kept in the services from
111111+ // if a song has changed/stamped
112112+ p.mu.Lock()
113113+ p.clearedStatus[userID] = false
114114+ p.mu.Unlock()
101115102116 return nil
103117}
104118105119// ClearPlayingNow removes the current playing status by setting an expired status
106120func (p *PlayingNowService) ClearPlayingNow(ctx context.Context, userID int64) error {
121121+ // Check if status is already cleared to avoid clearing on the users repo over and over
122122+ p.mu.RLock()
123123+ alreadyCleared := p.clearedStatus[userID]
124124+ p.mu.RUnlock()
125125+126126+ if alreadyCleared {
127127+ return nil
128128+ }
129129+107130 // Get user information
108131 user, err := p.db.GetUserByID(userID)
109132 if err != nil {
···140163 Item: emptyPlayView,
141164 }
142165143143- var swapRecord *string
166166+ var swapRecord *comatproto.RepoGetRecord_Output
144167 swapRecord, err = p.getStatusSwapRecord(ctx, atProtoClient)
168168+145169 if err != nil {
146170 return err
147171 }
148172173173+ var swapCid *string
174174+ if swapRecord != nil {
175175+ swapCid = swapRecord.Cid
176176+ }
177177+149178 // Update the record
150179 input := comatproto.RepoPutRecord_Input{
151180 Collection: "fm.teal.alpha.actor.status",
152181 Repo: atProtoClient.AccountDID.String(),
153182 Rkey: "self",
154183 Record: &lexutil.LexiconTypeDecoder{Val: status},
155155- SwapRecord: swapRecord,
184184+ SwapRecord: swapCid,
156185 }
157186158187 if _, err := comatproto.RepoPutRecord(ctx, atProtoClient, &input); err != nil {
···161190 }
162191163192 p.logger.Printf("Successfully cleared playing now status for user %d (DID: %s)", userID, did)
193193+194194+ // Mark status as cleared so we don't clear again until user starts playing a song again
195195+ p.mu.Lock()
196196+ p.clearedStatus[userID] = true
197197+ p.mu.Unlock()
198198+164199 return nil
165200}
166201···216251 // Get submission client agent
217252 submissionAgent := viper.GetString("app.submission_agent")
218253 if submissionAgent == "" {
219219- submissionAgent = "piper/v0.0.2"
254254+ submissionAgent = models.SubmissionAgent
220255 }
221256222257 playView := &teal.AlphaFeedDefs_PlayView{
···238273239274// getStatusSwapRecord retrieves the current swap record (CID) for the actor status record.
240275// Returns (nil, nil) if the record does not exist yet.
241241-func (p *PlayingNowService) getStatusSwapRecord(ctx context.Context, atApiClient *client.APIClient) (*string, error) {
276276+func (p *PlayingNowService) getStatusSwapRecord(ctx context.Context, atApiClient *client.APIClient) (*comatproto.RepoGetRecord_Output, error) {
242277 result, err := comatproto.RepoGetRecord(ctx, atApiClient, "", "fm.teal.alpha.actor.status", atApiClient.AccountDID.String(), "self")
243278244279 if err != nil {
···253288 return nil, fmt.Errorf("error getting the record: %w", err)
254289255290 }
256256- return result.Cid, nil
291291+292292+ return result, nil
257293}