import React from 'react' import { FlatList, FlatListProps, ListRenderItemInfo, Pressable, StyleSheet, View, } from 'react-native' 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 {Image} from 'expo-image' import {Emoji, EmojiName, emojiItems, emojiNames} from './types' import {SelectImageButton} from '#/screens/Onboarding/StepProfile/SelectImageButton' import { PlaceholderCanvas, PlaceholderCanvasRef, } from '#/screens/Onboarding/StepProfile/PlaceholderCanvas' import {Text} from '#/components/Typography' import {HITSLOP_10} from 'lib/constants' interface Avatar { image?: { path: string mime: string size: number width: number height: number } backgroundColor: Color placeholder: Emoji } const AvatarContext = React.createContext({} as Avatar) const SetAvatarContext = React.createContext< React.Dispatch> >({} as React.Dispatch>) export const useAvatar = () => React.useContext(AvatarContext) export const useSetAvatar = () => React.useContext(SetAvatarContext) export function StepProfile() { const {_} = useLingui() const t = useTheme() const {gtMobile} = useBreakpoints() const {track} = useAnalytics() const {state, dispatch} = React.useContext(Context) const [avatar, setAvatar] = React.useState({ placeholder: emojiItems.smile, backgroundColor: '#338388', }) const [uri, setUri] = React.useState('') const canvasRef = React.useRef(null) React.useEffect(() => { // TODO remove, this is for testing ;(async () => { const res = await canvasRef.current?.capture() if (res) { setUri(res) } })() }, [avatar]) React.useEffect(() => { track('OnboardingV2:StepProfile:Start') }, [track]) const onContinue = React.useCallback(async () => { let imageUri = avatar?.image?.path let imageMime = avatar?.image?.mime if (!imageUri) { imageUri = await canvasRef.current?.capture() } if (imageUri) { dispatch({ type: 'setProfileStepResults', imageUri, imageMime: imageMime ?? 'image/jpeg', }) } dispatch({type: 'next'}) track('OnboardingV2:StepProfile:End') }, [avatar?.image, dispatch, track]) return ( <> <Trans>Set your profile picture</Trans> Help people know you're not a bot by uploading a picture or creating an avatar! {/* TODO remove, testing */} ) } function AvatarCircle() { const t = useTheme() const avatar = useAvatar() const setAvatar = useSetAvatar() const Icon = avatar.placeholder.component const onPressRemoveAvatar = React.useCallback(() => { setAvatar(prev => ({ ...prev, image: undefined, })) }, [setAvatar]) if (avatar.image) { return ( {/* TODO Get a trash icon for alf */} x ) } return ( ) } const colors = [ '#338388', '#4ABFBD', '#8AB17D', '#E9C46A', '#F4A261', '#E76F51', ] as const type Color = (typeof colors)[number] function ColorItem({color}: {color: Color}) { const t = useTheme() const avatar = useAvatar() const setAvatar = useSetAvatar() const onPress = React.useCallback(() => { setAvatar(prev => ({ ...prev, backgroundColor: color, })) }, [color, setAvatar]) return ( ) } function colorRenderItem({item}: ListRenderItemInfo) { return } function EmojiItem({emojiName}: {emojiName: EmojiName}) { const t = useTheme() const avatar = useAvatar() const setAvatar = useSetAvatar() const Icon = emojiItems[emojiName].component const onPress = React.useCallback(() => { setAvatar(prev => ({ ...prev, placeholder: emojiItems[emojiName], })) }, [emojiName, setAvatar]) if (emojiName === 'camera') { return } return ( ) } function emojiRenderItem({item}: ListRenderItemInfo) { return } function Items({type}: {type: 'emojis' | 'colors'}) { if (type === 'colors') { return ( data={colors} renderItem={colorRenderItem} {...commonFlatListProps} /> ) } return ( data={emojiNames} renderItem={emojiRenderItem} {...commonFlatListProps} /> ) } const styles = StyleSheet.create({ imageContainer: { borderRadius: 100, height: 150, width: 150, overflow: 'hidden', borderWidth: 2, alignItems: 'center', justifyContent: 'center', }, paletteContainer: { height: 80, width: 80, marginHorizontal: 5, }, flatListOuter: { height: 100, }, flatListContainer: { paddingLeft: 40, paddingRight: 40, }, }) const commonFlatListProps: Partial> = { horizontal: true, contentContainerStyle: styles.flatListContainer, showsHorizontalScrollIndicator: false, }