Add button

This commit is contained in:
Eric Bailey
2025-07-16 11:20:45 -05:00
parent 10d8a9c35a
commit 53c8218f05
4 changed files with 154 additions and 38 deletions
@@ -95,10 +95,25 @@ function Inner({style}: ViewStyleProp & {}) {
<View
style={[
a.pt_md,
a.justify_between,
a.align_center,
gtPhone ? [a.flex_row, a.gap_xl] : [a.gap_md],
gtPhone
? [a.flex_row, a.gap_xl, a.justify_between, a.align_center]
: [a.gap_md],
]}>
<Button
label={_(msg`Verify now`)}
size="small"
variant="solid"
color={hasInitiated ? 'secondary' : 'primary'}
onPress={() => control.open()}>
<ButtonText>
{hasInitiated ? (
<Trans>Verify again</Trans>
) : (
<Trans>Verify now</Trans>
)}
</ButtonText>
</Button>
{lastInitiatedAt && timeAgo && diff ? (
<Text
style={[a.text_sm, a.italic, t.atoms.text_contrast_medium]}
@@ -118,20 +133,6 @@ function Inner({style}: ViewStyleProp & {}) {
<Trans>Age assurance only takes a few minutes</Trans>
</Text>
)}
<Button
label={_(msg`Verify now`)}
size="small"
variant="solid"
color={hasInitiated ? 'secondary' : 'primary'}
onPress={() => control.open()}>
<ButtonText>
{hasInitiated ? (
<Trans>Verify again</Trans>
) : (
<Trans>Verify now</Trans>
)}
</ButtonText>
</Button>
</View>
</>
)}
@@ -0,0 +1,95 @@
import {useMemo} from 'react'
import {View} from 'react-native'
import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {useAgeAssurance} from '#/state/ageAssurance/useAgeAssurance'
import {Nux, useNux, useSaveNux} from '#/state/queries/nuxs'
import {atoms as a, select, useTheme} from '#/alf'
import {ShieldCheck_Stroke2_Corner0_Rounded as Shield} from '#/components/icons/Shield'
import {Link} from '#/components/Link'
import {Text} from '#/components/Typography'
export function useInternalState() {
const {isReady, isDeclaredUnderage, isAgeRestricted, lastInitiatedAt} =
useAgeAssurance()
const {nux} = useNux(Nux.AgeAssuranceDismissibleHeaderButton)
const {mutate: save, variables} = useSaveNux()
const hidden = !!variables
const visible = useMemo(() => {
if (!isReady) return false
if (isDeclaredUnderage) return false
if (!isAgeRestricted) return false
if (lastInitiatedAt) return false
if (hidden) return false
if (nux && nux.completed) return false
return true
}, [
isReady,
isDeclaredUnderage,
isAgeRestricted,
lastInitiatedAt,
hidden,
nux,
])
const close = () => {
save({
id: Nux.AgeAssuranceDismissibleHeaderButton,
completed: true,
data: undefined,
})
}
return {visible, close}
}
export function AgeAssuranceDismissibleHeaderButton() {
const t = useTheme()
const {_} = useLingui()
const {visible, close} = useInternalState()
if (!visible) return null
return (
<Link
label={_(msg`Learn more about age assurance`)}
to="/settings/account"
onPress={close}>
<View
style={[
a.flex_row,
a.align_center,
a.gap_xs,
a.px_sm,
a.pr_sm,
a.rounded_full,
{
paddingVertical: 6,
backgroundColor: select(t.name, {
light: t.palette.primary_100,
dark: t.palette.primary_100,
dim: t.palette.primary_100,
}),
},
]}>
<Shield size="sm" />
<Text
style={[
a.font_bold,
a.leading_snug,
{
color: select(t.name, {
light: t.palette.primary_800,
dark: t.palette.primary_800,
dim: t.palette.primary_800,
}),
},
]}>
<Trans>Age Assurance</Trans>
</Text>
</View>
</Link>
)
}
+6
View File
@@ -8,6 +8,7 @@ export enum Nux {
InitialVerificationAnnouncement = 'InitialVerificationAnnouncement',
ActivitySubscriptions = 'ActivitySubscriptions',
AgeAssuranceDismissibleNotice = 'AgeAssuranceDismissibleNotice',
AgeAssuranceDismissibleHeaderButton = 'AgeAssuranceDismissibleHeaderButton',
}
export const nuxNames = new Set(Object.values(Nux))
@@ -33,6 +34,10 @@ export type AppNux = BaseNux<
id: Nux.AgeAssuranceDismissibleNotice
data: undefined
}
| {
id: Nux.AgeAssuranceDismissibleHeaderButton
data: undefined
}
>
export const NuxSchemas: Record<Nux, zod.ZodObject<any> | undefined> = {
@@ -41,4 +46,5 @@ export const NuxSchemas: Record<Nux, zod.ZodObject<any> | undefined> = {
[Nux.InitialVerificationAnnouncement]: undefined,
[Nux.ActivitySubscriptions]: undefined,
[Nux.AgeAssuranceDismissibleNotice]: undefined,
[Nux.AgeAssuranceDismissibleHeaderButton]: undefined,
}
+35 -21
View File
@@ -12,6 +12,10 @@ import {useSession} from '#/state/session'
import {useShellLayout} from '#/state/shell/shell-layout'
import {Logo} from '#/view/icons/Logo'
import {atoms as a, useTheme} from '#/alf'
import {
AgeAssuranceDismissibleHeaderButton,
useInternalState,
} from '#/components/ageAssurance/AgeAssuranceDismissibleHeaderButton'
import {ButtonIcon} from '#/components/Button'
import {Hashtag_Stroke2_Corner0_Rounded as FeedsIcon} from '#/components/icons/Hashtag'
import * as Layout from '#/components/Layout'
@@ -29,6 +33,7 @@ export function HomeHeaderLayoutMobile({
const headerMinimalShellTransform = useMinimalShellHeaderTransform()
const {hasSession} = useSession()
const playHaptic = useHaptics()
const {visible: aaButtonVisible} = useInternalState()
return (
<Animated.View
@@ -51,36 +56,45 @@ export function HomeHeaderLayoutMobile({
<Layout.Header.MenuButton />
</Layout.Header.Slot>
<View style={[a.flex_1, a.align_center]}>
<View style={[a.flex_1]} />
<View style={[a.absolute, a.inset_0, a.align_center, a.justify_center]}>
<PressableScale
targetScale={0.9}
onPress={() => {
playHaptic('Light')
emitSoftReset()
}}>
}}
style={{top: -2}}>
<Logo width={30} />
</PressableScale>
</View>
<Layout.Header.Slot>
{hasSession && (
<Link
testID="viewHeaderHomeFeedPrefsBtn"
to={{screen: 'Feeds'}}
hitSlop={HITSLOP_10}
label={_(msg`View your feeds and explore more`)}
size="small"
variant="ghost"
color="secondary"
shape="square"
style={[
a.justify_center,
{marginRight: -Layout.BUTTON_VISUAL_ALIGNMENT_OFFSET},
]}>
<ButtonIcon icon={FeedsIcon} size="lg" />
</Link>
)}
</Layout.Header.Slot>
{aaButtonVisible ? (
<View style={{right: -4}}>
<AgeAssuranceDismissibleHeaderButton />
</View>
) : (
<Layout.Header.Slot>
{hasSession && (
<Link
testID="viewHeaderHomeFeedPrefsBtn"
to={{screen: 'Feeds'}}
hitSlop={HITSLOP_10}
label={_(msg`View your feeds and explore more`)}
size="small"
variant="ghost"
color="secondary"
shape="square"
style={[
a.justify_center,
{marginRight: -Layout.BUTTON_VISUAL_ALIGNMENT_OFFSET},
]}>
<ButtonIcon icon={FeedsIcon} size="lg" />
</Link>
)}
</Layout.Header.Slot>
)}
</Layout.Header.Outer>
{children}
</Animated.View>