From f53d3dc87670ad6adabd87cc8e2a1ef10729f1a0 Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Tue, 15 Aug 2023 12:49:38 +0800 Subject: [PATCH 01/22] hide flagged attachment in carousel --- .../AttachmentCarousel/CarouselItem.js | 83 +++++++++++++++++++ .../extractAttachmentsFromReport.js | 6 +- .../Attachments/AttachmentCarousel/index.js | 10 +-- .../AttachmentCarousel/index.native.js | 11 +-- 4 files changed, 96 insertions(+), 14 deletions(-) create mode 100644 src/components/Attachments/AttachmentCarousel/CarouselItem.js diff --git a/src/components/Attachments/AttachmentCarousel/CarouselItem.js b/src/components/Attachments/AttachmentCarousel/CarouselItem.js new file mode 100644 index 000000000000..6b3056f134df --- /dev/null +++ b/src/components/Attachments/AttachmentCarousel/CarouselItem.js @@ -0,0 +1,83 @@ +import React, {useState, useEffect} from 'react'; +import PropTypes from 'prop-types'; +import CONST from '../../../CONST'; +import styles from '../../../styles/styles'; +import useLocalize from '../../../hooks/useLocalize'; +import PressableWithoutFeedback from '../../Pressable/PressableWithoutFeedback'; +import Text from '../../Text'; +import Button from '../../Button'; +import AttachmentView from '../AttachmentView'; + +const propTypes = { + /** Attachment required information such as the source and file name */ + item: PropTypes.shape({ + isAuthTokenRequired: PropTypes.bool, + source: PropTypes.string, + file: PropTypes.shape({name: PropTypes.string}), + isHidden: PropTypes.bool, + }).isRequired, + + /** Whether the attachment is currently being viewed in the carousel */ + isFocused: PropTypes.bool.isRequired, + + /** onPress callback */ + onPress: PropTypes.func, +}; + +const defaultProps = { + onPress: () => {}, +}; + +function CarouselItem({item, isFocused, onPress}) { + const {translate} = useLocalize(); + const [isHidden, setIsHidden] = useState(item.isHidden); + + useEffect(() => { + if (isFocused) { + return; + } + // When the attachment is out of focus, we want to hide the attachment back + setIsHidden(item.isHidden); + }, [isFocused, item.isHidden]); + + if (isHidden) { + return ( + + {translate('moderation.flaggedContent')} + + + ); + } + + return ( + + ); +} + +CarouselItem.propTypes = propTypes; +CarouselItem.defaultProps = defaultProps; + +export default CarouselItem; diff --git a/src/components/Attachments/AttachmentCarousel/extractAttachmentsFromReport.js b/src/components/Attachments/AttachmentCarousel/extractAttachmentsFromReport.js index 047a016674b7..05a0454540a0 100644 --- a/src/components/Attachments/AttachmentCarousel/extractAttachmentsFromReport.js +++ b/src/components/Attachments/AttachmentCarousel/extractAttachmentsFromReport.js @@ -30,6 +30,7 @@ function extractAttachmentsFromReport(report, reportActions, source) { source: tryResolveUrlFromApiRoot(expensifySource || attribs.src), isAuthTokenRequired: Boolean(expensifySource), file: {name: attribs[CONST.ATTACHMENT_ORIGINAL_FILENAME_ATTRIBUTE]}, + isHidden: attribs['data-hidden'] === 'true', }); }, }); @@ -38,7 +39,10 @@ function extractAttachmentsFromReport(report, reportActions, source) { if (!ReportActionsUtils.shouldReportActionBeVisible(action, key)) { return; } - htmlParser.write(_.get(action, ['message', 0, 'html'])); + const decision = _.get(action, ['message', 0, 'moderationDecision', 'decision'], ''); + const isHidden = decision === CONST.MODERATION.MODERATOR_DECISION_PENDING_HIDE || decision === CONST.MODERATION.MODERATOR_DECISION_HIDDEN; + const html = _.get(action, ['message', 0, 'html'], '').replace('/>', `data-hidden="${isHidden}" />`); + htmlParser.write(html); }); htmlParser.end(); diff --git a/src/components/Attachments/AttachmentCarousel/index.js b/src/components/Attachments/AttachmentCarousel/index.js index 564e60b65dd1..9875864f1549 100644 --- a/src/components/Attachments/AttachmentCarousel/index.js +++ b/src/components/Attachments/AttachmentCarousel/index.js @@ -5,7 +5,6 @@ import _ from 'underscore'; import * as DeviceCapabilities from '../../../libs/DeviceCapabilities'; import styles from '../../../styles/styles'; import CarouselActions from './CarouselActions'; -import AttachmentView from '../AttachmentView'; import withWindowDimensions from '../../withWindowDimensions'; import CarouselButtons from './CarouselButtons'; import extractAttachmentsFromReport from './extractAttachmentsFromReport'; @@ -15,6 +14,7 @@ import withLocalize from '../../withLocalize'; import compose from '../../../libs/compose'; import useCarouselArrows from './useCarouselArrows'; import useWindowDimensions from '../../../hooks/useWindowDimensions'; +import CarouselItem from './CarouselItem'; const canUseTouchScreen = DeviceCapabilities.canUseTouchScreen(); const viewabilityConfig = { @@ -130,17 +130,15 @@ function AttachmentCarousel({report, reportActions, source, onNavigate}) { * @param {String} item.source * @param {Object} item.file * @param {String} item.file.name + * @param {Boolean} item.isHidden * @returns {JSX.Element} */ const renderItem = useCallback( ({item}) => ( - canUseTouchScreen && setShouldShowArrows(!shouldShowArrows)} - isUsedInCarousel /> ), [activeSource, setShouldShowArrows, shouldShowArrows], diff --git a/src/components/Attachments/AttachmentCarousel/index.native.js b/src/components/Attachments/AttachmentCarousel/index.native.js index 58e248d514e1..77143fa11324 100644 --- a/src/components/Attachments/AttachmentCarousel/index.native.js +++ b/src/components/Attachments/AttachmentCarousel/index.native.js @@ -4,11 +4,11 @@ import {withOnyx} from 'react-native-onyx'; import AttachmentCarouselPager from './Pager'; import styles from '../../../styles/styles'; import CarouselButtons from './CarouselButtons'; -import AttachmentView from '../AttachmentView'; import ONYXKEYS from '../../../ONYXKEYS'; import {propTypes, defaultProps} from './attachmentCarouselPropTypes'; import extractAttachmentsFromReport from './extractAttachmentsFromReport'; import useCarouselArrows from './useCarouselArrows'; +import CarouselItem from './CarouselItem'; function AttachmentCarousel({report, reportActions, source, onNavigate, onClose}) { const {attachments, initialPage, initialActiveSource, initialItem} = useMemo(() => extractAttachmentsFromReport(report, reportActions, source), [report, reportActions, source]); @@ -64,17 +64,14 @@ function AttachmentCarousel({report, reportActions, source, onNavigate, onClose} /** * Defines how a single attachment should be rendered - * @param {{ isAuthTokenRequired: Boolean, source: String, file: { name: String } }} item + * @param {{ isAuthTokenRequired: Boolean, source: String, file: { name: String }, isHidden: Boolean }} item * @returns {JSX.Element} */ const renderItem = useCallback( ({item}) => ( - setShouldShowArrows(!shouldShowArrows)} /> ), From 104f0f4783f3635f42886405e5d310b5c2241c71 Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Wed, 16 Aug 2023 21:23:06 +0800 Subject: [PATCH 02/22] remove auto hide after out of focus --- .../Attachments/AttachmentCarousel/CarouselItem.js | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/components/Attachments/AttachmentCarousel/CarouselItem.js b/src/components/Attachments/AttachmentCarousel/CarouselItem.js index 6b3056f134df..d1254154543f 100644 --- a/src/components/Attachments/AttachmentCarousel/CarouselItem.js +++ b/src/components/Attachments/AttachmentCarousel/CarouselItem.js @@ -32,14 +32,6 @@ function CarouselItem({item, isFocused, onPress}) { const {translate} = useLocalize(); const [isHidden, setIsHidden] = useState(item.isHidden); - useEffect(() => { - if (isFocused) { - return; - } - // When the attachment is out of focus, we want to hide the attachment back - setIsHidden(item.isHidden); - }, [isFocused, item.isHidden]); - if (isHidden) { return ( Date: Wed, 16 Aug 2023 21:28:07 +0800 Subject: [PATCH 03/22] remove unused import --- src/components/Attachments/AttachmentCarousel/CarouselItem.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Attachments/AttachmentCarousel/CarouselItem.js b/src/components/Attachments/AttachmentCarousel/CarouselItem.js index d1254154543f..db8805cf90b3 100644 --- a/src/components/Attachments/AttachmentCarousel/CarouselItem.js +++ b/src/components/Attachments/AttachmentCarousel/CarouselItem.js @@ -1,4 +1,4 @@ -import React, {useState, useEffect} from 'react'; +import React, {useState} from 'react'; import PropTypes from 'prop-types'; import CONST from '../../../CONST'; import styles from '../../../styles/styles'; From 0fd41e9bd54092e85905895048b73917852d0d3e Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Fri, 18 Aug 2023 16:32:24 +0800 Subject: [PATCH 04/22] add comment and SELECTION_SCRAPER_HIDDEN_ELEMENT dataset --- .../Attachments/AttachmentCarousel/CarouselItem.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/components/Attachments/AttachmentCarousel/CarouselItem.js b/src/components/Attachments/AttachmentCarousel/CarouselItem.js index db8805cf90b3..1ff126bbc2b4 100644 --- a/src/components/Attachments/AttachmentCarousel/CarouselItem.js +++ b/src/components/Attachments/AttachmentCarousel/CarouselItem.js @@ -11,9 +11,19 @@ import AttachmentView from '../AttachmentView'; const propTypes = { /** Attachment required information such as the source and file name */ item: PropTypes.shape({ + /** Whether source URL requires authentication */ isAuthTokenRequired: PropTypes.bool, + + /** The source (URL) of the attachment */ source: PropTypes.string, - file: PropTypes.shape({name: PropTypes.string}), + + /** File additional information of the attachment */ + file: PropTypes.shape({ + /** File name of the attachment */ + name: PropTypes.string, + }), + + /** Whether the attachment is hidden by moderation */ isHidden: PropTypes.bool, }).isRequired, @@ -49,6 +59,7 @@ function CarouselItem({item, isFocused, onPress}) { {translate('moderation.revealMessage')} From 1734b16ac2c70921345a74021e6daa870fc62aef Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Wed, 23 Aug 2023 14:55:04 +0800 Subject: [PATCH 05/22] show hidden message button on a flagged attachment --- .../AttachmentCarousel/CarouselItem.js | 61 +++++++++++-------- .../extractAttachmentsFromReport.js | 6 +- 2 files changed, 39 insertions(+), 28 deletions(-) diff --git a/src/components/Attachments/AttachmentCarousel/CarouselItem.js b/src/components/Attachments/AttachmentCarousel/CarouselItem.js index 1ff126bbc2b4..1d739e04fd69 100644 --- a/src/components/Attachments/AttachmentCarousel/CarouselItem.js +++ b/src/components/Attachments/AttachmentCarousel/CarouselItem.js @@ -1,4 +1,5 @@ import React, {useState} from 'react'; +import {View} from 'react-native'; import PropTypes from 'prop-types'; import CONST from '../../../CONST'; import styles from '../../../styles/styles'; @@ -23,8 +24,8 @@ const propTypes = { name: PropTypes.string, }), - /** Whether the attachment is hidden by moderation */ - isHidden: PropTypes.bool, + /** Whether the attachment has been flagged */ + hasBeenFlagged: PropTypes.bool, }).isRequired, /** Whether the attachment is currently being viewed in the carousel */ @@ -40,43 +41,53 @@ const defaultProps = { function CarouselItem({item, isFocused, onPress}) { const {translate} = useLocalize(); - const [isHidden, setIsHidden] = useState(item.isHidden); + const [isHidden, setIsHidden] = useState(item.hasBeenFlagged); + + const renderButton = (style) => ( + + ); if (isHidden) { return ( {translate('moderation.flaggedContent')} - + {renderButton([styles.mt2])} ); } return ( - + + + + + + {item.hasBeenFlagged && renderButton([styles.mv4, styles.mh4, styles.alignSelfCenter])} + ); } diff --git a/src/components/Attachments/AttachmentCarousel/extractAttachmentsFromReport.js b/src/components/Attachments/AttachmentCarousel/extractAttachmentsFromReport.js index 3bcf2a096a51..4849bfa48977 100644 --- a/src/components/Attachments/AttachmentCarousel/extractAttachmentsFromReport.js +++ b/src/components/Attachments/AttachmentCarousel/extractAttachmentsFromReport.js @@ -31,8 +31,8 @@ function extractAttachmentsFromReport(report, reportActions) { source: tryResolveUrlFromApiRoot(expensifySource || attribs.src), isAuthTokenRequired: Boolean(expensifySource), file: {name: attribs[CONST.ATTACHMENT_ORIGINAL_FILENAME_ATTRIBUTE]}, - isHidden: attribs['data-hidden'] === 'true', isReceipt: false, + hasBeenFlagged: attribs['data-flagged'] === 'true', }); }, }); @@ -64,8 +64,8 @@ function extractAttachmentsFromReport(report, reportActions) { } const decision = _.get(action, ['message', 0, 'moderationDecision', 'decision'], ''); - const isHidden = decision === CONST.MODERATION.MODERATOR_DECISION_PENDING_HIDE || decision === CONST.MODERATION.MODERATOR_DECISION_HIDDEN; - const html = _.get(action, ['message', 0, 'html'], '').replace('/>', `data-hidden="${isHidden}" />`); + const hasBeenFlagged = decision === CONST.MODERATION.MODERATOR_DECISION_PENDING_HIDE || decision === CONST.MODERATION.MODERATOR_DECISION_HIDDEN; + const html = _.get(action, ['message', 0, 'html'], '').replace('/>', `data-flagged="${hasBeenFlagged}" />`); htmlParser.write(html); }); htmlParser.end(); From 83c629e2b58e9da0763a7baa0b780cc20c0d78be Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Wed, 23 Aug 2023 14:55:24 +0800 Subject: [PATCH 06/22] change default onpress to undefined --- src/components/Attachments/AttachmentCarousel/CarouselItem.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Attachments/AttachmentCarousel/CarouselItem.js b/src/components/Attachments/AttachmentCarousel/CarouselItem.js index 1d739e04fd69..ab21e8060bed 100644 --- a/src/components/Attachments/AttachmentCarousel/CarouselItem.js +++ b/src/components/Attachments/AttachmentCarousel/CarouselItem.js @@ -36,7 +36,7 @@ const propTypes = { }; const defaultProps = { - onPress: () => {}, + onPress: undefined, }; function CarouselItem({item, isFocused, onPress}) { From d5b8130a2feeffead5864e9b178c020932fd3e6f Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Wed, 23 Aug 2023 14:57:49 +0800 Subject: [PATCH 07/22] use view if it's not pressable --- .../AttachmentCarousel/CarouselItem.js | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/components/Attachments/AttachmentCarousel/CarouselItem.js b/src/components/Attachments/AttachmentCarousel/CarouselItem.js index ab21e8060bed..145c929be611 100644 --- a/src/components/Attachments/AttachmentCarousel/CarouselItem.js +++ b/src/components/Attachments/AttachmentCarousel/CarouselItem.js @@ -60,16 +60,25 @@ function CarouselItem({item, isFocused, onPress}) { ); if (isHidden) { - return ( + const children = ( + <> + {translate('moderation.flaggedContent')} + {renderButton([styles.mt2])} + + ); + return onPress ? ( - {translate('moderation.flaggedContent')} - {renderButton([styles.mt2])} + {children} + ) : ( + + {children} + ); } From 4dbf950a172d950852a5b96639211168b9177176 Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Wed, 23 Aug 2023 15:44:20 +0800 Subject: [PATCH 08/22] add safe area padding bottom --- .../Attachments/AttachmentCarousel/CarouselItem.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/components/Attachments/AttachmentCarousel/CarouselItem.js b/src/components/Attachments/AttachmentCarousel/CarouselItem.js index 145c929be611..cdcb3bae68fd 100644 --- a/src/components/Attachments/AttachmentCarousel/CarouselItem.js +++ b/src/components/Attachments/AttachmentCarousel/CarouselItem.js @@ -8,6 +8,7 @@ import PressableWithoutFeedback from '../../Pressable/PressableWithoutFeedback'; import Text from '../../Text'; import Button from '../../Button'; import AttachmentView from '../AttachmentView'; +import SafeAreaConsumer from '../../SafeAreaConsumer'; const propTypes = { /** Attachment required information such as the source and file name */ @@ -95,7 +96,11 @@ function CarouselItem({item, isFocused, onPress}) { /> - {item.hasBeenFlagged && renderButton([styles.mv4, styles.mh4, styles.alignSelfCenter])} + {item.hasBeenFlagged && ( + + {({safeAreaPaddingBottomStyle}) => renderButton([styles.m4, styles.alignSelfCenter, safeAreaPaddingBottomStyle])} + + )} ); } From e7956b3f9ab5385d52e5aa5bd742358cc1fcea9e Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Wed, 23 Aug 2023 18:12:01 +0800 Subject: [PATCH 09/22] add bg --- .../Attachments/AttachmentCarousel/CarouselItem.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/components/Attachments/AttachmentCarousel/CarouselItem.js b/src/components/Attachments/AttachmentCarousel/CarouselItem.js index cdcb3bae68fd..842682b8d323 100644 --- a/src/components/Attachments/AttachmentCarousel/CarouselItem.js +++ b/src/components/Attachments/AttachmentCarousel/CarouselItem.js @@ -98,7 +98,11 @@ function CarouselItem({item, isFocused, onPress}) { {item.hasBeenFlagged && ( - {({safeAreaPaddingBottomStyle}) => renderButton([styles.m4, styles.alignSelfCenter, safeAreaPaddingBottomStyle])} + {({safeAreaPaddingBottomStyle}) => ( + + {renderButton([styles.m4, styles.alignSelfCenter])} + + )} )} From 8863e79b73abcbb47693d5a68796569aa8a12a08 Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Wed, 23 Aug 2023 18:56:34 +0800 Subject: [PATCH 10/22] rename jsdoc param --- src/components/Attachments/AttachmentCarousel/index.js | 2 +- src/components/Attachments/AttachmentCarousel/index.native.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Attachments/AttachmentCarousel/index.js b/src/components/Attachments/AttachmentCarousel/index.js index 217c061aeb56..e15803cddf4a 100644 --- a/src/components/Attachments/AttachmentCarousel/index.js +++ b/src/components/Attachments/AttachmentCarousel/index.js @@ -147,7 +147,7 @@ function AttachmentCarousel({report, reportActions, source, onNavigate, setDownl * @param {String} item.source * @param {Object} item.file * @param {String} item.file.name - * @param {Boolean} item.isHidden + * @param {Boolean} item.hasBeenFlagged * @returns {JSX.Element} */ const renderItem = useCallback( diff --git a/src/components/Attachments/AttachmentCarousel/index.native.js b/src/components/Attachments/AttachmentCarousel/index.native.js index 6d089c948a50..9d3ec7b57535 100644 --- a/src/components/Attachments/AttachmentCarousel/index.native.js +++ b/src/components/Attachments/AttachmentCarousel/index.native.js @@ -85,7 +85,7 @@ function AttachmentCarousel({report, reportActions, source, onNavigate, onClose, /** * Defines how a single attachment should be rendered - * @param {{ isAuthTokenRequired: Boolean, source: String, file: { name: String }, isHidden: Boolean }} item + * @param {{ isAuthTokenRequired: Boolean, source: String, file: { name: String }, hasBeenFlagged: Boolean }} item * @returns {JSX.Element} */ const renderItem = useCallback( From dce672191ded79dbe6d506cd3c4c11e390adc2b3 Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Wed, 23 Aug 2023 19:06:00 +0800 Subject: [PATCH 11/22] created new style --- .../Attachments/AttachmentCarousel/CarouselItem.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/components/Attachments/AttachmentCarousel/CarouselItem.js b/src/components/Attachments/AttachmentCarousel/CarouselItem.js index 842682b8d323..bcf107423628 100644 --- a/src/components/Attachments/AttachmentCarousel/CarouselItem.js +++ b/src/components/Attachments/AttachmentCarousel/CarouselItem.js @@ -69,7 +69,7 @@ function CarouselItem({item, isFocused, onPress}) { ); return onPress ? ( ) : ( - - {children} - + {children} ); } From fc337d69e624bcad1e0e43ade8533072bd113a90 Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Wed, 23 Aug 2023 19:06:47 +0800 Subject: [PATCH 12/22] created new style --- src/styles/styles.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/styles/styles.js b/src/styles/styles.js index 8df481ddb70e..a4184cb16bba 100644 --- a/src/styles/styles.js +++ b/src/styles/styles.js @@ -2521,6 +2521,13 @@ const styles = { position: 'absolute', }, + attachmentRevealButtonContainer: { + flex: 1, + alignItems: 'center', + justifyContent: 'center', + ...spacing.ph4, + }, + arrowIcon: { height: 40, width: 40, From 4202190bcb7579b825ca19faf2b7ce4f8fbb6375 Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Wed, 23 Aug 2023 19:27:09 +0800 Subject: [PATCH 13/22] lint --- .../Attachments/AttachmentCarousel/CarouselItem.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/components/Attachments/AttachmentCarousel/CarouselItem.js b/src/components/Attachments/AttachmentCarousel/CarouselItem.js index bcf107423628..88289e14e18a 100644 --- a/src/components/Attachments/AttachmentCarousel/CarouselItem.js +++ b/src/components/Attachments/AttachmentCarousel/CarouselItem.js @@ -96,11 +96,7 @@ function CarouselItem({item, isFocused, onPress}) { {item.hasBeenFlagged && ( - {({safeAreaPaddingBottomStyle}) => ( - - {renderButton([styles.m4, styles.alignSelfCenter])} - - )} + {({safeAreaPaddingBottomStyle}) => {renderButton([styles.m4, styles.alignSelfCenter])}} )} From e850d52e79cf1243d20738daccb633bded9ad01c Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Mon, 4 Sep 2023 23:54:24 +0800 Subject: [PATCH 14/22] share the attachment visibilty state through context --- src/App.js | 2 + .../AttachmentCarousel/CarouselItem.js | 12 +++++- .../extractAttachmentsFromReport.js | 3 +- .../Attachments/AttachmentCarousel/index.js | 1 + .../AttachmentCarousel/index.native.js | 2 +- src/pages/home/report/ReportActionItem.js | 11 ++++++ .../home/report/ReportAttachmentsContext.js | 38 +++++++++++++++++++ 7 files changed, 65 insertions(+), 4 deletions(-) create mode 100644 src/pages/home/report/ReportAttachmentsContext.js diff --git a/src/App.js b/src/App.js index c432a0b666c8..cc171c202bc4 100644 --- a/src/App.js +++ b/src/App.js @@ -24,6 +24,7 @@ import {CurrentReportIDContextProvider} from './components/withCurrentReportID'; import {EnvironmentProvider} from './components/withEnvironment'; import * as Session from './libs/actions/Session'; import useDefaultDragAndDrop from './hooks/useDefaultDragAndDrop'; +import {ReportAttachmentsProvider} from './pages/home/report/ReportAttachmentsContext'; // For easier debugging and development, when we are in web we expose Onyx to the window, so you can more easily set data into Onyx if (window && Environment.isDevelopment()) { @@ -56,6 +57,7 @@ function App() { KeyboardStateProvider, PopoverContextProvider, CurrentReportIDContextProvider, + ReportAttachmentsProvider, PickerStateProvider, EnvironmentProvider, ThemeProvider, diff --git a/src/components/Attachments/AttachmentCarousel/CarouselItem.js b/src/components/Attachments/AttachmentCarousel/CarouselItem.js index 88289e14e18a..435568ba25a1 100644 --- a/src/components/Attachments/AttachmentCarousel/CarouselItem.js +++ b/src/components/Attachments/AttachmentCarousel/CarouselItem.js @@ -1,4 +1,4 @@ -import React, {useState} from 'react'; +import React, {useContext, useState} from 'react'; import {View} from 'react-native'; import PropTypes from 'prop-types'; import CONST from '../../../CONST'; @@ -9,10 +9,14 @@ import Text from '../../Text'; import Button from '../../Button'; import AttachmentView from '../AttachmentView'; import SafeAreaConsumer from '../../SafeAreaConsumer'; +import ReportAttachmentsContext from '../../../pages/home/report/ReportAttachmentsContext'; const propTypes = { /** Attachment required information such as the source and file name */ item: PropTypes.shape({ + /** Report action ID of the attachment */ + reportActionID: PropTypes.string, + /** Whether source URL requires authentication */ isAuthTokenRequired: PropTypes.bool, @@ -42,7 +46,11 @@ const defaultProps = { function CarouselItem({item, isFocused, onPress}) { const {translate} = useLocalize(); - const [isHidden, setIsHidden] = useState(item.hasBeenFlagged); + const {isAttachmentHidden} = useContext(ReportAttachmentsContext); + const [isHidden, setIsHidden] = useState(() => { + const isAttachmentHiddenValue = isAttachmentHidden[item.reportActionID]; + return isAttachmentHiddenValue === undefined ? item.hasBeenFlagged : isAttachmentHiddenValue; + }); const renderButton = (style) => (