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
+29 -30
View File
@@ -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 />
+54 -20
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
} }
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