import {useCallback, useState} from 'react' import {Keyboard, Pressable, View} from 'react-native' import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' import {useOpenComposer} from '#/lib/hooks/useOpenComposer' import { useCameraPermission, usePhotoLibraryPermission, useVideoLibraryPermission, } from '#/lib/hooks/usePermissions' import {openCamera, openUnifiedPicker} from '#/lib/media/picker' import {useCurrentAccountProfile} from '#/state/queries/useCurrentAccountProfile' import {MAX_IMAGES} from '#/view/com/composer/state/composer' import {UserAvatar} from '#/view/com/util/UserAvatar' import {atoms as a, native, useTheme, web} from '#/alf' import {Button} from '#/components/Button' import {useSheetWrapper} from '#/components/Dialog/sheet-wrapper' import {Camera_Stroke2_Corner0_Rounded as CameraIcon} from '#/components/icons/Camera' import {Image_Stroke2_Corner0_Rounded as ImageIcon} from '#/components/icons/Image' import {SubtleHover} from '#/components/SubtleHover' import {Text} from '#/components/Typography' import {useAnalytics} from '#/analytics' import {IS_NATIVE} from '#/env' export function ComposerPrompt() { const t = useTheme() const ax = useAnalytics() const {_} = useLingui() const {openComposer} = useOpenComposer() const profile = useCurrentAccountProfile() const [hover, setHover] = useState(false) const {requestCameraAccessIfNeeded} = useCameraPermission() const {requestPhotoAccessIfNeeded} = usePhotoLibraryPermission() const {requestVideoAccessIfNeeded} = useVideoLibraryPermission() const sheetWrapper = useSheetWrapper() const onPress = useCallback(() => { ax.metric('composerPrompt:press', {}) openComposer({}) }, [ax, openComposer]) const onPressImage = useCallback(async () => { ax.metric('composerPrompt:gallery:press', {}) // On web, open the composer with the gallery picker auto-opening if (!IS_NATIVE) { openComposer({openGallery: true}) return } try { const [photoAccess, videoAccess] = await Promise.all([ requestPhotoAccessIfNeeded(), requestVideoAccessIfNeeded(), ]) if (!photoAccess && !videoAccess) { return } if (Keyboard.isVisible()) { Keyboard.dismiss() } const selectionCountRemaining = MAX_IMAGES const {assets, canceled} = await sheetWrapper( openUnifiedPicker({selectionCountRemaining}), ) if (canceled) { return } if (assets.length > 0) { const imageUris = assets .filter(asset => asset.mimeType?.startsWith('image/')) .slice(0, MAX_IMAGES) .map(asset => ({ uri: asset.uri, width: asset.width, height: asset.height, })) if (imageUris.length > 0) { openComposer({imageUris}) } } } catch (err: any) { if (!String(err).toLowerCase().includes('cancel')) { ax.logger.error('Error opening image picker', {error: err}) } } }, [ ax, openComposer, requestPhotoAccessIfNeeded, requestVideoAccessIfNeeded, sheetWrapper, ]) const onPressCamera = useCallback(async () => { ax.metric('composerPrompt:camera:press', {}) try { if (!(await requestCameraAccessIfNeeded())) { return } if (IS_NATIVE && Keyboard.isVisible()) { Keyboard.dismiss() } const image = await openCamera({ mediaTypes: 'images', }) const imageUris = [ { uri: image.path, width: image.width, height: image.height, }, ] openComposer({ imageUris: IS_NATIVE ? imageUris : undefined, }) } catch (err: any) { if (!String(err).toLowerCase().includes('cancel')) { ax.logger.error('Error opening camera', {error: err}) } } }, [ax, openComposer, requestCameraAccessIfNeeded]) if (!profile) { return null } return ( setHover(true)} onPointerLeave={() => setHover(false)} style={({pressed}) => [ a.relative, a.flex_row, a.align_start, { paddingLeft: 18, paddingRight: 15, }, a.py_md, native({ paddingTop: 10, paddingBottom: 10, }), web({ cursor: 'pointer', outline: 'none', }), pressed && web({outline: 'none'}), ]}> What's up? {IS_NATIVE && ( )} ) }