From f2c46af41071e7ac514f53805612b45f7eea376e Mon Sep 17 00:00:00 2001 From: Barnabas Balogh Date: Sun, 3 May 2026 22:08:56 +0200 Subject: [PATCH] feat(jellyfin): add functionality to mark media as watched/unwatched --- .../jellyfin/JellyfinMediaMetadataUpdater.kt | 7 ++++++ .../JellyfinMediaMetadataUpdaterImpl.kt | 19 +++++++++++++++ .../data/jellyfin/client/JellyfinApiClient.kt | 24 +++++++++++++++++++ .../data/module/MediaRepositoryModule.kt | 5 ++++ 4 files changed, 55 insertions(+) create mode 100644 core/src/main/java/hu/bbara/purefin/jellyfin/JellyfinMediaMetadataUpdater.kt create mode 100644 data/src/main/java/hu/bbara/purefin/data/jellyfin/JellyfinMediaMetadataUpdaterImpl.kt diff --git a/core/src/main/java/hu/bbara/purefin/jellyfin/JellyfinMediaMetadataUpdater.kt b/core/src/main/java/hu/bbara/purefin/jellyfin/JellyfinMediaMetadataUpdater.kt new file mode 100644 index 00000000..50238f47 --- /dev/null +++ b/core/src/main/java/hu/bbara/purefin/jellyfin/JellyfinMediaMetadataUpdater.kt @@ -0,0 +1,7 @@ +package hu.bbara.purefin.jellyfin + +import java.util.UUID + +interface JellyfinMediaMetadataUpdater { + suspend fun markAsWatched(mediaId: UUID, watched: Boolean) +} \ No newline at end of file diff --git a/data/src/main/java/hu/bbara/purefin/data/jellyfin/JellyfinMediaMetadataUpdaterImpl.kt b/data/src/main/java/hu/bbara/purefin/data/jellyfin/JellyfinMediaMetadataUpdaterImpl.kt new file mode 100644 index 00000000..fee24724 --- /dev/null +++ b/data/src/main/java/hu/bbara/purefin/data/jellyfin/JellyfinMediaMetadataUpdaterImpl.kt @@ -0,0 +1,19 @@ +package hu.bbara.purefin.data.jellyfin + +import hu.bbara.purefin.data.jellyfin.client.JellyfinApiClient +import hu.bbara.purefin.jellyfin.JellyfinMediaMetadataUpdater +import java.util.UUID +import javax.inject.Inject + +class JellyfinMediaMetadataUpdaterImpl @Inject constructor( + private val jellyfinApiClient: JellyfinApiClient +) : JellyfinMediaMetadataUpdater { + + override suspend fun markAsWatched(mediaId: UUID, watched: Boolean) { + if (watched) { + jellyfinApiClient.markAsWatched(mediaId) + } else { + jellyfinApiClient.markAsUnwatched(mediaId) + } + } +} \ No newline at end of file diff --git a/data/src/main/java/hu/bbara/purefin/data/jellyfin/client/JellyfinApiClient.kt b/data/src/main/java/hu/bbara/purefin/data/jellyfin/client/JellyfinApiClient.kt index 1da88081..bfc091df 100644 --- a/data/src/main/java/hu/bbara/purefin/data/jellyfin/client/JellyfinApiClient.kt +++ b/data/src/main/java/hu/bbara/purefin/data/jellyfin/client/JellyfinApiClient.kt @@ -322,6 +322,30 @@ class JellyfinApiClient @Inject constructor( } } + suspend fun markAsWatched(mediaId: UUID) = withContext(Dispatchers.IO) { + logApiFailure("markAsWatched($mediaId)") { + if (!ensureConfigured()) { + return@logApiFailure + } + api.playStateApi.markPlayedItem( + itemId = mediaId, + userId = getUserId(), + ) + } + } + + suspend fun markAsUnwatched(mediaId: UUID) = withContext(Dispatchers.IO) { + logApiFailure("markAsUnwatched($mediaId)") { + if (!ensureConfigured()) { + return@logApiFailure + } + api.playStateApi.markUnplayedItem( + itemId = mediaId, + userId = getUserId(), + ) + } + } + suspend fun getMediaSources(mediaId: UUID): List = withContext(Dispatchers.IO) { logApiFailure("getMediaSources($mediaId)") { if (!ensureConfigured()) { diff --git a/data/src/main/java/hu/bbara/purefin/data/module/MediaRepositoryModule.kt b/data/src/main/java/hu/bbara/purefin/data/module/MediaRepositoryModule.kt index 2e6e193f..f957377f 100644 --- a/data/src/main/java/hu/bbara/purefin/data/module/MediaRepositoryModule.kt +++ b/data/src/main/java/hu/bbara/purefin/data/module/MediaRepositoryModule.kt @@ -12,7 +12,9 @@ import hu.bbara.purefin.data.SearchManager import hu.bbara.purefin.data.catalog.InMemoryAppContentRepository import hu.bbara.purefin.data.catalog.InMemoryLocalMediaRepository import hu.bbara.purefin.data.catalog.OfflineLocalMediaRepository +import hu.bbara.purefin.data.jellyfin.JellyfinMediaMetadataUpdaterImpl import hu.bbara.purefin.data.jellyfin.SearchManagerImpl +import hu.bbara.purefin.jellyfin.JellyfinMediaMetadataUpdater @Module @InstallIn(SingletonComponent::class) @@ -29,6 +31,9 @@ abstract class MediaRepositoryModule { @Binds abstract fun bindHomeRepository(impl: InMemoryAppContentRepository): HomeRepository + @Binds + abstract fun bindJellyfinMediaMetadataUpdater(impl: JellyfinMediaMetadataUpdaterImpl): JellyfinMediaMetadataUpdater + @Binds abstract fun bindSearchManager(impl: SearchManagerImpl): SearchManager } \ No newline at end of file