Skip to content

Commit

Permalink
subscription page fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
phillipthelen committed Oct 23, 2024
1 parent 40aa0d1 commit 52cdb8e
Show file tree
Hide file tree
Showing 13 changed files with 135 additions and 60 deletions.
6 changes: 5 additions & 1 deletion HabitRPG/Generated/Strings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -738,6 +738,10 @@ public enum L10n {
public static func nextCheckinPrizeXDays(_ p1: Int) -> String {
return L10n.tr("Mainstrings", "next_checkin_prize_x_days", p1)
}
/// Next Payment %@
public static func nextPaymentX(_ p1: String) -> String {
return L10n.tr("Mainstrings", "next_payment_x", p1)
}
/// Next prize at %d Check-Ins
public static func nextPrizeAtXCheckins(_ p1: Int) -> String {
return L10n.tr("Mainstrings", "next_prize_at_x_checkins", p1)
Expand Down Expand Up @@ -1086,7 +1090,7 @@ public enum L10n {
public static var subscriptionBenefitsTitle: String { return L10n.tr("Mainstrings", "subscription_benefits_title") }
/// You get these benefits for being a Subscriber
public static var subscriptionBenefitsTitleSubscribed: String { return L10n.tr("Mainstrings", "subscription_benefits_title_subscribed") }
/// Your %d months of subscription credit will activate after canceling
/// Your **%d months** of subscription credit will activate after canceling
public static func subscriptionCreditTitle(_ p1: Int) -> String {
return L10n.tr("Mainstrings", "subscription_credit_title", p1)
}
Expand Down
6 changes: 3 additions & 3 deletions HabitRPG/Repositories/Implementations/UserRepository.swift
Original file line number Diff line number Diff line change
Expand Up @@ -440,12 +440,12 @@ class UserRepository: BaseRepository<UserLocalRepository> {
return PurchaseNoRenewSubscriptionCall(identifier: identifier, receipt: receipt, recipient: recipient).objectSignal
}

private var lastSubscriptionCall: Date?
private static var lastSubscriptionCall: Date?
func subscribe(sku: String, receipt: String) -> Signal<UserProtocol?, Never> {
if let lastCall = lastSubscriptionCall, lastCall.timeIntervalSinceNow > -15 {
if let lastCall = UserRepository.lastSubscriptionCall, lastCall.timeIntervalSinceNow > -15 {
return Signal.empty
}
lastSubscriptionCall = Date()
UserRepository.lastSubscriptionCall = Date()
return SubscribeCall(sku: sku, receipt: receipt).objectSignal.flatMap(.latest) {[weak self] _ in
return self?.retrieveUser(withTasks: false, forced: true) ?? Signal.empty
}
Expand Down
3 changes: 2 additions & 1 deletion HabitRPG/Strings/Base.lproj/Mainstrings.strings
Original file line number Diff line number Diff line change
Expand Up @@ -753,6 +753,7 @@
"randomize" = "Randomize";
"finish" = "Finish";
"next" = "Next";
"next_payment_x" = "Next Payment %@";
"mana_points" = "Mana Points";
"character_level" = "Character Level";
"gold" = "Gold";
Expand Down Expand Up @@ -978,7 +979,7 @@
"subscription_duration" = "Recurring every %@";
"resubscribe" = "Resubscribe";
"renew_subscription" = "Renew Subscription";
"ending_on" = "Ending on %@";
"ending_on" = "Benefits end %@";
"not_recurring" = "Not Recurring";
"cancelled" = "Cancelled";
"cancel_subscription" = "Cancel subscription";
Expand Down
13 changes: 11 additions & 2 deletions HabitRPG/TableViewDataSources/ShopCollectionViewDataSource.swift
Original file line number Diff line number Diff line change
Expand Up @@ -69,19 +69,28 @@ class ShopCollectionViewDataSource: BaseReactiveCollectionViewDataSource<InAppRe
sections.append(ItemSection<InAppRewardProtocol>())
sections[0].showIfEmpty = needsGearSection

disposable.add(inventoryRepository.getShop(identifier: identifier).combineLatest(with: userRepository.getUser()).on(value: {[weak self] (shop, user) in
disposable.add(inventoryRepository.getShop(identifier: identifier).on(value: {[weak self] shop in
let sectionCount = self?.sections.count ?? 0
if sectionCount >= 2 {
self?.sections.removeLast(sectionCount - 1)
}
self?.loadCategories(shop?.categories ?? [])
self?.delegate?.updateShopHeader(shop: shop)

}).start())

disposable.add(userRepository.getUser().on(value: {[weak self] user in
var shouldReload = false
if self?.user?.isSubscribed != user.isSubscribed {
shouldReload = true
}
self?.user = user
if self?.selectedGearCategory == nil {
self?.selectedGearCategory = self?.userClass
}
self?.delegate?.updateNavBar(gold: Int(user.stats?.gold ?? 0), gems: user.gemCount, hourglasses: user.purchased?.subscriptionPlan?.consecutive?.hourglasses ?? 0)
if shouldReload {
self?.collectionView?.reloadData()
}
}).start())

disposable.add(userRepository.getInAppRewards()
Expand Down
14 changes: 6 additions & 8 deletions HabitRPG/UI/Inventory/ShopViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -86,14 +86,12 @@ class ShopViewController: BaseCollectionViewController, ShopCollectionViewDataSo
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)

if isSubscribed == nil {
userRepository.getUser().take(first: 1).on(value: { user in
self.isSubscribed = user.isSubscribed
if self.shopIdentifier == "timeTravelersShop" && !user.isSubscribed && user.purchased?.subscriptionPlan?.consecutive?.hourglasses == 0 {
SubscriptionModalViewController(presentationPoint: .timetravelers).show()
}
}).start()
}
userRepository.getUser().on(value: {[weak self] user in
if self?.isSubscribed == nil && self?.shopIdentifier == "timeTravelersShop" && !user.isSubscribed && user.purchased?.subscriptionPlan?.consecutive?.hourglasses == 0 {
SubscriptionModalViewController(presentationPoint: .timetravelers).show()
}
self?.isSubscribed = user.isSubscribed
}).start()

if let sectionKey = openToSection {
let section = dataSource?.sections.firstIndex(where: { section in
Expand Down
4 changes: 2 additions & 2 deletions HabitRPG/UI/Purchases/GiftSubscriptionViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ struct GiftSubscriptionPage: View {
.padding(.horizontal, 24)
.padding(.top, 16)
.padding(.bottom, 32)
Image(Asset.giftSubscriptionHills.name)
Image(viewModel.isGiftOneGetOne() ? Asset.giftSubscriptionHills.name : Asset.subscriptionBackground.name)
if viewModel.isGiftOneGetOne() {
VStack(alignment: .center, spacing: 6) {
HStack {
Expand All @@ -125,7 +125,7 @@ struct GiftSubscriptionPage: View {
.background(Color.purple300.ignoresSafeArea(.all, edges: .top).padding(.bottom, 4))
}.foregroundColor(.white)
.ignoresSafeArea(.all, edges: .bottom)
.background((viewModel.isGiftOneGetOne() ? Color.purple400 : Color.blue100).ignoresSafeArea(.all, edges: .bottom).padding(.top, 200))
.background((Color.purple400).ignoresSafeArea(.all, edges: .bottom).padding(.top, 200))
}
}

Expand Down
42 changes: 25 additions & 17 deletions HabitRPG/UI/Purchases/SubscriptionDetailViewUI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,15 @@ struct SubscriptionDetailViewUI: View {
default:
break
}
if let duration = duration {
return L10n.subscriptionDuration(duration)
} else if plan.isGroupPlanSub {
return L10n.memberGroupPlan
} else if let terminated = plan.dateTerminated {
if let terminated = plan.dateTerminated {
let formatter = DateFormatter()
formatter.dateStyle = .medium
formatter.timeStyle = .none
return L10n.endingOn(formatter.string(from: terminated))
} else if let duration = duration {
return L10n.subscriptionDuration(duration)
} else if plan.isGroupPlanSub {
return L10n.memberGroupPlan
} else {
return ""
}
Expand All @@ -82,6 +82,11 @@ struct SubscriptionDetailViewUI: View {
} else if plan.dateTerminated != nil {
return L10n.cancelled
} else if plan.paymentMethod == "Apple" {
if let nextEstimatedPayment = plan.nextEstimatedPayment {
let format = DateFormatter()
format.dateFormat = "MMM YYYY"
return L10n.nextPaymentX(format.string(from: nextEstimatedPayment))
}
return "Apple Pay"
} else if plan.paymentMethod == "Google" {
return "Google Pay"
Expand Down Expand Up @@ -183,6 +188,7 @@ struct SubscriptionDetailViewUI: View {
if plan.extraMonths > 0 {
Text(LocalizedStringKey(L10n.subscriptionCreditTitle(plan.extraMonths)))
.font(.system(size: 15))
.multilineTextAlignment(.center)
.foregroundColor(.green500)
.frame(maxWidth: .infinity)
.padding(.vertical, 11)
Expand All @@ -205,17 +211,19 @@ struct SubscriptionDetailViewUI: View {
activityPill
}
}
DetailContainer {
HStack {
VStack(alignment: .leading, spacing: 6) {
Text(L10n.Subscription.paymentMethod)
.font(.system(size: 15, weight: .semibold))
Text(paymentTypeText)
.font(.system(size: 13))
}
Spacer()
if let image = paymentImage {
Image(uiImage: image)
if !plan.isGroupPlanSub {
DetailContainer {
HStack {
VStack(alignment: .leading, spacing: 6) {
Text(L10n.Subscription.paymentMethod)
.font(.system(size: 15, weight: .semibold))
Text(paymentTypeText)
.font(.system(size: 13))
}
Spacer()
if let image = paymentImage {
Image(uiImage: image)
}
}
}
}
Expand Down Expand Up @@ -290,7 +298,7 @@ struct SubscriptionDetailViewUI: View {

func cancelSubscription() {
var url: URL?
if plan.paymentMethod == "Apple" || plan.isGifted {
if plan.paymentMethod == "Apple" || plan.isGifted || plan.dateTerminated != nil {
if #available(iOS 15.0, *) {
if let window = UIApplication.shared.connectedScenes.first as? UIWindowScene {
Task {
Expand Down
28 changes: 22 additions & 6 deletions HabitRPG/UI/Purchases/SubscriptionPage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ class SubscriptionViewModel: BaseSubscriptionViewModel {

@Published var activePromo: HabiticaPromotion?
@Published var isRestoringPurchase = false

@Published var scrollToTop: Date?

init(presentationPoint: PresentationPoint?) {
#if DEBUG
Expand All @@ -107,11 +109,14 @@ class SubscriptionViewModel: BaseSubscriptionViewModel {

super.init()


userRepository.getUser().on(value: {[weak self] user in
if (self?.scrollToTop == nil && self?.isSubscribed == false && user.isSubscribed) {
self?.scrollToTop = Date()
}
self?.isSubscribed = user.isSubscribed
self?.subscriptionPlan = user.purchased?.subscriptionPlan
self?.showHourglassPromo = user.purchased?.subscriptionPlan?.isEligableForHourglassPromo == true

}).start()

if presentationPoint != nil {
Expand Down Expand Up @@ -226,6 +231,7 @@ class SubscriptionViewModel: BaseSubscriptionViewModel {
case .success:
completion(true)
self.isSubscribed = true
self.scrollToTop = Date()
case .failure:
completion(false)
}
Expand Down Expand Up @@ -320,11 +326,11 @@ struct GiftSubscriptionSegment: View {
struct SubscriptionPage: View {
@ObservedObject var viewModel: SubscriptionViewModel

var backgroundColor: Color = Color(UIColor.purple300)
var backgroundColor: Color = .purple300
var textColor: Color = .white

var body: some View {
LazyVStack(spacing: 0) {
VStack(spacing: 0) {
if let endDate = viewModel.activePromo?.endDate, viewModel.activePromo?.identifier == "g1g1" {
G1G1Banner(endDate: endDate)
.frame(height: 96)
Expand Down Expand Up @@ -523,11 +529,21 @@ struct SubscriptionPage: View {
}

struct ScrollableSubscriptionPage: View {
let viewModel: SubscriptionViewModel
@ObservedObject var viewModel: SubscriptionViewModel

var body: some View {
ScrollView {
SubscriptionPage(viewModel: viewModel)
ScrollViewReader { reader in
ScrollView {
SubscriptionPage(viewModel: viewModel)
.id("page")
}
.onChange(of: viewModel.scrollToTop) { _ in
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: {
withAnimation {
reader.scrollTo("page", anchor: .top)
}
})
}
}
.background(Color.purple400.ignoresSafeArea(.all, edges: .bottom).padding(.top, 200))
}
Expand Down
Loading

0 comments on commit 52cdb8e

Please sign in to comment.