From 103821be9d3ba154ee046efc36742ac13f15da62 Mon Sep 17 00:00:00 2001 From: Jakub Szymczak Date: Mon, 11 Dec 2023 15:39:51 +0100 Subject: [PATCH 1/6] migrate LinkPreviewer to typescript --- src/pages/home/report/LinkPreviewer.js | 139 ------------------------ src/pages/home/report/LinkPreviewer.tsx | 120 ++++++++++++++++++++ 2 files changed, 120 insertions(+), 139 deletions(-) delete mode 100644 src/pages/home/report/LinkPreviewer.js create mode 100644 src/pages/home/report/LinkPreviewer.tsx diff --git a/src/pages/home/report/LinkPreviewer.js b/src/pages/home/report/LinkPreviewer.js deleted file mode 100644 index 5c16d5596774..000000000000 --- a/src/pages/home/report/LinkPreviewer.js +++ /dev/null @@ -1,139 +0,0 @@ -import {uniqBy} from 'lodash'; -import PropTypes from 'prop-types'; -import React from 'react'; -import {Image, View} from 'react-native'; -import _ from 'underscore'; -import Text from '@components/Text'; -import TextLink from '@components/TextLink'; -import useTheme from '@styles/themes/useTheme'; -import useStyleUtils from '@styles/useStyleUtils'; -import useThemeStyles from '@styles/useThemeStyles'; -import variables from '@styles/variables'; - -const IMAGE_TYPES = ['jpg', 'jpeg', 'png']; -const MAX_IMAGE_HEIGHT = 180; -const MAX_IMAGE_WIDTH = 340; - -const propTypes = { - /** Data about links provided in message. */ - linkMetadata: PropTypes.arrayOf( - PropTypes.shape({ - /** The URL of the link. */ - url: PropTypes.string, - - /** A description of the link. */ - description: PropTypes.string, - - /** The title of the link. */ - title: PropTypes.string, - - /** The publisher of the link. */ - publisher: PropTypes.string, - - /** The image associated with the link. */ - image: PropTypes.shape({ - /** The height of the image. */ - height: PropTypes.number, - - /** The width of the image. */ - width: PropTypes.number, - - /** The URL of the image. */ - url: PropTypes.string, - }), - - /** The provider logo associated with the link. */ - logo: PropTypes.shape({ - /** The height of the logo. */ - height: PropTypes.number, - - /** The width of the logo. */ - width: PropTypes.number, - - /** The URL of the logo. */ - url: PropTypes.string, - }), - }), - ), - - /** Maximum amount of visible link previews. -1 means unlimited amount of previews */ - maxAmountOfPreviews: PropTypes.number, -}; - -const defaultProps = { - linkMetadata: [], - maxAmountOfPreviews: -1, -}; - -function LinkPreviewer(props) { - const theme = useTheme(); - const styles = useThemeStyles(); - const StyleUtils = useStyleUtils(); - return _.map( - _.take(uniqBy(props.linkMetadata, 'url'), props.maxAmountOfPreviews >= 0 ? Math.min(props.maxAmountOfPreviews, props.linkMetadata.length) : props.linkMetadata.length), - (linkData) => { - if (_.isArray(linkData)) { - return; - } - const {description, image, title, logo, publisher, url} = linkData; - - return ( - linkData && ( - - - {!_.isEmpty(logo) && ( - - )} - {!_.isEmpty(publisher) && ( - - {publisher} - - )} - - {!_.isEmpty(title) && ( - - {title} - - )} - {!_.isEmpty(description) && {description}} - {!_.isEmpty(image) && IMAGE_TYPES.includes(image.type) && ( - - )} - - ) - ); - }, - ); -} - -LinkPreviewer.propTypes = propTypes; -LinkPreviewer.defaultProps = defaultProps; -LinkPreviewer.displayName = 'ReportLinkPreview'; - -export default LinkPreviewer; diff --git a/src/pages/home/report/LinkPreviewer.tsx b/src/pages/home/report/LinkPreviewer.tsx new file mode 100644 index 000000000000..c9f50ec91a48 --- /dev/null +++ b/src/pages/home/report/LinkPreviewer.tsx @@ -0,0 +1,120 @@ +import React from 'react'; +import {Image, View} from 'react-native'; +import Text from '@components/Text'; +import TextLink from '@components/TextLink'; +import useTheme from '@styles/themes/useTheme'; +import useStyleUtils from '@styles/useStyleUtils'; +import useThemeStyles from '@styles/useThemeStyles'; +import variables from '@styles/variables'; + +const IMAGE_TYPES = ['jpg', 'jpeg', 'png']; +const MAX_IMAGE_HEIGHT = 180; +const MAX_IMAGE_WIDTH = 340; + +type ImageData = { + /** The height of the image. */ + height: number; + + /** The width of the image. */ + width: number; + + /** The URL of the image. */ + url: string; + + /** The type of the image. */ + type?: string; +}; + +type LinkMetadata = { + /** The URL of the link. */ + url?: string; + + /** A description of the link. */ + description?: string; + + /** The title of the link. */ + title?: string; + + /** The publisher of the link. */ + publisher?: string; + + /** The image associated with the link. */ + image?: ImageData; + + /** The provider logo associated with the link. */ + logo?: ImageData; +}; + +type LinkPreviewerProps = { + /** Data about links provided in message. */ + linkMetadata?: LinkMetadata[]; + + /** Maximum amount of visible link previews. -1 means unlimited amount of previews */ + maxAmountOfPreviews?: number; +}; + +function LinkPreviewer({linkMetadata = [], maxAmountOfPreviews = -1}: LinkPreviewerProps) { + const theme = useTheme(); + const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); + const uniqueLinks = linkMetadata.filter((link, index, self) => self.findIndex((t) => t.url === link.url) === index); + const linksToShow = uniqueLinks.slice(0, maxAmountOfPreviews >= 0 ? Math.min(maxAmountOfPreviews, linkMetadata.length) : linkMetadata.length); + return linksToShow.map((linkData) => { + const {description, image, title, logo, publisher, url} = linkData; + return ( + linkData && ( + + + {logo && ( + + )} + {publisher && ( + + {publisher} + + )} + + {title && url && ( + + {title} + + )} + {description && {description}} + {image?.type && IMAGE_TYPES.includes(image.type) && ( + + )} + + ) + ); + }); +} + +LinkPreviewer.displayName = 'ReportLinkPreview'; + +export default LinkPreviewer; From 20463d1c466e0632c0878636811f7f01470f6b62 Mon Sep 17 00:00:00 2001 From: Jakub Szymczak Date: Wed, 13 Dec 2023 10:15:53 +0100 Subject: [PATCH 2/6] fix PR comments --- src/pages/home/report/LinkPreviewer.tsx | 41 ++++--------------------- src/types/onyx/ReportAction.ts | 36 +++++++++++++++++++++- 2 files changed, 41 insertions(+), 36 deletions(-) diff --git a/src/pages/home/report/LinkPreviewer.tsx b/src/pages/home/report/LinkPreviewer.tsx index c9f50ec91a48..cdc7bfff23be 100644 --- a/src/pages/home/report/LinkPreviewer.tsx +++ b/src/pages/home/report/LinkPreviewer.tsx @@ -6,45 +6,12 @@ import useTheme from '@styles/themes/useTheme'; import useStyleUtils from '@styles/useStyleUtils'; import useThemeStyles from '@styles/useThemeStyles'; import variables from '@styles/variables'; +import type {LinkMetadata} from '@src/types/onyx/ReportAction'; const IMAGE_TYPES = ['jpg', 'jpeg', 'png']; const MAX_IMAGE_HEIGHT = 180; const MAX_IMAGE_WIDTH = 340; -type ImageData = { - /** The height of the image. */ - height: number; - - /** The width of the image. */ - width: number; - - /** The URL of the image. */ - url: string; - - /** The type of the image. */ - type?: string; -}; - -type LinkMetadata = { - /** The URL of the link. */ - url?: string; - - /** A description of the link. */ - description?: string; - - /** The title of the link. */ - title?: string; - - /** The publisher of the link. */ - publisher?: string; - - /** The image associated with the link. */ - image?: ImageData; - - /** The provider logo associated with the link. */ - logo?: ImageData; -}; - type LinkPreviewerProps = { /** Data about links provided in message. */ linkMetadata?: LinkMetadata[]; @@ -58,8 +25,12 @@ function LinkPreviewer({linkMetadata = [], maxAmountOfPreviews = -1}: LinkPrevie const styles = useThemeStyles(); const StyleUtils = useStyleUtils(); const uniqueLinks = linkMetadata.filter((link, index, self) => self.findIndex((t) => t.url === link.url) === index); - const linksToShow = uniqueLinks.slice(0, maxAmountOfPreviews >= 0 ? Math.min(maxAmountOfPreviews, linkMetadata.length) : linkMetadata.length); + const maxAmmountOfLinks = maxAmountOfPreviews >= 0 ? Math.min(maxAmountOfPreviews, linkMetadata.length) : linkMetadata.length; + const linksToShow = uniqueLinks.slice(0, maxAmmountOfLinks); return linksToShow.map((linkData) => { + if (Array.isArray(linkData)) { + return; + } const {description, image, title, logo, publisher, url} = linkData; return ( linkData && ( diff --git a/src/types/onyx/ReportAction.ts b/src/types/onyx/ReportAction.ts index a0e90f4e9c34..60311e844054 100644 --- a/src/types/onyx/ReportAction.ts +++ b/src/types/onyx/ReportAction.ts @@ -144,9 +144,43 @@ type ReportActionBase = { isNewestReportAction?: boolean; }; +type ImageData = { + /** The height of the image. */ + height: number; + + /** The width of the image. */ + width: number; + + /** The URL of the image. */ + url: string; + + /** The type of the image. */ + type?: string; +}; + +type LinkMetadata = { + /** The URL of the link. */ + url?: string; + + /** A description of the link. */ + description?: string; + + /** The title of the link. */ + title?: string; + + /** The publisher of the link. */ + publisher?: string; + + /** The image associated with the link. */ + image?: ImageData; + + /** The provider logo associated with the link. */ + logo?: ImageData; +}; + type ReportAction = ReportActionBase & OriginalMessage; type ReportActions = Record; export default ReportAction; -export type {Message, ReportActions}; +export type {Message, ReportActions, LinkMetadata}; From 554727957f9e212678c2943045c63872a026175c Mon Sep 17 00:00:00 2001 From: Jakub Szymczak Date: Wed, 13 Dec 2023 10:24:49 +0100 Subject: [PATCH 3/6] fix typescript errors --- src/pages/home/report/LinkPreviewer.tsx | 2 +- src/types/onyx/ReportAction.ts | 37 ++----------------------- 2 files changed, 4 insertions(+), 35 deletions(-) diff --git a/src/pages/home/report/LinkPreviewer.tsx b/src/pages/home/report/LinkPreviewer.tsx index cdc7bfff23be..9b2bd2c45dc2 100644 --- a/src/pages/home/report/LinkPreviewer.tsx +++ b/src/pages/home/report/LinkPreviewer.tsx @@ -64,7 +64,7 @@ function LinkPreviewer({linkMetadata = [], maxAmountOfPreviews = -1}: LinkPrevie )} {description && {description}} - {image?.type && IMAGE_TYPES.includes(image.type) && ( + {image?.type && IMAGE_TYPES.includes(image.type) && image.width && image.height && ( ; From ed74e29cf6b0be7b31ae6365dfaf7c3d81d42d39 Mon Sep 17 00:00:00 2001 From: Jakub Szymczak Date: Thu, 14 Dec 2023 15:14:05 +0100 Subject: [PATCH 4/6] fix PR comments --- src/pages/home/report/LinkPreviewer.tsx | 92 ++++++++++++------------- 1 file changed, 45 insertions(+), 47 deletions(-) diff --git a/src/pages/home/report/LinkPreviewer.tsx b/src/pages/home/report/LinkPreviewer.tsx index 9b2bd2c45dc2..cd5895c062dc 100644 --- a/src/pages/home/report/LinkPreviewer.tsx +++ b/src/pages/home/report/LinkPreviewer.tsx @@ -24,64 +24,62 @@ function LinkPreviewer({linkMetadata = [], maxAmountOfPreviews = -1}: LinkPrevie const theme = useTheme(); const styles = useThemeStyles(); const StyleUtils = useStyleUtils(); - const uniqueLinks = linkMetadata.filter((link, index, self) => self.findIndex((t) => t.url === link.url) === index); + const uniqueLinks = linkMetadata.filter((link, index) => linkMetadata.findIndex(({url}) => url === link.url) === index); const maxAmmountOfLinks = maxAmountOfPreviews >= 0 ? Math.min(maxAmountOfPreviews, linkMetadata.length) : linkMetadata.length; const linksToShow = uniqueLinks.slice(0, maxAmmountOfLinks); return linksToShow.map((linkData) => { - if (Array.isArray(linkData)) { + if (!linkData && Array.isArray(linkData)) { return; } const {description, image, title, logo, publisher, url} = linkData; return ( - linkData && ( - - - {logo && ( - - )} - {publisher && ( - - {publisher} - - )} - - {title && url && ( - - {title} - - )} - {description && {description}} - {image?.type && IMAGE_TYPES.includes(image.type) && image.width && image.height && ( + + + {logo && ( )} + {publisher && ( + + {publisher} + + )} - ) + {title && url && ( + + {title} + + )} + {description && {description}} + {image?.type && IMAGE_TYPES.includes(image.type) && image.width && image.height && ( + + )} + ); }); } From 23a9a01bb9e3f4ff6b73db07de690c270bf179a2 Mon Sep 17 00:00:00 2001 From: Jakub Szymczak Date: Mon, 18 Dec 2023 12:54:28 +0100 Subject: [PATCH 5/6] fix comments --- src/pages/home/report/LinkPreviewer.tsx | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/pages/home/report/LinkPreviewer.tsx b/src/pages/home/report/LinkPreviewer.tsx index d0952c0365d9..dd6a2b9ab61e 100644 --- a/src/pages/home/report/LinkPreviewer.tsx +++ b/src/pages/home/report/LinkPreviewer.tsx @@ -20,11 +20,27 @@ type LinkPreviewerProps = { maxAmountOfPreviews?: number; }; +function filterNonUniqueLinks(linkMetadata: LinkMetadata[]): LinkMetadata[] { + const map = new Map(); + const result: LinkMetadata[] = []; + + linkMetadata.forEach((item) => { + if (!item.url || map.has(item.url)) { + return; + } + + map.set(item.url, item.url); + result.push(item); + }); + + return result; +} + function LinkPreviewer({linkMetadata = [], maxAmountOfPreviews = -1}: LinkPreviewerProps) { const theme = useTheme(); const styles = useThemeStyles(); const StyleUtils = useStyleUtils(); - const uniqueLinks = linkMetadata.filter((link, index) => linkMetadata.findIndex(({url}) => url === link.url) === index); + const uniqueLinks = filterNonUniqueLinks(linkMetadata); const maxAmmountOfLinks = maxAmountOfPreviews >= 0 ? Math.min(maxAmountOfPreviews, linkMetadata.length) : linkMetadata.length; const linksToShow = uniqueLinks.slice(0, maxAmmountOfLinks); return linksToShow.map((linkData) => { From 84a862be15d875b50212d787c5586cb610a97c79 Mon Sep 17 00:00:00 2001 From: Jakub Szymczak Date: Mon, 18 Dec 2023 12:55:42 +0100 Subject: [PATCH 6/6] fix naming --- src/pages/home/report/LinkPreviewer.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pages/home/report/LinkPreviewer.tsx b/src/pages/home/report/LinkPreviewer.tsx index dd6a2b9ab61e..209096d2fa15 100644 --- a/src/pages/home/report/LinkPreviewer.tsx +++ b/src/pages/home/report/LinkPreviewer.tsx @@ -21,15 +21,15 @@ type LinkPreviewerProps = { }; function filterNonUniqueLinks(linkMetadata: LinkMetadata[]): LinkMetadata[] { - const map = new Map(); + const linksMap = new Map(); const result: LinkMetadata[] = []; linkMetadata.forEach((item) => { - if (!item.url || map.has(item.url)) { + if (!item.url || linksMap.has(item.url)) { return; } - map.set(item.url, item.url); + linksMap.set(item.url, item.url); result.push(item); });