Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
139 changes: 0 additions & 139 deletions src/pages/home/report/LinkPreviewer.js

This file was deleted.

105 changes: 105 additions & 0 deletions src/pages/home/report/LinkPreviewer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import React from 'react';
import {Image, View} from 'react-native';
import Text from '@components/Text';
import TextLink from '@components/TextLink';
import useStyleUtils from '@hooks/useStyleUtils';
import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/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 LinkPreviewerProps = {
/** Data about links provided in message. */
linkMetadata?: LinkMetadata[];

/** Maximum amount of visible link previews. -1 means unlimited amount of previews */
maxAmountOfPreviews?: number;
};

function filterNonUniqueLinks(linkMetadata: LinkMetadata[]): LinkMetadata[] {
const linksMap = new Map<string, string>();
const result: LinkMetadata[] = [];

linkMetadata.forEach((item) => {
if (!item.url || linksMap.has(item.url)) {
return;
}

linksMap.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 = filterNonUniqueLinks(linkMetadata);
const maxAmmountOfLinks = maxAmountOfPreviews >= 0 ? Math.min(maxAmountOfPreviews, linkMetadata.length) : linkMetadata.length;
const linksToShow = uniqueLinks.slice(0, maxAmmountOfLinks);
return linksToShow.map((linkData) => {
if (!linkData && Array.isArray(linkData)) {
return;
}
const {description, image, title, logo, publisher, url} = linkData;
return (
<View
style={styles.linkPreviewWrapper}
key={url}
>
<View style={styles.flexRow}>
{logo && (
<Image
style={styles.linkPreviewLogoImage}
source={{uri: logo.url}}
/>
)}
{publisher && (
<Text
fontSize={variables.fontSizeLabel}
style={styles.pl2}
>
{publisher}
</Text>
)}
</View>
{title && url && (
<TextLink
fontSize={variables.fontSizeNormal}
style={[styles.mv2, StyleUtils.getTextColorStyle(theme.link), styles.alignSelfStart]}
href={url}
>
{title}
</TextLink>
)}
{description && <Text fontSize={variables.fontSizeNormal}>{description}</Text>}
{image?.type && IMAGE_TYPES.includes(image.type) && image.width && image.height && (
<Image
style={[
styles.linkPreviewImage,
{
aspectRatio: image.width / image.height,
maxHeight: Math.min(image.height, MAX_IMAGE_HEIGHT),

// Calculate maximum width when image is too tall, so it doesn't move away from left
maxWidth: Math.min((Math.min(image.height, MAX_IMAGE_HEIGHT) / image.height) * image.width, MAX_IMAGE_WIDTH),
},
]}
resizeMode="contain"
source={{uri: image.url}}
/>
)}
</View>
);
});
}

LinkPreviewer.displayName = 'ReportLinkPreview';

export default LinkPreviewer;
5 changes: 4 additions & 1 deletion src/types/onyx/ReportAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ type ImageMetadata = {

/** The URL of the image. */
url?: string;

/** The type of the image. */
type?: string;
};

type LinkMetadata = {
Expand Down Expand Up @@ -197,4 +200,4 @@ type ReportAction = ReportActionBase & OriginalMessage;
type ReportActions = Record<string, ReportAction>;

export default ReportAction;
export type {ReportActions, ReportActionBase, Message};
export type {ReportActions, ReportActionBase, Message, LinkMetadata};