From 582e0ff40ecc7e6ea6115be369c7db1bd86098a1 Mon Sep 17 00:00:00 2001 From: Aniket Tuli Date: Fri, 12 Jun 2026 03:03:41 -0700 Subject: [PATCH] refactor(trakt): snapshot scrobble item inputs through a single holder The stop-scrobble path snapshots its inputs via snapshotTraktScrobbleItemInputs() returning a TraktScrobbleItemInputs holder instead of seven loose locals, so adding a field to the item cannot silently miss the snapshot. Co-Authored-By: Claude Fable 5 --- .../PlayerScreenRuntimePlaybackActions.kt | 53 +++++++++++-------- 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerScreenRuntimePlaybackActions.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerScreenRuntimePlaybackActions.kt index 98c843d35..52ee175e5 100644 --- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerScreenRuntimePlaybackActions.kt +++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerScreenRuntimePlaybackActions.kt @@ -80,17 +80,40 @@ internal fun PlayerScreenRuntime.currentPlaybackProgressPercent( .coerceIn(0f, 100f) } -internal suspend fun PlayerScreenRuntime.currentTraktScrobbleItem() = +internal data class TraktScrobbleItemInputs( + val contentType: String, + val parentMetaId: String, + val videoId: String?, + val title: String, + val seasonNumber: Int?, + val episodeNumber: Int?, + val episodeTitle: String?, +) + +internal fun PlayerScreenRuntime.snapshotTraktScrobbleItemInputs() = TraktScrobbleItemInputs( + contentType = contentType ?: parentMetaType, + parentMetaId = parentMetaId, + videoId = activeVideoId, + title = title, + seasonNumber = activeSeasonNumber, + episodeNumber = activeEpisodeNumber, + episodeTitle = activeEpisodeTitle, +) + +private suspend fun TraktScrobbleItemInputs.buildItem() = TraktScrobbleRepository.buildItem( - contentType = contentType ?: parentMetaType, + contentType = contentType, parentMetaId = parentMetaId, - videoId = activeVideoId, + videoId = videoId, title = title, - seasonNumber = activeSeasonNumber, - episodeNumber = activeEpisodeNumber, - episodeTitle = activeEpisodeTitle, + seasonNumber = seasonNumber, + episodeNumber = episodeNumber, + episodeTitle = episodeTitle, ) +internal suspend fun PlayerScreenRuntime.currentTraktScrobbleItem() = + snapshotTraktScrobbleItemInputs().buildItem() + internal fun PlayerScreenRuntime.emitTraktScrobbleStart() { if (hasRequestedScrobbleStartForCurrentItem) return hasRequestedScrobbleStartForCurrentItem = true @@ -120,23 +143,9 @@ internal fun PlayerScreenRuntime.emitTraktScrobbleStop(progressPercent: Float? = val percent = provided ?: currentPlaybackProgressPercent() val itemSnapshot = currentTraktScrobbleItem - val contentTypeSnapshot = contentType ?: parentMetaType - val parentMetaIdSnapshot = parentMetaId - val videoIdSnapshot = activeVideoId - val titleSnapshot = title - val seasonNumberSnapshot = activeSeasonNumber - val episodeNumberSnapshot = activeEpisodeNumber - val episodeTitleSnapshot = activeEpisodeTitle + val inputsSnapshot = snapshotTraktScrobbleItemInputs() scope.launch(NonCancellable) { - val item = itemSnapshot ?: TraktScrobbleRepository.buildItem( - contentType = contentTypeSnapshot, - parentMetaId = parentMetaIdSnapshot, - videoId = videoIdSnapshot, - title = titleSnapshot, - seasonNumber = seasonNumberSnapshot, - episodeNumber = episodeNumberSnapshot, - episodeTitle = episodeTitleSnapshot, - ) ?: return@launch + val item = itemSnapshot ?: inputsSnapshot.buildItem() ?: return@launch TraktScrobbleRepository.scrobbleStop( item = item, progressPercent = percent,