organize imports and cleanup styles

This commit is contained in:
Hailey
2024-02-14 23:40:55 -08:00
parent ad50fe2b72
commit 1ecc5a7606
5 changed files with 93 additions and 112 deletions
@@ -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() {
<View>
<Image
source={avatar.image.path}
style={[styles.imageContainer, t.atoms.border_contrast_high]}
style={styles.imageContainer}
accessibilityIgnoresInvertColors
/>
<AvatarBottomButton onPress={onPressRemoveAvatar}>
@@ -105,14 +119,7 @@ export function AvatarCircle() {
return (
<View>
<View
style={[
styles.imageContainer,
t.atoms.border_contrast_high,
{
backgroundColor: avatar.backgroundColor,
},
]}>
<View style={styles.imageContainer}>
<Icon height={85} width={85} style={{color: t.palette.white}} />
</View>
<AvatarBottomButton onPress={onCameraPress}>
@@ -121,15 +128,3 @@ export function AvatarCircle() {
</View>
)
}
const styles = StyleSheet.create({
imageContainer: {
borderRadius: 100,
height: 150,
width: 150,
overflow: 'hidden',
borderWidth: 2,
alignItems: 'center',
justifyContent: 'center',
},
})
@@ -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<EmojiName>) {
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 (
<View style={styles.flatListOuter}>
<FlatList
<View
style={[
styles.flatListOuter,
isTabletOrDesktop && type === 'colors' && {width: 125},
]}>
<FlatList<any>
// 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}
/>
</View>
)
}
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<FlatListProps<any>> = {}
@@ -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<string>
@@ -15,6 +17,18 @@ export const PlaceholderCanvas = React.forwardRef<PlaceholderCanvasRef, {}>(
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<PlaceholderCanvasRef, {}>(
)
},
)
const styles = StyleSheet.create({
container: {
top: -2000,
position: 'absolute',
},
imageContainer: {
height: 150 * 5,
width: 150 * 5,
alignItems: 'center',
justifyContent: 'center',
},
})
+7 -9
View File
@@ -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',
})
}
+2 -3
View File
@@ -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: [],