Skip to content

Commit

Permalink
refactor: Separate UI setting into a separate object
Browse files Browse the repository at this point in the history
  • Loading branch information
Lastaapps committed Jan 28, 2024
1 parent bb1a8a8 commit 72c96b0
Show file tree
Hide file tree
Showing 8 changed files with 229 additions and 192 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@

package cz.lastaapps.menza.features.today.di

import cz.lastaapps.menza.features.today.domain.usecase.GetTodayUserSettingsUC
import cz.lastaapps.menza.features.today.ui.vm.DishListViewModel
import cz.lastaapps.menza.features.today.ui.vm.TodayViewModel
import org.koin.core.module.dsl.factoryOf

import org.koin.dsl.module

val todayModule = module {
factoryOf(::DishListViewModel)
factoryOf(::TodayViewModel)

factoryOf(::GetTodayUserSettingsUC)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright 2024, Petr Laštovička as Lasta apps, All rights reserved
*
* This file is part of Menza.
*
* Menza is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Menza is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Menza. If not, see <https://www.gnu.org/licenses/>.
*/

package cz.lastaapps.menza.features.today.domain.model

import cz.lastaapps.menza.features.settings.domain.model.DishLanguage
import cz.lastaapps.menza.features.settings.domain.model.DishListMode
import cz.lastaapps.menza.features.settings.domain.model.PriceType
import cz.lastaapps.menza.features.settings.domain.model.PriceType.Unset

internal data class TodayUserSettings(
val dishListMode: DishListMode? = null,
val useOliverRow: Boolean = false,
val priceType: PriceType = Unset,
val downloadOnMetered: Boolean = false,
val language: DishLanguage = DishLanguage.Czech,
val imageScale: Float = 1f,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* Copyright 2024, Petr Laštovička as Lasta apps, All rights reserved
*
* This file is part of Menza.
*
* Menza is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Menza is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Menza. If not, see <https://www.gnu.org/licenses/>.
*/

package cz.lastaapps.menza.features.today.domain.usecase

import cz.lastaapps.core.domain.UCContext
import cz.lastaapps.core.domain.UseCase
import cz.lastaapps.menza.features.settings.domain.usecase.GetDishLanguageUC
import cz.lastaapps.menza.features.settings.domain.usecase.GetDishListModeUC
import cz.lastaapps.menza.features.settings.domain.usecase.GetImageScaleUC
import cz.lastaapps.menza.features.settings.domain.usecase.GetImagesOnMeteredUC
import cz.lastaapps.menza.features.settings.domain.usecase.GetOliverRow
import cz.lastaapps.menza.features.settings.domain.usecase.GetPriceTypeUC
import cz.lastaapps.menza.features.today.domain.model.TodayUserSettings
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.channelFlow
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.update

internal class GetTodayUserSettingsUC(
context: UCContext,
private val getOliverRowUC: GetOliverRow,
private val getPriceTypeUC: GetPriceTypeUC,
private val getImagesOnMeteredUC: GetImagesOnMeteredUC,
private val getImageScaleUC: GetImageScaleUC,
private val getDishLanguageUC: GetDishLanguageUC,
private val getDishListModeUC: GetDishListModeUC,
) : UseCase(context) {
operator fun invoke(): Flow<TodayUserSettings> = channelFlow {
val state = MutableStateFlow(TodayUserSettings())

fun updateState(block: TodayUserSettings.() -> TodayUserSettings) =
state.update(block)

getPriceTypeUC().onEach {
updateState { copy(priceType = it) }
}.launchIn(this)

getImagesOnMeteredUC().onEach {
updateState { copy(downloadOnMetered = it) }
}.launchIn(this)

getImageScaleUC().onEach {
updateState { copy(imageScale = it) }
}.launchIn(this)

getDishLanguageUC().onEach {
updateState { copy(language = it) }
}.launchIn(this)

getDishListModeUC().onEach {
updateState { copy(dishListMode = it) }
}.launchIn(this)

getOliverRowUC().onEach {
updateState { copy(useOliverRow = it) }
}.launchIn(this)

state.collect { send(it) }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

package cz.lastaapps.menza.features.today.ui.screen

import androidx.compose.animation.Crossfade
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
Expand Down Expand Up @@ -99,17 +100,19 @@ private fun DishListContent(
scrollGridState: LazyStaggeredGridState,
modifier: Modifier = Modifier,
) {
val userSettings = state.userSettings

Column {
val gridSwitch: @Composable () -> Unit = {
CompactViewSwitch(
currentMode = state.dishListMode,
currentMode = userSettings.dishListMode,
onCompactChange = onViewMode,
modifier = Modifier.fillMaxWidth(),
)
}
val imageSizeSetting: @Composable () -> Unit = {
ImageSizeSetting(
progress = state.imageScale,
progress = userSettings.imageScale,
onProgressChanged = onImageScale,
modifier = Modifier.fillMaxWidth(),
)
Expand All @@ -125,75 +128,72 @@ private fun DishListContent(
}
}

when (state.dishListMode) {
COMPACT ->
TodayDishList(
isLoading = state.isLoading,
onRefresh = onRefresh,
data = state.items,
onNoItems = onNoItems,
onDishSelected = onDishSelected,
priceType = state.priceType,
downloadOnMetered = state.downloadOnMetered,
language = state.language,
imageScale = state.imageScale,
isOnMetered = state.isOnMetered,
header = header,
footer = {
Column(
verticalArrangement = Arrangement.spacedBy(Padding.MidSmall),
modifier = Modifier.fillMaxWidth(),
) {
gridSwitch()
Crossfade(
targetState = userSettings.dishListMode,
label = "dish_list_mode_router",
) { dishListMode ->
when (dishListMode) {
COMPACT ->
TodayDishList(
isLoading = state.isLoading,
onRefresh = onRefresh,
data = state.items,
onNoItems = onNoItems,
onDishSelected = onDishSelected,
userSettings = userSettings,
isOnMetered = state.isOnMetered,
header = header,
footer = {
Column(
verticalArrangement = Arrangement.spacedBy(Padding.MidSmall),
modifier = Modifier.fillMaxWidth(),
) {
gridSwitch()

OutlinedCard(modifier = Modifier.padding(horizontal = Padding.MidSmall)) {
Box(modifier = Modifier.padding(Padding.Medium)) {
imageSizeSetting()
OutlinedCard(modifier = Modifier.padding(horizontal = Padding.MidSmall)) {
Box(modifier = Modifier.padding(Padding.Medium)) {
imageSizeSetting()
}
}
}
}
},
modifier = modifier.fillMaxSize(),
scroll = scrollListState,
)
},
modifier = modifier.fillMaxSize(),
scroll = scrollListState,
)

GRID ->
TodayDishGrid(
isLoading = state.isLoading,
onRefresh = onRefresh,
data = state.items,
onNoItems = onNoItems,
onDishSelected = onDishSelected,
priceType = state.priceType,
downloadOnMetered = state.downloadOnMetered,
language = state.language,
isOnMetered = state.isOnMetered,
header = header,
footer = gridSwitch,
modifier = modifier.fillMaxSize(),
scrollGrid = scrollGridState,
)
GRID ->
TodayDishGrid(
isLoading = state.isLoading,
onRefresh = onRefresh,
data = state.items,
onNoItems = onNoItems,
onDishSelected = onDishSelected,
userSettings = userSettings,
isOnMetered = state.isOnMetered,
header = header,
footer = gridSwitch,
modifier = modifier.fillMaxSize(),
scrollGrid = scrollGridState,
)

HORIZONTAL ->
TodayDishHorizontal(
isLoading = state.isLoading,
onRefresh = onRefresh,
data = state.items,
onNoItems = onNoItems,
onDishSelected = onDishSelected,
useOliverRow = state.useOliverRow,
priceType = state.priceType,
downloadOnMetered = state.downloadOnMetered,
language = state.language,
isOnMetered = state.isOnMetered,
onOliverRow = onOliverRow,
header = header,
footer = gridSwitch,
modifier = modifier.fillMaxSize(),
scroll = scrollListState,
)
HORIZONTAL ->
TodayDishHorizontal(
isLoading = state.isLoading,
onRefresh = onRefresh,
data = state.items,
onNoItems = onNoItems,
onDishSelected = onDishSelected,
userSettings = userSettings,
isOnMetered = state.isOnMetered,
onOliverRow = onOliverRow,
header = header,
footer = gridSwitch,
modifier = modifier.fillMaxSize(),
scroll = scrollListState,
)

null -> {}
null -> {}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,19 +39,12 @@ import cz.lastaapps.core.ui.vm.VMContext
import cz.lastaapps.core.ui.vm.VMState
import cz.lastaapps.core.util.extensions.localLogger
import cz.lastaapps.menza.features.main.domain.usecase.GetSelectedMenzaUC
import cz.lastaapps.menza.features.settings.domain.model.DishLanguage
import cz.lastaapps.menza.features.settings.domain.model.DishListMode
import cz.lastaapps.menza.features.settings.domain.model.PriceType
import cz.lastaapps.menza.features.settings.domain.model.PriceType.Unset
import cz.lastaapps.menza.features.settings.domain.usecase.GetDishLanguageUC
import cz.lastaapps.menza.features.settings.domain.usecase.GetDishListModeUC
import cz.lastaapps.menza.features.settings.domain.usecase.GetImageScaleUC
import cz.lastaapps.menza.features.settings.domain.usecase.GetImagesOnMeteredUC
import cz.lastaapps.menza.features.settings.domain.usecase.GetOliverRow
import cz.lastaapps.menza.features.settings.domain.usecase.GetPriceTypeUC
import cz.lastaapps.menza.features.settings.domain.usecase.SetDishListModeUC
import cz.lastaapps.menza.features.settings.domain.usecase.SetImageScaleUC
import cz.lastaapps.menza.features.settings.domain.usecase.SetOliverRow
import cz.lastaapps.menza.features.today.domain.model.TodayUserSettings
import cz.lastaapps.menza.features.today.domain.usecase.GetTodayUserSettingsUC
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.Job
Expand All @@ -65,16 +58,11 @@ internal class DishListViewModel(
private val getSelectedMenzaUC: GetSelectedMenzaUC,
private val getTodayDishListUC: GetTodayDishListUC,
private val syncTodayDishListUC: SyncTodayDishListUC,
private val getOliverRowUC: GetOliverRow,
private val setOliverRowUC: SetOliverRow,
private val getPriceTypeUC: GetPriceTypeUC,
private val getImagesOnMeteredUC: GetImagesOnMeteredUC,
private val getImageScaleUC: GetImageScaleUC,
private val setImageScaleUC: SetImageScaleUC,
private val getDishLanguageUC: GetDishLanguageUC,
private val getDishListModeUC: GetDishListModeUC,
private val setDishListModeUC: SetDishListModeUC,
private val isOnMeteredUC: IsOnMeteredUC,
private val getUserSettingsUC: GetTodayUserSettingsUC,
private val openMenuLinkUC: OpenMenuUC,
) : StateViewModel<DishListState>(DishListState(), context), Appearing, ErrorHolder {
override var hasAppeared: Boolean = false
Expand Down Expand Up @@ -106,33 +94,12 @@ internal class DishListViewModel(
}
}

getPriceTypeUC().onEach {
updateState { copy(priceType = it) }
getUserSettingsUC().onEach {
updateState { copy(userSettings = it) }
}.launchInVM()

getImagesOnMeteredUC().onEach {
updateState { copy(downloadOnMetered = it) }
}.launchInVM()

getImageScaleUC().onEach {
updateState { copy(imageScale = it) }
}.launchInVM()

getDishLanguageUC().onEach {
updateState { copy(language = it) }
}.launchInVM()

getDishListModeUC().onEach {
updateState { copy(dishListMode = it) }
}.launchInVM()

isOnMeteredUC().onEach {
updateState { copy(isOnMetered = it) }
}.launchInVM()

getOliverRowUC().onEach {
updateState { copy(useOliverRow = it) }
}.launchInVM()
}

private var syncJob: Job? = null
Expand Down Expand Up @@ -177,15 +144,10 @@ internal class DishListViewModel(

internal data class DishListState(
val isLoading: Boolean = false,
val dishListMode: DishListMode? = null,
val error: DomainError? = null,
val selectedMenza: Option<Menza>? = null,
val items: ImmutableList<DishCategory> = persistentListOf(),
val useOliverRow: Boolean = false,
val priceType: PriceType = Unset,
val downloadOnMetered: Boolean = false,
val language: DishLanguage = DishLanguage.Czech,
val imageScale: Float = 1f,
val userSettings: TodayUserSettings = TodayUserSettings(),
val isOnMetered: Boolean = false,
) : VMState {
val showExperimentalWarning: Boolean =
Expand Down
Loading

0 comments on commit 72c96b0

Please sign in to comment.