Improve account creation when SMS can't be sent

This commit is contained in:
Sylvain Berfini 2026-03-05 16:05:11 +01:00
parent d6af726227
commit 18dbe4356a
6 changed files with 193 additions and 18 deletions

View file

@ -100,23 +100,7 @@ class RegisterFragment : GenericFragment() {
} }
binding.setOpenSubscribeWebPageClickListener { binding.setOpenSubscribeWebPageClickListener {
val url = getString(R.string.web_platform_register_email_url) openSubscribeOnlineWebpage()
try {
val browserIntent = Intent(Intent.ACTION_VIEW, url.toUri())
startActivity(browserIntent)
} catch (ise: IllegalStateException) {
Log.e(
"$TAG Can't start ACTION_VIEW intent for URL [$url], IllegalStateException: $ise"
)
} catch (anfe: ActivityNotFoundException) {
Log.e(
"$TAG Can't start ACTION_VIEW intent for URL [$url], ActivityNotFoundException: $anfe"
)
} catch (e: Exception) {
Log.e(
"$TAG Can't start ACTION_VIEW intent for URL [$url]: $e"
)
}
} }
binding.username.addTextChangedListener(object : TextWatcher { binding.username.addTextChangedListener(object : TextWatcher {
@ -152,6 +136,12 @@ class RegisterFragment : GenericFragment() {
} }
} }
viewModel.accountCantBeCreatedBySmsEvent.observe(viewLifecycleOwner) {
it.consume {
showPhoneNumberValidationNotAvailableDialog()
}
}
viewModel.goToSmsCodeConfirmationViewEvent.observe(viewLifecycleOwner) { viewModel.goToSmsCodeConfirmationViewEvent.observe(viewLifecycleOwner) {
it.consume { it.consume {
Log.i("$TAG Going to SMS code confirmation fragment") Log.i("$TAG Going to SMS code confirmation fragment")
@ -224,4 +214,47 @@ class RegisterFragment : GenericFragment() {
dialog.show() dialog.show()
} }
private fun openSubscribeOnlineWebpage() {
val url = getString(R.string.web_platform_register_email_url)
try {
val browserIntent = Intent(Intent.ACTION_VIEW, url.toUri())
startActivity(browserIntent)
} catch (ise: IllegalStateException) {
Log.e(
"$TAG Can't start ACTION_VIEW intent for URL [$url], IllegalStateException: $ise"
)
} catch (anfe: ActivityNotFoundException) {
Log.e(
"$TAG Can't start ACTION_VIEW intent for URL [$url], ActivityNotFoundException: $anfe"
)
} catch (e: Exception) {
Log.e(
"$TAG Can't start ACTION_VIEW intent for URL [$url]: $e"
)
}
}
private fun showPhoneNumberValidationNotAvailableDialog() {
val model = ConfirmationDialogModel()
val dialog = DialogUtils.getAccountCreationPhoneNumberValidationNotAvailableDialog(
requireActivity(),
model
)
model.dismissEvent.observe(viewLifecycleOwner) {
it.consume {
dialog.dismiss()
}
}
model.confirmEvent.observe(viewLifecycleOwner) {
it.consume {
openSubscribeOnlineWebpage()
dialog.dismiss()
}
}
dialog.show()
}
} }

View file

@ -108,6 +108,10 @@ class AccountCreationViewModel
MutableLiveData() MutableLiveData()
} }
val accountCantBeCreatedBySmsEvent: MutableLiveData<Event<Boolean>> by lazy {
MutableLiveData()
}
private var waitingForFlexiApiPushToken = false private var waitingForFlexiApiPushToken = false
private var waitForPushJob: Job? = null private var waitForPushJob: Job? = null
@ -166,7 +170,11 @@ class AccountCreationViewModel
operationInProgress.postValue(false) operationInProgress.postValue(false)
if (!errorMessage.isNullOrEmpty()) { if (!errorMessage.isNullOrEmpty()) {
showFormattedRedToast(errorMessage, R.drawable.warning_circle) if (request.type == AccountManagerServicesRequest.Type.SendPhoneNumberLinkingCodeBySms && statusCode == 422) {
// Do not show error message sent by the account management platform for this specific scenario
} else {
showFormattedRedToast(errorMessage, R.drawable.warning_circle)
}
} }
for (parameter in parameterErrors?.keys.orEmpty()) { for (parameter in parameterErrors?.keys.orEmpty()) {
@ -186,6 +194,7 @@ class AccountCreationViewModel
waitForPushJob?.cancel() waitForPushJob?.cancel()
} }
AccountManagerServicesRequest.Type.SendPhoneNumberLinkingCodeBySms -> { AccountManagerServicesRequest.Type.SendPhoneNumberLinkingCodeBySms -> {
Log.e("$TAG Error sending SMS code, clearing auth info & account")
val authInfo = accountCreatedAuthInfo val authInfo = accountCreatedAuthInfo
if (authInfo != null) { if (authInfo != null) {
coreContext.core.removeAuthInfo(authInfo) coreContext.core.removeAuthInfo(authInfo)
@ -194,6 +203,10 @@ class AccountCreationViewModel
if (account != null) { if (account != null) {
coreContext.core.removeAccount(account) coreContext.core.removeAccount(account)
} }
if (statusCode == 422) {
accountCantBeCreatedBySmsEvent.postValue(Event(true))
}
} }
else -> { else -> {
} }

View file

@ -66,6 +66,7 @@ import org.linphone.ui.main.contacts.model.ContactTrustDialogModel
import org.linphone.ui.main.contacts.model.NumberOrAddressPickerDialogModel import org.linphone.ui.main.contacts.model.NumberOrAddressPickerDialogModel
import org.linphone.ui.main.model.GroupSetOrEditSubjectDialogModel import org.linphone.ui.main.model.GroupSetOrEditSubjectDialogModel
import androidx.core.graphics.drawable.toDrawable import androidx.core.graphics.drawable.toDrawable
import org.linphone.databinding.DialogAssistantCreateAccountPhoneNumberValidationNotAvailableBinding
import org.linphone.databinding.DialogDeleteChatMessageBinding import org.linphone.databinding.DialogDeleteChatMessageBinding
import org.linphone.databinding.DialogManageAccountOutboundProxyHelpBinding import org.linphone.databinding.DialogManageAccountOutboundProxyHelpBinding
import org.linphone.ui.main.chat.model.MessageDeleteDialogModel import org.linphone.ui.main.chat.model.MessageDeleteDialogModel
@ -105,6 +106,22 @@ class DialogUtils {
return getDialog(context, binding) return getDialog(context, binding)
} }
@UiThread
fun getAccountCreationPhoneNumberValidationNotAvailableDialog(
context: Context,
viewModel: ConfirmationDialogModel
): Dialog {
val binding: DialogAssistantCreateAccountPhoneNumberValidationNotAvailableBinding = DataBindingUtil.inflate(
LayoutInflater.from(context),
R.layout.dialog_assistant_create_account_phone_number_validation_not_available,
null,
false
)
binding.viewModel = viewModel
return getDialog(context, binding)
}
@UiThread @UiThread
fun getAccountInternationalPrefixHelpDialog(context: Context): Dialog { fun getAccountInternationalPrefixHelpDialog(context: Context): Dialog {
val binding: DialogManageAccountInternationalPrefixHelpBinding = DataBindingUtil.inflate( val binding: DialogManageAccountInternationalPrefixHelpBinding = DataBindingUtil.inflate(

View file

@ -0,0 +1,106 @@
<?xml version="1.0" encoding="utf-8"?>
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<import type="android.view.View" />
<variable
name="viewModel"
type="org.linphone.utils.ConfirmationDialogModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:onClick="@{() -> viewModel.dismiss()}"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/dialog_background"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp"
android:layout_marginBottom="2dp"
android:src="@drawable/shape_dialog_background"
android:contentDescription="@null"
app:layout_constraintWidth_max="@dimen/dialog_max_width"
app:layout_constraintBottom_toBottomOf="@id/anchor"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/title" />
<androidx.appcompat.widget.AppCompatTextView
style="@style/section_header_style"
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:paddingTop="@dimen/dialog_top_bottom_margin"
android:text="@string/assistant_dialog_phone_number_validation_not_available_title"
app:layout_constraintVertical_chainStyle="packed"
app:layout_constraintBottom_toTopOf="@id/message"
app:layout_constraintStart_toStartOf="@id/dialog_background"
app:layout_constraintEnd_toEndOf="@id/dialog_background"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatTextView
style="@style/default_text_style"
android:id="@+id/message"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:layout_marginEnd="15dp"
android:layout_marginTop="10dp"
android:text="@string/assistant_dialog_phone_number_validation_not_available_message"
android:textSize="14sp"
app:layout_constraintBottom_toTopOf="@id/cancel"
app:layout_constraintStart_toStartOf="@id/dialog_background"
app:layout_constraintEnd_toEndOf="@id/dialog_background"
app:layout_constraintTop_toBottomOf="@id/title" />
<androidx.appcompat.widget.AppCompatTextView
android:onClick="@{() -> viewModel.confirm()}"
style="@style/primary_dialog_button_label_style"
android:id="@+id/confirm"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:layout_marginEnd="15dp"
android:text="@string/assistant_dialog_phone_number_validation_not_available_register_button_label"
app:layout_constrainedWidth="true"
app:layout_constraintHorizontal_bias="1"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="@id/dialog_background"
app:layout_constraintEnd_toStartOf="@id/cancel"
app:layout_constraintTop_toTopOf="@id/cancel"
app:layout_constraintBottom_toBottomOf="@id/cancel"/>
<androidx.appcompat.widget.AppCompatTextView
android:onClick="@{() -> viewModel.dismiss()}"
style="@style/secondary_dialog_button_label_style"
android:id="@+id/cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:layout_marginStart="15dp"
android:layout_marginEnd="15dp"
android:text="@string/dialog_cancel"
app:layout_constrainedWidth="true"
app:layout_constraintStart_toEndOf="@id/confirm"
app:layout_constraintEnd_toEndOf="@id/dialog_background"
app:layout_constraintTop_toBottomOf="@id/message"
app:layout_constraintBottom_toTopOf="@id/anchor"/>
<View
android:id="@+id/anchor"
android:layout_width="wrap_content"
android:layout_height="@dimen/dialog_top_bottom_margin"
app:layout_constraintTop_toBottomOf="@id/cancel"
app:layout_constraintStart_toStartOf="@id/dialog_background"
app:layout_constraintEnd_toEndOf="@id/dialog_background"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View file

@ -108,6 +108,9 @@
<string name="assistant_dialog_general_terms_and_privacy_policy_message">En continuant, vous acceptez nos %1$s et %2$s.</string> <string name="assistant_dialog_general_terms_and_privacy_policy_message">En continuant, vous acceptez nos %1$s et %2$s.</string>
<string name="assistant_dialog_confirm_phone_number_title">Confirmez votre numéro de téléphone</string> <string name="assistant_dialog_confirm_phone_number_title">Confirmez votre numéro de téléphone</string>
<string name="assistant_dialog_confirm_phone_number_message">Êtes-vous sûr que le %s est votre numéro de téléphone ?</string> <string name="assistant_dialog_confirm_phone_number_message">Êtes-vous sûr que le %s est votre numéro de téléphone ?</string>
<string name="assistant_dialog_phone_number_validation_not_available_title">Inscription par téléphone indisponible</string>
<string name="assistant_dialog_phone_number_validation_not_available_message">L\'inscription par numéro de téléphone n\'est pas disponible, veuillez utiliser l\'inscription par adresse email.</string>
<string name="assistant_dialog_phone_number_validation_not_available_register_button_label">S\'inscrire avec un email</string>
<string name="assistant_account_login">Connexion</string> <string name="assistant_account_login">Connexion</string>
<string name="assistant_scan_qr_code">Scanner un QR code</string> <string name="assistant_scan_qr_code">Scanner un QR code</string>
<string name="assistant_qr_code_invalid_toast">Ce QR code est invalide !</string> <string name="assistant_qr_code_invalid_toast">Ce QR code est invalide !</string>

View file

@ -150,6 +150,9 @@
<string name="assistant_dialog_general_terms_and_privacy_policy_message">By continuing, you accept our %1$s and %2$s.</string> <string name="assistant_dialog_general_terms_and_privacy_policy_message">By continuing, you accept our %1$s and %2$s.</string>
<string name="assistant_dialog_confirm_phone_number_title">Confirm phone number</string> <string name="assistant_dialog_confirm_phone_number_title">Confirm phone number</string>
<string name="assistant_dialog_confirm_phone_number_message">Are you sure your phone number is %s?</string> <string name="assistant_dialog_confirm_phone_number_message">Are you sure your phone number is %s?</string>
<string name="assistant_dialog_phone_number_validation_not_available_title">Phone number validation not available</string>
<string name="assistant_dialog_phone_number_validation_not_available_message">Phone number validation is not available, please use email account creation process.</string>
<string name="assistant_dialog_phone_number_validation_not_available_register_button_label">Register with an email</string>
<string name="assistant_account_login">Login</string> <string name="assistant_account_login">Login</string>
<string name="assistant_scan_qr_code">Scan QR code</string> <string name="assistant_scan_qr_code">Scan QR code</string>
<string name="assistant_qr_code_invalid_toast">Invalid QR code!</string> <string name="assistant_qr_code_invalid_toast">Invalid QR code!</string>