From 7486bc24443df01a058ea1ea0a541f3fa738ef1d Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Thu, 4 Jun 2026 07:04:01 -0400 Subject: [PATCH] fix(android): split tickPositionPoll into helpers for detekt complexity --- .../minstrel/player/PlayerController.kt | 45 +++++++++++++------ 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/android/app/src/main/java/com/fabledsword/minstrel/player/PlayerController.kt b/android/app/src/main/java/com/fabledsword/minstrel/player/PlayerController.kt index fd0251aa..fbb993de 100644 --- a/android/app/src/main/java/com/fabledsword/minstrel/player/PlayerController.kt +++ b/android/app/src/main/java/com/fabledsword/minstrel/player/PlayerController.kt @@ -513,20 +513,8 @@ class PlayerController @Inject constructor( */ private fun tickPositionPoll(controller: MediaController) { val upnpActive = activeUpnpHolder.active.value != null - // Pending-transport handling. Event-driven primary: as soon as Sonos's - // reported Track matches the wrapped player's currentMediaItemIndex, - // the user's transport press has been ack'd and pending clears. - // Safety fallback: if the deadline expires without an ack, clear - // anyway so we don't ignore Sonos's actual state forever. - if (upnpActive && remoteState.pendingTransportDeadlineMs > 0L) { - val sonosIdx = (remoteState.trackNumber - 1).coerceAtLeast(0) - val timedOut = SystemClock.elapsedRealtime() > remoteState.pendingTransportDeadlineMs - if (sonosIdx == controller.currentMediaItemIndex || timedOut) { - remoteState.clearPendingTransport() - } - } + resolvePendingTransport(controller, upnpActive) val pendingTransport = upnpActive && remoteState.pendingTransportDeadlineMs > 0L - val effectiveIsPlaying = if (upnpActive) remoteState.isPlaying else controller.isPlaying val effectivePosition = if (upnpActive) { @@ -545,6 +533,37 @@ class PlayerController @Inject constructor( val trackChanged = !pendingTransport && desiredIdx > current.queueIndex && desiredIdx in queueRefs.indices + publishTickIfChanged( + controller, current, trackChanged, desiredIdx, + effectiveIsPlaying, newPos, newDur, newBuf, + ) + } + + /** + * Event-driven primary path: clear pending the moment Sonos's reported + * Track matches the wrapped player's index. Safety fallback: clear on + * deadline so we don't ignore Sonos's actual state forever if SOAP fails. + */ + private fun resolvePendingTransport(controller: MediaController, upnpActive: Boolean) { + if (!upnpActive || remoteState.pendingTransportDeadlineMs <= 0L) return + val sonosIdx = (remoteState.trackNumber - 1).coerceAtLeast(0) + val timedOut = SystemClock.elapsedRealtime() > remoteState.pendingTransportDeadlineMs + if (sonosIdx == controller.currentMediaItemIndex || timedOut) { + remoteState.clearPendingTransport() + } + } + + @Suppress("LongParameterList") // assembled at one tick call site; refactor would cost clarity + private fun publishTickIfChanged( + controller: MediaController, + current: PlayerUiState, + trackChanged: Boolean, + desiredIdx: Int, + effectiveIsPlaying: Boolean, + newPos: Long, + newDur: Long, + newBuf: Long, + ) { val somethingChanged = trackChanged || current.isPlaying != effectiveIsPlaying || current.positionMs != newPos ||