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 8f4b517b85.
* 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>
This commit is contained in:
@@ -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>
|
||||
}
|
||||
Reference in New Issue
Block a user