mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-07-08 23:51:21 +02:00
Fixes overscrolling on recommended tabs (#881)
## Description If the continue watching row is empty on recommended pages, it would scroll to the first successfully loaded row even if previous ones are still pending. This PR fixes that so the page waits until the right first row is ready. ### Related issues Fixes #839 ### Testing Emulator & shield 2019 ## Screenshots N/A ## AI or LLM usage None
This commit is contained in:
parent
724d4d0da3
commit
6e676b9474
4 changed files with 42 additions and 15 deletions
|
|
@ -37,9 +37,10 @@ import com.github.damontecres.wholphin.ui.nav.Destination
|
|||
import com.github.damontecres.wholphin.util.ApiRequestPager
|
||||
import com.github.damontecres.wholphin.util.HomeRowLoadingState
|
||||
import com.github.damontecres.wholphin.util.LoadingState
|
||||
import kotlinx.coroutines.Deferred
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.launch
|
||||
import org.jellyfin.sdk.model.api.MediaType
|
||||
import java.util.UUID
|
||||
|
||||
|
|
@ -99,13 +100,13 @@ abstract class RecommendedViewModel(
|
|||
abstract fun update(
|
||||
@StringRes title: Int,
|
||||
row: HomeRowLoadingState,
|
||||
)
|
||||
): HomeRowLoadingState
|
||||
|
||||
fun update(
|
||||
@StringRes title: Int,
|
||||
block: suspend () -> List<BaseItem>,
|
||||
) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
): Deferred<HomeRowLoadingState> =
|
||||
viewModelScope.async(Dispatchers.IO) {
|
||||
val titleStr = context.getString(title)
|
||||
val row =
|
||||
try {
|
||||
|
|
@ -115,7 +116,6 @@ abstract class RecommendedViewModel(
|
|||
}
|
||||
update(title, row)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ import dagger.assisted.AssistedFactory
|
|||
import dagger.assisted.AssistedInject
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import kotlinx.coroutines.Deferred
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.firstOrNull
|
||||
|
|
@ -123,6 +124,8 @@ class RecommendedMovieViewModel
|
|||
}
|
||||
}
|
||||
|
||||
val jobs = mutableListOf<Deferred<HomeRowLoadingState>>()
|
||||
|
||||
update(R.string.recently_released) {
|
||||
val request =
|
||||
GetItemsRequest(
|
||||
|
|
@ -138,7 +141,7 @@ class RecommendedMovieViewModel
|
|||
enableTotalRecordCount = false,
|
||||
)
|
||||
GetItemsRequestHandler.execute(api, request).toBaseItems(api, false)
|
||||
}
|
||||
}.also(jobs::add)
|
||||
|
||||
update(R.string.recently_added) {
|
||||
val request =
|
||||
|
|
@ -155,7 +158,7 @@ class RecommendedMovieViewModel
|
|||
enableTotalRecordCount = false,
|
||||
)
|
||||
GetItemsRequestHandler.execute(api, request).toBaseItems(api, false)
|
||||
}
|
||||
}.also(jobs::add)
|
||||
|
||||
update(R.string.top_unwatched) {
|
||||
val request =
|
||||
|
|
@ -173,7 +176,7 @@ class RecommendedMovieViewModel
|
|||
enableTotalRecordCount = false,
|
||||
)
|
||||
GetItemsRequestHandler.execute(api, request).toBaseItems(api, false)
|
||||
}
|
||||
}.also(jobs::add)
|
||||
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
try {
|
||||
|
|
@ -216,8 +219,17 @@ class RecommendedMovieViewModel
|
|||
}
|
||||
}
|
||||
|
||||
// If the continue watching row is empty, then wait until the first successful row
|
||||
// is loaded before telling the UI that the page is loaded
|
||||
if (loading.value == LoadingState.Loading || loading.value == LoadingState.Pending) {
|
||||
loading.setValueOnMain(LoadingState.Success)
|
||||
for (i in 0..<jobs.size) {
|
||||
val result = jobs[i].await()
|
||||
if (result.completed) {
|
||||
Timber.v("First success")
|
||||
loading.setValueOnMain(LoadingState.Success)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -225,10 +237,11 @@ class RecommendedMovieViewModel
|
|||
override fun update(
|
||||
@StringRes title: Int,
|
||||
row: HomeRowLoadingState,
|
||||
) {
|
||||
): HomeRowLoadingState {
|
||||
rows.update { current ->
|
||||
current.toMutableList().apply { set(rowTitles[title]!!, row) }
|
||||
}
|
||||
return row
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ import dagger.assisted.AssistedFactory
|
|||
import dagger.assisted.AssistedInject
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import kotlinx.coroutines.Deferred
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
|
@ -170,6 +171,8 @@ class RecommendedTvShowViewModel
|
|||
}
|
||||
}
|
||||
|
||||
val jobs = mutableListOf<Deferred<HomeRowLoadingState>>()
|
||||
|
||||
update(R.string.recently_released) {
|
||||
val request =
|
||||
GetItemsRequest(
|
||||
|
|
@ -185,7 +188,7 @@ class RecommendedTvShowViewModel
|
|||
enableTotalRecordCount = false,
|
||||
)
|
||||
GetItemsRequestHandler.execute(api, request).toBaseItems(api, true)
|
||||
}
|
||||
}.also(jobs::add)
|
||||
|
||||
update(R.string.recently_added) {
|
||||
val request =
|
||||
|
|
@ -202,7 +205,7 @@ class RecommendedTvShowViewModel
|
|||
enableTotalRecordCount = false,
|
||||
)
|
||||
GetItemsRequestHandler.execute(api, request).toBaseItems(api, true)
|
||||
}
|
||||
}.also(jobs::add)
|
||||
|
||||
update(R.string.top_unwatched) {
|
||||
val request =
|
||||
|
|
@ -220,7 +223,7 @@ class RecommendedTvShowViewModel
|
|||
enableTotalRecordCount = false,
|
||||
)
|
||||
GetItemsRequestHandler.execute(api, request).toBaseItems(api, true)
|
||||
}
|
||||
}.also(jobs::add)
|
||||
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
try {
|
||||
|
|
@ -264,7 +267,14 @@ class RecommendedTvShowViewModel
|
|||
}
|
||||
|
||||
if (loading.value == LoadingState.Loading || loading.value == LoadingState.Pending) {
|
||||
loading.setValueOnMain(LoadingState.Success)
|
||||
for (i in 0..<jobs.size) {
|
||||
val result = jobs[i].await()
|
||||
if (result is HomeRowLoadingState.Success) {
|
||||
Timber.v("First success")
|
||||
loading.setValueOnMain(LoadingState.Success)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -272,10 +282,11 @@ class RecommendedTvShowViewModel
|
|||
override fun update(
|
||||
@StringRes title: Int,
|
||||
row: HomeRowLoadingState,
|
||||
) {
|
||||
): HomeRowLoadingState {
|
||||
rows.update { current ->
|
||||
current.toMutableList().apply { set(rowTitles[title]!!, row) }
|
||||
}
|
||||
return row
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
|||
|
|
@ -48,6 +48,9 @@ sealed interface RowLoadingState {
|
|||
sealed interface HomeRowLoadingState {
|
||||
val title: String
|
||||
|
||||
val completed: Boolean
|
||||
get() = this is Success || this is Error
|
||||
|
||||
data class Pending(
|
||||
override val title: String,
|
||||
) : HomeRowLoadingState
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue