refactor: MediaProgressWriter to LocalMediaUpdater and add markAsWatched support

This commit is contained in:
2026-05-04 18:10:02 +02:00
parent ed80948676
commit bc4b26291f
7 changed files with 34 additions and 8 deletions

View File

@@ -71,4 +71,9 @@ class CompositeLocalMediaRepository @Inject constructor(
val repository = onlineRepository
repository.updateWatchProgress(mediaId, positionMs, durationMs)
}
override suspend fun markAsWatched(mediaId: UUID, watched: Boolean) {
val repository = onlineRepository
repository.markAsWatched(mediaId, watched)
}
}

View File

@@ -8,7 +8,7 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow
import java.util.UUID
interface LocalMediaRepository : MediaProgressWriter {
interface LocalMediaRepository : LocalMediaUpdater {
val movies: StateFlow<Map<UUID, Movie>>
val series: StateFlow<Map<UUID, Series>>
val episodes: StateFlow<Map<UUID, Episode>>

View File

@@ -2,6 +2,7 @@ package hu.bbara.purefin.data
import java.util.UUID
interface MediaProgressWriter {
interface LocalMediaUpdater {
suspend fun updateWatchProgress(mediaId: UUID, positionMs: Long, durationMs: Long)
suspend fun markAsWatched(mediaId: UUID, watched: Boolean)
}

View File

@@ -5,7 +5,7 @@ import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import hu.bbara.purefin.data.CompositeLocalMediaRepository
import hu.bbara.purefin.data.MediaProgressWriter
import hu.bbara.purefin.data.LocalMediaUpdater
import hu.bbara.purefin.data.LocalMediaRepository
@@ -17,5 +17,5 @@ abstract class RepositoryModule {
abstract fun bindMediaRepository(impl: CompositeLocalMediaRepository): LocalMediaRepository
@Binds
abstract fun bindMediaProgressWrite(impl: CompositeLocalMediaRepository): MediaProgressWriter
abstract fun bindMediaProgressWrite(impl: CompositeLocalMediaRepository): LocalMediaUpdater
}

View File

@@ -2,7 +2,7 @@ package hu.bbara.purefin.player.manager
import android.util.Log
import dagger.hilt.android.scopes.ViewModelScoped
import hu.bbara.purefin.data.MediaProgressWriter
import hu.bbara.purefin.data.LocalMediaUpdater
import hu.bbara.purefin.data.PlaybackProgressReporter
import hu.bbara.purefin.data.PlaybackReportContext
import hu.bbara.purefin.player.model.MetadataState
@@ -24,7 +24,7 @@ import javax.inject.Inject
@ViewModelScoped
class ProgressManager @Inject constructor(
private val playbackProgressReporter: PlaybackProgressReporter,
private val mediaProgressWriter: MediaProgressWriter,
private val localMediaUpdater: LocalMediaUpdater,
) {
private val scope = CoroutineScope(SupervisorJob() + Dispatchers.Main.immediate)
private var progressJob: Job? = null
@@ -80,7 +80,7 @@ class ProgressManager @Inject constructor(
report(itemId, lastPositionMs, reportContext = activePlaybackReportContext, isStop = true)
scope.launch(Dispatchers.IO) {
try {
mediaProgressWriter.updateWatchProgress(itemId, lastPositionMs, lastDurationMs)
localMediaUpdater.updateWatchProgress(itemId, lastPositionMs, lastDurationMs)
} catch (e: Exception) {
Log.e("ProgressManager", "Local cache update failed", e)
}
@@ -127,7 +127,7 @@ class ProgressManager @Inject constructor(
activePlaybackReportContext?.let { reportContext ->
playbackProgressReporter.reportPlaybackStopped(itemId, ticks, reportContext)
}
mediaProgressWriter.updateWatchProgress(itemId, posMs, durMs)
localMediaUpdater.updateWatchProgress(itemId, posMs, durMs)
Log.d("ProgressManager", "Stop: $itemId at ${posMs}ms")
} catch (e: Exception) {
Log.e("ProgressManager", "Report failed", e)

View File

@@ -146,6 +146,22 @@ class InMemoryLocalMediaRepository @Inject constructor(
}
}
override suspend fun markAsWatched(mediaId: UUID, watched: Boolean) {
if (moviesState.value.containsKey(mediaId)) {
moviesState.update { current ->
val movie = current[mediaId] ?: return@update current
current + (mediaId to movie.copy(watched = watched))
}
return
}
if (episodesState.value.containsKey(mediaId)) {
episodesState.update { current ->
val episode = current[mediaId] ?: return@update current
current + (mediaId to episode.copy(watched = watched))
}
}
}
private suspend fun ensureSeriesContentLoaded(seriesId: UUID) {
seriesState.value[seriesId]?.takeIf { it.seasons.isNotEmpty() }?.let { return }

View File

@@ -58,4 +58,8 @@ class OfflineLocalMediaRepository @Inject constructor(
val watched = progressPercent >= 90.0
localDataSource.updateWatchProgress(mediaId, progressPercent, watched)
}
override suspend fun markAsWatched(mediaId: UUID, watched: Boolean) {
// Do nothing
}
}