diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/start/newmessage/NewMessage.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/start/newmessage/NewMessage.kt index c52ae8282a..c819a76b93 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/start/newmessage/NewMessage.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/start/newmessage/NewMessage.kt @@ -95,6 +95,7 @@ private fun EnterAccountId( onChange = callbacks::onChange, onContinue = callbacks::onContinue, error = state.error?.string(), + isTextErrorColor = state.isTextErrorColor ) BorderlessButtonWithIcon( diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/start/newmessage/NewMessageViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/start/newmessage/NewMessageViewModel.kt index cb94db68d9..a08282da74 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/start/newmessage/NewMessageViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/start/newmessage/NewMessageViewModel.kt @@ -45,16 +45,16 @@ internal class NewMessageViewModel @Inject constructor( loadOnsJob?.cancel() loadOnsJob = null - _state.update { State(newMessageIdOrOns = value) } + _state.update { it.copy(newMessageIdOrOns = value, isTextErrorColor = false, loading = false) } } override fun onContinue() { val idOrONS = state.value.newMessageIdOrOns if (PublicKeyValidation.isValid(idOrONS, isPrefixRequired = false)) { - onUnvalidatedPublicKey(idOrONS) + onUnvalidatedPublicKey(publicKey = idOrONS) } else { - resolveONS(idOrONS) + resolveONS(ons = idOrONS) } } @@ -70,7 +70,7 @@ internal class NewMessageViewModel @Inject constructor( if (loadOnsJob?.isActive == true) return // This could be an ONS name - _state.update { it.copy(error = null, loading = true) } + _state.update { it.copy(isTextErrorColor = false, error = null, loading = true) } loadOnsJob = viewModelScope.launch(Dispatchers.IO) { try { @@ -83,7 +83,7 @@ internal class NewMessageViewModel @Inject constructor( } private fun onError(e: Exception) { - _state.update { it.copy(loading = false, error = GetString(e) { it.toMessage() }) } + _state.update { it.copy(loading = false, isTextErrorColor = true, error = GetString(e) { it.toMessage() }) } } private fun onPublicKey(publicKey: String) { @@ -95,7 +95,7 @@ internal class NewMessageViewModel @Inject constructor( if (PublicKeyValidation.hasValidPrefix(publicKey)) { onPublicKey(publicKey) } else { - _state.update { it.copy(error = GetString(R.string.accountIdErrorInvalid), loading = false) } + _state.update { it.copy(isTextErrorColor = true, error = GetString(R.string.accountIdErrorInvalid), loading = false) } } } @@ -108,6 +108,7 @@ internal class NewMessageViewModel @Inject constructor( internal data class State( val newMessageIdOrOns: String = "", + val isTextErrorColor: Boolean = false, val error: GetString? = null, val loading: Boolean = false ) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/onboarding/loadaccount/LoadAccount.kt b/app/src/main/java/org/thoughtcrime/securesms/onboarding/loadaccount/LoadAccount.kt index caef0cca41..374a833bc8 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/onboarding/loadaccount/LoadAccount.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/onboarding/loadaccount/LoadAccount.kt @@ -107,7 +107,8 @@ private fun RecoveryPassword(state: State, onChange: (String) -> Unit = {}, onCo placeholder = stringResource(R.string.recoveryPasswordEnter), onChange = onChange, onContinue = onContinue, - error = state.error + error = state.error, + isTextErrorColor = state.isTextErrorColor ) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/onboarding/loadaccount/LoadAccountViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/onboarding/loadaccount/LoadAccountViewModel.kt index 1e2f46c698..63e089e29b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/onboarding/loadaccount/LoadAccountViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/onboarding/loadaccount/LoadAccountViewModel.kt @@ -23,6 +23,7 @@ class LoadAccountEvent(val mnemonic: ByteArray) internal data class State( val recoveryPhrase: String = "", + val isTextErrorColor: Boolean = false, val error: String? = null ) @@ -63,7 +64,7 @@ internal class LinkDeviceViewModel @Inject constructor( } fun onChange(recoveryPhrase: String) { - state.value = State(recoveryPhrase) + state.update { it.copy(recoveryPhrase = recoveryPhrase, isTextErrorColor = false) } } private fun onSuccess(seed: ByteArray) { @@ -73,6 +74,7 @@ internal class LinkDeviceViewModel @Inject constructor( private fun onFailure(error: Throwable) { state.update { it.copy( + isTextErrorColor = true, error = when (error) { is InvalidWord -> R.string.recoveryPasswordErrorMessageIncorrect is InputTooShort -> R.string.recoveryPasswordErrorMessageShort diff --git a/app/src/main/java/org/thoughtcrime/securesms/onboarding/pickname/PickDisplayName.kt b/app/src/main/java/org/thoughtcrime/securesms/onboarding/pickname/PickDisplayName.kt index 5276e6eb78..b6b4b017aa 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/onboarding/pickname/PickDisplayName.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/onboarding/pickname/PickDisplayName.kt @@ -57,7 +57,8 @@ internal fun DisplayName(state: State, onChange: (String) -> Unit = {}, onContin placeholder = stringResource(R.string.displayNameEnter), onChange = onChange, onContinue = onContinue, - error = state.error?.let { stringResource(it) } + error = state.error?.let { stringResource(it) }, + isTextErrorColor = state.isTextErrorColor ) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/onboarding/pickname/PickDisplayNameViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/onboarding/pickname/PickDisplayNameViewModel.kt index a6fb8fc35f..fbc027a197 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/onboarding/pickname/PickDisplayNameViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/onboarding/pickname/PickDisplayNameViewModel.kt @@ -43,8 +43,8 @@ internal class PickDisplayNameViewModel( val displayName = _states.value.displayName when { - displayName.isEmpty() -> { _states.update { it.copy(error = R.string.displayNameErrorDescription) } } - displayName.length > NAME_PADDED_LENGTH -> { _states.update { it.copy(error = R.string.displayNameErrorDescriptionShorter) } } + displayName.isEmpty() -> { _states.update { it.copy(isTextErrorColor = true, error = R.string.displayNameErrorDescription) } } + displayName.length > NAME_PADDED_LENGTH -> { _states.update { it.copy(isTextErrorColor = true, error = R.string.displayNameErrorDescriptionShorter) } } else -> { prefs.setProfileName(displayName) @@ -77,7 +77,7 @@ internal class PickDisplayNameViewModel( _states.update { state -> state.copy( displayName = value, - error = value.takeIf { it.length > NAME_PADDED_LENGTH }?.let { R.string.displayNameErrorDescriptionShorter } + isTextErrorColor = false ) } } @@ -103,6 +103,7 @@ internal class PickDisplayNameViewModel( data class State( @StringRes val title: Int = R.string.displayNamePick, @StringRes val description: Int = R.string.displayNameDescription, + val isTextErrorColor: Boolean = false, @StringRes val error: Int? = null, val displayName: String = "" ) diff --git a/app/src/main/java/org/thoughtcrime/securesms/ui/components/Text.kt b/app/src/main/java/org/thoughtcrime/securesms/ui/components/Text.kt index 34aa426ea1..1ff696ce12 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ui/components/Text.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/ui/components/Text.kt @@ -55,13 +55,26 @@ fun PreviewSessionOutlinedTextField() { verticalArrangement = Arrangement.spacedBy(10.dp)) { SessionOutlinedTextField( text = "text", - placeholder = "placeholder" + placeholder = "", ) SessionOutlinedTextField( text = "", placeholder = "placeholder" ) + + SessionOutlinedTextField( + text = "text", + placeholder = "", + error = "error" + ) + + SessionOutlinedTextField( + text = "text onChange after error", + placeholder = "", + error = "error", + isTextErrorColor = false + ) } } } @@ -75,7 +88,8 @@ fun SessionOutlinedTextField( textStyle: TextStyle = base, placeholder: String = "", onContinue: () -> Unit = {}, - error: String? = null + error: String? = null, + isTextErrorColor: Boolean = error != null ) { Column(modifier = modifier.animateContentSize()) { Box( @@ -93,7 +107,7 @@ fun SessionOutlinedTextField( Text( text = placeholder, style = base, - color = LocalColors.current.textSecondary(error != null), + color = LocalColors.current.textSecondary(isTextErrorColor), modifier = Modifier.wrapContentSize() .align(Alignment.CenterStart) .wrapContentSize() @@ -104,7 +118,7 @@ fun SessionOutlinedTextField( value = text, onValueChange = onChange, modifier = Modifier.wrapContentHeight().fillMaxWidth().contentDescription(contentDescription), - textStyle = textStyle.copy(color = LocalColors.current.text(error != null)), + textStyle = textStyle.copy(color = LocalColors.current.text(isTextErrorColor)), cursorBrush = SolidColor(LocalColors.current.text(error != null)), keyboardOptions = KeyboardOptions.Default.copy(imeAction = ImeAction.Done), keyboardActions = KeyboardActions(