Refactor the lifecycle state (#135)
This commit is contained in:
parent
932ea56335
commit
8552f0c469
32 changed files with 180 additions and 177 deletions
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
)
|
||||
)
|
||||
)*/
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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>(UiState.Normal)
|
||||
private val navigateToLogin = MutableSharedFlow<Boolean>()
|
||||
private val _uiState = MutableStateFlow<UiState>(UiState.Normal)
|
||||
val uiState = _uiState.asStateFlow()
|
||||
private val _navigateToLogin = MutableSharedFlow<Boolean>()
|
||||
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)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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>(UiState.Loading)
|
||||
private val _uiState = MutableStateFlow<UiState>(UiState.Loading)
|
||||
val uiState = _uiState.asStateFlow()
|
||||
|
||||
sealed class UiState {
|
||||
data class Normal(val downloadEpisodes: List<DownloadEpisodeItem>) : 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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>(UiState.Loading)
|
||||
private val _uiState = MutableStateFlow<UiState>(UiState.Loading)
|
||||
val uiState = _uiState.asStateFlow()
|
||||
|
||||
sealed class UiState {
|
||||
data class Normal(val downloadSections: List<DownloadSection>) : 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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>(UiState.Loading)
|
||||
private val _uiState = MutableStateFlow<UiState>(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,
|
||||
|
|
|
@ -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>(UiState.Loading)
|
||||
private val _uiState = MutableStateFlow<UiState>(UiState.Loading)
|
||||
val uiState = _uiState.asStateFlow()
|
||||
|
||||
sealed class UiState {
|
||||
data class Normal(val favoriteSections: List<FavoriteSection>) : 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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>(UiState.Loading)
|
||||
private val _uiState = MutableStateFlow<UiState>(UiState.Loading)
|
||||
val uiState = _uiState.asStateFlow()
|
||||
|
||||
sealed class UiState {
|
||||
data class Normal(val homeItems: List<HomeItem>) : 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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>(UiState.Loading)
|
||||
private val _uiState = MutableStateFlow<UiState>(UiState.Loading)
|
||||
val uiState = _uiState.asStateFlow()
|
||||
|
||||
sealed class UiState {
|
||||
data class Normal(val items: Flow<PagingData<BaseItemDto>>) : 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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>(UiState.Normal)
|
||||
private val navigateToMain = MutableSharedFlow<Boolean>()
|
||||
private val _uiState = MutableStateFlow<UiState>(UiState.Normal)
|
||||
val uiState = _uiState.asStateFlow()
|
||||
private val _navigateToMain = MutableSharedFlow<Boolean>()
|
||||
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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>(UiState.Loading)
|
||||
private val _uiState = MutableStateFlow<UiState>(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<BaseItemPerson> = 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,
|
||||
|
|
|
@ -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>(UiState.Loading)
|
||||
private val _uiState = MutableStateFlow<UiState>(UiState.Loading)
|
||||
val uiState = _uiState.asStateFlow()
|
||||
|
||||
sealed class UiState {
|
||||
data class Normal(val collections: List<BaseItemDto>) : 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)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -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>(UiState.Loading)
|
||||
private val _uiState = MutableStateFlow<UiState>(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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>(UiState.Loading)
|
||||
private val _uiState = MutableStateFlow<UiState>(UiState.Loading)
|
||||
val uiState = _uiState.asStateFlow()
|
||||
|
||||
sealed class UiState {
|
||||
data class Normal(val sections: List<FavoriteSection>) : 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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>(UiState.Loading)
|
||||
private val _uiState = MutableStateFlow<UiState>(UiState.Loading)
|
||||
val uiState = _uiState.asStateFlow()
|
||||
|
||||
sealed class UiState {
|
||||
data class Normal(val episodes: List<EpisodeItem>) : 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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<Boolean>(
|
||||
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<Boolean>()
|
||||
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)
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue