Design
This commit is contained in:
@@ -19,7 +19,7 @@ import {
|
|||||||
NativePurchaseRestricted,
|
NativePurchaseRestricted,
|
||||||
} from '#/state/purchases/types'
|
} from '#/state/purchases/types'
|
||||||
import {CenteredView} from '#/view/com/util/Views'
|
import {CenteredView} from '#/view/com/util/Views'
|
||||||
import {atoms as a, tokens, useTheme} from '#/alf'
|
import {atoms as a, tokens, useBreakpoints,useTheme} from '#/alf'
|
||||||
import {Admonition} from '#/components/Admonition'
|
import {Admonition} from '#/components/Admonition'
|
||||||
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
|
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
|
||||||
import {useDialogControl} from '#/components/Dialog'
|
import {useDialogControl} from '#/components/Dialog'
|
||||||
@@ -36,7 +36,7 @@ import {Globe_Stroke2_Corner0_Rounded as Globe} from '#/components/icons/Globe'
|
|||||||
import {Mark} from '#/components/icons/Logo'
|
import {Mark} from '#/components/icons/Logo'
|
||||||
import {PlusLarge_Stroke2_Corner0_Rounded as Plus} from '#/components/icons/Plus'
|
import {PlusLarge_Stroke2_Corner0_Rounded as Plus} from '#/components/icons/Plus'
|
||||||
import * as Layout from '#/components/Layout'
|
import * as Layout from '#/components/Layout'
|
||||||
import {createStaticClick, Link} from '#/components/Link'
|
import {createStaticClick, InlineLinkText, Link} from '#/components/Link'
|
||||||
import {Loader} from '#/components/Loader'
|
import {Loader} from '#/components/Loader'
|
||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
|
|
||||||
@@ -102,8 +102,8 @@ function Core({
|
|||||||
return (
|
return (
|
||||||
<View>
|
<View>
|
||||||
<View style={[a.flex_row, a.align_center, a.gap_xs]}>
|
<View style={[a.flex_row, a.align_center, a.gap_xs]}>
|
||||||
<Mark width={26} gradient="nordic" />
|
<Mark width={30} gradient="nordic" />
|
||||||
<Logotype width={80} fill={t.atoms.text_contrast_medium.color} />
|
<Logotype width={90} fill={t.atoms.text.color} />
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
{restricted === 'yes' ? (
|
{restricted === 'yes' ? (
|
||||||
@@ -118,15 +118,122 @@ function Core({
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{isSubscribedToCore ? (
|
{isSubscribedToCore ? (
|
||||||
<View style={[a.gap_sm, a.pt_lg]}>
|
<View style={[a.pt_md, a.gap_lg]}>
|
||||||
<Text style={[a.text_sm, a.font_bold, t.atoms.text_contrast_medium]}>
|
<View style={[a.gap_sm]}>
|
||||||
<Trans>Active subscriptions</Trans>
|
{coreSubscriptions.map(sub => (
|
||||||
</Text>
|
<Subscription key={sub.purchasedAt} subscription={sub} />
|
||||||
{coreSubscriptions.map(sub => (
|
))}
|
||||||
<Subscription key={sub.purchasedAt} subscription={sub} />
|
</View>
|
||||||
))}
|
|
||||||
|
<Divider />
|
||||||
|
|
||||||
|
<InfoCards />
|
||||||
</View>
|
</View>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
|
<View style={[a.pt_lg]}>
|
||||||
|
<Text style={[a.text_xs]}>
|
||||||
|
<InlineLinkText
|
||||||
|
to="#"
|
||||||
|
label="TODO REPLACE"
|
||||||
|
style={[a.text_xs, t.atoms.text_contrast_medium]}>
|
||||||
|
Terms and Conditions
|
||||||
|
</InlineLinkText>{' '}
|
||||||
|
·{' '}
|
||||||
|
<InlineLinkText
|
||||||
|
to="#"
|
||||||
|
label="TODO REPLACE"
|
||||||
|
style={[a.text_xs, t.atoms.text_contrast_medium]}>
|
||||||
|
Privacy Policy
|
||||||
|
</InlineLinkText>{' '}
|
||||||
|
·{' '}
|
||||||
|
<InlineLinkText
|
||||||
|
to="#"
|
||||||
|
label="TODO REPLACE"
|
||||||
|
style={[a.text_xs, t.atoms.text_contrast_medium]}>
|
||||||
|
EULA
|
||||||
|
</InlineLinkText>
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function InfoCards() {
|
||||||
|
const t = useTheme()
|
||||||
|
const {_} = useLingui()
|
||||||
|
const {gtPhone} = useBreakpoints()
|
||||||
|
const {features} = useFeatures()
|
||||||
|
const activeFeatures = features.filter(f => f.available)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={[a.flex_row, a.gap_md, a.flex_wrap]}>
|
||||||
|
<View
|
||||||
|
style={[
|
||||||
|
gtPhone ? a.flex_1 : a.w_full,
|
||||||
|
a.p_lg,
|
||||||
|
a.rounded_md,
|
||||||
|
a.gap_sm,
|
||||||
|
t.atoms.bg_contrast_25,
|
||||||
|
]}>
|
||||||
|
<Text
|
||||||
|
style={[
|
||||||
|
a.text_sm,
|
||||||
|
a.font_bold,
|
||||||
|
a.leading_snug,
|
||||||
|
t.atoms.text_contrast_medium,
|
||||||
|
]}>
|
||||||
|
<Trans>Features</Trans>
|
||||||
|
</Text>
|
||||||
|
<View style={[a.py_xs, a.gap_sm]}>
|
||||||
|
{activeFeatures.map(f => (
|
||||||
|
<View key={f.text} style={[a.flex_row, a.align_center, a.gap_xs]}>
|
||||||
|
<f.icon fill={t.atoms.text_contrast_low.color} size="xs" />
|
||||||
|
<Text style={[a.text_sm]}>{f.text}</Text>
|
||||||
|
</View>
|
||||||
|
))}
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View
|
||||||
|
style={[
|
||||||
|
gtPhone ? a.flex_1 : a.w_full,
|
||||||
|
a.p_lg,
|
||||||
|
a.rounded_md,
|
||||||
|
a.border,
|
||||||
|
a.gap_sm,
|
||||||
|
t.atoms.border_contrast_low,
|
||||||
|
]}>
|
||||||
|
<Text style={[a.text_sm, a.leading_snug, t.atoms.text_contrast_medium]}>
|
||||||
|
<Trans>
|
||||||
|
Your support helps Bluesky build a better internet. Thanks for being
|
||||||
|
a part of the ATmosphere!
|
||||||
|
</Trans>
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Link
|
||||||
|
to="https://blueskyweb.zendesk.com/hc/en-us"
|
||||||
|
label={_(msg`Contact support`)}
|
||||||
|
size="small"
|
||||||
|
variant="solid"
|
||||||
|
color="secondary"
|
||||||
|
style={[a.justify_center]}>
|
||||||
|
<ButtonText>
|
||||||
|
<Trans>Get support</Trans>
|
||||||
|
</ButtonText>
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
to="https://blueskyweb.zendesk.com/hc/en-us"
|
||||||
|
label={_(msg`Subscriptions FAQ`)}
|
||||||
|
size="small"
|
||||||
|
variant="outline"
|
||||||
|
color="secondary"
|
||||||
|
style={[a.justify_center]}>
|
||||||
|
<ButtonText>
|
||||||
|
<Trans>FAQ</Trans>
|
||||||
|
</ButtonText>
|
||||||
|
</Link>
|
||||||
|
</View>
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -135,49 +242,7 @@ function Purchase() {
|
|||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
const {_} = useLingui()
|
const {_} = useLingui()
|
||||||
const control = useDialogControl()
|
const control = useDialogControl()
|
||||||
|
const {features} = useFeatures()
|
||||||
const features = [
|
|
||||||
{
|
|
||||||
available: true,
|
|
||||||
icon: Check,
|
|
||||||
text: _(msg`Bluesky+ supporter badge`),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
available: true,
|
|
||||||
icon: Check,
|
|
||||||
text: _(msg`Custom app icons`),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
available: true,
|
|
||||||
icon: Check,
|
|
||||||
text: _(msg`Profile customizations`),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
available: true,
|
|
||||||
icon: Check,
|
|
||||||
text: _(msg`Higher video upload limits`),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
available: true,
|
|
||||||
icon: Check,
|
|
||||||
text: _(msg`High quality video resolution`),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
available: false,
|
|
||||||
icon: Clock,
|
|
||||||
text: _(msg`Inline post translations (coming soon)`),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
available: false,
|
|
||||||
icon: Clock,
|
|
||||||
text: _(msg`Post analytics (coming soon)`),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
available: false,
|
|
||||||
icon: Clock,
|
|
||||||
text: _(msg`Bookmark folders (coming soon)`),
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -355,14 +420,32 @@ export function Subscription({
|
|||||||
return (
|
return (
|
||||||
<View
|
<View
|
||||||
key={sub.purchasedAt}
|
key={sub.purchasedAt}
|
||||||
style={[
|
style={[a.px_lg, a.rounded_md, a.overflow_hidden]}>
|
||||||
a.px_lg,
|
<GradientFill gradient={tokens.gradients.nordic} />
|
||||||
a.rounded_md,
|
<View
|
||||||
a.border,
|
style={[
|
||||||
a.overflow_hidden,
|
a.absolute,
|
||||||
t.atoms.border_contrast_low,
|
t.atoms.bg,
|
||||||
]}>
|
{
|
||||||
<View style={[a.flex_row, a.justify_between, a.align_center, a.py_sm]}>
|
borderRadius: a.rounded_md.borderRadius - 2,
|
||||||
|
top: 2,
|
||||||
|
bottom: 2,
|
||||||
|
left: 2,
|
||||||
|
right: 2,
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<View
|
||||||
|
style={[
|
||||||
|
a.flex_row,
|
||||||
|
a.justify_between,
|
||||||
|
a.align_center,
|
||||||
|
{
|
||||||
|
paddingTop: 10,
|
||||||
|
paddingBottom: 8,
|
||||||
|
},
|
||||||
|
]}>
|
||||||
<View style={[a.flex_row, a.align_center, a.gap_sm]}>
|
<View style={[a.flex_row, a.align_center, a.gap_sm]}>
|
||||||
<Text style={[a.text_lg, a.font_heavy]}>{ui.title}</Text>
|
<Text style={[a.text_lg, a.font_heavy]}>{ui.title}</Text>
|
||||||
|
|
||||||
@@ -400,7 +483,16 @@ export function Subscription({
|
|||||||
|
|
||||||
<Divider />
|
<Divider />
|
||||||
|
|
||||||
<View style={[a.py_sm, a.flex_row, a.justify_between, a.align_center]}>
|
<View
|
||||||
|
style={[
|
||||||
|
a.flex_row,
|
||||||
|
a.gap_md,
|
||||||
|
a.align_center,
|
||||||
|
{
|
||||||
|
paddingTop: 8,
|
||||||
|
paddingBottom: 10,
|
||||||
|
},
|
||||||
|
]}>
|
||||||
<View
|
<View
|
||||||
style={[
|
style={[
|
||||||
a.flex_row,
|
a.flex_row,
|
||||||
@@ -409,8 +501,8 @@ export function Subscription({
|
|||||||
a.gap_xs,
|
a.gap_xs,
|
||||||
{left: -1},
|
{left: -1},
|
||||||
]}>
|
]}>
|
||||||
<ui.PlatformLogo size="md" fill={t.atoms.text_contrast_low.color} />
|
<ui.PlatformLogo size="sm" fill={t.atoms.text_contrast_low.color} />
|
||||||
<Text style={[a.text_sm, a.font_bold, t.atoms.text_contrast_medium]}>
|
<Text style={[a.text_sm, t.atoms.text_contrast_medium]}>
|
||||||
{ui.platformName}
|
{ui.platformName}
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
@@ -428,3 +520,54 @@ export function Subscription({
|
|||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function useFeatures() {
|
||||||
|
const {_} = useLingui()
|
||||||
|
|
||||||
|
const features = [
|
||||||
|
{
|
||||||
|
available: true,
|
||||||
|
icon: Check,
|
||||||
|
text: _(msg`Bluesky+ profile badge`),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
available: true,
|
||||||
|
icon: Check,
|
||||||
|
text: _(msg`Custom app icons`),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
available: true,
|
||||||
|
icon: Check,
|
||||||
|
text: _(msg`Profile customizations`),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
available: true,
|
||||||
|
icon: Check,
|
||||||
|
text: _(msg`Higher video upload limits`),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
available: true,
|
||||||
|
icon: Check,
|
||||||
|
text: _(msg`High quality video resolution`),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
available: false,
|
||||||
|
icon: Clock,
|
||||||
|
text: _(msg`Inline post translations (coming soon)`),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
available: false,
|
||||||
|
icon: Clock,
|
||||||
|
text: _(msg`Post analytics (coming soon)`),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
available: false,
|
||||||
|
icon: Clock,
|
||||||
|
text: _(msg`Bookmark folders (coming soon)`),
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
return {
|
||||||
|
features,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user