diff options
author | Eric Bailey <git@esb.lol> | 2024-01-25 22:22:40 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-25 20:22:40 -0800 |
commit | 3371038f7d8b740f2415d3a54dc99b69e0598042 (patch) | |
tree | 9ef008e132f268ce6a8a23765ab34fda71a4bedc /src/screens/Onboarding/Layout.tsx | |
parent | 5443503593a67cc7ff6e081ef9b1fe66ea0cbe0d (diff) | |
download | voidsky-3371038f7d8b740f2415d3a54dc99b69e0598042.tar.zst |
New Onboarding (#2596)
* Add round and square buttons * Allow some style for buttons, add icons * Change text selection color * Center button text, whoops * Outer layout, some primitive updates * WIP * onboarding feed prefs (#2590) * add `style` to toggle label to modify text style * Revert "add `style` to toggle label to modify text style" This reverts commit 8f4b517b8585ca64a4bf44f6cb40ac070ece8932. * following feed prefs * remove unnecessary memo * reusable divider component * org imports * add finished screen * Theme SelectedAccountCard * Require at least 3 interests * Placeholder save logic * WIP algo feeds * Improve lineHeight handling, add RichText, improve Link by adding InlineLink * Inherit lineHeight in heading comps * Algo feeds mostly good * Topical feeds ish * Layout cleanup * Improve button styles * moderation prefs for onboarding (#2594) * WIP algo feeds * modify controlalbelgroup typing for easy .map() * adjust padding on button * add moderation screen * add moderation screen * add moderation screen --------- Co-authored-by: Eric Bailey <git@esb.lol> * Fix toggle button styles * A11y props on outer portal * Put it all on red * New data shape * Handle mock data * Bulk write (not yet) * Remove interests validation * Clean up interests * i18n layout and first step * Clean up suggested follows screen * Clean up following step * Clean up algo feeds step * Clean up topical feeds * Add skeleton for feed card * WIP moderation step * cleanup moderation styles (#2605) * cleanup moderation styles * fix(?) toggle button group styles * adjust toggle to fit any screen * Some more cleanup * Icons * ToggleButton tweaks * Reset * Hook up data * Better suggestions * Bulk write * Some logging * Use new api * Concat topical feeds * Metrics * Disable links in RichText, feedcards * Tweak primary feed cards * Update metrics * Fix layout shift * Fix ToggleButton again, whoops * Error state * Bump api package, ensure interests are saved * Better fix for autofill * i18n, button positions * Remove unused export * Add default prefs object * Fix overflow in user cards * Add 2 lines of bios to suggested accounts cards * Nits * Don't resolve facets by default * Update storybook * Disable flag for now * Remove age dialog from moderations step * Improvements and tweaks to new onboarding --------- Co-authored-by: Hailey <153161762+haileyok@users.noreply.github.com> Co-authored-by: Paul Frazee <pfrazee@gmail.com>
Diffstat (limited to 'src/screens/Onboarding/Layout.tsx')
-rw-r--r-- | src/screens/Onboarding/Layout.tsx | 231 |
1 files changed, 231 insertions, 0 deletions
diff --git a/src/screens/Onboarding/Layout.tsx b/src/screens/Onboarding/Layout.tsx new file mode 100644 index 000000000..50487c189 --- /dev/null +++ b/src/screens/Onboarding/Layout.tsx @@ -0,0 +1,231 @@ +import React from 'react' +import {View} from 'react-native' +import {useSafeAreaInsets} from 'react-native-safe-area-context' +import {useLingui} from '@lingui/react' +import {msg} from '@lingui/macro' + +import {IS_DEV} from '#/env' +import {isWeb} from '#/platform/detection' +import {useOnboardingDispatch} from '#/state/shell' + +import { + useTheme, + atoms as a, + useBreakpoints, + web, + native, + flatten, + TextStyleProp, +} from '#/alf' +import {H2, P, leading} from '#/components/Typography' +import {ChevronLeft_Stroke2_Corner0_Rounded as ChevronLeft} from '#/components/icons/Chevron' +import {Button, ButtonIcon} from '#/components/Button' +import {ScrollView} from '#/view/com/util/Views' +import {createPortalGroup} from '#/components/Portal' + +import {Context} from '#/screens/Onboarding/state' + +const COL_WIDTH = 500 + +export const OnboardingControls = createPortalGroup() + +export function Layout({children}: React.PropsWithChildren<{}>) { + const {_} = useLingui() + const t = useTheme() + const insets = useSafeAreaInsets() + const {gtMobile} = useBreakpoints() + const onboardDispatch = useOnboardingDispatch() + const {state, dispatch} = React.useContext(Context) + const scrollview = React.useRef<ScrollView>(null) + const prevActiveStep = React.useRef<string>(state.activeStep) + + React.useEffect(() => { + if (state.activeStep !== prevActiveStep.current) { + prevActiveStep.current = state.activeStep + scrollview.current?.scrollTo({y: 0, animated: false}) + } + }, [state]) + + const paddingTop = gtMobile ? a.py_5xl : a.py_lg + const dialogLabel = _(msg`Set up your account`) + + return ( + <View + aria-modal + role="dialog" + aria-role="dialog" + aria-label={dialogLabel} + accessibilityLabel={dialogLabel} + accessibilityHint={_( + msg`The following steps will help customize your Bluesky experience.`, + )} + style={[ + // @ts-ignore web only -prf + isWeb ? a.fixed : a.absolute, + a.inset_0, + a.flex_1, + t.atoms.bg, + ]}> + {IS_DEV && ( + <View style={[a.absolute, a.p_xl, a.z_10, {right: 0, top: insets.top}]}> + <Button + variant="ghost" + color="negative" + size="small" + onPress={() => onboardDispatch({type: 'skip'})} + // DEV ONLY + label="Clear onboarding state"> + Clear + </Button> + </View> + )} + + {!gtMobile && state.hasPrev && ( + <View + style={[ + web(a.fixed), + native(a.absolute), + a.flex_row, + a.w_full, + a.justify_center, + a.z_20, + a.px_xl, + { + top: paddingTop.paddingTop + insets.top - 1, + }, + ]}> + <View style={[a.w_full, a.align_start, {maxWidth: COL_WIDTH}]}> + <Button + key={state.activeStep} // remove focus state on nav + variant="ghost" + color="secondary" + size="small" + shape="round" + label={_(msg`Go back to previous step`)} + style={[a.absolute]} + onPress={() => dispatch({type: 'prev'})}> + <ButtonIcon icon={ChevronLeft} /> + </Button> + </View> + </View> + )} + + <ScrollView + ref={scrollview} + style={[a.h_full, a.w_full, {paddingTop: insets.top}]} + contentContainerStyle={{borderWidth: 0}} + // @ts-ignore web only --prf + dataSet={{'stable-gutters': 1}}> + <View + style={[a.flex_row, a.justify_center, gtMobile ? a.px_5xl : a.px_xl]}> + <View style={[a.flex_1, {maxWidth: COL_WIDTH}]}> + <View style={[a.w_full, a.align_center, paddingTop]}> + <View + style={[ + a.flex_row, + a.gap_sm, + a.w_full, + {paddingTop: 17, maxWidth: '60%'}, + ]}> + {Array(state.totalSteps) + .fill(0) + .map((_, i) => ( + <View + key={i} + style={[ + a.flex_1, + a.pt_xs, + a.rounded_full, + t.atoms.bg_contrast_50, + { + backgroundColor: + i + 1 <= state.activeStepIndex + ? t.palette.primary_500 + : t.palette.contrast_100, + }, + ]} + /> + ))} + </View> + </View> + + <View + style={[a.w_full, a.mb_5xl, {paddingTop: gtMobile ? 20 : 40}]}> + {children} + </View> + + <View style={{height: 200}} /> + </View> + </View> + </ScrollView> + + <View + style={[ + // @ts-ignore web only -prf + isWeb ? a.fixed : a.absolute, + {bottom: 0, left: 0, right: 0}, + t.atoms.bg, + t.atoms.border, + a.border_t, + a.align_center, + gtMobile ? a.px_5xl : a.px_xl, + isWeb + ? a.py_2xl + : { + paddingTop: a.pt_lg.paddingTop, + paddingBottom: insets.bottom, + }, + ]}> + <View + style={[ + a.w_full, + {maxWidth: COL_WIDTH}, + gtMobile && [a.flex_row, a.justify_between], + ]}> + {gtMobile && + (state.hasPrev ? ( + <Button + key={state.activeStep} // remove focus state on nav + variant="solid" + color="secondary" + size="large" + shape="round" + label={_(msg`Go back to previous step`)} + onPress={() => dispatch({type: 'prev'})}> + <ButtonIcon icon={ChevronLeft} /> + </Button> + ) : ( + <View style={{height: 54}} /> + ))} + <OnboardingControls.Outlet /> + </View> + </View> + </View> + ) +} + +export function Title({ + children, + style, +}: React.PropsWithChildren<TextStyleProp>) { + return ( + <H2 + style={[ + a.pb_sm, + { + lineHeight: leading(a.text_4xl, a.leading_tight), + }, + flatten(style), + ]}> + {children} + </H2> + ) +} + +export function Description({ + children, + style, +}: React.PropsWithChildren<TextStyleProp>) { + const t = useTheme() + return <P style={[t.atoms.text_contrast_700, flatten(style)]}>{children}</P> +} |