mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-07-08 15:50:16 +02:00
Fix focusing before loading on recommended pages (#220)
Basically now will wait until a row is loaded before sending the focus request
This commit is contained in:
parent
b7cb6efc4f
commit
c5a5345f6c
3 changed files with 83 additions and 39 deletions
|
|
@ -12,7 +12,7 @@ import com.github.damontecres.wholphin.services.FavoriteWatchManager
|
|||
import com.github.damontecres.wholphin.services.NavigationManager
|
||||
import com.github.damontecres.wholphin.ui.SlimItemFields
|
||||
import com.github.damontecres.wholphin.ui.data.RowColumn
|
||||
import com.github.damontecres.wholphin.ui.launchIO
|
||||
import com.github.damontecres.wholphin.ui.setValueOnMain
|
||||
import com.github.damontecres.wholphin.util.ApiRequestPager
|
||||
import com.github.damontecres.wholphin.util.ExceptionHandler
|
||||
import com.github.damontecres.wholphin.util.GetItemsRequestHandler
|
||||
|
|
@ -26,6 +26,8 @@ import dagger.assisted.AssistedInject
|
|||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.awaitAll
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
|
|
@ -95,8 +97,8 @@ class RecommendedMovieViewModel
|
|||
),
|
||||
)
|
||||
|
||||
withContext(Dispatchers.Main) {
|
||||
loading.value = LoadingState.Success
|
||||
if (resumeItems.isNotEmpty()) {
|
||||
loading.setValueOnMain(LoadingState.Success)
|
||||
}
|
||||
} catch (ex: Exception) {
|
||||
Timber.e(ex, "Exception fetching movie recommendations")
|
||||
|
|
@ -159,23 +161,31 @@ class RecommendedMovieViewModel
|
|||
R.string.suggestions to suggestedItems,
|
||||
R.string.top_unwatched to unwatchedTopRatedItems,
|
||||
)
|
||||
|
||||
rows.forEachIndexed { index, (title, pager) ->
|
||||
viewModelScope.launchIO {
|
||||
val title = context.getString(title)
|
||||
val result =
|
||||
try {
|
||||
pager.init()
|
||||
if (pager.isNotEmpty()) {
|
||||
pager.getBlocking(0)
|
||||
rows
|
||||
.mapIndexed { index, (title, pager) ->
|
||||
viewModelScope.async(Dispatchers.IO + ExceptionHandler()) {
|
||||
val title = context.getString(title)
|
||||
val result =
|
||||
try {
|
||||
pager.init()
|
||||
if (pager.isNotEmpty()) {
|
||||
pager.getBlocking(0)
|
||||
}
|
||||
HomeRowLoadingState.Success(title, pager)
|
||||
} catch (ex: Exception) {
|
||||
Timber.e(ex, "Error fetching %s", title)
|
||||
HomeRowLoadingState.Error(title, null, ex)
|
||||
}
|
||||
HomeRowLoadingState.Success(title, pager)
|
||||
} catch (ex: Exception) {
|
||||
Timber.e(ex, "Error fetching %s", title)
|
||||
HomeRowLoadingState.Error(title, null, ex)
|
||||
update(index + 1, result)
|
||||
if (result is HomeRowLoadingState.Success && result.items.isNotEmpty() &&
|
||||
(loading.value == LoadingState.Loading || loading.value == LoadingState.Pending)
|
||||
) {
|
||||
loading.setValueOnMain(LoadingState.Success)
|
||||
}
|
||||
update(index + 1, result)
|
||||
}
|
||||
}
|
||||
}.awaitAll()
|
||||
if (loading.value == LoadingState.Loading || loading.value == LoadingState.Pending) {
|
||||
loading.setValueOnMain(LoadingState.Success)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import com.github.damontecres.wholphin.services.FavoriteWatchManager
|
|||
import com.github.damontecres.wholphin.services.NavigationManager
|
||||
import com.github.damontecres.wholphin.ui.SlimItemFields
|
||||
import com.github.damontecres.wholphin.ui.data.RowColumn
|
||||
import com.github.damontecres.wholphin.ui.launchIO
|
||||
import com.github.damontecres.wholphin.ui.setValueOnMain
|
||||
import com.github.damontecres.wholphin.util.ApiRequestPager
|
||||
import com.github.damontecres.wholphin.util.ExceptionHandler
|
||||
import com.github.damontecres.wholphin.util.GetItemsRequestHandler
|
||||
|
|
@ -27,6 +27,8 @@ import dagger.assisted.AssistedInject
|
|||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.awaitAll
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
|
|
@ -123,8 +125,8 @@ class RecommendedTvShowViewModel
|
|||
),
|
||||
)
|
||||
|
||||
withContext(Dispatchers.Main) {
|
||||
loading.value = LoadingState.Success
|
||||
if (resumeItems.isNotEmpty() || nextUpItems.isNotEmpty()) {
|
||||
loading.setValueOnMain(LoadingState.Success)
|
||||
}
|
||||
} catch (ex: Exception) {
|
||||
Timber.e(ex, "Exception fetching tv recommendations")
|
||||
|
|
@ -188,19 +190,31 @@ class RecommendedTvShowViewModel
|
|||
R.string.top_unwatched to unwatchedTopRatedItems,
|
||||
)
|
||||
|
||||
rows.forEachIndexed { index, (title, pager) ->
|
||||
viewModelScope.launchIO {
|
||||
val title = context.getString(title)
|
||||
val result =
|
||||
try {
|
||||
pager.init()
|
||||
HomeRowLoadingState.Success(title, pager)
|
||||
} catch (ex: Exception) {
|
||||
Timber.e(ex, "Error fetching %s", title)
|
||||
HomeRowLoadingState.Error(title, null, ex)
|
||||
rows
|
||||
.mapIndexed { index, (title, pager) ->
|
||||
viewModelScope.async(Dispatchers.IO + ExceptionHandler()) {
|
||||
val title = context.getString(title)
|
||||
val result =
|
||||
try {
|
||||
pager.init()
|
||||
if (pager.isNotEmpty()) {
|
||||
pager.getBlocking(0)
|
||||
}
|
||||
HomeRowLoadingState.Success(title, pager)
|
||||
} catch (ex: Exception) {
|
||||
Timber.e(ex, "Error fetching %s", title)
|
||||
HomeRowLoadingState.Error(title, null, ex)
|
||||
}
|
||||
update(index + 2, result)
|
||||
if (result is HomeRowLoadingState.Success && result.items.isNotEmpty() &&
|
||||
(loading.value == LoadingState.Loading || loading.value == LoadingState.Pending)
|
||||
) {
|
||||
loading.setValueOnMain(LoadingState.Success)
|
||||
}
|
||||
update(index + 2, result)
|
||||
}
|
||||
}
|
||||
}.awaitAll()
|
||||
if (loading.value == LoadingState.Loading || loading.value == LoadingState.Pending) {
|
||||
loading.setValueOnMain(LoadingState.Success)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -197,8 +197,20 @@ fun HomePageContent(
|
|||
loadingState: LoadingState? = null,
|
||||
) {
|
||||
val scope = rememberCoroutineScope()
|
||||
val firstRow =
|
||||
remember {
|
||||
homeRows
|
||||
.indexOfFirst {
|
||||
when (it) {
|
||||
is HomeRowLoadingState.Error -> false
|
||||
is HomeRowLoadingState.Loading -> true
|
||||
is HomeRowLoadingState.Pending -> true
|
||||
is HomeRowLoadingState.Success -> it.items.isNotEmpty()
|
||||
}
|
||||
}.coerceAtLeast(0)
|
||||
}
|
||||
var position by rememberSaveable(stateSaver = RowColumnSaver) {
|
||||
mutableStateOf(RowColumn(0, 0))
|
||||
mutableStateOf(RowColumn(firstRow, 0))
|
||||
}
|
||||
var focusedItem =
|
||||
position.let {
|
||||
|
|
@ -208,11 +220,19 @@ fun HomePageContent(
|
|||
val listState = rememberLazyListState()
|
||||
val focusRequester = remember { FocusRequester() }
|
||||
val positionFocusRequester = remember { FocusRequester() }
|
||||
LaunchedEffect(Unit) {
|
||||
positionFocusRequester.tryRequestFocus()
|
||||
// Hacky, but mostly works
|
||||
delay(50)
|
||||
listState.animateScrollToItem(position.row)
|
||||
var focused by remember { mutableStateOf(false) }
|
||||
LaunchedEffect(homeRows) {
|
||||
if (!focused) {
|
||||
homeRows
|
||||
.indexOfFirst { it is HomeRowLoadingState.Success && it.items.isNotEmpty() }
|
||||
.takeIf { it >= 0 }
|
||||
?.let {
|
||||
positionFocusRequester.tryRequestFocus()
|
||||
delay(50)
|
||||
listState.animateScrollToItem(position.row)
|
||||
focused = true
|
||||
}
|
||||
}
|
||||
}
|
||||
LaunchedEffect(position) {
|
||||
listState.animateScrollToItem(position.row)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue