diff --git a/app/src/main/kotlin/com/subtracks/playback/Scrobbler.kt b/app/src/main/kotlin/com/subtracks/playback/Scrobbler.kt index f8dbd97d..f033d12f 100644 --- a/app/src/main/kotlin/com/subtracks/playback/Scrobbler.kt +++ b/app/src/main/kotlin/com/subtracks/playback/Scrobbler.kt @@ -59,6 +59,7 @@ class ScrobblePolicy( item?.id != songId || (item != null && item.id == lastItemId && positionMs < previousPosition && positionMs <= RESTART_POSITION_MS) if (restarted) { + val sameSong = item != null && item.id == songId songId = item?.id lastItemId = null playedMs = 0 @@ -68,7 +69,7 @@ class ScrobblePolicy( if (item == null || !isPlaying) return null nowPlayingSent = true startedAt = now() - return Scrobble.NowPlaying(item.id) + return if (sameSong) null else Scrobble.NowPlaying(item.id) } lastPositionMs = positionMs lastItemId = item?.id diff --git a/app/src/test/kotlin/com/subtracks/playback/ScrobblePolicyTest.kt b/app/src/test/kotlin/com/subtracks/playback/ScrobblePolicyTest.kt index d1a22faf..d451514a 100644 --- a/app/src/test/kotlin/com/subtracks/playback/ScrobblePolicyTest.kt +++ b/app/src/test/kotlin/com/subtracks/playback/ScrobblePolicyTest.kt @@ -130,15 +130,46 @@ class ScrobblePolicyTest { } @Test - fun restartingTheSameTrackScrobblesAgain() { + fun restartingTheSameTrackResubmitsWithoutReannouncing() { val item = track(durationMs = 200_000) play(item, toPositionMs = 100_000) clock = 120_000L val repeat = play(item, toPositionMs = 100_000) - assertEquals(Scrobble.NowPlaying("s1"), repeat.first()) + assertEquals(emptyList(), repeat.filterIsInstance()) assertEquals(Scrobble.Submission("s1", 120_000L), repeat.last()) } + @Test + fun doesNotReannounceTheTrackItJustLeftWhenItsPositionResets() { + val events = mutableListOf() + events += play(track(id = "s1"), toPositionMs = 100_000) + events += + listOfNotNull( + policy.advance(track(id = "s1"), 200_000, isPlaying = true, positionMs = 0), + policy.advance(track(id = "s2"), 200_000, isPlaying = true, positionMs = 0), + ) + assertEquals( + listOf(Scrobble.NowPlaying("s1"), Scrobble.Submission("s1", 1_000L), Scrobble.NowPlaying("s2")), + events, + ) + } + + @Test + fun doesNotReannounceWhenTheNewTracksPositionJittersBackToZero() { + val events = mutableListOf() + events += play(track(id = "s1"), toPositionMs = 100_000) + events += + listOfNotNull( + policy.advance(track(id = "s2"), 200_000, isPlaying = true, positionMs = 0), + policy.advance(track(id = "s2"), 200_000, isPlaying = true, positionMs = 500), + policy.advance(track(id = "s2"), 200_000, isPlaying = true, positionMs = 0), + ) + assertEquals( + listOf(Scrobble.NowPlaying("s1"), Scrobble.Submission("s1", 1_000L), Scrobble.NowPlaying("s2")), + events, + ) + } + @Test fun aTransitionDoesNotReannounceTheNewTrackOnAStaleLowPosition() { val first = track(id = "s1")