diff --git a/src/screens/Onboarding/StepProfile/AvatarCircle.tsx b/src/screens/Onboarding/StepProfile/AvatarCircle.tsx index b4478e600c..5411a72b26 100644 --- a/src/screens/Onboarding/StepProfile/AvatarCircle.tsx +++ b/src/screens/Onboarding/StepProfile/AvatarCircle.tsx @@ -1,21 +1,16 @@ import React from 'react' -import { - LayoutAnimation, - Pressable, - PressableProps, - StyleSheet, - View, -} from 'react-native' +import {LayoutAnimation, Pressable, PressableProps, View} from 'react-native' +import {Image} from 'expo-image' +import {TimesLarge_Stroke2_Corner0_Rounded as Times} from '#/components/icons/Times' +import {Camera_Stroke2_Corner0_Rounded as Camera} from '#/components/icons/Camera' +import {useAvatar, useSetAvatar} from '#/screens/Onboarding/StepProfile/index' + import {atoms as a, useTheme} from '#/alf' import {usePhotoLibraryPermission} from 'lib/hooks/usePermissions' import {openPicker} from 'lib/media/picker.shared' import {isNative, isWeb} from 'platform/detection' import {openCropper} from 'lib/media/picker' import {compressIfNeeded} from 'lib/media/manip' -import {Image} from 'expo-image' -import {TimesLarge_Stroke2_Corner0_Rounded as Times} from '#/components/icons/Times' -import {Camera_Stroke2_Corner0_Rounded as Camera} from '#/components/icons/Camera' -import {useAvatar, useSetAvatar} from '#/screens/Onboarding/StepProfile/index' export function AvatarBottomButton({...props}: PressableProps) { const t = useTheme() @@ -43,6 +38,25 @@ export function AvatarCircle() { const Icon = avatar.placeholder.component const {requestPhotoAccessIfNeeded} = usePhotoLibraryPermission() + const styles = React.useMemo( + () => ({ + imageContainer: [ + a.rounded_full, + a.overflow_hidden, + a.align_center, + a.justify_center, + t.atoms.border_contrast_high, + { + height: 150, + width: 150, + borderWidth: 2, + backgroundColor: avatar.backgroundColor, + }, + ], + }), + [avatar.backgroundColor, t.atoms.border_contrast_high], + ) + const onCameraPress = React.useCallback(async () => { if (!(await requestPhotoAccessIfNeeded())) { return @@ -93,7 +107,7 @@ export function AvatarCircle() { @@ -105,14 +119,7 @@ export function AvatarCircle() { return ( - + @@ -121,15 +128,3 @@ export function AvatarCircle() { ) } - -const styles = StyleSheet.create({ - imageContainer: { - borderRadius: 100, - height: 150, - width: 150, - overflow: 'hidden', - borderWidth: 2, - alignItems: 'center', - justifyContent: 'center', - }, -}) diff --git a/src/screens/Onboarding/StepProfile/AvatarCreatorItems.tsx b/src/screens/Onboarding/StepProfile/AvatarCreatorItems.tsx index 8eb3df9bc7..667365bc4a 100644 --- a/src/screens/Onboarding/StepProfile/AvatarCreatorItems.tsx +++ b/src/screens/Onboarding/StepProfile/AvatarCreatorItems.tsx @@ -1,11 +1,13 @@ import React from 'react' -import {atoms as a, useTheme} from '#/alf' -import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' +import {FlatList, ListRenderItemInfo, Pressable, View} from 'react-native' import Animated, { useAnimatedStyle, useSharedValue, withTiming, } from 'react-native-reanimated' + +import {atoms as a, useTheme} from '#/alf' +import {useAvatar, useSetAvatar} from '#/screens/Onboarding/StepProfile/index' import { AvatarColor, avatarColors, @@ -13,15 +15,7 @@ import { EmojiName, emojiNames, } from '#/screens/Onboarding/StepProfile/types' -import { - FlatList, - FlatListProps, - ListRenderItemInfo, - Pressable, - StyleSheet, - View, -} from 'react-native' -import {useAvatar, useSetAvatar} from '#/screens/Onboarding/StepProfile/index' +import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' const WITH_TIMING_CONFIG = {duration: 150} @@ -31,9 +25,26 @@ function AnimatedCircle({ }: React.PropsWithChildren<{selected: boolean}>) { const t = useTheme() const {isTabletOrDesktop} = useWebMediaQueries() - const styles = useStyles() const size = useSharedValue(selected ? 1.2 : 1) + const styles = React.useMemo( + () => ({ + imageContainer: [ + a.rounded_full, + a.overflow_hidden, + a.align_center, + a.justify_center, + {height: 150, width: 150, borderWidth: 2}, + ], + paletteContainer: { + height: 70, + width: 70, + margin: isTabletOrDesktop ? 8 : 2, + }, + }), + [isTabletOrDesktop], + ) + React.useEffect(() => { if (selected && size.value !== 1.2) { size.value = withTiming(1.2, WITH_TIMING_CONFIG) @@ -125,63 +136,40 @@ function emojiRenderItem({item}: ListRenderItemInfo) { export function AvatarCreatorItems({type}: {type: 'emojis' | 'colors'}) { const {isTabletOrDesktop} = useWebMediaQueries() - const styles = useStyles() + + const styles = React.useMemo( + () => ({ + flatListOuter: isTabletOrDesktop + ? { + height: 435, + } + : [a.flex_row, a.align_center, {height: 100}], + }), + [isTabletOrDesktop], + ) return ( - - + // Changing the value of numColumns on the fly isn't supported, so we want the flatlist to re-render whenever - // the size of the screen changes + // the size of the screen changes. Should only happen when `isTabletOrDesktop` changes. key={isTabletOrDesktop ? 0 : 1} data={type === 'colors' ? avatarColors : emojiNames} renderItem={type === 'colors' ? colorRenderItem : emojiRenderItem} style={[isTabletOrDesktop && {marginHorizontal: 10}]} contentContainerStyle={[ a.align_center, - {height: 100}, - !isTabletOrDesktop && styles.flatListContainer, isTabletOrDesktop && type === 'colors' && a.pr_xs, + !isTabletOrDesktop && {paddingHorizontal: 40}, ]} numColumns={isTabletOrDesktop && type === 'emojis' ? 4 : undefined} showsHorizontalScrollIndicator={isTabletOrDesktop && type === 'colors'} horizontal={!isTabletOrDesktop} - {...commonFlatListProps} /> ) } - -const useStyles = () => { - const {isTabletOrDesktop} = useWebMediaQueries() - - return StyleSheet.create({ - imageContainer: { - borderRadius: 100, - height: 150, - width: 150, - overflow: 'hidden', - borderWidth: 2, - alignItems: 'center', - justifyContent: 'center', - }, - paletteContainer: { - height: 70, - width: 70, - margin: isTabletOrDesktop ? 8 : 2, - }, - flatListOuter: isTabletOrDesktop - ? { - height: 435, - } - : { - flexDirection: 'row', - alignItems: 'center', - height: 100, - }, - flatListContainer: { - paddingHorizontal: 40, - }, - }) -} - -const commonFlatListProps: Partial> = {} diff --git a/src/screens/Onboarding/StepProfile/PlaceholderCanvas.tsx b/src/screens/Onboarding/StepProfile/PlaceholderCanvas.tsx index 83d96cb250..15a68520b6 100644 --- a/src/screens/Onboarding/StepProfile/PlaceholderCanvas.tsx +++ b/src/screens/Onboarding/StepProfile/PlaceholderCanvas.tsx @@ -1,7 +1,9 @@ import React from 'react' import {useAvatar} from '#/screens/Onboarding/StepProfile/index' import ViewShot from 'react-native-view-shot' -import {StyleSheet, View} from 'react-native' +import {View} from 'react-native' + +import {atoms as a} from '#/alf' export interface PlaceholderCanvasRef { capture: () => Promise @@ -15,6 +17,18 @@ export const PlaceholderCanvas = React.forwardRef( const viewshotRef = React.useRef() const Icon = avatar.placeholder.component + const styles = React.useMemo( + () => ({ + container: [a.absolute, {top: -2000}], + imageContainer: [ + a.align_center, + a.justify_center, + {height: 150 * 5, width: 150 * 5}, + ], + }), + [], + ) + React.useImperativeHandle(ref, () => ({ // @ts-ignore this library doesn't have types capture: viewshotRef.current.capture, @@ -43,16 +57,3 @@ export const PlaceholderCanvas = React.forwardRef( ) }, ) - -const styles = StyleSheet.create({ - container: { - top: -2000, - position: 'absolute', - }, - imageContainer: { - height: 150 * 5, - width: 150 * 5, - alignItems: 'center', - justifyContent: 'center', - }, -}) diff --git a/src/screens/Onboarding/StepProfile/index.tsx b/src/screens/Onboarding/StepProfile/index.tsx index 14deab35c9..f25ec78275 100644 --- a/src/screens/Onboarding/StepProfile/index.tsx +++ b/src/screens/Onboarding/StepProfile/index.tsx @@ -4,26 +4,25 @@ import {useLingui} from '@lingui/react' import {msg, Trans} from '@lingui/macro' import {atoms as a, useBreakpoints, useTheme} from '#/alf' -import {Button, ButtonText, ButtonIcon} from '#/components/Button' import {StreamingLive_Stroke2_Corner0_Rounded as StreamingLive} from '#/components/icons/StreamingLive' -import {useAnalytics} from '#/lib/analytics/analytics' - import {Context} from '#/screens/Onboarding/state' import { Title, Description, OnboardingControls, } from '#/screens/Onboarding/Layout' -import {ChevronRight_Stroke2_Corner0_Rounded as ChevronRight} from '#/components/icons/Chevron' -import {IconCircle} from '#/components/IconCircle' +import {AvatarCreatorItems} from '#/screens/Onboarding/StepProfile/AvatarCreatorItems' +import {AvatarCircle} from '#/screens/Onboarding/StepProfile/AvatarCircle' import {Emoji, emojiItems, AvatarColor, avatarColors} from './types' import { PlaceholderCanvas, PlaceholderCanvasRef, } from '#/screens/Onboarding/StepProfile/PlaceholderCanvas' +import {Button, ButtonText, ButtonIcon} from '#/components/Button' +import {ChevronRight_Stroke2_Corner0_Rounded as ChevronRight} from '#/components/icons/Chevron' +import {IconCircle} from '#/components/IconCircle' import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' -import {AvatarCircle} from '#/screens/Onboarding/StepProfile/AvatarCircle' -import {AvatarCreatorItems} from '#/screens/Onboarding/StepProfile/AvatarCreatorItems' +import {useAnalytics} from '#/lib/analytics/analytics' interface Avatar { image?: { @@ -64,7 +63,6 @@ export function StepProfile() { const onContinue = React.useCallback(async () => { let imageUri = avatar?.image?.path - let imageMime = avatar?.image?.mime if (!imageUri) { imageUri = await canvasRef.current?.capture() } @@ -73,7 +71,7 @@ export function StepProfile() { dispatch({ type: 'setProfileStepResults', imageUri, - imageMime: imageMime ?? 'image/jpeg', + imageMime: avatar.image?.mime ?? 'image/jpeg', }) } diff --git a/src/screens/Onboarding/state.ts b/src/screens/Onboarding/state.ts index aa09746cbb..caecdb794e 100644 --- a/src/screens/Onboarding/state.ts +++ b/src/screens/Onboarding/state.ts @@ -81,9 +81,8 @@ export type ApiResponseMap = { export const initialState: OnboardingState = { hasPrev: false, totalSteps: 8, - // activeStep: 'interests', // TODO revert this - activeStep: 'profile', - activeStepIndex: 7, + activeStep: 'interests', + activeStepIndex: 1, interestsStepResults: { selectedInterests: [],