mirror of
https://github.com/signalapp/Signal-Android.git
synced 2025-12-24 21:15:48 +00:00
Fix phone number formatter in Registration V2.
This commit is contained in:
committed by
Cody Henthorne
parent
b771a21518
commit
6ad72f00af
@@ -3,7 +3,7 @@
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.registration.v2.ui.shared
|
||||
package org.thoughtcrime.securesms.registration.v2.ui
|
||||
|
||||
/**
|
||||
* An ordered list of checkpoints of the registration process.
|
||||
@@ -12,7 +12,6 @@ import androidx.activity.viewModels
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.thoughtcrime.securesms.BaseActivity
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.registration.v2.ui.shared.RegistrationV2ViewModel
|
||||
|
||||
/**
|
||||
* Activity to hold the entire registration process.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.registration.v2.ui.shared
|
||||
package org.thoughtcrime.securesms.registration.v2.ui
|
||||
|
||||
import com.google.i18n.phonenumbers.Phonenumber
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.registration.v2.ui.shared
|
||||
package org.thoughtcrime.securesms.registration.v2.ui
|
||||
|
||||
import android.content.Context
|
||||
import androidx.lifecycle.ViewModel
|
||||
@@ -26,7 +26,6 @@ import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
import org.thoughtcrime.securesms.registration.RegistrationData
|
||||
import org.thoughtcrime.securesms.registration.RegistrationUtil
|
||||
import org.thoughtcrime.securesms.registration.v2.data.RegistrationRepository
|
||||
import org.thoughtcrime.securesms.registration.v2.ui.toE164
|
||||
import org.thoughtcrime.securesms.util.FeatureFlags
|
||||
import org.thoughtcrime.securesms.util.Util
|
||||
import org.thoughtcrime.securesms.util.dualsim.MccMncProducer
|
||||
@@ -24,8 +24,8 @@ import org.thoughtcrime.securesms.profiles.edit.CreateProfileActivity
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
import org.thoughtcrime.securesms.registration.fragments.RegistrationViewDelegate.setDebugLogSubmitMultiTapView
|
||||
import org.thoughtcrime.securesms.registration.fragments.SignalStrengthPhoneStateListener
|
||||
import org.thoughtcrime.securesms.registration.v2.ui.shared.RegistrationCheckpoint
|
||||
import org.thoughtcrime.securesms.registration.v2.ui.shared.RegistrationV2ViewModel
|
||||
import org.thoughtcrime.securesms.registration.v2.ui.RegistrationCheckpoint
|
||||
import org.thoughtcrime.securesms.registration.v2.ui.RegistrationV2ViewModel
|
||||
|
||||
/**
|
||||
* The final screen of account registration, where the user enters their verification code.
|
||||
|
||||
@@ -21,9 +21,9 @@ import org.signal.core.util.logging.Log
|
||||
import org.thoughtcrime.securesms.compose.ComposeFragment
|
||||
import org.thoughtcrime.securesms.registration.compose.GrantPermissionsScreen
|
||||
import org.thoughtcrime.securesms.registration.fragments.WelcomePermissions
|
||||
import org.thoughtcrime.securesms.registration.v2.ui.shared.RegistrationCheckpoint
|
||||
import org.thoughtcrime.securesms.registration.v2.ui.shared.RegistrationV2State
|
||||
import org.thoughtcrime.securesms.registration.v2.ui.shared.RegistrationV2ViewModel
|
||||
import org.thoughtcrime.securesms.registration.v2.ui.RegistrationCheckpoint
|
||||
import org.thoughtcrime.securesms.registration.v2.ui.RegistrationV2State
|
||||
import org.thoughtcrime.securesms.registration.v2.ui.RegistrationV2ViewModel
|
||||
import org.thoughtcrime.securesms.util.BackupUtil
|
||||
import org.thoughtcrime.securesms.util.navigation.safeNavigate
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ package org.thoughtcrime.securesms.registration.v2.ui.phonenumber
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.text.SpannableStringBuilder
|
||||
import android.text.TextWatcher
|
||||
import android.view.KeyEvent
|
||||
import android.view.Menu
|
||||
import android.view.MenuInflater
|
||||
@@ -38,9 +39,9 @@ import org.thoughtcrime.securesms.databinding.FragmentRegistrationEnterPhoneNumb
|
||||
import org.thoughtcrime.securesms.phonenumbers.PhoneNumberFormatter
|
||||
import org.thoughtcrime.securesms.registration.fragments.RegistrationViewDelegate.setDebugLogSubmitMultiTapView
|
||||
import org.thoughtcrime.securesms.registration.util.CountryPrefix
|
||||
import org.thoughtcrime.securesms.registration.v2.ui.shared.RegistrationCheckpoint
|
||||
import org.thoughtcrime.securesms.registration.v2.ui.shared.RegistrationV2State
|
||||
import org.thoughtcrime.securesms.registration.v2.ui.shared.RegistrationV2ViewModel
|
||||
import org.thoughtcrime.securesms.registration.v2.ui.RegistrationCheckpoint
|
||||
import org.thoughtcrime.securesms.registration.v2.ui.RegistrationV2State
|
||||
import org.thoughtcrime.securesms.registration.v2.ui.RegistrationV2ViewModel
|
||||
import org.thoughtcrime.securesms.registration.v2.ui.toE164
|
||||
import org.thoughtcrime.securesms.util.PlayServicesUtil
|
||||
import org.thoughtcrime.securesms.util.SpanUtil
|
||||
@@ -63,8 +64,11 @@ class EnterPhoneNumberV2Fragment : LoggingFragment(R.layout.fragment_registratio
|
||||
private lateinit var phoneNumberInputLayout: TextInputEditText
|
||||
private lateinit var spinnerView: MaterialAutoCompleteTextView
|
||||
|
||||
private var currentPhoneNumberFormatter: TextWatcher? = null
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
setDebugLogSubmitMultiTapView(binding.verifyHeader)
|
||||
requireActivity().onBackPressedDispatcher.addCallback(
|
||||
viewLifecycleOwner,
|
||||
object : OnBackPressedCallback(true) {
|
||||
@@ -80,25 +84,14 @@ class EnterPhoneNumberV2Fragment : LoggingFragment(R.layout.fragment_registratio
|
||||
R.layout.registration_country_code_dropdown_item,
|
||||
fragmentViewModel.supportedCountryPrefixes
|
||||
)
|
||||
setDebugLogSubmitMultiTapView(binding.verifyHeader)
|
||||
binding.registerButton.setOnClickListener { onRegistrationButtonClicked() }
|
||||
|
||||
binding.toolbar.title = null
|
||||
binding.toolbar.title = ""
|
||||
val activity = requireActivity() as AppCompatActivity
|
||||
activity.setSupportActionBar(binding.toolbar)
|
||||
|
||||
requireActivity().addMenuProvider(UseProxyMenuProvider(), viewLifecycleOwner)
|
||||
|
||||
val existingPhoneNumber = sharedViewModel.uiState.value?.phoneNumber
|
||||
if (existingPhoneNumber != null) {
|
||||
fragmentViewModel.restoreState(existingPhoneNumber)
|
||||
fragmentViewModel.phoneNumber()?.let {
|
||||
phoneNumberInputLayout.setText(it.nationalNumber.toString())
|
||||
}
|
||||
} else if (spinnerView.editableText.isBlank()) {
|
||||
spinnerView.setText(fragmentViewModel.countryPrefix().toString())
|
||||
}
|
||||
|
||||
sharedViewModel.uiState.observe(viewLifecycleOwner) { sharedState ->
|
||||
presentRegisterButton(sharedState)
|
||||
presentProgressBar(sharedState.inProgress, sharedState.isReRegister)
|
||||
@@ -108,6 +101,19 @@ 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")
|
||||
}
|
||||
}
|
||||
|
||||
if (fragmentViewModel.isEnteredNumberValid(fragmentState)) {
|
||||
sharedViewModel.setPhoneNumber(fragmentViewModel.parsePhoneNumber(fragmentState))
|
||||
} else {
|
||||
@@ -121,12 +127,26 @@ class EnterPhoneNumberV2Fragment : LoggingFragment(R.layout.fragment_registratio
|
||||
|
||||
initializeInputFields()
|
||||
|
||||
val existingPhoneNumber = sharedViewModel.uiState.value?.phoneNumber
|
||||
if (existingPhoneNumber != null) {
|
||||
fragmentViewModel.restoreState(existingPhoneNumber)
|
||||
fragmentViewModel.phoneNumber()?.let {
|
||||
phoneNumberInputLayout.setText(it.nationalNumber.toString())
|
||||
}
|
||||
} else if (spinnerView.editableText.isBlank()) {
|
||||
spinnerView.setText(fragmentViewModel.countryPrefix().toString())
|
||||
}
|
||||
|
||||
ViewUtil.focusAndShowKeyboard(phoneNumberInputLayout)
|
||||
}
|
||||
|
||||
private fun initializeInputFields() {
|
||||
binding.countryCode.editText?.addTextChangedListener { s ->
|
||||
val countryCode: Int = s.toString().toInt()
|
||||
fragmentViewModel.setCountry(countryCode)
|
||||
}
|
||||
|
||||
phoneNumberInputLayout.addTextChangedListener {
|
||||
// TODO [regv2]: country code as you type formatter
|
||||
fragmentViewModel.setPhoneNumber(it?.toString())
|
||||
}
|
||||
phoneNumberInputLayout.onFocusChangeListener = View.OnFocusChangeListener { _: View?, hasFocus: Boolean ->
|
||||
@@ -155,7 +175,6 @@ class EnterPhoneNumberV2Fragment : LoggingFragment(R.layout.fragment_registratio
|
||||
}
|
||||
|
||||
fragmentViewModel.supportedCountryPrefixes.firstOrNull { it.toString() == s.toString() }?.let {
|
||||
// TODO [regv2]: setCountryFormatter(it.regionCode)
|
||||
fragmentViewModel.setCountry(it.digits)
|
||||
val numberLength: Int = phoneNumberInputLayout.text?.length ?: 0
|
||||
phoneNumberInputLayout.setSelection(numberLength, numberLength)
|
||||
|
||||
@@ -5,10 +5,12 @@
|
||||
|
||||
package org.thoughtcrime.securesms.registration.v2.ui.phonenumber
|
||||
|
||||
import android.text.TextWatcher
|
||||
|
||||
/**
|
||||
* State holder for the phone number entry screen, including phone number and Play Services errors.
|
||||
*/
|
||||
data class EnterPhoneNumberV2State(val countryPrefixIndex: Int, val phoneNumber: String, val error: Error = Error.NONE) {
|
||||
data class EnterPhoneNumberV2State(val countryPrefixIndex: Int, val phoneNumber: String, val phoneNumberFormatter: TextWatcher? = null, val error: Error = Error.NONE) {
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
|
||||
@@ -5,13 +5,18 @@
|
||||
|
||||
package org.thoughtcrime.securesms.registration.v2.ui.phonenumber
|
||||
|
||||
import android.telephony.PhoneNumberFormattingTextWatcher
|
||||
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.PhoneNumber
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.thoughtcrime.securesms.registration.util.CountryPrefix
|
||||
|
||||
@@ -51,6 +56,18 @@ class EnterPhoneNumberV2ViewModel : ViewModel() {
|
||||
store.update {
|
||||
it.copy(countryPrefixIndex = matchingIndex)
|
||||
}
|
||||
|
||||
viewModelScope.launch {
|
||||
withContext(Dispatchers.Default) {
|
||||
val regionCode = PhoneNumberUtil.getInstance().getRegionCodeForCountryCode(digits)
|
||||
val textWatcher = PhoneNumberFormattingTextWatcher(regionCode)
|
||||
|
||||
store.update {
|
||||
Log.d(TAG, "Updating phone number formatter in state")
|
||||
it.copy(phoneNumberFormatter = textWatcher)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun parsePhoneNumber(state: EnterPhoneNumberV2State): PhoneNumber {
|
||||
|
||||
@@ -9,7 +9,6 @@ import android.Manifest
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.navigation.fragment.NavHostFragment
|
||||
@@ -21,9 +20,10 @@ import org.thoughtcrime.securesms.databinding.FragmentRegistrationWelcomeV2Bindi
|
||||
import org.thoughtcrime.securesms.permissions.Permissions
|
||||
import org.thoughtcrime.securesms.registration.fragments.RegistrationViewDelegate.setDebugLogSubmitMultiTapView
|
||||
import org.thoughtcrime.securesms.registration.fragments.WelcomePermissions
|
||||
import org.thoughtcrime.securesms.registration.v2.ui.RegistrationV2ViewModel
|
||||
import org.thoughtcrime.securesms.registration.v2.ui.grantpermissions.GrantPermissionsV2Fragment
|
||||
import org.thoughtcrime.securesms.registration.v2.ui.shared.RegistrationV2ViewModel
|
||||
import org.thoughtcrime.securesms.util.BackupUtil
|
||||
import org.thoughtcrime.securesms.util.CommunicationActions
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
||||
import org.thoughtcrime.securesms.util.Util
|
||||
import org.thoughtcrime.securesms.util.navigation.safeNavigate
|
||||
@@ -33,7 +33,6 @@ import kotlin.jvm.optionals.getOrNull
|
||||
* First screen that is displayed on the very first app launch.
|
||||
*/
|
||||
class WelcomeV2Fragment : LoggingFragment(R.layout.fragment_registration_welcome_v2) {
|
||||
private val TAG = Log.tag(WelcomeV2Fragment::class.java)
|
||||
private val sharedViewModel by activityViewModels<RegistrationV2ViewModel>()
|
||||
private val binding: FragmentRegistrationWelcomeV2Binding by ViewBinderDelegate(FragmentRegistrationWelcomeV2Binding::bind)
|
||||
|
||||
@@ -44,7 +43,6 @@ class WelcomeV2Fragment : LoggingFragment(R.layout.fragment_registration_welcome
|
||||
setDebugLogSubmitMultiTapView(binding.title)
|
||||
binding.welcomeContinueButton.setOnClickListener { onContinueClicked() }
|
||||
binding.welcomeTermsButton.setOnClickListener { onTermsClicked() }
|
||||
binding.welcomeTransferOrRestore.setOnClickListener { onRestoreFromBackupClicked() }
|
||||
}
|
||||
|
||||
private fun onContinueClicked() {
|
||||
@@ -65,12 +63,8 @@ class WelcomeV2Fragment : LoggingFragment(R.layout.fragment_registration_welcome
|
||||
NavHostFragment.findNavController(this).safeNavigate(WelcomeV2FragmentDirections.actionSkipRestore())
|
||||
}
|
||||
|
||||
private fun onRestoreFromBackupClicked() {
|
||||
Toast.makeText(requireContext(), "Not yet implemented.", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
private fun onTermsClicked() {
|
||||
Toast.makeText(requireContext(), "Not yet implemented.", Toast.LENGTH_SHORT).show()
|
||||
CommunicationActions.openBrowserLink(requireContext(), TERMS_AND_CONDITIONS_URL)
|
||||
}
|
||||
|
||||
private fun maybePrefillE164() {
|
||||
@@ -87,4 +81,9 @@ class WelcomeV2Fragment : LoggingFragment(R.layout.fragment_registration_welcome
|
||||
Log.i(TAG, "No phone permission.")
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val TAG = Log.tag(WelcomeV2Fragment::class.java)
|
||||
private const val TERMS_AND_CONDITIONS_URL = "https://signal.org/legal"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
app:layout_goneMarginBottom="@dimen/registration_button_bottom_margin"
|
||||
app:materialThemeOverlay="@style/ThemeOverlay.Signal.CircularProgressIndicator.Tonal" />
|
||||
|
||||
<!-- TODO [regv2]: delete this -->
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/welcome_transfer_or_restore"
|
||||
style="@style/Signal.Widget.Button.Large.Secondary"
|
||||
|
||||
Reference in New Issue
Block a user