diff --git a/src/pages/NewChatConfirmPage.tsx b/src/pages/NewChatConfirmPage.tsx index 2c94dbbc7840..78e28cda332f 100644 --- a/src/pages/NewChatConfirmPage.tsx +++ b/src/pages/NewChatConfirmPage.tsx @@ -1,4 +1,4 @@ -import React, {useCallback, useMemo, useRef} from 'react'; +import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react'; import {View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import type {OnyxEntry} from 'react-native-onyx'; @@ -15,6 +15,7 @@ import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails' import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import type {CustomRNImageManipulatorResult} from '@libs/cropOrRotateImage/types'; +import * as FileUtils from '@libs/fileDownload/FileUtils'; import Navigation from '@libs/Navigation/Navigation'; import * as OptionsListUtils from '@libs/OptionsListUtils'; import * as ReportUtils from '@libs/ReportUtils'; @@ -45,7 +46,7 @@ function navigateToEditChatName() { function NewChatConfirmPage({newGroupDraft, allPersonalDetails}: NewChatConfirmPageProps) { const optimisticReportID = useRef(ReportUtils.generateReportID()); - const fileRef = useRef(); + const [avatarFile, setAvatarFile] = useState(); const {translate} = useLocalize(); const styles = useThemeStyles(); const personalData = useCurrentUserPersonalDetails(); @@ -104,10 +105,33 @@ function NewChatConfirmPage({newGroupDraft, allPersonalDetails}: NewChatConfirmP } const logins: string[] = (newGroupDraft.participants ?? []).map((participant) => participant.login); - Report.navigateToAndOpenReport(logins, true, newGroupDraft.reportName ?? '', newGroupDraft.avatarUri ?? '', fileRef.current, optimisticReportID.current, true); - }, [newGroupDraft]); + Report.navigateToAndOpenReport(logins, true, newGroupDraft.reportName ?? '', newGroupDraft.avatarUri ?? '', avatarFile, optimisticReportID.current, true); + }, [newGroupDraft, avatarFile]); const stashedLocalAvatarImage = newGroupDraft?.avatarUri; + + useEffect(() => { + if (!stashedLocalAvatarImage) { + return; + } + + const onSuccess = (file: File) => { + setAvatarFile(file); + }; + + const onFailure = () => { + setAvatarFile(undefined); + Report.setGroupDraft({avatarUri: null, avatarFileName: null, avatarFileType: null}); + }; + + // If the user navigates back to the member selection page and then returns to the confirmation page, the component will re-mount, causing avatarFile to be null. + // To handle this, we re-read the avatar image file from disk whenever the component re-mounts. + FileUtils.readFileAsync(stashedLocalAvatarImage, newGroupDraft?.avatarFileName ?? '', onSuccess, onFailure, newGroupDraft?.avatarFileType ?? ''); + + // we only need to run this when the component re-mounted + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + return ( { - fileRef.current = image; - Report.setGroupDraft({avatarUri: image?.uri ?? ''}); + setAvatarFile(image); + Report.setGroupDraft({avatarUri: image.uri ?? '', avatarFileName: image.name ?? '', avatarFileType: image.type}); }} onImageRemoved={() => { - fileRef.current = undefined; - Report.setGroupDraft({avatarUri: null}); + setAvatarFile(undefined); + Report.setGroupDraft({avatarUri: null, avatarFileName: null, avatarFileType: null}); }} size={CONST.AVATAR_SIZE.XLARGE} avatarStyle={styles.avatarXLarge} diff --git a/src/types/onyx/NewGroupChatDraft.ts b/src/types/onyx/NewGroupChatDraft.ts index 9e4ad3c54299..e075ed6e5e33 100644 --- a/src/types/onyx/NewGroupChatDraft.ts +++ b/src/types/onyx/NewGroupChatDraft.ts @@ -17,6 +17,12 @@ type NewGroupChatDraft = { /** New group chat avatar URI */ avatarUri: string | null; + + /** New group chat avatar file name */ + avatarFileName: string | null; + + /** New group chat avatar file type */ + avatarFileType: string | null; }; export type {SelectedParticipant}; export default NewGroupChatDraft;