diff --git a/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/settings/SettingsDownloadsLimitScreen.kt b/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/settings/SettingsDownloadsLimitScreen.kt index a4b0d71a1..69a621132 100644 --- a/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/settings/SettingsDownloadsLimitScreen.kt +++ b/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/settings/SettingsDownloadsLimitScreen.kt @@ -17,26 +17,13 @@ */ package com.infomaniak.swisstransfer.ui.screen.main.settings -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.verticalScroll -import androidx.compose.material3.Scaffold import androidx.compose.material3.Surface import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableIntStateOf -import androidx.compose.runtime.saveable.rememberSaveable -import androidx.compose.runtime.setValue -import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.vector.ImageVector import com.infomaniak.multiplatform_swisstransfer.common.models.DownloadLimit import com.infomaniak.swisstransfer.R -import com.infomaniak.swisstransfer.ui.components.SwissTransferTobAppBar -import com.infomaniak.swisstransfer.ui.components.TopAppBarButton +import com.infomaniak.swisstransfer.ui.screen.main.settings.components.OptionScaffold import com.infomaniak.swisstransfer.ui.screen.main.settings.components.SettingOption -import com.infomaniak.swisstransfer.ui.screen.main.settings.components.SettingTitle -import com.infomaniak.swisstransfer.ui.screen.main.settings.components.SingleSelectOptions import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme import com.infomaniak.swisstransfer.ui.utils.PreviewMobile @@ -46,25 +33,14 @@ fun SettingsDownloadsLimitScreen( navigateBack: (() -> Unit)?, onDownloadLimitChange: (DownloadLimit) -> Unit, ) { - Scaffold(topBar = { - val canDisplayBackButton = navigateBack?.let { TopAppBarButton.backButton(navigateBack) } - SwissTransferTobAppBar(R.string.settingsOptionDownloadLimit, navigationMenu = canDisplayBackButton) - }) { paddingsValue -> - Column( - modifier = Modifier - .verticalScroll(rememberScrollState()) - .padding(paddingsValue), - ) { - SettingTitle(titleRes = R.string.settingsDownloadsLimitTitle) - - var selectedItem by rememberSaveable { mutableIntStateOf(downloadLimit.ordinal) } - SingleSelectOptions(DownloadLimitOption.entries, { selectedItem }, { position -> - selectedItem = position - val selectedDownloadLimit = DownloadLimit.entries[position] - onDownloadLimitChange(selectedDownloadLimit) - }) - } - } + OptionScaffold( + topAppBarTitleRes = R.string.settingsOptionDownloadLimit, + optionTitleRes = R.string.settingsDownloadsLimitTitle, + enumEntries = DownloadLimitOption.entries, + selectedSettingOptionPosition = downloadLimit.ordinal, + setSelectedSettingOptionPosition = { position -> onDownloadLimitChange(DownloadLimit.entries[position]) }, + navigateBack = navigateBack + ) } enum class DownloadLimitOption( diff --git a/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/settings/SettingsEmailLanguageScreen.kt b/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/settings/SettingsEmailLanguageScreen.kt index 3aa88b978..6b9601652 100644 --- a/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/settings/SettingsEmailLanguageScreen.kt +++ b/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/settings/SettingsEmailLanguageScreen.kt @@ -17,27 +17,14 @@ */ package com.infomaniak.swisstransfer.ui.screen.main.settings -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.verticalScroll -import androidx.compose.material3.Scaffold import androidx.compose.material3.Surface import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableIntStateOf -import androidx.compose.runtime.saveable.rememberSaveable -import androidx.compose.runtime.setValue -import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.res.stringResource import com.infomaniak.multiplatform_swisstransfer.common.models.EmailLanguage import com.infomaniak.swisstransfer.R -import com.infomaniak.swisstransfer.ui.components.SwissTransferTobAppBar -import com.infomaniak.swisstransfer.ui.components.TopAppBarButton +import com.infomaniak.swisstransfer.ui.screen.main.settings.components.OptionScaffold import com.infomaniak.swisstransfer.ui.screen.main.settings.components.SettingOption -import com.infomaniak.swisstransfer.ui.screen.main.settings.components.SettingTitle -import com.infomaniak.swisstransfer.ui.screen.main.settings.components.SingleSelectOptions import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme import com.infomaniak.swisstransfer.ui.utils.PreviewMobile @@ -47,25 +34,14 @@ fun SettingsEmailLanguageScreen( navigateBack: (() -> Unit)?, onEmailLanguageChange: (EmailLanguage) -> Unit, ) { - Scaffold(topBar = { - val canDisplayBackButton = navigateBack?.let { TopAppBarButton.backButton(navigateBack) } - SwissTransferTobAppBar(R.string.settingsOptionEmailLanguage, navigationMenu = canDisplayBackButton) - }) { paddingsValue -> - Column( - modifier = Modifier - .verticalScroll(rememberScrollState()) - .padding(paddingsValue), - ) { - SettingTitle(titleRes = R.string.settingsEmailLanguageTitle) - - var selectedItem by rememberSaveable { mutableIntStateOf(emailLanguage.ordinal) } - SingleSelectOptions(EmailLanguageOption.entries, { selectedItem }, { position -> - selectedItem = position - val selectedEmailLanguage = EmailLanguage.entries[position] - onEmailLanguageChange(selectedEmailLanguage) - }) - } - } + OptionScaffold( + topAppBarTitleRes = R.string.settingsOptionEmailLanguage, + optionTitleRes = R.string.settingsEmailLanguageTitle, + enumEntries = EmailLanguageOption.entries, + selectedSettingOptionPosition = emailLanguage.ordinal, + setSelectedSettingOptionPosition = { position -> onEmailLanguageChange(EmailLanguage.entries[position]) }, + navigateBack = navigateBack + ) } enum class EmailLanguageOption( diff --git a/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/settings/SettingsThemeScreen.kt b/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/settings/SettingsThemeScreen.kt index e30770521..87eda75e7 100644 --- a/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/settings/SettingsThemeScreen.kt +++ b/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/settings/SettingsThemeScreen.kt @@ -17,31 +17,18 @@ */ package com.infomaniak.swisstransfer.ui.screen.main.settings -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.verticalScroll -import androidx.compose.material3.Scaffold import androidx.compose.material3.Surface import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableIntStateOf -import androidx.compose.runtime.saveable.rememberSaveable -import androidx.compose.runtime.setValue -import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.res.stringResource import com.infomaniak.multiplatform_swisstransfer.common.models.Theme import com.infomaniak.swisstransfer.R -import com.infomaniak.swisstransfer.ui.components.SwissTransferTobAppBar -import com.infomaniak.swisstransfer.ui.components.TopAppBarButton import com.infomaniak.swisstransfer.ui.images.AppImages.AppIcons import com.infomaniak.swisstransfer.ui.images.icons.CircleBlack import com.infomaniak.swisstransfer.ui.images.icons.CircleBlackAndWhite import com.infomaniak.swisstransfer.ui.images.icons.CircleWhite +import com.infomaniak.swisstransfer.ui.screen.main.settings.components.OptionScaffold import com.infomaniak.swisstransfer.ui.screen.main.settings.components.SettingOption -import com.infomaniak.swisstransfer.ui.screen.main.settings.components.SettingTitle -import com.infomaniak.swisstransfer.ui.screen.main.settings.components.SingleSelectOptions import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme import com.infomaniak.swisstransfer.ui.utils.PreviewMobile @@ -51,25 +38,14 @@ fun SettingsThemeScreen( navigateBack: (() -> Unit)?, onThemeUpdate: (Theme) -> Unit, ) { - Scaffold(topBar = { - val canDisplayBackButton = navigateBack?.let { TopAppBarButton.backButton(navigateBack) } - SwissTransferTobAppBar(R.string.settingsOptionTheme, navigationMenu = canDisplayBackButton) - }) { paddingsValue -> - Column( - modifier = Modifier - .verticalScroll(rememberScrollState()) - .padding(paddingsValue), - ) { - SettingTitle(titleRes = R.string.settingsThemeTitle) - - var selectedItem by rememberSaveable { mutableIntStateOf(theme.ordinal) } - SingleSelectOptions(ThemeOption.entries, { selectedItem }, { position -> - selectedItem = position - val selectedTheme = Theme.entries[position] - onThemeUpdate(selectedTheme) - }) - } - } + OptionScaffold( + topAppBarTitleRes = R.string.settingsOptionTheme, + optionTitleRes = R.string.settingsThemeTitle, + enumEntries = ThemeOption.entries, + selectedSettingOptionPosition = theme.ordinal, + setSelectedSettingOptionPosition = { position -> onThemeUpdate(Theme.entries[position]) }, + navigateBack = navigateBack + ) } enum class ThemeOption( diff --git a/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/settings/SettingsValidityPeriodScreen.kt b/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/settings/SettingsValidityPeriodScreen.kt index d49cc307d..dd344d655 100644 --- a/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/settings/SettingsValidityPeriodScreen.kt +++ b/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/settings/SettingsValidityPeriodScreen.kt @@ -17,27 +17,14 @@ */ package com.infomaniak.swisstransfer.ui.screen.main.settings -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.verticalScroll -import androidx.compose.material3.Scaffold import androidx.compose.material3.Surface import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableIntStateOf -import androidx.compose.runtime.saveable.rememberSaveable -import androidx.compose.runtime.setValue -import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.res.pluralStringResource import com.infomaniak.multiplatform_swisstransfer.common.models.ValidityPeriod import com.infomaniak.swisstransfer.R -import com.infomaniak.swisstransfer.ui.components.SwissTransferTobAppBar -import com.infomaniak.swisstransfer.ui.components.TopAppBarButton +import com.infomaniak.swisstransfer.ui.screen.main.settings.components.OptionScaffold import com.infomaniak.swisstransfer.ui.screen.main.settings.components.SettingOption -import com.infomaniak.swisstransfer.ui.screen.main.settings.components.SettingTitle -import com.infomaniak.swisstransfer.ui.screen.main.settings.components.SingleSelectOptions import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme import com.infomaniak.swisstransfer.ui.utils.PreviewMobile @@ -47,25 +34,14 @@ fun SettingsValidityPeriodScreen( navigateBack: (() -> Unit)?, onValidityPeriodChange: (ValidityPeriod) -> Unit, ) { - Scaffold(topBar = { - val canDisplayBackButton = navigateBack?.let { TopAppBarButton.backButton(navigateBack) } - SwissTransferTobAppBar(R.string.settingsOptionValidityPeriod, navigationMenu = canDisplayBackButton) - }) { paddingsValue -> - Column( - modifier = Modifier - .verticalScroll(rememberScrollState()) - .padding(paddingsValue), - ) { - SettingTitle(titleRes = R.string.settingsValidityPeriodTitle) - - var selectedItem by rememberSaveable { mutableIntStateOf(validityPeriod.ordinal) } - SingleSelectOptions(ValidityPeriodOption.entries, { selectedItem }, { position -> - selectedItem = position - val selectedValidityPeriod = ValidityPeriod.entries[position] - onValidityPeriodChange(selectedValidityPeriod) - }) - } - } + OptionScaffold( + topAppBarTitleRes = R.string.settingsOptionValidityPeriod, + optionTitleRes = R.string.settingsValidityPeriodTitle, + enumEntries = ValidityPeriodOption.entries, + selectedSettingOptionPosition = validityPeriod.ordinal, + setSelectedSettingOptionPosition = { position -> onValidityPeriodChange(ValidityPeriod.entries[position]) }, + navigateBack = navigateBack + ) } enum class ValidityPeriodOption( diff --git a/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/settings/components/OptionScaffold.kt b/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/settings/components/OptionScaffold.kt new file mode 100644 index 000000000..2ae90d55d --- /dev/null +++ b/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/settings/components/OptionScaffold.kt @@ -0,0 +1,62 @@ +/* + * Infomaniak SwissTransfer - Android + * Copyright (C) 2024 Infomaniak Network SA + * + * This program 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. + * + * This program 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 this program. If not, see . + */ +package com.infomaniak.swisstransfer.ui.screen.main.settings.components + +import androidx.annotation.StringRes +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.Scaffold +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableIntStateOf +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import com.infomaniak.swisstransfer.ui.components.SwissTransferTobAppBar +import com.infomaniak.swisstransfer.ui.components.TopAppBarButton + +@Composable +fun OptionScaffold( + @StringRes topAppBarTitleRes: Int, + @StringRes optionTitleRes: Int, + enumEntries: List, + selectedSettingOptionPosition: Int, + setSelectedSettingOptionPosition: (Int) -> Unit, + navigateBack: (() -> Unit)? = null, +) { + Scaffold(topBar = { + val canDisplayBackButton = navigateBack?.let { TopAppBarButton.backButton(navigateBack) } + SwissTransferTobAppBar(topAppBarTitleRes, navigationMenu = canDisplayBackButton) + }) { paddingsValue -> + Column( + modifier = Modifier + .verticalScroll(rememberScrollState()) + .padding(paddingsValue), + ) { + OptionTitle(titleRes = optionTitleRes) + + var selectedItem by rememberSaveable { mutableIntStateOf(selectedSettingOptionPosition) } + SingleSelectOptions(enumEntries, { selectedItem }, { position -> + selectedItem = position + setSelectedSettingOptionPosition(position) + }) + } + } +} diff --git a/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/settings/components/SingleSelectOptions.kt b/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/settings/components/SingleSelectOptions.kt index 27548b433..19442f6d1 100644 --- a/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/settings/components/SingleSelectOptions.kt +++ b/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/settings/components/SingleSelectOptions.kt @@ -69,9 +69,12 @@ private fun SettingOptionItem(item: SettingOption, isSelected: Boolean, onClick: item.icon?.let { Image(imageVector = it, contentDescription = null) Spacer(modifier = Modifier.width(Margin.Medium)) + } ?: run { + // Make sure the items with no icons have the same height as the ones with icons + Spacer(modifier = Modifier.height(Margin.Large)) } - Text(text = item.title(), Modifier.weight(1.0f)) + Text(text = item.title(), Modifier.weight(1.0f), style = SwissTransferTheme.typography.bodyRegular) if (isSelected) Spacer(modifier = Modifier.width(Margin.Medium)) AnimatedVisibility( @@ -105,13 +108,19 @@ private fun SettingOptionItemPreview() { SwissTransferTheme { Surface { Column { - val item = object : SettingOption { + val iconItem = object : SettingOption { override val title: @Composable () -> String = { stringResource(R.string.appName) } override val imageVector: ImageVector = AppIcons.Add override val imageVectorResId = null } - SettingOptionItem(item = item, isSelected = true) {} - SettingOptionItem(item = item, isSelected = false) {} + val textItem = object : SettingOption { + override val title: @Composable () -> String = { stringResource(R.string.appName) } + override val imageVector = null + override val imageVectorResId = null + } + SettingOptionItem(item = iconItem, isSelected = true) {} + SettingOptionItem(item = iconItem, isSelected = false) {} + SettingOptionItem(item = textItem, isSelected = false) {} } } } diff --git a/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/settings/components/SettingTitle.kt b/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/settings/components/Titles.kt similarity index 69% rename from app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/settings/components/SettingTitle.kt rename to app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/settings/components/Titles.kt index d792d1ab4..fbd4b3a03 100644 --- a/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/settings/components/SettingTitle.kt +++ b/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/settings/components/Titles.kt @@ -29,12 +29,26 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import com.infomaniak.swisstransfer.R import com.infomaniak.swisstransfer.ui.theme.Dimens +import com.infomaniak.swisstransfer.ui.theme.Margin import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme @Composable fun SettingTitle(@StringRes titleRes: Int) { + UnpaddedTitle( + Modifier.padding(horizontal = Dimens.SettingHorizontalMargin, vertical = Dimens.SettingVerticalMargin), + titleRes + ) +} + +@Composable +fun OptionTitle(@StringRes titleRes: Int) { + UnpaddedTitle(Modifier.padding(horizontal = Dimens.SettingHorizontalMargin, vertical = Margin.Large), titleRes) +} + +@Composable +private fun UnpaddedTitle(modifier: Modifier, titleRes: Int) { Text( - modifier = Modifier.padding(horizontal = Dimens.SettingHorizontalMargin, vertical = Dimens.SettingVerticalMargin), + modifier = modifier, text = stringResource(id = titleRes), style = SwissTransferTheme.typography.bodySmallRegular, color = SwissTransferTheme.colors.secondaryTextColor, @@ -44,12 +58,23 @@ fun SettingTitle(@StringRes titleRes: Int) { @Preview(name = "Light") @Preview(name = "Dark", uiMode = Configuration.UI_MODE_NIGHT_YES or Configuration.UI_MODE_TYPE_NORMAL) @Composable -private fun SettingTitlePreview() { +private fun OptionTitlePreview() { SwissTransferTheme { Surface { Box { - SettingTitle(titleRes = R.string.appName) + OptionTitle(titleRes = R.string.appName) } } } } + +@Preview(name = "Light") +@Preview(name = "Dark", uiMode = Configuration.UI_MODE_NIGHT_YES or Configuration.UI_MODE_TYPE_NORMAL) +@Composable +private fun SettingTitlePreview() { + SwissTransferTheme { + Surface { + SettingTitle(titleRes = R.string.appName) + } + } +}