diff --git a/app/src/main/java/com/infomaniak/swisstransfer/ui/components/NewTransferFab.kt b/app/src/main/java/com/infomaniak/swisstransfer/ui/components/NewTransferFab.kt
new file mode 100644
index 000000000..51ebd35c3
--- /dev/null
+++ b/app/src/main/java/com/infomaniak/swisstransfer/ui/components/NewTransferFab.kt
@@ -0,0 +1,58 @@
+/*
+ * 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 androidx.compose.material3.FloatingActionButtonDefaults
+import androidx.compose.material3.FloatingActionButtonElevation
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.dp
+import com.infomaniak.swisstransfer.ui.NewTransferActivity
+import com.infomaniak.swisstransfer.ui.utils.launchActivity
+
+@Composable
+fun NewTransferFab(
+ modifier: Modifier = Modifier,
+ newTransferFabType: NewTransferFabType
+) {
+ val context = LocalContext.current
+ SwissTransferFab(
+ modifier = modifier,
+ fabType = newTransferFabType.fabType,
+ elevation = newTransferFabType.elevation(),
+ onClick = { context.launchActivity(NewTransferActivity::class) },
+ )
+}
+
+enum class NewTransferFabType(val fabType: FabType, private val defaultElevation: Dp?) {
+ BOTTOM_BAR(FabType.NORMAL, null),
+ EMPTY_STATE(FabType.BIG, null),
+ NAVIGATION_RAIL(FabType.NORMAL, 0.dp);
+
+ @Composable
+ fun elevation(): FloatingActionButtonElevation {
+ return if (defaultElevation != null) {
+ FloatingActionButtonDefaults.elevation(defaultElevation)
+ } else {
+ FloatingActionButtonDefaults.elevation()
+ }
+ }
+}
diff --git a/app/src/main/java/com/infomaniak/swisstransfer/ui/components/SwissTransferFab.kt b/app/src/main/java/com/infomaniak/swisstransfer/ui/components/SwissTransferFab.kt
new file mode 100644
index 000000000..5bf88dd2d
--- /dev/null
+++ b/app/src/main/java/com/infomaniak/swisstransfer/ui/components/SwissTransferFab.kt
@@ -0,0 +1,82 @@
+/*
+ * 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.compose.foundation.layout.size
+import androidx.compose.foundation.shape.CornerBasedShape
+import androidx.compose.material3.FloatingActionButton
+import androidx.compose.material3.FloatingActionButtonDefaults
+import androidx.compose.material3.FloatingActionButtonElevation
+import androidx.compose.material3.Icon
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+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.app.Add
+import com.infomaniak.swisstransfer.ui.theme.Shapes
+import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme
+
+@Composable
+fun SwissTransferFab(
+ modifier: Modifier = Modifier,
+ fabType: FabType = FabType.NORMAL,
+ elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(),
+ onClick: () -> Unit,
+) {
+ FloatingActionButton(
+ modifier = modifier.let { if (fabType == FabType.BIG) it.size(80.dp) else it },
+ onClick = onClick,
+ containerColor = SwissTransferTheme.materialColors.primary,
+ shape = fabType.shape,
+ elevation = elevation,
+ ) {
+ Icon(
+ imageVector = AppIcons.Add,
+ contentDescription = stringResource(id = R.string.contentDescriptionCreateNewTransferButton),
+ )
+ }
+}
+
+enum class FabType(val shape: CornerBasedShape) {
+ NORMAL(Shapes.medium),
+ BIG(Shapes.large),
+}
+
+
+@Preview
+@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES or Configuration.UI_MODE_TYPE_NORMAL)
+@Composable
+private fun SwissTransferFabPreview() {
+ SwissTransferTheme {
+ SwissTransferFab(onClick = {})
+ }
+}
+
+@Preview
+@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES or Configuration.UI_MODE_TYPE_NORMAL)
+@Composable
+private fun SwissTransferFabBigPreview() {
+ SwissTransferTheme {
+ SwissTransferFab(fabType = FabType.BIG, onClick = {})
+ }
+}
diff --git a/app/src/main/java/com/infomaniak/swisstransfer/ui/icons/app/Add.kt b/app/src/main/java/com/infomaniak/swisstransfer/ui/icons/app/Add.kt
new file mode 100644
index 000000000..a60af7e80
--- /dev/null
+++ b/app/src/main/java/com/infomaniak/swisstransfer/ui/icons/app/Add.kt
@@ -0,0 +1,65 @@
+package com.infomaniak.swisstransfer.ui.icons.app
+
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.size
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.PathFillType.Companion.NonZero
+import androidx.compose.ui.graphics.SolidColor
+import androidx.compose.ui.graphics.StrokeCap.Companion.Round
+import androidx.compose.ui.graphics.StrokeJoin
+import androidx.compose.ui.graphics.vector.ImageVector
+import androidx.compose.ui.graphics.vector.ImageVector.Builder
+import androidx.compose.ui.graphics.vector.group
+import androidx.compose.ui.graphics.vector.path
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import com.infomaniak.swisstransfer.ui.icons.AppIcons
+
+val AppIcons.Add: ImageVector
+ get() {
+ if (_add != null) {
+ return _add!!
+ }
+ _add = Builder(
+ name = "Add",
+ defaultWidth = 24.0.dp,
+ defaultHeight = 24.0.dp,
+ viewportWidth = 24.0f,
+ viewportHeight = 24.0f
+ ).apply {
+ group {
+ path(
+ fill = null,
+ stroke = SolidColor(Color(0xFF9f9f9f)),
+ strokeLineWidth = 2.0f,
+ strokeLineCap = Round,
+ strokeLineJoin = StrokeJoin.Round,
+ strokeLineMiter = 4.0f,
+ pathFillType = NonZero
+ ) {
+ moveTo(1.5f, 12.0f)
+ horizontalLineToRelative(21.0f)
+ moveTo(12.0f, 1.5f)
+ verticalLineToRelative(21.0f)
+ }
+ }
+ }.build()
+ return _add!!
+ }
+
+private var _add: ImageVector? = null
+
+@Preview
+@Composable
+private fun Preview() {
+ Box {
+ Image(
+ imageVector = AppIcons.Add,
+ contentDescription = null,
+ modifier = Modifier.size(250.dp)
+ )
+ }
+}
diff --git a/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/components/AppNavigationSuiteScaffold.kt b/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/components/AppNavigationSuiteScaffold.kt
index 4a4baf198..663b0e5bc 100644
--- a/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/components/AppNavigationSuiteScaffold.kt
+++ b/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/components/AppNavigationSuiteScaffold.kt
@@ -19,8 +19,6 @@
package com.infomaniak.swisstransfer.ui.screen.main.components
import androidx.compose.foundation.layout.*
-import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.filled.Add
import androidx.compose.material3.*
import androidx.compose.material3.adaptive.navigationsuite.NavigationSuite
import androidx.compose.material3.adaptive.navigationsuite.NavigationSuiteScaffold
@@ -29,6 +27,8 @@ import androidx.compose.material3.adaptive.navigationsuite.NavigationSuiteType
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
+import com.infomaniak.swisstransfer.ui.components.NewTransferFab
+import com.infomaniak.swisstransfer.ui.components.NewTransferFabType
import com.infomaniak.swisstransfer.ui.navigation.MainNavigation
import com.infomaniak.swisstransfer.ui.navigation.NavigationItem
import com.infomaniak.swisstransfer.ui.theme.Margin
@@ -116,9 +116,10 @@ private fun AppNavigationRail(
) {
NavigationRail(
header = {
- FloatingActionButton(onClick = {}, modifier = Modifier.padding(bottom = Margin.Large)) {
- Icon(Icons.Default.Add, contentDescription = null)
- }
+ NewTransferFab(
+ modifier = Modifier.padding(vertical = Margin.Medium),
+ newTransferFabType = NewTransferFabType.NAVIGATION_RAIL,
+ )
},
containerColor = SwissTransferTheme.colors.navigationItemBackground
) {
@@ -142,4 +143,4 @@ private fun NavigationIcon(isNavigationBar: Boolean, navigationItem: NavigationI
@Composable
private fun NavigationLabel(navigationItem: NavigationItem) {
Text(stringResource(navigationItem.label))
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/received/ReceivedScreen.kt b/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/received/ReceivedScreen.kt
index 032c1b136..ce5155265 100644
--- a/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/received/ReceivedScreen.kt
+++ b/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/received/ReceivedScreen.kt
@@ -18,10 +18,55 @@
package com.infomaniak.swisstransfer.ui.screen.main.received
+import androidx.compose.foundation.layout.padding
+import androidx.compose.material3.Scaffold
+import androidx.compose.material3.Surface
import androidx.compose.material3.Text
+import androidx.compose.material3.adaptive.navigationsuite.NavigationSuiteType
import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import com.infomaniak.swisstransfer.ui.components.NewTransferFab
+import com.infomaniak.swisstransfer.ui.components.NewTransferFabType
+import com.infomaniak.swisstransfer.ui.screen.main.LocalNavType
+import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme
+import com.infomaniak.swisstransfer.ui.utils.PreviewMobile
+import com.infomaniak.swisstransfer.ui.utils.PreviewTablet
@Composable
fun ReceivedScreen(navigateToDetails: (transferId: Int) -> Unit) {
- Text("Received screen")
+ ReceivedScreen(navType = LocalNavType.current)
+}
+
+@Composable
+private fun ReceivedScreen(navType: NavigationSuiteType) {
+ Scaffold(
+ floatingActionButton = {
+ if (navType == NavigationSuiteType.NavigationBar) NewTransferFab(newTransferFabType = NewTransferFabType.BOTTOM_BAR)
+ }
+ ) { contentPadding ->
+ Text(
+ text = "Received screen",
+ modifier = Modifier.padding(contentPadding),
+ )
+ }
+}
+
+@PreviewMobile
+@Composable
+private fun ReceivedScreenMobilePreview() {
+ SwissTransferTheme {
+ Surface {
+ ReceivedScreen(navType = NavigationSuiteType.NavigationBar)
+ }
+ }
+}
+
+@PreviewTablet
+@Composable
+private fun ReceivedScreenTabletPreview() {
+ SwissTransferTheme {
+ Surface {
+ ReceivedScreen(navType = NavigationSuiteType.NavigationRail)
+ }
+ }
}
diff --git a/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/sent/SentScreen.kt b/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/sent/SentScreen.kt
index 937ea0cca..a46b20ebb 100644
--- a/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/sent/SentScreen.kt
+++ b/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/sent/SentScreen.kt
@@ -18,13 +18,117 @@
package com.infomaniak.swisstransfer.ui.screen.main.sent
+import androidx.compose.foundation.layout.*
+import androidx.compose.material3.Scaffold
+import androidx.compose.material3.Surface
import androidx.compose.material3.Text
+import androidx.compose.material3.adaptive.navigationsuite.NavigationSuiteType
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+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.unit.dp
+import androidx.lifecycle.compose.collectAsStateWithLifecycle
+import androidx.lifecycle.viewmodel.compose.viewModel
+import com.infomaniak.swisstransfer.R
+import com.infomaniak.swisstransfer.ui.components.NewTransferFab
+import com.infomaniak.swisstransfer.ui.components.NewTransferFabType
import com.infomaniak.swisstransfer.ui.screen.main.LocalNavType
+import com.infomaniak.swisstransfer.ui.theme.Margin
+import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme
+import com.infomaniak.swisstransfer.ui.utils.PreviewMobile
+import com.infomaniak.swisstransfer.ui.utils.PreviewTablet
@Composable
-fun SentScreen(navigateToDetails: (transferId: Int) -> Unit) {
- val navType = LocalNavType.current
+fun SentScreen(
+ navigateToDetails: (transferId: Int) -> Unit,
+ sentViewModel: SentViewModel = viewModel(),
+) {
+ val transfers by sentViewModel.transfers.collectAsStateWithLifecycle()
+ SentScreen(
+ transfers = transfers,
+ navType = LocalNavType.current,
+ )
+}
+
+@Composable
+private fun SentScreen(transfers: List?, navType: NavigationSuiteType) {
+ if (transfers == null) return
+
+ if (transfers.isEmpty()) {
+ EmptyScreen()
+ } else {
+ TransferScreen(navType)
+ }
+}
+
+@Composable
+fun EmptyScreen() {
+ Column(
+ modifier = Modifier.fillMaxSize(),
+ horizontalAlignment = Alignment.CenterHorizontally,
+ verticalArrangement = Arrangement.Center,
+ ) {
+ val maxWidth = 300.dp
+ Text(
+ modifier = Modifier.widthIn(max = maxWidth),
+ text = stringResource(id = R.string.sentEmptyTitle),
+ style = SwissTransferTheme.typography.specificMedium32,
+ textAlign = TextAlign.Center,
+ )
+ Spacer(modifier = Modifier.height(Margin.Medium))
+ Text(
+ modifier = Modifier.widthIn(max = maxWidth),
+ text = stringResource(id = R.string.firstTransferDescription),
+ style = SwissTransferTheme.typography.bodyRegular
+ )
+ NewTransferFab(
+ modifier = Modifier.padding(top = Margin.ExtraLarge),
+ newTransferFabType = NewTransferFabType.EMPTY_STATE,
+ )
+ }
+}
- Text("Sent screen $navType")
+@Composable
+private fun TransferScreen(
+ navType: NavigationSuiteType,
+) {
+ Scaffold(
+ floatingActionButton = {
+ if (navType == NavigationSuiteType.NavigationBar) NewTransferFab(newTransferFabType = NewTransferFabType.BOTTOM_BAR)
+ }
+ ) { contentPadding ->
+ Text(
+ text = "Sent screen",
+ modifier = Modifier.padding(contentPadding),
+ )
+ }
+}
+
+@PreviewMobile
+@Composable
+private fun SentScreenMobilePreview() {
+ SwissTransferTheme {
+ Surface {
+ SentScreen(
+ transfers = emptyList(),
+ navType = NavigationSuiteType.NavigationBar,
+ )
+ }
+ }
+}
+
+@PreviewTablet
+@Composable
+private fun SentScreenTabletPreview() {
+ SwissTransferTheme {
+ Surface {
+ SentScreen(
+ transfers = emptyList(),
+ navType = NavigationSuiteType.NavigationRail,
+ )
+ }
+ }
}
diff --git a/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/sent/SentViewModel.kt b/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/sent/SentViewModel.kt
new file mode 100644
index 000000000..51e431c74
--- /dev/null
+++ b/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/sent/SentViewModel.kt
@@ -0,0 +1,29 @@
+/*
+ * 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.sent
+
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.viewModelScope
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.flow
+import kotlinx.coroutines.flow.stateIn
+
+class SentViewModel : ViewModel() {
+ val transfers = flow> { emit(emptyList()) }.stateIn(viewModelScope, SharingStarted.Eagerly, null)
+}
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 5775df830..2e7adb22a 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
@@ -26,5 +26,6 @@ val Shapes = Shapes(
extraSmall = RoundedCornerShape(4.dp),
small = RoundedCornerShape(8.dp),
medium = RoundedCornerShape(16.dp),
+ large = RoundedCornerShape(24.dp),
extraLarge = RoundedCornerShape(50),
)
diff --git a/app/src/main/java/com/infomaniak/swisstransfer/ui/utils/ContextExt.kt b/app/src/main/java/com/infomaniak/swisstransfer/ui/utils/ContextExt.kt
new file mode 100644
index 000000000..c30aa7321
--- /dev/null
+++ b/app/src/main/java/com/infomaniak/swisstransfer/ui/utils/ContextExt.kt
@@ -0,0 +1,30 @@
+/*
+ * 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.utils
+
+import android.app.Activity
+import android.content.Context
+import android.content.Intent
+import android.os.Bundle
+import kotlin.reflect.KClass
+
+
+fun Context.launchActivity(kClass: KClass, options: Bundle? = null) {
+ startActivity(Intent(this, kClass.java), options)
+}
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index 3ed730b9a..d93235ceb 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -16,7 +16,10 @@
~ along with this program. If not, see .
-->
+ New transfer
+ Make your first transfer!
Received
+ Our story begins here
Sent
Settings
diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml
index 3ed730b9a..d93235ceb 100644
--- a/app/src/main/res/values-es/strings.xml
+++ b/app/src/main/res/values-es/strings.xml
@@ -16,7 +16,10 @@
~ along with this program. If not, see .
-->
+ New transfer
+ Make your first transfer!
Received
+ Our story begins here
Sent
Settings
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index c9b45e348..1506968a2 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -16,7 +16,10 @@
~ along with this program. If not, see .
-->
+ Nouveau transfert
+ Fais ton premier transfert !
Recu
+ Notre histoire commence ici
Envoyé
Paramètres
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
index 3ed730b9a..d93235ceb 100644
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -16,7 +16,10 @@
~ along with this program. If not, see .
-->
+ New transfer
+ Make your first transfer!
Received
+ Our story begins here
Sent
Settings
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 65215d957..45f00150a 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -19,7 +19,10 @@
SwissTransfer
+ New transfer
+ Make your first transfer!
Received
+ Our story begins here
Sent
Settings