diff --git a/app/src/main/java/com/infomaniak/swisstransfer/ui/components/SwissTransferTopAppBar.kt b/app/src/main/java/com/infomaniak/swisstransfer/ui/components/SwissTransferTopAppBar.kt
index f8106f1e9..4eb48ebb8 100644
--- a/app/src/main/java/com/infomaniak/swisstransfer/ui/components/SwissTransferTopAppBar.kt
+++ b/app/src/main/java/com/infomaniak/swisstransfer/ui/components/SwissTransferTopAppBar.kt
@@ -31,6 +31,40 @@ import com.infomaniak.swisstransfer.ui.images.icons.Cross
import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme
import com.infomaniak.swisstransfer.ui.utils.PreviewAllWindows
+@Composable
+fun SwissTransferTopAppBar(
+ title: String? = null,
+ @StringRes titleRes: Int,
+ navigationMenu: TopAppBarButton? = null,
+ vararg actionMenus: TopAppBarButton,
+) {
+ if (title != null) {
+ SwissTransferTopAppBar(title = title, navigationMenu = navigationMenu, actionMenus = actionMenus)
+ } else {
+ SwissTransferTopAppBar(titleRes = titleRes, navigationMenu = navigationMenu, actionMenus = actionMenus)
+ }
+}
+
+@Composable
+@OptIn(ExperimentalMaterial3Api::class)
+fun SwissTransferTopAppBar(
+ title: String,
+ navigationMenu: TopAppBarButton? = null,
+ vararg actionMenus: TopAppBarButton,
+) {
+ TopAppBar(
+ colors = TopAppBarDefaults.topAppBarColors(
+ containerColor = SwissTransferTheme.materialColors.tertiary,
+ titleContentColor = SwissTransferTheme.colors.toolbarTextColor,
+ actionIconContentColor = SwissTransferTheme.colors.toolbarIconColor,
+ navigationIconContentColor = SwissTransferTheme.colors.toolbarIconColor,
+ ),
+ title = { Text(text = title, style = SwissTransferTheme.typography.h2) },
+ navigationIcon = { navigationMenu?.let { MenuButton(navigationMenu) } },
+ actions = { actionMenus.forEach { actionMenu -> MenuButton(actionMenu) } },
+ )
+}
+
@Composable
@OptIn(ExperimentalMaterial3Api::class)
fun SwissTransferTopAppBar(
@@ -45,7 +79,7 @@ fun SwissTransferTopAppBar(
actionIconContentColor = SwissTransferTheme.colors.toolbarIconColor,
navigationIconContentColor = SwissTransferTheme.colors.toolbarIconColor,
),
- title = { Text(stringResource(id = titleRes), style = SwissTransferTheme.typography.h2) },
+ title = { Text(text = stringResource(id = titleRes), style = SwissTransferTheme.typography.h2) },
navigationIcon = { navigationMenu?.let { MenuButton(navigationMenu) } },
actions = { actionMenus.forEach { actionMenu -> MenuButton(actionMenu) } },
)
@@ -81,8 +115,7 @@ private fun SwissTransferTopAppBarPreview() {
SwissTransferTopAppBar(
titleRes = R.string.appName,
navigationMenu = TopAppBarButton.backButton {},
- TopAppBarButton(AppIcons.Add, R.string.appName) {},
- TopAppBarButton.closeButton {},
+ actionMenus = arrayOf(TopAppBarButton(AppIcons.Add, R.string.appName) {}, TopAppBarButton.closeButton {}),
)
}
}
diff --git a/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/newtransfer/FilesSize.kt b/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/newtransfer/FilesSize.kt
new file mode 100644
index 000000000..9d593e829
--- /dev/null
+++ b/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/newtransfer/FilesSize.kt
@@ -0,0 +1,89 @@
+/*
+ * 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.newtransfer
+
+import androidx.compose.foundation.layout.*
+import androidx.compose.material3.Surface
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.res.pluralStringResource
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.tooling.preview.PreviewParameter
+import com.infomaniak.swisstransfer.R
+import com.infomaniak.swisstransfer.ui.components.FileUi
+import com.infomaniak.swisstransfer.ui.previewparameter.FileUiListPreviewParameter
+import com.infomaniak.swisstransfer.ui.theme.Margin
+import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme
+import com.infomaniak.swisstransfer.ui.utils.HumanReadableSizeUtils.formatSpaceLeft
+import com.infomaniak.swisstransfer.ui.utils.HumanReadableSizeUtils.getFilesSize
+import com.infomaniak.swisstransfer.ui.utils.HumanReadableSizeUtils.getSpaceLeft
+
+@Composable
+fun FilesSize(files: List, withSpaceLeft: Boolean) {
+ Row(
+ modifier = Modifier
+ .fillMaxWidth()
+ .wrapContentHeight()
+ .padding(vertical = Margin.Medium)
+ ) {
+ val filesCount = files.count()
+ val filesSize = LocalContext.current.getFilesSize(files)
+ Text(
+ pluralStringResource(R.plurals.filesCount, filesCount, filesCount),
+ modifier = Modifier
+ .padding(start = Margin.Medium)
+ .wrapContentWidth(),
+ color = SwissTransferTheme.colors.secondaryTextColor,
+ style = SwissTransferTheme.typography.bodySmallRegular,
+ )
+ Text(
+ "•",
+ modifier = Modifier.padding(horizontal = Margin.Small),
+ color = SwissTransferTheme.colors.secondaryTextColor,
+ style = SwissTransferTheme.typography.bodySmallRegular,
+ )
+ Text(
+ filesSize,
+ color = SwissTransferTheme.colors.secondaryTextColor,
+ style = SwissTransferTheme.typography.bodySmallRegular,
+ )
+ if (withSpaceLeft) {
+ val context = LocalContext.current
+ val spaceLeft = formatSpaceLeft { context.getSpaceLeft(files) }
+ Spacer(modifier = Modifier.weight(1f))
+ Text(
+ modifier = Modifier.padding(horizontal = Margin.Medium),
+ text = spaceLeft,
+ color = SwissTransferTheme.colors.secondaryTextColor,
+ style = SwissTransferTheme.typography.bodySmallRegular,
+ )
+ }
+ }
+}
+
+@Preview
+@Composable
+fun FileSizePreview(@PreviewParameter(FileUiListPreviewParameter::class) files: List) {
+ SwissTransferTheme {
+ Surface {
+ FilesSize(files, withSpaceLeft = true)
+ }
+ }
+}
diff --git a/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/newtransfer/importfiles/FilesDetailsScreen.kt b/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/newtransfer/importfiles/FilesDetailsScreen.kt
new file mode 100644
index 000000000..a46e64e87
--- /dev/null
+++ b/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/newtransfer/importfiles/FilesDetailsScreen.kt
@@ -0,0 +1,101 @@
+/*
+ * 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.newtransfer.importfiles
+
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.padding
+import androidx.compose.material3.Surface
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.tooling.preview.PreviewParameter
+import com.infomaniak.swisstransfer.R
+import com.infomaniak.swisstransfer.ui.components.FileItemList
+import com.infomaniak.swisstransfer.ui.components.FileUi
+import com.infomaniak.swisstransfer.ui.components.SwissTransferTopAppBar
+import com.infomaniak.swisstransfer.ui.components.TopAppBarButton
+import com.infomaniak.swisstransfer.ui.previewparameter.FileUiListPreviewParameter
+import com.infomaniak.swisstransfer.ui.screen.newtransfer.FilesSize
+import com.infomaniak.swisstransfer.ui.theme.Margin
+import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme
+import com.infomaniak.swisstransfer.ui.utils.PreviewAllWindows
+
+@Composable
+fun FilesDetailsScreen(
+ withSpaceLeft: Boolean,
+ title: String? = null,
+ files: List? = null,
+ onFileRemoved: (uuid: String) -> Unit,
+) {
+ val files = listOf(
+ FileUi(
+ fileName = "The 5-Step Guide to Not Breaking Your Code.txt",
+ uid = "The 5-Step Guide to Not Breaking Your Code.txt",
+ fileSizeInBytes = 57689032,
+ mimeType = null,
+ uri = "",
+ ),
+ FileUi(
+ fileName = "Introduction to Turning It Off and On Again.pptx",
+ uid = "Introduction to Turning It Off and On Again.pptx",
+ fileSizeInBytes = 89723143,
+ mimeType = null,
+ uri = "",
+ ),
+ FileUi(
+ fileName = "Learning to Copy and Paste: A Complete Guide.docx",
+ uid = "Learning to Copy and Paste: A Complete Guide.docx",
+ fileSizeInBytes = 237866728,
+ mimeType = null,
+ uri = "",
+ ),
+ )
+ Column {
+ SwissTransferTopAppBar(
+ title = title,
+ titleRes = R.string.importFilesScreenTitle,
+ navigationMenu = TopAppBarButton.backButton {},
+ TopAppBarButton.closeButton {},
+ )
+ FilesSize(files, withSpaceLeft)
+
+ FileItemList(
+ modifier = Modifier.padding(horizontal = Margin.Medium),
+ files = files,
+ isRemoveButtonVisible = true,
+ isCheckboxVisible = false,
+ isUidChecked = { false },
+ setUidCheckStatus = { _, _ -> },
+ onRemoveUid = { onFileRemoved(it) },
+ )
+ }
+}
+
+@PreviewAllWindows
+@Composable
+private fun FilesDetailsScreenPreview(@PreviewParameter(FileUiListPreviewParameter::class) files: List) {
+ SwissTransferTheme {
+ Surface {
+ FilesDetailsScreen(
+ withSpaceLeft = true,
+ title = "My album",
+ files = files,
+ onFileRemoved = {},
+ )
+ }
+ }
+}
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 5a19a816c..f20578cfc 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
@@ -35,11 +35,9 @@ import com.infomaniak.swisstransfer.ui.screen.newtransfer.NewTransferViewModel
import com.infomaniak.swisstransfer.ui.screen.newtransfer.importfiles.components.ImportedFilesCard
import com.infomaniak.swisstransfer.ui.theme.Margin
import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme
-import com.infomaniak.swisstransfer.ui.utils.HumanReadableSizeUtils.getHumanReadableSize
+import com.infomaniak.swisstransfer.ui.utils.HumanReadableSizeUtils.getFilesSize
import com.infomaniak.swisstransfer.ui.utils.PreviewAllWindows
-private const val TOTAL_FILE_SIZE: Long = 50_000_000_000L
-
@Composable
fun ImportFilesScreen(
newTransferViewModel: NewTransferViewModel = hiltViewModel(),
@@ -68,9 +66,7 @@ private fun ImportFilesScreen(
val importedFiles = files()
val humanReadableSize = remember(importedFiles) {
- val usedSpace = importedFiles.sumOf { it.fileSizeInBytes }
- val spaceLeft = (TOTAL_FILE_SIZE - usedSpace).coerceAtLeast(0)
- getHumanReadableSize(context, spaceLeft)
+ context.getFilesSize(importedFiles)
}
val isSendButtonEnabled by remember { derivedStateOf { importedFiles.isNotEmpty() } }
diff --git a/app/src/main/java/com/infomaniak/swisstransfer/ui/utils/HumanReadableSizeUtils.kt b/app/src/main/java/com/infomaniak/swisstransfer/ui/utils/HumanReadableSizeUtils.kt
index 1ea0e0e32..b7feedad5 100644
--- a/app/src/main/java/com/infomaniak/swisstransfer/ui/utils/HumanReadableSizeUtils.kt
+++ b/app/src/main/java/com/infomaniak/swisstransfer/ui/utils/HumanReadableSizeUtils.kt
@@ -24,10 +24,20 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.pluralStringResource
import com.infomaniak.swisstransfer.R
+import com.infomaniak.swisstransfer.ui.components.FileUi
object HumanReadableSizeUtils {
- fun getHumanReadableSize(context: Context, sizeInBytes: Long): String {
- return Formatter.formatShortFileSize(context, sizeInBytes)
+ private const val TOTAL_FILE_SIZE: Long = 50_000_000_000L
+
+ private fun getHumanReadableSize(context: Context, sizeInBytes: Long) = Formatter.formatFileSize(context, sizeInBytes)
+
+ private fun getFilesSizeInBytes(files: List) = files.sumOf { it.fileSizeInBytes }
+
+ fun Context.getFilesSize(files: List): String = getHumanReadableSize(this, getFilesSizeInBytes(files))
+
+ fun Context.getSpaceLeft(files: List): String {
+ val spaceLeft = (TOTAL_FILE_SIZE - getFilesSizeInBytes(files)).coerceAtLeast(0)
+ return getHumanReadableSize(this, spaceLeft)
}
@Composable
@@ -42,7 +52,7 @@ object HumanReadableSizeUtils {
val sizeParts = humanReadableSize.split(' ', Typography.nbsp)
return if (sizeParts.size == 2) {
- val local = resources.configuration.getLocales().get(0)
+ val local = resources.configuration.getLocales()[0]
val parsedNumber = NumberFormat.getInstance(local).parse(sizeParts.first())
parsedNumber?.toDouble()?.toInt() ?: 0
} else {