refactor: native feature management (#2350)

This commit is contained in:
Mo
2023-07-12 12:56:08 -05:00
committed by GitHub
parent 49f7581cd8
commit 078ef3772c
223 changed files with 3996 additions and 3438 deletions

View File

@@ -1,32 +1,26 @@
import { Subscription } from '@standardnotes/security'
import { destroyAllObjectProperties } from '@/Utils'
import {
ApplicationEvent,
ClientDisplayableError,
convertTimestampToMilliseconds,
InternalEventBusInterface,
Invitation,
InvitationStatus,
SubscriptionClientInterface,
SubscriptionManagerEvent,
SubscriptionManagerInterface,
} from '@standardnotes/snjs'
import { action, computed, makeObservable, observable, runInAction } from 'mobx'
import { computed, makeObservable, observable, runInAction } from 'mobx'
import { WebApplication } from '../../Application/WebApplication'
import { AbstractViewController } from '../Abstract/AbstractViewController'
import { AvailableSubscriptions } from './AvailableSubscriptionsType'
import { Subscription } from './SubscriptionType'
export class SubscriptionController extends AbstractViewController {
private readonly ALLOWED_SUBSCRIPTION_INVITATIONS = 5
onlineSubscription: Subscription | undefined = undefined
availableSubscriptions: AvailableSubscriptions | undefined = undefined
subscriptionInvitations: Invitation[] | undefined = undefined
hasAccount: boolean
hasFirstPartySubscription: boolean
onlineSubscription: Subscription | undefined = undefined
override deinit() {
super.deinit()
;(this.onlineSubscription as unknown) = undefined
;(this.availableSubscriptions as unknown) = undefined
;(this.subscriptionInvitations as unknown) = undefined
destroyAllObjectProperties(this)
@@ -35,39 +29,28 @@ export class SubscriptionController extends AbstractViewController {
constructor(
application: WebApplication,
eventBus: InternalEventBusInterface,
private subscriptionManager: SubscriptionClientInterface,
private subscriptionManager: SubscriptionManagerInterface,
) {
super(application, eventBus)
this.hasAccount = application.hasAccount()
this.hasFirstPartySubscription = application.features.hasFirstPartySubscription()
makeObservable(this, {
onlineSubscription: observable,
availableSubscriptions: observable,
subscriptionInvitations: observable,
hasAccount: observable,
hasFirstPartySubscription: observable,
onlineSubscription: observable,
userSubscriptionName: computed,
userSubscriptionExpirationDate: computed,
isUserSubscriptionExpired: computed,
isUserSubscriptionCanceled: computed,
hasFirstPartyOnlineOrOfflineSubscription: computed,
usedInvitationsCount: computed,
allowedInvitationsCount: computed,
allInvitationsUsed: computed,
setUserSubscription: action,
setAvailableSubscriptions: action,
})
this.disposers.push(
application.addEventObserver(async () => {
if (application.hasAccount()) {
this.getSubscriptionInfo().catch(console.error)
this.reloadSubscriptionInvitations().catch(console.error)
}
runInAction(() => {
this.hasFirstPartySubscription = application.features.hasFirstPartySubscription()
this.hasAccount = application.hasAccount()
})
}, ApplicationEvent.Launched),
@@ -75,15 +58,6 @@ export class SubscriptionController extends AbstractViewController {
this.disposers.push(
application.addEventObserver(async () => {
runInAction(() => {
this.hasFirstPartySubscription = application.features.hasFirstPartySubscription()
})
}, ApplicationEvent.LocalDataLoaded),
)
this.disposers.push(
application.addEventObserver(async () => {
this.getSubscriptionInfo().catch(console.error)
this.reloadSubscriptionInvitations().catch(console.error)
runInAction(() => {
this.hasAccount = application.hasAccount()
@@ -91,50 +65,33 @@ export class SubscriptionController extends AbstractViewController {
}, ApplicationEvent.SignedIn),
)
this.disposers.push(
application.subscriptions.addEventObserver(async (event) => {
if (event === SubscriptionManagerEvent.DidFetchSubscription) {
runInAction(() => {
this.onlineSubscription = application.subscriptions.getOnlineSubscription()
})
}
}),
)
this.disposers.push(
application.addEventObserver(async () => {
this.getSubscriptionInfo().catch(console.error)
this.reloadSubscriptionInvitations().catch(console.error)
runInAction(() => {
this.hasFirstPartySubscription = application.features.hasFirstPartySubscription()
})
}, ApplicationEvent.UserRolesChanged),
)
}
get userSubscriptionName(): string {
if (
this.availableSubscriptions &&
this.onlineSubscription &&
this.availableSubscriptions[this.onlineSubscription.planName]
) {
return this.availableSubscriptions[this.onlineSubscription.planName].name
get hasFirstPartyOnlineOrOfflineSubscription(): boolean {
if (this.application.sessions.isSignedIn()) {
if (!this.application.sessions.isSignedIntoFirstPartyServer()) {
return false
}
return this.application.subscriptions.getOnlineSubscription() !== undefined
} else {
return this.application.features.hasFirstPartyOfflineSubscription()
}
return ''
}
get userSubscriptionExpirationDate(): Date | undefined {
if (!this.onlineSubscription) {
return undefined
}
return new Date(convertTimestampToMilliseconds(this.onlineSubscription.endsAt))
}
get isUserSubscriptionExpired(): boolean {
if (!this.userSubscriptionExpirationDate) {
return false
}
return this.userSubscriptionExpirationDate.getTime() < new Date().getTime()
}
get isUserSubscriptionCanceled(): boolean {
return Boolean(this.onlineSubscription?.cancelled)
}
hasValidSubscription(): boolean {
return this.onlineSubscription != undefined && !this.isUserSubscriptionExpired && !this.isUserSubscriptionCanceled
}
get usedInvitationsCount(): number {
@@ -153,14 +110,6 @@ export class SubscriptionController extends AbstractViewController {
return this.usedInvitationsCount === this.ALLOWED_SUBSCRIPTION_INVITATIONS
}
public setUserSubscription(subscription: Subscription): void {
this.onlineSubscription = subscription
}
public setAvailableSubscriptions(subscriptions: AvailableSubscriptions): void {
this.availableSubscriptions = subscriptions
}
async sendSubscriptionInvitation(inviteeEmail: string): Promise<boolean> {
const success = await this.subscriptionManager.inviteToSubscription(inviteeEmail)
@@ -181,33 +130,6 @@ export class SubscriptionController extends AbstractViewController {
return success
}
private async getAvailableSubscriptions() {
try {
const subscriptions = await this.application.getAvailableSubscriptions()
if (!(subscriptions instanceof ClientDisplayableError)) {
this.setAvailableSubscriptions(subscriptions)
}
} catch (error) {
void error
}
}
private async getSubscription() {
try {
const subscription = await this.application.getUserSubscription()
if (!(subscription instanceof ClientDisplayableError) && subscription) {
this.setUserSubscription(subscription)
}
} catch (error) {
console.error(error)
}
}
private async getSubscriptionInfo() {
await this.getSubscription()
await this.getAvailableSubscriptions()
}
private async reloadSubscriptionInvitations(): Promise<void> {
this.subscriptionInvitations = await this.subscriptionManager.listSubscriptionInvitations()
}