diff --git a/app/src/main/java/org/jellyfin/mobile/controller/ApiController.kt b/app/src/main/java/org/jellyfin/mobile/controller/ApiController.kt index 136b598b30..730b7ab374 100644 --- a/app/src/main/java/org/jellyfin/mobile/controller/ApiController.kt +++ b/app/src/main/java/org/jellyfin/mobile/controller/ApiController.kt @@ -73,15 +73,15 @@ class ApiController( } private fun configureApiClientUser(userId: String, accessToken: String) { + apiClient.userId = userId.toUUID() + apiClient.accessToken = accessToken // Append user id to device id to ensure uniqueness across sessions apiClient.deviceInfo = baseDeviceInfo.copy(id = baseDeviceInfo.id + userId) - apiClient.accessToken = accessToken - apiClient.userId = userId.toUUID() } private fun resetApiClientUser() { - apiClient.deviceInfo = baseDeviceInfo - apiClient.accessToken = null apiClient.userId = null + apiClient.accessToken = null + apiClient.deviceInfo = baseDeviceInfo } } diff --git a/app/src/main/java/org/jellyfin/mobile/media/MediaService.kt b/app/src/main/java/org/jellyfin/mobile/media/MediaService.kt index 8375f3c2df..31b82d5788 100644 --- a/app/src/main/java/org/jellyfin/mobile/media/MediaService.kt +++ b/app/src/main/java/org/jellyfin/mobile/media/MediaService.kt @@ -173,7 +173,12 @@ class MediaService : MediaBrowserServiceCompat() { loadingJob.join() val items = try { - if (apiClient.userId != null) libraryBrowser.loadLibrary(parentId) else null + if (apiClient.userId != null) { + libraryBrowser.loadLibrary(parentId) + } else { + Timber.e("Missing userId in ApiClient") + null + } } catch (e: ApiClientException) { Timber.e(e) null diff --git a/app/src/main/java/org/jellyfin/mobile/media/car/LibraryBrowser.kt b/app/src/main/java/org/jellyfin/mobile/media/car/LibraryBrowser.kt index 9bd49e838b..2e166a7ca6 100644 --- a/app/src/main/java/org/jellyfin/mobile/media/car/LibraryBrowser.kt +++ b/app/src/main/java/org/jellyfin/mobile/media/car/LibraryBrowser.kt @@ -40,7 +40,7 @@ import org.jellyfin.sdk.model.api.SortOrder import org.jellyfin.sdk.model.serializer.toUUID import org.jellyfin.sdk.model.serializer.toUUIDOrNull import timber.log.Timber -import java.util.* +import java.util.UUID @Suppress("TooManyFunctions") class LibraryBrowser( @@ -76,8 +76,10 @@ class LibraryBrowser( val split = parentId.split('|') @Suppress("MagicNumber") - if (split.size !in 1..3) + if (split.size !in 1..3) { + Timber.e("Invalid libraryId format '$parentId'") return null + } val type = split[0] val libraryId = split.getOrNull(1)?.toUUIDOrNull() @@ -114,8 +116,10 @@ class LibraryBrowser( suspend fun buildPlayQueue(mediaId: String): Pair, Int>? { val split = mediaId.split('|') @Suppress("MagicNumber") - if (split.size != 3) + if (split.size != 3) { + Timber.e("Invalid mediaId format '$mediaId'") return null + } val type = split[0] val collectionId = split[1].toUUID() @@ -221,7 +225,7 @@ class LibraryBrowser( .map { item -> val itemImageUrl = imageApi.getItemImageUrl( itemId = item.id, - imageType = ImageType.PRIMARY + imageType = ImageType.PRIMARY, ) val description = MediaDescriptionCompat.Builder().apply { diff --git a/app/src/main/java/org/jellyfin/mobile/player/PlayerViewModel.kt b/app/src/main/java/org/jellyfin/mobile/player/PlayerViewModel.kt index f1a9468304..9ed337562f 100644 --- a/app/src/main/java/org/jellyfin/mobile/player/PlayerViewModel.kt +++ b/app/src/main/java/org/jellyfin/mobile/player/PlayerViewModel.kt @@ -26,7 +26,6 @@ import kotlinx.coroutines.delay import kotlinx.coroutines.launch import org.jellyfin.mobile.BuildConfig import org.jellyfin.mobile.PLAYER_EVENT_CHANNEL -import org.jellyfin.mobile.controller.ApiController import org.jellyfin.mobile.player.source.JellyfinMediaSource import org.jellyfin.mobile.player.source.MediaQueueManager import org.jellyfin.mobile.utils.Constants @@ -51,10 +50,8 @@ import org.koin.core.component.KoinComponent import org.koin.core.component.inject import org.koin.core.qualifier.named import timber.log.Timber -import java.util.* class PlayerViewModel(application: Application) : AndroidViewModel(application), KoinComponent, Player.Listener { - private val apiController by inject() private val playStateApi by inject() private val lifecycleObserver = PlayerLifecycleObserver(this) @@ -243,9 +240,7 @@ class PlayerViewModel(application: Application) : AndroidViewModel(application), // Mark video as watched if playback finished if (hasFinished) { - playStateApi.markPlayedItem( - itemId = mediaSource.itemId, - ) + playStateApi.markPlayedItem(itemId = mediaSource.itemId) } } catch (e: ApiClientException) { Timber.e(e, "Failed to report playback stop") diff --git a/app/src/main/java/org/jellyfin/mobile/player/source/MediaSourceResolver.kt b/app/src/main/java/org/jellyfin/mobile/player/source/MediaSourceResolver.kt index bae2340d1c..c2429faa06 100644 --- a/app/src/main/java/org/jellyfin/mobile/player/source/MediaSourceResolver.kt +++ b/app/src/main/java/org/jellyfin/mobile/player/source/MediaSourceResolver.kt @@ -9,7 +9,7 @@ import org.jellyfin.sdk.model.api.DeviceProfile import org.jellyfin.sdk.model.api.PlaybackInfoDto import org.jellyfin.sdk.model.serializer.toUUIDOrNull import timber.log.Timber -import java.util.* +import java.util.UUID class MediaSourceResolver( private val apiClient: ApiClient, @@ -25,7 +25,7 @@ class MediaSourceResolver( ): Result { // Load media source info val mediaSourceInfo = try { - val playbackInfoResponse by mediaInfoApi.getPostedPlaybackInfo( + val response by mediaInfoApi.getPostedPlaybackInfo( itemId = itemId, data = PlaybackInfoDto( userId = apiClient.userId, @@ -37,7 +37,7 @@ class MediaSourceResolver( ), ) - playbackInfoResponse.mediaSources?.find { source -> + response.mediaSources?.find { source -> source.id?.toUUIDOrNull() == itemId } ?: return Result.failure(PlayerException.UnsupportedContent()) } catch (e: ApiClientException) { @@ -47,10 +47,8 @@ class MediaSourceResolver( // Load additional item info if possible val item = try { - val itemsResponse by itemsApi.getItemsByUserId( - ids = listOf(itemId), - ) - itemsResponse.items?.firstOrNull() + val response by itemsApi.getItemsByUserId(ids = listOf(itemId)) + response.items?.firstOrNull() } catch (e: ApiClientException) { Timber.e(e, "Failed to load item for media source $itemId") null