mirror of
https://github.com/signalapp/Signal-Android.git
synced 2025-12-23 20:48:43 +00:00
Update country picker for findBy and changeNumber.
This commit is contained in:
@@ -1,132 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2024 Signal Messenger, LLC
|
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.thoughtcrime.securesms.components.settings.app.changenumber;
|
|
||||||
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.text.Editable;
|
|
||||||
import android.text.TextWatcher;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.EditText;
|
|
||||||
import android.widget.ListView;
|
|
||||||
import android.widget.SimpleAdapter;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.fragment.app.ListFragment;
|
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
|
||||||
import androidx.loader.app.LoaderManager;
|
|
||||||
import androidx.loader.content.Loader;
|
|
||||||
import androidx.navigation.fragment.NavHostFragment;
|
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.R;
|
|
||||||
import org.thoughtcrime.securesms.database.loaders.CountryListLoader;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public final class ChangeNumberCountryPickerFragment extends ListFragment implements LoaderManager.LoaderCallbacks<ArrayList<Map<String, String>>> {
|
|
||||||
|
|
||||||
public static final String KEY_COUNTRY = "country";
|
|
||||||
public static final String KEY_COUNTRY_CODE = "country_code";
|
|
||||||
|
|
||||||
private EditText countryFilter;
|
|
||||||
private ChangeNumberViewModel model;
|
|
||||||
private String resultKey;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) {
|
|
||||||
return inflater.inflate(R.layout.fragment_registration_country_picker, container, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
|
||||||
super.onViewCreated(view, savedInstanceState);
|
|
||||||
|
|
||||||
if (getArguments() != null) {
|
|
||||||
ChangeNumberCountryPickerFragmentArgs arguments = ChangeNumberCountryPickerFragmentArgs.fromBundle(requireArguments());
|
|
||||||
resultKey = arguments.getResultKey();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (resultKey == null) {
|
|
||||||
model = new ViewModelProvider(requireActivity()).get(ChangeNumberViewModel.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
countryFilter = view.findViewById(R.id.country_search);
|
|
||||||
|
|
||||||
countryFilter.addTextChangedListener(new FilterWatcher());
|
|
||||||
LoaderManager.getInstance(this).initLoader(0, null, this).forceLoad();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onListItemClick(@NonNull ListView listView, @NonNull View view, int position, long id) {
|
|
||||||
Map<String, String> item = (Map<String, String>) getListAdapter().getItem(position);
|
|
||||||
|
|
||||||
int countryCode = Integer.parseInt(item.get("country_code").replace("+", ""));
|
|
||||||
String countryName = item.get("country_name");
|
|
||||||
|
|
||||||
if (resultKey == null) {
|
|
||||||
model.setNewCountry(countryCode, countryName);
|
|
||||||
} else {
|
|
||||||
Bundle result = new Bundle();
|
|
||||||
result.putString(KEY_COUNTRY, countryName);
|
|
||||||
result.putInt(KEY_COUNTRY_CODE, countryCode);
|
|
||||||
getParentFragmentManager().setFragmentResult(resultKey, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
NavHostFragment.findNavController(this).navigateUp();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NonNull Loader<ArrayList<Map<String, String>>> onCreateLoader(int id, @Nullable Bundle args) {
|
|
||||||
return new CountryListLoader(getActivity());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onLoadFinished(@NonNull Loader<ArrayList<Map<String, String>>> loader,
|
|
||||||
@NonNull ArrayList<Map<String, String>> results)
|
|
||||||
{
|
|
||||||
((TextView) getListView().getEmptyView()).setText(
|
|
||||||
R.string.country_selection_fragment__no_matching_countries);
|
|
||||||
String[] from = { "country_name", "country_code" };
|
|
||||||
int[] to = { R.id.country_name, R.id.country_code };
|
|
||||||
|
|
||||||
setListAdapter(new SimpleAdapter(getActivity(), results, R.layout.country_list_item, from, to));
|
|
||||||
|
|
||||||
applyFilter(countryFilter.getText());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void applyFilter(@NonNull CharSequence text) {
|
|
||||||
SimpleAdapter listAdapter = (SimpleAdapter) getListAdapter();
|
|
||||||
|
|
||||||
if (listAdapter != null) {
|
|
||||||
listAdapter.getFilter().filter(text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onLoaderReset(@NonNull Loader<ArrayList<Map<String, String>>> loader) {
|
|
||||||
setListAdapter(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private class FilterWatcher implements TextWatcher {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void afterTextChanged(Editable s) {
|
|
||||||
applyFilter(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -14,12 +14,15 @@ import androidx.fragment.app.activityViewModels
|
|||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import com.google.android.material.snackbar.Snackbar
|
import com.google.android.material.snackbar.Snackbar
|
||||||
|
import org.signal.core.util.getParcelableCompat
|
||||||
import org.signal.core.util.logging.Log
|
import org.signal.core.util.logging.Log
|
||||||
import org.thoughtcrime.securesms.LoggingFragment
|
import org.thoughtcrime.securesms.LoggingFragment
|
||||||
import org.thoughtcrime.securesms.R
|
import org.thoughtcrime.securesms.R
|
||||||
import org.thoughtcrime.securesms.components.ViewBinderDelegate
|
import org.thoughtcrime.securesms.components.ViewBinderDelegate
|
||||||
import org.thoughtcrime.securesms.databinding.FragmentChangeNumberEnterPhoneNumberBinding
|
import org.thoughtcrime.securesms.databinding.FragmentChangeNumberEnterPhoneNumberBinding
|
||||||
|
import org.thoughtcrime.securesms.registration.ui.countrycode.Country
|
||||||
import org.thoughtcrime.securesms.registration.util.ChangeNumberInputController
|
import org.thoughtcrime.securesms.registration.util.ChangeNumberInputController
|
||||||
|
import org.thoughtcrime.securesms.registrationv3.ui.countrycode.CountryCodeFragment
|
||||||
import org.thoughtcrime.securesms.util.Dialogs
|
import org.thoughtcrime.securesms.util.Dialogs
|
||||||
import org.thoughtcrime.securesms.util.navigation.safeNavigate
|
import org.thoughtcrime.securesms.util.navigation.safeNavigate
|
||||||
|
|
||||||
@@ -65,15 +68,15 @@ class ChangeNumberEnterPhoneNumberFragment : LoggingFragment(R.layout.fragment_c
|
|||||||
override fun onNumberInputDone(view: View) = Unit
|
override fun onNumberInputDone(view: View) = Unit
|
||||||
|
|
||||||
override fun onPickCountry(view: View) {
|
override fun onPickCountry(view: View) {
|
||||||
findNavController().safeNavigate(ChangeNumberEnterPhoneNumberFragmentDirections.actionEnterPhoneNumberChangeFragmentToCountryPickerFragment(OLD_NUMBER_COUNTRY_SELECT))
|
findNavController().safeNavigate(ChangeNumberEnterPhoneNumberFragmentDirections.actionEnterPhoneNumberChangeFragmentToCountryPickerFragment(OLD_NUMBER_COUNTRY_SELECT, viewModel.oldCountry))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setNationalNumber(number: String) {
|
override fun setNationalNumber(number: String) {
|
||||||
viewModel.setOldNationalNumber(number)
|
viewModel.setOldNationalNumber(number)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setCountry(countryCode: Int) {
|
override fun setCountry(country: Country) {
|
||||||
viewModel.setOldCountry(countryCode)
|
viewModel.setOldCountry(country)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -96,25 +99,27 @@ class ChangeNumberEnterPhoneNumberFragment : LoggingFragment(R.layout.fragment_c
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onPickCountry(view: View) {
|
override fun onPickCountry(view: View) {
|
||||||
findNavController().safeNavigate(ChangeNumberEnterPhoneNumberFragmentDirections.actionEnterPhoneNumberChangeFragmentToCountryPickerFragment(NEW_NUMBER_COUNTRY_SELECT))
|
findNavController().safeNavigate(ChangeNumberEnterPhoneNumberFragmentDirections.actionEnterPhoneNumberChangeFragmentToCountryPickerFragment(NEW_NUMBER_COUNTRY_SELECT, viewModel.newCountry))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setNationalNumber(number: String) {
|
override fun setNationalNumber(number: String) {
|
||||||
viewModel.setNewNationalNumber(number)
|
viewModel.setNewNationalNumber(number)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setCountry(countryCode: Int) {
|
override fun setCountry(country: Country) {
|
||||||
viewModel.setNewCountry(countryCode)
|
viewModel.setNewCountry(country)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
parentFragmentManager.setFragmentResultListener(OLD_NUMBER_COUNTRY_SELECT, this) { _: String, bundle: Bundle ->
|
parentFragmentManager.setFragmentResultListener(OLD_NUMBER_COUNTRY_SELECT, this) { _: String, bundle: Bundle ->
|
||||||
viewModel.setOldCountry(bundle.getInt(ChangeNumberCountryPickerFragment.KEY_COUNTRY_CODE), bundle.getString(ChangeNumberCountryPickerFragment.KEY_COUNTRY))
|
val country = bundle.getParcelableCompat(CountryCodeFragment.RESULT_COUNTRY, Country::class.java)!!
|
||||||
|
viewModel.setOldCountry(country)
|
||||||
}
|
}
|
||||||
|
|
||||||
parentFragmentManager.setFragmentResultListener(NEW_NUMBER_COUNTRY_SELECT, this) { _: String, bundle: Bundle ->
|
parentFragmentManager.setFragmentResultListener(NEW_NUMBER_COUNTRY_SELECT, this) { _: String, bundle: Bundle ->
|
||||||
viewModel.setNewCountry(bundle.getInt(ChangeNumberCountryPickerFragment.KEY_COUNTRY_CODE), bundle.getString(ChangeNumberCountryPickerFragment.KEY_COUNTRY))
|
val country = bundle.getParcelableCompat(CountryCodeFragment.RESULT_COUNTRY, Country::class.java)!!
|
||||||
|
viewModel.setNewCountry(country)
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.liveOldNumberState.observe(viewLifecycleOwner, oldController::updateNumber)
|
viewModel.liveOldNumberState.observe(viewLifecycleOwner, oldController::updateNumber)
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ package org.thoughtcrime.securesms.components.settings.app.changenumber
|
|||||||
|
|
||||||
import org.thoughtcrime.securesms.registration.data.network.Challenge
|
import org.thoughtcrime.securesms.registration.data.network.Challenge
|
||||||
import org.thoughtcrime.securesms.registration.data.network.VerificationCodeRequestResult
|
import org.thoughtcrime.securesms.registration.data.network.VerificationCodeRequestResult
|
||||||
|
import org.thoughtcrime.securesms.registration.ui.countrycode.Country
|
||||||
import org.thoughtcrime.securesms.registration.viewmodel.NumberViewState
|
import org.thoughtcrime.securesms.registration.viewmodel.NumberViewState
|
||||||
import org.whispersystems.signalservice.api.svr.Svr3Credentials
|
import org.whispersystems.signalservice.api.svr.Svr3Credentials
|
||||||
import org.whispersystems.signalservice.internal.push.AuthCredentials
|
import org.whispersystems.signalservice.internal.push.AuthCredentials
|
||||||
@@ -32,7 +33,9 @@ data class ChangeNumberState(
|
|||||||
val captchaToken: String? = null,
|
val captchaToken: String? = null,
|
||||||
val challengesRequested: List<Challenge> = emptyList(),
|
val challengesRequested: List<Challenge> = emptyList(),
|
||||||
val challengesPresented: Set<Challenge> = emptySet(),
|
val challengesPresented: Set<Challenge> = emptySet(),
|
||||||
val allowedToRequestCode: Boolean = false
|
val allowedToRequestCode: Boolean = false,
|
||||||
|
val oldCountry: Country? = null,
|
||||||
|
val newCountry: Country? = null
|
||||||
) {
|
) {
|
||||||
val challengesRemaining: List<Challenge> = challengesRequested.filterNot { it in challengesPresented }
|
val challengesRemaining: List<Challenge> = challengesRequested.filterNot { it in challengesPresented }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import org.thoughtcrime.securesms.registration.data.network.SessionMetadataResul
|
|||||||
import org.thoughtcrime.securesms.registration.data.network.VerificationCodeRequestResult
|
import org.thoughtcrime.securesms.registration.data.network.VerificationCodeRequestResult
|
||||||
import org.thoughtcrime.securesms.registration.sms.SmsRetrieverReceiver
|
import org.thoughtcrime.securesms.registration.sms.SmsRetrieverReceiver
|
||||||
import org.thoughtcrime.securesms.registration.ui.RegistrationViewModel
|
import org.thoughtcrime.securesms.registration.ui.RegistrationViewModel
|
||||||
|
import org.thoughtcrime.securesms.registration.ui.countrycode.Country
|
||||||
import org.thoughtcrime.securesms.registration.viewmodel.NumberViewState
|
import org.thoughtcrime.securesms.registration.viewmodel.NumberViewState
|
||||||
import org.thoughtcrime.securesms.registration.viewmodel.SvrAuthCredentialSet
|
import org.thoughtcrime.securesms.registration.viewmodel.SvrAuthCredentialSet
|
||||||
import org.thoughtcrime.securesms.util.dualsim.MccMncProducer
|
import org.thoughtcrime.securesms.util.dualsim.MccMncProducer
|
||||||
@@ -100,15 +101,24 @@ class ChangeNumberViewModel : ViewModel() {
|
|||||||
val svrTriesRemaining: Int
|
val svrTriesRemaining: Int
|
||||||
get() = store.value.svrTriesRemaining
|
get() = store.value.svrTriesRemaining
|
||||||
|
|
||||||
|
val oldCountry: Country?
|
||||||
|
get() = store.value.oldCountry
|
||||||
|
|
||||||
|
val newCountry: Country?
|
||||||
|
get() = store.value.newCountry
|
||||||
|
|
||||||
fun setOldNationalNumber(updatedNumber: String) {
|
fun setOldNationalNumber(updatedNumber: String) {
|
||||||
store.update {
|
store.update {
|
||||||
it.copy(oldPhoneNumber = oldNumberState.toBuilder().nationalNumber(updatedNumber).build())
|
it.copy(oldPhoneNumber = oldNumberState.toBuilder().nationalNumber(updatedNumber).build())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setOldCountry(countryCode: Int, country: String? = null) {
|
fun setOldCountry(country: Country) {
|
||||||
store.update {
|
store.update {
|
||||||
it.copy(oldPhoneNumber = oldNumberState.toBuilder().selectedCountryDisplayName(country).countryCode(countryCode).build())
|
it.copy(
|
||||||
|
oldPhoneNumber = oldNumberState.toBuilder().selectedCountryDisplayName(country.name).countryCode(country.countryCode).build(),
|
||||||
|
oldCountry = country
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,9 +128,12 @@ class ChangeNumberViewModel : ViewModel() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setNewCountry(countryCode: Int, country: String? = null) {
|
fun setNewCountry(country: Country) {
|
||||||
store.update {
|
store.update {
|
||||||
it.copy(number = number.toBuilder().selectedCountryDisplayName(country).countryCode(countryCode).build())
|
it.copy(
|
||||||
|
number = number.toBuilder().selectedCountryDisplayName(country.name).countryCode(country.countryCode).build(),
|
||||||
|
newCountry = country
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import androidx.activity.compose.setContent
|
|||||||
import androidx.activity.result.ActivityResultLauncher
|
import androidx.activity.result.ActivityResultLauncher
|
||||||
import androidx.activity.result.contract.ActivityResultContract
|
import androidx.activity.result.contract.ActivityResultContract
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.Arrangement.Absolute.spacedBy
|
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
@@ -26,8 +25,6 @@ import androidx.compose.foundation.layout.heightIn
|
|||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
|
||||||
import androidx.compose.foundation.lazy.items
|
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.foundation.text.KeyboardActions
|
import androidx.compose.foundation.text.KeyboardActions
|
||||||
import androidx.compose.foundation.text.KeyboardOptions
|
import androidx.compose.foundation.text.KeyboardOptions
|
||||||
@@ -49,14 +46,9 @@ import androidx.compose.ui.platform.LocalContext
|
|||||||
import androidx.compose.ui.res.dimensionResource
|
import androidx.compose.ui.res.dimensionResource
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.AnnotatedString
|
|
||||||
import androidx.compose.ui.text.SpanStyle
|
|
||||||
import androidx.compose.ui.text.buildAnnotatedString
|
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
|
||||||
import androidx.compose.ui.text.input.ImeAction
|
import androidx.compose.ui.text.input.ImeAction
|
||||||
import androidx.compose.ui.text.input.KeyboardType
|
import androidx.compose.ui.text.input.KeyboardType
|
||||||
import androidx.compose.ui.text.input.VisualTransformation
|
import androidx.compose.ui.text.input.VisualTransformation
|
||||||
import androidx.compose.ui.text.intl.Locale
|
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
@@ -83,7 +75,9 @@ import org.thoughtcrime.securesms.components.settings.app.usernamelinks.main.Use
|
|||||||
import org.thoughtcrime.securesms.invites.InviteActions
|
import org.thoughtcrime.securesms.invites.InviteActions
|
||||||
import org.thoughtcrime.securesms.phonenumbers.PhoneNumberVisualTransformation
|
import org.thoughtcrime.securesms.phonenumbers.PhoneNumberVisualTransformation
|
||||||
import org.thoughtcrime.securesms.recipients.RecipientId
|
import org.thoughtcrime.securesms.recipients.RecipientId
|
||||||
import org.thoughtcrime.securesms.registration.util.CountryPrefix
|
import org.thoughtcrime.securesms.registration.ui.countrycode.Country
|
||||||
|
import org.thoughtcrime.securesms.registration.ui.countrycode.CountryCodeState
|
||||||
|
import org.thoughtcrime.securesms.registrationv3.ui.countrycode.Screen
|
||||||
import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme
|
import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme
|
||||||
import org.thoughtcrime.securesms.util.viewModel
|
import org.thoughtcrime.securesms.util.viewModel
|
||||||
import org.whispersystems.signalservice.api.util.PhoneNumberFormatter
|
import org.whispersystems.signalservice.api.util.PhoneNumberFormatter
|
||||||
@@ -160,7 +154,7 @@ class FindByActivity : PassphraseRequiredActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onSelectCountryPrefixClick = {
|
onSelectCountryClick = {
|
||||||
navController.navigate("select-country-prefix")
|
navController.navigate("select-country-prefix")
|
||||||
},
|
},
|
||||||
onQrCodeScanClicked = {
|
onQrCodeScanClicked = {
|
||||||
@@ -171,24 +165,21 @@ class FindByActivity : PassphraseRequiredActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
composable("select-country-prefix") {
|
composable("select-country-prefix") {
|
||||||
Scaffolds.Settings(
|
Screen(
|
||||||
title = stringResource(id = R.string.FindByActivity__select_country_code),
|
state = CountryCodeState(
|
||||||
onNavigationClick = { navController.popBackStack() },
|
query = state.query,
|
||||||
navigationIconPainter = painterResource(id = R.drawable.symbol_arrow_left_24)
|
filteredList = state.filteredCountries,
|
||||||
) { paddingValues ->
|
countryList = state.supportedCountries
|
||||||
SelectCountryScreen(
|
),
|
||||||
paddingValues = paddingValues,
|
title = stringResource(R.string.FindByActivity__select_country_code),
|
||||||
searchEntry = state.countryPrefixSearchEntry,
|
onSearch = { search -> viewModel.filterCountries(search) },
|
||||||
onSearchEntryChanged = viewModel::onCountryPrefixSearchEntryChanged,
|
onDismissed = { navController.popBackStack() },
|
||||||
supportedCountryPrefixes = state.supportedCountryPrefixes,
|
onClick = { country ->
|
||||||
onCountryPrefixSelected = {
|
viewModel.onCountrySelected(country)
|
||||||
navController.popBackStack()
|
navController.popBackStack()
|
||||||
viewModel.onCountryPrefixSelected(it)
|
|
||||||
viewModel.onCountryPrefixSearchEntryChanged("")
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
dialog("invalid-entry") {
|
dialog("invalid-entry") {
|
||||||
val title = if (state.mode == FindByMode.USERNAME) {
|
val title = if (state.mode == FindByMode.USERNAME) {
|
||||||
@@ -201,8 +192,8 @@ class FindByActivity : PassphraseRequiredActivity() {
|
|||||||
stringResource(id = R.string.FindByActivity__s_is_not_a_valid_username, state.userEntry)
|
stringResource(id = R.string.FindByActivity__s_is_not_a_valid_username, state.userEntry)
|
||||||
} else {
|
} else {
|
||||||
val formattedNumber = remember(state.userEntry) {
|
val formattedNumber = remember(state.userEntry) {
|
||||||
val cleansed = state.userEntry.removePrefix(state.selectedCountryPrefix.digits.toString())
|
val cleansed = state.userEntry.removePrefix(state.selectedCountry.countryCode.toString())
|
||||||
PhoneNumberFormatter.formatE164(state.selectedCountryPrefix.digits.toString(), cleansed)
|
PhoneNumberFormatter.formatE164(state.selectedCountry.countryCode.toString(), cleansed)
|
||||||
}
|
}
|
||||||
stringResource(id = R.string.FindByActivity__s_is_not_a_valid_phone_number, formattedNumber)
|
stringResource(id = R.string.FindByActivity__s_is_not_a_valid_phone_number, formattedNumber)
|
||||||
}
|
}
|
||||||
@@ -240,8 +231,8 @@ class FindByActivity : PassphraseRequiredActivity() {
|
|||||||
stringResource(id = R.string.FindByActivity__s_is_not_a_signal_user, state.userEntry)
|
stringResource(id = R.string.FindByActivity__s_is_not_a_signal_user, state.userEntry)
|
||||||
} else {
|
} else {
|
||||||
val formattedNumber = remember(state.userEntry) {
|
val formattedNumber = remember(state.userEntry) {
|
||||||
val cleansed = state.userEntry.removePrefix(state.selectedCountryPrefix.digits.toString())
|
val cleansed = state.userEntry.removePrefix(state.selectedCountry.countryCode.toString())
|
||||||
PhoneNumberFormatter.formatE164(state.selectedCountryPrefix.digits.toString(), cleansed)
|
PhoneNumberFormatter.formatE164(state.selectedCountry.countryCode.toString(), cleansed)
|
||||||
}
|
}
|
||||||
stringResource(id = R.string.FindByActivity__s_is_not_a_signal_user_would, formattedNumber)
|
stringResource(id = R.string.FindByActivity__s_is_not_a_signal_user_would, formattedNumber)
|
||||||
}
|
}
|
||||||
@@ -303,7 +294,7 @@ private fun Content(
|
|||||||
state: FindByState,
|
state: FindByState,
|
||||||
onUserEntryChanged: (String) -> Unit,
|
onUserEntryChanged: (String) -> Unit,
|
||||||
onNextClick: () -> Unit,
|
onNextClick: () -> Unit,
|
||||||
onSelectCountryPrefixClick: () -> Unit,
|
onSelectCountryClick: () -> Unit,
|
||||||
onQrCodeScanClicked: () -> Unit
|
onQrCodeScanClicked: () -> Unit
|
||||||
) {
|
) {
|
||||||
val placeholderLabel = remember(state.mode) {
|
val placeholderLabel = remember(state.mode) {
|
||||||
@@ -338,8 +329,8 @@ private fun Content(
|
|||||||
val visualTransformation = if (state.mode == FindByMode.USERNAME) {
|
val visualTransformation = if (state.mode == FindByMode.USERNAME) {
|
||||||
VisualTransformation.None
|
VisualTransformation.None
|
||||||
} else {
|
} else {
|
||||||
remember(state.selectedCountryPrefix) {
|
remember(state.selectedCountry.countryCode) {
|
||||||
PhoneNumberVisualTransformation(state.selectedCountryPrefix.regionCode)
|
PhoneNumberVisualTransformation(state.selectedCountry.regionCode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -355,8 +346,8 @@ private fun Content(
|
|||||||
{
|
{
|
||||||
PhoneNumberEntryPrefix(
|
PhoneNumberEntryPrefix(
|
||||||
enabled = !state.isLookupInProgress,
|
enabled = !state.isLookupInProgress,
|
||||||
selectedCountryPrefix = state.selectedCountryPrefix,
|
selectedCountry = state.selectedCountry,
|
||||||
onSelectCountryPrefixClick = onSelectCountryPrefixClick
|
onSelectCountryClick = onSelectCountryClick
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -448,8 +439,8 @@ private fun Content(
|
|||||||
@Composable
|
@Composable
|
||||||
private fun PhoneNumberEntryPrefix(
|
private fun PhoneNumberEntryPrefix(
|
||||||
enabled: Boolean,
|
enabled: Boolean,
|
||||||
selectedCountryPrefix: CountryPrefix,
|
selectedCountry: Country,
|
||||||
onSelectCountryPrefixClick: () -> Unit
|
onSelectCountryClick: () -> Unit
|
||||||
) {
|
) {
|
||||||
Row(
|
Row(
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
@@ -459,10 +450,10 @@ private fun PhoneNumberEntryPrefix(
|
|||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.clip(RoundedCornerShape(1000.dp))
|
.clip(RoundedCornerShape(1000.dp))
|
||||||
.clickable(onClick = onSelectCountryPrefixClick, enabled = enabled)
|
.clickable(onClick = onSelectCountryClick, enabled = enabled)
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
text = selectedCountryPrefix.toString(),
|
text = "+${selectedCountry.countryCode}",
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(start = 12.dp, top = 6.dp, bottom = 6.dp)
|
.padding(start = 12.dp, top = 6.dp, bottom = 6.dp)
|
||||||
)
|
)
|
||||||
@@ -486,113 +477,6 @@ private fun PhoneNumberEntryPrefix(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun SelectCountryScreen(
|
|
||||||
paddingValues: PaddingValues,
|
|
||||||
searchEntry: String,
|
|
||||||
onSearchEntryChanged: (String) -> Unit,
|
|
||||||
onCountryPrefixSelected: (CountryPrefix) -> Unit,
|
|
||||||
supportedCountryPrefixes: List<CountryPrefix>
|
|
||||||
) {
|
|
||||||
val focusRequester = remember {
|
|
||||||
FocusRequester()
|
|
||||||
}
|
|
||||||
|
|
||||||
Column(
|
|
||||||
modifier = Modifier.padding(paddingValues)
|
|
||||||
) {
|
|
||||||
TextFields.TextField(
|
|
||||||
value = searchEntry,
|
|
||||||
onValueChange = onSearchEntryChanged,
|
|
||||||
placeholder = { Text(text = stringResource(id = R.string.FindByActivity__search)) },
|
|
||||||
shape = RoundedCornerShape(32.dp),
|
|
||||||
colors = TextFieldDefaults.colors(
|
|
||||||
unfocusedIndicatorColor = Color.Transparent,
|
|
||||||
focusedIndicatorColor = Color.Transparent,
|
|
||||||
disabledIndicatorColor = Color.Transparent,
|
|
||||||
errorIndicatorColor = Color.Transparent,
|
|
||||||
cursorColor = MaterialTheme.colorScheme.onSurface
|
|
||||||
),
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(horizontal = 16.dp, vertical = 10.dp)
|
|
||||||
.focusRequester(focusRequester)
|
|
||||||
.heightIn(min = 44.dp),
|
|
||||||
contentPadding = TextFieldDefaults.contentPaddingWithoutLabel(top = 10.dp, bottom = 10.dp)
|
|
||||||
)
|
|
||||||
|
|
||||||
LazyColumn {
|
|
||||||
items(
|
|
||||||
items = supportedCountryPrefixes
|
|
||||||
) {
|
|
||||||
CountryPrefixRowItem(
|
|
||||||
searchTerm = searchEntry,
|
|
||||||
countryPrefix = it,
|
|
||||||
onClick = { onCountryPrefixSelected(it) }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LaunchedEffect(Unit) {
|
|
||||||
focusRequester.requestFocus()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun CountryPrefixRowItem(
|
|
||||||
searchTerm: String,
|
|
||||||
countryPrefix: CountryPrefix,
|
|
||||||
onClick: () -> Unit
|
|
||||||
) {
|
|
||||||
val regionDisplayName = remember(countryPrefix.regionCode, Locale.current) {
|
|
||||||
PhoneNumberFormatter.getRegionDisplayName(countryPrefix.regionCode).orElse(countryPrefix.regionCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (searchTerm.isNotBlank() && !regionDisplayName.contains(searchTerm, ignoreCase = true)) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val highlightedName: AnnotatedString = remember(regionDisplayName, searchTerm) {
|
|
||||||
if (searchTerm.isBlank()) {
|
|
||||||
AnnotatedString(regionDisplayName)
|
|
||||||
} else {
|
|
||||||
buildAnnotatedString {
|
|
||||||
append(regionDisplayName)
|
|
||||||
|
|
||||||
val startIndex = regionDisplayName.indexOf(searchTerm, ignoreCase = true)
|
|
||||||
|
|
||||||
addStyle(
|
|
||||||
style = SpanStyle(
|
|
||||||
fontWeight = FontWeight.Bold
|
|
||||||
),
|
|
||||||
start = startIndex,
|
|
||||||
end = startIndex + searchTerm.length
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Column(
|
|
||||||
verticalArrangement = spacedBy((-2).dp),
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.clickable(onClick = onClick)
|
|
||||||
.padding(horizontal = dimensionResource(id = CoreUiR.dimen.gutter))
|
|
||||||
.padding(top = 16.dp, bottom = 14.dp)
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
text = highlightedName
|
|
||||||
)
|
|
||||||
|
|
||||||
Text(
|
|
||||||
text = countryPrefix.toString(),
|
|
||||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
|
||||||
style = MaterialTheme.typography.bodyMedium
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Preview(name = "Light Theme", group = "content - phone", uiMode = Configuration.UI_MODE_NIGHT_NO)
|
@Preview(name = "Light Theme", group = "content - phone", uiMode = Configuration.UI_MODE_NIGHT_NO)
|
||||||
@Preview(name = "Dark Theme", group = "content - phone", uiMode = Configuration.UI_MODE_NIGHT_YES)
|
@Preview(name = "Dark Theme", group = "content - phone", uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||||
@Composable
|
@Composable
|
||||||
@@ -606,7 +490,7 @@ private fun ContentPreviewPhoneNumber() {
|
|||||||
),
|
),
|
||||||
onUserEntryChanged = {},
|
onUserEntryChanged = {},
|
||||||
onNextClick = {},
|
onNextClick = {},
|
||||||
onSelectCountryPrefixClick = {},
|
onSelectCountryClick = {},
|
||||||
onQrCodeScanClicked = {}
|
onQrCodeScanClicked = {}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -625,23 +509,8 @@ private fun ContentPreviewUsername() {
|
|||||||
),
|
),
|
||||||
onUserEntryChanged = {},
|
onUserEntryChanged = {},
|
||||||
onNextClick = {},
|
onNextClick = {},
|
||||||
onSelectCountryPrefixClick = {},
|
onSelectCountryClick = {},
|
||||||
onQrCodeScanClicked = {}
|
onQrCodeScanClicked = {}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Preview(name = "Light Theme", group = "select country", uiMode = Configuration.UI_MODE_NIGHT_NO)
|
|
||||||
@Preview(name = "Dark Theme", group = "select country", uiMode = Configuration.UI_MODE_NIGHT_YES)
|
|
||||||
@Composable
|
|
||||||
private fun SelectCountryScreenPreview() {
|
|
||||||
Previews.Preview {
|
|
||||||
SelectCountryScreen(
|
|
||||||
paddingValues = PaddingValues(0.dp),
|
|
||||||
searchEntry = "",
|
|
||||||
onSearchEntryChanged = {},
|
|
||||||
supportedCountryPrefixes = FindByState(mode = FindByMode.PHONE_NUMBER).supportedCountryPrefixes,
|
|
||||||
onCountryPrefixSelected = {}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -9,7 +9,8 @@ import com.google.i18n.phonenumbers.NumberParseException
|
|||||||
import com.google.i18n.phonenumbers.PhoneNumberUtil
|
import com.google.i18n.phonenumbers.PhoneNumberUtil
|
||||||
import org.signal.core.util.orNull
|
import org.signal.core.util.orNull
|
||||||
import org.thoughtcrime.securesms.recipients.Recipient
|
import org.thoughtcrime.securesms.recipients.Recipient
|
||||||
import org.thoughtcrime.securesms.registration.util.CountryPrefix
|
import org.thoughtcrime.securesms.registration.ui.countrycode.Country
|
||||||
|
import org.thoughtcrime.securesms.registration.ui.countrycode.CountryUtils
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* State for driving find by number/username screen.
|
* State for driving find by number/username screen.
|
||||||
@@ -17,12 +18,11 @@ import org.thoughtcrime.securesms.registration.util.CountryPrefix
|
|||||||
data class FindByState(
|
data class FindByState(
|
||||||
val mode: FindByMode,
|
val mode: FindByMode,
|
||||||
val userEntry: String = "",
|
val userEntry: String = "",
|
||||||
val supportedCountryPrefixes: List<CountryPrefix> = PhoneNumberUtil.getInstance().supportedCallingCodes
|
val supportedCountries: List<Country> = CountryUtils.getCountries(),
|
||||||
.map { CountryPrefix(it, PhoneNumberUtil.getInstance().getRegionCodeForCountryCode(it)) }
|
val filteredCountries: List<Country> = emptyList(),
|
||||||
.sortedBy { it.digits.toString() },
|
val selectedCountry: Country = supportedCountries.first(),
|
||||||
val selectedCountryPrefix: CountryPrefix = supportedCountryPrefixes.first(),
|
val isLookupInProgress: Boolean = false,
|
||||||
val countryPrefixSearchEntry: String = "",
|
val query: String = ""
|
||||||
val isLookupInProgress: Boolean = false
|
|
||||||
) {
|
) {
|
||||||
companion object {
|
companion object {
|
||||||
fun startingState(self: Recipient, mode: FindByMode): FindByState {
|
fun startingState(self: Recipient, mode: FindByMode): FindByState {
|
||||||
@@ -36,7 +36,7 @@ data class FindByState(
|
|||||||
|
|
||||||
val state = FindByState(mode = mode)
|
val state = FindByState(mode = mode)
|
||||||
return state.copy(
|
return state.copy(
|
||||||
selectedCountryPrefix = state.supportedCountryPrefixes.firstOrNull { it.digits == countryCode } ?: state.supportedCountryPrefixes.first()
|
selectedCountry = state.supportedCountries.firstOrNull { it.countryCode == countryCode } ?: state.supportedCountries.first()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import org.signal.core.util.concurrent.safeBlockingGet
|
|||||||
import org.thoughtcrime.securesms.profiles.manage.UsernameRepository
|
import org.thoughtcrime.securesms.profiles.manage.UsernameRepository
|
||||||
import org.thoughtcrime.securesms.recipients.Recipient
|
import org.thoughtcrime.securesms.recipients.Recipient
|
||||||
import org.thoughtcrime.securesms.recipients.RecipientRepository
|
import org.thoughtcrime.securesms.recipients.RecipientRepository
|
||||||
import org.thoughtcrime.securesms.registration.util.CountryPrefix
|
import org.thoughtcrime.securesms.registration.ui.countrycode.Country
|
||||||
import org.thoughtcrime.securesms.util.UsernameUtil
|
import org.thoughtcrime.securesms.util.UsernameUtil
|
||||||
|
|
||||||
class FindByViewModel(
|
class FindByViewModel(
|
||||||
@@ -40,12 +40,8 @@ class FindByViewModel(
|
|||||||
internalState.value = state.value.copy(userEntry = cleansed)
|
internalState.value = state.value.copy(userEntry = cleansed)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onCountryPrefixSearchEntryChanged(searchEntry: String) {
|
fun onCountrySelected(country: Country) {
|
||||||
internalState.value = state.value.copy(countryPrefixSearchEntry = searchEntry)
|
internalState.value = state.value.copy(selectedCountry = country)
|
||||||
}
|
|
||||||
|
|
||||||
fun onCountryPrefixSelected(countryPrefix: CountryPrefix) {
|
|
||||||
internalState.value = state.value.copy(selectedCountryPrefix = countryPrefix)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun onNextClicked(context: Context): FindByResult {
|
suspend fun onNextClicked(context: Context): FindByResult {
|
||||||
@@ -80,7 +76,7 @@ class FindByViewModel(
|
|||||||
@WorkerThread
|
@WorkerThread
|
||||||
private fun performPhoneLookup(context: Context): FindByResult {
|
private fun performPhoneLookup(context: Context): FindByResult {
|
||||||
val stateSnapshot = state.value
|
val stateSnapshot = state.value
|
||||||
val countryCode = stateSnapshot.selectedCountryPrefix.digits
|
val countryCode = stateSnapshot.selectedCountry.countryCode
|
||||||
val nationalNumber = stateSnapshot.userEntry.removePrefix(countryCode.toString())
|
val nationalNumber = stateSnapshot.userEntry.removePrefix(countryCode.toString())
|
||||||
|
|
||||||
val e164 = "+$countryCode$nationalNumber"
|
val e164 = "+$countryCode$nationalNumber"
|
||||||
@@ -92,4 +88,22 @@ class FindByViewModel(
|
|||||||
is RecipientRepository.LookupResult.Success -> FindByResult.Success(result.recipientId)
|
is RecipientRepository.LookupResult.Success -> FindByResult.Success(result.recipientId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun filterCountries(filterBy: String) {
|
||||||
|
if (filterBy.isEmpty()) {
|
||||||
|
internalState.value = state.value.copy(
|
||||||
|
query = filterBy,
|
||||||
|
filteredCountries = emptyList()
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
internalState.value = state.value.copy(
|
||||||
|
query = filterBy,
|
||||||
|
filteredCountries = state.value.supportedCountries.filter { country: Country ->
|
||||||
|
country.name.contains(filterBy, ignoreCase = true) ||
|
||||||
|
country.countryCode.toString().contains(filterBy) ||
|
||||||
|
(filterBy.equals("usa", ignoreCase = true) && country.name.equals("United States", ignoreCase = true))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ object CountryUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
fun countryToEmoji(countryCode: String): String {
|
fun countryToEmoji(countryCode: String): String {
|
||||||
return if (countryCode.isNotEmpty()) {
|
return if (countryCode.isNotEmpty()) {
|
||||||
countryCode
|
countryCode
|
||||||
|
|||||||
@@ -21,7 +21,10 @@ import com.google.i18n.phonenumbers.PhoneNumberUtil;
|
|||||||
|
|
||||||
import org.thoughtcrime.securesms.R;
|
import org.thoughtcrime.securesms.R;
|
||||||
import org.thoughtcrime.securesms.components.LabeledEditText;
|
import org.thoughtcrime.securesms.components.LabeledEditText;
|
||||||
|
import org.thoughtcrime.securesms.registration.ui.countrycode.Country;
|
||||||
|
import org.thoughtcrime.securesms.registration.ui.countrycode.CountryUtils;
|
||||||
import org.thoughtcrime.securesms.registration.viewmodel.NumberViewState;
|
import org.thoughtcrime.securesms.registration.viewmodel.NumberViewState;
|
||||||
|
import org.whispersystems.signalservice.api.util.PhoneNumberFormatter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle the logic and formatting of phone number input specifically for change number flows.
|
* Handle the logic and formatting of phone number input specifically for change number flows.
|
||||||
@@ -150,7 +153,7 @@ public final class ChangeNumberInputController {
|
|||||||
|
|
||||||
private void setCountryDisplay(@Nullable String regionDisplayName) {
|
private void setCountryDisplay(@Nullable String regionDisplayName) {
|
||||||
countrySpinnerAdapter.clear();
|
countrySpinnerAdapter.clear();
|
||||||
if (regionDisplayName == null) {
|
if (regionDisplayName == null || regionDisplayName.isEmpty()) {
|
||||||
countrySpinnerAdapter.add(context.getString(R.string.RegistrationActivity_select_your_country));
|
countrySpinnerAdapter.add(context.getString(R.string.RegistrationActivity_select_your_country));
|
||||||
} else {
|
} else {
|
||||||
countrySpinnerAdapter.add(regionDisplayName);
|
countrySpinnerAdapter.add(regionDisplayName);
|
||||||
@@ -245,7 +248,8 @@ public final class ChangeNumberInputController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!isUpdating) {
|
if (!isUpdating) {
|
||||||
callbacks.setCountry(countryCode);
|
Country country = new Country(CountryUtils.countryToEmoji(regionCode), PhoneNumberFormatter.getRegionDisplayName(regionCode).orElse(""), countryCode, regionCode);
|
||||||
|
callbacks.setCountry(country);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -269,6 +273,6 @@ public final class ChangeNumberInputController {
|
|||||||
|
|
||||||
void setNationalNumber(@NonNull String number);
|
void setNationalNumber(@NonNull String number);
|
||||||
|
|
||||||
void setCountry(int countryCode);
|
void setCountry(@NonNull Country country);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,6 +75,7 @@ class CountryCodeFragment : ComposeFragment() {
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val TAG = Log.tag(CountryCodeFragment::class.java)
|
private val TAG = Log.tag(CountryCodeFragment::class.java)
|
||||||
|
const val RESULT_KEY = "result_key"
|
||||||
const val REQUEST_KEY_COUNTRY = "request_key_country"
|
const val REQUEST_KEY_COUNTRY = "request_key_country"
|
||||||
const val REQUEST_COUNTRY = "country"
|
const val REQUEST_COUNTRY = "country"
|
||||||
const val RESULT_COUNTRY = "country"
|
const val RESULT_COUNTRY = "country"
|
||||||
@@ -86,6 +87,8 @@ class CountryCodeFragment : ComposeFragment() {
|
|||||||
override fun FragmentContent() {
|
override fun FragmentContent() {
|
||||||
val state by viewModel.state.collectAsStateWithLifecycle()
|
val state by viewModel.state.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
|
val resultKey = arguments?.getString(RESULT_KEY) ?: REQUEST_KEY_COUNTRY
|
||||||
|
|
||||||
Screen(
|
Screen(
|
||||||
state = state,
|
state = state,
|
||||||
title = stringResource(R.string.CountryCodeFragment__your_country),
|
title = stringResource(R.string.CountryCodeFragment__your_country),
|
||||||
@@ -93,7 +96,7 @@ class CountryCodeFragment : ComposeFragment() {
|
|||||||
onDismissed = { findNavController().popBackStack() },
|
onDismissed = { findNavController().popBackStack() },
|
||||||
onClick = { country ->
|
onClick = { country ->
|
||||||
setFragmentResult(
|
setFragmentResult(
|
||||||
REQUEST_KEY_COUNTRY,
|
resultKey,
|
||||||
bundleOf(
|
bundleOf(
|
||||||
RESULT_COUNTRY to country
|
RESULT_COUNTRY to country
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -58,13 +58,18 @@
|
|||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/countryPickerFragment"
|
android:id="@+id/countryPickerFragment"
|
||||||
android:name="org.thoughtcrime.securesms.components.settings.app.changenumber.ChangeNumberCountryPickerFragment"
|
android:name="org.thoughtcrime.securesms.registrationv3.ui.countrycode.CountryCodeFragment"
|
||||||
tools:layout="@layout/fragment_registration_country_picker">
|
tools:layout="@layout/fragment_registration_country_picker">
|
||||||
|
|
||||||
<argument
|
<argument
|
||||||
android:name="result_key"
|
android:name="result_key"
|
||||||
app:argType="string"
|
app:argType="string"
|
||||||
app:nullable="true" />
|
app:nullable="true" />
|
||||||
|
|
||||||
|
<argument
|
||||||
|
android:name="country"
|
||||||
|
app:argType="org.thoughtcrime.securesms.registration.ui.countrycode.Country"
|
||||||
|
app:nullable="true" />
|
||||||
</fragment>
|
</fragment>
|
||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
|
|||||||
Reference in New Issue
Block a user