kopia lustrzana https://github.com/ryukoposting/Signal-Android
Add and sync displayBadgesOnProfile Flag.
rodzic
b9f060b442
commit
6b94fc82eb
|
@ -6,7 +6,9 @@ import io.reactivex.rxjava3.schedulers.Schedulers
|
|||
import org.thoughtcrime.securesms.badges.models.Badge
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory
|
||||
import org.thoughtcrime.securesms.database.RecipientDatabase
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
import org.thoughtcrime.securesms.storage.StorageSyncHelper
|
||||
import org.thoughtcrime.securesms.util.ProfileUtil
|
||||
|
||||
class BadgeRepository(context: Context) {
|
||||
|
@ -17,10 +19,16 @@ class BadgeRepository(context: Context) {
|
|||
displayBadgesOnProfile: Boolean,
|
||||
selfBadges: List<Badge> = Recipient.self().badges
|
||||
): Completable = Completable.fromAction {
|
||||
val recipientDatabase: RecipientDatabase = DatabaseFactory.getRecipientDatabase(context)
|
||||
|
||||
SignalStore.donationsValues().setDisplayBadgesOnProfile(displayBadgesOnProfile)
|
||||
|
||||
recipientDatabase.markNeedsSync(Recipient.self().id)
|
||||
StorageSyncHelper.scheduleSyncForDataChange()
|
||||
|
||||
val badges = selfBadges.map { it.copy(visible = displayBadgesOnProfile) }
|
||||
ProfileUtil.uploadProfileWithBadges(context, badges)
|
||||
|
||||
val recipientDatabase: RecipientDatabase = DatabaseFactory.getRecipientDatabase(context)
|
||||
recipientDatabase.setBadges(Recipient.self().id, badges)
|
||||
}.subscribeOn(Schedulers.io())
|
||||
|
||||
|
|
|
@ -36,10 +36,6 @@ data class Badge(
|
|||
val visible: Boolean,
|
||||
) : Parcelable, Key {
|
||||
|
||||
fun setVisible(): Badge {
|
||||
return copy(visible = true)
|
||||
}
|
||||
|
||||
fun isExpired(): Boolean = expirationTimestamp < System.currentTimeMillis() && expirationTimestamp > 0
|
||||
fun isBoost(): Boolean = id == BOOST_BADGE_ID
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ import io.reactivex.rxjava3.subjects.PublishSubject
|
|||
import org.signal.core.util.logging.Log
|
||||
import org.thoughtcrime.securesms.badges.BadgeRepository
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.SubscriptionsRepository
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
import org.thoughtcrime.securesms.util.livedata.Store
|
||||
import org.whispersystems.libsignal.util.guava.Optional
|
||||
|
@ -36,7 +37,7 @@ class BadgesOverviewViewModel(
|
|||
state.copy(
|
||||
stage = if (state.stage == BadgesOverviewState.Stage.INIT) BadgesOverviewState.Stage.READY else state.stage,
|
||||
allUnlockedBadges = recipient.badges,
|
||||
displayBadgesOnProfile = recipient.badges.firstOrNull()?.visible == true,
|
||||
displayBadgesOnProfile = SignalStore.donationsValues().getDisplayBadgesOnProfile(),
|
||||
featuredBadge = recipient.featuredBadge
|
||||
)
|
||||
}
|
||||
|
|
|
@ -11,17 +11,20 @@ import io.reactivex.rxjava3.core.Completable
|
|||
import io.reactivex.rxjava3.core.Observable
|
||||
import io.reactivex.rxjava3.core.Single
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
||||
import org.signal.core.util.concurrent.SignalExecutors
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.signal.core.util.money.FiatMoney
|
||||
import org.signal.donations.GooglePayApi
|
||||
import org.signal.donations.GooglePayPaymentSource
|
||||
import org.signal.donations.StripeApi
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
|
||||
import org.thoughtcrime.securesms.jobmanager.JobTracker
|
||||
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint
|
||||
import org.thoughtcrime.securesms.jobs.BoostReceiptRequestResponseJob
|
||||
import org.thoughtcrime.securesms.jobs.SubscriptionReceiptRequestResponseJob
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
import org.thoughtcrime.securesms.storage.StorageSyncHelper
|
||||
import org.thoughtcrime.securesms.subscription.LevelUpdate
|
||||
import org.thoughtcrime.securesms.subscription.LevelUpdateOperation
|
||||
|
@ -60,6 +63,17 @@ class DonationPaymentRepository(activity: Activity) : StripeApi.PaymentIntentFet
|
|||
|
||||
fun isGooglePayAvailable(): Completable = googlePayApi.queryIsReadyToPay()
|
||||
|
||||
fun scheduleSyncForAccountRecordChange() {
|
||||
SignalExecutors.BOUNDED.execute {
|
||||
scheduleSyncForAccountRecordChangeSync()
|
||||
}
|
||||
}
|
||||
|
||||
fun scheduleSyncForAccountRecordChangeSync() {
|
||||
DatabaseFactory.getRecipientDatabase(application).markNeedsSync(Recipient.self().id)
|
||||
StorageSyncHelper.scheduleSyncForDataChange()
|
||||
}
|
||||
|
||||
fun internetConnectionObserver(): Observable<Boolean> = Observable.create {
|
||||
val observer = object : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context?, intent: Intent?) {
|
||||
|
@ -124,7 +138,7 @@ class DonationPaymentRepository(activity: Activity) : StripeApi.PaymentIntentFet
|
|||
.donationsValues()
|
||||
.setSubscriber(Subscriber(subscriberId, SignalStore.donationsValues().getSubscriptionCurrency().currencyCode))
|
||||
|
||||
StorageSyncHelper.scheduleSyncForDataChange()
|
||||
scheduleSyncForAccountRecordChangeSync()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,9 @@ import org.thoughtcrime.securesms.components.settings.DSLConfiguration
|
|||
import org.thoughtcrime.securesms.components.settings.DSLSettingsAdapter
|
||||
import org.thoughtcrime.securesms.components.settings.DSLSettingsBottomSheetFragment
|
||||
import org.thoughtcrime.securesms.components.settings.DSLSettingsText
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.DonationPaymentComponent
|
||||
import org.thoughtcrime.securesms.components.settings.configure
|
||||
import org.thoughtcrime.securesms.keyboard.findListener
|
||||
import java.util.Locale
|
||||
|
||||
/**
|
||||
|
@ -13,6 +15,8 @@ import java.util.Locale
|
|||
*/
|
||||
class SetCurrencyFragment : DSLSettingsBottomSheetFragment() {
|
||||
|
||||
private lateinit var donationPaymentComponent: DonationPaymentComponent
|
||||
|
||||
private val viewModel: SetCurrencyViewModel by viewModels(
|
||||
factoryProducer = {
|
||||
val args = SetCurrencyFragmentArgs.fromBundle(requireArguments())
|
||||
|
@ -21,6 +25,8 @@ class SetCurrencyFragment : DSLSettingsBottomSheetFragment() {
|
|||
)
|
||||
|
||||
override fun bindAdapter(adapter: DSLSettingsAdapter) {
|
||||
donationPaymentComponent = findListener()!!
|
||||
|
||||
viewModel.state.observe(viewLifecycleOwner) { state ->
|
||||
adapter.submitList(getConfiguration(state).toMappingModelList())
|
||||
}
|
||||
|
@ -34,6 +40,7 @@ class SetCurrencyFragment : DSLSettingsBottomSheetFragment() {
|
|||
summary = DSLSettingsText.from(currency.currencyCode),
|
||||
onClick = {
|
||||
viewModel.setSelectedCurrency(currency.currencyCode)
|
||||
donationPaymentComponent.donationPaymentRepository.scheduleSyncForAccountRecordChange()
|
||||
dismissAllowingStateLoss()
|
||||
}
|
||||
)
|
||||
|
|
|
@ -6,7 +6,6 @@ import androidx.lifecycle.ViewModel
|
|||
import androidx.lifecycle.ViewModelProvider
|
||||
import org.thoughtcrime.securesms.BuildConfig
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
import org.thoughtcrime.securesms.storage.StorageSyncHelper
|
||||
import org.thoughtcrime.securesms.subscription.Subscriber
|
||||
import org.thoughtcrime.securesms.util.livedata.Store
|
||||
import org.whispersystems.signalservice.api.subscriptions.SubscriberId
|
||||
|
@ -52,8 +51,6 @@ class SetCurrencyViewModel(
|
|||
)
|
||||
)
|
||||
}
|
||||
|
||||
StorageSyncHelper.scheduleSyncForDataChange()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,6 @@ import org.thoughtcrime.securesms.components.settings.app.subscription.DonationE
|
|||
import org.thoughtcrime.securesms.components.settings.app.subscription.DonationPaymentRepository
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.SubscriptionsRepository
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
import org.thoughtcrime.securesms.storage.StorageSyncHelper
|
||||
import org.thoughtcrime.securesms.subscription.LevelUpdate
|
||||
import org.thoughtcrime.securesms.subscription.Subscriber
|
||||
import org.thoughtcrime.securesms.subscription.Subscription
|
||||
|
@ -105,7 +104,7 @@ class SubscribeViewModel(
|
|||
val usd = PlatformCurrencyUtil.USD
|
||||
val newSubscriber = SignalStore.donationsValues().getSubscriber(usd) ?: Subscriber(SubscriberId.generate(), usd.currencyCode)
|
||||
SignalStore.donationsValues().setSubscriber(newSubscriber)
|
||||
StorageSyncHelper.scheduleSyncForDataChange()
|
||||
donationPaymentRepository.scheduleSyncForAccountRecordChange()
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -22,6 +22,7 @@ import org.thoughtcrime.securesms.badges.BadgeImageView
|
|||
import org.thoughtcrime.securesms.badges.BadgeRepository
|
||||
import org.thoughtcrime.securesms.components.FixedRoundedCornerBottomSheetDialogFragment
|
||||
import org.thoughtcrime.securesms.components.settings.app.AppSettingsActivity
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
import org.thoughtcrime.securesms.util.SpanUtil
|
||||
import org.thoughtcrime.securesms.util.visible
|
||||
|
@ -87,7 +88,7 @@ class ThanksForYourSupportBottomSheetDialogFragment : FixedRoundedCornerBottomSh
|
|||
|
||||
val otherBadges = Recipient.self().badges.filterNot { it.id == args.badge.id }
|
||||
val hasOtherBadges = otherBadges.isNotEmpty()
|
||||
val displayingBadges = otherBadges.all { it.visible }
|
||||
val displayingBadges = SignalStore.donationsValues().getDisplayBadgesOnProfile()
|
||||
|
||||
if (hasOtherBadges && displayingBadges) {
|
||||
switch.isChecked = false
|
||||
|
|
|
@ -9,6 +9,7 @@ import org.thoughtcrime.securesms.jobmanager.Data;
|
|||
import org.thoughtcrime.securesms.jobmanager.Job;
|
||||
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
|
||||
import org.thoughtcrime.securesms.subscription.SubscriptionNotification;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.whispersystems.signalservice.internal.EmptyResponse;
|
||||
import org.whispersystems.signalservice.internal.ServiceResponse;
|
||||
|
||||
|
@ -85,7 +86,9 @@ public class DonationReceiptRedemptionJob extends BaseJob {
|
|||
ReceiptCredentialPresentation presentation = new ReceiptCredentialPresentation(presentationBytes);
|
||||
|
||||
ServiceResponse<EmptyResponse> response = ApplicationDependencies.getDonationsService()
|
||||
.redeemReceipt(presentation, false, false)
|
||||
.redeemReceipt(presentation,
|
||||
SignalStore.donationsValues().getDisplayBadgesOnProfile(),
|
||||
false)
|
||||
.blockingGet();
|
||||
|
||||
if (response.getApplicationError().isPresent()) {
|
||||
|
|
|
@ -221,10 +221,13 @@ public class RefreshOwnProfileJob extends BaseJob {
|
|||
List<Badge> appBadges = badges.stream().map(Badges::fromServiceBadge).collect(Collectors.toList());
|
||||
|
||||
if (userHasVisibleBadges && userHasInvisibleBadges) {
|
||||
Log.d(TAG, "Detected mixed visibility of badges. Telling the server to mark them all visible.", true);
|
||||
boolean displayBadgesOnProfile = SignalStore.donationsValues().getDisplayBadgesOnProfile();
|
||||
Log.d(TAG, "Detected mixed visibility of badges. Telling the server to mark them all " +
|
||||
(displayBadgesOnProfile ? "" : "not") +
|
||||
" visible.", true);
|
||||
|
||||
BadgeRepository badgeRepository = new BadgeRepository(context);
|
||||
badgeRepository.setVisibilityForAllBadges(true, appBadges).blockingSubscribe();
|
||||
badgeRepository.setVisibilityForAllBadges(displayBadgesOnProfile, appBadges).blockingSubscribe();
|
||||
} else {
|
||||
DatabaseFactory.getRecipientDatabase(context)
|
||||
.setBadges(Recipient.self().getId(), appBadges);
|
||||
|
|
|
@ -29,6 +29,7 @@ internal class DonationsValues internal constructor(store: KeyValueStore) : Sign
|
|||
private const val USER_MANUALLY_CANCELLED = "donation.user.manually.cancelled"
|
||||
private const val KEY_LEVEL_OPERATION_PREFIX = "donation.level.operation."
|
||||
private const val KEY_LEVEL_HISTORY = "donation.level.history"
|
||||
private const val DISPLAY_BADGES_ON_PROFILE = "donation.display.badges.on.profile"
|
||||
}
|
||||
|
||||
override fun onFirstEverAppLaunch() = Unit
|
||||
|
@ -188,4 +189,12 @@ internal class DonationsValues internal constructor(store: KeyValueStore) : Sign
|
|||
fun clearUserManuallyCancelled() {
|
||||
remove(USER_MANUALLY_CANCELLED)
|
||||
}
|
||||
|
||||
fun setDisplayBadgesOnProfile(enabled: Boolean) {
|
||||
putBoolean(DISPLAY_BADGES_ON_PROFILE, enabled)
|
||||
}
|
||||
|
||||
fun getDisplayBadgesOnProfile(): Boolean {
|
||||
return getBoolean(DISPLAY_BADGES_ON_PROFILE, false)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -108,8 +108,9 @@ public class AccountRecordProcessor extends DefaultStorageRecordProcessor<Signal
|
|||
boolean primarySendsSms = local.isPrimarySendsSms();
|
||||
String e164 = local.getE164();
|
||||
List<String> defaultReactions = remote.getDefaultReactions().size() > 0 ? remote.getDefaultReactions() : local.getDefaultReactions();
|
||||
boolean matchesRemote = doParamsMatch(remote, unknownFields, givenName, familyName, avatarUrlPath, profileKey, noteToSelfArchived, noteToSelfForcedUnread, readReceipts, typingIndicators, sealedSenderIndicators, linkPreviews, phoneNumberSharingMode, unlisted, pinnedConversations, preferContactAvatars, payments, universalExpireTimer, primarySendsSms, e164, defaultReactions, subscriber);
|
||||
boolean matchesLocal = doParamsMatch(local, unknownFields, givenName, familyName, avatarUrlPath, profileKey, noteToSelfArchived, noteToSelfForcedUnread, readReceipts, typingIndicators, sealedSenderIndicators, linkPreviews, phoneNumberSharingMode, unlisted, pinnedConversations, preferContactAvatars, payments, universalExpireTimer, primarySendsSms, e164, defaultReactions, subscriber);
|
||||
boolean displayBadgesOnProfile = remote.isDisplayBadgesOnProfile();
|
||||
boolean matchesRemote = doParamsMatch(remote, unknownFields, givenName, familyName, avatarUrlPath, profileKey, noteToSelfArchived, noteToSelfForcedUnread, readReceipts, typingIndicators, sealedSenderIndicators, linkPreviews, phoneNumberSharingMode, unlisted, pinnedConversations, preferContactAvatars, payments, universalExpireTimer, primarySendsSms, e164, defaultReactions, subscriber, displayBadgesOnProfile);
|
||||
boolean matchesLocal = doParamsMatch(local, unknownFields, givenName, familyName, avatarUrlPath, profileKey, noteToSelfArchived, noteToSelfForcedUnread, readReceipts, typingIndicators, sealedSenderIndicators, linkPreviews, phoneNumberSharingMode, unlisted, pinnedConversations, preferContactAvatars, payments, universalExpireTimer, primarySendsSms, e164, defaultReactions, subscriber, displayBadgesOnProfile);
|
||||
|
||||
if (matchesRemote) {
|
||||
return remote;
|
||||
|
@ -139,6 +140,7 @@ public class AccountRecordProcessor extends DefaultStorageRecordProcessor<Signal
|
|||
.setE164(e164)
|
||||
.setDefaultReactions(defaultReactions)
|
||||
.setSubscriber(subscriber)
|
||||
.setDisplayBadgesOnProfile(displayBadgesOnProfile)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
@ -179,7 +181,8 @@ public class AccountRecordProcessor extends DefaultStorageRecordProcessor<Signal
|
|||
boolean primarySendsSms,
|
||||
String e164,
|
||||
@NonNull List <String> defaultReactions,
|
||||
@NonNull SignalAccountRecord.Subscriber subscriber)
|
||||
@NonNull SignalAccountRecord.Subscriber subscriber,
|
||||
boolean displayBadgesOnProfile)
|
||||
{
|
||||
return Arrays.equals(contact.serializeUnknownFields(), unknownFields) &&
|
||||
Objects.equals(contact.getGivenName().or(""), givenName) &&
|
||||
|
@ -201,6 +204,7 @@ public class AccountRecordProcessor extends DefaultStorageRecordProcessor<Signal
|
|||
contact.getUniversalExpireTimer() == universalExpireTimer &&
|
||||
contact.isPrimarySendsSms() == primarySendsSms &&
|
||||
Objects.equals(contact.getPinnedConversations(), pinnedConversations) &&
|
||||
Objects.equals(contact.getSubscriber(), subscriber);
|
||||
Objects.equals(contact.getSubscriber(), subscriber) &&
|
||||
contact.isDisplayBadgesOnProfile() == displayBadgesOnProfile;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -133,6 +133,7 @@ public final class StorageSyncHelper {
|
|||
.setE164(TextSecurePreferences.getLocalNumber(context))
|
||||
.setDefaultReactions(SignalStore.emojiValues().getReactions())
|
||||
.setSubscriber(StorageSyncModels.localToRemoteSubscriber(SignalStore.donationsValues().getSubscriber()))
|
||||
.setDisplayBadgesOnProfile(SignalStore.donationsValues().getDisplayBadgesOnProfile())
|
||||
.build();
|
||||
|
||||
return SignalStorageRecord.forAccount(account);
|
||||
|
@ -156,6 +157,7 @@ public final class StorageSyncHelper {
|
|||
SignalStore.paymentsValues().setEnabledAndEntropy(update.getNew().getPayments().isEnabled(), Entropy.fromBytes(update.getNew().getPayments().getEntropy().orNull()));
|
||||
SignalStore.settings().setUniversalExpireTimer(update.getNew().getUniversalExpireTimer());
|
||||
SignalStore.emojiValues().setReactions(update.getNew().getDefaultReactions());
|
||||
SignalStore.donationsValues().setDisplayBadgesOnProfile(update.getNew().isDisplayBadgesOnProfile());
|
||||
|
||||
Subscriber subscriber = StorageSyncModels.remoteToLocalSubscriber(update.getNew().getSubscriber());
|
||||
if (subscriber != null) {
|
||||
|
|
|
@ -158,6 +158,10 @@ public final class SignalAccountRecord implements SignalRecord {
|
|||
diff.add("Subscriber");
|
||||
}
|
||||
|
||||
if (!Objects.equals(this.isDisplayBadgesOnProfile(), that.isDisplayBadgesOnProfile())) {
|
||||
diff.add("DisplayBadgesOnProfile");
|
||||
}
|
||||
|
||||
return diff.toString();
|
||||
} else {
|
||||
return "Different class. " + getClass().getSimpleName() + " | " + other.getClass().getSimpleName();
|
||||
|
@ -252,6 +256,10 @@ public final class SignalAccountRecord implements SignalRecord {
|
|||
return subscriber;
|
||||
}
|
||||
|
||||
public boolean isDisplayBadgesOnProfile() {
|
||||
return proto.getDisplayBadgesOnProfile();
|
||||
}
|
||||
|
||||
AccountRecord toProto() {
|
||||
return proto;
|
||||
}
|
||||
|
@ -575,6 +583,11 @@ public final class SignalAccountRecord implements SignalRecord {
|
|||
return this;
|
||||
}
|
||||
|
||||
public Builder setDisplayBadgesOnProfile(boolean displayBadgesOnProfile) {
|
||||
builder.setDisplayBadgesOnProfile(displayBadgesOnProfile);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SignalAccountRecord build() {
|
||||
AccountRecord proto = builder.build();
|
||||
|
||||
|
|
|
@ -150,4 +150,5 @@ message AccountRecord {
|
|||
repeated string preferredReactionEmoji = 20;
|
||||
bytes subscriberId = 21;
|
||||
string subscriberCurrencyCode = 22;
|
||||
bool displayBadgesOnProfile = 23;
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue