Centralize where we make decisions about donations availability.

main
Alex Hart 2022-11-04 12:51:42 -03:00 zatwierdzone przez Cody Henthorne
rodzic f6f1fdb87d
commit 8f06381239
9 zmienionych plików z 62 dodań i 16 usunięć

Wyświetl plik

@ -18,12 +18,12 @@ import org.thoughtcrime.securesms.badges.models.LargeBadge
import org.thoughtcrime.securesms.components.FixedRoundedCornerBottomSheetDialogFragment import org.thoughtcrime.securesms.components.FixedRoundedCornerBottomSheetDialogFragment
import org.thoughtcrime.securesms.components.ViewBinderDelegate import org.thoughtcrime.securesms.components.ViewBinderDelegate
import org.thoughtcrime.securesms.components.settings.app.AppSettingsActivity import org.thoughtcrime.securesms.components.settings.app.AppSettingsActivity
import org.thoughtcrime.securesms.components.settings.app.subscription.InAppDonations
import org.thoughtcrime.securesms.databinding.ViewBadgeBottomSheetDialogFragmentBinding import org.thoughtcrime.securesms.databinding.ViewBadgeBottomSheetDialogFragmentBinding
import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.recipients.RecipientId import org.thoughtcrime.securesms.recipients.RecipientId
import org.thoughtcrime.securesms.util.BottomSheetUtil import org.thoughtcrime.securesms.util.BottomSheetUtil
import org.thoughtcrime.securesms.util.CommunicationActions import org.thoughtcrime.securesms.util.CommunicationActions
import org.thoughtcrime.securesms.util.PlayServicesUtil
import org.thoughtcrime.securesms.util.ViewUtil import org.thoughtcrime.securesms.util.ViewUtil
import org.thoughtcrime.securesms.util.adapter.mapping.MappingAdapter import org.thoughtcrime.securesms.util.adapter.mapping.MappingAdapter
import org.thoughtcrime.securesms.util.visible import org.thoughtcrime.securesms.util.visible
@ -57,7 +57,7 @@ class ViewBadgeBottomSheetDialogFragment : FixedRoundedCornerBottomSheetDialogFr
} }
@Suppress("CascadeIf") @Suppress("CascadeIf")
if (PlayServicesUtil.getPlayServicesStatus(requireContext()) != PlayServicesUtil.PlayServicesStatus.SUCCESS) { if (InAppDonations.hasAtLeastOnePaymentMethodAvailable()) {
binding.noSupport.visible = true binding.noSupport.visible = true
binding.action.icon = ContextCompat.getDrawable(requireContext(), R.drawable.ic_open_20) binding.action.icon = ContextCompat.getDrawable(requireContext(), R.drawable.ic_open_20)
binding.action.setText(R.string.preferences__donate_to_signal) binding.action.setText(R.string.preferences__donate_to_signal)

Wyświetl plik

@ -14,13 +14,13 @@ import org.thoughtcrime.securesms.components.settings.DSLSettingsIcon
import org.thoughtcrime.securesms.components.settings.DSLSettingsText import org.thoughtcrime.securesms.components.settings.DSLSettingsText
import org.thoughtcrime.securesms.components.settings.PreferenceModel import org.thoughtcrime.securesms.components.settings.PreferenceModel
import org.thoughtcrime.securesms.components.settings.PreferenceViewHolder import org.thoughtcrime.securesms.components.settings.PreferenceViewHolder
import org.thoughtcrime.securesms.components.settings.app.subscription.InAppDonations
import org.thoughtcrime.securesms.components.settings.configure import org.thoughtcrime.securesms.components.settings.configure
import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.keyvalue.SignalStore
import org.thoughtcrime.securesms.phonenumbers.PhoneNumberFormatter import org.thoughtcrime.securesms.phonenumbers.PhoneNumberFormatter
import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.stories.Stories.isFeatureFlagEnabled import org.thoughtcrime.securesms.stories.Stories.isFeatureFlagEnabled
import org.thoughtcrime.securesms.util.FeatureFlags import org.thoughtcrime.securesms.util.FeatureFlags
import org.thoughtcrime.securesms.util.PlayServicesUtil
import org.thoughtcrime.securesms.util.Util import org.thoughtcrime.securesms.util.Util
import org.thoughtcrime.securesms.util.adapter.mapping.LayoutFactory import org.thoughtcrime.securesms.util.adapter.mapping.LayoutFactory
import org.thoughtcrime.securesms.util.adapter.mapping.MappingAdapter import org.thoughtcrime.securesms.util.adapter.mapping.MappingAdapter
@ -71,7 +71,7 @@ class AppSettingsFragment : DSLSettingsFragment(R.string.text_secure_normal__men
} }
) )
if (PlayServicesUtil.getPlayServicesStatus(requireContext()) == PlayServicesUtil.PlayServicesStatus.SUCCESS) { if (InAppDonations.hasAtLeastOnePaymentMethodAvailable()) {
clickPref( clickPref(
title = DSLSettingsText.from(R.string.preferences__donate_to_signal), title = DSLSettingsText.from(R.string.preferences__donate_to_signal),
icon = DSLSettingsIcon.from(R.drawable.ic_heart_24), icon = DSLSettingsIcon.from(R.drawable.ic_heart_24),

Wyświetl plik

@ -0,0 +1,44 @@
package org.thoughtcrime.securesms.components.settings.app.subscription
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
import org.thoughtcrime.securesms.util.FeatureFlags
import org.thoughtcrime.securesms.util.PlayServicesUtil
/**
* Helper object to determine in-app donations availability.
*/
object InAppDonations {
/**
* The user is:
*
* - Able to use Credit Cards and is in a region where they are able to be accepted.
* - Able to access Google Play services (and thus possibly able to use Google Pay).
* - Able to use PayPal and is in a region where it is able to be accepted.
*/
fun hasAtLeastOnePaymentMethodAvailable(): Boolean {
return isCreditCardAvailable() || isPayPalAvailable() || isPlayServicesAvailable()
}
/**
* Whether the user is in a region that supports credit cards, based off local phone number.
*/
fun isCreditCardAvailable(): Boolean {
return FeatureFlags.creditCardPayments()
}
/**
* Whether the user is in a region that supports PayPal, based off local phone number.
*/
fun isPayPalAvailable(): Boolean {
return false
}
/**
* Whether Play Services is available. This will *not* tell you whether a user has Google Pay set up, but is
* enough information to determine whether we can display Google Pay as an option.
*/
private fun isPlayServicesAvailable(): Boolean {
return PlayServicesUtil.getPlayServicesStatus(ApplicationDependencies.getApplication()) == PlayServicesUtil.PlayServicesStatus.SUCCESS
}
}

Wyświetl plik

@ -34,6 +34,7 @@ import org.thoughtcrime.securesms.components.settings.DSLConfiguration
import org.thoughtcrime.securesms.components.settings.DSLSettingsFragment import org.thoughtcrime.securesms.components.settings.DSLSettingsFragment
import org.thoughtcrime.securesms.components.settings.DSLSettingsText import org.thoughtcrime.securesms.components.settings.DSLSettingsText
import org.thoughtcrime.securesms.components.settings.app.subscription.DonationPaymentComponent import org.thoughtcrime.securesms.components.settings.app.subscription.DonationPaymentComponent
import org.thoughtcrime.securesms.components.settings.app.subscription.InAppDonations
import org.thoughtcrime.securesms.components.settings.app.subscription.boost.Boost import org.thoughtcrime.securesms.components.settings.app.subscription.boost.Boost
import org.thoughtcrime.securesms.components.settings.app.subscription.donate.card.CreditCardFragment import org.thoughtcrime.securesms.components.settings.app.subscription.donate.card.CreditCardFragment
import org.thoughtcrime.securesms.components.settings.app.subscription.donate.card.CreditCardResult import org.thoughtcrime.securesms.components.settings.app.subscription.donate.card.CreditCardResult
@ -53,7 +54,6 @@ import org.thoughtcrime.securesms.components.settings.configure
import org.thoughtcrime.securesms.databinding.DonateToSignalFragmentBinding import org.thoughtcrime.securesms.databinding.DonateToSignalFragmentBinding
import org.thoughtcrime.securesms.payments.FiatMoneyUtil import org.thoughtcrime.securesms.payments.FiatMoneyUtil
import org.thoughtcrime.securesms.subscription.Subscription import org.thoughtcrime.securesms.subscription.Subscription
import org.thoughtcrime.securesms.util.FeatureFlags
import org.thoughtcrime.securesms.util.LifecycleDisposable import org.thoughtcrime.securesms.util.LifecycleDisposable
import org.thoughtcrime.securesms.util.Material3OnScrollHelper import org.thoughtcrime.securesms.util.Material3OnScrollHelper
import org.thoughtcrime.securesms.util.Projection import org.thoughtcrime.securesms.util.Projection
@ -457,7 +457,7 @@ class DonateToSignalFragment : DSLSettingsFragment(
} }
private fun launchCreditCard(gatewayResponse: GatewayResponse) { private fun launchCreditCard(gatewayResponse: GatewayResponse) {
if (FeatureFlags.creditCardPayments()) { if (InAppDonations.isCreditCardAvailable()) {
findNavController().safeNavigate(DonateToSignalFragmentDirections.actionDonateToSignalFragmentToCreditCardFragment(gatewayResponse.request)) findNavController().safeNavigate(DonateToSignalFragmentDirections.actionDonateToSignalFragmentToCreditCardFragment(gatewayResponse.request))
} else { } else {
error("Credit cards are not currently enabled.") error("Credit cards are not currently enabled.")

Wyświetl plik

@ -16,6 +16,7 @@ import org.thoughtcrime.securesms.components.settings.DSLSettingsIcon
import org.thoughtcrime.securesms.components.settings.DSLSettingsText import org.thoughtcrime.securesms.components.settings.DSLSettingsText
import org.thoughtcrime.securesms.components.settings.NO_TINT import org.thoughtcrime.securesms.components.settings.NO_TINT
import org.thoughtcrime.securesms.components.settings.app.subscription.DonationPaymentComponent import org.thoughtcrime.securesms.components.settings.app.subscription.DonationPaymentComponent
import org.thoughtcrime.securesms.components.settings.app.subscription.InAppDonations
import org.thoughtcrime.securesms.components.settings.app.subscription.donate.DonateToSignalType import org.thoughtcrime.securesms.components.settings.app.subscription.donate.DonateToSignalType
import org.thoughtcrime.securesms.components.settings.app.subscription.models.GooglePayButton import org.thoughtcrime.securesms.components.settings.app.subscription.models.GooglePayButton
import org.thoughtcrime.securesms.components.settings.configure import org.thoughtcrime.securesms.components.settings.configure
@ -81,7 +82,7 @@ class GatewaySelectorBottomSheet : DSLSettingsBottomSheetFragment() {
// PayPal // PayPal
// Credit Card // Credit Card
if (state.isCreditCardAvailable) { if (InAppDonations.isCreditCardAvailable()) {
space(12.dp) space(12.dp)
primaryButton( primaryButton(

Wyświetl plik

@ -1,11 +1,8 @@
package org.thoughtcrime.securesms.components.settings.app.subscription.donate.gateway package org.thoughtcrime.securesms.components.settings.app.subscription.donate.gateway
import org.thoughtcrime.securesms.badges.models.Badge import org.thoughtcrime.securesms.badges.models.Badge
import org.thoughtcrime.securesms.util.FeatureFlags
data class GatewaySelectorState( data class GatewaySelectorState(
val badge: Badge, val badge: Badge,
val isGooglePayAvailable: Boolean = false, val isGooglePayAvailable: Boolean = false
val isPayPalAvailable: Boolean = false,
val isCreditCardAvailable: Boolean = FeatureFlags.creditCardPayments()
) )

Wyświetl plik

@ -2,6 +2,8 @@ package org.thoughtcrime.securesms.components.settings.app.subscription.donate.g
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import io.reactivex.rxjava3.disposables.CompositeDisposable
import io.reactivex.rxjava3.kotlin.plusAssign
import io.reactivex.rxjava3.kotlin.subscribeBy import io.reactivex.rxjava3.kotlin.subscribeBy
import org.thoughtcrime.securesms.components.settings.app.subscription.DonationPaymentRepository import org.thoughtcrime.securesms.components.settings.app.subscription.DonationPaymentRepository
import org.thoughtcrime.securesms.util.rx.RxStore import org.thoughtcrime.securesms.util.rx.RxStore
@ -12,6 +14,7 @@ class GatewaySelectorViewModel(
) : ViewModel() { ) : ViewModel() {
private val store = RxStore(GatewaySelectorState(args.request.badge)) private val store = RxStore(GatewaySelectorState(args.request.badge))
private val disposables = CompositeDisposable()
val state = store.stateFlowable val state = store.stateFlowable
@ -21,10 +24,11 @@ class GatewaySelectorViewModel(
override fun onCleared() { override fun onCleared() {
store.dispose() store.dispose()
disposables.clear()
} }
private fun checkIfGooglePayIsAvailable() { private fun checkIfGooglePayIsAvailable() {
repository.isGooglePayAvailable().subscribeBy( disposables += repository.isGooglePayAvailable().subscribeBy(
onComplete = { onComplete = {
store.update { it.copy(isGooglePayAvailable = true) } store.update { it.copy(isGooglePayAvailable = true) }
}, },

Wyświetl plik

@ -18,6 +18,7 @@ import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.badges.models.Badge; import org.thoughtcrime.securesms.badges.models.Badge;
import org.thoughtcrime.securesms.components.settings.app.AppSettingsActivity; import org.thoughtcrime.securesms.components.settings.app.AppSettingsActivity;
import org.thoughtcrime.securesms.components.settings.app.subscription.InAppDonations;
import org.thoughtcrime.securesms.database.model.MegaphoneRecord; import org.thoughtcrime.securesms.database.model.MegaphoneRecord;
import org.thoughtcrime.securesms.database.model.RemoteMegaphoneRecord; import org.thoughtcrime.securesms.database.model.RemoteMegaphoneRecord;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
@ -36,7 +37,6 @@ import org.thoughtcrime.securesms.profiles.manage.ManageProfileActivity;
import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.util.FeatureFlags; import org.thoughtcrime.securesms.util.FeatureFlags;
import org.thoughtcrime.securesms.util.LocaleFeatureFlags; import org.thoughtcrime.securesms.util.LocaleFeatureFlags;
import org.thoughtcrime.securesms.util.PlayServicesUtil;
import org.thoughtcrime.securesms.util.ServiceUtil; import org.thoughtcrime.securesms.util.ServiceUtil;
import org.thoughtcrime.securesms.util.VersionTracker; import org.thoughtcrime.securesms.util.VersionTracker;
import org.thoughtcrime.securesms.util.dynamiclanguage.DynamicLanguageContextWrapper; import org.thoughtcrime.securesms.util.dynamiclanguage.DynamicLanguageContextWrapper;
@ -396,7 +396,7 @@ public final class Megaphones {
return timeSinceLastDonatePrompt > MIN_TIME_BETWEEN_DONATE_MEGAPHONES && return timeSinceLastDonatePrompt > MIN_TIME_BETWEEN_DONATE_MEGAPHONES &&
VersionTracker.getDaysSinceFirstInstalled(context) >= 7 && VersionTracker.getDaysSinceFirstInstalled(context) >= 7 &&
LocaleFeatureFlags.isInDonateMegaphone() && LocaleFeatureFlags.isInDonateMegaphone() &&
PlayServicesUtil.getPlayServicesStatus(context) == PlayServicesUtil.PlayServicesStatus.SUCCESS && InAppDonations.INSTANCE.hasAtLeastOnePaymentMethodAvailable() &&
Recipient.self() Recipient.self()
.getBadges() .getBadges()
.stream() .stream()

Wyświetl plik

@ -10,6 +10,7 @@ import org.signal.core.util.concurrent.SignalExecutors
import org.signal.core.util.logging.Log import org.signal.core.util.logging.Log
import org.thoughtcrime.securesms.badges.models.Badge import org.thoughtcrime.securesms.badges.models.Badge
import org.thoughtcrime.securesms.components.settings.app.AppSettingsActivity import org.thoughtcrime.securesms.components.settings.app.AppSettingsActivity
import org.thoughtcrime.securesms.components.settings.app.subscription.InAppDonations
import org.thoughtcrime.securesms.database.RemoteMegaphoneDatabase import org.thoughtcrime.securesms.database.RemoteMegaphoneDatabase
import org.thoughtcrime.securesms.database.SignalDatabase import org.thoughtcrime.securesms.database.SignalDatabase
import org.thoughtcrime.securesms.database.model.RemoteMegaphoneRecord import org.thoughtcrime.securesms.database.model.RemoteMegaphoneRecord
@ -20,7 +21,6 @@ import org.thoughtcrime.securesms.providers.BlobProvider
import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.util.FeatureFlags import org.thoughtcrime.securesms.util.FeatureFlags
import org.thoughtcrime.securesms.util.LocaleFeatureFlags import org.thoughtcrime.securesms.util.LocaleFeatureFlags
import org.thoughtcrime.securesms.util.PlayServicesUtil
import org.thoughtcrime.securesms.util.VersionTracker import org.thoughtcrime.securesms.util.VersionTracker
import java.util.Objects import java.util.Objects
import kotlin.math.min import kotlin.math.min
@ -121,7 +121,7 @@ object RemoteMegaphoneRepository {
private fun shouldShowDonateMegaphone(): Boolean { private fun shouldShowDonateMegaphone(): Boolean {
return VersionTracker.getDaysSinceFirstInstalled(context) >= 7 && return VersionTracker.getDaysSinceFirstInstalled(context) >= 7 &&
PlayServicesUtil.getPlayServicesStatus(context) == PlayServicesUtil.PlayServicesStatus.SUCCESS && InAppDonations.hasAtLeastOnePaymentMethodAvailable() &&
Recipient.self() Recipient.self()
.badges .badges
.stream() .stream()