Skip to content

Commit

Permalink
Merge pull request #232 from Infomaniak/verify-author-email
Browse files Browse the repository at this point in the history
feat: Make sure Transfer author email is mandatory and correctly formatted
  • Loading branch information
KevinBoulongne authored Dec 9, 2024
2 parents 75cffb3 + 3f92812 commit 3be0b83
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,21 @@ class ImportFilesViewModel @Inject constructor(
val filesToImportCount = importationFilesManager.filesToImportCount
val currentSessionFilesCount = importationFilesManager.currentSessionFilesCount

//region Transfer Author Email
private var _transferAuthorEmail by mutableStateOf("")
val transferAuthorEmail = GetSetCallbacks(get = { _transferAuthorEmail }, set = { _transferAuthorEmail = it })
//endregion

//region Transfer Message
private var _transferMessage by mutableStateOf("")
val transferMessage = GetSetCallbacks(get = { _transferMessage }, set = { _transferMessage = it })
//endregion

//region Password
private var transferPassword by mutableStateOf("")
private val isPasswordValid by derivedStateOf { transferPassword.length in PASSWORD_MIN_LENGTH..PASSWORD_MAX_LENGTH }
//endregion

private var isFirstViewModelCreation: Boolean
get() = savedStateHandle.get<Boolean>(IS_VIEW_MODEL_RESTORED_KEY) ?: true
set(value) {
Expand Down Expand Up @@ -137,7 +152,7 @@ class ImportFilesViewModel @Inject constructor(
private fun generateNewUploadSession(): NewUploadSession {
return NewUploadSession(
duration = selectedValidityPeriodOption.value.apiValue,
authorEmail = "",
authorEmail = if (selectedTransferType.value == TransferTypeUi.MAIL) _transferAuthorEmail else "",
password = if (selectedPasswordOption.value == PasswordTransferOption.ACTIVATED) transferPassword else NO_PASSWORD,
message = _transferMessage,
numberOfDownload = selectedDownloadLimitOption.value.apiValue,
Expand Down Expand Up @@ -240,16 +255,6 @@ class ImportFilesViewModel @Inject constructor(
}
//endregion

//region Transfer Message
private var _transferMessage by mutableStateOf("")
val transferMessage = GetSetCallbacks(get = { _transferMessage }, set = { _transferMessage = it })
//endregion

//region Password
private var transferPassword by mutableStateOf("")
private val isPasswordValid by derivedStateOf { transferPassword.length in PASSWORD_MIN_LENGTH..PASSWORD_MAX_LENGTH }
//endregion

sealed class SendActionResult {
data class Success(val totalSize: Long) : SendActionResult()
data object Failure : SendActionResult()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,11 @@ import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.infomaniak.core2.isEmail
import com.infomaniak.multiplatform_swisstransfer.common.interfaces.ui.FileUi
import com.infomaniak.swisstransfer.R
import com.infomaniak.swisstransfer.ui.components.*
Expand Down Expand Up @@ -102,6 +104,7 @@ fun ImportFilesScreen(
files = { files },
filesToImportCount = { filesToImportCount },
currentSessionFilesCount = { currentSessionFilesCount },
transferAuthorEmail = importFilesViewModel.transferAuthorEmail,
transferMessage = importFilesViewModel.transferMessage,
selectedTransferType = GetSetCallbacks(
get = { selectedTransferType },
Expand Down Expand Up @@ -136,6 +139,7 @@ private fun ImportFilesScreen(
files: () -> List<FileUi>,
filesToImportCount: () -> Int,
currentSessionFilesCount: () -> Int,
transferAuthorEmail: GetSetCallbacks<String>,
transferMessage: GetSetCallbacks<String>,
selectedTransferType: GetSetCallbacks<TransferTypeUi>,
transferOptionsCallbacks: TransferOptionsCallbacks,
Expand All @@ -145,6 +149,9 @@ private fun ImportFilesScreen(
shouldStartByPromptingUserForFiles: Boolean,
sendTransfer: () -> Unit,
) {

val shouldShowEmailAddressesFields by remember { derivedStateOf { selectedTransferType.get() == TransferTypeUi.MAIL } }

BottomStickyButtonScaffold(
topBar = {
SwissTransferTopAppBar(
Expand All @@ -154,14 +161,27 @@ private fun ImportFilesScreen(
)
},
topButton = { modifier ->
SendButton(modifier, filesToImportCount, currentSessionFilesCount, files, sendTransfer)
SendButton(
modifier = modifier,
filesToImportCount = filesToImportCount,
currentSessionFilesCount = currentSessionFilesCount,
importedFiles = files,
shouldShowEmailAddressesFields = { shouldShowEmailAddressesFields },
transferAuthorEmail = transferAuthorEmail,
navigateToUploadProgress = sendTransfer,
)
},
content = {
Column(modifier = Modifier.verticalScroll(rememberScrollState())) {
val modifier = Modifier.padding(horizontal = HORIZONTAL_PADDING)
FilesToImport(modifier, files, removeFileByUid, addFiles, shouldStartByPromptingUserForFiles)
Spacer(Modifier.height(Margin.Medium))
ImportTextFields(modifier, transferMessage, selectedTransferType.get)
ImportTextFields(
horizontalPaddingModifier = modifier,
transferAuthorEmail = transferAuthorEmail,
transferMessage = transferMessage,
shouldShowEmailAddressesFields = { shouldShowEmailAddressesFields },
)
SendByOptions(modifier, selectedTransferType)
TransferOptions(modifier, transferOptionsCallbacks)
}
Expand Down Expand Up @@ -198,11 +218,12 @@ private fun FilesToImport(
@Composable
private fun ColumnScope.ImportTextFields(
horizontalPaddingModifier: Modifier,
transferAuthorEmail: GetSetCallbacks<String>,
transferMessage: GetSetCallbacks<String>,
selectedTransferType: () -> TransferTypeUi,
shouldShowEmailAddressesFields: () -> Boolean,
) {
val modifier = horizontalPaddingModifier.fillMaxWidth()
EmailAddressesTextFields(modifier, selectedTransferType)
EmailAddressesTextFields(modifier, transferAuthorEmail, shouldShowEmailAddressesFields)
SwissTransferTextField(
modifier = modifier,
label = stringResource(R.string.transferMessagePlaceholder),
Expand All @@ -213,16 +234,29 @@ private fun ColumnScope.ImportTextFields(
}

@Composable
private fun ColumnScope.EmailAddressesTextFields(modifier: Modifier, selectedTransferType: () -> TransferTypeUi) {
private fun ColumnScope.EmailAddressesTextFields(
modifier: Modifier,
transferAuthorEmail: GetSetCallbacks<String>,
shouldShowEmailAddressesFields: () -> Boolean,
) {
AnimatedVisibility(visible = shouldShowEmailAddressesFields()) {
Column {

val shouldShowEmailAddressesFields by remember { derivedStateOf { selectedTransferType() == TransferTypeUi.MAIL } }
val isError = transferAuthorEmail.get().isNotEmpty() && !transferAuthorEmail.get().isEmail()
val supportingText: @Composable (() -> Unit)? = if (isError) {
{ Text(stringResource(R.string.invalidAddress)) }
} else {
null
}

AnimatedVisibility(visible = shouldShowEmailAddressesFields) {
Column {
SwissTransferTextField(
modifier = modifier,
label = stringResource(R.string.transferSenderAddressPlaceholder),
onValueChange = { /* TODO */ },
initialValue = transferAuthorEmail.get(),
keyboardType = KeyboardType.Email,
isError = isError,
supportingText = supportingText,
onValueChange = transferAuthorEmail.set,
)
Spacer(Modifier.height(Margin.Medium))
SwissTransferTextField(
Expand Down Expand Up @@ -309,25 +343,30 @@ private fun SendButton(
filesToImportCount: () -> Int,
currentSessionFilesCount: () -> Int,
importedFiles: () -> List<FileUi>,
shouldShowEmailAddressesFields: () -> Boolean,
transferAuthorEmail: GetSetCallbacks<String>,
navigateToUploadProgress: () -> Unit,
) {
val remainingFilesCount = filesToImportCount()
val isImporting by remember(remainingFilesCount) { derivedStateOf { remainingFilesCount > 0 } }

val total = currentSessionFilesCount()
val importProgress = remember(remainingFilesCount, total) { 1 - (remainingFilesCount.toFloat() / total) }

val progress: (() -> Float)? = if (isImporting) {
{ importProgress }
} else {
null
}

val isSenderEmailCorrect by remember {
derivedStateOf { if (shouldShowEmailAddressesFields()) transferAuthorEmail.get().isEmail() else true }
}

LargeButton(
modifier = modifier,
titleRes = R.string.transferSendButton,
style = ButtonType.PRIMARY,
enabled = { importedFiles().isNotEmpty() && !isImporting },
enabled = { importedFiles().isNotEmpty() && !isImporting && isSenderEmailCorrect },
progress = progress,
onClick = navigateToUploadProgress,
)
Expand Down Expand Up @@ -388,6 +427,7 @@ private fun Preview(@PreviewParameter(FileUiListPreviewParameter::class) files:
files = { files },
filesToImportCount = { 0 },
currentSessionFilesCount = { 0 },
transferAuthorEmail = GetSetCallbacks(get = { "" }, set = {}),
transferMessage = GetSetCallbacks(get = { "" }, set = {}),
selectedTransferType = GetSetCallbacks(get = { TransferTypeUi.MAIL }, set = {}),
transferOptionsCallbacks = transferOptionsCallbacks,
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values-de/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
<string name="firstTransferDescription">Mache deine erste Überweisung!</string>
<string name="fromHeader">Von:</string>
<string name="importFilesScreenTitle">Zu übertragende Dateien</string>
<string name="invalidAddress">Ungültige Adresse</string>
<string name="messageHeader">Nachricht:</string>
<string name="myFilesTitle">Meine Dateien</string>
<string name="networkUnavailable">Auf Netzwerk warten…</string>
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values-es/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
<string name="firstTransferDescription">Realice su primera transferencia</string>
<string name="fromHeader">De:</string>
<string name="importFilesScreenTitle">Archivos para transferir</string>
<string name="invalidAddress">Dirección no válida</string>
<string name="messageHeader">Mensaje:</string>
<string name="myFilesTitle">Mis archivos</string>
<string name="networkUnavailable">Esperando la red…</string>
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values-fr/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
<string name="firstTransferDescription">Fais ton premier transfert !</string>
<string name="fromHeader">De :</string>
<string name="importFilesScreenTitle">Fichiers à transférer</string>
<string name="invalidAddress">Adresse invalide</string>
<string name="messageHeader">Message :</string>
<string name="myFilesTitle">Mes fichiers</string>
<string name="networkUnavailable">En attente de réseau…</string>
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values-it/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
<string name="firstTransferDescription">Effettua il tuo primo trasferimento!</string>
<string name="fromHeader">Da:</string>
<string name="importFilesScreenTitle">File da trasferire</string>
<string name="invalidAddress">Indirizzo non valido</string>
<string name="messageHeader">Messaggio:</string>
<string name="myFilesTitle">I miei file</string>
<string name="networkUnavailable">In attesa della rete…</string>
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
<string name="firstTransferDescription">Make your first transfer!</string>
<string name="fromHeader">From:</string>
<string name="importFilesScreenTitle">Files to transfer</string>
<string name="invalidAddress">Invalid address</string>
<string name="messageHeader">Message:</string>
<string name="myFilesTitle">My files</string>
<string name="networkUnavailable">Waiting for network…</string>
Expand Down

0 comments on commit 3be0b83

Please sign in to comment.