Make DonationSubscriptionManager a singleton instance, not a static class
This commit is contained in:
parent
8a0e1a9a2c
commit
714a789cc5
@ -223,10 +223,11 @@ public class AppEnvironment: NSObject {
|
||||
},
|
||||
)
|
||||
|
||||
let donationSubscriptionManager = DependenciesBridge.shared.donationSubscriptionManager
|
||||
cron.scheduleFrequently(
|
||||
mustBeRegistered: true,
|
||||
mustBeConnected: true,
|
||||
operation: { try await DonationSubscriptionManager.redeemSubscriptionIfNecessary() },
|
||||
operation: { try await donationSubscriptionManager.redeemSubscriptionIfNecessary() },
|
||||
handleResult: {
|
||||
switch $0 {
|
||||
case .success, .failure(is CancellationError):
|
||||
|
||||
@ -2006,7 +2006,7 @@ private extension CVComponentState.Builder {
|
||||
self.giftBadge = GiftBadge(
|
||||
messageUniqueId: messageUniqueId,
|
||||
otherUserShortName: threadViewModel.shortName ?? threadViewModel.name,
|
||||
cachedBadge: DonationSubscriptionManager.getCachedBadge(level: .giftBadge(level)),
|
||||
cachedBadge: DependenciesBridge.shared.donationSubscriptionManager.getCachedBadge(level: .giftBadge(level)),
|
||||
expirationDate: expirationDate,
|
||||
redemptionState: giftBadge.redemptionState,
|
||||
)
|
||||
|
||||
@ -83,7 +83,7 @@ extension ConversationViewController {
|
||||
let mode: BadgeIssueSheetState.Mode
|
||||
if isRedeemed {
|
||||
let hasCurrentSubscription = SSKEnvironment.shared.databaseStorageRef.read { tx -> Bool in
|
||||
return DonationSubscriptionManager.probablyHasCurrentSubscription(tx: tx)
|
||||
return DependenciesBridge.shared.donationSubscriptionManager.probablyHasCurrentSubscription(tx: tx)
|
||||
}
|
||||
mode = .giftBadgeExpired(hasCurrentSubscription: hasCurrentSubscription)
|
||||
} else {
|
||||
|
||||
@ -386,13 +386,13 @@ class DeleteAccountConfirmationViewController: OWSTableViewController2 {
|
||||
|
||||
private func deleteDonationSubscriptionIfNecessary() async throws {
|
||||
let activeSubscriptionId = SSKEnvironment.shared.databaseStorageRef.read {
|
||||
DonationSubscriptionManager.getSubscriberID(transaction: $0)
|
||||
DependenciesBridge.shared.donationSubscriptionManager.getSubscriberID(tx: $0)
|
||||
}
|
||||
guard let activeSubscriptionId else {
|
||||
return
|
||||
}
|
||||
Logger.info("Found subscriber ID. Canceling subscription...")
|
||||
return try await DonationSubscriptionManager.cancelSubscription(for: activeSubscriptionId)
|
||||
return try await DependenciesBridge.shared.donationSubscriptionManager.cancelSubscription(for: activeSubscriptionId)
|
||||
}
|
||||
|
||||
private func leaveGroups() async throws {
|
||||
|
||||
@ -74,7 +74,7 @@ public class BadgeGiftingChooseBadgeViewController: OWSTableViewController2 {
|
||||
private func loadData() async -> State {
|
||||
do {
|
||||
Logger.info("[Gifting] Fetching donation configuration...")
|
||||
let donationConfiguration = try await DonationSubscriptionManager.fetchDonationConfiguration()
|
||||
let donationConfiguration = try await DependenciesBridge.shared.donationSubscriptionManager.fetchDonationConfiguration()
|
||||
Logger.info("[Gifting] Populating badge assets...")
|
||||
let giftBadge = donationConfiguration.gift.badge
|
||||
try await SSKEnvironment.shared.profileManagerRef.badgeStore.populateAssetsOnBadge(giftBadge)
|
||||
|
||||
@ -581,10 +581,10 @@ extension DonationSettingsViewController {
|
||||
return ActionSheetAction(title: title.localizedTitle) { _ in
|
||||
Task.detached {
|
||||
let subscriberId = SSKEnvironment.shared.databaseStorageRef.read { tx in
|
||||
return DonationSubscriptionManager.getSubscriberID(transaction: tx)
|
||||
return DependenciesBridge.shared.donationSubscriptionManager.getSubscriberID(tx: tx)
|
||||
}
|
||||
if let subscriberId {
|
||||
try await DonationSubscriptionManager.cancelSubscription(for: subscriberId)
|
||||
try await DependenciesBridge.shared.donationSubscriptionManager.cancelSubscription(for: subscriberId)
|
||||
}
|
||||
await self.loadAndUpdateState()
|
||||
await self.showDonateViewController(preferredDonateMode: .monthly)
|
||||
|
||||
@ -120,7 +120,7 @@ class DonationSettingsViewController: OWSTableViewController2 {
|
||||
|
||||
@objc
|
||||
private func didLongPressAvatar(sender: UIGestureRecognizer) {
|
||||
let subscriberID = SSKEnvironment.shared.databaseStorageRef.read { DonationSubscriptionManager.getSubscriberID(transaction: $0) }
|
||||
let subscriberID = SSKEnvironment.shared.databaseStorageRef.read { DependenciesBridge.shared.donationSubscriptionManager.getSubscriberID(tx: $0) }
|
||||
guard let subscriberID else { return }
|
||||
|
||||
UIPasteboard.general.string = subscriberID.asBase64Url
|
||||
@ -163,7 +163,7 @@ class DonationSettingsViewController: OWSTableViewController2 {
|
||||
let resultStore = DependenciesBridge.shared.donationReceiptCredentialResultStore
|
||||
|
||||
return (
|
||||
subscriberID: DonationSubscriptionManager.getSubscriberID(transaction: tx),
|
||||
subscriberID: DependenciesBridge.shared.donationSubscriptionManager.getSubscriberID(tx: tx),
|
||||
hasEverRedeemedRecurringSubscriptionBadge: resultStore.getRedemptionSuccessForAnyRecurringSubscription(tx: tx) != nil,
|
||||
recurringSubscriptionReceiptCredentialRequestError: resultStore.getRequestErrorForAnyRecurringSubscription(tx: tx),
|
||||
oneTimeBoostReceiptCredentialRequestError: resultStore.getRequestError(errorMode: .oneTimeBoost, tx: tx),
|
||||
@ -175,7 +175,7 @@ class DonationSettingsViewController: OWSTableViewController2 {
|
||||
}
|
||||
|
||||
async let currentSubscription = DonationViewsUtil.loadCurrentSubscription(subscriberID: subscriberID)
|
||||
async let donationConfiguration = DonationSubscriptionManager.fetchDonationConfiguration()
|
||||
async let donationConfiguration = DependenciesBridge.shared.donationSubscriptionManager.fetchDonationConfiguration()
|
||||
|
||||
do {
|
||||
let subscriptionStatus: State.SubscriptionStatus
|
||||
@ -451,7 +451,7 @@ class DonationSettingsViewController: OWSTableViewController2 {
|
||||
|
||||
static func shouldShowExpiredGiftBadgeSheetWithSneakyTransaction() -> Bool {
|
||||
let expiredGiftBadgeID = SSKEnvironment.shared.databaseStorageRef.read { transaction in
|
||||
DonationSubscriptionManager.mostRecentlyExpiredGiftBadgeID(transaction: transaction)
|
||||
DependenciesBridge.shared.donationSubscriptionManager.mostRecentlyExpiredGiftBadgeID(tx: transaction)
|
||||
}
|
||||
guard let expiredGiftBadgeID, GiftBadgeIds.contains(expiredGiftBadgeID) else {
|
||||
return false
|
||||
@ -465,7 +465,7 @@ class DonationSettingsViewController: OWSTableViewController2 {
|
||||
}
|
||||
Logger.info("[Gifting] Preparing to show gift badge expiration sheet...")
|
||||
firstly {
|
||||
DonationSubscriptionManager.getCachedBadge(level: .giftBadge(.signalGift)).fetchIfNeeded()
|
||||
DependenciesBridge.shared.donationSubscriptionManager.getCachedBadge(level: .giftBadge(.signalGift)).fetchIfNeeded()
|
||||
}.done { [weak self] cachedValue in
|
||||
guard let self else { return }
|
||||
guard UIApplication.shared.frontmostViewController == self else { return }
|
||||
@ -473,12 +473,12 @@ class DonationSettingsViewController: OWSTableViewController2 {
|
||||
// The server confirmed this badge doesn't exist. This shouldn't happen,
|
||||
// but clear the flag so that we don't keep trying.
|
||||
Logger.warn("[Gifting] Clearing expired badge ID because the server said it didn't exist")
|
||||
DonationSubscriptionManager.clearMostRecentlyExpiredBadgeIDWithSneakyTransaction()
|
||||
DependenciesBridge.shared.donationSubscriptionManager.clearMostRecentlyExpiredBadgeIDWithSneakyTransaction()
|
||||
return
|
||||
}
|
||||
|
||||
let hasCurrentSubscription = SSKEnvironment.shared.databaseStorageRef.read { tx -> Bool in
|
||||
return DonationSubscriptionManager.probablyHasCurrentSubscription(tx: tx)
|
||||
return DependenciesBridge.shared.donationSubscriptionManager.probablyHasCurrentSubscription(tx: tx)
|
||||
}
|
||||
Logger.info("[Gifting] Showing badge gift expiration sheet (hasCurrentSubscription: \(hasCurrentSubscription))")
|
||||
let sheet = BadgeIssueSheet(badge: profileBadge, mode: .giftBadgeExpired(hasCurrentSubscription: hasCurrentSubscription))
|
||||
@ -486,7 +486,7 @@ class DonationSettingsViewController: OWSTableViewController2 {
|
||||
self.present(sheet, animated: true)
|
||||
|
||||
// We've shown it, so don't show it again.
|
||||
DonationSubscriptionManager.clearMostRecentlyExpiredGiftBadgeIDWithSneakyTransaction()
|
||||
DependenciesBridge.shared.donationSubscriptionManager.clearMostRecentlyExpiredGiftBadgeIDWithSneakyTransaction()
|
||||
}.cauterize()
|
||||
}
|
||||
|
||||
@ -728,10 +728,10 @@ extension DonationSettingsViewController: BadgeConfigurationDelegate {
|
||||
}
|
||||
|
||||
await SSKEnvironment.shared.databaseStorageRef.awaitableWrite { tx in
|
||||
DonationSubscriptionManager.setDisplayBadgesOnProfile(
|
||||
DependenciesBridge.shared.donationSubscriptionManager.setDisplayBadgesOnProfile(
|
||||
displayBadgesOnProfile,
|
||||
updateStorageService: true,
|
||||
transaction: tx,
|
||||
tx: tx,
|
||||
)
|
||||
}
|
||||
} catch {
|
||||
|
||||
@ -246,7 +246,7 @@ class InternalSettingsViewController: OWSTableViewController2 {
|
||||
TSThread.anyFetchAll(transaction: tx).filter { $0.isGroupThread }.count,
|
||||
TSInteraction.anyCount(transaction: tx),
|
||||
try? Attachment.Record.fetchCount(tx.database),
|
||||
DonationSubscriptionManager.getSubscriberID(transaction: tx),
|
||||
DependenciesBridge.shared.donationSubscriptionManager.getSubscriberID(tx: tx),
|
||||
SSKEnvironment.shared.storageServiceManagerRef.currentManifestVersion(tx: tx),
|
||||
DependenciesBridge.shared.tsAccountManager.getRegistrationId(for: .aci, tx: tx),
|
||||
DependenciesBridge.shared.tsAccountManager.getRegistrationId(for: .pni, tx: tx),
|
||||
|
||||
@ -62,7 +62,7 @@ final class BadgeConfigurationViewController: OWSTableViewController2, BadgeColl
|
||||
|
||||
static func load(delegate: BadgeConfigurationDelegate, tx: DBReadTransaction) -> Self {
|
||||
let badges = SSKEnvironment.shared.profileManagerRef.localUserProfile(tx: tx)?.badges ?? []
|
||||
let shouldDisplayOnProfile = DonationSubscriptionManager.displayBadgesOnProfile(transaction: tx)
|
||||
let shouldDisplayOnProfile = DependenciesBridge.shared.donationSubscriptionManager.displayBadgesOnProfile(tx: tx)
|
||||
return Self(availableBadges: badges, shouldDisplayOnProfile: shouldDisplayOnProfile, delegate: delegate)
|
||||
}
|
||||
|
||||
|
||||
@ -116,7 +116,7 @@ class ProfileSettingsViewController: OWSTableViewController2 {
|
||||
let localProfile: OWSUserProfile
|
||||
(localProfile, displayBadgesOnProfile) = databaseStorage.read { tx in (
|
||||
profileManager.localUserProfile(tx: tx)!,
|
||||
DonationSubscriptionManager.displayBadgesOnProfile(transaction: tx),
|
||||
DependenciesBridge.shared.donationSubscriptionManager.displayBadgesOnProfile(tx: tx),
|
||||
) }
|
||||
|
||||
allBadges = localProfile.badges
|
||||
@ -725,10 +725,10 @@ class ProfileSettingsViewController: OWSTableViewController2 {
|
||||
}
|
||||
try await updatePromise.awaitable()
|
||||
await databaseStorage.awaitableWrite { transaction in
|
||||
DonationSubscriptionManager.setDisplayBadgesOnProfile(
|
||||
DependenciesBridge.shared.donationSubscriptionManager.setDisplayBadgesOnProfile(
|
||||
displayBadgesOnProfile,
|
||||
updateStorageService: true,
|
||||
transaction: transaction,
|
||||
tx: transaction,
|
||||
)
|
||||
}
|
||||
} catch {
|
||||
|
||||
@ -229,7 +229,7 @@ class BadgeThanksSheet: OWSTableSheetViewController {
|
||||
guard let giftBadge = incomingMessage.giftBadge else {
|
||||
throw OWSAssertionError("trying to redeem message without a badge")
|
||||
}
|
||||
try await DonationSubscriptionManager.redeemReceiptCredentialPresentation(
|
||||
try await DependenciesBridge.shared.donationSubscriptionManager.redeemReceiptCredentialPresentation(
|
||||
receiptCredentialPresentation: try giftBadge.getReceiptCredentialPresentation(),
|
||||
)
|
||||
await Self.updateGiftBadge(incomingMessage: incomingMessage, state: .redeemed)
|
||||
|
||||
@ -33,13 +33,13 @@ extension DonateViewController {
|
||||
do {
|
||||
if let existingSubscriberId = monthly.subscriberID {
|
||||
Logger.info("[Donations] Cancelling existing subscription")
|
||||
try await DonationSubscriptionManager.cancelSubscription(for: existingSubscriberId)
|
||||
try await DependenciesBridge.shared.donationSubscriptionManager.cancelSubscription(for: existingSubscriberId)
|
||||
} else {
|
||||
Logger.info("[Donations] No existing subscription to cancel")
|
||||
}
|
||||
|
||||
Logger.info("[Donations] Preparing new monthly subscription with Apple Pay")
|
||||
subscriberId = try await DonationSubscriptionManager.prepareNewSubscription(
|
||||
subscriberId = try await DependenciesBridge.shared.donationSubscriptionManager.prepareNewSubscription(
|
||||
currencyCode: monthly.selectedCurrencyCode,
|
||||
)
|
||||
|
||||
@ -54,7 +54,7 @@ extension DonateViewController {
|
||||
let paymentMethodId = confirmedIntent.paymentMethodId
|
||||
|
||||
Logger.info("[Donations] Finalizing new subscription for Apple Pay donation")
|
||||
_ = try await DonationSubscriptionManager.finalizeNewSubscription(
|
||||
_ = try await DependenciesBridge.shared.donationSubscriptionManager.finalizeNewSubscription(
|
||||
forSubscriberId: subscriberId,
|
||||
paymentType: .applePay(paymentMethodId: paymentMethodId),
|
||||
subscription: selectedSubscriptionLevel,
|
||||
@ -76,7 +76,7 @@ extension DonateViewController {
|
||||
from: self,
|
||||
operation: {
|
||||
try await DonationViewsUtil.waitForRedemption(paymentMethod: .applePay) {
|
||||
try await DonationSubscriptionManager.requestAndRedeemReceipt(
|
||||
try await DependenciesBridge.shared.donationSubscriptionManager.requestAndRedeemReceipt(
|
||||
subscriberId: subscriberId,
|
||||
subscriptionLevel: selectedSubscriptionLevel.level,
|
||||
priorSubscriptionLevel: monthly.currentSubscriptionLevel?.level,
|
||||
|
||||
@ -78,13 +78,13 @@ extension DonateViewController {
|
||||
wrappedAsyncBlock: {
|
||||
if let existingSubscriberId = monthly.subscriberID {
|
||||
Logger.info("[Donations] Cancelling existing subscription")
|
||||
try await DonationSubscriptionManager.cancelSubscription(for: existingSubscriberId)
|
||||
try await DependenciesBridge.shared.donationSubscriptionManager.cancelSubscription(for: existingSubscriberId)
|
||||
} else {
|
||||
Logger.info("[Donations] No existing subscription to cancel")
|
||||
}
|
||||
|
||||
Logger.info("[Donations] Preparing new monthly subscription with PayPal")
|
||||
let subscriberId = try await DonationSubscriptionManager.prepareNewSubscription(
|
||||
let subscriberId = try await DependenciesBridge.shared.donationSubscriptionManager.prepareNewSubscription(
|
||||
currencyCode: monthly.selectedCurrencyCode,
|
||||
)
|
||||
|
||||
@ -107,7 +107,7 @@ extension DonateViewController {
|
||||
from: self,
|
||||
operation: {
|
||||
Logger.info("[Donations] Finalizing new subscription for PayPal donation")
|
||||
_ = try await DonationSubscriptionManager.finalizeNewSubscription(
|
||||
_ = try await DependenciesBridge.shared.donationSubscriptionManager.finalizeNewSubscription(
|
||||
forSubscriberId: subscriberId,
|
||||
paymentType: .paypal(paymentMethodId: paymentMethodId),
|
||||
subscription: selectedSubscriptionLevel,
|
||||
@ -116,7 +116,7 @@ extension DonateViewController {
|
||||
|
||||
Logger.info("[Donations] Redeeming monthly receipt for PayPal donation")
|
||||
try await DonationViewsUtil.waitForRedemption(paymentMethod: .paypal) {
|
||||
try await DonationSubscriptionManager.requestAndRedeemReceipt(
|
||||
try await DependenciesBridge.shared.donationSubscriptionManager.requestAndRedeemReceipt(
|
||||
subscriberId: subscriberId,
|
||||
subscriptionLevel: selectedSubscriptionLevel.level,
|
||||
priorSubscriptionLevel: monthly.currentSubscriptionLevel?.level,
|
||||
|
||||
@ -47,7 +47,7 @@ extension DonateViewController {
|
||||
from: self,
|
||||
operation: {
|
||||
try await DonationViewsUtil.waitForRedemption(paymentMethod: .applePay) {
|
||||
try await DonationSubscriptionManager.requestAndRedeemReceipt(
|
||||
try await DependenciesBridge.shared.donationSubscriptionManager.requestAndRedeemReceipt(
|
||||
boostPaymentIntentId: confirmedIntent.paymentIntentId,
|
||||
amount: amount,
|
||||
paymentProcessor: .stripe,
|
||||
|
||||
@ -83,7 +83,7 @@ extension DonateViewController {
|
||||
)
|
||||
|
||||
try await DonationViewsUtil.waitForRedemption(paymentMethod: .paypal) {
|
||||
try await DonationSubscriptionManager.requestAndRedeemReceipt(
|
||||
try await DependenciesBridge.shared.donationSubscriptionManager.requestAndRedeemReceipt(
|
||||
boostPaymentIntentId: paymentIntentId,
|
||||
amount: amount,
|
||||
paymentProcessor: .braintree,
|
||||
|
||||
@ -528,7 +528,7 @@ class DonateViewController: OWSViewController, OWSNavigationChildController {
|
||||
try await DonationViewsUtil.wrapInProgressView(
|
||||
from: self,
|
||||
operation: {
|
||||
let subscription = try await DonationSubscriptionManager.updateSubscriptionLevel(
|
||||
let subscription = try await DependenciesBridge.shared.donationSubscriptionManager.updateSubscriptionLevel(
|
||||
for: subscriberID,
|
||||
to: selectedSubscriptionLevel,
|
||||
currencyCode: monthly.selectedCurrencyCode,
|
||||
@ -540,7 +540,7 @@ class DonateViewController: OWSViewController, OWSNavigationChildController {
|
||||
|
||||
try await DonationViewsUtil.waitForRedemption(paymentMethod: subscription.donationPaymentMethod) {
|
||||
// Treat updates like new subscriptions
|
||||
try await DonationSubscriptionManager.requestAndRedeemReceipt(
|
||||
try await DependenciesBridge.shared.donationSubscriptionManager.requestAndRedeemReceipt(
|
||||
subscriberId: subscriberID,
|
||||
subscriptionLevel: selectedSubscriptionLevel.level,
|
||||
priorSubscriptionLevel: subscription.level,
|
||||
@ -657,7 +657,7 @@ class DonateViewController: OWSViewController, OWSNavigationChildController {
|
||||
canCancel: false,
|
||||
asyncBlock: { modal in
|
||||
do {
|
||||
try await DonationSubscriptionManager.cancelSubscription(for: subscriberID)
|
||||
try await DependenciesBridge.shared.donationSubscriptionManager.cancelSubscription(for: subscriberID)
|
||||
modal.dismiss { [weak self] in
|
||||
guard let self else { return }
|
||||
self.onFinished(.monthlySubscriptionCancelled(
|
||||
@ -774,9 +774,9 @@ class DonateViewController: OWSViewController, OWSNavigationChildController {
|
||||
pendingIDEALSubscription,
|
||||
) = SSKEnvironment.shared.databaseStorageRef.read {
|
||||
(
|
||||
DonationSubscriptionManager.getSubscriberID(transaction: $0),
|
||||
DonationSubscriptionManager.getSubscriberCurrencyCode(transaction: $0),
|
||||
DonationSubscriptionManager.getMostRecentSubscriptionPaymentMethod(transaction: $0),
|
||||
DependenciesBridge.shared.donationSubscriptionManager.getSubscriberID(tx: $0),
|
||||
DependenciesBridge.shared.donationSubscriptionManager.getSubscriberCurrencyCode(tx: $0),
|
||||
DependenciesBridge.shared.donationSubscriptionManager.getMostRecentSubscriptionPaymentMethod(tx: $0),
|
||||
DependenciesBridge.shared.donationReceiptCredentialResultStore
|
||||
.getRequestError(errorMode: .oneTimeBoost, tx: $0),
|
||||
DependenciesBridge.shared.donationReceiptCredentialResultStore
|
||||
@ -787,7 +787,7 @@ class DonateViewController: OWSViewController, OWSNavigationChildController {
|
||||
}
|
||||
|
||||
let donationConfigurationClosure = { () async throws -> DonationConfiguration in
|
||||
let donationConfiguration = try await DonationSubscriptionManager.fetchDonationConfiguration()
|
||||
let donationConfiguration = try await DependenciesBridge.shared.donationSubscriptionManager.fetchDonationConfiguration()
|
||||
|
||||
let boostBadge = donationConfiguration.boost.badge
|
||||
let subscriptionBadges = donationConfiguration.subscription.levels.map { $0.badge }
|
||||
|
||||
@ -28,13 +28,13 @@ extension DonationPaymentDetailsViewController {
|
||||
operation: {
|
||||
if let existingSubscriberId {
|
||||
Logger.info("[Donations] Cancelling existing subscription")
|
||||
try await DonationSubscriptionManager.cancelSubscription(for: existingSubscriberId)
|
||||
try await DependenciesBridge.shared.donationSubscriptionManager.cancelSubscription(for: existingSubscriberId)
|
||||
} else {
|
||||
Logger.info("[Donations] No existing subscription to cancel")
|
||||
}
|
||||
|
||||
Logger.info("[Donations] Preparing new monthly subscription")
|
||||
let subscriberId = try await DonationSubscriptionManager.prepareNewSubscription(currencyCode: currencyCode)
|
||||
let subscriberId = try await DependenciesBridge.shared.donationSubscriptionManager.prepareNewSubscription(currencyCode: currencyCode)
|
||||
|
||||
Logger.info("[Donations] Creating Signal payment method for new monthly subscription")
|
||||
let clientSecret = try await Stripe.createSignalPaymentMethodForSubscription(subscriberId: subscriberId)
|
||||
|
||||
@ -219,7 +219,7 @@ extension DonationViewsUtil {
|
||||
) async throws -> ProfileBadge? {
|
||||
switch donationType {
|
||||
case .oneTime:
|
||||
switch try await DonationSubscriptionManager.getCachedBadge(level: .boostBadge).fetchIfNeeded().awaitable() {
|
||||
switch try await DependenciesBridge.shared.donationSubscriptionManager.getCachedBadge(level: .boostBadge).fetchIfNeeded().awaitable() {
|
||||
case .notFound:
|
||||
return nil
|
||||
case let .profileBadge(profileBadge):
|
||||
|
||||
@ -295,7 +295,7 @@ public enum DonationViewsUtil {
|
||||
paymentMethod: DonationPaymentMethod,
|
||||
) async throws {
|
||||
return try await DonationViewsUtil.waitForRedemption(paymentMethod: paymentMethod) {
|
||||
try await DonationSubscriptionManager.requestAndRedeemReceipt(
|
||||
try await DependenciesBridge.shared.donationSubscriptionManager.requestAndRedeemReceipt(
|
||||
boostPaymentIntentId: paymentIntentId,
|
||||
amount: amount,
|
||||
paymentProcessor: .stripe,
|
||||
@ -313,7 +313,7 @@ public enum DonationViewsUtil {
|
||||
) async throws {
|
||||
Logger.info("[Donations] Finalizing new subscription")
|
||||
|
||||
_ = try await DonationSubscriptionManager.finalizeNewSubscription(
|
||||
_ = try await DependenciesBridge.shared.donationSubscriptionManager.finalizeNewSubscription(
|
||||
forSubscriberId: subscriberId,
|
||||
paymentType: paymentType,
|
||||
subscription: newSubscriptionLevel,
|
||||
@ -323,7 +323,7 @@ public enum DonationViewsUtil {
|
||||
Logger.info("[Donations] Redeeming monthly receipts")
|
||||
|
||||
return try await DonationViewsUtil.waitForRedemption(paymentMethod: paymentType.paymentMethod) {
|
||||
try await DonationSubscriptionManager.requestAndRedeemReceipt(
|
||||
try await DependenciesBridge.shared.donationSubscriptionManager.requestAndRedeemReceipt(
|
||||
subscriberId: subscriberId,
|
||||
subscriptionLevel: newSubscriptionLevel.level,
|
||||
priorSubscriptionLevel: priorSubscriptionLevel?.level,
|
||||
|
||||
@ -51,7 +51,7 @@ class ChatListFYISheetCoordinator {
|
||||
private let backupExportJobRunner: BackupExportJobRunner
|
||||
private let backupSubscriptionIssueStore: BackupSubscriptionIssueStore
|
||||
private let donationReceiptCredentialResultStore: DonationReceiptCredentialResultStore
|
||||
private let donationSubscriptionManager: DonationSubscriptionManager.Type
|
||||
private let donationSubscriptionManager: DonationSubscriptionManager
|
||||
private let db: DB
|
||||
private let keyTransparencyStore: KeyTransparencyStore
|
||||
private let networkManager: NetworkManager
|
||||
@ -61,7 +61,7 @@ class ChatListFYISheetCoordinator {
|
||||
backupExportJobRunner: BackupExportJobRunner,
|
||||
backupSubscriptionIssueStore: BackupSubscriptionIssueStore,
|
||||
donationReceiptCredentialResultStore: DonationReceiptCredentialResultStore,
|
||||
donationSubscriptionManager: DonationSubscriptionManager.Type,
|
||||
donationSubscriptionManager: DonationSubscriptionManager,
|
||||
db: DB,
|
||||
keyTransparencyStore: KeyTransparencyStore,
|
||||
networkManager: NetworkManager,
|
||||
@ -104,13 +104,13 @@ class ChatListFYISheetCoordinator {
|
||||
} else if let sheet = shouldShowBadgeIssueSheet(errorMode: .recurringSubscriptionRenewal, tx: tx) {
|
||||
return sheet
|
||||
} else if
|
||||
let expiredBadgeID = donationSubscriptionManager.mostRecentlyExpiredBadgeID(transaction: tx),
|
||||
donationSubscriptionManager.showExpirySheetOnHomeScreenKey(transaction: tx)
|
||||
let expiredBadgeID = donationSubscriptionManager.mostRecentlyExpiredBadgeID(tx: tx),
|
||||
donationSubscriptionManager.showExpirySheetOnHomeScreenKey(tx: tx)
|
||||
{
|
||||
return .badgeExpiration(FYISheet.BadgeExpiration(
|
||||
expiredBadgeID: expiredBadgeID,
|
||||
donationSubscriberID: donationSubscriptionManager.getSubscriberID(transaction: tx),
|
||||
mostRecentSubscriptionPaymentMethod: donationSubscriptionManager.getMostRecentSubscriptionPaymentMethod(transaction: tx),
|
||||
donationSubscriberID: donationSubscriptionManager.getSubscriberID(tx: tx),
|
||||
mostRecentSubscriptionPaymentMethod: donationSubscriptionManager.getMostRecentSubscriptionPaymentMethod(tx: tx),
|
||||
probablyHasCurrentSubscription: donationSubscriptionManager.probablyHasCurrentSubscription(tx: tx),
|
||||
))
|
||||
} else if backupSubscriptionIssueStore.shouldWarnIAPSubscriptionExpired(tx: tx) {
|
||||
@ -335,7 +335,7 @@ class ChatListFYISheetCoordinator {
|
||||
await chatListViewController.awaitablePresent(badgeIssueSheet, animated: true)
|
||||
|
||||
await db.awaitableWrite { tx in
|
||||
donationSubscriptionManager.setShowExpirySheetOnHomeScreenKey(show: false, transaction: tx)
|
||||
donationSubscriptionManager.setShowExpirySheetOnHomeScreenKey(show: false, tx: tx)
|
||||
}
|
||||
} else if SubscriptionBadgeIds.contains(expiredBadgeID) {
|
||||
/// We expect to show an error sheet when the subscription fails to
|
||||
@ -390,7 +390,7 @@ class ChatListFYISheetCoordinator {
|
||||
}
|
||||
|
||||
await db.awaitableWrite { tx in
|
||||
donationSubscriptionManager.setShowExpirySheetOnHomeScreenKey(show: false, transaction: tx)
|
||||
donationSubscriptionManager.setShowExpirySheetOnHomeScreenKey(show: false, tx: tx)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -376,7 +376,7 @@ public class ChatListViewController: OWSViewController, HomeTabViewController {
|
||||
backupExportJobRunner: DependenciesBridge.shared.backupExportJobRunner,
|
||||
backupSubscriptionIssueStore: BackupSubscriptionIssueStore(),
|
||||
donationReceiptCredentialResultStore: DependenciesBridge.shared.donationReceiptCredentialResultStore,
|
||||
donationSubscriptionManager: DonationSubscriptionManager.self,
|
||||
donationSubscriptionManager: DependenciesBridge.shared.donationSubscriptionManager,
|
||||
db: DependenciesBridge.shared.db,
|
||||
keyTransparencyStore: KeyTransparencyStore(),
|
||||
networkManager: SSKEnvironment.shared.networkManagerRef,
|
||||
|
||||
@ -125,36 +125,42 @@ public protocol _MessageBackup_DonationSubscriptionManagerShim {
|
||||
}
|
||||
|
||||
public class _MessageBackup_DonationSubscriptionManagerWrapper: _MessageBackup_DonationSubscriptionManagerShim {
|
||||
private let donationSubscriptionManager: DonationSubscriptionManager
|
||||
|
||||
public init(_ donationSubscriptionManager: DonationSubscriptionManager) {
|
||||
self.donationSubscriptionManager = donationSubscriptionManager
|
||||
}
|
||||
|
||||
public func displayBadgesOnProfile(tx: DBReadTransaction) -> Bool {
|
||||
DonationSubscriptionManager.displayBadgesOnProfile(transaction: tx)
|
||||
donationSubscriptionManager.displayBadgesOnProfile(tx: tx)
|
||||
}
|
||||
|
||||
public func setDisplayBadgesOnProfile(value: Bool, tx: DBWriteTransaction) {
|
||||
DonationSubscriptionManager.setDisplayBadgesOnProfile(value, updateStorageService: false, transaction: tx)
|
||||
donationSubscriptionManager.setDisplayBadgesOnProfile(value, updateStorageService: false, tx: tx)
|
||||
}
|
||||
|
||||
public func getSubscriberID(tx: DBReadTransaction) -> Data? {
|
||||
DonationSubscriptionManager.getSubscriberID(transaction: tx)
|
||||
donationSubscriptionManager.getSubscriberID(tx: tx)
|
||||
}
|
||||
|
||||
public func setSubscriberID(subscriberID: Data, tx: DBWriteTransaction) {
|
||||
DonationSubscriptionManager.setSubscriberID(subscriberID, transaction: tx)
|
||||
donationSubscriptionManager.setSubscriberID(subscriberID, tx: tx)
|
||||
}
|
||||
|
||||
public func getSubscriberCurrencyCode(tx: DBReadTransaction) -> String? {
|
||||
DonationSubscriptionManager.getSubscriberCurrencyCode(transaction: tx)
|
||||
donationSubscriptionManager.getSubscriberCurrencyCode(tx: tx)
|
||||
}
|
||||
|
||||
public func setSubscriberCurrencyCode(currencyCode: Currency.Code?, tx: DBWriteTransaction) {
|
||||
DonationSubscriptionManager.setSubscriberCurrencyCode(currencyCode, transaction: tx)
|
||||
donationSubscriptionManager.setSubscriberCurrencyCode(currencyCode, tx: tx)
|
||||
}
|
||||
|
||||
public func userManuallyCancelledSubscription(tx: DBReadTransaction) -> Bool {
|
||||
DonationSubscriptionManager.userManuallyCancelledSubscription(transaction: tx)
|
||||
donationSubscriptionManager.userManuallyCancelledSubscription(tx: tx)
|
||||
}
|
||||
|
||||
public func setUserManuallyCancelledSubscription(value: Bool, tx: DBWriteTransaction) {
|
||||
DonationSubscriptionManager.setUserManuallyCancelledSubscription(value, updateStorageService: false, transaction: tx)
|
||||
donationSubscriptionManager.setUserManuallyCancelledSubscription(value, updateStorageService: false, tx: tx)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1232,6 +1232,15 @@ extension AppSetup.GlobalsContinuation {
|
||||
)
|
||||
|
||||
let donationReceiptCredentialResultStore = DonationReceiptCredentialResultStore()
|
||||
let donationSubscriptionManager = DonationSubscriptionManager(
|
||||
db: db,
|
||||
donationReceiptCredentialResultStore: donationReceiptCredentialResultStore,
|
||||
networkManager: networkManager,
|
||||
profileManager: profileManager,
|
||||
storageServiceManager: storageServiceManager,
|
||||
subscriptionConfigManager: subscriptionConfigManager,
|
||||
tsAccountManager: tsAccountManager,
|
||||
)
|
||||
|
||||
let usernameApiClient = UsernameApiClientImpl(
|
||||
networkManager: networkManager,
|
||||
@ -1452,7 +1461,7 @@ extension AppSetup.GlobalsContinuation {
|
||||
callServiceSettingsStore: CallServiceSettingsStore(),
|
||||
chatStyleArchiver: backupChatStyleArchiver,
|
||||
disappearingMessageConfigurationStore: disappearingMessagesConfigurationStore,
|
||||
donationSubscriptionManager: BackupArchive.Wrappers.DonationSubscriptionManager(),
|
||||
donationSubscriptionManager: BackupArchive.Wrappers.DonationSubscriptionManager(donationSubscriptionManager),
|
||||
imageQuality: BackupArchive.Wrappers.ImageQuality(),
|
||||
keyTransparencyManager: keyTransparencyManager,
|
||||
keyTransparencyStore: keyTransparencyStore,
|
||||
@ -1743,6 +1752,7 @@ extension AppSetup.GlobalsContinuation {
|
||||
disappearingMessagesConfigurationStore: disappearingMessagesConfigurationStore,
|
||||
disappearingMessagesExpirationJob: disappearingMessagesExpirationJob,
|
||||
donationReceiptCredentialResultStore: donationReceiptCredentialResultStore,
|
||||
donationSubscriptionManager: donationSubscriptionManager,
|
||||
editManager: editManager,
|
||||
editMessageStore: editMessageStore,
|
||||
externalPendingIDEALDonationStore: externalPendingIDEALDonationStore,
|
||||
@ -1866,6 +1876,7 @@ extension AppSetup.GlobalsContinuation {
|
||||
dateProvider: dateProvider,
|
||||
db: db,
|
||||
donationReceiptCredentialResultStore: donationReceiptCredentialResultStore,
|
||||
donationSubscriptionManager: donationSubscriptionManager,
|
||||
networkManager: networkManager,
|
||||
profileManager: profileManager,
|
||||
reachabilityManager: reachabilityManager,
|
||||
|
||||
@ -110,6 +110,7 @@ public class DependenciesBridge {
|
||||
public let disappearingMessagesConfigurationStore: DisappearingMessagesConfigurationStore
|
||||
public let disappearingMessagesExpirationJob: DisappearingMessagesExpirationJob
|
||||
public let donationReceiptCredentialResultStore: DonationReceiptCredentialResultStore
|
||||
public let donationSubscriptionManager: DonationSubscriptionManager
|
||||
public let editManager: EditManager
|
||||
public let editMessageStore: EditMessageStore
|
||||
public let externalPendingIDEALDonationStore: ExternalPendingIDEALDonationStore
|
||||
@ -252,6 +253,7 @@ public class DependenciesBridge {
|
||||
disappearingMessagesConfigurationStore: DisappearingMessagesConfigurationStore,
|
||||
disappearingMessagesExpirationJob: DisappearingMessagesExpirationJob,
|
||||
donationReceiptCredentialResultStore: DonationReceiptCredentialResultStore,
|
||||
donationSubscriptionManager: DonationSubscriptionManager,
|
||||
editManager: EditManager,
|
||||
editMessageStore: EditMessageStore,
|
||||
externalPendingIDEALDonationStore: ExternalPendingIDEALDonationStore,
|
||||
@ -393,6 +395,7 @@ public class DependenciesBridge {
|
||||
self.disappearingMessagesConfigurationStore = disappearingMessagesConfigurationStore
|
||||
self.disappearingMessagesExpirationJob = disappearingMessagesExpirationJob
|
||||
self.donationReceiptCredentialResultStore = donationReceiptCredentialResultStore
|
||||
self.donationSubscriptionManager = donationSubscriptionManager
|
||||
self.editManager = editManager
|
||||
self.editMessageStore = editMessageStore
|
||||
self.externalPendingIDEALDonationStore = externalPendingIDEALDonationStore
|
||||
|
||||
@ -51,6 +51,7 @@ public class DonationReceiptCredentialRedemptionJobQueue {
|
||||
dateProvider: @escaping DateProvider,
|
||||
db: any DB,
|
||||
donationReceiptCredentialResultStore: DonationReceiptCredentialResultStore,
|
||||
donationSubscriptionManager: DonationSubscriptionManager,
|
||||
networkManager: NetworkManager,
|
||||
profileManager: ProfileManager,
|
||||
reachabilityManager: SSKReachabilityManager,
|
||||
@ -60,6 +61,7 @@ public class DonationReceiptCredentialRedemptionJobQueue {
|
||||
dateProvider: dateProvider,
|
||||
db: db,
|
||||
donationReceiptCredentialResultStore: donationReceiptCredentialResultStore,
|
||||
donationSubscriptionManager: donationSubscriptionManager,
|
||||
logger: .donations,
|
||||
networkManager: networkManager,
|
||||
profileManager: profileManager,
|
||||
@ -222,6 +224,7 @@ private class DonationReceiptCredentialRedemptionJobRunnerFactory: JobRunnerFact
|
||||
private let dateProvider: DateProvider
|
||||
private let db: DB
|
||||
private let donationReceiptCredentialResultStore: DonationReceiptCredentialResultStore
|
||||
private let donationSubscriptionManager: DonationSubscriptionManager
|
||||
private let logger: PrefixedLogger
|
||||
private let networkManager: NetworkManager
|
||||
private let profileManager: ProfileManager
|
||||
@ -231,6 +234,7 @@ private class DonationReceiptCredentialRedemptionJobRunnerFactory: JobRunnerFact
|
||||
dateProvider: @escaping DateProvider,
|
||||
db: DB,
|
||||
donationReceiptCredentialResultStore: DonationReceiptCredentialResultStore,
|
||||
donationSubscriptionManager: DonationSubscriptionManager,
|
||||
logger: PrefixedLogger,
|
||||
networkManager: NetworkManager,
|
||||
profileManager: ProfileManager,
|
||||
@ -239,6 +243,7 @@ private class DonationReceiptCredentialRedemptionJobRunnerFactory: JobRunnerFact
|
||||
self.dateProvider = dateProvider
|
||||
self.db = db
|
||||
self.donationReceiptCredentialResultStore = donationReceiptCredentialResultStore
|
||||
self.donationSubscriptionManager = donationSubscriptionManager
|
||||
self.logger = logger
|
||||
self.networkManager = networkManager
|
||||
self.profileManager = profileManager
|
||||
@ -253,6 +258,7 @@ private class DonationReceiptCredentialRedemptionJobRunnerFactory: JobRunnerFact
|
||||
dateProvider: dateProvider,
|
||||
db: db,
|
||||
donationReceiptCredentialResultStore: donationReceiptCredentialResultStore,
|
||||
donationSubscriptionManager: donationSubscriptionManager,
|
||||
networkManager: networkManager,
|
||||
profileManager: profileManager,
|
||||
tsAccountManager: tsAccountManager,
|
||||
@ -268,6 +274,7 @@ private class DonationReceiptCredentialRedemptionJobRunner: JobRunner {
|
||||
private let dateProvider: DateProvider
|
||||
private let db: DB
|
||||
private let donationReceiptCredentialResultStore: DonationReceiptCredentialResultStore
|
||||
private let donationSubscriptionManager: DonationSubscriptionManager
|
||||
private let networkManager: NetworkManager
|
||||
private let profileManager: ProfileManager
|
||||
private let receiptCredentialManager: ReceiptCredentialManager
|
||||
@ -281,6 +288,7 @@ private class DonationReceiptCredentialRedemptionJobRunner: JobRunner {
|
||||
dateProvider: @escaping DateProvider,
|
||||
db: DB,
|
||||
donationReceiptCredentialResultStore: DonationReceiptCredentialResultStore,
|
||||
donationSubscriptionManager: DonationSubscriptionManager,
|
||||
networkManager: NetworkManager,
|
||||
profileManager: ProfileManager,
|
||||
tsAccountManager: TSAccountManager,
|
||||
@ -290,6 +298,7 @@ private class DonationReceiptCredentialRedemptionJobRunner: JobRunner {
|
||||
self.dateProvider = dateProvider
|
||||
self.db = db
|
||||
self.donationReceiptCredentialResultStore = donationReceiptCredentialResultStore
|
||||
self.donationSubscriptionManager = donationSubscriptionManager
|
||||
self.networkManager = networkManager
|
||||
self.profileManager = profileManager
|
||||
self.receiptCredentialManager = ReceiptCredentialManager(
|
||||
@ -616,7 +625,7 @@ private class DonationReceiptCredentialRedemptionJobRunner: JobRunner {
|
||||
}
|
||||
}
|
||||
|
||||
try await DonationSubscriptionManager.redeemReceiptCredentialPresentation(
|
||||
try await donationSubscriptionManager.redeemReceiptCredentialPresentation(
|
||||
receiptCredentialPresentation: receiptCredentialPresentation,
|
||||
)
|
||||
|
||||
@ -671,9 +680,9 @@ private class DonationReceiptCredentialRedemptionJobRunner: JobRunner {
|
||||
private func loadBadge(paymentType: PaymentType) async throws -> ProfileBadge {
|
||||
switch paymentType {
|
||||
case .oneTimeBoost:
|
||||
return try await DonationSubscriptionManager.getBoostBadge()
|
||||
return try await donationSubscriptionManager.getBoostBadge()
|
||||
case let .recurringSubscription(_, targetSubscriptionLevel, _, _):
|
||||
return try await DonationSubscriptionManager.getSubscriptionBadge(subscriptionLevel: targetSubscriptionLevel)
|
||||
return try await donationSubscriptionManager.getSubscriptionBadge(subscriptionLevel: targetSubscriptionLevel)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1168,9 +1168,9 @@ extension OWSUserProfile {
|
||||
}
|
||||
|
||||
if case .localUser = internalAddress, case .setTo = changes.badges {
|
||||
DonationSubscriptionManager.reconcileBadgeStates(
|
||||
DependenciesBridge.shared.donationSubscriptionManager.reconcileBadgeStates(
|
||||
currentLocalUserProfile: newInstance,
|
||||
transaction: tx,
|
||||
tx: tx,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -2163,6 +2163,7 @@ class StorageServiceOperation {
|
||||
avatarDefaultColorManager: DependenciesBridge.shared.avatarDefaultColorManager,
|
||||
backupPlanManager: DependenciesBridge.shared.backupPlanManager,
|
||||
backupSubscriptionManager: DependenciesBridge.shared.backupSubscriptionManager,
|
||||
donationSubscriptionManager: DependenciesBridge.shared.donationSubscriptionManager,
|
||||
dmConfigurationStore: DependenciesBridge.shared.disappearingMessagesConfigurationStore,
|
||||
linkPreviewSettingStore: DependenciesBridge.shared.linkPreviewSettingStore,
|
||||
localUsernameManager: DependenciesBridge.shared.localUsernameManager,
|
||||
|
||||
@ -1194,6 +1194,7 @@ class StorageServiceAccountRecordUpdater: StorageServiceRecordUpdater {
|
||||
private let avatarDefaultColorManager: AvatarDefaultColorManager
|
||||
private let backupPlanManager: BackupPlanManager
|
||||
private let backupSubscriptionManager: BackupSubscriptionManager
|
||||
private let donationSubscriptionManager: DonationSubscriptionManager
|
||||
private let dmConfigurationStore: DisappearingMessagesConfigurationStore
|
||||
private let linkPreviewSettingStore: LinkPreviewSettingStore
|
||||
private let localUsernameManager: LocalUsernameManager
|
||||
@ -1221,6 +1222,7 @@ class StorageServiceAccountRecordUpdater: StorageServiceRecordUpdater {
|
||||
avatarDefaultColorManager: AvatarDefaultColorManager,
|
||||
backupPlanManager: BackupPlanManager,
|
||||
backupSubscriptionManager: BackupSubscriptionManager,
|
||||
donationSubscriptionManager: DonationSubscriptionManager,
|
||||
dmConfigurationStore: DisappearingMessagesConfigurationStore,
|
||||
linkPreviewSettingStore: LinkPreviewSettingStore,
|
||||
localUsernameManager: LocalUsernameManager,
|
||||
@ -1248,6 +1250,7 @@ class StorageServiceAccountRecordUpdater: StorageServiceRecordUpdater {
|
||||
self.avatarDefaultColorManager = avatarDefaultColorManager
|
||||
self.backupPlanManager = backupPlanManager
|
||||
self.backupSubscriptionManager = backupSubscriptionManager
|
||||
self.donationSubscriptionManager = donationSubscriptionManager
|
||||
self.dmConfigurationStore = dmConfigurationStore
|
||||
self.linkPreviewSettingStore = linkPreviewSettingStore
|
||||
self.localUsernameManager = localUsernameManager
|
||||
@ -1377,13 +1380,13 @@ class StorageServiceAccountRecordUpdater: StorageServiceRecordUpdater {
|
||||
}
|
||||
|
||||
if
|
||||
let donationSubscriberID = DonationSubscriptionManager.getSubscriberID(transaction: transaction),
|
||||
let donationSubscriberCurrencyCode = DonationSubscriptionManager.getSubscriberCurrencyCode(transaction: transaction)
|
||||
let donationSubscriberID = donationSubscriptionManager.getSubscriberID(tx: transaction),
|
||||
let donationSubscriberCurrencyCode = donationSubscriptionManager.getSubscriberCurrencyCode(tx: transaction)
|
||||
{
|
||||
builder.setDonorSubscriberID(donationSubscriberID)
|
||||
builder.setDonorSubscriberCurrencyCode(donationSubscriberCurrencyCode)
|
||||
}
|
||||
builder.setDonorSubscriptionManuallyCancelled(DonationSubscriptionManager.userManuallyCancelledSubscription(transaction: transaction))
|
||||
builder.setDonorSubscriptionManuallyCancelled(donationSubscriptionManager.userManuallyCancelledSubscription(tx: transaction))
|
||||
|
||||
if let backupSubscriberData = backupSubscriptionManager.getIAPSubscriberData(tx: transaction) {
|
||||
var subscriberDataBuilder = StorageServiceProtoAccountRecordIAPSubscriberData.builder()
|
||||
@ -1404,7 +1407,7 @@ class StorageServiceAccountRecordUpdater: StorageServiceRecordUpdater {
|
||||
builder.setReadOnboardingStory(systemStoryManager.isOnboardingStoryRead(transaction: transaction))
|
||||
builder.setViewedOnboardingStory(systemStoryManager.isOnboardingStoryViewed(transaction: transaction))
|
||||
|
||||
builder.setDisplayBadgesOnProfile(DonationSubscriptionManager.displayBadgesOnProfile(transaction: transaction))
|
||||
builder.setDisplayBadgesOnProfile(donationSubscriptionManager.displayBadgesOnProfile(tx: transaction))
|
||||
|
||||
builder.setKeepMutedChatsArchived(SSKPreferences.shouldKeepMutedChatsArchived(transaction: transaction))
|
||||
|
||||
@ -1686,21 +1689,21 @@ class StorageServiceAccountRecordUpdater: StorageServiceRecordUpdater {
|
||||
let donationSubscriberId = record.donorSubscriberID,
|
||||
let donationSubscriberCurrencyCode = record.donorSubscriberCurrencyCode
|
||||
{
|
||||
if donationSubscriberId != DonationSubscriptionManager.getSubscriberID(transaction: transaction) {
|
||||
DonationSubscriptionManager.setSubscriberID(donationSubscriberId, transaction: transaction)
|
||||
if donationSubscriberId != donationSubscriptionManager.getSubscriberID(tx: transaction) {
|
||||
donationSubscriptionManager.setSubscriberID(donationSubscriberId, tx: transaction)
|
||||
}
|
||||
|
||||
if donationSubscriberCurrencyCode != DonationSubscriptionManager.getSubscriberCurrencyCode(transaction: transaction) {
|
||||
DonationSubscriptionManager.setSubscriberCurrencyCode(donationSubscriberCurrencyCode, transaction: transaction)
|
||||
if donationSubscriberCurrencyCode != donationSubscriptionManager.getSubscriberCurrencyCode(tx: transaction) {
|
||||
donationSubscriptionManager.setSubscriberCurrencyCode(donationSubscriberCurrencyCode, tx: transaction)
|
||||
}
|
||||
}
|
||||
|
||||
let localDonationSubscriptionManuallyCancelled = DonationSubscriptionManager.userManuallyCancelledSubscription(transaction: transaction)
|
||||
let localDonationSubscriptionManuallyCancelled = donationSubscriptionManager.userManuallyCancelledSubscription(tx: transaction)
|
||||
if localDonationSubscriptionManuallyCancelled != record.donorSubscriptionManuallyCancelled {
|
||||
DonationSubscriptionManager.setUserManuallyCancelledSubscription(
|
||||
donationSubscriptionManager.setUserManuallyCancelledSubscription(
|
||||
record.donorSubscriptionManuallyCancelled,
|
||||
updateStorageService: false,
|
||||
transaction: transaction,
|
||||
tx: transaction,
|
||||
)
|
||||
}
|
||||
|
||||
@ -1728,12 +1731,12 @@ class StorageServiceAccountRecordUpdater: StorageServiceRecordUpdater {
|
||||
)
|
||||
}
|
||||
|
||||
let localDisplayBadgesOnProfile = DonationSubscriptionManager.displayBadgesOnProfile(transaction: transaction)
|
||||
let localDisplayBadgesOnProfile = donationSubscriptionManager.displayBadgesOnProfile(tx: transaction)
|
||||
if localDisplayBadgesOnProfile != record.displayBadgesOnProfile {
|
||||
DonationSubscriptionManager.setDisplayBadgesOnProfile(
|
||||
donationSubscriptionManager.setDisplayBadgesOnProfile(
|
||||
record.displayBadgesOnProfile,
|
||||
updateStorageService: false,
|
||||
transaction: transaction,
|
||||
tx: transaction,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -47,7 +47,7 @@ public final class CachedBadge: Equatable {
|
||||
}
|
||||
// Otherwise, kick off a new fetch.
|
||||
let fetchPromise: Promise<Value> = Promise.wrapAsync {
|
||||
try await DonationSubscriptionManager.getOneTimeBadge(level: self.badgeLevel)
|
||||
try await DependenciesBridge.shared.donationSubscriptionManager.getOneTimeBadge(level: self.badgeLevel)
|
||||
}.then { profileBadge -> Promise<Value> in
|
||||
switch profileBadge {
|
||||
case .none:
|
||||
|
||||
@ -51,6 +51,8 @@ public extension Notification.Name {
|
||||
static let hasExpiredGiftBadgeDidChangeNotification = NSNotification.Name("hasExpiredGiftBadgeDidChangeNotification")
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
|
||||
/// Responsible for one-time and recurring-subscription actions related to
|
||||
/// donation payments and their resulting profile badges.
|
||||
///
|
||||
@ -63,16 +65,12 @@ public extension Notification.Name {
|
||||
/// Not to be confused with ``BackupSubscriptionManager``, which does many
|
||||
/// similar things but designed around In-App Payments (StoreKit) and paid-tier
|
||||
/// Backups.
|
||||
public enum DonationSubscriptionManager {
|
||||
|
||||
private static var receiptCredentialRedemptionJobQueue: DonationReceiptCredentialRedemptionJobQueue {
|
||||
SSKEnvironment.shared.donationReceiptCredentialRedemptionJobQueue
|
||||
}
|
||||
public class DonationSubscriptionManager {
|
||||
|
||||
/// - Note
|
||||
/// This collection name is reused by other subscription-related stores. For
|
||||
/// example, see ``DonationReceiptCredentialResultStore``.
|
||||
private static let subscriptionKVS = KeyValueStore(collection: "SubscriptionKeyValueStore")
|
||||
private let subscriptionKVS = KeyValueStore(collection: "SubscriptionKeyValueStore")
|
||||
|
||||
fileprivate static let subscriberIDKey = "subscriberID"
|
||||
fileprivate static let subscriberCurrencyCodeKey = "subscriberCurrencyCode"
|
||||
@ -88,17 +86,48 @@ public enum DonationSubscriptionManager {
|
||||
fileprivate static let showExpirySheetOnHomeScreenKey = "showExpirySheetOnHomeScreenKey"
|
||||
fileprivate static let mostRecentSubscriptionPaymentMethodKey = "mostRecentSubscriptionPaymentMethod"
|
||||
|
||||
private let db: any DB
|
||||
private let donationReceiptCredentialResultStore: DonationReceiptCredentialResultStore
|
||||
private let networkManager: NetworkManager
|
||||
private let profileManager: ProfileManager
|
||||
private let storageServiceManager: StorageServiceManager
|
||||
private let subscriptionConfigManager: SubscriptionConfigManager
|
||||
private let tsAccountManager: TSAccountManager
|
||||
|
||||
/// Lazily accessed to avoid dealing with a circular dependency.
|
||||
private var receiptCredentialRedemptionJobQueue: DonationReceiptCredentialRedemptionJobQueue {
|
||||
SSKEnvironment.shared.donationReceiptCredentialRedemptionJobQueue
|
||||
}
|
||||
|
||||
init(
|
||||
db: any DB,
|
||||
donationReceiptCredentialResultStore: DonationReceiptCredentialResultStore,
|
||||
networkManager: NetworkManager,
|
||||
profileManager: ProfileManager,
|
||||
storageServiceManager: StorageServiceManager,
|
||||
subscriptionConfigManager: SubscriptionConfigManager,
|
||||
tsAccountManager: TSAccountManager,
|
||||
) {
|
||||
self.db = db
|
||||
self.donationReceiptCredentialResultStore = donationReceiptCredentialResultStore
|
||||
self.networkManager = networkManager
|
||||
self.profileManager = profileManager
|
||||
self.storageServiceManager = storageServiceManager
|
||||
self.subscriptionConfigManager = subscriptionConfigManager
|
||||
self.tsAccountManager = tsAccountManager
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
|
||||
public static func currentProfileSubscriptionBadges(tx: DBReadTransaction) -> [OWSUserProfileBadgeInfo] {
|
||||
let localProfile = SSKEnvironment.shared.profileManagerRef.localUserProfile(tx: tx)
|
||||
public func currentProfileSubscriptionBadges(tx: DBReadTransaction) -> [OWSUserProfileBadgeInfo] {
|
||||
let localProfile = profileManager.localUserProfile(tx: tx)
|
||||
return (localProfile?.badges ?? []).filter { SubscriptionBadgeIds.contains($0.badgeId) }
|
||||
}
|
||||
|
||||
/// A low-overhead, synchronous check for whether we *probably* have a
|
||||
/// current donation subscription. Callers who need to know precise details
|
||||
/// about our subscription should use ``SubscriptionFetcher``.
|
||||
public static func probablyHasCurrentSubscription(tx: DBReadTransaction) -> Bool {
|
||||
public func probablyHasCurrentSubscription(tx: DBReadTransaction) -> Bool {
|
||||
return !currentProfileSubscriptionBadges(tx: tx).isEmpty
|
||||
}
|
||||
|
||||
@ -108,27 +137,27 @@ public enum DonationSubscriptionManager {
|
||||
/// payment has been authorized.
|
||||
///
|
||||
/// - Returns: The new subscriber ID.
|
||||
public static func prepareNewSubscription(currencyCode: Currency.Code) async throws -> Data {
|
||||
public func prepareNewSubscription(currencyCode: Currency.Code) async throws -> Data {
|
||||
Logger.info("[Donations] Setting up new subscription")
|
||||
let subscriberID = try await setupNewSubscriberID()
|
||||
Logger.info("[Donations] Caching params after setting up new subscription")
|
||||
|
||||
await SSKEnvironment.shared.databaseStorageRef.awaitableWrite { transaction in
|
||||
self.setUserManuallyCancelledSubscription(false, transaction: transaction)
|
||||
self.setSubscriberID(subscriberID, transaction: transaction)
|
||||
self.setSubscriberCurrencyCode(currencyCode, transaction: transaction)
|
||||
self.setMostRecentlyExpiredBadgeID(badgeID: nil, transaction: transaction)
|
||||
self.setShowExpirySheetOnHomeScreenKey(show: false, transaction: transaction)
|
||||
await db.awaitableWrite { tx in
|
||||
self.setUserManuallyCancelledSubscription(false, tx: tx)
|
||||
self.setSubscriberID(subscriberID, tx: tx)
|
||||
self.setSubscriberCurrencyCode(currencyCode, tx: tx)
|
||||
self.setMostRecentlyExpiredBadgeID(badgeID: nil, tx: tx)
|
||||
self.setShowExpirySheetOnHomeScreenKey(show: false, tx: tx)
|
||||
}
|
||||
|
||||
SSKEnvironment.shared.storageServiceManagerRef.recordPendingLocalAccountUpdates()
|
||||
storageServiceManager.recordPendingLocalAccountUpdates()
|
||||
|
||||
return subscriberID
|
||||
}
|
||||
|
||||
/// Finalize a new subscription, after payment has been authorized with the
|
||||
/// given processor.
|
||||
public static func finalizeNewSubscription(
|
||||
public func finalizeNewSubscription(
|
||||
forSubscriberId subscriberId: Data,
|
||||
paymentType: RecurringSubscriptionPaymentType,
|
||||
subscription: DonationSubscriptionLevel,
|
||||
@ -156,10 +185,10 @@ public enum DonationSubscriptionManager {
|
||||
|
||||
Logger.info("[Donations] Selecting subscription level on service")
|
||||
|
||||
await SSKEnvironment.shared.databaseStorageRef.awaitableWrite { transaction in
|
||||
setMostRecentSubscriptionPaymentMethod(
|
||||
await db.awaitableWrite { tx in
|
||||
self.setMostRecentSubscriptionPaymentMethod(
|
||||
paymentMethod: paymentType.paymentMethod,
|
||||
transaction: transaction,
|
||||
tx: tx,
|
||||
)
|
||||
}
|
||||
|
||||
@ -167,7 +196,7 @@ public enum DonationSubscriptionManager {
|
||||
}
|
||||
|
||||
/// Update the subscription level for the given subscriber ID.
|
||||
public static func updateSubscriptionLevel(
|
||||
public func updateSubscriptionLevel(
|
||||
for subscriberID: Data,
|
||||
to subscription: DonationSubscriptionLevel,
|
||||
currencyCode: Currency.Code,
|
||||
@ -182,12 +211,7 @@ public enum DonationSubscriptionManager {
|
||||
}
|
||||
|
||||
/// Cancel a subscription for the given subscriber ID.
|
||||
public static func cancelSubscription(for subscriberID: Data) async throws {
|
||||
let databaseStorage = SSKEnvironment.shared.databaseStorageRef
|
||||
let donationReceiptCredentialResultStore = DependenciesBridge.shared.donationReceiptCredentialResultStore
|
||||
let networkManager = SSKEnvironment.shared.networkManagerRef
|
||||
let storageServiceManager = SSKEnvironment.shared.storageServiceManagerRef
|
||||
|
||||
public func cancelSubscription(for subscriberID: Data) async throws {
|
||||
Logger.info("[Donations] Cancelling subscription")
|
||||
|
||||
let request = OWSRequestFactory.deleteSubscriberID(subscriberID)
|
||||
@ -197,14 +221,14 @@ public enum DonationSubscriptionManager {
|
||||
}
|
||||
Logger.info("[Donations] Deleted remote subscription.")
|
||||
|
||||
await databaseStorage.awaitableWrite { transaction in
|
||||
self.setSubscriberID(nil, transaction: transaction)
|
||||
self.setSubscriberCurrencyCode(nil, transaction: transaction)
|
||||
self.setMostRecentSubscriptionPaymentMethod(paymentMethod: nil, transaction: transaction)
|
||||
self.setUserManuallyCancelledSubscription(true, transaction: transaction)
|
||||
await db.awaitableWrite { tx in
|
||||
self.setSubscriberID(nil, tx: tx)
|
||||
self.setSubscriberCurrencyCode(nil, tx: tx)
|
||||
self.setMostRecentSubscriptionPaymentMethod(paymentMethod: nil, tx: tx)
|
||||
self.setUserManuallyCancelledSubscription(true, tx: tx)
|
||||
|
||||
donationReceiptCredentialResultStore.clearRedemptionSuccessForAnyRecurringSubscription(tx: transaction)
|
||||
donationReceiptCredentialResultStore.clearRequestErrorForAnyRecurringSubscription(tx: transaction)
|
||||
self.donationReceiptCredentialResultStore.clearRedemptionSuccessForAnyRecurringSubscription(tx: tx)
|
||||
self.donationReceiptCredentialResultStore.clearRequestErrorForAnyRecurringSubscription(tx: tx)
|
||||
}
|
||||
|
||||
storageServiceManager.recordPendingLocalAccountUpdates()
|
||||
@ -214,13 +238,13 @@ public enum DonationSubscriptionManager {
|
||||
/// Generate and register an ID for a new subscriber.
|
||||
///
|
||||
/// - Returns the new subscriber ID.
|
||||
private static func setupNewSubscriberID() async throws -> Data {
|
||||
private func setupNewSubscriberID() async throws -> Data {
|
||||
Logger.info("[Donations] Setting up new subscriber ID")
|
||||
|
||||
let newSubscriberID = Randomness.generateRandomBytes(UInt(32))
|
||||
let request = OWSRequestFactory.setSubscriberID(newSubscriberID)
|
||||
|
||||
let response = try await SSKEnvironment.shared.networkManagerRef
|
||||
let response = try await networkManager
|
||||
.asyncRequest(request, retryPolicy: .hopefullyRecoverable)
|
||||
|
||||
let statusCode = response.responseStatusCode
|
||||
@ -231,7 +255,7 @@ public enum DonationSubscriptionManager {
|
||||
return newSubscriberID
|
||||
}
|
||||
|
||||
private static func setDefaultPaymentMethod(
|
||||
private func setDefaultPaymentMethod(
|
||||
for subscriberId: Data,
|
||||
using processor: DonationPaymentProcessor,
|
||||
paymentMethodId: String,
|
||||
@ -241,7 +265,7 @@ public enum DonationSubscriptionManager {
|
||||
processor: processor.rawValue,
|
||||
paymentMethodId: paymentMethodId,
|
||||
)
|
||||
let response = try await SSKEnvironment.shared.networkManagerRef
|
||||
let response = try await networkManager
|
||||
.asyncRequest(request, retryPolicy: .hopefullyRecoverable)
|
||||
let statusCode = response.responseStatusCode
|
||||
if statusCode != 200 {
|
||||
@ -249,7 +273,7 @@ public enum DonationSubscriptionManager {
|
||||
}
|
||||
}
|
||||
|
||||
private static func setDefaultIDEALPaymentMethod(
|
||||
private func setDefaultIDEALPaymentMethod(
|
||||
for subscriberId: Data,
|
||||
setupIntentId: String,
|
||||
) async throws {
|
||||
@ -258,7 +282,7 @@ public enum DonationSubscriptionManager {
|
||||
setupIntentId: setupIntentId,
|
||||
)
|
||||
|
||||
let response = try await SSKEnvironment.shared.networkManagerRef
|
||||
let response = try await networkManager
|
||||
.asyncRequest(request, retryPolicy: .hopefullyRecoverable)
|
||||
let statusCode = response.responseStatusCode
|
||||
if statusCode != 200 {
|
||||
@ -270,15 +294,11 @@ public enum DonationSubscriptionManager {
|
||||
///
|
||||
/// - Returns
|
||||
/// The updated subscription.
|
||||
private static func setSubscription(
|
||||
private func setSubscription(
|
||||
for subscriberID: Data,
|
||||
subscription: DonationSubscriptionLevel,
|
||||
currencyCode: Currency.Code,
|
||||
) async throws -> Subscription {
|
||||
let databaseStorage = SSKEnvironment.shared.databaseStorageRef
|
||||
let networkManager = SSKEnvironment.shared.networkManagerRef
|
||||
let storageServiceManager = SSKEnvironment.shared.storageServiceManagerRef
|
||||
|
||||
let key = Randomness.generateRandomBytes(UInt(32)).asBase64Url
|
||||
let request = OWSRequestFactory.subscriptionSetSubscriptionLevelRequest(
|
||||
subscriberID: subscriberID,
|
||||
@ -302,8 +322,8 @@ public enum DonationSubscriptionManager {
|
||||
throw OWSAssertionError("Failed to fetch valid subscription object after setSubscription")
|
||||
}
|
||||
|
||||
await databaseStorage.awaitableWrite { transaction in
|
||||
setSubscriberCurrencyCode(currencyCode, transaction: transaction)
|
||||
await db.awaitableWrite { tx in
|
||||
self.setSubscriberCurrencyCode(currencyCode, tx: tx)
|
||||
}
|
||||
|
||||
storageServiceManager.recordPendingLocalAccountUpdates()
|
||||
@ -313,7 +333,7 @@ public enum DonationSubscriptionManager {
|
||||
|
||||
// MARK: -
|
||||
|
||||
public static func requestAndRedeemReceipt(
|
||||
public func requestAndRedeemReceipt(
|
||||
subscriberId: Data,
|
||||
subscriptionLevel: UInt,
|
||||
priorSubscriptionLevel: UInt?,
|
||||
@ -321,15 +341,13 @@ public enum DonationSubscriptionManager {
|
||||
paymentMethod: DonationPaymentMethod?,
|
||||
isNewSubscription: Bool,
|
||||
) async throws {
|
||||
let db = DependenciesBridge.shared.db
|
||||
|
||||
let (
|
||||
receiptCredentialRequestContext,
|
||||
receiptCredentialRequest,
|
||||
) = ReceiptCredentialManager.generateReceiptRequest()
|
||||
|
||||
let redemptionJobRecord = await db.awaitableWrite { tx in
|
||||
return receiptCredentialRedemptionJobQueue.saveSubscriptionRedemptionJob(
|
||||
return self.receiptCredentialRedemptionJobQueue.saveSubscriptionRedemptionJob(
|
||||
paymentProcessor: paymentProcessor,
|
||||
paymentMethod: paymentMethod,
|
||||
receiptCredentialRequestContext: receiptCredentialRequestContext,
|
||||
@ -347,21 +365,19 @@ public enum DonationSubscriptionManager {
|
||||
)
|
||||
}
|
||||
|
||||
public static func requestAndRedeemReceipt(
|
||||
public func requestAndRedeemReceipt(
|
||||
boostPaymentIntentId: String,
|
||||
amount: FiatMoney,
|
||||
paymentProcessor: DonationPaymentProcessor,
|
||||
paymentMethod: DonationPaymentMethod,
|
||||
) async throws {
|
||||
let db = DependenciesBridge.shared.db
|
||||
|
||||
let (
|
||||
receiptCredentialRequestContext,
|
||||
receiptCredentialRequest,
|
||||
) = ReceiptCredentialManager.generateReceiptRequest()
|
||||
|
||||
let redemptionJobRecord = await db.awaitableWrite { tx in
|
||||
return receiptCredentialRedemptionJobQueue.saveBoostRedemptionJob(
|
||||
return self.receiptCredentialRedemptionJobQueue.saveBoostRedemptionJob(
|
||||
amount: amount,
|
||||
paymentProcessor: paymentProcessor,
|
||||
paymentMethod: paymentMethod,
|
||||
@ -377,7 +393,7 @@ public enum DonationSubscriptionManager {
|
||||
)
|
||||
}
|
||||
|
||||
public static func redeemReceiptCredentialPresentation(
|
||||
public func redeemReceiptCredentialPresentation(
|
||||
receiptCredentialPresentation: ReceiptCredentialPresentation,
|
||||
) async throws {
|
||||
let expiresAtForLogging: String = {
|
||||
@ -386,36 +402,35 @@ public enum DonationSubscriptionManager {
|
||||
}()
|
||||
Logger.info("[Donations] Redeeming receipt credential presentation. Expires at \(expiresAtForLogging)")
|
||||
|
||||
let databaseStorage = SSKEnvironment.shared.databaseStorageRef
|
||||
let receiptCredentialPresentationData = receiptCredentialPresentation.serialize()
|
||||
let request = OWSRequestFactory.subscriptionRedeemReceiptCredential(
|
||||
receiptCredentialPresentation: receiptCredentialPresentationData,
|
||||
displayBadgesOnProfile: databaseStorage.read(block: displayBadgesOnProfile(transaction:)),
|
||||
displayBadgesOnProfile: db.read { tx in displayBadgesOnProfile(tx: tx) },
|
||||
)
|
||||
let response = try await SSKEnvironment.shared.networkManagerRef.asyncRequest(request)
|
||||
let response = try await networkManager.asyncRequest(request)
|
||||
let statusCode = response.responseStatusCode
|
||||
if statusCode != 200 {
|
||||
throw OWSAssertionError("[Donations] Receipt credential presentation request failed with status code \(statusCode)")
|
||||
}
|
||||
_ = try await SSKEnvironment.shared.profileManagerImplRef.fetchLocalUsersProfile(authedAccount: .implicit())
|
||||
_ = try await profileManager.fetchLocalUsersProfile(authedAccount: .implicit())
|
||||
}
|
||||
|
||||
// MARK: Heartbeat
|
||||
|
||||
public static func redeemSubscriptionIfNecessary() async throws {
|
||||
public func redeemSubscriptionIfNecessary() async throws {
|
||||
struct CheckerStore: SubscriptionRedemptionNecessityCheckerStore {
|
||||
let donationSubscriptionManager: DonationSubscriptionManager.Type
|
||||
let donationSubscriptionManager: DonationSubscriptionManager
|
||||
|
||||
func subscriberId(tx: DBReadTransaction) -> Data? {
|
||||
return donationSubscriptionManager.getSubscriberID(transaction: tx)
|
||||
return donationSubscriptionManager.getSubscriberID(tx: tx)
|
||||
}
|
||||
|
||||
func getLastRedemptionNecessaryCheck(tx: DBReadTransaction) -> Date? {
|
||||
return donationSubscriptionManager.subscriptionKVS.getDate(donationSubscriptionManager.lastSubscriptionHeartbeatKey, transaction: tx)
|
||||
return donationSubscriptionManager.subscriptionKVS.getDate(DonationSubscriptionManager.lastSubscriptionHeartbeatKey, transaction: tx)
|
||||
}
|
||||
|
||||
func setLastRedemptionNecessaryCheck(_ now: Date, tx: DBWriteTransaction) {
|
||||
donationSubscriptionManager.subscriptionKVS.setDate(now, key: donationSubscriptionManager.lastSubscriptionHeartbeatKey, transaction: tx)
|
||||
donationSubscriptionManager.subscriptionKVS.setDate(now, key: DonationSubscriptionManager.lastSubscriptionHeartbeatKey, transaction: tx)
|
||||
}
|
||||
}
|
||||
|
||||
@ -426,16 +441,16 @@ public enum DonationSubscriptionManager {
|
||||
>(
|
||||
checkerStore: CheckerStore(donationSubscriptionManager: self),
|
||||
dateProvider: { Date() },
|
||||
db: DependenciesBridge.shared.db,
|
||||
db: db,
|
||||
logger: logger,
|
||||
networkManager: SSKEnvironment.shared.networkManagerRef,
|
||||
tsAccountManager: DependenciesBridge.shared.tsAccountManager,
|
||||
networkManager: networkManager,
|
||||
tsAccountManager: tsAccountManager,
|
||||
)
|
||||
|
||||
_ = try await subscriptionRedemptionNecessityChecker.redeemSubscriptionIfNecessary(
|
||||
fetchSubscriptionBlock: { db, subscriptionFetcher -> (subscriberID: Data, subscription: Subscription)? in
|
||||
if
|
||||
let subscriberID = db.read(block: { getSubscriberID(transaction: $0) }),
|
||||
let subscriberID = db.read(block: { self.getSubscriberID(tx: $0) }),
|
||||
let subscription = try await subscriptionFetcher.fetch(subscriberID: subscriberID)
|
||||
{
|
||||
return (subscriberID, subscription)
|
||||
@ -460,7 +475,7 @@ public enum DonationSubscriptionManager {
|
||||
},
|
||||
saveRedemptionJobBlock: { subscriberId, subscription, tx -> DonationReceiptCredentialRedemptionJobRecord? in
|
||||
if
|
||||
receiptCredentialRedemptionJobQueue.subscriptionJobExists(
|
||||
self.receiptCredentialRedemptionJobQueue.subscriptionJobExists(
|
||||
subscriberID: subscriberId,
|
||||
tx: tx,
|
||||
)
|
||||
@ -493,7 +508,7 @@ public enum DonationSubscriptionManager {
|
||||
receiptCredentialRequest,
|
||||
) = ReceiptCredentialManager.generateReceiptRequest()
|
||||
|
||||
return receiptCredentialRedemptionJobQueue.saveSubscriptionRedemptionJob(
|
||||
return self.receiptCredentialRedemptionJobQueue.saveSubscriptionRedemptionJob(
|
||||
paymentProcessor: donationPaymentProcessor,
|
||||
paymentMethod: subscription.donationPaymentMethod,
|
||||
receiptCredentialRequestContext: receiptCredentialRequestContext,
|
||||
@ -506,22 +521,19 @@ public enum DonationSubscriptionManager {
|
||||
)
|
||||
},
|
||||
startRedemptionJobBlock: { jobRecord async throws in
|
||||
try await receiptCredentialRedemptionJobQueue.runRedemptionJob(jobRecord: jobRecord)
|
||||
try await self.receiptCredentialRedemptionJobQueue.runRedemptionJob(jobRecord: jobRecord)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - State management
|
||||
// MARK: - State management
|
||||
|
||||
extension DonationSubscriptionManager {
|
||||
|
||||
public static func getSubscriberID(transaction: DBReadTransaction) -> Data? {
|
||||
public func getSubscriberID(tx: DBReadTransaction) -> Data? {
|
||||
guard
|
||||
let subscriberID = subscriptionKVS.getObject(
|
||||
subscriberIDKey,
|
||||
Self.subscriberIDKey,
|
||||
ofClass: NSData.self,
|
||||
transaction: transaction,
|
||||
transaction: tx,
|
||||
) as Data?
|
||||
else {
|
||||
return nil
|
||||
@ -529,19 +541,19 @@ extension DonationSubscriptionManager {
|
||||
return subscriberID
|
||||
}
|
||||
|
||||
public static func setSubscriberID(_ subscriberID: Data?, transaction: DBWriteTransaction) {
|
||||
public func setSubscriberID(_ subscriberID: Data?, tx: DBWriteTransaction) {
|
||||
subscriptionKVS.setObject(
|
||||
subscriberID as NSData?,
|
||||
key: subscriberIDKey,
|
||||
transaction: transaction,
|
||||
key: Self.subscriberIDKey,
|
||||
transaction: tx,
|
||||
)
|
||||
}
|
||||
|
||||
public static func getSubscriberCurrencyCode(transaction: DBReadTransaction) -> String? {
|
||||
public func getSubscriberCurrencyCode(tx: DBReadTransaction) -> String? {
|
||||
guard
|
||||
let subscriberCurrencyCode = subscriptionKVS.getString(
|
||||
subscriberCurrencyCodeKey,
|
||||
transaction: transaction,
|
||||
Self.subscriberCurrencyCodeKey,
|
||||
transaction: tx,
|
||||
)
|
||||
else {
|
||||
return nil
|
||||
@ -549,127 +561,127 @@ extension DonationSubscriptionManager {
|
||||
return subscriberCurrencyCode
|
||||
}
|
||||
|
||||
public static func setSubscriberCurrencyCode(
|
||||
public func setSubscriberCurrencyCode(
|
||||
_ currencyCode: Currency.Code?,
|
||||
transaction: DBWriteTransaction,
|
||||
tx: DBWriteTransaction,
|
||||
) {
|
||||
subscriptionKVS.setString(
|
||||
currencyCode,
|
||||
key: subscriberCurrencyCodeKey,
|
||||
transaction: transaction,
|
||||
key: Self.subscriberCurrencyCodeKey,
|
||||
transaction: tx,
|
||||
)
|
||||
}
|
||||
|
||||
public static func userManuallyCancelledSubscription(transaction: DBReadTransaction) -> Bool {
|
||||
return subscriptionKVS.getBool(userManuallyCancelledSubscriptionKey, transaction: transaction) ?? false
|
||||
public func userManuallyCancelledSubscription(tx: DBReadTransaction) -> Bool {
|
||||
return subscriptionKVS.getBool(Self.userManuallyCancelledSubscriptionKey, transaction: tx) ?? false
|
||||
}
|
||||
|
||||
public static func setUserManuallyCancelledSubscription(_ value: Bool, updateStorageService: Bool = false, transaction: DBWriteTransaction) {
|
||||
guard value != userManuallyCancelledSubscription(transaction: transaction) else { return }
|
||||
subscriptionKVS.setBool(value, key: userManuallyCancelledSubscriptionKey, transaction: transaction)
|
||||
public func setUserManuallyCancelledSubscription(_ value: Bool, updateStorageService: Bool = false, tx: DBWriteTransaction) {
|
||||
guard value != userManuallyCancelledSubscription(tx: tx) else { return }
|
||||
subscriptionKVS.setBool(value, key: Self.userManuallyCancelledSubscriptionKey, transaction: tx)
|
||||
if updateStorageService {
|
||||
SSKEnvironment.shared.storageServiceManagerRef.recordPendingLocalAccountUpdates()
|
||||
storageServiceManager.recordPendingLocalAccountUpdates()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
|
||||
public static func displayBadgesOnProfile(transaction: DBReadTransaction) -> Bool {
|
||||
return subscriptionKVS.getBool(displayBadgesOnProfileKey, transaction: transaction) ?? false
|
||||
public func displayBadgesOnProfile(tx: DBReadTransaction) -> Bool {
|
||||
return subscriptionKVS.getBool(Self.displayBadgesOnProfileKey, transaction: tx) ?? false
|
||||
}
|
||||
|
||||
public static func setDisplayBadgesOnProfile(_ value: Bool, updateStorageService: Bool = false, transaction: DBWriteTransaction) {
|
||||
guard value != displayBadgesOnProfile(transaction: transaction) else { return }
|
||||
subscriptionKVS.setBool(value, key: displayBadgesOnProfileKey, transaction: transaction)
|
||||
public func setDisplayBadgesOnProfile(_ value: Bool, updateStorageService: Bool = false, tx: DBWriteTransaction) {
|
||||
guard value != displayBadgesOnProfile(tx: tx) else { return }
|
||||
subscriptionKVS.setBool(value, key: Self.displayBadgesOnProfileKey, transaction: tx)
|
||||
if updateStorageService {
|
||||
SSKEnvironment.shared.storageServiceManagerRef.recordPendingLocalAccountUpdates()
|
||||
storageServiceManager.recordPendingLocalAccountUpdates()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
|
||||
fileprivate static func setKnownUserSubscriptionBadgeIDs(badgeIDs: [String], transaction: DBWriteTransaction) {
|
||||
subscriptionKVS.setStringArray(badgeIDs, key: knownUserSubscriptionBadgeIDsKey, transaction: transaction)
|
||||
private func setKnownUserSubscriptionBadgeIDs(badgeIDs: [String], tx: DBWriteTransaction) {
|
||||
subscriptionKVS.setStringArray(badgeIDs, key: Self.knownUserSubscriptionBadgeIDsKey, transaction: tx)
|
||||
}
|
||||
|
||||
fileprivate static func knownUserSubscriptionBadgeIDs(transaction: DBReadTransaction) -> [String] {
|
||||
return subscriptionKVS.getStringArray(knownUserSubscriptionBadgeIDsKey, transaction: transaction) ?? []
|
||||
private func knownUserSubscriptionBadgeIDs(tx: DBReadTransaction) -> [String] {
|
||||
return subscriptionKVS.getStringArray(Self.knownUserSubscriptionBadgeIDsKey, transaction: tx) ?? []
|
||||
}
|
||||
|
||||
fileprivate static func setKnownUserBoostBadgeIDs(badgeIDs: [String], transaction: DBWriteTransaction) {
|
||||
subscriptionKVS.setStringArray(badgeIDs, key: knownUserBoostBadgeIDsKey, transaction: transaction)
|
||||
private func setKnownUserBoostBadgeIDs(badgeIDs: [String], tx: DBWriteTransaction) {
|
||||
subscriptionKVS.setStringArray(badgeIDs, key: Self.knownUserBoostBadgeIDsKey, transaction: tx)
|
||||
}
|
||||
|
||||
fileprivate static func knownUserBoostBadgeIDs(transaction: DBReadTransaction) -> [String] {
|
||||
return subscriptionKVS.getStringArray(knownUserBoostBadgeIDsKey, transaction: transaction) ?? []
|
||||
private func knownUserBoostBadgeIDs(tx: DBReadTransaction) -> [String] {
|
||||
return subscriptionKVS.getStringArray(Self.knownUserBoostBadgeIDsKey, transaction: tx) ?? []
|
||||
}
|
||||
|
||||
fileprivate static func setKnownUserGiftBadgeIDs(badgeIDs: [String], transaction: DBWriteTransaction) {
|
||||
subscriptionKVS.setStringArray(badgeIDs, key: knownUserGiftBadgeIDsKey, transaction: transaction)
|
||||
private func setKnownUserGiftBadgeIDs(badgeIDs: [String], tx: DBWriteTransaction) {
|
||||
subscriptionKVS.setStringArray(badgeIDs, key: Self.knownUserGiftBadgeIDsKey, transaction: tx)
|
||||
}
|
||||
|
||||
fileprivate static func knownUserGiftBadgeIDs(transaction: DBReadTransaction) -> [String] {
|
||||
return subscriptionKVS.getStringArray(knownUserGiftBadgeIDsKey, transaction: transaction) ?? []
|
||||
private func knownUserGiftBadgeIDs(tx: DBReadTransaction) -> [String] {
|
||||
return subscriptionKVS.getStringArray(Self.knownUserGiftBadgeIDsKey, transaction: tx) ?? []
|
||||
}
|
||||
|
||||
fileprivate static func setMostRecentlyExpiredBadgeID(badgeID: String?, transaction: DBWriteTransaction) {
|
||||
private func setMostRecentlyExpiredBadgeID(badgeID: String?, tx: DBWriteTransaction) {
|
||||
guard let badgeID else {
|
||||
subscriptionKVS.removeValue(forKey: mostRecentlyExpiredBadgeIDKey, transaction: transaction)
|
||||
subscriptionKVS.removeValue(forKey: Self.mostRecentlyExpiredBadgeIDKey, transaction: tx)
|
||||
return
|
||||
}
|
||||
|
||||
subscriptionKVS.setString(badgeID, key: mostRecentlyExpiredBadgeIDKey, transaction: transaction)
|
||||
subscriptionKVS.setString(badgeID, key: Self.mostRecentlyExpiredBadgeIDKey, transaction: tx)
|
||||
|
||||
}
|
||||
|
||||
public static func mostRecentlyExpiredBadgeID(transaction: DBReadTransaction) -> String? {
|
||||
subscriptionKVS.getString(mostRecentlyExpiredBadgeIDKey, transaction: transaction)
|
||||
public func mostRecentlyExpiredBadgeID(tx: DBReadTransaction) -> String? {
|
||||
subscriptionKVS.getString(Self.mostRecentlyExpiredBadgeIDKey, transaction: tx)
|
||||
}
|
||||
|
||||
public static func clearMostRecentlyExpiredBadgeIDWithSneakyTransaction() {
|
||||
SSKEnvironment.shared.databaseStorageRef.write { transaction in
|
||||
self.setMostRecentlyExpiredBadgeID(badgeID: nil, transaction: transaction)
|
||||
public func clearMostRecentlyExpiredBadgeIDWithSneakyTransaction() {
|
||||
db.write { tx in
|
||||
self.setMostRecentlyExpiredBadgeID(badgeID: nil, tx: tx)
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate static func setMostRecentlyExpiredGiftBadgeID(badgeID: String?, transaction: DBWriteTransaction) {
|
||||
private func setMostRecentlyExpiredGiftBadgeID(badgeID: String?, tx: DBWriteTransaction) {
|
||||
if let badgeID {
|
||||
subscriptionKVS.setString(badgeID, key: mostRecentlyExpiredGiftBadgeIDKey, transaction: transaction)
|
||||
subscriptionKVS.setString(badgeID, key: Self.mostRecentlyExpiredGiftBadgeIDKey, transaction: tx)
|
||||
} else {
|
||||
subscriptionKVS.removeValue(forKey: mostRecentlyExpiredGiftBadgeIDKey, transaction: transaction)
|
||||
subscriptionKVS.removeValue(forKey: Self.mostRecentlyExpiredGiftBadgeIDKey, transaction: tx)
|
||||
}
|
||||
transaction.addSyncCompletion {
|
||||
tx.addSyncCompletion {
|
||||
NotificationCenter.default.postOnMainThread(name: .hasExpiredGiftBadgeDidChangeNotification, object: nil)
|
||||
}
|
||||
}
|
||||
|
||||
public static func mostRecentlyExpiredGiftBadgeID(transaction: DBReadTransaction) -> String? {
|
||||
subscriptionKVS.getString(mostRecentlyExpiredGiftBadgeIDKey, transaction: transaction)
|
||||
public func mostRecentlyExpiredGiftBadgeID(tx: DBReadTransaction) -> String? {
|
||||
subscriptionKVS.getString(Self.mostRecentlyExpiredGiftBadgeIDKey, transaction: tx)
|
||||
}
|
||||
|
||||
public static func clearMostRecentlyExpiredGiftBadgeIDWithSneakyTransaction() {
|
||||
SSKEnvironment.shared.databaseStorageRef.write { transaction in
|
||||
self.setMostRecentlyExpiredGiftBadgeID(badgeID: nil, transaction: transaction)
|
||||
public func clearMostRecentlyExpiredGiftBadgeIDWithSneakyTransaction() {
|
||||
db.write { tx in
|
||||
self.setMostRecentlyExpiredGiftBadgeID(badgeID: nil, tx: tx)
|
||||
}
|
||||
}
|
||||
|
||||
public static func setShowExpirySheetOnHomeScreenKey(show: Bool, transaction: DBWriteTransaction) {
|
||||
subscriptionKVS.setBool(show, key: showExpirySheetOnHomeScreenKey, transaction: transaction)
|
||||
public func setShowExpirySheetOnHomeScreenKey(show: Bool, tx: DBWriteTransaction) {
|
||||
subscriptionKVS.setBool(show, key: Self.showExpirySheetOnHomeScreenKey, transaction: tx)
|
||||
}
|
||||
|
||||
public static func showExpirySheetOnHomeScreenKey(transaction: DBReadTransaction) -> Bool {
|
||||
return subscriptionKVS.getBool(showExpirySheetOnHomeScreenKey, transaction: transaction) ?? false
|
||||
public func showExpirySheetOnHomeScreenKey(tx: DBReadTransaction) -> Bool {
|
||||
return subscriptionKVS.getBool(Self.showExpirySheetOnHomeScreenKey, transaction: tx) ?? false
|
||||
}
|
||||
|
||||
public static func setMostRecentSubscriptionPaymentMethod(
|
||||
public func setMostRecentSubscriptionPaymentMethod(
|
||||
paymentMethod: DonationPaymentMethod?,
|
||||
transaction: DBWriteTransaction,
|
||||
tx: DBWriteTransaction,
|
||||
) {
|
||||
subscriptionKVS.setString(paymentMethod?.rawValue, key: mostRecentSubscriptionPaymentMethodKey, transaction: transaction)
|
||||
subscriptionKVS.setString(paymentMethod?.rawValue, key: Self.mostRecentSubscriptionPaymentMethodKey, transaction: tx)
|
||||
}
|
||||
|
||||
public static func getMostRecentSubscriptionPaymentMethod(transaction: DBReadTransaction) -> DonationPaymentMethod? {
|
||||
guard let paymentMethodString = subscriptionKVS.getString(mostRecentSubscriptionPaymentMethodKey, transaction: transaction) else {
|
||||
public func getMostRecentSubscriptionPaymentMethod(tx: DBReadTransaction) -> DonationPaymentMethod? {
|
||||
guard let paymentMethodString = subscriptionKVS.getString(Self.mostRecentSubscriptionPaymentMethodKey, transaction: tx) else {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -680,16 +692,13 @@ extension DonationSubscriptionManager {
|
||||
|
||||
return paymentMethod
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
|
||||
extension DonationSubscriptionManager {
|
||||
// MARK: -
|
||||
|
||||
private static let cachedBadges = AtomicValue<[OneTimeBadgeLevel: CachedBadge]>([:], lock: .init())
|
||||
|
||||
public static func getCachedBadge(level: OneTimeBadgeLevel) -> CachedBadge {
|
||||
return self.cachedBadges.update {
|
||||
public func getCachedBadge(level: OneTimeBadgeLevel) -> CachedBadge {
|
||||
return Self.cachedBadges.update {
|
||||
if let cachedBadge = $0[level] {
|
||||
return cachedBadge
|
||||
}
|
||||
@ -699,7 +708,7 @@ extension DonationSubscriptionManager {
|
||||
}
|
||||
}
|
||||
|
||||
public static func getBoostBadge() async throws -> ProfileBadge {
|
||||
public func getBoostBadge() async throws -> ProfileBadge {
|
||||
let profileBadge = try await getOneTimeBadge(level: .boostBadge)
|
||||
guard let profileBadge else {
|
||||
owsFail("No badge for this level was found")
|
||||
@ -707,7 +716,7 @@ extension DonationSubscriptionManager {
|
||||
return profileBadge
|
||||
}
|
||||
|
||||
public static func getOneTimeBadge(level: OneTimeBadgeLevel) async throws -> ProfileBadge? {
|
||||
public func getOneTimeBadge(level: OneTimeBadgeLevel) async throws -> ProfileBadge? {
|
||||
let donationConfiguration = try await fetchDonationConfiguration()
|
||||
switch level {
|
||||
case .boostBadge:
|
||||
@ -722,7 +731,7 @@ extension DonationSubscriptionManager {
|
||||
}
|
||||
}
|
||||
|
||||
public static func getSubscriptionBadge(subscriptionLevel levelRawValue: UInt) async throws -> ProfileBadge {
|
||||
public func getSubscriptionBadge(subscriptionLevel levelRawValue: UInt) async throws -> ProfileBadge {
|
||||
let donationConfiguration = try await fetchDonationConfiguration()
|
||||
guard
|
||||
let matchingLevel = donationConfiguration.subscription.levels.first(where: {
|
||||
@ -735,18 +744,15 @@ extension DonationSubscriptionManager {
|
||||
return matchingLevel.badge
|
||||
}
|
||||
|
||||
public static func fetchDonationConfiguration() async throws -> DonationSubscriptionConfiguration {
|
||||
let subscriptionConfigManager = DependenciesBridge.shared.subscriptionConfigManager
|
||||
public func fetchDonationConfiguration() async throws -> DonationSubscriptionConfiguration {
|
||||
return try await subscriptionConfigManager.donationConfiguration()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
// MARK: -
|
||||
|
||||
extension DonationSubscriptionManager {
|
||||
public static func reconcileBadgeStates(
|
||||
public func reconcileBadgeStates(
|
||||
currentLocalUserProfile: OWSUserProfile,
|
||||
transaction: DBWriteTransaction,
|
||||
tx: DBWriteTransaction,
|
||||
) {
|
||||
let currentBadges = currentLocalUserProfile.badges
|
||||
|
||||
@ -766,14 +772,14 @@ extension DonationSubscriptionManager {
|
||||
}
|
||||
|
||||
// Read existing values
|
||||
let persistedSubscriberBadgeIDs = Self.knownUserSubscriptionBadgeIDs(transaction: transaction)
|
||||
let persistedBoostBadgeIDs = Self.knownUserBoostBadgeIDs(transaction: transaction)
|
||||
let persistedGiftBadgeIDs = Self.knownUserGiftBadgeIDs(transaction: transaction)
|
||||
let oldExpiredGiftBadgeID = Self.mostRecentlyExpiredGiftBadgeID(transaction: transaction)
|
||||
var expiringBadgeId = Self.mostRecentlyExpiredBadgeID(transaction: transaction)
|
||||
var userManuallyCancelled = Self.userManuallyCancelledSubscription(transaction: transaction)
|
||||
var showExpiryOnHomeScreen = Self.showExpirySheetOnHomeScreenKey(transaction: transaction)
|
||||
var displayBadgesOnProfile = Self.displayBadgesOnProfile(transaction: transaction)
|
||||
let persistedSubscriberBadgeIDs = self.knownUserSubscriptionBadgeIDs(tx: tx)
|
||||
let persistedBoostBadgeIDs = self.knownUserBoostBadgeIDs(tx: tx)
|
||||
let persistedGiftBadgeIDs = self.knownUserGiftBadgeIDs(tx: tx)
|
||||
let oldExpiredGiftBadgeID = self.mostRecentlyExpiredGiftBadgeID(tx: tx)
|
||||
var expiringBadgeId = self.mostRecentlyExpiredBadgeID(tx: tx)
|
||||
var userManuallyCancelled = self.userManuallyCancelledSubscription(tx: tx)
|
||||
var showExpiryOnHomeScreen = self.showExpirySheetOnHomeScreenKey(tx: tx)
|
||||
var displayBadgesOnProfile = self.displayBadgesOnProfile(tx: tx)
|
||||
|
||||
let isCurrentlyDisplayingBadgesOnProfile = currentBadges.allSatisfy { badge in
|
||||
badge.isVisible ?? {
|
||||
@ -881,20 +887,17 @@ extension DonationSubscriptionManager {
|
||||
""")
|
||||
|
||||
// Persist new values
|
||||
Self.setKnownUserSubscriptionBadgeIDs(badgeIDs: currentSubscriberBadgeIDs, transaction: transaction)
|
||||
Self.setKnownUserBoostBadgeIDs(badgeIDs: currentBoostBadgeIDs, transaction: transaction)
|
||||
Self.setKnownUserGiftBadgeIDs(badgeIDs: currentGiftBadgeIDs, transaction: transaction)
|
||||
Self.setMostRecentlyExpiredGiftBadgeID(badgeID: newExpiredGiftBadgeID, transaction: transaction)
|
||||
Self.setMostRecentlyExpiredBadgeID(badgeID: expiringBadgeId, transaction: transaction)
|
||||
Self.setShowExpirySheetOnHomeScreenKey(show: showExpiryOnHomeScreen, transaction: transaction)
|
||||
Self.setUserManuallyCancelledSubscription(userManuallyCancelled, transaction: transaction)
|
||||
Self.setDisplayBadgesOnProfile(displayBadgesOnProfile, transaction: transaction)
|
||||
self.setKnownUserSubscriptionBadgeIDs(badgeIDs: currentSubscriberBadgeIDs, tx: tx)
|
||||
self.setKnownUserBoostBadgeIDs(badgeIDs: currentBoostBadgeIDs, tx: tx)
|
||||
self.setKnownUserGiftBadgeIDs(badgeIDs: currentGiftBadgeIDs, tx: tx)
|
||||
self.setMostRecentlyExpiredGiftBadgeID(badgeID: newExpiredGiftBadgeID, tx: tx)
|
||||
self.setMostRecentlyExpiredBadgeID(badgeID: expiringBadgeId, tx: tx)
|
||||
self.setShowExpirySheetOnHomeScreenKey(show: showExpiryOnHomeScreen, tx: tx)
|
||||
self.setUserManuallyCancelledSubscription(userManuallyCancelled, tx: tx)
|
||||
self.setDisplayBadgesOnProfile(displayBadgesOnProfile, tx: tx)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
|
||||
extension DonationSubscriptionManager {
|
||||
// MARK: -
|
||||
|
||||
public enum RecurringSubscriptionPaymentType {
|
||||
case applePay(paymentMethodId: String)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user