Fix phone number autofill in Registration V2.
This commit is contained in:
parent
380c33642c
commit
220d3877a2
5 changed files with 62 additions and 42 deletions
|
@ -5,7 +5,10 @@
|
|||
|
||||
package org.thoughtcrime.securesms.registration.v2.ui
|
||||
|
||||
import com.google.i18n.phonenumbers.NumberParseException
|
||||
import com.google.i18n.phonenumbers.PhoneNumberUtil
|
||||
import com.google.i18n.phonenumbers.Phonenumber
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
import org.thoughtcrime.securesms.registration.v2.data.network.Challenge
|
||||
import org.whispersystems.signalservice.internal.push.AuthCredentials
|
||||
|
@ -16,7 +19,7 @@ import org.whispersystems.signalservice.internal.push.AuthCredentials
|
|||
data class RegistrationV2State(
|
||||
val sessionId: String? = null,
|
||||
val enteredCode: String = "",
|
||||
val phoneNumber: Phonenumber.PhoneNumber? = null,
|
||||
val phoneNumber: Phonenumber.PhoneNumber? = fetchExistingE164FromValues(),
|
||||
val inProgress: Boolean = false,
|
||||
val isReRegister: Boolean = false,
|
||||
val recoveryPassword: String? = SignalStore.svr().getRecoveryPassword(),
|
||||
|
@ -43,4 +46,22 @@ data class RegistrationV2State(
|
|||
val networkError: Throwable? = null
|
||||
) {
|
||||
val challengesRemaining: List<Challenge> = challengesRequested.filterNot { it in challengesPresented }
|
||||
|
||||
companion object {
|
||||
private val TAG = Log.tag(RegistrationV2State::class)
|
||||
|
||||
private fun fetchExistingE164FromValues(): Phonenumber.PhoneNumber? {
|
||||
val existingE164 = SignalStore.registrationValues().sessionE164
|
||||
if (existingE164 != null) {
|
||||
try {
|
||||
return PhoneNumberUtil.getInstance().parse(existingE164, null)
|
||||
} catch (ex: NumberParseException) {
|
||||
Log.w(TAG, "Could not parse stored E164.", ex)
|
||||
return null
|
||||
}
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,8 +10,6 @@ import android.content.Context
|
|||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.asLiveData
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.google.i18n.phonenumbers.NumberParseException
|
||||
import com.google.i18n.phonenumbers.PhoneNumberUtil
|
||||
import com.google.i18n.phonenumbers.Phonenumber
|
||||
import kotlinx.coroutines.CoroutineExceptionHandler
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
@ -106,19 +104,8 @@ class RegistrationV2ViewModel : ViewModel() {
|
|||
val isReregister: Boolean
|
||||
get() = store.value.isReRegister
|
||||
|
||||
init {
|
||||
val existingE164 = SignalStore.registrationValues().sessionE164
|
||||
if (existingE164 != null) {
|
||||
try {
|
||||
val existingPhoneNumber = PhoneNumberUtil.getInstance().parse(existingE164, null)
|
||||
if (existingPhoneNumber != null) {
|
||||
setPhoneNumber(existingPhoneNumber)
|
||||
}
|
||||
} catch (ex: NumberParseException) {
|
||||
Log.w(TAG, "Could not parse stored E164.", ex)
|
||||
}
|
||||
}
|
||||
}
|
||||
val phoneNumber: Phonenumber.PhoneNumber?
|
||||
get() = store.value.phoneNumber
|
||||
|
||||
fun maybePrefillE164(context: Context) {
|
||||
Log.v(TAG, "maybePrefillE164()")
|
||||
|
|
|
@ -19,6 +19,7 @@ import androidx.compose.ui.platform.LocalContext
|
|||
import androidx.core.content.ContextCompat
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.navigation.fragment.NavHostFragment
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.navigation.fragment.navArgs
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.thoughtcrime.securesms.compose.ComposeFragment
|
||||
|
@ -101,7 +102,7 @@ class GrantPermissionsV2Fragment : ComposeFragment() {
|
|||
|
||||
private fun proceedToNextScreen() {
|
||||
when (welcomeAction) {
|
||||
WelcomeAction.CONTINUE -> NavHostFragment.findNavController(this).safeNavigate(GrantPermissionsV2FragmentDirections.actionEnterPhoneNumber())
|
||||
WelcomeAction.CONTINUE -> findNavController().safeNavigate(GrantPermissionsV2FragmentDirections.actionEnterPhoneNumber())
|
||||
WelcomeAction.RESTORE_BACKUP -> {
|
||||
val restoreIntent = RestoreActivity.getIntentForRestore(requireActivity())
|
||||
launchRestoreActivity.launch(restoreIntent)
|
||||
|
|
|
@ -130,15 +130,7 @@ class EnterPhoneNumberV2Fragment : LoggingFragment(R.layout.fragment_registratio
|
|||
fragmentViewModel.uiState.observe(viewLifecycleOwner) { fragmentState ->
|
||||
|
||||
fragmentState.phoneNumberFormatter?.let {
|
||||
if (it != currentPhoneNumberFormatter) {
|
||||
currentPhoneNumberFormatter?.let { oldWatcher ->
|
||||
Log.d(TAG, "Removing current phone number formatter in fragment")
|
||||
phoneNumberInputLayout.removeTextChangedListener(oldWatcher)
|
||||
}
|
||||
phoneNumberInputLayout.addTextChangedListener(it)
|
||||
currentPhoneNumberFormatter = it
|
||||
Log.d(TAG, "Updating phone number formatter in fragment")
|
||||
}
|
||||
bindPhoneNumberFormatter(it)
|
||||
}
|
||||
|
||||
if (fragmentViewModel.isEnteredNumberValid(fragmentState)) {
|
||||
|
@ -154,19 +146,33 @@ class EnterPhoneNumberV2Fragment : LoggingFragment(R.layout.fragment_registratio
|
|||
|
||||
initializeInputFields()
|
||||
|
||||
val existingPhoneNumber = sharedViewModel.uiState.value?.phoneNumber
|
||||
val existingPhoneNumber = sharedViewModel.phoneNumber
|
||||
if (existingPhoneNumber != null) {
|
||||
fragmentViewModel.restoreState(existingPhoneNumber)
|
||||
fragmentViewModel.phoneNumber()?.let {
|
||||
phoneNumberInputLayout.setText(it.nationalNumber.toString())
|
||||
spinnerView.setText(existingPhoneNumber.countryCode.toString())
|
||||
fragmentViewModel.formatter?.let {
|
||||
bindPhoneNumberFormatter(it)
|
||||
}
|
||||
phoneNumberInputLayout.setText(existingPhoneNumber.nationalNumber.toString())
|
||||
} else {
|
||||
spinnerView.setText(fragmentViewModel.countryPrefix().toString())
|
||||
}
|
||||
|
||||
spinnerView.setText(fragmentViewModel.countryPrefix().toString())
|
||||
|
||||
ViewUtil.focusAndShowKeyboard(phoneNumberInputLayout)
|
||||
}
|
||||
|
||||
private fun bindPhoneNumberFormatter(formatter: TextWatcher) {
|
||||
if (formatter != currentPhoneNumberFormatter) {
|
||||
currentPhoneNumberFormatter?.let { oldWatcher ->
|
||||
Log.d(TAG, "Removing current phone number formatter in fragment")
|
||||
phoneNumberInputLayout.removeTextChangedListener(oldWatcher)
|
||||
}
|
||||
phoneNumberInputLayout.addTextChangedListener(formatter)
|
||||
currentPhoneNumberFormatter = formatter
|
||||
Log.d(TAG, "Updating phone number formatter in fragment")
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleChallenges(remainingChallenges: List<Challenge>) {
|
||||
when (remainingChallenges.first()) {
|
||||
Challenge.CAPTCHA -> moveToCaptcha()
|
||||
|
@ -187,11 +193,13 @@ class EnterPhoneNumberV2Fragment : LoggingFragment(R.layout.fragment_registratio
|
|||
phoneNumberInputLayout.addTextChangedListener {
|
||||
fragmentViewModel.setPhoneNumber(it?.toString())
|
||||
}
|
||||
|
||||
phoneNumberInputLayout.onFocusChangeListener = View.OnFocusChangeListener { _: View?, hasFocus: Boolean ->
|
||||
if (hasFocus) {
|
||||
binding.scrollView.postDelayed({ binding.scrollView.smoothScrollTo(0, binding.registerButton.bottom) }, 250)
|
||||
}
|
||||
}
|
||||
|
||||
phoneNumberInputLayout.imeOptions = EditorInfo.IME_ACTION_DONE
|
||||
phoneNumberInputLayout.setOnEditorActionListener { v: TextView?, actionId: Int, _: KeyEvent? ->
|
||||
if (actionId == EditorInfo.IME_ACTION_DONE && v != null) {
|
||||
|
@ -298,7 +306,7 @@ class EnterPhoneNumberV2Fragment : LoggingFragment(R.layout.fragment_registratio
|
|||
is VerificationCodeRequestResult.ExternalServiceFailure -> presentRemoteErrorDialog(getString(R.string.RegistrationActivity_unable_to_connect_to_service), skipToNextScreen)
|
||||
is VerificationCodeRequestResult.ImpossibleNumber -> {
|
||||
MaterialAlertDialogBuilder(requireContext()).apply {
|
||||
setMessage(getString(R.string.RegistrationActivity_the_number_you_specified_s_is_invalid, fragmentViewModel.phoneNumber()?.toE164()))
|
||||
setMessage(getString(R.string.RegistrationActivity_the_number_you_specified_s_is_invalid, fragmentViewModel.phoneNumber?.toE164()))
|
||||
setPositiveButton(android.R.string.ok, null)
|
||||
show()
|
||||
}
|
||||
|
@ -369,7 +377,7 @@ class EnterPhoneNumberV2Fragment : LoggingFragment(R.layout.fragment_registratio
|
|||
Dialogs.showAlertDialog(
|
||||
requireContext(),
|
||||
getString(R.string.RegistrationActivity_invalid_number),
|
||||
getString(R.string.RegistrationActivity_the_number_you_specified_s_is_invalid, fragmentViewModel.phoneNumber()?.toE164())
|
||||
getString(R.string.RegistrationActivity_the_number_you_specified_s_is_invalid, fragmentViewModel.phoneNumber?.toE164())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
package org.thoughtcrime.securesms.registration.v2.ui.phonenumber
|
||||
|
||||
import android.telephony.PhoneNumberFormattingTextWatcher
|
||||
import android.text.TextWatcher
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.asLiveData
|
||||
import androidx.lifecycle.viewModelScope
|
||||
|
@ -31,6 +32,17 @@ class EnterPhoneNumberV2ViewModel : ViewModel() {
|
|||
private val store = MutableStateFlow(EnterPhoneNumberV2State())
|
||||
val uiState = store.asLiveData()
|
||||
|
||||
val formatter: TextWatcher?
|
||||
get() = store.value.phoneNumberFormatter
|
||||
|
||||
val phoneNumber: PhoneNumber?
|
||||
get() = try {
|
||||
parsePhoneNumber(store.value)
|
||||
} catch (ex: NumberParseException) {
|
||||
Log.w(TAG, "Could not parse phone number in current state.", ex)
|
||||
null
|
||||
}
|
||||
|
||||
val supportedCountryPrefixes: List<CountryPrefix> = PhoneNumberUtil.getInstance().supportedCallingCodes
|
||||
.map { CountryPrefix(it, PhoneNumberUtil.getInstance().getRegionCodeForCountryCode(it)) }
|
||||
.sortedBy { it.digits }
|
||||
|
@ -45,15 +57,6 @@ class EnterPhoneNumberV2ViewModel : ViewModel() {
|
|||
return supportedCountryPrefixes[store.value.countryPrefixIndex]
|
||||
}
|
||||
|
||||
fun phoneNumber(): PhoneNumber? {
|
||||
return try {
|
||||
parsePhoneNumber(store.value)
|
||||
} catch (ex: NumberParseException) {
|
||||
Log.w(TAG, "Could not parse phone number in current state.", ex)
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
fun setPhoneNumber(phoneNumber: String?) {
|
||||
store.update { it.copy(phoneNumber = phoneNumber ?: "") }
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue