diff --git a/app/build.gradle.kts b/app/build.gradle.kts index d336e429b..a4c75305b 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -83,6 +83,8 @@ dependencies { implementation(libs.androidx.adaptive.layout) implementation(libs.androidx.adaptive.navigation) + implementation(libs.swisstransfer.core) + // Compose preview tools implementation(libs.compose.ui.tooling.preview) debugImplementation(libs.compose.ui.tooling) diff --git a/app/src/main/java/com/infomaniak/swisstransfer/di/ApplicationModule.kt b/app/src/main/java/com/infomaniak/swisstransfer/di/ApplicationModule.kt index f31f2dfbe..5c867609e 100644 --- a/app/src/main/java/com/infomaniak/swisstransfer/di/ApplicationModule.kt +++ b/app/src/main/java/com/infomaniak/swisstransfer/di/ApplicationModule.kt @@ -17,11 +17,26 @@ */ package com.infomaniak.swisstransfer.di +import com.infomaniak.multiplatform_swisstransfer.SwissTransferInjection +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.CoroutineScope +import javax.inject.Singleton + +@Module +@InstallIn(SingletonComponent::class) object ApplicationModule { -// @Provides -// @Singleton -// fun providesSwissTransferInjection() { -// // TODO: Implement this method -// } + @Provides + @Singleton + fun providesSwissTransferInjection() = SwissTransferInjection() + + @Provides + @Singleton + fun providesGlobalCoroutineScope(@DefaultDispatcher defaultDispatcher: CoroutineDispatcher): CoroutineScope { + return CoroutineScope(defaultDispatcher) + } } diff --git a/app/src/main/java/com/infomaniak/swisstransfer/ui/MainApplication.kt b/app/src/main/java/com/infomaniak/swisstransfer/ui/MainApplication.kt index 18dcfc5f2..ca2e2f661 100644 --- a/app/src/main/java/com/infomaniak/swisstransfer/ui/MainApplication.kt +++ b/app/src/main/java/com/infomaniak/swisstransfer/ui/MainApplication.kt @@ -18,8 +18,23 @@ package com.infomaniak.swisstransfer.ui import android.app.Application +import com.infomaniak.multiplatform_swisstransfer.SwissTransferInjection import dagger.hilt.android.HiltAndroidApp +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.launch +import javax.inject.Inject @HiltAndroidApp class MainApplication : Application() { + + @Inject + lateinit var swissTransferInjection: SwissTransferInjection + + @Inject + lateinit var globalCoroutineScope: CoroutineScope + + override fun onCreate() { + super.onCreate() + globalCoroutineScope.launch { swissTransferInjection.loadDefaultAccount() } + } } 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 8196cc489..a4b0d71a1 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 @@ -24,10 +24,13 @@ 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 @@ -38,7 +41,11 @@ import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme import com.infomaniak.swisstransfer.ui.utils.PreviewMobile @Composable -fun SettingsDownloadsLimitScreen(navigateBack: (() -> Unit)?) { +fun SettingsDownloadsLimitScreen( + downloadLimit: DownloadLimit, + navigateBack: (() -> Unit)?, + onDownloadLimitChange: (DownloadLimit) -> Unit, +) { Scaffold(topBar = { val canDisplayBackButton = navigateBack?.let { TopAppBarButton.backButton(navigateBack) } SwissTransferTobAppBar(R.string.settingsOptionDownloadLimit, navigationMenu = canDisplayBackButton) @@ -50,13 +57,17 @@ fun SettingsDownloadsLimitScreen(navigateBack: (() -> Unit)?) { ) { SettingTitle(titleRes = R.string.settingsDownloadsLimitTitle) - val (selectedItem, setSelectedItem) = rememberSaveable { mutableIntStateOf(0) } // TODO: Use DataStore or Realm - SingleSelectOptions(DownloadsLimit.entries, { selectedItem }, setSelectedItem) + var selectedItem by rememberSaveable { mutableIntStateOf(downloadLimit.ordinal) } + SingleSelectOptions(DownloadLimitOption.entries, { selectedItem }, { position -> + selectedItem = position + val selectedDownloadLimit = DownloadLimit.entries[position] + onDownloadLimitChange(selectedDownloadLimit) + }) } } } -enum class DownloadsLimit( +enum class DownloadLimitOption( override val title: @Composable () -> String, override val imageVector: ImageVector? = null, override val imageVectorResId: Int? = null, @@ -72,7 +83,11 @@ enum class DownloadsLimit( private fun SettingsThemeScreenPreview() { SwissTransferTheme { Surface { - SettingsDownloadsLimitScreen {} + SettingsDownloadsLimitScreen( + downloadLimit = DownloadLimit.TWOHUNDREDFIFTY, + navigateBack = {}, + onDownloadLimitChange = {}, + ) } } } 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 ca24a4268..3aa88b978 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 @@ -24,11 +24,14 @@ 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 @@ -39,7 +42,11 @@ import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme import com.infomaniak.swisstransfer.ui.utils.PreviewMobile @Composable -fun SettingsEmailLanguageScreen(navigateBack: (() -> Unit)?) { +fun SettingsEmailLanguageScreen( + emailLanguage: EmailLanguage, + navigateBack: (() -> Unit)?, + onEmailLanguageChange: (EmailLanguage) -> Unit, +) { Scaffold(topBar = { val canDisplayBackButton = navigateBack?.let { TopAppBarButton.backButton(navigateBack) } SwissTransferTobAppBar(R.string.settingsOptionEmailLanguage, navigationMenu = canDisplayBackButton) @@ -51,13 +58,17 @@ fun SettingsEmailLanguageScreen(navigateBack: (() -> Unit)?) { ) { SettingTitle(titleRes = R.string.settingsEmailLanguageTitle) - val (selectedItem, setSelectedItem) = rememberSaveable { mutableIntStateOf(0) } // TODO: Use DataStore or Realm - SingleSelectOptions(EmailLanguage.entries, { selectedItem }, setSelectedItem) + var selectedItem by rememberSaveable { mutableIntStateOf(emailLanguage.ordinal) } + SingleSelectOptions(EmailLanguageOption.entries, { selectedItem }, { position -> + selectedItem = position + val selectedEmailLanguage = EmailLanguage.entries[position] + onEmailLanguageChange(selectedEmailLanguage) + }) } } } -enum class EmailLanguage( +enum class EmailLanguageOption( override val title: @Composable () -> String, override val imageVector: ImageVector? = null, override val imageVectorResId: Int? = null, @@ -74,7 +85,11 @@ enum class EmailLanguage( private fun SettingsThemeScreenPreview() { SwissTransferTheme { Surface { - SettingsEmailLanguageScreen {} + SettingsEmailLanguageScreen( + emailLanguage = EmailLanguage.FRENCH, + navigateBack = {}, + onEmailLanguageChange = {}, + ) } } } diff --git a/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/settings/SettingsScreen.kt b/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/settings/SettingsScreen.kt index 4096f9b70..483fb0e5f 100644 --- a/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/settings/SettingsScreen.kt +++ b/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/settings/SettingsScreen.kt @@ -28,7 +28,13 @@ import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.res.pluralStringResource import androidx.compose.ui.res.stringResource +import com.infomaniak.multiplatform_swisstransfer.common.interfaces.appSettings.AppSettings +import com.infomaniak.multiplatform_swisstransfer.common.models.DownloadLimit +import com.infomaniak.multiplatform_swisstransfer.common.models.EmailLanguage +import com.infomaniak.multiplatform_swisstransfer.common.models.Theme +import com.infomaniak.multiplatform_swisstransfer.common.models.ValidityPeriod import com.infomaniak.swisstransfer.BuildConfig import com.infomaniak.swisstransfer.R import com.infomaniak.swisstransfer.ui.components.BrandTobAppBar @@ -45,8 +51,11 @@ import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme import com.infomaniak.swisstransfer.ui.utils.PreviewMobile @Composable -fun SettingsScreen(onItemClick: (SettingsOptionScreens) -> Unit, getSelectedSetting: () -> SettingsOptionScreens?) { - +fun SettingsScreen( + appSettings: AppSettings, + onItemClick: (SettingsOptionScreens) -> Unit, + getSelectedSetting: () -> SettingsOptionScreens?, +) { val selectedSetting = getSelectedSetting() Scaffold(topBar = { BrandTobAppBar() }) { paddingsValue -> @@ -67,7 +76,7 @@ fun SettingsScreen(onItemClick: (SettingsOptionScreens) -> Unit, getSelectedSett titleRes = R.string.settingsOptionTheme, isSelected = { selectedSetting == THEME }, icon = AppIcons.PaintbrushPalette, - description = "TODO", + description = appSettings.theme.getString(), endIcon = CHEVRON, onClick = { onItemClick(THEME) }, ) @@ -86,7 +95,7 @@ fun SettingsScreen(onItemClick: (SettingsOptionScreens) -> Unit, getSelectedSett titleRes = R.string.settingsOptionValidityPeriod, isSelected = { selectedSetting == VALIDITY_PERIOD }, icon = AppIcons.ArrowDownFile, - description = "TODO", + description = appSettings.validityPeriod.getString(), endIcon = CHEVRON, onClick = { onItemClick(VALIDITY_PERIOD) }, ) @@ -94,7 +103,7 @@ fun SettingsScreen(onItemClick: (SettingsOptionScreens) -> Unit, getSelectedSett titleRes = R.string.settingsOptionDownloadLimit, isSelected = { selectedSetting == DOWNLOAD_LIMIT }, icon = AppIcons.Clock, - description = "TODO", + description = appSettings.downloadLimit.getString(), endIcon = CHEVRON, onClick = { onItemClick(DOWNLOAD_LIMIT) }, ) @@ -102,7 +111,7 @@ fun SettingsScreen(onItemClick: (SettingsOptionScreens) -> Unit, getSelectedSett titleRes = R.string.settingsOptionEmailLanguage, isSelected = { selectedSetting == EMAIL_LANGUAGE }, icon = AppIcons.SpeechBubble, - description = "TODO", + description = appSettings.emailLanguage.getString(), endIcon = CHEVRON, onClick = { onItemClick(EMAIL_LANGUAGE) }, ) @@ -137,18 +146,57 @@ fun SettingsScreen(onItemClick: (SettingsOptionScreens) -> Unit, getSelectedSett } } +@Composable +private fun Theme?.getString(): String { + return when (this) { + Theme.SYSTEM -> stringResource(R.string.settingsOptionThemeSystem) + Theme.DARK -> stringResource(R.string.settingsOptionThemeDark) + Theme.LIGHT -> stringResource(R.string.settingsOptionThemeLight) + else -> "" + } +} + +@Composable +private fun ValidityPeriod?.getString(): String { + return this?.value?.toInt()?.let { + pluralStringResource(R.plurals.settingsValidityPeriodValue, it, it) + } ?: "" +} + +@Composable +private fun DownloadLimit?.getString() = this?.value ?: "" + +@Composable +private fun EmailLanguage?.getString(): String { + return when (this) { + EmailLanguage.ENGLISH -> stringResource(R.string.settingsEmailLanguageValueEnglish) + EmailLanguage.FRENCH -> stringResource(R.string.settingsEmailLanguageValueFrench) + EmailLanguage.GERMAN -> stringResource(R.string.settingsEmailLanguageValueGerman) + EmailLanguage.ITALIAN -> stringResource(R.string.settingsEmailLanguageValueItalian) + EmailLanguage.SPANISH -> stringResource(R.string.settingsEmailLanguageValueSpanish) + else -> "" + } +} + enum class SettingsOptionScreens { THEME, NOTIFICATIONS, VALIDITY_PERIOD, DOWNLOAD_LIMIT, EMAIL_LANGUAGE, DISCOVER_INFOMANIAK, SHARE_IDEAS, GIVE_FEEDBACK, } +private class DummyAppSettings( + override var theme: Theme = Theme.SYSTEM, + override var downloadLimit: DownloadLimit = DownloadLimit.TWOHUNDREDFIFTY, + override var emailLanguage: EmailLanguage = EmailLanguage.FRENCH, + override var validityPeriod: ValidityPeriod = ValidityPeriod.THIRTY, +) : AppSettings + @PreviewMobile @Composable private fun SettingsScreenPreview() { SwissTransferTheme { Surface(color = MaterialTheme.colorScheme.background) { - SettingsScreen(onItemClick = {}, getSelectedSetting = { null }) + SettingsScreen(appSettings = DummyAppSettings(), onItemClick = {}, getSelectedSetting = { null }) } } } diff --git a/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/settings/SettingsScreenWrapper.kt b/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/settings/SettingsScreenWrapper.kt index bf2f824b6..432ef5234 100644 --- a/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/settings/SettingsScreenWrapper.kt +++ b/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/settings/SettingsScreenWrapper.kt @@ -36,6 +36,9 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource +import androidx.hilt.navigation.compose.hiltViewModel +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.infomaniak.multiplatform_swisstransfer.common.interfaces.appSettings.AppSettings import com.infomaniak.swisstransfer.R import com.infomaniak.swisstransfer.ui.components.TwoPaneScaffold import com.infomaniak.swisstransfer.ui.screen.main.settings.SettingsOptionScreens.* @@ -44,22 +47,29 @@ import com.infomaniak.swisstransfer.ui.utils.* @OptIn(ExperimentalMaterial3AdaptiveApi::class) @Composable -fun SettingsScreenWrapper(windowAdaptiveInfo: WindowAdaptiveInfo = currentWindowAdaptiveInfo()) { - TwoPaneScaffold( - windowAdaptiveInfo = windowAdaptiveInfo, - listPane = { ListPane(this) }, - detailPane = { DetailPane(this) }, - ) +fun SettingsScreenWrapper( + windowAdaptiveInfo: WindowAdaptiveInfo = currentWindowAdaptiveInfo(), + settingsViewModel: SettingsViewModel = hiltViewModel(), +) { + val appSettings by settingsViewModel.appSettingsFlow.collectAsStateWithLifecycle(null) + appSettings?.let { safeAppSettings -> + TwoPaneScaffold( + windowAdaptiveInfo = windowAdaptiveInfo, + listPane = { ListPane(this, safeAppSettings) }, + detailPane = { DetailPane(safeAppSettings, settingsViewModel, navigator = this) }, + ) + } } @OptIn(ExperimentalMaterial3AdaptiveApi::class) @Composable -private fun ListPane(navigator: ThreePaneScaffoldNavigator) { +private fun ListPane(navigator: ThreePaneScaffoldNavigator, appSettings: AppSettings) { val context = LocalContext.current val aboutURL = stringResource(R.string.urlAbout) val userReportURL = stringResource(R.string.urlUserReportAndroid) SettingsScreen( + appSettings, onItemClick = { item -> when (item) { NOTIFICATIONS -> context.openAppNotificationSettings() @@ -78,7 +88,11 @@ private fun ListPane(navigator: ThreePaneScaffoldNavigator) { +private fun DetailPane( + appSettings: AppSettings, + settingsViewModel: SettingsViewModel, + navigator: ThreePaneScaffoldNavigator, +) { var lastSelectedScreen by rememberSaveable { mutableStateOf(null) } val destination = navigator.currentDestination?.content ?: lastSelectedScreen @@ -88,10 +102,26 @@ private fun DetailPane(navigator: ThreePaneScaffoldNavigator Unit)? = if (navigator.canNavigateBack()) navigateBackCallback else null when (destination) { - THEME -> SettingsThemeScreen(navigateBack) - VALIDITY_PERIOD -> SettingsValidityPeriodScreen(navigateBack) - DOWNLOAD_LIMIT -> SettingsDownloadsLimitScreen(navigateBack) - EMAIL_LANGUAGE -> SettingsEmailLanguageScreen(navigateBack) + THEME -> SettingsThemeScreen( + theme = appSettings.theme, + navigateBack = navigateBack, + onThemeUpdate = settingsViewModel::setTheme, + ) + VALIDITY_PERIOD -> SettingsValidityPeriodScreen( + validityPeriod = appSettings.validityPeriod, + navigateBack = navigateBack, + onValidityPeriodChange = settingsViewModel::setValidityPeriod, + ) + DOWNLOAD_LIMIT -> SettingsDownloadsLimitScreen( + downloadLimit = appSettings.downloadLimit, + navigateBack = navigateBack, + onDownloadLimitChange = settingsViewModel::setDownloadLimit, + ) + EMAIL_LANGUAGE -> SettingsEmailLanguageScreen( + emailLanguage = appSettings.emailLanguage, + navigateBack = navigateBack, + onEmailLanguageChange = settingsViewModel::setEmailLanguage, + ) NOTIFICATIONS, DISCOVER_INFOMANIAK, SHARE_IDEAS, 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 264b41815..e30770521 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 @@ -31,6 +31,7 @@ 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 @@ -45,7 +46,11 @@ import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme import com.infomaniak.swisstransfer.ui.utils.PreviewMobile @Composable -fun SettingsThemeScreen(navigateBack: (() -> Unit)?) { +fun SettingsThemeScreen( + theme: Theme, + navigateBack: (() -> Unit)?, + onThemeUpdate: (Theme) -> Unit, +) { Scaffold(topBar = { val canDisplayBackButton = navigateBack?.let { TopAppBarButton.backButton(navigateBack) } SwissTransferTobAppBar(R.string.settingsOptionTheme, navigationMenu = canDisplayBackButton) @@ -57,8 +62,12 @@ fun SettingsThemeScreen(navigateBack: (() -> Unit)?) { ) { SettingTitle(titleRes = R.string.settingsThemeTitle) - var selectedItem by rememberSaveable { mutableIntStateOf(0) } // TODO: Use DataStore or Realm - SingleSelectOptions(ThemeOption.entries, { selectedItem }, { selectedItem = it }) + var selectedItem by rememberSaveable { mutableIntStateOf(theme.ordinal) } + SingleSelectOptions(ThemeOption.entries, { selectedItem }, { position -> + selectedItem = position + val selectedTheme = Theme.entries[position] + onThemeUpdate(selectedTheme) + }) } } } @@ -78,7 +87,7 @@ enum class ThemeOption( private fun SettingsThemeScreenPreview() { SwissTransferTheme { Surface { - SettingsThemeScreen {} + SettingsThemeScreen(theme = Theme.SYSTEM, navigateBack = {}, onThemeUpdate = {}) } } } diff --git a/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/settings/SettingsDurationValidityScreen.kt b/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/settings/SettingsValidityPeriodScreen.kt similarity index 76% rename from app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/settings/SettingsDurationValidityScreen.kt rename to app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/settings/SettingsValidityPeriodScreen.kt index 97df99f1f..d49cc307d 100644 --- a/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/settings/SettingsDurationValidityScreen.kt +++ b/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/settings/SettingsValidityPeriodScreen.kt @@ -24,11 +24,14 @@ 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 @@ -39,7 +42,11 @@ import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme import com.infomaniak.swisstransfer.ui.utils.PreviewMobile @Composable -fun SettingsValidityPeriodScreen(navigateBack: (() -> Unit)?) { +fun SettingsValidityPeriodScreen( + validityPeriod: ValidityPeriod, + navigateBack: (() -> Unit)?, + onValidityPeriodChange: (ValidityPeriod) -> Unit, +) { Scaffold(topBar = { val canDisplayBackButton = navigateBack?.let { TopAppBarButton.backButton(navigateBack) } SwissTransferTobAppBar(R.string.settingsOptionValidityPeriod, navigationMenu = canDisplayBackButton) @@ -51,13 +58,17 @@ fun SettingsValidityPeriodScreen(navigateBack: (() -> Unit)?) { ) { SettingTitle(titleRes = R.string.settingsValidityPeriodTitle) - val (selectedItem, setSelectedItem) = rememberSaveable { mutableIntStateOf(0) } // TODO: Use DataStore or Realm - SingleSelectOptions(ValidityPeriod.entries, { selectedItem }, setSelectedItem) + var selectedItem by rememberSaveable { mutableIntStateOf(validityPeriod.ordinal) } + SingleSelectOptions(ValidityPeriodOption.entries, { selectedItem }, { position -> + selectedItem = position + val selectedValidityPeriod = ValidityPeriod.entries[position] + onValidityPeriodChange(selectedValidityPeriod) + }) } } } -enum class ValidityPeriod( +enum class ValidityPeriodOption( override val title: @Composable () -> String, override val imageVector: ImageVector? = null, override val imageVectorResId: Int? = null, @@ -73,7 +84,11 @@ enum class ValidityPeriod( private fun SettingsThemeScreenPreview() { SwissTransferTheme { Surface { - SettingsValidityPeriodScreen {} + SettingsValidityPeriodScreen( + validityPeriod = ValidityPeriod.THIRTY, + navigateBack = {}, + onValidityPeriodChange = {}, + ) } } } diff --git a/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/settings/SettingsViewModel.kt b/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/settings/SettingsViewModel.kt new file mode 100644 index 000000000..2f647e85e --- /dev/null +++ b/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/settings/SettingsViewModel.kt @@ -0,0 +1,57 @@ +/* + * 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 + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.infomaniak.multiplatform_swisstransfer.SwissTransferInjection +import com.infomaniak.multiplatform_swisstransfer.common.models.DownloadLimit +import com.infomaniak.multiplatform_swisstransfer.common.models.EmailLanguage +import com.infomaniak.multiplatform_swisstransfer.common.models.Theme +import com.infomaniak.multiplatform_swisstransfer.common.models.ValidityPeriod +import com.infomaniak.swisstransfer.di.IoDispatcher +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.launch +import javax.inject.Inject + +@HiltViewModel +class SettingsViewModel @Inject constructor( + private val swissTransferInjection: SwissTransferInjection, + @IoDispatcher private val ioDispatcher: CoroutineDispatcher, +) : ViewModel() { + private val appSettingsManager inline get() = swissTransferInjection.appSettingsManager + + val appSettingsFlow = appSettingsManager.appSettings + + fun setTheme(theme: Theme) = viewModelScope.launch(ioDispatcher) { + appSettingsManager.setTheme(theme) + } + + fun setValidityPeriod(validityPeriod: ValidityPeriod) = viewModelScope.launch(ioDispatcher) { + appSettingsManager.setValidityPeriod(validityPeriod) + } + + fun setDownloadLimit(downloadLimit: DownloadLimit) = viewModelScope.launch(ioDispatcher) { + appSettingsManager.setDownloadLimit(downloadLimit) + } + + fun setEmailLanguage(emailLanguage: EmailLanguage) = viewModelScope.launch(ioDispatcher) { + appSettingsManager.setEmailLanguage(emailLanguage) + } +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 545482f80..229e2ca7e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -14,6 +14,7 @@ lifecycleRuntimeKtx = "2.8.4" material3Beta = "1.3.0-rc01" navigation = "2.8.0-rc01" serialization = "1.7.1" +swisstransfer = "0.1.1" [libraries] androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" } @@ -21,6 +22,7 @@ androidx-adaptive = { module = "androidx.compose.material3.adaptive:adaptive", v androidx-adaptive-layout = { module = "androidx.compose.material3.adaptive:adaptive-layout", version.ref = "adaptiveLayout" } androidx-adaptive-navigation = { module = "androidx.compose.material3.adaptive:adaptive-navigation", version.ref = "adaptiveLayout" } androidx-constraintlayout-compose = { module = "androidx.constraintlayout:constraintlayout-compose", version.ref = "constraintlayoutCompose" } +swisstransfer-core = { module = "com.github.Infomaniak.multiplatform-SwissTransfer:STCore", version.ref = "swisstransfer" } androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" } compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" } diff --git a/settings.gradle.kts b/settings.gradle.kts index 90211f215..1a80ad33d 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -17,7 +17,9 @@ dependencyResolutionManagement { @Suppress("UnstableApiUsage") repositories { google() + // mavenLocal() // TODO Do not put this in production mavenCentral() + maven { url = uri("https://jitpack.io") } } }