diff --git a/app/src/main/java/com/infomaniak/swisstransfer/ui/components/LargeButton.kt b/app/src/main/java/com/infomaniak/swisstransfer/ui/components/LargeButton.kt index 516e75ccc..962c61a59 100644 --- a/app/src/main/java/com/infomaniak/swisstransfer/ui/components/LargeButton.kt +++ b/app/src/main/java/com/infomaniak/swisstransfer/ui/components/LargeButton.kt @@ -80,6 +80,12 @@ enum class ButtonType(val buttonColors: @Composable () -> ButtonColors) { contentColor = SwissTransferTheme.materialColors.primary, ) }), + ERROR({ + ButtonDefaults.buttonColors( + containerColor = SwissTransferTheme.materialColors.error, + contentColor = SwissTransferTheme.materialColors.onError, + ) + }), } @Preview(name = "Light") diff --git a/app/src/main/java/com/infomaniak/swisstransfer/ui/components/SwissTransferBottomSheet.kt b/app/src/main/java/com/infomaniak/swisstransfer/ui/components/SwissTransferBottomSheet.kt new file mode 100644 index 000000000..aee96ec75 --- /dev/null +++ b/app/src/main/java/com/infomaniak/swisstransfer/ui/components/SwissTransferBottomSheet.kt @@ -0,0 +1,148 @@ +/* + * 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.components + +import android.content.res.Configuration +import androidx.annotation.StringRes +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.* +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.infomaniak.swisstransfer.R +import com.infomaniak.swisstransfer.ui.icons.AppIcons +import com.infomaniak.swisstransfer.ui.icons.illu.ArrowCurvedDownright +import com.infomaniak.swisstransfer.ui.theme.Margin +import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun SwissTransferBottomSheet( + modifier: Modifier = Modifier, + onDismissRequest: () -> Unit, + imageVector: ImageVector? = null, + @StringRes titleRes: Int, + @StringRes descriptionRes: Int? = null, + content: @Composable (() -> Unit)? = null, + topButton: @Composable ((Modifier) -> Unit)? = null, + bottomButton: @Composable ((Modifier) -> Unit)? = null, +) { + ModalBottomSheet( + modifier = modifier, + onDismissRequest = onDismissRequest, + ) { + BottomSheetContent( + imageVector = imageVector, + titleRes = titleRes, + descriptionRes = descriptionRes, + content = content, + topButton = topButton, + bottomButton = bottomButton, + ) + } +} +@Composable +private fun BottomSheetContent( + imageVector: ImageVector?, + titleRes: Int, + descriptionRes: Int?, + content: @Composable (() -> Unit)?, + topButton: @Composable ((Modifier) -> Unit)? = null, + bottomButton: @Composable ((Modifier) -> Unit)? = null, +) { + Column( + modifier = Modifier + .fillMaxWidth() + .verticalScroll(rememberScrollState()), + horizontalAlignment = Alignment.CenterHorizontally + ) { + imageVector?.let { + Icon(imageVector = imageVector, contentDescription = null) + Spacer(modifier = Modifier.height(Margin.Large)) + } + + Text( + text = stringResource(titleRes), + style = SwissTransferTheme.typography.bodyMedium, + color = SwissTransferTheme.colors.primaryTextColor, + ) + Spacer(modifier = Modifier.height(Margin.Large)) + + descriptionRes?.let { + Text( + text = stringResource(it), + style = SwissTransferTheme.typography.bodyRegular, + color = SwissTransferTheme.colors.secondaryTextColor, + ) + Spacer(modifier = Modifier.height(Margin.Large)) + } + + content?.let { + it() + Spacer(modifier = Modifier.height(Margin.Large)) + } + + DoubleButtonCombo(topButton = topButton, bottomButton = bottomButton) + } +} +@Preview +@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES or Configuration.UI_MODE_TYPE_NORMAL) +@Composable +private fun BottomSheetDefaultsPreview() { + SwissTransferTheme { + Surface { + BottomSheetContent( + imageVector = AppIcons.Illu.ArrowCurvedDownright, + titleRes = R.string.appName, + descriptionRes = R.string.sentEmptyTitle, + content = { + Box( + modifier = Modifier + .size(200.dp) + .background(Color.Gray), + ) {} + }, + topButton = { + LargeButton( + modifier = it, + titleRes = R.string.appName, + style = ButtonType.ERROR, + onClick = { /*TODO*/ }, + ) + }, + bottomButton = { + LargeButton( + modifier = it, + titleRes = R.string.appName, + style = ButtonType.TERTIARY, + onClick = { /*TODO*/ }, + ) + }, + ) + } + } +} diff --git a/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/newtransfer/importfiles/ImportFilesScreen.kt b/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/newtransfer/importfiles/ImportFilesScreen.kt index 07d4e2528..91407ac79 100644 --- a/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/newtransfer/importfiles/ImportFilesScreen.kt +++ b/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/newtransfer/importfiles/ImportFilesScreen.kt @@ -19,21 +19,25 @@ package com.infomaniak.swisstransfer.ui.screen.newtransfer.importfiles import androidx.compose.foundation.layout.Column -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable +import androidx.compose.foundation.layout.size +import androidx.compose.material3.Surface +import androidx.compose.runtime.* +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp import com.infomaniak.swisstransfer.R -import com.infomaniak.swisstransfer.ui.components.BottomStickyButtonScaffold -import com.infomaniak.swisstransfer.ui.components.ButtonType -import com.infomaniak.swisstransfer.ui.components.LargeButton -import com.infomaniak.swisstransfer.ui.components.SwissTransferTobAppBar +import com.infomaniak.swisstransfer.ui.components.* import com.infomaniak.swisstransfer.ui.icons.AppIcons import com.infomaniak.swisstransfer.ui.icons.app.Add +import com.infomaniak.swisstransfer.ui.icons.illu.ArrowCurvedDownright import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme import com.infomaniak.swisstransfer.ui.utils.PreviewMobile import com.infomaniak.swisstransfer.ui.utils.PreviewTablet @Composable fun ImportFilesScreen() { + var showImportChoiceBottomSheet by remember { mutableStateOf(false) } + BottomStickyButtonScaffold( topBar = { SwissTransferTobAppBar() }, topButton = { modifier -> @@ -42,7 +46,7 @@ fun ImportFilesScreen() { titleRes = R.string.buttonAddFiles, imageVector = AppIcons.Add, style = ButtonType.TERTIARY, - onClick = { /*TODO*/ }, + onClick = { showImportChoiceBottomSheet = true }, ) }, bottomButton = { modifier -> @@ -54,11 +58,51 @@ fun ImportFilesScreen() { }, ) { Column { - Text("ImportFilesScreen") + ImportChoiceBottomSheet( + showImportChoiceBottomSheet = { showImportChoiceBottomSheet }, + onDismissRequest = { showImportChoiceBottomSheet = false }, + ) } } } +@Composable +private fun ImportChoiceBottomSheet( + showImportChoiceBottomSheet: () -> Boolean, + onDismissRequest: () -> Unit, +) { + if (showImportChoiceBottomSheet()) { + SwissTransferBottomSheet( + onDismissRequest = onDismissRequest, + imageVector = AppIcons.Illu.ArrowCurvedDownright, + titleRes = R.string.appName, + descriptionRes = R.string.sentEmptyTitle, + content = { + Surface( + modifier = Modifier.size(200.dp), + color = Color.Gray, + ) {} + }, + topButton = { + LargeButton( + modifier = it, + titleRes = R.string.appName, + style = ButtonType.ERROR, + onClick = { /*TODO*/ }, + ) + }, + bottomButton = { + LargeButton( + modifier = it, + titleRes = R.string.appName, + style = ButtonType.TERTIARY, + onClick = { /*TODO*/ }, + ) + }, + ) + } +} + @PreviewMobile @PreviewTablet @Composable @@ -67,3 +111,14 @@ private fun ImportFilesScreenPreview() { ImportFilesScreen() } } + +@PreviewMobile +@PreviewTablet +@Composable +private fun ImportChoiceBottomSheetPreview() { + SwissTransferTheme { + Surface { + ImportChoiceBottomSheet({ true }, {}) + } + } +} diff --git a/app/src/main/java/com/infomaniak/swisstransfer/ui/theme/ColorDark.kt b/app/src/main/java/com/infomaniak/swisstransfer/ui/theme/ColorDark.kt index b673a73ae..e80c7fe32 100644 --- a/app/src/main/java/com/infomaniak/swisstransfer/ui/theme/ColorDark.kt +++ b/app/src/main/java/com/infomaniak/swisstransfer/ui/theme/ColorDark.kt @@ -37,6 +37,9 @@ private const val specific2 = 0xFF334117 private const val specific3 = 0xFF503E0F private const val specific4 = 0xFFEAC35D +// Extra palette +private const val error = 0xFFFC8878 + val DarkColorScheme = darkColorScheme( primary = Color(green_main), onPrimary = Color(dark1), @@ -49,7 +52,11 @@ val DarkColorScheme = darkColorScheme( surface = Color(dark1), // Same value as background onSurface = Color(green_main), onSurfaceVariant = Color(rabbit), + surfaceContainerLow = Color(dark2), // Used for bottom sheet backgrounds surfaceContainerHighest = Color(dark2), + + error = Color(error), + // onError: uses default values ) val CustomDarkColorScheme = CustomColorScheme( diff --git a/app/src/main/java/com/infomaniak/swisstransfer/ui/theme/ColorLight.kt b/app/src/main/java/com/infomaniak/swisstransfer/ui/theme/ColorLight.kt index 5f2c92181..fcc0338ea 100644 --- a/app/src/main/java/com/infomaniak/swisstransfer/ui/theme/ColorLight.kt +++ b/app/src/main/java/com/infomaniak/swisstransfer/ui/theme/ColorLight.kt @@ -43,6 +43,8 @@ private const val specific4 = 0xFFCF9E1B private const val on_primary = 0xFFF7FCFA private const val white = 0xFFFFFFFF +private const val error = 0xFFF44336 + val LightColorScheme = lightColorScheme( primary = Color(green_main), onPrimary = Color(on_primary), @@ -55,7 +57,11 @@ val LightColorScheme = lightColorScheme( surface = Color(white), // Same value as background onSurface = Color(green_main), onSurfaceVariant = Color(green_dark), + surfaceContainerLow = Color(white), // Same value as background. Used for bottom sheet backgrounds surfaceContainerHighest = Color(polar_bear), + + error = Color(error), + // onError: uses default values ) val CustomLightColorScheme = CustomColorScheme( diff --git a/app/src/main/java/com/infomaniak/swisstransfer/ui/theme/Shapes.kt b/app/src/main/java/com/infomaniak/swisstransfer/ui/theme/Shapes.kt index 2e7adb22a..3968f132d 100644 --- a/app/src/main/java/com/infomaniak/swisstransfer/ui/theme/Shapes.kt +++ b/app/src/main/java/com/infomaniak/swisstransfer/ui/theme/Shapes.kt @@ -27,5 +27,4 @@ val Shapes = Shapes( small = RoundedCornerShape(8.dp), medium = RoundedCornerShape(16.dp), large = RoundedCornerShape(24.dp), - extraLarge = RoundedCornerShape(50), )