From 6791cd0140c930eb3df74ef08d0d4e6f0e76fd45 Mon Sep 17 00:00:00 2001 From: Lasta apps Date: Sat, 20 Jan 2024 17:20:56 +0200 Subject: [PATCH] feat(dish-lang): Added startup UI --- .../settings/domain/model/DishLanguage.kt | 24 +++ .../features/starting/di/startingModule.kt | 2 + .../ui/component/DishLanguageComponent.kt | 56 ++++++ .../ui/navigation/StartingComponent.kt | 15 ++ .../starting/ui/navigation/StartingContent.kt | 3 + .../starting/ui/screen/DishLanguageScreen.kt | 166 ++++++++++++++++++ .../starting/ui/vm/DishLanguageViewModel.kt | 48 +++++ app/src/main/res/values-cs/strings.xml | 8 +- app/src/main/res/values/strings.xml | 9 +- 9 files changed, 329 insertions(+), 2 deletions(-) create mode 100644 app/src/main/kotlin/cz/lastaapps/menza/features/settings/domain/model/DishLanguage.kt create mode 100644 app/src/main/kotlin/cz/lastaapps/menza/features/starting/ui/component/DishLanguageComponent.kt create mode 100644 app/src/main/kotlin/cz/lastaapps/menza/features/starting/ui/screen/DishLanguageScreen.kt create mode 100644 app/src/main/kotlin/cz/lastaapps/menza/features/starting/ui/vm/DishLanguageViewModel.kt diff --git a/app/src/main/kotlin/cz/lastaapps/menza/features/settings/domain/model/DishLanguage.kt b/app/src/main/kotlin/cz/lastaapps/menza/features/settings/domain/model/DishLanguage.kt new file mode 100644 index 00000000..64c11ba4 --- /dev/null +++ b/app/src/main/kotlin/cz/lastaapps/menza/features/settings/domain/model/DishLanguage.kt @@ -0,0 +1,24 @@ +/* + * 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 . + */ + +package cz.lastaapps.menza.features.settings.domain.model + +internal enum class DishLanguage { + Czech, English +} \ No newline at end of file diff --git a/app/src/main/kotlin/cz/lastaapps/menza/features/starting/di/startingModule.kt b/app/src/main/kotlin/cz/lastaapps/menza/features/starting/di/startingModule.kt index dcfeee15..d86bad0c 100644 --- a/app/src/main/kotlin/cz/lastaapps/menza/features/starting/di/startingModule.kt +++ b/app/src/main/kotlin/cz/lastaapps/menza/features/starting/di/startingModule.kt @@ -22,6 +22,7 @@ package cz.lastaapps.menza.features.starting.di import cz.lastaapps.menza.features.starting.domain.usecase.CheckDataDownloadNeededUC import cz.lastaapps.menza.features.starting.domain.usecase.DownloadInitDataUC import cz.lastaapps.menza.features.starting.ui.vm.AllSetViewModel +import cz.lastaapps.menza.features.starting.ui.vm.DishLanguageViewModel import cz.lastaapps.menza.features.starting.ui.vm.DownloadViewModel import cz.lastaapps.menza.features.starting.ui.vm.PriceTypeViewModel @@ -31,6 +32,7 @@ import org.koin.dsl.module val startingModule = module { factoryOf(::DownloadViewModel) + factoryOf(::DishLanguageViewModel) factoryOf(::AllSetViewModel) factoryOf(::PriceTypeViewModel) diff --git a/app/src/main/kotlin/cz/lastaapps/menza/features/starting/ui/component/DishLanguageComponent.kt b/app/src/main/kotlin/cz/lastaapps/menza/features/starting/ui/component/DishLanguageComponent.kt new file mode 100644 index 00000000..705e685b --- /dev/null +++ b/app/src/main/kotlin/cz/lastaapps/menza/features/starting/ui/component/DishLanguageComponent.kt @@ -0,0 +1,56 @@ +/* + * 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 . + */ + +package cz.lastaapps.menza.features.starting.ui.component + +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import com.arkivanov.decompose.ComponentContext +import cz.lastaapps.menza.features.starting.ui.screen.DishLanguageScreen +import cz.lastaapps.menza.features.starting.ui.vm.DishLanguageViewModel +import cz.lastaapps.menza.ui.theme.Padding.More +import cz.lastaapps.menza.ui.util.getOrCreateKoin +import org.koin.core.component.KoinComponent + +internal interface DishLanguageComponent { + val viewModel: DishLanguageViewModel +} + +internal class DefaultDishLanguageComponent( + componentContext: ComponentContext, +) : DishLanguageComponent, KoinComponent, ComponentContext by componentContext { + override val viewModel: DishLanguageViewModel = getOrCreateKoin() +} + +@Composable +internal fun DishLanguageContent( + component: DishLanguageComponent, + modifier: Modifier = Modifier, + onNext: () -> Unit, +) { + DishLanguageScreen( + onDone = onNext, + viewModel = component.viewModel, + modifier = modifier + .padding(More.Screen) + .fillMaxSize(), + ) +} diff --git a/app/src/main/kotlin/cz/lastaapps/menza/features/starting/ui/navigation/StartingComponent.kt b/app/src/main/kotlin/cz/lastaapps/menza/features/starting/ui/navigation/StartingComponent.kt index fb0b248c..5c914294 100644 --- a/app/src/main/kotlin/cz/lastaapps/menza/features/starting/ui/navigation/StartingComponent.kt +++ b/app/src/main/kotlin/cz/lastaapps/menza/features/starting/ui/navigation/StartingComponent.kt @@ -33,13 +33,16 @@ import cz.lastaapps.menza.features.settings.ui.component.DefaultReorderMenzaComp import cz.lastaapps.menza.features.settings.ui.component.ReorderMenzaComponent import cz.lastaapps.menza.features.starting.ui.component.AllSetComponent import cz.lastaapps.menza.features.starting.ui.component.DefaultAllSetComponent +import cz.lastaapps.menza.features.starting.ui.component.DefaultDishLanguageComponent import cz.lastaapps.menza.features.starting.ui.component.DefaultDownloadComponent import cz.lastaapps.menza.features.starting.ui.component.DefaultPolicyComponent import cz.lastaapps.menza.features.starting.ui.component.DefaultPriceTypeComponent +import cz.lastaapps.menza.features.starting.ui.component.DishLanguageComponent import cz.lastaapps.menza.features.starting.ui.component.DownloadComponent import cz.lastaapps.menza.features.starting.ui.component.PolicyComponent import cz.lastaapps.menza.features.starting.ui.component.PriceTypeComponent import cz.lastaapps.menza.features.starting.ui.navigation.DefaultStartingComponent.Config.AllSet +import cz.lastaapps.menza.features.starting.ui.navigation.DefaultStartingComponent.Config.ChooseDishLanguage import cz.lastaapps.menza.features.starting.ui.navigation.DefaultStartingComponent.Config.ChoosePrice import cz.lastaapps.menza.features.starting.ui.navigation.DefaultStartingComponent.Config.ChooseTheme import cz.lastaapps.menza.features.starting.ui.navigation.DefaultStartingComponent.Config.DownloadData @@ -66,6 +69,9 @@ internal interface StartingComponent { @JvmInline value class ChoosePrice(val component: PriceTypeComponent) : Child + @JvmInline + value class ChooseDishLanguage(val component: DishLanguageComponent) : Child + @JvmInline value class ChooseTheme(val component: AppThemeComponent) : Child @@ -98,6 +104,11 @@ internal class DefaultStartingComponent( when (configuration) { AllSet -> Child.AllSet(DefaultAllSetComponent(componentContext)) ChoosePrice -> Child.ChoosePrice(DefaultPriceTypeComponent(componentContext)) + ChooseDishLanguage -> Child.ChooseDishLanguage( + DefaultDishLanguageComponent( + componentContext, + ), + ) ChooseTheme -> Child.ChooseTheme(DefaultAppThemeComponent(componentContext)) DownloadData -> Child.DownloadData(DefaultDownloadComponent(componentContext)) OrderMenzaList -> Child.OrderMenzaList(DefaultReorderMenzaComponent(componentContext)) @@ -120,6 +131,9 @@ internal class DefaultStartingComponent( @Serializable data object ChoosePrice : Config + @Serializable + data object ChooseDishLanguage : Config + @Serializable data object ChooseTheme : Config @@ -135,6 +149,7 @@ internal class DefaultStartingComponent( DownloadData, ChooseTheme, ChoosePrice, + ChooseDishLanguage, OrderMenzaList, AllSet, ) diff --git a/app/src/main/kotlin/cz/lastaapps/menza/features/starting/ui/navigation/StartingContent.kt b/app/src/main/kotlin/cz/lastaapps/menza/features/starting/ui/navigation/StartingContent.kt index be506bea..2f1989c9 100644 --- a/app/src/main/kotlin/cz/lastaapps/menza/features/starting/ui/navigation/StartingContent.kt +++ b/app/src/main/kotlin/cz/lastaapps/menza/features/starting/ui/navigation/StartingContent.kt @@ -35,10 +35,12 @@ import com.arkivanov.decompose.extensions.compose.subscribeAsState import cz.lastaapps.menza.features.settings.ui.component.AppThemeContent import cz.lastaapps.menza.features.settings.ui.component.ReorderMenzaContent import cz.lastaapps.menza.features.starting.ui.component.AllSetContent +import cz.lastaapps.menza.features.starting.ui.component.DishLanguageContent import cz.lastaapps.menza.features.starting.ui.component.DownloadContent import cz.lastaapps.menza.features.starting.ui.component.PolicyContent import cz.lastaapps.menza.features.starting.ui.component.PriceTypeContent import cz.lastaapps.menza.features.starting.ui.navigation.StartingComponent.Child.AllSet +import cz.lastaapps.menza.features.starting.ui.navigation.StartingComponent.Child.ChooseDishLanguage import cz.lastaapps.menza.features.starting.ui.navigation.StartingComponent.Child.ChoosePrice import cz.lastaapps.menza.features.starting.ui.navigation.StartingComponent.Child.ChooseTheme import cz.lastaapps.menza.features.starting.ui.navigation.StartingComponent.Child.DownloadData @@ -73,6 +75,7 @@ internal fun StartingContent( when (page) { is AllSet -> AllSetContent(page.component, childModifier, onDone) is ChoosePrice -> PriceTypeContent(page.component, childModifier, next) + is ChooseDishLanguage -> DishLanguageContent(page.component, childModifier, next) is ChooseTheme -> AppThemeContent(page.component, next) is DownloadData -> DownloadContent(page.component, hostState, childModifier, next) is OrderMenzaList -> ReorderMenzaContent(page.component, onDone = next) diff --git a/app/src/main/kotlin/cz/lastaapps/menza/features/starting/ui/screen/DishLanguageScreen.kt b/app/src/main/kotlin/cz/lastaapps/menza/features/starting/ui/screen/DishLanguageScreen.kt new file mode 100644 index 00000000..147e89ec --- /dev/null +++ b/app/src/main/kotlin/cz/lastaapps/menza/features/starting/ui/screen/DishLanguageScreen.kt @@ -0,0 +1,166 @@ +/* + * 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 . + */ + +package cz.lastaapps.menza.features.starting.ui.screen + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.IntrinsicSize +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.material3.ElevatedCard +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.Preview +import cz.lastaapps.core.ui.vm.HandleAppear +import cz.lastaapps.core.ui.vm.HandleDismiss +import cz.lastaapps.menza.R +import cz.lastaapps.menza.features.settings.domain.model.DishLanguage +import cz.lastaapps.menza.features.starting.ui.vm.DishLanguageState +import cz.lastaapps.menza.features.starting.ui.vm.DishLanguageViewModel +import cz.lastaapps.menza.ui.theme.AppTheme +import cz.lastaapps.menza.ui.theme.Padding + +@Composable +internal fun DishLanguageScreen( + onDone: () -> Unit, + viewModel: DishLanguageViewModel, + modifier: Modifier = Modifier, +) { + DishLanguageEffects( + viewModel, + onSelected = onDone, + ) + + DishLanguageContent( + onLanguage = { viewModel.selectLanguage(it) }, + modifier = modifier, + ) +} + +@Composable +private fun DishLanguageEffects( + viewModel: DishLanguageViewModel, + onSelected: () -> Unit, +) { + HandleAppear(viewModel) + + HandleDismiss( + viewModel, + DishLanguageState::isSelected, + DishLanguageViewModel::dismissSelected, + onSelected, + ) +} + +@Composable +private fun DishLanguageContent( + onLanguage: (DishLanguage) -> Unit, + modifier: Modifier = Modifier, +) = Box( + modifier = modifier.fillMaxSize(), + contentAlignment = Alignment.Center, +) { + Surface( + shape = MaterialTheme.shapes.large, + color = MaterialTheme.colorScheme.primaryContainer, + ) { + Column( + modifier = Modifier + .padding(Padding.Medium), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy( + Padding.Medium, + Alignment.CenterVertically, + ), + ) { + Text( + text = stringResource(R.string.language_choose_title), + style = MaterialTheme.typography.headlineSmall, + textAlign = TextAlign.Center, + ) + + Text( + text = stringResource(R.string.language_choose_subtitle), + style = MaterialTheme.typography.bodyMedium, + textAlign = TextAlign.Center, + ) + + Column( + modifier = Modifier.width(IntrinsicSize.Max), + verticalArrangement = Arrangement.spacedBy(Padding.Small), + ) { + LanguageButton( + stringResource(R.string.language_choose_czech_title), + stringResource(R.string.language_choose_czech_description), + onClick = { onLanguage(DishLanguage.Czech) }, + modifier = Modifier.fillMaxWidth(), + ) + LanguageButton( + stringResource(R.string.language_choose_english_title), + stringResource(R.string.language_choose_english_description), + onClick = { onLanguage(DishLanguage.English) }, + modifier = Modifier.fillMaxWidth(), + ) + } + } + } +} + +@Composable +private fun LanguageButton( + title: String, + subtitle: String, + onClick: () -> Unit, + modifier: Modifier = Modifier, +) = ElevatedCard(onClick, modifier) { + Column( + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(Padding.Tiny), + modifier = Modifier.padding(Padding.MidSmall), + ) { + Text( + title, + style = MaterialTheme.typography.labelLarge, + textAlign = TextAlign.Center, + ) + Text( + subtitle, + style = MaterialTheme.typography.bodySmall, + textAlign = TextAlign.Center, + ) + } +} + +@Preview +@Composable +private fun DishLanguagePreview() { + AppTheme { + DishLanguageContent(onLanguage = {}) + } +} diff --git a/app/src/main/kotlin/cz/lastaapps/menza/features/starting/ui/vm/DishLanguageViewModel.kt b/app/src/main/kotlin/cz/lastaapps/menza/features/starting/ui/vm/DishLanguageViewModel.kt new file mode 100644 index 00000000..762eb8b5 --- /dev/null +++ b/app/src/main/kotlin/cz/lastaapps/menza/features/starting/ui/vm/DishLanguageViewModel.kt @@ -0,0 +1,48 @@ +/* + * 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 . + */ + +package cz.lastaapps.menza.features.starting.ui.vm + +import cz.lastaapps.core.ui.vm.Appearing +import cz.lastaapps.core.ui.vm.StateViewModel +import cz.lastaapps.core.ui.vm.VMContext +import cz.lastaapps.core.ui.vm.VMState +import cz.lastaapps.menza.features.settings.domain.model.DishLanguage + +internal class DishLanguageViewModel( + context: VMContext, +) : StateViewModel(DishLanguageState(), context), Appearing { + override var hasAppeared: Boolean = false + + override fun onAppeared() { + + } + + fun selectLanguage(language: DishLanguage) { + updateState { copy(isSelected = true) } + } + + fun dismissSelected() { + updateState { copy(isSelected = false) } + } +} + +internal data class DishLanguageState( + val isSelected: Boolean = false, +) : VMState diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 6f10502f..520e26ce 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -1,5 +1,5 @@