Smooth out purchase
This commit is contained in:
+29
-30
@@ -112,36 +112,35 @@ function InnerApp() {
|
|||||||
key={currentAccount?.did}>
|
key={currentAccount?.did}>
|
||||||
<QueryProvider currentDid={currentAccount?.did}>
|
<QueryProvider currentDid={currentAccount?.did}>
|
||||||
<PurchasesProvider>
|
<PurchasesProvider>
|
||||||
|
<ComposerProvider>
|
||||||
<ComposerProvider>
|
<StatsigProvider>
|
||||||
<StatsigProvider>
|
<MessagesProvider>
|
||||||
<MessagesProvider>
|
{/* LabelDefsProvider MUST come before ModerationOptsProvider */}
|
||||||
{/* LabelDefsProvider MUST come before ModerationOptsProvider */}
|
<LabelDefsProvider>
|
||||||
<LabelDefsProvider>
|
<ModerationOptsProvider>
|
||||||
<ModerationOptsProvider>
|
<LoggedOutViewProvider>
|
||||||
<LoggedOutViewProvider>
|
<SelectedFeedProvider>
|
||||||
<SelectedFeedProvider>
|
<HiddenRepliesProvider>
|
||||||
<HiddenRepliesProvider>
|
<UnreadNotifsProvider>
|
||||||
<UnreadNotifsProvider>
|
<BackgroundNotificationPreferencesProvider>
|
||||||
<BackgroundNotificationPreferencesProvider>
|
<MutedThreadsProvider>
|
||||||
<MutedThreadsProvider>
|
<SafeAreaProvider>
|
||||||
<SafeAreaProvider>
|
<ProgressGuideProvider>
|
||||||
<ProgressGuideProvider>
|
<Shell />
|
||||||
<Shell />
|
<NuxDialogs />
|
||||||
<NuxDialogs />
|
</ProgressGuideProvider>
|
||||||
</ProgressGuideProvider>
|
</SafeAreaProvider>
|
||||||
</SafeAreaProvider>
|
</MutedThreadsProvider>
|
||||||
</MutedThreadsProvider>
|
</BackgroundNotificationPreferencesProvider>
|
||||||
</BackgroundNotificationPreferencesProvider>
|
</UnreadNotifsProvider>
|
||||||
</UnreadNotifsProvider>
|
</HiddenRepliesProvider>
|
||||||
</HiddenRepliesProvider>
|
</SelectedFeedProvider>
|
||||||
</SelectedFeedProvider>
|
</LoggedOutViewProvider>
|
||||||
</LoggedOutViewProvider>
|
</ModerationOptsProvider>
|
||||||
</ModerationOptsProvider>
|
</LabelDefsProvider>
|
||||||
</LabelDefsProvider>
|
</MessagesProvider>
|
||||||
</MessagesProvider>
|
</StatsigProvider>
|
||||||
</StatsigProvider>
|
</ComposerProvider>
|
||||||
</ComposerProvider>
|
|
||||||
</PurchasesProvider>
|
</PurchasesProvider>
|
||||||
</QueryProvider>
|
</QueryProvider>
|
||||||
<ToastContainer />
|
<ToastContainer />
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import {msg, Trans} from '@lingui/macro'
|
|||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
import {useNavigationState} from '@react-navigation/native'
|
import {useNavigationState} from '@react-navigation/native'
|
||||||
|
|
||||||
|
import {isWeb} from '#/platform/detection'
|
||||||
import {usePurchaseOffering} from '#/state/purchases/hooks/usePurchaseOffering'
|
import {usePurchaseOffering} from '#/state/purchases/hooks/usePurchaseOffering'
|
||||||
import {useSubscriptionGroup} from '#/state/purchases/hooks/useSubscriptionGroup'
|
import {useSubscriptionGroup} from '#/state/purchases/hooks/useSubscriptionGroup'
|
||||||
import {
|
import {
|
||||||
@@ -15,6 +16,7 @@ import {parseOfferingId} from '#/state/purchases/types'
|
|||||||
import {useSession} from '#/state/session'
|
import {useSession} from '#/state/session'
|
||||||
import * as Toast from '#/view/com/util/Toast'
|
import * as Toast from '#/view/com/util/Toast'
|
||||||
import {atoms as a, tokens, useBreakpoints, useTheme} from '#/alf'
|
import {atoms as a, tokens, useBreakpoints, useTheme} from '#/alf'
|
||||||
|
import {Admonition} from '#/components/Admonition'
|
||||||
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
|
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
|
||||||
import * as Dialog from '#/components/Dialog'
|
import * as Dialog from '#/components/Dialog'
|
||||||
import * as Toggle from '#/components/forms/Toggle'
|
import * as Toggle from '#/components/forms/Toggle'
|
||||||
@@ -45,46 +47,70 @@ function DialogInner({control}: {control: Dialog.DialogControlProps}) {
|
|||||||
const currentRoute = routes.at(routes.length - 1)
|
const currentRoute = routes.at(routes.length - 1)
|
||||||
const isOnSubscriptionsPage = currentRoute?.name === 'Subscriptions'
|
const isOnSubscriptionsPage = currentRoute?.name === 'Subscriptions'
|
||||||
|
|
||||||
|
const [error, setError] = React.useState<string>('')
|
||||||
const [offeringId, setOfferingId] = React.useState<SubscriptionOfferingId>(
|
const [offeringId, setOfferingId] = React.useState<SubscriptionOfferingId>(
|
||||||
SubscriptionOfferingId.CoreAnnual,
|
SubscriptionOfferingId.CoreAnnual,
|
||||||
)
|
)
|
||||||
const {data: coreOffering} = useSubscriptionGroup(SubscriptionGroupId.Core)
|
const {data: coreOffering} = useSubscriptionGroup(SubscriptionGroupId.Core)
|
||||||
const {mutateAsync: purchaseOffering, isPending} = usePurchaseOffering()
|
const {mutateAsync: purchaseOffering, isPending} = usePurchaseOffering()
|
||||||
|
|
||||||
console.log({coreOffering})
|
|
||||||
|
|
||||||
const onPressSubscribe = async () => {
|
const onPressSubscribe = async () => {
|
||||||
try {
|
async function purchase() {
|
||||||
if (!currentAccount) return
|
if (!currentAccount) return
|
||||||
|
|
||||||
const offering = coreOffering?.offerings.find(o => o.id === offeringId)
|
const offering = coreOffering?.offerings.find(o => o.id === offeringId)
|
||||||
|
|
||||||
if (!offering) {
|
if (!offering) {
|
||||||
throw new Error('No offering')
|
Toast.show(
|
||||||
|
_(msg`Hmmmm. We couldn't locate that subscription.`),
|
||||||
|
'xmark',
|
||||||
|
)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await purchaseOffering({
|
||||||
|
did: currentAccount.did,
|
||||||
|
email: currentAccount.email!,
|
||||||
|
offering,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isWeb) {
|
||||||
|
try {
|
||||||
|
await purchase()
|
||||||
|
control.close()
|
||||||
|
} catch (e: any) {
|
||||||
|
setError(
|
||||||
|
_(
|
||||||
|
msg`Hmmm. Something went wrong, sorry about that. Please try again.`,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
control.close(async () => {
|
control.close(async () => {
|
||||||
try {
|
try {
|
||||||
await purchaseOffering({
|
await purchase()
|
||||||
did: currentAccount.did,
|
|
||||||
email: currentAccount.email!,
|
|
||||||
offering,
|
|
||||||
})
|
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
/**
|
/**
|
||||||
* @see https://www.revenuecat.com/docs/test-and-launch/errors
|
* @see https://www.revenuecat.com/docs/test-and-launch/errors
|
||||||
*/
|
*/
|
||||||
if (e.code === PURCHASES_ERROR_CODE.PURCHASE_CANCELLED_ERROR) {
|
switch (e.code) {
|
||||||
control.open()
|
case PURCHASES_ERROR_CODE.PURCHASE_CANCELLED_ERROR:
|
||||||
} else {
|
// do nothing, just reopen
|
||||||
Toast.show(
|
break
|
||||||
_(msg`Hmmmm, something went wrong. Please try again.`),
|
default:
|
||||||
'xmark',
|
Toast.show(
|
||||||
)
|
_(
|
||||||
|
msg`Hmmm. Something went wrong, sorry about that. Please try again.`,
|
||||||
|
),
|
||||||
|
'xmark',
|
||||||
|
)
|
||||||
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
control.open()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} catch (e: any) {
|
|
||||||
Toast.show(_(msg`Hmmmm. We couldn't locate that subscription.`), 'xmark')
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,17 +282,25 @@ function DialogInner({control}: {control: Dialog.DialogControlProps}) {
|
|||||||
disabled={isPending}
|
disabled={isPending}
|
||||||
style={[a.flex_1, a.overflow_hidden]}>
|
style={[a.flex_1, a.overflow_hidden]}>
|
||||||
<GradientFill gradient={tokens.gradients.nordic} />
|
<GradientFill gradient={tokens.gradients.nordic} />
|
||||||
<ButtonText style={[t.atoms.text]}>
|
<ButtonText style={[{color: 'white'}]}>
|
||||||
<Trans>Subscribe</Trans>
|
<Trans>Subscribe</Trans>
|
||||||
</ButtonText>
|
</ButtonText>
|
||||||
<ButtonIcon
|
<ButtonIcon
|
||||||
icon={isPending ? Loader : Plus}
|
icon={isPending ? Loader : Plus}
|
||||||
position="right"
|
position="right"
|
||||||
style={[t.atoms.text]}
|
style={[{color: 'white'}]}
|
||||||
/>
|
/>
|
||||||
</Button>
|
</Button>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
|
{error && (
|
||||||
|
<View style={[a.flex_row, a.pt_md, a.gap_sm]}>
|
||||||
|
<Admonition type="error" style={[a.flex_1]}>
|
||||||
|
{error}
|
||||||
|
</Admonition>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
|
||||||
<View style={[a.pt_md]}>
|
<View style={[a.pt_md]}>
|
||||||
<Text style={[a.text_xs]}>
|
<Text style={[a.text_xs]}>
|
||||||
<InlineLinkText
|
<InlineLinkText
|
||||||
|
|||||||
Reference in New Issue
Block a user