diff --git a/app/src/main/kotlin/com/subtracks/playback/Scrobbler.kt b/app/src/main/kotlin/com/subtracks/playback/Scrobbler.kt index f033d12f..c31ecb74 100644 --- a/app/src/main/kotlin/com/subtracks/playback/Scrobbler.kt +++ b/app/src/main/kotlin/com/subtracks/playback/Scrobbler.kt @@ -59,7 +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 + val alreadyAnnounced = nowPlayingSent && item?.id == songId songId = item?.id lastItemId = null playedMs = 0 @@ -69,7 +69,7 @@ class ScrobblePolicy( if (item == null || !isPlaying) return null nowPlayingSent = true startedAt = now() - return if (sameSong) null else Scrobble.NowPlaying(item.id) + return if (alreadyAnnounced) 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 d451514a..86c8b136 100644 --- a/app/src/test/kotlin/com/subtracks/playback/ScrobblePolicyTest.kt +++ b/app/src/test/kotlin/com/subtracks/playback/ScrobblePolicyTest.kt @@ -170,6 +170,14 @@ class ScrobblePolicyTest { ) } + @Test + fun announcesWhenATrackLoadedWhilePausedStartsFromTheBeginning() { + val item = track(id = "s1") + assertNull(policy.advance(item, 200_000, isPlaying = false, positionMs = 0)) + assertNull(policy.advance(item, 200_000, isPlaying = false, positionMs = 2_500)) + assertEquals(Scrobble.NowPlaying("s1"), policy.advance(item, 200_000, isPlaying = true, positionMs = 0)) + } + @Test fun aTransitionDoesNotReannounceTheNewTrackOnAStaleLowPosition() { val first = track(id = "s1") diff --git a/app/src/test/kotlin/com/subtracks/playback/ScrobblerTest.kt b/app/src/test/kotlin/com/subtracks/playback/ScrobblerTest.kt index 4043d31e..d66b2575 100644 --- a/app/src/test/kotlin/com/subtracks/playback/ScrobblerTest.kt +++ b/app/src/test/kotlin/com/subtracks/playback/ScrobblerTest.kt @@ -190,4 +190,34 @@ class ScrobblerTest { enabled.value = true assertEquals(listOf(Call.NowPlaying("s1")), sink.calls) } + + @Test + fun aTransitionSendsNowPlayingOnceForTheNewTrack() = + runTest { + val sink = RecordingSink() + val scrobbler = Scrobbler(sink = sink, enabled = flowOf(true), scope = testScope(), policy = ScrobblePolicy(now = { 1_000L })) + val state = MutableStateFlow(PlaybackState()) + val position = MutableStateFlow(0L) + scrobbler.attach(state, position) + val first = QueueItem("s1", "One", "Artist", "Album", null, durationMs = 30_000) + val second = QueueItem("s2", "Two", "Artist", "Album", null, durationMs = 30_000) + + state.value = PlaybackState(item = first, isPlaying = true) + var tick = 500L + while (tick <= 15_000L) { + position.value = tick + tick += 500 + } + position.value = 0L + state.value = PlaybackState(item = second, isPlaying = true) + + assertEquals( + listOf( + Call.NowPlaying("s1"), + Call.Scrobble("s1", 1_000L), + Call.NowPlaying("s2"), + ), + sink.calls, + ) + } }