From 4788eec10258774daf655db132def46ed6e52258 Mon Sep 17 00:00:00 2001 From: Barnabas Balogh Date: Fri, 8 May 2026 19:30:44 +0200 Subject: [PATCH] feat: add SeriesIdLookUpUseCase for episode to series ID mapping and update track preference saving logic --- .../content/episode/SeriesIdLookUpUseCase.kt | 14 ++++++++++++++ .../core/player/manager/PlayerManager.kt | 17 ++++++++++++----- .../jellyfin/DefaultPlayableMediaRepository.kt | 8 ++++---- 3 files changed, 30 insertions(+), 9 deletions(-) create mode 100644 core/src/main/java/hu/bbara/purefin/core/feature/content/episode/SeriesIdLookUpUseCase.kt diff --git a/core/src/main/java/hu/bbara/purefin/core/feature/content/episode/SeriesIdLookUpUseCase.kt b/core/src/main/java/hu/bbara/purefin/core/feature/content/episode/SeriesIdLookUpUseCase.kt new file mode 100644 index 00000000..95377456 --- /dev/null +++ b/core/src/main/java/hu/bbara/purefin/core/feature/content/episode/SeriesIdLookUpUseCase.kt @@ -0,0 +1,14 @@ +package hu.bbara.purefin.core.feature.content.episode + +import hu.bbara.purefin.core.data.LocalMediaRepository +import java.util.UUID +import javax.inject.Inject +import kotlinx.coroutines.flow.first + +class SeriesIdLookUpUseCase @Inject constructor( + private val localMediaRepository: LocalMediaRepository, +) { + suspend operator fun invoke(episodeId: UUID): UUID? { + return localMediaRepository.getEpisode(episodeId).first()?.seriesId + } +} diff --git a/core/src/main/java/hu/bbara/purefin/core/player/manager/PlayerManager.kt b/core/src/main/java/hu/bbara/purefin/core/player/manager/PlayerManager.kt index 225a89e1..487bbac1 100644 --- a/core/src/main/java/hu/bbara/purefin/core/player/manager/PlayerManager.kt +++ b/core/src/main/java/hu/bbara/purefin/core/player/manager/PlayerManager.kt @@ -11,19 +11,20 @@ import androidx.media3.exoplayer.ExoPlayer import dagger.hilt.android.scopes.ViewModelScoped import hu.bbara.purefin.core.data.PlayableMediaRepository import hu.bbara.purefin.core.data.PlaybackReportContext +import hu.bbara.purefin.core.feature.content.episode.SeriesIdLookUpUseCase import hu.bbara.purefin.core.player.model.MetadataState import hu.bbara.purefin.core.player.model.PlaybackProgressSnapshot import hu.bbara.purefin.core.player.model.PlaybackStateSnapshot import hu.bbara.purefin.core.player.model.SegmentStatus import hu.bbara.purefin.core.player.model.TrackOption import hu.bbara.purefin.core.player.model.TrackType +import hu.bbara.purefin.core.player.preference.TrackMatcher +import hu.bbara.purefin.core.player.preference.TrackPreferencesRepository import hu.bbara.purefin.model.AudioTrackProperties import hu.bbara.purefin.model.MediaSegment import hu.bbara.purefin.model.PlayableMedia import hu.bbara.purefin.model.SegmentType import hu.bbara.purefin.model.SubtitleTrackProperties -import hu.bbara.purefin.core.player.preference.TrackMatcher -import hu.bbara.purefin.core.player.preference.TrackPreferencesRepository import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob @@ -52,7 +53,8 @@ class PlayerManager @Inject constructor( private val trackMapper: TrackMapper, private val playableMediaRepository: PlayableMediaRepository, private val trackPreferencesRepository: TrackPreferencesRepository, - private val trackMatcher: TrackMatcher + private val trackMatcher: TrackMatcher, + private val seriesIdLookUpUseCase: SeriesIdLookUpUseCase ) { companion object { private const val SEEK_SETTLE_TOLERANCE_MS = 750L @@ -338,6 +340,11 @@ class PlayerManager @Inject constructor( } private suspend fun saveTrackPreference(option: TrackOption, mediaId: UUID) { + val preferenceMediaId = when (currentPlayableMedia.firstOrNull()) { + is PlayableMedia.Episode -> seriesIdLookUpUseCase(mediaId) ?: mediaId + else -> mediaId + }.toString() + when (option.type) { TrackType.AUDIO -> { val properties = AudioTrackProperties( @@ -345,7 +352,7 @@ class PlayerManager @Inject constructor( channelCount = option.channelCount, label = option.label ) - trackPreferencesRepository.saveAudioPreference(mediaId.toString(), properties) + trackPreferencesRepository.saveAudioPreference(preferenceMediaId, properties) } TrackType.TEXT -> { @@ -355,7 +362,7 @@ class PlayerManager @Inject constructor( label = option.label, isOff = option.isOff ) - trackPreferencesRepository.saveSubtitlePreference(mediaId.toString(), properties) + trackPreferencesRepository.saveSubtitlePreference(preferenceMediaId, properties) } TrackType.VIDEO -> { diff --git a/data/src/main/java/hu/bbara/purefin/data/jellyfin/DefaultPlayableMediaRepository.kt b/data/src/main/java/hu/bbara/purefin/data/jellyfin/DefaultPlayableMediaRepository.kt index 8021c471..cd11a7e0 100644 --- a/data/src/main/java/hu/bbara/purefin/data/jellyfin/DefaultPlayableMediaRepository.kt +++ b/data/src/main/java/hu/bbara/purefin/data/jellyfin/DefaultPlayableMediaRepository.kt @@ -9,16 +9,16 @@ import androidx.media3.common.util.UnstableApi import hu.bbara.purefin.core.data.PlayableMediaRepository import hu.bbara.purefin.core.data.PlaybackReportContext import hu.bbara.purefin.core.data.UserSessionRepository +import hu.bbara.purefin.core.image.ArtworkKind +import hu.bbara.purefin.core.image.ImageUrlBuilder +import hu.bbara.purefin.core.player.preference.TrackPreferencesRepository import hu.bbara.purefin.data.jellyfin.client.JellyfinApiClient import hu.bbara.purefin.data.jellyfin.playback.JellyfinPlaybackResolver import hu.bbara.purefin.data.jellyfin.playback.PlaybackDecision import hu.bbara.purefin.data.jellyfin.playback.playbackCustomCacheKey -import hu.bbara.purefin.core.image.ArtworkKind -import hu.bbara.purefin.core.image.ImageUrlBuilder import hu.bbara.purefin.model.MediaSegment import hu.bbara.purefin.model.PlayableMedia import hu.bbara.purefin.model.SegmentType -import hu.bbara.purefin.core.player.preference.TrackPreferencesRepository import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.first import kotlinx.coroutines.withContext @@ -48,7 +48,7 @@ class DefaultPlayableMediaRepository @Inject constructor( val mediaItem = getMediaItem(baseItem, playbackDecision) val resumePositionMs = calculateResumePosition(baseItem, playbackDecision.mediaSource) - val mediaTrackPreferences = trackPreferencesRepository.getMediaPreferences(mediaId.toString()).first() + val mediaTrackPreferences = trackPreferencesRepository.getMediaPreferences(baseItem.parentId.toString()).first() val mediaSegments = getMediaSegments(mediaId) when (baseItem.type) { BaseItemKind.MOVIE -> PlayableMedia.Movie(