diff --git a/src/components/dialogs/SubscriptionsDialog.tsx b/src/components/dialogs/SubscriptionsDialog.tsx
new file mode 100644
index 0000000000..eb54c760b6
--- /dev/null
+++ b/src/components/dialogs/SubscriptionsDialog.tsx
@@ -0,0 +1,269 @@
+import React from 'react'
+import {Linking, View} from 'react-native'
+import {msg, Trans} from '@lingui/macro'
+import {useLingui} from '@lingui/react'
+
+import {useCreateCheckout} from '#/state/purchases/subscriptions/useCreateCheckout'
+import {useSession} from '#/state/session'
+import * as Toast from '#/view/com/util/Toast'
+import {atoms as a, tokens, useBreakpoints, useTheme, web} from '#/alf'
+import {Button, ButtonIcon, ButtonText} from '#/components/Button'
+import * as Dialog from '#/components/Dialog'
+import * as Toggle from '#/components/forms/Toggle'
+import {GradientFill} from '#/components/GradientFill'
+import {Full as BlueskyPlusLogo} from '#/components/icons/BlueskyPlus'
+import {ChevronRight_Stroke2_Corner0_Rounded as ChevronRightIcon} from '#/components/icons/Chevron'
+import {InlineLinkText} from '#/components/Link'
+import {Loader} from '#/components/Loader'
+import {Text} from '#/components/Typography'
+
+export function SubscriptionsDialog({
+ control,
+}: {
+ control: Dialog.DialogControlProps
+}) {
+ return (
+
+
+
+ )
+}
+
+function DialogInner() {
+ const {_} = useLingui()
+ const {gtMobile} = useBreakpoints()
+ const {currentAccount} = useSession()
+ const t = useTheme()
+ const [plan, setPlan] = React.useState<'monthly' | 'annual'>('monthly')
+
+ const {mutateAsync: createCheckout, isPending} = useCreateCheckout()
+
+ const onPressSubscribe = async () => {
+ try {
+ if (!currentAccount) return
+ const data = await createCheckout({
+ did: currentAccount.did,
+ email: currentAccount.email!,
+ price:
+ plan === 'monthly'
+ ? 'price_1QLsNLAwTlpRxHkAhuUwbnlL'
+ : 'price_1QLsOjAwTlpRxHkAcrV8DL2P',
+ })
+
+ if (!data?.checkoutUrl) {
+ throw new Error('No checkout URL')
+ }
+
+ Linking.openURL(data.checkoutUrl)
+ } catch (e: any) {
+ Toast.show(_(msg`Could not take you to checkout`), 'xmark')
+ }
+ }
+
+ return (
+
+
+
+
+
+
+
+
+
+
+ Early bird discount!
+
+
+ Support Bluesky now and get a 25% discount for a year
+
+ setPlan(values[0] as 'monthly' | 'annual')}
+ style={[a.w_full, a.gap_md, a.my_xl]}>
+
+ {({selected}) => (
+
+
+
+
+
+ Monthly plan
+
+
+ $6/month
+
+
+
+
+ Billed monthly, cancel anytime. $8/month after 12 months
+
+
+
+
+ )}
+
+
+ {({selected}) => (
+
+
+
+
+
+ Annual plan
+
+
+ $60/year
+
+
+
+ Billed annually, renews at $80/year
+
+
+
+ )}
+
+
+
+
+
+ Terms and Conditions
+ {' '}
+ ·{' '}
+
+ Privacy Policy
+ {' '}
+ ·{' '}
+
+ EULA
+
+
+
+
+
+
+ )
+}
+
+function MarketingBlurb() {
+ return (
+ <>
+
+
+
+
+ Here's the thing: we don't have any premium features yet because all
+ our servers are on fire. Support us now so we can put the fires out
+ and get working on those features!
+
+
+
+
+ What you'll get now:
+
+
+
+ {' '}
+ · A supporter badge on your profile
+
+
+ {' '}
+ · A warm fuzzy feeling knowing you helped us out
+
+
+
+
+ What you'll get soon:
+
+
+
+ {' '}
+ · Custom profile colors
+
+
+ {' '}
+ · Longer and higher quality videos
+
+
+ {' '}
+ · Custom app icons
+
+
+ >
+ )
+}
diff --git a/src/components/forms/Toggle.tsx b/src/components/forms/Toggle.tsx
index 4e3695bbf2..9205e97632 100644
--- a/src/components/forms/Toggle.tsx
+++ b/src/components/forms/Toggle.tsx
@@ -1,5 +1,5 @@
import React from 'react'
-import {Pressable, View, ViewStyle} from 'react-native'
+import {Pressable, StyleProp, View, ViewStyle} from 'react-native'
import Animated, {LinearTransition} from 'react-native-reanimated'
import {HITSLOP_10} from '#/lib/constants'
@@ -57,6 +57,7 @@ export type GroupProps = React.PropsWithChildren<{
disabled?: boolean
onChange: (value: string[]) => void
label: string
+ style?: StyleProp
}>
export type ItemProps = ViewStyleProp & {
@@ -82,6 +83,7 @@ export function Group({
type = 'checkbox',
maxSelections,
label,
+ style,
}: GroupProps) {
const groupRole = type === 'radio' ? 'radiogroup' : undefined
const values = type === 'radio' ? providedValues.slice(0, 1) : providedValues
@@ -134,7 +136,7 @@ export function Group({
return (
{gradient && }
@@ -54,15 +61,20 @@ export function Logotype(props: Props) {
const {fill, ...rest} = props
const gradient = fill === 'nordic'
const styles = StyleSheet.flatten(props.style)
- const _fill = gradient ? 'url(#nordic)' : fill || styles?.color || t.palette.primary_500
+ const _fill = gradient
+ ? 'url(#nordic)'
+ : fill || styles?.color || t.palette.primary_500
// @ts-ignore it's fiiiiine
const size = parseInt(rest.width || 100)
const ratio = 78 / 330
+ const {_} = useLingui()
return (