Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.StringRes
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
Expand All @@ -37,6 +37,7 @@ import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.collectAsState
Expand All @@ -53,14 +54,17 @@ import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardCapitalization
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.Dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.google.accompanist.permissions.ExperimentalPermissionsApi
import com.google.accompanist.permissions.PermissionState
import com.google.accompanist.permissions.rememberPermissionState
import com.infomaniak.core.auth.models.user.User
import com.infomaniak.core.common.mapSync
import com.infomaniak.core.ui.compose.bottomstickybuttonscaffolds.BottomStickyButtonScaffold
import com.infomaniak.core.ui.compose.margin.Margin
import com.infomaniak.core.ui.compose.preview.PreviewAllWindows
import com.infomaniak.core.ui.compose.preview.previewparameter.UserListPreviewParameterProvider
import com.infomaniak.multiplatform_swisstransfer.common.interfaces.ui.FileUi
import com.infomaniak.multiplatform_swisstransfer.common.matomo.MatomoScreen
import com.infomaniak.swisstransfer.R
Expand All @@ -71,7 +75,7 @@ import com.infomaniak.swisstransfer.ui.components.LargeButton
import com.infomaniak.swisstransfer.ui.components.SwissTransferTextField
import com.infomaniak.swisstransfer.ui.components.SwissTransferTopAppBar
import com.infomaniak.swisstransfer.ui.components.TopAppBarButtons
import com.infomaniak.swisstransfer.ui.previewparameter.FileUiListPreviewParameter
import com.infomaniak.swisstransfer.ui.previewparameter.filesPreviewData
import com.infomaniak.swisstransfer.ui.screen.main.settings.DownloadLimitOption
import com.infomaniak.swisstransfer.ui.screen.main.settings.EmailLanguageOption
import com.infomaniak.swisstransfer.ui.screen.main.settings.ValidityPeriodOption
Expand Down Expand Up @@ -287,47 +291,54 @@ private fun FilesToImport(
}

