UNPKG

stream-chat-react-native-core

Version:

The official React Native and Expo components for Stream Chat, a service for building chat applications

91 lines (78 loc) 3.4 kB
import { useCallback } from 'react'; import { Alert, Linking } from 'react-native'; import { useChannelEditDetailsContext } from '../../../contexts/channelEditDetailsContext/ChannelEditDetailsContext'; import { useTranslationContext } from '../../../contexts/translationContext/TranslationContext'; import { NativeHandlers } from '../../../native'; import type { File } from '../../../types/types'; import { compressedImageURI } from '../../../utils/compressImage'; export type UseEditChannelImageResult = { /** * Open the device's native image picker and return a single picked image * with the compression configured on `ChannelDetails` already applied * to its `uri`. Returns `undefined` if the user cancels or denies access. */ pickImageFromNativePicker: () => Promise<File | undefined>; /** * Launch the device's camera and return the captured image. Returns * `undefined` if the user cancels or denies access. The native camera * handler already honors `compressImageQuality`, so no extra compression * pass is needed for camera files. */ takePhoto: () => Promise<File | undefined>; }; /** * Hook that exposes the two image-acquisition flows used by the channel edit * screen — camera capture and native gallery pick — using the same control * flow and compression behavior as the message composer (`takeAndUploadImage` * and `pickAndUploadImageFromNativePicker` in `MessageInputContext`). The * hook intentionally does NOT upload the picked file; the consumer receives a * `File` and decides what to do with it. * * Reads `compressImageQuality` from `ChannelEditDetailsContext`. */ export const useEditChannelImage = (): UseEditChannelImageResult => { const { compressImageQuality } = useChannelEditDetailsContext(); const { t } = useTranslationContext(); const takePhoto = useCallback(async (): Promise<File | undefined> => { const file = await NativeHandlers.takePhoto({ compressImageQuality: compressImageQuality ?? 1, mediaType: 'image', }); if (file.askToOpenSettings) { Alert.alert( t('Allow camera access in device settings'), t('Device camera is used to take photos or videos.'), [ { style: 'cancel', text: t('Cancel') }, { onPress: () => Linking.openSettings(), style: 'default', text: t('Open Settings') }, ], ); return undefined; } if (file.cancelled) { return undefined; } return file; }, [compressImageQuality, t]); const pickImageFromNativePicker = useCallback(async (): Promise<File | undefined> => { const result = await NativeHandlers.pickImage({ maxNumberOfFiles: 1 }); if (result.askToOpenSettings) { Alert.alert( t('Allow access to your Gallery'), t('Device gallery permissions is used to take photos or videos.'), [ { style: 'cancel', text: t('Cancel') }, { onPress: () => Linking.openSettings(), style: 'default', text: t('Open Settings') }, ], ); return undefined; } if (result.cancelled || !result.assets?.length) { return undefined; } const asset = result.assets[0]; const compressedUri = await compressedImageURI(asset, compressImageQuality); return { ...asset, uri: compressedUri }; }, [compressImageQuality, t]); return { pickImageFromNativePicker, takePhoto }; };