Update country picker for findBy and changeNumber.

This commit is contained in:
Michelle Tang
2025-02-07 14:35:45 -05:00
committed by GitHub
parent 20ab362f2c
commit 850c20bcd8
11 changed files with 115 additions and 330 deletions

View File

@@ -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) {
}
}
}

View File

@@ -14,12 +14,15 @@ import androidx.fragment.app.activityViewModels
import androidx.navigation.fragment.findNavController
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.snackbar.Snackbar
import org.signal.core.util.getParcelableCompat
import org.signal.core.util.logging.Log
import org.thoughtcrime.securesms.LoggingFragment
import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.components.ViewBinderDelegate
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.registrationv3.ui.countrycode.CountryCodeFragment
import org.thoughtcrime.securesms.util.Dialogs
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 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) {
viewModel.setOldNationalNumber(number)
}
override fun setCountry(countryCode: Int) {
viewModel.setOldCountry(countryCode)
override fun setCountry(country: Country) {
viewModel.setOldCountry(country)
}
}
)
@@ -96,25 +99,27 @@ class ChangeNumberEnterPhoneNumberFragment : LoggingFragment(R.layout.fragment_c
}
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) {
viewModel.setNewNationalNumber(number)
}
override fun setCountry(countryCode: Int) {
viewModel.setNewCountry(countryCode)
override fun setCountry(country: Country) {
viewModel.setNewCountry(country)
}
}
)
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 ->
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)

View File

@@ -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.VerificationCodeRequestResult
import org.thoughtcrime.securesms.registration.ui.countrycode.Country
import org.thoughtcrime.securesms.registration.viewmodel.NumberViewState
import org.whispersystems.signalservice.api.svr.Svr3Credentials
import org.whispersystems.signalservice.internal.push.AuthCredentials
@@ -32,7 +33,9 @@ data class ChangeNumberState(
val captchaToken: String? = null,
val challengesRequested: List<Challenge> = emptyList(),
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 }
}

View File

@@ -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.sms.SmsRetrieverReceiver
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.SvrAuthCredentialSet
import org.thoughtcrime.securesms.util.dualsim.MccMncProducer
@@ -100,15 +101,24 @@ class ChangeNumberViewModel : ViewModel() {
val svrTriesRemaining: Int
get() = store.value.svrTriesRemaining
val oldCountry: Country?
get() = store.value.oldCountry
val newCountry: Country?
get() = store.value.newCountry
fun setOldNationalNumber(updatedNumber: String) {
store.update {
it.copy(oldPhoneNumber = oldNumberState.toBuilder().nationalNumber(updatedNumber).build())
}
}
fun setOldCountry(countryCode: Int, country: String? = null) {
fun setOldCountry(country: Country) {
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 {
it.copy(number = number.toBuilder().selectedCountryDisplayName(country).countryCode(countryCode).build())
it.copy(
number = number.toBuilder().selectedCountryDisplayName(country.name).countryCode(country.countryCode).build(),
newCountry = country
)
}
}