From 8552f0c469f671c711aa3f85cf858370bfbea4fa Mon Sep 17 00:00:00 2001 From: Jarne Demeulemeester <32322857+jarnedemeulemeester@users.noreply.github.com> Date: Mon, 25 Jul 2022 12:57:09 +0200 Subject: [PATCH] Refactor the lifecycle state (#135) --- .../jellyfin/fragments/AddServerFragment.kt | 11 +++--- .../jellyfin/fragments/DownloadFragment.kt | 2 +- .../fragments/DownloadSeriesFragment.kt | 2 +- .../fragments/EpisodeBottomSheetFragment.kt | 2 +- .../jellyfin/fragments/FavoriteFragment.kt | 2 +- .../jdtech/jellyfin/fragments/HomeFragment.kt | 2 +- .../jellyfin/fragments/LibraryFragment.kt | 6 +++- .../jellyfin/fragments/LoginFragment.kt | 10 ++++-- .../jellyfin/fragments/MediaFragment.kt | 2 +- .../jellyfin/fragments/MediaInfoFragment.kt | 7 +++- .../fragments/PersonDetailFragment.kt | 7 +++- .../fragments/SearchResultFragment.kt | 7 +++- .../jellyfin/fragments/SeasonFragment.kt | 7 +++- .../fragments/ServerSelectFragment.kt | 2 +- .../dev/jdtech/jellyfin/tv/ui/HomeFragment.kt | 2 +- .../jellyfin/tv/ui/MediaDetailFragment.kt | 6 ++-- .../jellyfin/tv/ui/TvAddServerFragment.kt | 10 ++++-- .../jdtech/jellyfin/tv/ui/TvLoginFragment.kt | 10 ++++-- .../jellyfin/viewmodels/AddServerViewModel.kt | 33 +++++++++--------- .../viewmodels/DownloadSeriesViewModel.kt | 14 ++++---- .../jellyfin/viewmodels/DownloadViewModel.kt | 14 ++++---- .../viewmodels/EpisodeBottomSheetViewModel.kt | 18 +++++----- .../jellyfin/viewmodels/FavoriteViewModel.kt | 17 ++++------ .../jellyfin/viewmodels/HomeViewModel.kt | 15 ++++---- .../jellyfin/viewmodels/LibraryViewModel.kt | 14 ++++---- .../jellyfin/viewmodels/LoginViewModel.kt | 24 ++++++------- .../jellyfin/viewmodels/MediaInfoViewModel.kt | 17 ++++------ .../jellyfin/viewmodels/MediaViewModel.kt | 14 ++++---- .../viewmodels/PersonDetailViewModel.kt | 15 ++++---- .../viewmodels/SearchResultViewModel.kt | 17 ++++------ .../jellyfin/viewmodels/SeasonViewModel.kt | 14 ++++---- .../viewmodels/ServerSelectViewModel.kt | 34 ++++++++----------- 32 files changed, 180 insertions(+), 177 deletions(-) diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/AddServerFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/AddServerFragment.kt index 6015fdfe..b09da829 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/AddServerFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/AddServerFragment.kt @@ -45,8 +45,8 @@ class AddServerFragment : Fragment() { } viewLifecycleOwner.lifecycleScope.launch { - viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.onUiState(viewLifecycleOwner.lifecycleScope) { uiState -> + viewLifecycleOwner.lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.uiState.collect { uiState -> Timber.d("$uiState") when (uiState) { is AddServerViewModel.UiState.Normal -> bindUiStateNormal() @@ -54,8 +54,11 @@ class AddServerFragment : Fragment() { is AddServerViewModel.UiState.Loading -> bindUiStateLoading() } } - viewModel.onNavigateToLogin(viewLifecycleOwner.lifecycleScope) { - Timber.d("Navigate to login: $it") + } + } + viewLifecycleOwner.lifecycleScope.launch { + viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.navigateToLogin.collect { if (it) { navigateToLoginFragment() } diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/DownloadFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/DownloadFragment.kt index 5c4261b3..9da04e86 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/DownloadFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/DownloadFragment.kt @@ -47,7 +47,7 @@ class DownloadFragment : Fragment() { viewLifecycleOwner.lifecycleScope.launch { viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.onUiState(viewLifecycleOwner.lifecycleScope) { uiState -> + viewModel.uiState.collect { uiState -> Timber.d("$uiState") when (uiState) { is DownloadViewModel.UiState.Normal -> bindUiStateNormal(uiState) diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/DownloadSeriesFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/DownloadSeriesFragment.kt index 3adf6d77..c5267254 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/DownloadSeriesFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/DownloadSeriesFragment.kt @@ -51,7 +51,7 @@ class DownloadSeriesFragment : Fragment() { viewLifecycleOwner.lifecycleScope.launch { viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.onUiState(viewLifecycleOwner.lifecycleScope) { uiState -> + viewModel.uiState.collect { uiState -> when (uiState) { is DownloadSeriesViewModel.UiState.Normal -> bindUiStateNormal(uiState) is DownloadSeriesViewModel.UiState.Loading -> bindUiStateLoading(uiState) diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/EpisodeBottomSheetFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/EpisodeBottomSheetFragment.kt index eff6ed0a..3c017234 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/EpisodeBottomSheetFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/EpisodeBottomSheetFragment.kt @@ -60,7 +60,7 @@ class EpisodeBottomSheetFragment : BottomSheetDialogFragment() { viewLifecycleOwner.lifecycleScope.launch { viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.onUiState(viewLifecycleOwner.lifecycleScope) { uiState -> + viewModel.uiState.collect { uiState -> Timber.d("$uiState") when (uiState) { is EpisodeBottomSheetViewModel.UiState.Normal -> bindUiStateNormal(uiState) diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/FavoriteFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/FavoriteFragment.kt index c74ae6d4..963ff445 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/FavoriteFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/FavoriteFragment.kt @@ -46,7 +46,7 @@ class FavoriteFragment : Fragment() { viewLifecycleOwner.lifecycleScope.launch { viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.onUiState(viewLifecycleOwner.lifecycleScope) { uiState -> + viewModel.uiState.collect { uiState -> Timber.d("$uiState") when (uiState) { is FavoriteViewModel.UiState.Normal -> bindUiStateNormal(uiState) diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/HomeFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/HomeFragment.kt index 29b7daa3..d0a9fc01 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/HomeFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/HomeFragment.kt @@ -111,7 +111,7 @@ class HomeFragment : Fragment() { private fun bindState() { viewLifecycleOwner.lifecycleScope.launch { viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.onUiState(viewLifecycleOwner.lifecycleScope) { uiState -> + viewModel.uiState.collect { uiState -> Timber.d("$uiState") when (uiState) { is HomeViewModel.UiState.Normal -> bindUiStateNormal(uiState) diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/LibraryFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/LibraryFragment.kt index a3783f0a..771afffb 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/LibraryFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/LibraryFragment.kt @@ -124,14 +124,18 @@ class LibraryFragment : Fragment() { viewLifecycleOwner.lifecycleScope.launch { viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.onUiState(viewLifecycleOwner.lifecycleScope) { uiState -> + viewModel.uiState.collect { uiState -> when (uiState) { is LibraryViewModel.UiState.Normal -> bindUiStateNormal(uiState) is LibraryViewModel.UiState.Loading -> bindUiStateLoading() is LibraryViewModel.UiState.Error -> bindUiStateError(uiState) } } + } + } + viewLifecycleOwner.lifecycleScope.launch { + viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { // Sorting options val sortBy = SortBy.fromString(sp.getString("sortBy", SortBy.defaultValue.name)!!) val sortOrder = try { diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/LoginFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/LoginFragment.kt index 04a2689f..285fc87f 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/LoginFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/LoginFragment.kt @@ -46,7 +46,7 @@ class LoginFragment : Fragment() { viewLifecycleOwner.lifecycleScope.launch { viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.onUiState(viewLifecycleOwner.lifecycleScope) { uiState -> + viewModel.uiState.collect { uiState -> Timber.d("$uiState") when(uiState) { is LoginViewModel.UiState.Normal -> bindUiStateNormal() @@ -54,8 +54,12 @@ class LoginFragment : Fragment() { is LoginViewModel.UiState.Loading -> bindUiStateLoading() } } - viewModel.onNavigateToMain(viewLifecycleOwner.lifecycleScope) { - Timber.d("Navigate to MainActivity: $it") + } + } + + viewLifecycleOwner.lifecycleScope.launch { + viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.navigateToMain.collect { if (it) { navigateToMainActivity() } diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/MediaFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/MediaFragment.kt index 2635028a..76daa03f 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/MediaFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/MediaFragment.kt @@ -47,7 +47,7 @@ class MediaFragment : Fragment() { viewLifecycleOwner.lifecycleScope.launch { viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.onUiState(viewLifecycleOwner.lifecycleScope) { uiState -> + viewModel.uiState.collect { uiState -> Timber.d("$uiState") when (uiState) { is MediaViewModel.UiState.Normal -> bindUiStateNormal(uiState) diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/MediaInfoFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/MediaInfoFragment.kt index 2ee2a5a7..eb6983cb 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/MediaInfoFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/MediaInfoFragment.kt @@ -61,7 +61,7 @@ class MediaInfoFragment : Fragment() { viewLifecycleOwner.lifecycleScope.launch { viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.onUiState(viewLifecycleOwner.lifecycleScope) { uiState -> + viewModel.uiState.collect { uiState -> Timber.d("$uiState") when (uiState) { is MediaInfoViewModel.UiState.Normal -> bindUiStateNormal(uiState) @@ -69,6 +69,11 @@ class MediaInfoFragment : Fragment() { is MediaInfoViewModel.UiState.Error -> bindUiStateError(uiState) } } + } + } + + viewLifecycleOwner.lifecycleScope.launch { + viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { if (!args.isOffline) { viewModel.loadData(args.itemId, args.itemType) } else { diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/PersonDetailFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/PersonDetailFragment.kt index 862318af..cea77ed4 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/PersonDetailFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/PersonDetailFragment.kt @@ -53,7 +53,7 @@ internal class PersonDetailFragment : Fragment() { viewLifecycleOwner.lifecycleScope.launch { viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.onUiState(viewLifecycleOwner.lifecycleScope) { uiState -> + viewModel.uiState.collect { uiState -> Timber.d("$uiState") when (uiState) { is PersonDetailViewModel.UiState.Normal -> bindUiStateNormal(uiState) @@ -61,6 +61,11 @@ internal class PersonDetailFragment : Fragment() { is PersonDetailViewModel.UiState.Error -> bindUiStateError(uiState) } } + } + } + + viewLifecycleOwner.lifecycleScope.launch { + viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { viewModel.loadData(args.personId) } } diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/SearchResultFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/SearchResultFragment.kt index f02166ff..ece3a79e 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/SearchResultFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/SearchResultFragment.kt @@ -48,7 +48,7 @@ class SearchResultFragment : Fragment() { viewLifecycleOwner.lifecycleScope.launch { viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.onUiState(viewLifecycleOwner.lifecycleScope) { uiState -> + viewModel.uiState.collect { uiState -> Timber.d("$uiState") when (uiState) { is SearchResultViewModel.UiState.Normal -> bindUiStateNormal(uiState) @@ -56,6 +56,11 @@ class SearchResultFragment : Fragment() { is SearchResultViewModel.UiState.Error -> bindUiStateError(uiState) } } + } + } + + viewLifecycleOwner.lifecycleScope.launch { + viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { viewModel.loadData(args.query) } } diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/SeasonFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/SeasonFragment.kt index af81e982..bf24b2a1 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/SeasonFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/SeasonFragment.kt @@ -44,7 +44,7 @@ class SeasonFragment : Fragment() { viewLifecycleOwner.lifecycleScope.launch { viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.onUiState(viewLifecycleOwner.lifecycleScope) { uiState -> + viewModel.uiState.collect { uiState -> Timber.d("$uiState") when (uiState) { is SeasonViewModel.UiState.Normal -> bindUiStateNormal(uiState) @@ -52,6 +52,11 @@ class SeasonFragment : Fragment() { is SeasonViewModel.UiState.Error -> bindUiStateError(uiState) } } + } + } + + viewLifecycleOwner.lifecycleScope.launch { + viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { viewModel.loadEpisodes(args.seriesId, args.seasonId) } } diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/ServerSelectFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/ServerSelectFragment.kt index 0cb77c16..77c7bc39 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/ServerSelectFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/ServerSelectFragment.kt @@ -50,7 +50,7 @@ class ServerSelectFragment : Fragment() { viewLifecycleOwner.lifecycleScope.launch { viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.onNavigateToMain(viewLifecycleOwner.lifecycleScope) { + viewModel.navigateToMain.collect { if (it) { navigateToMainActivity() } diff --git a/app/src/main/java/dev/jdtech/jellyfin/tv/ui/HomeFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/tv/ui/HomeFragment.kt index 885211ba..a956dc81 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/tv/ui/HomeFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/tv/ui/HomeFragment.kt @@ -55,7 +55,7 @@ internal class HomeFragment : BrowseSupportFragment() { viewLifecycleOwner.lifecycleScope.launch { viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.onUiState(viewLifecycleOwner.lifecycleScope) { uiState -> + viewModel.uiState.collect { uiState -> Timber.d("$uiState") when (uiState) { is HomeViewModel.UiState.Normal -> bindUiStateNormal(uiState) diff --git a/app/src/main/java/dev/jdtech/jellyfin/tv/ui/MediaDetailFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/tv/ui/MediaDetailFragment.kt index 48b2ebb1..c8b543e6 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/tv/ui/MediaDetailFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/tv/ui/MediaDetailFragment.kt @@ -63,7 +63,7 @@ internal class MediaDetailFragment : Fragment() { viewLifecycleOwner.lifecycleScope.launch { viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.onUiState(viewLifecycleOwner.lifecycleScope) { uiState -> + viewModel.uiState.collect { uiState -> Timber.d("$uiState") when (uiState) { is MediaInfoViewModel.UiState.Normal -> bindUiStateNormal(uiState) @@ -194,12 +194,12 @@ internal class MediaDetailFragment : Fragment() { false -> { val typedValue = TypedValue() requireActivity().theme.resolveAttribute(R.attr.colorOnSecondaryContainer, typedValue, true) - binding.checkButton.imageTintList = ColorStateList.valueOf( + /*binding.checkButton.imageTintList = ColorStateList.valueOf( resources.getColor( typedValue.resourceId, requireActivity().theme ) - ) + )*/ } } diff --git a/app/src/main/java/dev/jdtech/jellyfin/tv/ui/TvAddServerFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/tv/ui/TvAddServerFragment.kt index ff73cdff..e5aff469 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/tv/ui/TvAddServerFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/tv/ui/TvAddServerFragment.kt @@ -47,7 +47,7 @@ internal class TvAddServerFragment : Fragment() { viewLifecycleOwner.lifecycleScope.launch { viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.onUiState(viewLifecycleOwner.lifecycleScope) { uiState -> + viewModel.uiState.collect { uiState -> Timber.d("$uiState") when (uiState) { is AddServerViewModel.UiState.Normal -> bindUiStateNormal() @@ -55,8 +55,12 @@ internal class TvAddServerFragment : Fragment() { is AddServerViewModel.UiState.Loading -> bindUiStateLoading() } } - viewModel.onNavigateToLogin(viewLifecycleOwner.lifecycleScope) { - Timber.d("Navigate to login: $it") + } + } + + viewLifecycleOwner.lifecycleScope.launch { + viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.navigateToLogin.collect { if (it) { navigateToLoginFragment() } diff --git a/app/src/main/java/dev/jdtech/jellyfin/tv/ui/TvLoginFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/tv/ui/TvLoginFragment.kt index b25e1714..f83e81f1 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/tv/ui/TvLoginFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/tv/ui/TvLoginFragment.kt @@ -46,7 +46,7 @@ class TvLoginFragment : Fragment() { viewLifecycleOwner.lifecycleScope.launch { viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { - viewModel.onUiState(viewLifecycleOwner.lifecycleScope) { uiState -> + viewModel.uiState.collect { uiState -> Timber.d("$uiState") when(uiState) { is LoginViewModel.UiState.Normal -> bindUiStateNormal() @@ -54,8 +54,12 @@ class TvLoginFragment : Fragment() { is LoginViewModel.UiState.Loading -> bindUiStateLoading() } } - viewModel.onNavigateToMain(viewLifecycleOwner.lifecycleScope) { - Timber.d("Navigate to MainActivity: $it") + } + } + + viewLifecycleOwner.lifecycleScope.launch { + viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { + viewModel.navigateToMain.collect { if (it) { navigateToMainActivity() } diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/AddServerViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/AddServerViewModel.kt index 01126d98..99f195d5 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/AddServerViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/AddServerViewModel.kt @@ -2,7 +2,6 @@ package dev.jdtech.jellyfin.viewmodels import android.content.res.Resources import android.widget.Toast -import androidx.lifecycle.LifecycleCoroutineScope import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel @@ -12,6 +11,7 @@ import dev.jdtech.jellyfin.api.JellyfinApi import dev.jdtech.jellyfin.database.Server import dev.jdtech.jellyfin.database.ServerDatabaseDao import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.cancel import kotlinx.coroutines.flow.* import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -31,8 +31,12 @@ constructor( ) : ViewModel() { private val resources: Resources = application.resources - private val uiState = MutableStateFlow(UiState.Normal) - private val navigateToLogin = MutableSharedFlow() + private val _uiState = MutableStateFlow(UiState.Normal) + val uiState = _uiState.asStateFlow() + private val _navigateToLogin = MutableSharedFlow() + val navigateToLogin = _navigateToLogin.asSharedFlow() + + private var serverFound = false sealed class UiState { object Normal : UiState() @@ -40,14 +44,6 @@ constructor( data class Error(val message: String) : UiState() } - fun onUiState(scope: LifecycleCoroutineScope, collector: (UiState) -> Unit) { - scope.launch { uiState.collect { collector(it) } } - } - - fun onNavigateToLogin(scope: LifecycleCoroutineScope, collector: (Boolean) -> Unit) { - scope.launch { navigateToLogin.collect { collector(it) } } - } - /** * Run multiple check on the server before continuing: * @@ -58,7 +54,7 @@ constructor( */ fun checkServer(inputValue: String) { viewModelScope.launch { - uiState.emit(UiState.Loading) + _uiState.emit(UiState.Loading) try { // Check if input value is not empty @@ -78,6 +74,7 @@ constructor( recommended .onCompletion { + if (serverFound) return@onCompletion when { greatServers.isNotEmpty() -> { connectToServer(greatServers.first()) @@ -102,14 +99,18 @@ constructor( } .collect { recommendedServerInfo -> when (recommendedServerInfo.score) { - RecommendedServerInfoScore.GREAT -> greatServers.add(recommendedServerInfo) + RecommendedServerInfoScore.GREAT -> { + serverFound = true + connectToServer(recommendedServerInfo) + this.cancel() + } RecommendedServerInfoScore.GOOD -> goodServers.add(recommendedServerInfo) RecommendedServerInfoScore.OK -> okServers.add(recommendedServerInfo) RecommendedServerInfoScore.BAD -> Unit } } } catch (e: Exception) { - uiState.emit( + _uiState.emit( UiState.Error( e.message ?: resources.getString(R.string.unknown_error) ) @@ -133,8 +134,8 @@ constructor( api.accessToken = null } - uiState.emit(UiState.Normal) - navigateToLogin.emit(true) + _uiState.emit(UiState.Normal) + _navigateToLogin.emit(true) } /** diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/DownloadSeriesViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/DownloadSeriesViewModel.kt index 970fb3ad..20e541ec 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/DownloadSeriesViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/DownloadSeriesViewModel.kt @@ -7,6 +7,7 @@ import dagger.hilt.android.lifecycle.HiltViewModel import dev.jdtech.jellyfin.adapters.DownloadEpisodeItem import dev.jdtech.jellyfin.models.DownloadSeriesMetadata import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch import javax.inject.Inject @@ -14,7 +15,8 @@ import javax.inject.Inject class DownloadSeriesViewModel @Inject constructor() : ViewModel() { - private val uiState = MutableStateFlow(UiState.Loading) + private val _uiState = MutableStateFlow(UiState.Loading) + val uiState = _uiState.asStateFlow() sealed class UiState { data class Normal(val downloadEpisodes: List) : UiState() @@ -22,17 +24,13 @@ constructor() : ViewModel() { data class Error(val error: Exception) : UiState() } - fun onUiState(scope: LifecycleCoroutineScope, collector: (UiState) -> Unit) { - scope.launch { uiState.collect { collector(it) } } - } - fun loadEpisodes(seriesMetadata: DownloadSeriesMetadata) { viewModelScope.launch { - uiState.emit(UiState.Loading) + _uiState.emit(UiState.Loading) try { - uiState.emit(UiState.Normal(getEpisodes((seriesMetadata)))) + _uiState.emit(UiState.Normal(getEpisodes((seriesMetadata)))) } catch (e: Exception) { - uiState.emit(UiState.Error(e)) + _uiState.emit(UiState.Error(e)) } } } diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/DownloadViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/DownloadViewModel.kt index d547b1af..13f1df85 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/DownloadViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/DownloadViewModel.kt @@ -9,6 +9,7 @@ import dev.jdtech.jellyfin.models.PlayerItem import dev.jdtech.jellyfin.utils.loadDownloadedEpisodes import kotlinx.coroutines.* import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch import org.jellyfin.sdk.model.api.BaseItemKind import java.util.* @@ -20,7 +21,8 @@ class DownloadViewModel constructor( private val downloadDatabase: DownloadDatabaseDao, ) : ViewModel() { - private val uiState = MutableStateFlow(UiState.Loading) + private val _uiState = MutableStateFlow(UiState.Loading) + val uiState = _uiState.asStateFlow() sealed class UiState { data class Normal(val downloadSections: List) : UiState() @@ -28,17 +30,13 @@ constructor( data class Error(val error: Exception) : UiState() } - fun onUiState(scope: LifecycleCoroutineScope, collector: (UiState) -> Unit) { - scope.launch { uiState.collect { collector(it) } } - } - init { loadData() } fun loadData() { viewModelScope.launch { - uiState.emit(UiState.Loading) + _uiState.emit(UiState.Loading) try { val items = loadDownloadedEpisodes(downloadDatabase) @@ -70,9 +68,9 @@ constructor( ) } } - uiState.emit(UiState.Normal(downloadSections)) + _uiState.emit(UiState.Normal(downloadSections)) } catch (e: Exception) { - uiState.emit(UiState.Error(e)) + _uiState.emit(UiState.Error(e)) } } } diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/EpisodeBottomSheetViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/EpisodeBottomSheetViewModel.kt index e09bb8e1..a052c370 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/EpisodeBottomSheetViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/EpisodeBottomSheetViewModel.kt @@ -10,6 +10,7 @@ import dev.jdtech.jellyfin.models.PlayerItem import dev.jdtech.jellyfin.repository.JellyfinRepository import dev.jdtech.jellyfin.utils.* import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch import org.jellyfin.sdk.api.client.exception.ApiClientException import org.jellyfin.sdk.model.DateTime @@ -29,7 +30,8 @@ constructor( private val jellyfinRepository: JellyfinRepository, private val downloadDatabase: DownloadDatabaseDao ) : ViewModel() { - private val uiState = MutableStateFlow(UiState.Loading) + private val _uiState = MutableStateFlow(UiState.Loading) + val uiState = _uiState.asStateFlow() sealed class UiState { data class Normal( @@ -48,10 +50,6 @@ constructor( data class Error(val error: Exception) : UiState() } - fun onUiState(scope: LifecycleCoroutineScope, collector: (UiState) -> Unit) { - scope.launch { uiState.collect { collector(it) } } - } - var item: BaseItemDto? = null private var runTime: String = "" private var dateString: String = "" @@ -67,7 +65,7 @@ constructor( fun loadEpisode(episodeId: UUID) { viewModelScope.launch { - uiState.emit(UiState.Loading) + _uiState.emit(UiState.Loading) try { val tempItem = jellyfinRepository.getItem(episodeId) item = tempItem @@ -77,7 +75,7 @@ constructor( favorite = tempItem.userData?.isFavorite == true canDownload = tempItem.canDownload == true downloaded = isItemDownloaded(downloadDatabase, episodeId) - uiState.emit( + _uiState.emit( UiState.Normal( tempItem, runTime, @@ -91,19 +89,19 @@ constructor( ) ) } catch (e: Exception) { - uiState.emit(UiState.Error(e)) + _uiState.emit(UiState.Error(e)) } } } fun loadEpisode(playerItem: PlayerItem) { viewModelScope.launch { - uiState.emit(UiState.Loading) + _uiState.emit(UiState.Loading) playerItems.add(playerItem) item = downloadMetadataToBaseItemDto(playerItem.item!!) available = isItemAvailable(playerItem.itemId) Timber.d("Available: $available") - uiState.emit( + _uiState.emit( UiState.Normal( item!!, runTime, diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/FavoriteViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/FavoriteViewModel.kt index a45344e8..9f00790d 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/FavoriteViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/FavoriteViewModel.kt @@ -1,6 +1,5 @@ package dev.jdtech.jellyfin.viewmodels -import androidx.lifecycle.LifecycleCoroutineScope import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel @@ -8,6 +7,7 @@ import dev.jdtech.jellyfin.models.FavoriteSection import dev.jdtech.jellyfin.repository.JellyfinRepository import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import org.jellyfin.sdk.model.api.BaseItemKind @@ -20,7 +20,8 @@ class FavoriteViewModel constructor( private val jellyfinRepository: JellyfinRepository ) : ViewModel() { - private val uiState = MutableStateFlow(UiState.Loading) + private val _uiState = MutableStateFlow(UiState.Loading) + val uiState = _uiState.asStateFlow() sealed class UiState { data class Normal(val favoriteSections: List) : UiState() @@ -28,22 +29,18 @@ constructor( data class Error(val error: Exception) : UiState() } - fun onUiState(scope: LifecycleCoroutineScope, collector: (UiState) -> Unit) { - scope.launch { uiState.collect { collector(it) } } - } - init { loadData() } fun loadData() { viewModelScope.launch { - uiState.emit(UiState.Loading) + _uiState.emit(UiState.Loading) try { val items = jellyfinRepository.getFavoriteItems() if (items.isEmpty()) { - uiState.emit(UiState.Normal(emptyList())) + _uiState.emit(UiState.Normal(emptyList())) return@launch } @@ -76,9 +73,9 @@ constructor( } } - uiState.emit(UiState.Normal(favoriteSections)) + _uiState.emit(UiState.Normal(favoriteSections)) } catch (e: Exception) { - uiState.emit(UiState.Error(e)) + _uiState.emit(UiState.Error(e)) } } } diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/HomeViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/HomeViewModel.kt index bbdc7f9a..991ca534 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/HomeViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/HomeViewModel.kt @@ -1,7 +1,6 @@ package dev.jdtech.jellyfin.viewmodels import android.app.Application -import androidx.lifecycle.LifecycleCoroutineScope import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel @@ -17,6 +16,7 @@ import dev.jdtech.jellyfin.utils.syncPlaybackProgress import dev.jdtech.jellyfin.utils.toView import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import java.util.* @@ -28,7 +28,8 @@ class HomeViewModel @Inject internal constructor( private val repository: JellyfinRepository, private val downloadDatabase: DownloadDatabaseDao, ) : ViewModel() { - private val uiState = MutableStateFlow(UiState.Loading) + private val _uiState = MutableStateFlow(UiState.Loading) + val uiState = _uiState.asStateFlow() sealed class UiState { data class Normal(val homeItems: List) : UiState() @@ -36,10 +37,6 @@ class HomeViewModel @Inject internal constructor( data class Error(val error: Exception) : UiState() } - fun onUiState(scope: LifecycleCoroutineScope, collector: (UiState) -> Unit) { - scope.launch { uiState.collect { collector(it) } } - } - init { loadData(updateCapabilities = true) } @@ -48,7 +45,7 @@ class HomeViewModel @Inject internal constructor( private fun loadData(updateCapabilities: Boolean) { viewModelScope.launch { - uiState.emit(UiState.Loading) + _uiState.emit(UiState.Loading) try { if (updateCapabilities) repository.postCapabilities() @@ -57,9 +54,9 @@ class HomeViewModel @Inject internal constructor( withContext(Dispatchers.Default) { syncPlaybackProgress(downloadDatabase, repository) } - uiState.emit(UiState.Normal(updated)) + _uiState.emit(UiState.Normal(updated)) } catch (e: Exception) { - uiState.emit(UiState.Error(e)) + _uiState.emit(UiState.Error(e)) } } } diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/LibraryViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/LibraryViewModel.kt index 372072cb..946f4306 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/LibraryViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/LibraryViewModel.kt @@ -7,6 +7,7 @@ import dev.jdtech.jellyfin.repository.JellyfinRepository import dev.jdtech.jellyfin.utils.SortBy import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch import org.jellyfin.sdk.model.api.BaseItemDto import org.jellyfin.sdk.model.api.BaseItemKind @@ -21,7 +22,8 @@ class LibraryViewModel constructor( private val jellyfinRepository: JellyfinRepository ) : ViewModel() { - private val uiState = MutableStateFlow(UiState.Loading) + private val _uiState = MutableStateFlow(UiState.Loading) + val uiState = _uiState.asStateFlow() sealed class UiState { data class Normal(val items: Flow>) : UiState() @@ -29,10 +31,6 @@ constructor( data class Error(val error: Exception) : UiState() } - fun onUiState(scope: LifecycleCoroutineScope, collector: (UiState) -> Unit) { - scope.launch { uiState.collect { collector(it) } } - } - fun loadItems( parentId: UUID, libraryType: String?, @@ -46,7 +44,7 @@ constructor( else -> null } viewModelScope.launch { - uiState.emit(UiState.Loading) + _uiState.emit(UiState.Loading) try { val items = jellyfinRepository.getItemsPaging( @@ -56,9 +54,9 @@ constructor( sortBy = sortBy, sortOrder = sortOrder ) - uiState.emit(UiState.Normal(items)) + _uiState.emit(UiState.Normal(items)) } catch (e: Exception) { - uiState.emit(UiState.Error(e)) + _uiState.emit(UiState.Error(e)) } } } diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/LoginViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/LoginViewModel.kt index b58687c3..ece3d085 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/LoginViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/LoginViewModel.kt @@ -12,6 +12,8 @@ import dev.jdtech.jellyfin.database.ServerDatabaseDao import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asSharedFlow +import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import org.jellyfin.sdk.model.api.AuthenticateUserByName @@ -30,8 +32,10 @@ constructor( ) : ViewModel() { private val resources: Resources = application.resources - private val uiState = MutableStateFlow(UiState.Normal) - private val navigateToMain = MutableSharedFlow() + private val _uiState = MutableStateFlow(UiState.Normal) + val uiState = _uiState.asStateFlow() + private val _navigateToMain = MutableSharedFlow() + val navigateToMain = _navigateToMain.asSharedFlow() sealed class UiState { object Normal : UiState() @@ -39,14 +43,6 @@ constructor( data class Error(val message: String) : UiState() } - fun onUiState(scope: LifecycleCoroutineScope, collector: (UiState) -> Unit) { - scope.launch { uiState.collect { collector(it) } } - } - - fun onNavigateToMain(scope: LifecycleCoroutineScope, collector: (Boolean) -> Unit) { - scope.launch { navigateToMain.collect { collector(it) } } - } - /** * Send a authentication request to the Jellyfin server * @@ -55,7 +51,7 @@ constructor( */ fun login(username: String, password: String) { viewModelScope.launch { - uiState.emit(UiState.Loading) + _uiState.emit(UiState.Loading) try { val authenticationResult by jellyfinApi.userApi.authenticateUserByName( @@ -87,15 +83,15 @@ constructor( userId = authenticationResult.user?.id } - uiState.emit(UiState.Normal) - navigateToMain.emit(true) + _uiState.emit(UiState.Normal) + _navigateToMain.emit(true) } catch (e: Exception) { Timber.e(e) val message = if (e.cause?.message?.contains("401") == true) resources.getString(R.string.login_error_wrong_username_password) else resources.getString( R.string.unknown_error ) - uiState.emit(UiState.Error(message)) + _uiState.emit(UiState.Error(message)) } } } diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/MediaInfoViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/MediaInfoViewModel.kt index 788d1d3c..7cd12a86 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/MediaInfoViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/MediaInfoViewModel.kt @@ -2,7 +2,6 @@ package dev.jdtech.jellyfin.viewmodels import android.app.Application import android.net.Uri -import androidx.lifecycle.LifecycleCoroutineScope import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel @@ -13,6 +12,7 @@ import dev.jdtech.jellyfin.repository.JellyfinRepository import dev.jdtech.jellyfin.utils.* import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import org.jellyfin.sdk.api.client.exception.ApiClientException @@ -31,7 +31,8 @@ constructor( private val jellyfinRepository: JellyfinRepository, private val downloadDatabase: DownloadDatabaseDao, ) : ViewModel() { - private val uiState = MutableStateFlow(UiState.Loading) + private val _uiState = MutableStateFlow(UiState.Loading) + val uiState = _uiState.asStateFlow() sealed class UiState { data class Normal( @@ -56,10 +57,6 @@ constructor( data class Error(val error: Exception) : UiState() } - fun onUiState(scope: LifecycleCoroutineScope, collector: (UiState) -> Unit) { - scope.launch { uiState.collect { collector(it) } } - } - var item: BaseItemDto? = null private var actors: List = emptyList() private var director: BaseItemPerson? = null @@ -83,7 +80,7 @@ constructor( fun loadData(itemId: UUID, itemType: BaseItemKind) { viewModelScope.launch { - uiState.emit(UiState.Loading) + _uiState.emit(UiState.Loading) try { val tempItem = jellyfinRepository.getItem(itemId) item = tempItem @@ -102,7 +99,7 @@ constructor( nextUp = getNextUp(itemId) seasons = jellyfinRepository.getSeasons(itemId) } - uiState.emit( + _uiState.emit( UiState.Normal( tempItem, actors, @@ -122,7 +119,7 @@ constructor( ) ) } catch (e: Exception) { - uiState.emit(UiState.Error(e)) + _uiState.emit(UiState.Error(e)) } } } @@ -142,7 +139,7 @@ constructor( played = tempItem.userData?.played ?: false favorite = tempItem.userData?.isFavorite ?: false available = isItemAvailable(tempItem.id) - uiState.emit( + _uiState.emit( UiState.Normal( tempItem, actors, diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/MediaViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/MediaViewModel.kt index 0fd2fed7..cff7b51f 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/MediaViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/MediaViewModel.kt @@ -5,6 +5,7 @@ import dagger.hilt.android.lifecycle.HiltViewModel import dev.jdtech.jellyfin.models.CollectionType import dev.jdtech.jellyfin.repository.JellyfinRepository import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch import org.jellyfin.sdk.model.api.BaseItemDto import javax.inject.Inject @@ -16,7 +17,8 @@ constructor( private val jellyfinRepository: JellyfinRepository ) : ViewModel() { - private val uiState = MutableStateFlow(UiState.Loading) + private val _uiState = MutableStateFlow(UiState.Loading) + val uiState = _uiState.asStateFlow() sealed class UiState { data class Normal(val collections: List) : UiState() @@ -24,24 +26,20 @@ constructor( data class Error(val error: Exception) : UiState() } - fun onUiState(scope: LifecycleCoroutineScope, collector: (UiState) -> Unit) { - scope.launch { uiState.collect { collector(it) } } - } - init { loadData() } fun loadData() { viewModelScope.launch { - uiState.emit(UiState.Loading) + _uiState.emit(UiState.Loading) try { val items = jellyfinRepository.getItems() val collections = items.filter { collection -> CollectionType.unsupportedCollections.none { it.type == collection.collectionType } } - uiState.emit(UiState.Normal(collections)) + _uiState.emit(UiState.Normal(collections)) } catch (e: Exception) { - uiState.emit( + _uiState.emit( UiState.Error(e) ) } diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/PersonDetailViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/PersonDetailViewModel.kt index 7f8bbe12..57dedf99 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/PersonDetailViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/PersonDetailViewModel.kt @@ -1,11 +1,11 @@ package dev.jdtech.jellyfin.viewmodels -import androidx.lifecycle.LifecycleCoroutineScope import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel import dev.jdtech.jellyfin.repository.JellyfinRepository import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch import org.jellyfin.sdk.model.api.BaseItemDto import org.jellyfin.sdk.model.api.BaseItemKind @@ -17,7 +17,8 @@ internal class PersonDetailViewModel @Inject internal constructor( private val jellyfinRepository: JellyfinRepository ) : ViewModel() { - private val uiState = MutableStateFlow(UiState.Loading) + private val _uiState = MutableStateFlow(UiState.Loading) + val uiState = _uiState.asStateFlow() sealed class UiState { data class Normal(val data: PersonOverview, val starredIn: StarredIn) : UiState() @@ -25,13 +26,9 @@ internal class PersonDetailViewModel @Inject internal constructor( data class Error(val error: Exception) : UiState() } - fun onUiState(scope: LifecycleCoroutineScope, collector: (UiState) -> Unit) { - scope.launch { uiState.collect { collector(it) } } - } - fun loadData(personId: UUID) { viewModelScope.launch { - uiState.emit(UiState.Loading) + _uiState.emit(UiState.Loading) try { val personDetail = jellyfinRepository.getItem(personId) @@ -52,9 +49,9 @@ internal class PersonDetailViewModel @Inject internal constructor( val starredIn = StarredIn(movies, shows) - uiState.emit(UiState.Normal(data, starredIn)) + _uiState.emit(UiState.Normal(data, starredIn)) } catch (e: Exception) { - uiState.emit(UiState.Error(e)) + _uiState.emit(UiState.Error(e)) } } } diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/SearchResultViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/SearchResultViewModel.kt index a857db39..5b9dd2e0 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/SearchResultViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/SearchResultViewModel.kt @@ -1,6 +1,5 @@ package dev.jdtech.jellyfin.viewmodels -import androidx.lifecycle.LifecycleCoroutineScope import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel @@ -8,6 +7,7 @@ import dev.jdtech.jellyfin.models.FavoriteSection import dev.jdtech.jellyfin.repository.JellyfinRepository import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import org.jellyfin.sdk.model.api.BaseItemKind @@ -20,7 +20,8 @@ class SearchResultViewModel constructor( private val jellyfinRepository: JellyfinRepository ) : ViewModel() { - private val uiState = MutableStateFlow(UiState.Loading) + private val _uiState = MutableStateFlow(UiState.Loading) + val uiState = _uiState.asStateFlow() sealed class UiState { data class Normal(val sections: List) : UiState() @@ -28,18 +29,14 @@ constructor( data class Error(val error: Exception) : UiState() } - fun onUiState(scope: LifecycleCoroutineScope, collector: (UiState) -> Unit) { - scope.launch { uiState.collect { collector(it) } } - } - fun loadData(query: String) { viewModelScope.launch { - uiState.emit(UiState.Loading) + _uiState.emit(UiState.Loading) try { val items = jellyfinRepository.getSearchItems(query) if (items.isEmpty()) { - uiState.emit(UiState.Normal(emptyList())) + _uiState.emit(UiState.Normal(emptyList())) return@launch } @@ -72,9 +69,9 @@ constructor( } } - uiState.emit(UiState.Normal(sections)) + _uiState.emit(UiState.Normal(sections)) } catch (e: Exception) { - uiState.emit(UiState.Error(e)) + _uiState.emit(UiState.Error(e)) } } } diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/SeasonViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/SeasonViewModel.kt index dc0b4e92..cf4207ad 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/SeasonViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/SeasonViewModel.kt @@ -5,6 +5,7 @@ import dagger.hilt.android.lifecycle.HiltViewModel import dev.jdtech.jellyfin.adapters.EpisodeItem import dev.jdtech.jellyfin.repository.JellyfinRepository import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch import org.jellyfin.sdk.model.api.ItemFields import java.util.* @@ -16,7 +17,8 @@ class SeasonViewModel constructor( private val jellyfinRepository: JellyfinRepository ) : ViewModel() { - private val uiState = MutableStateFlow(UiState.Loading) + private val _uiState = MutableStateFlow(UiState.Loading) + val uiState = _uiState.asStateFlow() sealed class UiState { data class Normal(val episodes: List) : UiState() @@ -24,18 +26,14 @@ constructor( data class Error(val error: Exception) : UiState() } - fun onUiState(scope: LifecycleCoroutineScope, collector: (UiState) -> Unit) { - scope.launch { uiState.collect { collector(it) } } - } - fun loadEpisodes(seriesId: UUID, seasonId: UUID) { viewModelScope.launch { - uiState.emit(UiState.Loading) + _uiState.emit(UiState.Loading) try { val episodes = getEpisodes(seriesId, seasonId) - uiState.emit(UiState.Normal(episodes)) + _uiState.emit(UiState.Normal(episodes)) } catch (e: Exception) { - uiState.emit(UiState.Error(e)) + _uiState.emit(UiState.Error(e)) } } } diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/ServerSelectViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/ServerSelectViewModel.kt index 194c4fee..ab578c50 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/ServerSelectViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/ServerSelectViewModel.kt @@ -1,7 +1,6 @@ package dev.jdtech.jellyfin.viewmodels import android.content.SharedPreferences -import androidx.lifecycle.LifecycleCoroutineScope import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel @@ -9,8 +8,8 @@ import dev.jdtech.jellyfin.api.JellyfinApi import dev.jdtech.jellyfin.database.Server import dev.jdtech.jellyfin.database.ServerDatabaseDao import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.channels.BufferOverflow import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.asSharedFlow import kotlinx.coroutines.launch import java.util.* import javax.inject.Inject @@ -25,15 +24,8 @@ constructor( ) : ViewModel() { val servers = database.getAllServers() - private val navigateToMain = MutableSharedFlow( - replay = 0, - extraBufferCapacity = 1, - onBufferOverflow = BufferOverflow.DROP_OLDEST - ) - - fun onNavigateToMain(scope: LifecycleCoroutineScope, collector: (Boolean) -> Unit) { - scope.launch { navigateToMain.collect { collector(it) } } - } + private val _navigateToMain = MutableSharedFlow() + val navigateToMain = _navigateToMain.asSharedFlow() /** * Delete server from database @@ -47,16 +39,18 @@ constructor( } fun connectToServer(server: Server) { - val spEdit = sharedPreferences.edit() - spEdit.putString("selectedServer", server.id) - spEdit.apply() + viewModelScope.launch { + val spEdit = sharedPreferences.edit() + spEdit.putString("selectedServer", server.id) + spEdit.apply() - jellyfinApi.apply { - api.baseUrl = server.address - api.accessToken = server.accessToken - userId = UUID.fromString(server.userId) + jellyfinApi.apply { + api.baseUrl = server.address + api.accessToken = server.accessToken + userId = UUID.fromString(server.userId) + } + + _navigateToMain.emit(true) } - - navigateToMain.tryEmit(true) } } \ No newline at end of file