Skip to content

Commit

Permalink
fix: Carousel list not scrollable sometimes, remove animations from list
Browse files Browse the repository at this point in the history
  • Loading branch information
Lastaapps committed Jan 11, 2025
1 parent b6e36af commit 1089f83
Show file tree
Hide file tree
Showing 8 changed files with 262 additions and 227 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2024, Petr Laštovička as Lasta apps, All rights reserved
* Copyright 2025, Petr Laštovička as Lasta apps, All rights reserved
*
* This file is part of Menza.
*
Expand Down Expand Up @@ -73,12 +73,12 @@ class GetTodayDishListUC(
.map { category ->
category.copy(
dishList =
category.dishList
.map { dish ->
ratings[dish.id]?.let {
dish.copy(rating = it)
} ?: dish
}.toImmutableList(),
category.dishList
.map { dish ->
ratings[dish.id]?.let {
dish.copy(rating = it)
} ?: dish
}.toImmutableList(),
)
}.toImmutableList()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ private fun MenzaList(
items(menzaList, key = { it.type.toString() }) { menza ->
MenzaItem(
menza = menza,
selected = selectedMenza == menza,
selected = selectedMenza?.type == menza.type,
onClick = onMenzaSelect,
modifier = Modifier.fillMaxWidth(),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,12 @@ import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridState
import androidx.compose.material3.SnackbarHostState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.saveable.Saver
import androidx.compose.runtime.saveable.listSaver
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.lifecycle.Lifecycle.State.RESUMED
import androidx.lifecycle.compose.LocalLifecycleOwner
import cz.lastaapps.api.core.domain.model.dish.Dish
import cz.lastaapps.menza.features.main.ui.widgets.WrapMenzaNotSelected
import cz.lastaapps.menza.features.settings.domain.model.DishListMode
Expand All @@ -59,7 +56,6 @@ import cz.lastaapps.menza.features.today.ui.widget.TodayDishHorizontal
import cz.lastaapps.menza.features.today.ui.widget.TodayDishList
import cz.lastaapps.menza.ui.theme.Padding
import cz.lastaapps.menza.ui.util.HandleError
import kotlinx.coroutines.flow.collectLatest

@Composable
internal fun DishListScreen(
Expand All @@ -73,14 +69,15 @@ internal fun DishListScreen(
) {
DishListEffects(viewModel, hostState)

val lifecycle = LocalLifecycleOwner.current
LaunchedEffect(lifecycle, viewModel) {
lifecycle.lifecycle.currentStateFlow.collectLatest {
viewModel.setIsResumed(it == RESUMED)
}
}

val state by viewModel.flowState

// resets scroll position when new menza is selected
val scrollStates: ScrollStates =
rememberSaveable(
state.selectedMenza?.getOrNull(),
saver = ScrollStates.Saver,
) { ScrollStates().also { println("Created new state: ${it.carousel.hashCode()}") } }

DishListContent(
state = state,
modifier = modifier,
Expand All @@ -93,6 +90,7 @@ internal fun DishListScreen(
onRating = onRating,
panels = panels,
onOsturak = onOsturak,
scrollStates = scrollStates,
)
}

Expand All @@ -117,13 +115,8 @@ private fun DishListContent(
onOliverRow: (Boolean) -> Unit,
onOsturak: () -> Unit,
onRating: (Dish) -> Unit,
scrollStates: ScrollStates,
modifier: Modifier = Modifier,
// resets scroll position when new menza is selected
scrollStates: ScrollStates =
rememberSaveable(
state.selectedMenza,
saver = ScrollStates.Saver,
) { ScrollStates() },
) {
Column(
modifier = modifier,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2024, Petr Laštovička as Lasta apps, All rights reserved
* Copyright 2025, Petr Laštovička as Lasta apps, All rights reserved
*
* This file is part of Menza.
*
Expand All @@ -20,6 +20,7 @@
package cz.lastaapps.menza.features.today.ui.vm

import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable
import arrow.core.Either.Left
import arrow.core.Either.Right
import arrow.core.Option
Expand All @@ -30,6 +31,7 @@ import cz.lastaapps.api.core.domain.sync.mapSync
import cz.lastaapps.api.main.domain.usecase.GetTodayDishListUC
import cz.lastaapps.api.main.domain.usecase.OpenMenuUC
import cz.lastaapps.api.main.domain.usecase.SyncTodayDishListUC
import cz.lastaapps.core.data.AppInfoProvider
import cz.lastaapps.core.domain.error.DomainError
import cz.lastaapps.core.domain.usecase.IsOnMeteredUC
import cz.lastaapps.core.ui.vm.ErrorHolder
Expand All @@ -54,6 +56,7 @@ import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.mapLatest
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import kotlin.time.Duration.Companion.seconds
Expand All @@ -69,6 +72,7 @@ internal class DishListViewModel(
private val isOnMeteredUC: IsOnMeteredUC,
private val getUserSettingsUC: GetTodayUserSettingsUC,
private val openMenuLinkUC: OpenMenuUC,
private val appInfoProvider: AppInfoProvider,
) : StateViewModel<DishListState>(DishListState(), context),
ErrorHolder {
private val log = localLogger()
Expand Down Expand Up @@ -112,16 +116,17 @@ internal class DishListViewModel(
}.launchIn(scope)

// Refreshes the screen if user is looking at the data for at least 42 seconds
flow
.map {
it.isResumed to it.selectedMenza?.getOrNull()
}.distinctUntilChanged()
.onEach { (resumed, menza) ->
while (resumed && menza != null) {
delay(42.seconds)
load(menza, true)
}
}.launchIn(scope)
if (appInfoProvider.isDebug()) {
flow
.map { it.selectedMenza?.getOrNull() }
.distinctUntilChanged()
.mapLatest { menza ->
while (menza != null) {
delay(42.seconds)
load(menza, true)
}
}.launchIn(scope)
}
}

private var syncJob: Job? = null
Expand Down Expand Up @@ -156,8 +161,6 @@ internal class DishListViewModel(
setOliverRowUC(used)
}

fun setIsResumed(resumed: Boolean) = updateState { copy(isResumed = resumed) }

private suspend fun load(
menza: Menza,
isForced: Boolean,
Expand All @@ -176,15 +179,14 @@ internal class DishListViewModel(
override fun dismissError() = updateState { copy(error = null) }
}

@Immutable
internal data class DishListState(
val isLoading: Boolean = false,
val error: DomainError? = null,
val selectedMenza: Option<Menza>? = null,
val items: ImmutableList<DishCategory> = persistentListOf(),
val userSettings: TodayUserSettings = TodayUserSettings(),
val isOnMetered: Boolean = false,
// is the UI consuming this viewModel is resumed
val isResumed: Boolean = false,
) : VMState {
val showExperimentalWarning: Boolean =
selectedMenza?.getOrNull()?.isExperimental ?: false
Expand Down
Loading

0 comments on commit 1089f83

Please sign in to comment.