···11import React from 'react'
22import {View} from 'react-native'
33-import ViewShot from 'react-native-view-shot'
33+import type ViewShot from 'react-native-view-shot'
4455import {useAvatar} from '#/screens/Onboarding/StepProfile/index'
66import {atoms as a} from '#/alf'
7788+const LazyViewShot = React.lazy(
99+ // @ts-expect-error dynamic import
1010+ () => import('react-native-view-shot/src/index'),
1111+)
1212+813const SIZE_MULTIPLIER = 5
9141015export interface PlaceholderCanvasRef {
1111- capture: () => Promise<string>
1616+ capture: () => Promise<string | undefined>
1217}
13181419// This component is supposed to be invisible to the user. We only need this for ViewShot to have something to
···1621export const PlaceholderCanvas = React.forwardRef<PlaceholderCanvasRef, {}>(
1722 function PlaceholderCanvas({}, ref) {
1823 const {avatar} = useAvatar()
1919- const viewshotRef = React.useRef()
2424+ const viewshotRef = React.useRef<ViewShot>(null)
2025 const Icon = avatar.placeholder.component
21262227 const styles = React.useMemo(
···3237 )
33383439 React.useImperativeHandle(ref, () => ({
3535- // @ts-ignore this library doesn't have types
3636- capture: viewshotRef.current.capture,
4040+ capture: async () => {
4141+ if (viewshotRef.current?.capture) {
4242+ return await viewshotRef.current.capture()
4343+ }
4444+ },
3745 }))
38463947 return (
4048 <View style={styles.container}>
4141- <ViewShot
4949+ <LazyViewShot
4250 // @ts-ignore this library doesn't have types
4351 ref={viewshotRef}
4452 options={{
···6068 style={{color: 'white'}}
6169 />
6270 </View>
6363- </ViewShot>
7171+ </LazyViewShot>
6472 </View>
6573 )
6674 },
+10-6
src/screens/Onboarding/StepProfile/index.tsx
···1010import {useLingui} from '@lingui/react'
11111212import {useAnalytics} from '#/lib/analytics/analytics'
1313+import {usePhotoLibraryPermission} from '#/lib/hooks/usePermissions'
1414+import {compressIfNeeded} from '#/lib/media/manip'
1515+import {openCropper} from '#/lib/media/picker'
1616+import {getDataUriSize} from '#/lib/media/util'
1717+import {useRequestNotificationsPermission} from '#/lib/notifications/notifications'
1318import {logEvent, useGate} from '#/lib/statsig/statsig'
1414-import {usePhotoLibraryPermission} from 'lib/hooks/usePermissions'
1515-import {compressIfNeeded} from 'lib/media/manip'
1616-import {openCropper} from 'lib/media/picker'
1717-import {getDataUriSize} from 'lib/media/util'
1818-import {useRequestNotificationsPermission} from 'lib/notifications/notifications'
1919-import {isNative, isWeb} from 'platform/detection'
1919+import {isNative, isWeb} from '#/platform/detection'
2020import {
2121 DescriptionText,
2222 OnboardingControls,
···132132133133 const onContinue = React.useCallback(async () => {
134134 let imageUri = avatar?.image?.path
135135+136136+ // In the event that view-shot didn't load in time and the user pressed continue, this will just be undefined
137137+ // and the default avatar will be used. We don't want to block getting through create if this fails for some
138138+ // reason
135139 if (!imageUri || avatar.useCreatedAvatar) {
136140 imageUri = await canvasRef.current?.capture()
137141 }
···66import type tldts from 'tldts'
7788import {logEvent} from '#/lib/statsig/statsig'
99+import {isEmailMaybeInvalid} from '#/lib/strings/email'
910import {logger} from '#/logger'
1010-import {isEmailMaybeInvalid} from 'lib/strings/email'
1111import {ScreenTransition} from '#/screens/Login/ScreenTransition'
1212import {is13, is18, useSignupContext} from '#/screens/Signup/state'
1313import {Policies} from '#/screens/Signup/StepInfo/Policies'
···5959 import('tldts/dist/index.cjs.min.js').then(tldts => {
6060 tldtsRef.current = tldts
6161 })
6262+ // This will get used in the avatar creator a few steps later, so lets preload it now
6363+ // @ts-expect-error - valid path
6464+ import('react-native-view-shot/src/index')
6265 }, [])
63666467 const onNextPress = () => {