From 2400440eb77c7cb31feada410486ee370cb7a417 Mon Sep 17 00:00:00 2001 From: Vivek Kumar Date: Fri, 22 Apr 2022 00:54:44 +0530 Subject: [PATCH 1/6] added separate logic to extract attachment info --- src/libs/fileDownload/getAttachmentDetails.js | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 src/libs/fileDownload/getAttachmentDetails.js diff --git a/src/libs/fileDownload/getAttachmentDetails.js b/src/libs/fileDownload/getAttachmentDetails.js new file mode 100644 index 000000000000..a6896266ccd0 --- /dev/null +++ b/src/libs/fileDownload/getAttachmentDetails.js @@ -0,0 +1,39 @@ +import CONST from '../../CONST'; +import Config from '../../CONFIG'; + +/** + * Extract the thumbnail URL, source URL and the original filename from the HTML. + * @param {String} html + * @returns {Object} + */ +const PREVIEW_SOURCE_REGEX = new RegExp(`${CONST.ATTACHMENT_PREVIEW_ATTRIBUTE}\s*=\s*"(.+?)"`, "i"); +const SOURCE_REGEX = new RegExp(`${CONST.ATTACHMENT_SOURCE_ATTRIBUTE}\s*=\s*"(.+?)"`, "i"); +const ORIGINAL_FILENAME_REGEX = new RegExp(`${CONST.ATTACHMENT_ORIGINAL_FILENAME_ATTRIBUTE}\s*=\s*"(.+?)"`, "i"); + +export default function getAttachmentName(html) { + if (!html) { + return { + previewSourceURL: null, + sourceURL: null, + originalFileName: null + }; + } + let previewSourceURL = html.match(PREVIEW_SOURCE_REGEX)[1]; + let sourceURL = html.match(SOURCE_REGEX)[1]; + let originalFileName = html.match(ORIGINAL_FILENAME_REGEX)[1]; + + // Update the image URL so the images can be accessed depending on the config environment + previewSourceURL = previewSourceURL.replace( + Config.EXPENSIFY.EXPENSIFY_URL, + Config.EXPENSIFY.URL_API_ROOT, + ); + sourceURL = sourceURL.replace( + Config.EXPENSIFY.EXPENSIFY_URL, + Config.EXPENSIFY.URL_API_ROOT, + ); + return { + previewSourceURL, + sourceURL, + originalFileName + } +} \ No newline at end of file From db6b7880b23b36d49920acf15ac7b87798347fec Mon Sep 17 00:00:00 2001 From: Vivek Kumar Date: Fri, 22 Apr 2022 00:55:15 +0530 Subject: [PATCH 2/6] introduced constants for attachments related --- src/CONST.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/CONST.js b/src/CONST.js index 4a7a3f87e0d8..c1b5a3f7271c 100755 --- a/src/CONST.js +++ b/src/CONST.js @@ -399,6 +399,8 @@ const CONST = { }, ATTACHMENT_SOURCE_ATTRIBUTE: 'data-expensify-source', + ATTACHMENT_PREVIEW_ATTRIBUTE: 'src', + ATTACHMENT_ORIGINAL_FILENAME_ATTRIBUTE: 'data-name', ATTACHMENT_PICKER_TYPE: { FILE: 'file', From 536b8711514f2957cf837f595d7ed6c60f78a7ab Mon Sep 17 00:00:00 2001 From: Vivek Kumar Date: Fri, 22 Apr 2022 00:55:45 +0530 Subject: [PATCH 3/6] added logic to show download option in context menu --- .../report/ContextMenu/ContextMenuActions.js | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/pages/home/report/ContextMenu/ContextMenuActions.js b/src/pages/home/report/ContextMenu/ContextMenuActions.js index b61ebe62f150..1a2191ba6341 100644 --- a/src/pages/home/report/ContextMenu/ContextMenuActions.js +++ b/src/pages/home/report/ContextMenu/ContextMenuActions.js @@ -8,6 +8,9 @@ import * as ReportUtils from '../../../../libs/reportUtils'; import ReportActionComposeFocusManager from '../../../../libs/ReportActionComposeFocusManager'; import {hideContextMenu, showDeleteModal} from './ReportActionContextMenu'; import CONST from '../../../../CONST'; +import getAttachmentDetails from '../../../../libs/fileDownload/getAttachmentDetails'; +import fileDownload from '../../../../libs/fileDownload'; +import addEncryptedAuthTokenToURL from '../../../../libs/addEncryptedAuthTokenToURL'; /** * Gets the HTML version of the message in an action. @@ -27,6 +30,26 @@ const CONTEXT_MENU_TYPES = { // A list of all the context actions in this menu. export default [ + { + textTranslateKey: 'common.download', + icon: Expensicons.Download, + successTextTranslateKey: 'common.download', + successIcon: Expensicons.Checkmark, + shouldShow: (type, reportAction) => { + const message = _.last(lodashGet(reportAction, 'message', [{}])); + const isAttachment = _.has(reportAction, 'isAttachment') + ? reportAction.isAttachment + : ReportUtils.isReportMessageAttachment(message); + return isAttachment; + }, + onPress: (closePopover, {reportAction}) => { + const message = _.last(lodashGet(reportAction, 'message', [{}])); + const html = lodashGet(message, 'html', ''); + let {sourceURL, originalFileName} = getAttachmentDetails(html); + sourceURL = addEncryptedAuthTokenToURL(sourceURL); + fileDownload(sourceURL, originalFileName); + }, + }, { textTranslateKey: 'reportActionContextMenu.copyURLToClipboard', icon: Expensicons.Clipboard, From f69a3450fb79f342f045c1feff5009f3e8d96a8d Mon Sep 17 00:00:00 2001 From: Vivek Kumar Date: Wed, 27 Apr 2022 00:48:52 +0530 Subject: [PATCH 4/6] fixed linter issue --- src/libs/fileDownload/getAttachmentDetails.js | 18 +++++++++--------- .../report/ContextMenu/ContextMenuActions.js | 6 ++++-- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/libs/fileDownload/getAttachmentDetails.js b/src/libs/fileDownload/getAttachmentDetails.js index a6896266ccd0..6daa7fff9d5f 100644 --- a/src/libs/fileDownload/getAttachmentDetails.js +++ b/src/libs/fileDownload/getAttachmentDetails.js @@ -6,24 +6,24 @@ import Config from '../../CONFIG'; * @param {String} html * @returns {Object} */ -const PREVIEW_SOURCE_REGEX = new RegExp(`${CONST.ATTACHMENT_PREVIEW_ATTRIBUTE}\s*=\s*"(.+?)"`, "i"); -const SOURCE_REGEX = new RegExp(`${CONST.ATTACHMENT_SOURCE_ATTRIBUTE}\s*=\s*"(.+?)"`, "i"); -const ORIGINAL_FILENAME_REGEX = new RegExp(`${CONST.ATTACHMENT_ORIGINAL_FILENAME_ATTRIBUTE}\s*=\s*"(.+?)"`, "i"); +const PREVIEW_SOURCE_REGEX = new RegExp(`${CONST.ATTACHMENT_PREVIEW_ATTRIBUTE}*=*"(.+?)"`, 'i'); +const SOURCE_REGEX = new RegExp(`${CONST.ATTACHMENT_SOURCE_ATTRIBUTE}*=*"(.+?)"`, 'i'); +const ORIGINAL_FILENAME_REGEX = new RegExp(`${CONST.ATTACHMENT_ORIGINAL_FILENAME_ATTRIBUTE}*=*"(.+?)"`, 'i'); export default function getAttachmentName(html) { if (!html) { return { previewSourceURL: null, sourceURL: null, - originalFileName: null + originalFileName: null, }; } let previewSourceURL = html.match(PREVIEW_SOURCE_REGEX)[1]; let sourceURL = html.match(SOURCE_REGEX)[1]; - let originalFileName = html.match(ORIGINAL_FILENAME_REGEX)[1]; + const originalFileName = html.match(ORIGINAL_FILENAME_REGEX)[1]; // Update the image URL so the images can be accessed depending on the config environment - previewSourceURL = previewSourceURL.replace( + previewSourceURL = previewSourceURL.replace( Config.EXPENSIFY.EXPENSIFY_URL, Config.EXPENSIFY.URL_API_ROOT, ); @@ -34,6 +34,6 @@ export default function getAttachmentName(html) { return { previewSourceURL, sourceURL, - originalFileName - } -} \ No newline at end of file + originalFileName, + }; +} diff --git a/src/pages/home/report/ContextMenu/ContextMenuActions.js b/src/pages/home/report/ContextMenu/ContextMenuActions.js index 1a2191ba6341..d52db04a0143 100644 --- a/src/pages/home/report/ContextMenu/ContextMenuActions.js +++ b/src/pages/home/report/ContextMenu/ContextMenuActions.js @@ -34,7 +34,7 @@ export default [ textTranslateKey: 'common.download', icon: Expensicons.Download, successTextTranslateKey: 'common.download', - successIcon: Expensicons.Checkmark, + successIcon: Expensicons.Download, shouldShow: (type, reportAction) => { const message = _.last(lodashGet(reportAction, 'message', [{}])); const isAttachment = _.has(reportAction, 'isAttachment') @@ -45,7 +45,9 @@ export default [ onPress: (closePopover, {reportAction}) => { const message = _.last(lodashGet(reportAction, 'message', [{}])); const html = lodashGet(message, 'html', ''); - let {sourceURL, originalFileName} = getAttachmentDetails(html); + const attachmentDetails = getAttachmentDetails(html); + const {originalFileName} = attachmentDetails; + let {sourceURL} = attachmentDetails; sourceURL = addEncryptedAuthTokenToURL(sourceURL); fileDownload(sourceURL, originalFileName); }, From 40bce51c28ae8d45aff676c439adcc4313e04224 Mon Sep 17 00:00:00 2001 From: Vivek Kumar Date: Wed, 27 Apr 2022 10:37:03 +0530 Subject: [PATCH 5/6] updated code to use chaining --- src/libs/fileDownload/getAttachmentDetails.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/libs/fileDownload/getAttachmentDetails.js b/src/libs/fileDownload/getAttachmentDetails.js index 6daa7fff9d5f..8b8e777ab911 100644 --- a/src/libs/fileDownload/getAttachmentDetails.js +++ b/src/libs/fileDownload/getAttachmentDetails.js @@ -18,19 +18,17 @@ export default function getAttachmentName(html) { originalFileName: null, }; } - let previewSourceURL = html.match(PREVIEW_SOURCE_REGEX)[1]; - let sourceURL = html.match(SOURCE_REGEX)[1]; - const originalFileName = html.match(ORIGINAL_FILENAME_REGEX)[1]; - - // Update the image URL so the images can be accessed depending on the config environment - previewSourceURL = previewSourceURL.replace( + const previewSourceURL = html.match(PREVIEW_SOURCE_REGEX)[1].replace( Config.EXPENSIFY.EXPENSIFY_URL, Config.EXPENSIFY.URL_API_ROOT, ); - sourceURL = sourceURL.replace( + const sourceURL = html.match(SOURCE_REGEX)[1].replace( Config.EXPENSIFY.EXPENSIFY_URL, Config.EXPENSIFY.URL_API_ROOT, ); + const originalFileName = html.match(ORIGINAL_FILENAME_REGEX)[1]; + + // Update the image URL so the images can be accessed depending on the config environment return { previewSourceURL, sourceURL, From f28df4dafaba2a2e331827195ec78b2a1acab3ff Mon Sep 17 00:00:00 2001 From: Vivek Kumar Date: Wed, 27 Apr 2022 16:13:19 +0530 Subject: [PATCH 6/6] updated code to show download icon only when attachment is uploaded --- src/pages/home/report/ContextMenu/ContextMenuActions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/home/report/ContextMenu/ContextMenuActions.js b/src/pages/home/report/ContextMenu/ContextMenuActions.js index d52db04a0143..099ee746b9c9 100644 --- a/src/pages/home/report/ContextMenu/ContextMenuActions.js +++ b/src/pages/home/report/ContextMenu/ContextMenuActions.js @@ -40,7 +40,7 @@ export default [ const isAttachment = _.has(reportAction, 'isAttachment') ? reportAction.isAttachment : ReportUtils.isReportMessageAttachment(message); - return isAttachment; + return isAttachment && reportAction.reportActionID; }, onPress: (closePopover, {reportAction}) => { const message = _.last(lodashGet(reportAction, 'message', [{}]));