···439439 s.logger.Printf("failed to get last tracks for user %d: %v", user.ID, err)
440440 }
441441442442- // Check if this is a new track (by PlayParams.id)
442442+ // For uploaded tracks, the API returns an empty URL, but we store a generated hash.
443443+ // Compute the hash here so the comparison uses the same value as what's in the DB.
444444+ currentURL := currentAppleTrack.Attributes.URL
445445+ if currentURL == "" {
446446+ currentURL = generateUploadHash(currentAppleTrack)
447447+ }
448448+449449+ // Check if this is a new track (by URL / upload hash)
443450 if len(lastTracks) > 0 {
444451 lastTrack := lastTracks[0]
445445- // If the URL matches, it's the same track
446446- if lastTrack.URL == currentAppleTrack.Attributes.URL {
452452+ if lastTrack.URL == currentURL {
447453 s.logger.Printf("track unchanged for user %d: %s by %s", user.ID, currentAppleTrack.Attributes.Name, currentAppleTrack.Attributes.ArtistName)
448454 return nil
449455 }