diff --git a/src/components/Attachments/AttachmentCarousel/index.native.tsx b/src/components/Attachments/AttachmentCarousel/index.native.tsx index 7d08aa0c7153..a8eb614202a7 100644 --- a/src/components/Attachments/AttachmentCarousel/index.native.tsx +++ b/src/components/Attachments/AttachmentCarousel/index.native.tsx @@ -1,6 +1,6 @@ import React, {useCallback, useEffect, useRef, useState} from 'react'; import {Keyboard, View} from 'react-native'; -import {withOnyx} from 'react-native-onyx'; +import {useOnyx} from 'react-native-onyx'; import type {Attachment, AttachmentSource} from '@components/Attachments/types'; import BlockingView from '@components/BlockingViews/BlockingView'; import FullScreenLoadingIndicator from '@components/FullscreenLoadingIndicator'; @@ -15,47 +15,55 @@ import CarouselButtons from './CarouselButtons'; import extractAttachments from './extractAttachments'; import type {AttachmentCarouselPagerHandle} from './Pager'; import AttachmentCarouselPager from './Pager'; -import type {AttachmentCaraouselOnyxProps, AttachmentCarouselProps} from './types'; +import type {AttachmentCarouselProps} from './types'; import useCarouselArrows from './useCarouselArrows'; -function AttachmentCarousel({report, reportActions, parentReportActions, source, onNavigate, setDownloadButtonVisibility, onClose, type, accountID}: AttachmentCarouselProps) { +function AttachmentCarousel({report, source, onNavigate, setDownloadButtonVisibility, onClose, type, accountID}: AttachmentCarouselProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); const pagerRef = useRef(null); + const [parentReportActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`, {canEvict: false}); + const [reportActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.reportID}`, {canEvict: false}); const [page, setPage] = useState(); const [attachments, setAttachments] = useState([]); const {shouldShowArrows, setShouldShowArrows, autoHideArrows, cancelAutoHideArrows} = useCarouselArrows(); const [activeSource, setActiveSource] = useState(source); - const compareImage = useCallback((attachment: Attachment) => attachment.source === source, [source]); useEffect(() => { const parentReportAction = report.parentReportActionID && parentReportActions ? parentReportActions[report.parentReportActionID] : undefined; - let targetAttachments: Attachment[] = []; + let newAttachments: Attachment[] = []; if (type === CONST.ATTACHMENT_TYPE.NOTE && accountID) { - targetAttachments = extractAttachments(CONST.ATTACHMENT_TYPE.NOTE, {privateNotes: report.privateNotes, accountID}); + newAttachments = extractAttachments(CONST.ATTACHMENT_TYPE.NOTE, {privateNotes: report.privateNotes, accountID}); } else { - targetAttachments = extractAttachments(CONST.ATTACHMENT_TYPE.REPORT, {parentReportAction, reportActions}); + newAttachments = extractAttachments(CONST.ATTACHMENT_TYPE.REPORT, {parentReportAction, reportActions}); } - const initialPage = targetAttachments.findIndex(compareImage); + let newIndex = newAttachments.findIndex(compareImage); + const index = attachments.findIndex(compareImage); + + // If newAttachments includes an attachment with the same index, update newIndex to that index. + // Previously, uploading an attachment offline would dismiss the modal when the image was previewed and the connection was restored. + // Now, instead of dismissing the modal, we replace it with the new attachment that has the same index. + if (newIndex === -1 && index !== -1 && newAttachments.at(index)) { + newIndex = index; + } - // Dismiss the modal when deleting an attachment during its display in preview. - if (initialPage === -1 && attachments.find(compareImage)) { + // If no matching attachment with the same index, dismiss the modal + if (newIndex === -1 && index !== -1 && attachments.at(index)) { Navigation.dismissModal(); } else { - setPage(initialPage); - setAttachments(targetAttachments); + setPage(newIndex); + setAttachments(newAttachments); // Update the download button visibility in the parent modal if (setDownloadButtonVisibility) { - setDownloadButtonVisibility(initialPage !== -1); + setDownloadButtonVisibility(newIndex !== -1); } - const attachment = targetAttachments.at(initialPage); - + const attachment = newAttachments.at(newIndex); // Update the parent modal's state with the source and name from the mapped attachments - if (initialPage !== -1 && attachment !== undefined && onNavigate) { + if (newIndex !== -1 && attachment !== undefined && onNavigate) { onNavigate(attachment); } } @@ -148,13 +156,4 @@ function AttachmentCarousel({report, reportActions, parentReportActions, source, AttachmentCarousel.displayName = 'AttachmentCarousel'; -export default withOnyx({ - parentReportActions: { - key: ({report}) => `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`, - canEvict: false, - }, - reportActions: { - key: ({report}) => `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.reportID}`, - canEvict: false, - }, -})(AttachmentCarousel); +export default AttachmentCarousel; diff --git a/src/components/Attachments/AttachmentCarousel/index.tsx b/src/components/Attachments/AttachmentCarousel/index.tsx index 62159725854d..a1408aaf400e 100644 --- a/src/components/Attachments/AttachmentCarousel/index.tsx +++ b/src/components/Attachments/AttachmentCarousel/index.tsx @@ -5,7 +5,7 @@ import type {ListRenderItemInfo} from 'react-native'; import {Keyboard, PixelRatio, View} from 'react-native'; import type {GestureType} from 'react-native-gesture-handler'; import {Gesture, GestureDetector} from 'react-native-gesture-handler'; -import {withOnyx} from 'react-native-onyx'; +import {useOnyx} from 'react-native-onyx'; import Animated, {scrollTo, useAnimatedRef, useSharedValue} from 'react-native-reanimated'; import type {Attachment, AttachmentSource} from '@components/Attachments/types'; import BlockingView from '@components/BlockingViews/BlockingView'; @@ -26,7 +26,7 @@ import CarouselButtons from './CarouselButtons'; import CarouselItem from './CarouselItem'; import extractAttachments from './extractAttachments'; import AttachmentCarouselPagerContext from './Pager/AttachmentCarouselPagerContext'; -import type {AttachmentCaraouselOnyxProps, AttachmentCarouselProps, UpdatePageProps} from './types'; +import type {AttachmentCarouselProps, UpdatePageProps} from './types'; import useCarouselArrows from './useCarouselArrows'; import useCarouselContextEvents from './useCarouselContextEvents'; @@ -38,7 +38,7 @@ const viewabilityConfig = { const MIN_FLING_VELOCITY = 500; -function AttachmentCarousel({report, reportActions, parentReportActions, source, onNavigate, setDownloadButtonVisibility, type, accountID, onClose}: AttachmentCarouselProps) { +function AttachmentCarousel({report, source, onNavigate, setDownloadButtonVisibility, type, accountID, onClose}: AttachmentCarouselProps) { const theme = useTheme(); const {translate} = useLocalize(); const {windowWidth} = useWindowDimensions(); @@ -48,7 +48,8 @@ function AttachmentCarousel({report, reportActions, parentReportActions, source, const scrollRef = useAnimatedRef>>(); const nope = useSharedValue(false); const pagerRef = useRef(null); - + const [parentReportActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`, {canEvict: false}); + const [reportActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.reportID}`, {canEvict: false}); const canUseTouchScreen = DeviceCapabilities.canUseTouchScreen(); const modalStyles = styles.centeredModalStyles(shouldUseNarrowLayout, true); @@ -73,14 +74,14 @@ function AttachmentCarousel({report, reportActions, parentReportActions, source, useEffect(() => { const parentReportAction = report.parentReportActionID && parentReportActions ? parentReportActions[report.parentReportActionID] : undefined; - let targetAttachments: Attachment[] = []; + let newAttachments: Attachment[] = []; if (type === CONST.ATTACHMENT_TYPE.NOTE && accountID) { - targetAttachments = extractAttachments(CONST.ATTACHMENT_TYPE.NOTE, {privateNotes: report.privateNotes, accountID}); + newAttachments = extractAttachments(CONST.ATTACHMENT_TYPE.NOTE, {privateNotes: report.privateNotes, accountID}); } else { - targetAttachments = extractAttachments(CONST.ATTACHMENT_TYPE.REPORT, {parentReportAction, reportActions: reportActions ?? undefined}); + newAttachments = extractAttachments(CONST.ATTACHMENT_TYPE.REPORT, {parentReportAction, reportActions: reportActions ?? undefined}); } - if (isEqual(attachments, targetAttachments)) { + if (isEqual(attachments, newAttachments)) { if (attachments.length === 0) { setPage(-1); setDownloadButtonVisibility?.(false); @@ -88,23 +89,31 @@ function AttachmentCarousel({report, reportActions, parentReportActions, source, return; } - const initialPage = targetAttachments.findIndex(compareImage); + let newIndex = newAttachments.findIndex(compareImage); + const index = attachments.findIndex(compareImage); + + // If newAttachments includes an attachment with the same index, update newIndex to that index. + // Previously, uploading an attachment offline would dismiss the modal when the image was previewed and the connection was restored. + // Now, instead of dismissing the modal, we replace it with the new attachment that has the same index. + if (newIndex === -1 && index !== -1 && newAttachments.at(index)) { + newIndex = index; + } - // Dismiss the modal when deleting an attachment during its display in preview. - if (initialPage === -1 && attachments.find(compareImage)) { + // If no matching attachment with the same index, dismiss the modal + if (newIndex === -1 && index !== -1 && attachments.at(index)) { Navigation.dismissModal(); } else { - setPage(initialPage); - setAttachments(targetAttachments); + setPage(newIndex); + setAttachments(newAttachments); // Update the download button visibility in the parent modal if (setDownloadButtonVisibility) { - setDownloadButtonVisibility(initialPage !== -1); + setDownloadButtonVisibility(newIndex !== -1); } - const attachment = targetAttachments.at(initialPage); + const attachment = newAttachments.at(newIndex); // Update the parent modal's state with the source and name from the mapped attachments - if (initialPage !== -1 && attachment !== undefined && onNavigate) { + if (newIndex !== -1 && attachment !== undefined && onNavigate) { onNavigate(attachment); } } @@ -307,13 +316,4 @@ function AttachmentCarousel({report, reportActions, parentReportActions, source, AttachmentCarousel.displayName = 'AttachmentCarousel'; -export default withOnyx({ - parentReportActions: { - key: ({report}) => `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`, - canEvict: false, - }, - reportActions: { - key: ({report}) => `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.reportID}`, - canEvict: false, - }, -})(AttachmentCarousel); +export default AttachmentCarousel; diff --git a/src/components/Attachments/AttachmentCarousel/types.ts b/src/components/Attachments/AttachmentCarousel/types.ts index d31ebbd328cd..c77e7b0f79d5 100644 --- a/src/components/Attachments/AttachmentCarousel/types.ts +++ b/src/components/Attachments/AttachmentCarousel/types.ts @@ -1,23 +1,14 @@ import type {ViewToken} from 'react-native'; -import type {OnyxEntry} from 'react-native-onyx'; import type {ValueOf} from 'type-fest'; import type {Attachment, AttachmentSource} from '@components/Attachments/types'; import type CONST from '@src/CONST'; -import type {Report, ReportActions} from '@src/types/onyx'; +import type {Report} from '@src/types/onyx'; type UpdatePageProps = { viewableItems: ViewToken[]; }; -type AttachmentCaraouselOnyxProps = { - /** Object of report actions for this report */ - reportActions: OnyxEntry; - - /** The report actions of the parent report */ - parentReportActions: OnyxEntry; -}; - -type AttachmentCarouselProps = AttachmentCaraouselOnyxProps & { +type AttachmentCarouselProps = { /** Source is used to determine the starting index in the array of attachments */ source: AttachmentSource; @@ -40,4 +31,4 @@ type AttachmentCarouselProps = AttachmentCaraouselOnyxProps & { onClose: () => void; }; -export type {AttachmentCarouselProps, UpdatePageProps, AttachmentCaraouselOnyxProps}; +export type {AttachmentCarouselProps, UpdatePageProps};