This commit is contained in:
Mo
2022-11-13 09:28:16 -06:00
committed by GitHub
parent e56a960bbf
commit d519aca685
49 changed files with 512 additions and 151 deletions

View File

@@ -1,4 +1,5 @@
import { WebApplication } from '@/Application/Application'
import { PremiumFeatureModalType } from '@/Components/PremiumFeaturesModal/PremiumFeatureModalType'
import { destroyAllObjectProperties } from '@/Utils'
import {
ApplicationEvent,
@@ -16,6 +17,7 @@ export class FeaturesController extends AbstractViewController {
hasSmartViews: boolean
hasFiles: boolean
premiumAlertFeatureName: string | undefined
premiumAlertType: PremiumFeatureModalType | undefined = undefined
override deinit() {
super.deinit()
@@ -25,6 +27,7 @@ export class FeaturesController extends AbstractViewController {
;(this.hasSmartViews as unknown) = undefined
;(this.hasFiles as unknown) = undefined
;(this.premiumAlertFeatureName as unknown) = undefined
;(this.premiumAlertType as unknown) = undefined
destroyAllObjectProperties(this)
}
@@ -43,10 +46,11 @@ export class FeaturesController extends AbstractViewController {
hasFolders: observable,
hasSmartViews: observable,
hasFiles: observable,
premiumAlertType: observable,
premiumAlertFeatureName: observable,
showPremiumAlert: action,
closePremiumAlert: action,
showPurchaseSuccessAlert: action,
})
this.showPremiumAlert = this.showPremiumAlert.bind(this)
@@ -55,6 +59,9 @@ export class FeaturesController extends AbstractViewController {
this.disposers.push(
application.addEventObserver(async (event) => {
switch (event) {
case ApplicationEvent.DidPurchaseSubscription:
this.showPurchaseSuccessAlert()
break
case ApplicationEvent.FeaturesUpdated:
case ApplicationEvent.Launched:
runInAction(() => {
@@ -76,11 +83,17 @@ export class FeaturesController extends AbstractViewController {
public async showPremiumAlert(featureName: string): Promise<void> {
this.premiumAlertFeatureName = featureName
return when(() => this.premiumAlertFeatureName === undefined)
this.premiumAlertType = PremiumFeatureModalType.UpgradePrompt
return when(() => this.premiumAlertType === undefined)
}
showPurchaseSuccessAlert = () => {
this.premiumAlertType = PremiumFeatureModalType.UpgradeSuccess
}
public closePremiumAlert() {
this.premiumAlertFeatureName = undefined
this.premiumAlertType = undefined
}
private isEntitledToFiles(): boolean {

View File

@@ -1,5 +1,6 @@
import { LoggingDomain, log } from '@/Logging'
import { loadPurchaseFlowUrl } from '@/Components/PurchaseFlow/PurchaseFlowFunctions'
import { InternalEventBus } from '@standardnotes/snjs'
import { InternalEventBus, AppleIAPProductId } from '@standardnotes/snjs'
import { action, makeObservable, observable } from 'mobx'
import { WebApplication } from '../../Application/Application'
import { AbstractViewController } from '../Abstract/AbstractViewController'
@@ -26,15 +27,67 @@ export class PurchaseFlowController extends AbstractViewController {
this.currentPane = currentPane
}
openPurchaseFlow = (): void => {
openPurchaseFlow = (plan = AppleIAPProductId.ProPlanYearly): void => {
const user = this.application.getUser()
if (!user) {
this.isOpen = true
return
}
if (this.application.isNativeIOS()) {
void this.beginIosIapPurchaseFlow(plan)
} else {
loadPurchaseFlowUrl(this.application).catch(console.error)
}
}
openPurchaseWebpage = () => {
loadPurchaseFlowUrl(this.application).catch((err) => {
console.error(err)
this.application.alertService.alert(err).catch(console.error)
})
}
beginIosIapPurchaseFlow = async (plan: AppleIAPProductId): Promise<void> => {
const result = await this.application.mobileDevice().purchaseSubscriptionIAP(plan)
log(LoggingDomain.Purchasing, 'BeginIosIapPurchaseFlow result', result)
if (!result) {
void this.application.alertService.alert('Your purchase was canceled or failed. Please try again.')
return
}
const showGenericError = () => {
void this.application.alertService.alert(
'There was an error confirming your purchase. Please contact support at help@standardnotes.com.',
)
}
log(LoggingDomain.Purchasing, 'Confirming result with our server')
const token = await this.application.getNewSubscriptionToken()
if (!token) {
log(LoggingDomain.Purchasing, 'Unable to generate subscription token')
showGenericError()
return
}
const confirmResult = await this.application.subscriptions.confirmAppleIAP(result, token)
log(LoggingDomain.Purchasing, 'Server confirm result', confirmResult)
if (confirmResult) {
void this.application.alerts.alert(
'Please allow a few minutes for your subscription benefits to activate. You will see a confirmation alert in the app when your subscription is ready.',
'Your purchase was successful!',
)
} else {
showGenericError()
}
}
closePurchaseFlow = (): void => {
this.isOpen = false
}

View File

@@ -21,7 +21,6 @@ export class SubscriptionController extends AbstractViewController {
userSubscription: Subscription | undefined = undefined
availableSubscriptions: AvailableSubscriptions | undefined = undefined
subscriptionInvitations: Invitation[] | undefined = undefined
hideSubscriptionMarketing: boolean
hasAccount: boolean
override deinit() {
@@ -39,14 +38,12 @@ export class SubscriptionController extends AbstractViewController {
private subscriptionManager: SubscriptionClientInterface,
) {
super(application, eventBus)
this.hideSubscriptionMarketing = application.hideSubscriptionMarketing
this.hasAccount = application.hasAccount()
makeObservable(this, {
userSubscription: observable,
availableSubscriptions: observable,
subscriptionInvitations: observable,
hideSubscriptionMarketing: observable,
hasAccount: observable,
userSubscriptionName: computed,