kopia lustrzana https://github.com/ryukoposting/Signal-Android
Add PNP Listing Wiring.
rodzic
8e9f311fca
commit
176a705079
|
@ -0,0 +1,34 @@
|
|||
package org.thoughtcrime.securesms.components
|
||||
|
||||
import android.view.View
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.DefaultLifecycleObserver
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.viewbinding.ViewBinding
|
||||
import org.whispersystems.signalservice.api.util.Preconditions
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
/**
|
||||
* ViewBinderDelegate which enforces the "best practices" for maintaining a reference to a view binding given by
|
||||
* Android official documentation.
|
||||
*/
|
||||
class ViewBinderDelegate<T : ViewBinding>(private val bindingFactory: (View) -> T) : DefaultLifecycleObserver {
|
||||
|
||||
private var binding: T? = null
|
||||
|
||||
operator fun getValue(thisRef: Fragment, property: KProperty<*>): T {
|
||||
Preconditions.checkState(thisRef.viewLifecycleOwner.lifecycle.currentState.isAtLeast(Lifecycle.State.CREATED))
|
||||
|
||||
if (binding == null) {
|
||||
thisRef.viewLifecycleOwner.lifecycle.addObserver(this@ViewBinderDelegate)
|
||||
binding = bindingFactory(thisRef.requireView())
|
||||
}
|
||||
|
||||
return binding!!
|
||||
}
|
||||
|
||||
override fun onDestroy(owner: LifecycleOwner) {
|
||||
binding = null
|
||||
}
|
||||
}
|
|
@ -19,7 +19,6 @@ import androidx.annotation.Nullable;
|
|||
import androidx.annotation.RequiresApi;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.lifecycle.ViewModelProviders;
|
||||
import androidx.navigation.Navigation;
|
||||
|
||||
import com.airbnb.lottie.SimpleColorFilter;
|
||||
|
@ -36,8 +35,11 @@ import org.thoughtcrime.securesms.avatar.picker.AvatarPickerFragment;
|
|||
import org.thoughtcrime.securesms.databinding.ProfileCreateFragmentBinding;
|
||||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
import org.thoughtcrime.securesms.groups.ParcelableGroupId;
|
||||
import org.thoughtcrime.securesms.keyvalue.PhoneNumberPrivacyValues;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.mediasend.Media;
|
||||
import org.thoughtcrime.securesms.mms.GlideApp;
|
||||
import org.thoughtcrime.securesms.profiles.edit.pnp.WhoCanSeeMyPhoneNumberFragment;
|
||||
import org.thoughtcrime.securesms.profiles.manage.EditProfileNameFragment;
|
||||
import org.thoughtcrime.securesms.providers.BlobProvider;
|
||||
import org.thoughtcrime.securesms.util.CommunicationActions;
|
||||
|
@ -59,9 +61,9 @@ import static org.thoughtcrime.securesms.profiles.edit.EditProfileActivity.SHOW_
|
|||
*/
|
||||
public class EditProfileFragment extends LoggingFragment {
|
||||
|
||||
private static final String TAG = Log.tag(EditProfileFragment.class);
|
||||
private static final int MAX_DESCRIPTION_GLYPHS = 480;
|
||||
private static final int MAX_DESCRIPTION_BYTES = 8192;
|
||||
private static final String TAG = Log.tag(EditProfileFragment.class);
|
||||
private static final int MAX_DESCRIPTION_GLYPHS = 480;
|
||||
private static final int MAX_DESCRIPTION_BYTES = 8192;
|
||||
|
||||
private Intent nextIntent;
|
||||
|
||||
|
@ -209,10 +211,15 @@ public class EditProfileFragment extends LoggingFragment {
|
|||
binding.profileDescriptionText.setOnLinkClickListener(v -> CommunicationActions.openBrowserLink(requireContext(), getString(R.string.EditProfileFragment__support_link)));
|
||||
|
||||
if (FeatureFlags.phoneNumberPrivacy()) {
|
||||
getParentFragmentManager().setFragmentResultListener(WhoCanSeeMyPhoneNumberFragment.REQUEST_KEY, getViewLifecycleOwner(), (requestKey, result) -> {
|
||||
if (WhoCanSeeMyPhoneNumberFragment.REQUEST_KEY.equals(requestKey)) {
|
||||
presentWhoCanFindMeDescription(SignalStore.phoneNumberPrivacy().getPhoneNumberListingMode());
|
||||
}
|
||||
});
|
||||
|
||||
binding.whoCanFindMeContainer.setVisibility(View.VISIBLE);
|
||||
binding.whoCanFindMeContainer.setOnClickListener(v -> SafeNavigation.safeNavigate(Navigation.findNavController(v), EditProfileFragmentDirections.actionCreateProfileFragmentToPhoneNumberPrivacy()));
|
||||
// TODO [alex] -- Where does this value come from?
|
||||
binding.whoCanFindMeDescription.setText(R.string.PhoneNumberPrivacy_everyone);
|
||||
presentWhoCanFindMeDescription(SignalStore.phoneNumberPrivacy().getPhoneNumberListingMode());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -279,6 +286,17 @@ public class EditProfileFragment extends LoggingFragment {
|
|||
}
|
||||
}
|
||||
|
||||
private void presentWhoCanFindMeDescription(PhoneNumberPrivacyValues.PhoneNumberListingMode phoneNumberListingMode) {
|
||||
switch (phoneNumberListingMode) {
|
||||
case LISTED:
|
||||
binding.whoCanFindMeDescription.setText(R.string.PhoneNumberPrivacy_everyone);
|
||||
break;
|
||||
case UNLISTED:
|
||||
binding.whoCanFindMeDescription.setText(R.string.PhoneNumberPrivacy_nobody);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void startAvatarSelection() {
|
||||
if (viewModel.isGroup()) {
|
||||
Parcelable groupId = ParcelableGroupId.from(viewModel.getGroupId());
|
||||
|
|
|
@ -1,11 +1,17 @@
|
|||
package org.thoughtcrime.securesms.profiles.edit.pnp
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.fragment.app.setFragmentResult
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import io.reactivex.rxjava3.kotlin.subscribeBy
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.components.ViewBinderDelegate
|
||||
import org.thoughtcrime.securesms.components.settings.DSLConfiguration
|
||||
import org.thoughtcrime.securesms.components.settings.DSLSettingsFragment
|
||||
import org.thoughtcrime.securesms.components.settings.DSLSettingsText
|
||||
import org.thoughtcrime.securesms.components.settings.configure
|
||||
import org.thoughtcrime.securesms.databinding.WhoCanSeeMyPhoneNumberFragmentBinding
|
||||
import org.thoughtcrime.securesms.util.FeatureFlags
|
||||
import org.thoughtcrime.securesms.util.LifecycleDisposable
|
||||
import org.thoughtcrime.securesms.util.adapter.mapping.MappingAdapter
|
||||
|
@ -13,17 +19,37 @@ import org.thoughtcrime.securesms.util.adapter.mapping.MappingAdapter
|
|||
/**
|
||||
* Allows the user to select who can see their phone number during registration.
|
||||
*/
|
||||
class WhoCanSeeMyPhoneNumberFragment : DSLSettingsFragment(titleId = R.string.WhoCanSeeMyPhoneNumberFragment__who_can_find_me_by_number) {
|
||||
class WhoCanSeeMyPhoneNumberFragment : DSLSettingsFragment(
|
||||
titleId = R.string.WhoCanSeeMyPhoneNumberFragment__who_can_find_me_by_number,
|
||||
layoutId = R.layout.who_can_see_my_phone_number_fragment
|
||||
) {
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* Components can listen to this result to know when the user hit the submit button.
|
||||
*/
|
||||
const val REQUEST_KEY = "who_can_see_my_phone_number_key"
|
||||
}
|
||||
|
||||
private val viewModel: WhoCanSeeMyPhoneNumberViewModel by viewModels()
|
||||
private val lifecycleDisposable = LifecycleDisposable()
|
||||
|
||||
private val binding by ViewBinderDelegate(WhoCanSeeMyPhoneNumberFragmentBinding::bind)
|
||||
|
||||
override fun bindAdapter(adapter: MappingAdapter) {
|
||||
require(FeatureFlags.phoneNumberPrivacy())
|
||||
|
||||
lifecycleDisposable += viewModel.state.subscribe {
|
||||
adapter.submitList(getConfiguration(it).toMappingModelList())
|
||||
}
|
||||
|
||||
binding.save.setOnClickListener {
|
||||
binding.save.isEnabled = false
|
||||
viewModel.onSave().subscribeBy(onComplete = {
|
||||
setFragmentResult(REQUEST_KEY, Bundle())
|
||||
findNavController().popBackStack()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private fun getConfiguration(state: WhoCanSeeMyPhoneNumberState): DSLConfiguration {
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
package org.thoughtcrime.securesms.profiles.edit.pnp
|
||||
|
||||
import io.reactivex.rxjava3.core.Completable
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
|
||||
import org.thoughtcrime.securesms.jobs.RefreshAttributesJob
|
||||
import org.thoughtcrime.securesms.keyvalue.PhoneNumberPrivacyValues
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
|
||||
/**
|
||||
* Manages the current phone-number listing state.
|
||||
*/
|
||||
class WhoCanSeeMyPhoneNumberRepository {
|
||||
|
||||
fun getCurrentState(): WhoCanSeeMyPhoneNumberState {
|
||||
return when (SignalStore.phoneNumberPrivacy().phoneNumberListingMode) {
|
||||
PhoneNumberPrivacyValues.PhoneNumberListingMode.LISTED -> WhoCanSeeMyPhoneNumberState.EVERYONE
|
||||
PhoneNumberPrivacyValues.PhoneNumberListingMode.UNLISTED -> WhoCanSeeMyPhoneNumberState.NOBODY
|
||||
}
|
||||
}
|
||||
|
||||
fun onSave(whoCanSeeMyPhoneNumberState: WhoCanSeeMyPhoneNumberState): Completable {
|
||||
return Completable.fromAction {
|
||||
SignalStore.phoneNumberPrivacy().phoneNumberListingMode = when (whoCanSeeMyPhoneNumberState) {
|
||||
WhoCanSeeMyPhoneNumberState.EVERYONE -> PhoneNumberPrivacyValues.PhoneNumberListingMode.LISTED
|
||||
WhoCanSeeMyPhoneNumberState.NOBODY -> PhoneNumberPrivacyValues.PhoneNumberListingMode.UNLISTED
|
||||
}
|
||||
|
||||
ApplicationDependencies.getJobManager().add(RefreshAttributesJob())
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,13 +2,15 @@ package org.thoughtcrime.securesms.profiles.edit.pnp
|
|||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.rxjava3.core.Completable
|
||||
import io.reactivex.rxjava3.core.Flowable
|
||||
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
||||
import org.thoughtcrime.securesms.util.rx.RxStore
|
||||
|
||||
class WhoCanSeeMyPhoneNumberViewModel : ViewModel() {
|
||||
|
||||
private val store = RxStore(WhoCanSeeMyPhoneNumberState.EVERYONE)
|
||||
private val repository = WhoCanSeeMyPhoneNumberRepository()
|
||||
private val store = RxStore(repository.getCurrentState())
|
||||
private val disposables = CompositeDisposable()
|
||||
|
||||
val state: Flowable<WhoCanSeeMyPhoneNumberState> = store.stateFlowable.subscribeOn(AndroidSchedulers.mainThread())
|
||||
|
@ -21,6 +23,10 @@ class WhoCanSeeMyPhoneNumberViewModel : ViewModel() {
|
|||
store.update { WhoCanSeeMyPhoneNumberState.NOBODY }
|
||||
}
|
||||
|
||||
fun onSave(): Completable {
|
||||
return repository.onSave(store.state).observeOn(AndroidSchedulers.mainThread())
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
disposables.clear()
|
||||
}
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<include layout="@layout/dsl_settings_toolbar" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recycler"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:orientation="vertical"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/toolbar" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/save"
|
||||
style="@style/Signal.Widget.Button.Large.Tonal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/dsl_settings_gutter"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:text="@string/save"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
Ładowanie…
Reference in New Issue