Smooth out purchase

This commit is contained in:
Eric Bailey
2024-11-26 09:27:38 -06:00
parent 6e79fec72d
commit 011ef85230
2 changed files with 83 additions and 50 deletions
-1
View File
@@ -112,7 +112,6 @@ function InnerApp() {
key={currentAccount?.did}> key={currentAccount?.did}>
<QueryProvider currentDid={currentAccount?.did}> <QueryProvider currentDid={currentAccount?.did}>
<PurchasesProvider> <PurchasesProvider>
<ComposerProvider> <ComposerProvider>
<StatsigProvider> <StatsigProvider>
<MessagesProvider> <MessagesProvider>
+48 -14
View File
@@ -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
} }
control.close(async () => {
try {
await purchaseOffering({ await purchaseOffering({
did: currentAccount.did, did: currentAccount.did,
email: currentAccount.email!, email: currentAccount.email!,
offering, 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 () => {
try {
await purchase()
} 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
break
default:
Toast.show( Toast.show(
_(msg`Hmmmm, something went wrong. Please try again.`), _(
msg`Hmmm. Something went wrong, sorry about that. Please try again.`,
),
'xmark', '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