refactor: moved CompositeMediaRepository to the domain level + changes in connected classes

This commit is contained in:
2026-04-24 09:04:51 +02:00
parent 8423e63937
commit a9bd23e26c
7 changed files with 40 additions and 55 deletions

View File

@@ -1,7 +0,0 @@
package hu.bbara.purefin.data
import java.util.UUID
interface EpisodeSeriesLookup {
suspend fun preferenceKeyFor(mediaId: UUID): String
}

View File

@@ -3,10 +3,11 @@ package hu.bbara.purefin.data
import hu.bbara.purefin.model.Episode
import hu.bbara.purefin.model.Movie
import hu.bbara.purefin.model.Series
import java.util.UUID
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow
import java.util.UUID
//TODO rename MediaRepository
interface MediaCatalogReader {
val movies: StateFlow<Map<UUID, Movie>>
val series: StateFlow<Map<UUID, Series>>

View File

@@ -1,16 +0,0 @@
package hu.bbara.purefin.data.catalog
import hu.bbara.purefin.data.EpisodeSeriesLookup
import hu.bbara.purefin.data.MediaCatalogReader
import java.util.UUID
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class DefaultEpisodeSeriesLookup @Inject constructor(
private val mediaCatalogReader: MediaCatalogReader,
) : EpisodeSeriesLookup {
override suspend fun preferenceKeyFor(mediaId: UUID): String {
return mediaCatalogReader.episodes.value[mediaId]?.seriesId?.toString() ?: mediaId.toString()
}
}

View File

@@ -0,0 +1,16 @@
package hu.bbara.purefin.data.module
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import hu.bbara.purefin.data.OfflineCatalogReader
import hu.bbara.purefin.data.catalog.OfflineMediaRepository
@Module
@InstallIn(SingletonComponent::class)
abstract class MediaRepositoryModule {
@Binds
abstract fun bindOfflineCatalogReader(impl: OfflineMediaRepository): OfflineCatalogReader
}

View File

@@ -4,14 +4,13 @@ import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import hu.bbara.purefin.data.EpisodeSeriesLookup
import hu.bbara.purefin.data.PlayableMediaRepository
import hu.bbara.purefin.core.player.manager.PlayerManager
import hu.bbara.purefin.core.player.manager.ProgressManager
import hu.bbara.purefin.core.player.model.MediaContext
import hu.bbara.purefin.core.player.model.PlayerUiState
import hu.bbara.purefin.core.player.model.TrackOption
import hu.bbara.purefin.core.player.preference.TrackPreferencesRepository
import hu.bbara.purefin.data.PlayableMediaRepository
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
@@ -30,7 +29,6 @@ class PlayerViewModel @Inject constructor(
private val playerManager: PlayerManager,
private val playableMediaRepository: PlayableMediaRepository,
private val trackPreferencesRepository: TrackPreferencesRepository,
private val episodeSeriesLookup: EpisodeSeriesLookup,
private val progressManager: ProgressManager,
) : ViewModel() {
companion object {
@@ -156,7 +154,10 @@ class PlayerViewModel @Inject constructor(
if (result != null) {
val (mediaItem, resumePositionMs) = result
val preferenceKey = episodeSeriesLookup.preferenceKeyFor(uuid)
// TODO use CatalogReader for this instead of episodeSeriesLookup
// val preferenceKey = episodeSeriesLookup.preferenceKeyFor(uuid)
val preferenceKey = uuid.toString()
val preferences = trackPreferencesRepository.getMediaPreferences(preferenceKey).first()
val mediaSegments = playableMediaRepository.getMediaSegments(uuid)

View File

@@ -1,8 +1,7 @@
package hu.bbara.purefin.data.catalog
package hu.bbara.purefin.data
import hu.bbara.purefin.data.MediaCatalogReader
import hu.bbara.purefin.data.MediaProgressWriter
import hu.bbara.purefin.data.NetworkMonitor
import hu.bbara.purefin.data.catalog.InMemoryMediaRepository
import hu.bbara.purefin.data.catalog.OfflineMediaRepository
import hu.bbara.purefin.model.Episode
import hu.bbara.purefin.model.Movie
import hu.bbara.purefin.model.Series
@@ -13,7 +12,6 @@ import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.stateIn
@@ -26,34 +24,31 @@ import javax.inject.Singleton
class CompositeMediaRepository @Inject constructor(
private val offlineRepository: OfflineMediaRepository,
private val onlineRepository: InMemoryMediaRepository,
private val networkMonitor: NetworkMonitor,
) : MediaCatalogReader, MediaProgressWriter {
private val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
private val activeRepository: Flow<MediaCatalogReader> =
networkMonitor.isOnline.flatMapLatest { online ->
flowOf(if (online) onlineRepository else offlineRepository)
}
// TODO move this into the domain layer and there you can use NetworkMonitor. Data should be free of android stuff.
private val activeRepository: Flow<MediaCatalogReader> = flowOf(onlineRepository)
override val movies: StateFlow<Map<UUID, Movie>> = activeRepository
.flatMapLatest { it.movies }
.stateIn(scope, SharingStarted.Eagerly, emptyMap())
.stateIn(scope, SharingStarted.Companion.Eagerly, emptyMap())
override val series: StateFlow<Map<UUID, Series>> = activeRepository
.flatMapLatest { it.series }
.stateIn(scope, SharingStarted.Eagerly, emptyMap())
.stateIn(scope, SharingStarted.Companion.Eagerly, emptyMap())
override val episodes: StateFlow<Map<UUID, Episode>> = activeRepository
.flatMapLatest { it.episodes }
.stateIn(scope, SharingStarted.Eagerly, emptyMap())
.stateIn(scope, SharingStarted.Companion.Eagerly, emptyMap())
override fun observeSeriesWithContent(seriesId: UUID): Flow<Series?> {
return activeRepository.flatMapLatest { it.observeSeriesWithContent(seriesId) }
}
override suspend fun updateWatchProgress(mediaId: UUID, positionMs: Long, durationMs: Long) {
val repository = if (networkMonitor.isOnline.first()) onlineRepository else offlineRepository
val repository = onlineRepository
repository.updateWatchProgress(mediaId, positionMs, durationMs)
}
}

View File

@@ -1,18 +1,19 @@
package hu.bbara.purefin.data.catalog
package hu.bbara.purefin.module
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import hu.bbara.purefin.data.EpisodeSeriesLookup
import hu.bbara.purefin.data.CompositeMediaRepository
import hu.bbara.purefin.data.HomeRepository
import hu.bbara.purefin.data.MediaCatalogReader
import hu.bbara.purefin.data.MediaProgressWriter
import hu.bbara.purefin.data.OfflineCatalogReader
import hu.bbara.purefin.data.catalog.InMemoryAppContentRepository
@Module
@InstallIn(SingletonComponent::class)
abstract class MediaRepositoryModule {
abstract class RepositoryModule {
@Binds
abstract fun bindHomeRepository(impl: InMemoryAppContentRepository): HomeRepository
@@ -21,11 +22,5 @@ abstract class MediaRepositoryModule {
abstract fun bindMediaCatalogReader(impl: CompositeMediaRepository): MediaCatalogReader
@Binds
abstract fun bindMediaProgressWriter(impl: CompositeMediaRepository): MediaProgressWriter
@Binds
abstract fun bindOfflineCatalogReader(impl: OfflineMediaRepository): OfflineCatalogReader
@Binds
abstract fun bindEpisodeSeriesLookup(impl: DefaultEpisodeSeriesLookup): EpisodeSeriesLookup
abstract fun bindMediaProgressWrite(impl: CompositeMediaRepository): MediaProgressWriter
}