From 713ace0d7c34d4adb13610e93e32b4f12502d1e1 Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Tue, 14 Oct 2025 14:07:44 +0100 Subject: [PATCH 1/9] feat: add attachment modal route for Share --- src/ROUTES.ts | 1 + src/SCREENS.ts | 1 + src/libs/AvatarUtils.ts | 17 ++++++- .../ModalStackNavigators/index.tsx | 3 ++ src/libs/Navigation/linkingConfig/config.ts | 1 + src/libs/Navigation/types.ts | 7 +++ src/pages/Share/ShareDetailsPage.tsx | 49 ++++++++++--------- .../AttachmentModalBaseContent/index.tsx | 6 +-- .../AttachmentModalContainer/index.tsx | 3 +- .../media/AttachmentModalScreen/index.tsx | 10 ++++ .../ShareDetailsAttachmentModalContent.tsx | 40 +++++++++++++++ .../media/AttachmentModalScreen/types.ts | 1 + .../workspace/tags/WorkspaceViewTagsPage.tsx | 2 +- 13 files changed, 109 insertions(+), 32 deletions(-) create mode 100644 src/pages/media/AttachmentModalScreen/routes/ShareDetailsAttachmentModalContent.tsx diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 57ae610d6680..360bc652514c 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -2377,6 +2377,7 @@ const ROUTES = { route: 'share/share-details/:reportOrAccountID', getRoute: (reportOrAccountID: string) => `share/share-details/${reportOrAccountID}` as const, }, + SHARE_DETAILS_ATTACHMENT: 'share/details/:reportOrAccountID/attachment', SHARE_SUBMIT_DETAILS: { route: 'share/submit-details/:reportOrAccountID', getRoute: (reportOrAccountID: string) => `share/submit-details/${reportOrAccountID}` as const, diff --git a/src/SCREENS.ts b/src/SCREENS.ts index 50cc539a859f..f81ab3622c7a 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -778,6 +778,7 @@ const SCREENS = { SHARE: { ROOT: 'Share_Root', SHARE_DETAILS: 'Share_Details', + SHARE_DETAILS_ATTACHMENT: 'Share_Details_Attachment', SUBMIT_DETAILS: 'Submit_Details', }, TRANSACTION_RECEIPT: 'TransactionReceipt', diff --git a/src/libs/AvatarUtils.ts b/src/libs/AvatarUtils.ts index 93080df42d1f..0cc33d2c5cdf 100644 --- a/src/libs/AvatarUtils.ts +++ b/src/libs/AvatarUtils.ts @@ -3,6 +3,8 @@ import CONST from '@src/CONST'; import type {TranslationPaths} from '@src/languages/types'; import {splitExtensionFromFileName, validateImageForCorruption} from './fileDownload/FileUtils'; import getImageResolution from './fileDownload/getImageResolution'; +import tryResolveUrlFromApiRoot from './tryResolveUrlFromApiRoot'; +import type {AvatarSource} from './UserUtils'; /** * Validation result containing error information if validation fails @@ -108,4 +110,17 @@ async function validateAvatarImage(image: FileObject): Promise return {isValid: true}; } -export {isValidExtension, isValidSize, isValidResolution, validateAvatarImage}; +function getValidatedImageSource(source: AvatarSource | undefined) { + const numberSource = Number(source); + if (numberSource !== 0) { + return numberSource; + } + + if (typeof source === 'string') { + return tryResolveUrlFromApiRoot(decodeURIComponent(source)); + } + + return undefined; +} + +export {isValidExtension, isValidSize, isValidResolution, validateAvatarImage, getValidatedImageSource}; diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx index 120151d88a2d..de1659fe014d 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx @@ -54,6 +54,8 @@ import SCREENS from '@src/SCREENS'; import type ReactComponentModule from '@src/types/utils/ReactComponentModule'; import useModalStackScreenOptions from './useModalStackScreenOptions'; +const loadAttachmentModalScreen = () => require('../../../../pages/media/AttachmentModalScreen').default; + type Screens = Partial React.ComponentType>>; const OPTIONS_PER_SCREEN: Partial> = { @@ -877,6 +879,7 @@ const RestrictedActionModalStackNavigator = createModalStackNavigator({ [SCREENS.SHARE.ROOT]: () => require('@pages/Share/ShareRootPage').default, [SCREENS.SHARE.SHARE_DETAILS]: () => require('@pages/Share/ShareDetailsPage').default, + [SCREENS.SHARE.SHARE_DETAILS_ATTACHMENT]: loadAttachmentModalScreen, [SCREENS.SHARE.SUBMIT_DETAILS]: () => require('@pages/Share/SubmitDetailsPage').default, }); diff --git a/src/libs/Navigation/linkingConfig/config.ts b/src/libs/Navigation/linkingConfig/config.ts index 18b0291478fd..27cc48c027ce 100644 --- a/src/libs/Navigation/linkingConfig/config.ts +++ b/src/libs/Navigation/linkingConfig/config.ts @@ -1848,6 +1848,7 @@ const config: LinkingOptions['config'] = { }, }, [SCREENS.SHARE.SHARE_DETAILS]: {path: ROUTES.SHARE_DETAILS.route}, + [SCREENS.SHARE.SHARE_DETAILS_ATTACHMENT]: {path: ROUTES.SHARE_DETAILS_ATTACHMENT}, [SCREENS.SHARE.SUBMIT_DETAILS]: {path: ROUTES.SHARE_SUBMIT_DETAILS.route}, }, }, diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index 0e44d8ad7d5f..8ea4153bcf21 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -2152,6 +2152,7 @@ type SharedScreensParamList = { type ShareNavigatorParamList = { [SCREENS.SHARE.ROOT]: undefined; [SCREENS.SHARE.SHARE_DETAILS]: {reportOrAccountID: string}; + [SCREENS.SHARE.SHARE_DETAILS_ATTACHMENT]: {reportOrAccountID: string}; [SCREENS.SHARE.SUBMIT_DETAILS]: {reportOrAccountID: string}; }; @@ -2230,6 +2231,12 @@ type AttachmentModalScreensParamList = { iouType: IOUType; readonly: string; }; + [SCREENS.SHARE.SHARE_DETAILS_ATTACHMENT]: AttachmentModalContainerModalProps & { + source?: AvatarSource; + fallbackSource?: AvatarSource; + originalFileName?: string; + headerTitle?: string; + }; }; type AuthScreensParamList = SharedScreensParamList & diff --git a/src/pages/Share/ShareDetailsPage.tsx b/src/pages/Share/ShareDetailsPage.tsx index faa42e5705d5..1eb40ab925ef 100644 --- a/src/pages/Share/ShareDetailsPage.tsx +++ b/src/pages/Share/ShareDetailsPage.tsx @@ -1,9 +1,8 @@ import type {StackScreenProps} from '@react-navigation/stack'; import reportsSelector from '@selectors/Attributes'; -import React, {useEffect, useMemo, useState} from 'react'; +import React, {useCallback, useContext, useEffect, useMemo, useState} from 'react'; import {SafeAreaView, View} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; -import AttachmentModal from '@components/AttachmentModal'; import AttachmentPreview from '@components/AttachmentPreview'; import Button from '@components/Button'; import FixedFooter from '@components/FixedFooter'; @@ -28,6 +27,7 @@ import {getReportDisplayOption} from '@libs/OptionsListUtils'; import {shouldValidateFile} from '@libs/ReceiptUtils'; import {getReportOrDraftReport, isDraftReport} from '@libs/ReportUtils'; import NotFoundPage from '@pages/ErrorPage/NotFoundPage'; +import AttachmentModalContext from '@pages/media/AttachmentModalScreen/AttachmentModalContext'; import variables from '@styles/variables'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -41,11 +41,9 @@ import {showErrorAlert} from './ShareRootPage'; type ShareDetailsPageProps = StackScreenProps; -function ShareDetailsPage({ - route: { - params: {reportOrAccountID}, - }, -}: ShareDetailsPageProps) { +function ShareDetailsPage({route}: ShareDetailsPageProps) { + const {reportOrAccountID} = route.params; + const styles = useThemeStyles(); const {translate} = useLocalize(); const [unknownUserDetails] = useOnyx(ONYXKEYS.SHARE_UNKNOWN_USER_DETAILS, {canBeMissing: true}); @@ -63,10 +61,22 @@ function ShareDetailsPage({ const report: OnyxEntry = getReportOrDraftReport(reportOrAccountID); const displayReport = useMemo(() => getReportDisplayOption(report, unknownUserDetails, reportAttributesDerived), [report, unknownUserDetails, reportAttributesDerived]); + const originalFileName = currentAttachment?.content.split('/').pop(); const fileSource = shouldUsePreValidatedFile ? (validatedFile?.uri ?? '') : (currentAttachment?.content ?? ''); const validateFileName = shouldUsePreValidatedFile ? getFileName(validatedFile?.uri ?? CONST.ATTACHMENT_IMAGE_DEFAULT_NAME) : getFileName(currentAttachment?.content ?? ''); const fileType = shouldUsePreValidatedFile ? (validatedFile?.type ?? CONST.SHARE_FILE_MIMETYPE.JPEG) : (currentAttachment?.mimeType ?? ''); + const reportAttachmentsContext = useContext(AttachmentModalContext); + const showAttachmentModalScreen = useCallback(() => { + reportAttachmentsContext.setCurrentAttachment({ + source: currentAttachment?.content, + headerTitle: originalFileName, + originalFileName, + fallbackSource: FallbackAvatar, + }); + Navigation.navigate(ROUTES.SHARE_DETAILS_ATTACHMENT); + }, [reportAttachmentsContext, currentAttachment?.content, originalFileName]); + useEffect(() => { if (!currentAttachment?.content || errorTitle) { return; @@ -204,23 +214,14 @@ function ShareDetailsPage({ {translate('common.attachment')} - - {({show}) => ( - { - showErrorAlert(translate('attachmentPicker.attachmentError'), translate('attachmentPicker.errorWhileSelectingCorruptedAttachment')); - }} - /> - )} - + { + showErrorAlert(translate('attachmentPicker.attachmentError'), translate('attachmentPicker.errorWhileSelectingCorruptedAttachment')); + }} + /> )} diff --git a/src/pages/media/AttachmentModalScreen/AttachmentModalBaseContent/index.tsx b/src/pages/media/AttachmentModalScreen/AttachmentModalBaseContent/index.tsx index 7dc066948e6d..711a3d7630cc 100644 --- a/src/pages/media/AttachmentModalScreen/AttachmentModalBaseContent/index.tsx +++ b/src/pages/media/AttachmentModalScreen/AttachmentModalBaseContent/index.tsx @@ -86,7 +86,7 @@ function AttachmentModalBaseContent({ const [currentAttachmentLink, setCurrentAttachmentLink] = useState(attachmentLink); const fallbackFile = useMemo(() => (originalFileName ? {name: originalFileName} : undefined), [originalFileName]); - const [files, setFilesInternal] = useState(); + const [files, setFilesInternal] = useState(() => filesProp ?? fallbackFile); const [isMultipleFiles, setIsMultipleFiles] = useState(() => Array.isArray(files)); const fileToDisplay = useMemo(() => { if (isMultipleFiles) { @@ -106,10 +106,6 @@ function AttachmentModalBaseContent({ }, []); useEffect(() => { - if (!filesProp) { - return; - } - setFile(filesProp ?? fallbackFile); }, [filesProp, fallbackFile, setFile]); diff --git a/src/pages/media/AttachmentModalScreen/AttachmentModalContainer/index.tsx b/src/pages/media/AttachmentModalScreen/AttachmentModalContainer/index.tsx index 30a0991123f6..3ec85b9211bc 100644 --- a/src/pages/media/AttachmentModalScreen/AttachmentModalContainer/index.tsx +++ b/src/pages/media/AttachmentModalScreen/AttachmentModalContainer/index.tsx @@ -27,7 +27,8 @@ function AttachmentModalContainer({ const closeModal = useCallback(() => { Navigation.dismissModal(); - }, []); + resetAttachmentModalAndClose(); + }, [resetAttachmentModalAndClose]); useEffect(() => { onShow?.(); diff --git a/src/pages/media/AttachmentModalScreen/index.tsx b/src/pages/media/AttachmentModalScreen/index.tsx index 749260326f9a..319201824506 100644 --- a/src/pages/media/AttachmentModalScreen/index.tsx +++ b/src/pages/media/AttachmentModalScreen/index.tsx @@ -5,6 +5,7 @@ import ProfileAvatarModalContent from './routes/ProfileAvatarModalContent'; import ReportAddAttachmentModalContent from './routes/report/ReportAddAttachmentModalContent'; import ReportAttachmentModalContent from './routes/ReportAttachmentModalContent'; import ReportAvatarModalContent from './routes/ReportAvatarModalContent'; +import ShareDetailsAttachmentModalContent from './routes/ShareDetailsAttachmentModalContent'; import TransactionReceiptModalContent from './routes/TransactionReceiptModalContent'; import WorkspaceAvatarModalContent from './routes/WorkspaceAvatarModalContent'; import type {AttachmentModalScreenProps, AttachmentModalScreenType} from './types'; @@ -81,6 +82,15 @@ function AttachmentModalScreen({route, ); } + if (route.name === SCREENS.SHARE.SHARE_DETAILS_ATTACHMENT) { + return ( + } + navigation={navigation as NavigationType} + /> + ); + } + return null; } diff --git a/src/pages/media/AttachmentModalScreen/routes/ShareDetailsAttachmentModalContent.tsx b/src/pages/media/AttachmentModalScreen/routes/ShareDetailsAttachmentModalContent.tsx new file mode 100644 index 000000000000..44bef34da6be --- /dev/null +++ b/src/pages/media/AttachmentModalScreen/routes/ShareDetailsAttachmentModalContent.tsx @@ -0,0 +1,40 @@ +import React, {useMemo} from 'react'; +import {getValidatedImageSource} from '@libs/AvatarUtils'; +import type {AttachmentModalBaseContentProps} from '@pages/media/AttachmentModalScreen/AttachmentModalBaseContent/types'; +import AttachmentModalContainer from '@pages/media/AttachmentModalScreen/AttachmentModalContainer'; +import type {AttachmentModalScreenProps} from '@pages/media/AttachmentModalScreen/types'; +import type SCREENS from '@src/SCREENS'; +import useDownloadAttachment from './hooks/useDownloadAttachment'; +import useReportAttachmentModalType from './hooks/useReportAttachmentModalType'; + +function ShareDetailsAttachmentModalContent({route, navigation}: AttachmentModalScreenProps) { + const {source: sourceParam, originalFileName, headerTitle, onShow, onClose} = route.params; + + const source = useMemo(() => getValidatedImageSource(sourceParam), [sourceParam]); + + const onDownloadAttachment = useDownloadAttachment({}); + + const contentProps = useMemo( + () => ({ + source: sourceParam, + originalFileName: originalFileName ?? '', + headerTitle, + onDownloadAttachment, + }), + [headerTitle, onDownloadAttachment, originalFileName, sourceParam], + ); + + const modalType = useReportAttachmentModalType(source); + return ( + + navigation={navigation} + contentProps={contentProps} + modalType={modalType} + onShow={onShow} + onClose={onClose} + /> + ); +} +ShareDetailsAttachmentModalContent.displayName = 'ReportAttachmentModalContent'; + +export default ShareDetailsAttachmentModalContent; diff --git a/src/pages/media/AttachmentModalScreen/types.ts b/src/pages/media/AttachmentModalScreen/types.ts index e383d298bc97..c00adab84716 100644 --- a/src/pages/media/AttachmentModalScreen/types.ts +++ b/src/pages/media/AttachmentModalScreen/types.ts @@ -46,6 +46,7 @@ const ATTACHMENT_MODAL_SCREENS = [ SCREENS.WORKSPACE_AVATAR, SCREENS.TRANSACTION_RECEIPT, SCREENS.MONEY_REQUEST.RECEIPT_PREVIEW, + SCREENS.SHARE.SHARE_DETAILS_ATTACHMENT, ]; type AttachmentModalScreenType = TupleToUnion; diff --git a/src/pages/workspace/tags/WorkspaceViewTagsPage.tsx b/src/pages/workspace/tags/WorkspaceViewTagsPage.tsx index cb1c69f8573c..78ab02f92bdb 100644 --- a/src/pages/workspace/tags/WorkspaceViewTagsPage.tsx +++ b/src/pages/workspace/tags/WorkspaceViewTagsPage.tsx @@ -131,7 +131,7 @@ function WorkspaceViewTagsPage({route}: WorkspaceViewTagsProps) { enabled: tag.enabled, isDisabled: tag.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE, rightElement: hasDependentTags ? ( - + ) : ( Date: Tue, 14 Oct 2025 15:07:11 +0100 Subject: [PATCH 2/9] fix: ShareDetailsAttachment screen type --- .../routes/ShareDetailsAttachmentModalContent.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/media/AttachmentModalScreen/routes/ShareDetailsAttachmentModalContent.tsx b/src/pages/media/AttachmentModalScreen/routes/ShareDetailsAttachmentModalContent.tsx index 44bef34da6be..d2eaf1d09450 100644 --- a/src/pages/media/AttachmentModalScreen/routes/ShareDetailsAttachmentModalContent.tsx +++ b/src/pages/media/AttachmentModalScreen/routes/ShareDetailsAttachmentModalContent.tsx @@ -7,7 +7,7 @@ import type SCREENS from '@src/SCREENS'; import useDownloadAttachment from './hooks/useDownloadAttachment'; import useReportAttachmentModalType from './hooks/useReportAttachmentModalType'; -function ShareDetailsAttachmentModalContent({route, navigation}: AttachmentModalScreenProps) { +function ShareDetailsAttachmentModalContent({route, navigation}: AttachmentModalScreenProps) { const {source: sourceParam, originalFileName, headerTitle, onShow, onClose} = route.params; const source = useMemo(() => getValidatedImageSource(sourceParam), [sourceParam]); @@ -26,7 +26,7 @@ function ShareDetailsAttachmentModalContent({route, navigation}: AttachmentModal const modalType = useReportAttachmentModalType(source); return ( - + navigation={navigation} contentProps={contentProps} modalType={modalType} From 8170ce7bea8341767235c46295f6448f1915a471 Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Tue, 14 Oct 2025 15:07:22 +0100 Subject: [PATCH 3/9] fix: use old source validation logic --- .../routes/ShareDetailsAttachmentModalContent.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/media/AttachmentModalScreen/routes/ShareDetailsAttachmentModalContent.tsx b/src/pages/media/AttachmentModalScreen/routes/ShareDetailsAttachmentModalContent.tsx index d2eaf1d09450..6177e30451a4 100644 --- a/src/pages/media/AttachmentModalScreen/routes/ShareDetailsAttachmentModalContent.tsx +++ b/src/pages/media/AttachmentModalScreen/routes/ShareDetailsAttachmentModalContent.tsx @@ -1,5 +1,5 @@ import React, {useMemo} from 'react'; -import {getValidatedImageSource} from '@libs/AvatarUtils'; +import tryResolveUrlFromApiRoot from '@libs/tryResolveUrlFromApiRoot'; import type {AttachmentModalBaseContentProps} from '@pages/media/AttachmentModalScreen/AttachmentModalBaseContent/types'; import AttachmentModalContainer from '@pages/media/AttachmentModalScreen/AttachmentModalContainer'; import type {AttachmentModalScreenProps} from '@pages/media/AttachmentModalScreen/types'; @@ -10,7 +10,7 @@ import useReportAttachmentModalType from './hooks/useReportAttachmentModalType'; function ShareDetailsAttachmentModalContent({route, navigation}: AttachmentModalScreenProps) { const {source: sourceParam, originalFileName, headerTitle, onShow, onClose} = route.params; - const source = useMemo(() => getValidatedImageSource(sourceParam), [sourceParam]); + const source = useMemo(() => Number(sourceParam) || (typeof sourceParam === 'string' ? tryResolveUrlFromApiRoot(decodeURIComponent(sourceParam)) : undefined), [sourceParam]); const onDownloadAttachment = useDownloadAttachment({}); From a7fb882cd95bba7b990ac3cfe2fce0868ddf76f7 Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Tue, 14 Oct 2025 15:11:34 +0100 Subject: [PATCH 4/9] revert: AvatarUtils changes --- src/libs/AvatarUtils.ts | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/src/libs/AvatarUtils.ts b/src/libs/AvatarUtils.ts index 0cc33d2c5cdf..93080df42d1f 100644 --- a/src/libs/AvatarUtils.ts +++ b/src/libs/AvatarUtils.ts @@ -3,8 +3,6 @@ import CONST from '@src/CONST'; import type {TranslationPaths} from '@src/languages/types'; import {splitExtensionFromFileName, validateImageForCorruption} from './fileDownload/FileUtils'; import getImageResolution from './fileDownload/getImageResolution'; -import tryResolveUrlFromApiRoot from './tryResolveUrlFromApiRoot'; -import type {AvatarSource} from './UserUtils'; /** * Validation result containing error information if validation fails @@ -110,17 +108,4 @@ async function validateAvatarImage(image: FileObject): Promise return {isValid: true}; } -function getValidatedImageSource(source: AvatarSource | undefined) { - const numberSource = Number(source); - if (numberSource !== 0) { - return numberSource; - } - - if (typeof source === 'string') { - return tryResolveUrlFromApiRoot(decodeURIComponent(source)); - } - - return undefined; -} - -export {isValidExtension, isValidSize, isValidResolution, validateAvatarImage, getValidatedImageSource}; +export {isValidExtension, isValidSize, isValidResolution, validateAvatarImage}; From b5877300b2f8fd2de2ba8756317ea246ca74f2aa Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Tue, 14 Oct 2025 15:53:03 +0100 Subject: [PATCH 5/9] refactor: extract variables --- .../routes/ShareDetailsAttachmentModalContent.tsx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/pages/media/AttachmentModalScreen/routes/ShareDetailsAttachmentModalContent.tsx b/src/pages/media/AttachmentModalScreen/routes/ShareDetailsAttachmentModalContent.tsx index 6177e30451a4..c162ce37ed85 100644 --- a/src/pages/media/AttachmentModalScreen/routes/ShareDetailsAttachmentModalContent.tsx +++ b/src/pages/media/AttachmentModalScreen/routes/ShareDetailsAttachmentModalContent.tsx @@ -8,20 +8,21 @@ import useDownloadAttachment from './hooks/useDownloadAttachment'; import useReportAttachmentModalType from './hooks/useReportAttachmentModalType'; function ShareDetailsAttachmentModalContent({route, navigation}: AttachmentModalScreenProps) { - const {source: sourceParam, originalFileName, headerTitle, onShow, onClose} = route.params; + const {source: sourceParam, originalFileName: originalFileNameParam, headerTitle, onShow, onClose} = route.params; const source = useMemo(() => Number(sourceParam) || (typeof sourceParam === 'string' ? tryResolveUrlFromApiRoot(decodeURIComponent(sourceParam)) : undefined), [sourceParam]); + const originalFileName = originalFileNameParam ?? ''; const onDownloadAttachment = useDownloadAttachment({}); const contentProps = useMemo( () => ({ - source: sourceParam, - originalFileName: originalFileName ?? '', + source, + originalFileName, headerTitle, onDownloadAttachment, }), - [headerTitle, onDownloadAttachment, originalFileName, sourceParam], + [headerTitle, onDownloadAttachment, originalFileName, source], ); const modalType = useReportAttachmentModalType(source); From 929b926319b431ced398ebd541aefeb568a19122 Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Wed, 15 Oct 2025 14:27:45 +0100 Subject: [PATCH 6/9] fix: use `validateFileName` like before --- src/pages/Share/ShareDetailsPage.tsx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/pages/Share/ShareDetailsPage.tsx b/src/pages/Share/ShareDetailsPage.tsx index 1eb40ab925ef..0e6bfdc3d333 100644 --- a/src/pages/Share/ShareDetailsPage.tsx +++ b/src/pages/Share/ShareDetailsPage.tsx @@ -61,7 +61,6 @@ function ShareDetailsPage({route}: ShareDetailsPageProps) { const report: OnyxEntry = getReportOrDraftReport(reportOrAccountID); const displayReport = useMemo(() => getReportDisplayOption(report, unknownUserDetails, reportAttributesDerived), [report, unknownUserDetails, reportAttributesDerived]); - const originalFileName = currentAttachment?.content.split('/').pop(); const fileSource = shouldUsePreValidatedFile ? (validatedFile?.uri ?? '') : (currentAttachment?.content ?? ''); const validateFileName = shouldUsePreValidatedFile ? getFileName(validatedFile?.uri ?? CONST.ATTACHMENT_IMAGE_DEFAULT_NAME) : getFileName(currentAttachment?.content ?? ''); const fileType = shouldUsePreValidatedFile ? (validatedFile?.type ?? CONST.SHARE_FILE_MIMETYPE.JPEG) : (currentAttachment?.mimeType ?? ''); @@ -70,12 +69,12 @@ function ShareDetailsPage({route}: ShareDetailsPageProps) { const showAttachmentModalScreen = useCallback(() => { reportAttachmentsContext.setCurrentAttachment({ source: currentAttachment?.content, - headerTitle: originalFileName, - originalFileName, + headerTitle: validateFileName, + originalFileName: validateFileName, fallbackSource: FallbackAvatar, }); Navigation.navigate(ROUTES.SHARE_DETAILS_ATTACHMENT); - }, [reportAttachmentsContext, currentAttachment?.content, originalFileName]); + }, [reportAttachmentsContext, currentAttachment?.content, validateFileName]); useEffect(() => { if (!currentAttachment?.content || errorTitle) { From 1e0abd298fbb6083f9bd7df1d755e42c05c79686 Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Fri, 7 Nov 2025 22:20:36 +0000 Subject: [PATCH 7/9] fix: invalid source prop --- src/pages/Share/ShareDetailsPage.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/Share/ShareDetailsPage.tsx b/src/pages/Share/ShareDetailsPage.tsx index 0e6bfdc3d333..184c1acd16f2 100644 --- a/src/pages/Share/ShareDetailsPage.tsx +++ b/src/pages/Share/ShareDetailsPage.tsx @@ -68,13 +68,13 @@ function ShareDetailsPage({route}: ShareDetailsPageProps) { const reportAttachmentsContext = useContext(AttachmentModalContext); const showAttachmentModalScreen = useCallback(() => { reportAttachmentsContext.setCurrentAttachment({ - source: currentAttachment?.content, + source: fileSource, headerTitle: validateFileName, originalFileName: validateFileName, fallbackSource: FallbackAvatar, }); Navigation.navigate(ROUTES.SHARE_DETAILS_ATTACHMENT); - }, [reportAttachmentsContext, currentAttachment?.content, validateFileName]); + }, [reportAttachmentsContext, fileSource, validateFileName]); useEffect(() => { if (!currentAttachment?.content || errorTitle) { From 59fd83f30cf034d9ca02f3f9a3caf73645c13824 Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Fri, 7 Nov 2025 22:31:20 +0000 Subject: [PATCH 8/9] fix: remove unnecessary `SafeAreaView` --- src/pages/Share/ShareDetailsPage.tsx | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/pages/Share/ShareDetailsPage.tsx b/src/pages/Share/ShareDetailsPage.tsx index 184c1acd16f2..579aa7ac14b4 100644 --- a/src/pages/Share/ShareDetailsPage.tsx +++ b/src/pages/Share/ShareDetailsPage.tsx @@ -1,7 +1,7 @@ import type {StackScreenProps} from '@react-navigation/stack'; import reportsSelector from '@selectors/Attributes'; import React, {useCallback, useContext, useEffect, useMemo, useState} from 'react'; -import {SafeAreaView, View} from 'react-native'; +import {View} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; import AttachmentPreview from '@components/AttachmentPreview'; import Button from '@components/Button'; @@ -17,6 +17,7 @@ import TextInput from '@components/TextInput'; import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; +import useSafeAreaInsets from '@hooks/useSafeAreaInsets'; import useThemeStyles from '@hooks/useThemeStyles'; import {addAttachmentWithComment, addComment, getCurrentUserAccountID, openReport} from '@libs/actions/Report'; import {canUseTouchScreen} from '@libs/DeviceCapabilities'; @@ -212,16 +213,14 @@ function ShareDetailsPage({route}: ShareDetailsPageProps) { {translate('common.attachment')} - - { - showErrorAlert(translate('attachmentPicker.attachmentError'), translate('attachmentPicker.errorWhileSelectingCorruptedAttachment')); - }} - /> - + { + showErrorAlert(translate('attachmentPicker.attachmentError'), translate('attachmentPicker.errorWhileSelectingCorruptedAttachment')); + }} + /> )} From 2e66016b7bd7c4fda5534bbf72f01d5c7aeb51cf Mon Sep 17 00:00:00 2001 From: Christoph Pader Date: Fri, 7 Nov 2025 22:32:06 +0000 Subject: [PATCH 9/9] remove unused input --- src/pages/Share/ShareDetailsPage.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/Share/ShareDetailsPage.tsx b/src/pages/Share/ShareDetailsPage.tsx index 579aa7ac14b4..1ea715172b17 100644 --- a/src/pages/Share/ShareDetailsPage.tsx +++ b/src/pages/Share/ShareDetailsPage.tsx @@ -17,7 +17,6 @@ import TextInput from '@components/TextInput'; import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; -import useSafeAreaInsets from '@hooks/useSafeAreaInsets'; import useThemeStyles from '@hooks/useThemeStyles'; import {addAttachmentWithComment, addComment, getCurrentUserAccountID, openReport} from '@libs/actions/Report'; import {canUseTouchScreen} from '@libs/DeviceCapabilities';