@Composable
private fun ColumnScope.ImportTextFields(
private fun ImportTextFields(
horizontalPaddingModifier: Modifier,
transferTitleState: MutableState<String>,
emailTextFieldCallbacks: EmailTextFieldCallbacks,
transferMessageCallbacks: GetSetCallbacks<String>,
shouldShowEmailAddressesFields: () -> Boolean,
) {
val modifier = horizontalPaddingModifier.fillMaxWidth()
if (LocalUser.current.isApiV2()) {

val textFieldSpacing = Margin.Medium
Column(verticalArrangement = Arrangement.spacedBy(textFieldSpacing)) {
if (LocalUser.current.isApiV2()) {
SwissTransferTextField(
modifier = modifier,
label = stringResource(R.string.transferTitlePlaceholder),
isRequired = false,
maxLineNumber = 1,
onValueChange = { transferTitleState.value = it },
)
}

EmailAddressesTextFields(modifier, emailTextFieldCallbacks, shouldShowEmailAddressesFields, textFieldSpacing)

SwissTransferTextField(
modifier = modifier,
label = stringResource(R.string.transferTitlePlaceholder),
label = stringResource(R.string.transferMessagePlaceholder),
isRequired = false,
maxLineNumber = 1,
onValueChange = { transferTitleState.value = it }
minLineNumber = 3,
capitalization = KeyboardCapitalization.Sentences,
onValueChange = transferMessageCallbacks.set,
)
}
EmailAddressesTextFields(modifier, emailTextFieldCallbacks, shouldShowEmailAddressesFields)
SwissTransferTextField(
modifier = modifier,
label = stringResource(R.string.transferMessagePlaceholder),
isRequired = false,
minLineNumber = 3,
capitalization = KeyboardCapitalization.Sentences,
onValueChange = transferMessageCallbacks.set,
)
}

@Composable
private fun ColumnScope.EmailAddressesTextFields(
private fun EmailAddressesTextFields(
modifier: Modifier,
emailTextFieldCallbacks: EmailTextFieldCallbacks,
shouldShowEmailAddressesFields: () -> Boolean,
textFieldSpacing: Dp,
) = with(emailTextFieldCallbacks) {
AnimatedVisibility(visible = shouldShowEmailAddressesFields()) {
Column {
AnimatedVisibility(visible = shouldShowEmailAddressesFields(), modifier = modifier) {
Column(verticalArrangement = Arrangement.spacedBy(textFieldSpacing)) {
val isAuthorError = checkEmailError(isAuthor = true)
val isRecipientError = checkEmailError(isAuthor = false)

SwissTransferTextField(
modifier = modifier,
modifier = Modifier.fillMaxWidth(),
label = stringResource(R.string.transferSenderAddressPlaceholder),
initialValue = transferAuthorEmail.get(),
keyboardType = KeyboardType.Email,
Expand All @@ -338,17 +349,16 @@ private fun ColumnScope.EmailAddressesTextFields(
supportingText = getEmailError(isAuthorError),
onValueChange = transferAuthorEmail.set,
)
Spacer(Modifier.height(Margin.Medium))

EmailAddressTextField(
modifier = modifier,
modifier = Modifier.fillMaxWidth(),
label = stringResource(R.string.transferRecipientAddressPlaceholder),
initialValue = recipientEmail.get(),
validatedRecipientsEmails = validatedRecipientsEmails,
onValueChange = { recipientEmail.set(it.text) },
isError = isRecipientError,
supportingText = getEmailError(isRecipientError),
)
Spacer(Modifier.height(Margin.Medium))
}
}
}
Expand Down Expand Up @@ -489,7 +499,8 @@ enum class PasswordTransferOption(

@PreviewAllWindows
@Composable
private fun Preview(@PreviewParameter(FileUiListPreviewParameter::class) files: List<FileUi>) {
private fun Preview(@PreviewParameter(UserListPreviewParameterProvider::class) users: List<User>) {
val files = filesPreviewData
val transferOptionsCallbacks = TransferOptionsCallbacks(
transferOptionsStates = {
listOf(
Expand Down Expand Up @@ -524,20 +535,22 @@ private fun Preview(@PreviewParameter(FileUiListPreviewParameter::class) files:
validatedRecipientsEmails = GetSetCallbacks(get = { setOf("test.test@ik.me") }, set = {}),
)

SwissTransferTheme {
PickFilesScreen(
files = { files },
canSendStatus = { CanSendStatus.Yes },
transferTitleState = remember { mutableStateOf("") },
emailTextFieldCallbacks = emailTextFieldCallbacks,
transferMessageCallbacks = GetSetCallbacks(get = { "" }, set = {}),
selectedTransferType = GetSetCallbacks(get = { TransferTypeUi.Mail }, set = {}),
transferOptionsCallbacks = transferOptionsCallbacks,
pickFiles = {},
exitNewTransfer = {},
onSendButtonClick = {},
isAwaitingSend = { true },
navigateToFilesDetails = {},
)
CompositionLocalProvider(LocalUser provides users.first()) {
SwissTransferTheme {
PickFilesScreen(
files = { files },
canSendStatus = { CanSendStatus.Yes },
transferTitleState = remember { mutableStateOf("") },
emailTextFieldCallbacks = emailTextFieldCallbacks,
transferMessageCallbacks = GetSetCallbacks(get = { "" }, set = {}),
selectedTransferType = GetSetCallbacks(get = { TransferTypeUi.Mail }, set = {}),
transferOptionsCallbacks = transferOptionsCallbacks,
pickFiles = {},
exitNewTransfer = {},
onSendButtonClick = {},
isAwaitingSend = { true },
navigateToFilesDetails = {},
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextFieldDefaults
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
Expand All @@ -57,6 +58,7 @@ import androidx.compose.ui.input.key.KeyEventType
import androidx.compose.ui.input.key.key
import androidx.compose.ui.input.key.onPreviewKeyEvent
import androidx.compose.ui.input.key.type
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
Expand All @@ -68,10 +70,12 @@ import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.text.input.TransformedText
import androidx.compose.ui.text.input.VisualTransformation
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.infomaniak.core.common.utils.isEmailRfc5321Compliant
import com.infomaniak.core.ui.compose.margin.Margin
import com.infomaniak.core.ui.compose.preview.PreviewLightAndDark
import com.infomaniak.core.common.utils.isEmailRfc5321Compliant
import com.infomaniak.swisstransfer.R
import com.infomaniak.swisstransfer.ui.components.SwissTransferInputChip
import com.infomaniak.swisstransfer.ui.components.SwissTransferTextFieldDefaults
Expand Down Expand Up @@ -130,7 +134,7 @@ fun EmailAddressTextField(
}

BasicTextField(
modifier = emailAddressTextFieldModifier,
modifier = emailAddressTextFieldModifier.padding(top = minimizedLabelHalfHeight()),
value = textFieldValue,
onValueChange = state::updateUiTextValue,
textStyle = TextStyle(color = SwissTransferTheme.colors.primaryTextColor),
Expand All @@ -155,6 +159,17 @@ fun EmailAddressTextField(
)
}

/**
* Copied from OutlineTextField so the BasicTextField can have the same spacing as OutlineTextField with a label
*/
@Composable
private fun minimizedLabelHalfHeight(): Dp {
val compositionLocalValue = MaterialTheme.typography.bodySmall.lineHeight
val fallbackValue = 16.sp
val value = if (compositionLocalValue.isSp) compositionLocalValue else fallbackValue
return with(LocalDensity.current) { value.toDp() / 2 }
}

private class EmailAddressTextFieldState(
initialText: String,
private val validatedRecipientsEmails: GetSetCallbacks<Set<String>>,
Expand Down
Loading