diff --git a/app/components/markdown/markdown.tsx b/app/components/markdown/markdown.tsx index b0182e885..db51bf7d1 100644 --- a/app/components/markdown/markdown.tsx +++ b/app/components/markdown/markdown.tsx @@ -55,7 +55,7 @@ type MarkdownProps = { disableTables?: boolean; enableLatex: boolean; enableInlineLatex: boolean; - imagesMetadata?: Record; + imagesMetadata?: Record; isEdited?: boolean; isReplyPost?: boolean; isSearchResult?: boolean; diff --git a/app/components/markdown/markdown_image/index.tsx b/app/components/markdown/markdown_image/index.tsx index 955f29581..15d9b9621 100644 --- a/app/components/markdown/markdown_image/index.tsx +++ b/app/components/markdown/markdown_image/index.tsx @@ -36,7 +36,7 @@ import type {GalleryItemType} from '@typings/screens/gallery'; type MarkdownImageProps = { disabled?: boolean; errorTextStyle: StyleProp; - imagesMetadata: Record; + imagesMetadata: Record; isReplyPost?: boolean; linkDestination?: string; layoutHeight?: number; @@ -90,7 +90,7 @@ const MarkdownImage = ({ const fileInfo = useMemo(() => { const link = decodeURIComponent(uri); let filename = parseUrl(link.substr(link.lastIndexOf('/'))).pathname.replace('/', ''); - let extension = metadata.format || filename.split('.').pop(); + let extension = metadata?.format || filename.split('.').pop(); if (extension === filename) { const ext = filename.indexOf('.') === -1 ? '.png' : filename.substring(filename.lastIndexOf('.')); filename = `${filename}${ext}`; diff --git a/app/components/markdown/markdown_table_image/index.tsx b/app/components/markdown/markdown_table_image/index.tsx index 2558a19e7..c7a6606a7 100644 --- a/app/components/markdown/markdown_table_image/index.tsx +++ b/app/components/markdown/markdown_table_image/index.tsx @@ -18,7 +18,7 @@ import type {GalleryItemType} from '@typings/screens/gallery'; type MarkdownTableImageProps = { disabled?: boolean; - imagesMetadata: Record; + imagesMetadata: Record; location?: string; postId: string; serverURL?: string; @@ -55,7 +55,8 @@ const MarkTableImage = ({disabled, imagesMetadata, location, postId, serverURL, }; const getFileInfo = () => { - const {height, width} = metadata; + const height = metadata?.height || 0; + const width = metadata?.width || 0; const link = decodeURIComponent(getImageSource()); let filename = parseUrl(link.substr(link.lastIndexOf('/'))).pathname.replace('/', ''); let extension = filename.split('.').pop(); @@ -109,7 +110,7 @@ const MarkTableImage = ({disabled, imagesMetadata, location, postId, serverURL, /> ); } else { - const {height, width} = calculateDimensions(metadata.height, metadata.width, 100, 100); + const {height, width} = calculateDimensions(metadata?.height, metadata?.width, 100, 100); image = ( { setError(true); @@ -66,8 +66,8 @@ const ImagePreview = ({expandedLink, isReplyPost, layoutWidth, link, location, m id: fileId, postId, uri: imageUrl, - width: imageProps.width, - height: imageProps.height, + width: imageProps?.width || 0, + height: imageProps?.height || 0, name: extractFilenameFromUrl(imageUrl) || 'imagePreview.png', mime_type: lookupMimeType(imageUrl) || 'image/png', type: 'image', diff --git a/app/components/post_list/post/body/content/image_preview/index.ts b/app/components/post_list/post/body/content/image_preview/index.ts index f9f6e1e35..4a4e68e17 100644 --- a/app/components/post_list/post/body/content/image_preview/index.ts +++ b/app/components/post_list/post/body/content/image_preview/index.ts @@ -12,8 +12,8 @@ import ImagePreview from './image_preview'; import type {WithDatabaseArgs} from '@typings/database/database'; -const enhance = withObservables(['metadata'], ({database, metadata}: WithDatabaseArgs & {metadata: PostMetadata}) => { - const link = metadata.embeds?.[0].url; +const enhance = withObservables(['metadata'], ({database, metadata}: WithDatabaseArgs & {metadata: PostMetadata | undefined | null}) => { + const link = metadata?.embeds?.[0].url; return { expandedLink: observeExpandedLinks(database).pipe( diff --git a/app/components/post_list/post/body/content/index.tsx b/app/components/post_list/post/body/content/index.tsx index d755f3c49..38ae3b79b 100644 --- a/app/components/post_list/post/body/content/index.tsx +++ b/app/components/post_list/post/body/content/index.tsx @@ -46,7 +46,7 @@ const Content = ({isReplyPost, layoutWidth, location, post, theme}: ContentProps isReplyPost={isReplyPost} layoutWidth={layoutWidth} location={location} - metadata={post.metadata!} + metadata={post.metadata} postId={post.id} theme={theme} /> @@ -57,7 +57,7 @@ const Content = ({isReplyPost, layoutWidth, location, post, theme}: ContentProps ); } @@ -67,7 +67,7 @@ const Content = ({isReplyPost, layoutWidth, location, post, theme}: ContentProps isReplyPost={isReplyPost} layoutWidth={layoutWidth} location={location} - metadata={post.metadata!} + metadata={post.metadata} postId={post.id} removeLinkPreview={post.props?.remove_link_preview === 'true'} theme={theme} @@ -81,7 +81,7 @@ const Content = ({isReplyPost, layoutWidth, location, post, theme}: ContentProps channelId={post.channelId} layoutWidth={layoutWidth} location={location} - metadata={post.metadata!} + metadata={post.metadata} postId={post.id} theme={theme} /> diff --git a/app/components/post_list/post/body/content/message_attachments/attachment_fields.tsx b/app/components/post_list/post/body/content/message_attachments/attachment_fields.tsx index 86c84ec23..3d665938f 100644 --- a/app/components/post_list/post/body/content/message_attachments/attachment_fields.tsx +++ b/app/components/post_list/post/body/content/message_attachments/attachment_fields.tsx @@ -15,7 +15,7 @@ type Props = { channelId: string; fields: MessageAttachmentField[]; location: string; - metadata?: PostMetadata; + metadata?: PostMetadata | null; textStyles?: MarkdownTextStyles; theme: Theme; } diff --git a/app/components/post_list/post/body/content/message_attachments/attachment_pretext.tsx b/app/components/post_list/post/body/content/message_attachments/attachment_pretext.tsx index efafa817d..fc23e368b 100644 --- a/app/components/post_list/post/body/content/message_attachments/attachment_pretext.tsx +++ b/app/components/post_list/post/body/content/message_attachments/attachment_pretext.tsx @@ -13,7 +13,7 @@ type Props = { blockStyles?: MarkdownBlockStyles; channelId: string; location: string; - metadata?: PostMetadata; + metadata?: PostMetadata | null; textStyles?: MarkdownTextStyles; theme: Theme; value?: string; diff --git a/app/components/post_list/post/body/content/message_attachments/attachment_text.tsx b/app/components/post_list/post/body/content/message_attachments/attachment_text.tsx index f6d72eb76..cebf0d2ba 100644 --- a/app/components/post_list/post/body/content/message_attachments/attachment_text.tsx +++ b/app/components/post_list/post/body/content/message_attachments/attachment_text.tsx @@ -17,7 +17,7 @@ type Props = { channelId: string; hasThumbnail?: boolean; location: string; - metadata?: PostMetadata; + metadata?: PostMetadata | null; textStyles?: MarkdownTextStyles; theme: Theme; value?: string; diff --git a/app/components/post_list/post/body/content/message_attachments/index.tsx b/app/components/post_list/post/body/content/message_attachments/index.tsx index 866f3d3e8..986714445 100644 --- a/app/components/post_list/post/body/content/message_attachments/index.tsx +++ b/app/components/post_list/post/body/content/message_attachments/index.tsx @@ -11,7 +11,7 @@ type Props = { channelId: string; layoutWidth?: number; location: string; - metadata?: PostMetadata; + metadata?: PostMetadata | undefined | null; postId: string; theme: Theme; } diff --git a/app/components/post_list/post/body/content/message_attachments/message_attachment.tsx b/app/components/post_list/post/body/content/message_attachments/message_attachment.tsx index 5cedb5c37..7b00e6268 100644 --- a/app/components/post_list/post/body/content/message_attachments/message_attachment.tsx +++ b/app/components/post_list/post/body/content/message_attachments/message_attachment.tsx @@ -24,7 +24,7 @@ type Props = { channelId: string; layoutWidth?: number; location: string; - metadata?: PostMetadata; + metadata?: PostMetadata | null; postId: string; theme: Theme; } @@ -142,7 +142,7 @@ export default function MessageAttachment({attachment, channelId, layoutWidth, l {Boolean(metadata?.images?.[attachment.image_url]) && { }; }); -const selectOpenGraphData = (url: string, metadata: PostMetadata) => { - if (!metadata.embeds) { +const selectOpenGraphData = (url: string, metadata: PostMetadata | undefined | null) => { + if (!metadata?.embeds) { return undefined; } @@ -61,7 +61,7 @@ const selectOpenGraphData = (url: string, metadata: PostMetadata) => { const Opengraph = ({isReplyPost, layoutWidth, location, metadata, postId, showLinkPreviews, theme}: OpengraphProps) => { const intl = useIntl(); - const link = metadata.embeds![0]!.url; + const link = metadata?.embeds![0]!.url || ''; const openGraphData = selectOpenGraphData(link, metadata); if (!showLinkPreviews || !openGraphData) { @@ -73,7 +73,7 @@ const Opengraph = ({isReplyPost, layoutWidth, location, metadata, postId, showLi openGraphData?.images && openGraphData.images instanceof Array && openGraphData.images.length && - metadata.images); + metadata?.images); const goToLink = () => { const onError = () => { diff --git a/app/components/post_list/post/body/content/opengraph/opengraph_image/index.tsx b/app/components/post_list/post/body/content/opengraph/opengraph_image/index.tsx index a895b665d..70a7cc55d 100644 --- a/app/components/post_list/post/body/content/opengraph/opengraph_image/index.tsx +++ b/app/components/post_list/post/body/content/opengraph/opengraph_image/index.tsx @@ -23,7 +23,7 @@ type OpengraphImageProps = { isReplyPost: boolean; layoutWidth?: number; location: string; - metadata: PostMetadata; + metadata: PostMetadata | undefined | null; openGraphImages: never[]; postId: string; theme: Theme; @@ -68,7 +68,7 @@ const OpengraphImage = ({isReplyPost, layoutWidth, location, metadata, openGraph }), [isReplyPost, dimensions]); const bestImage = getNearestPoint(bestDimensions, openGraphImages, 'width', 'height'); const imageUrl = (bestImage.secure_url || bestImage.url)!; - const imagesMetadata = metadata.images; + const imagesMetadata = metadata?.images; let ogImage; if (imagesMetadata && imagesMetadata[imageUrl]) { diff --git a/app/components/post_list/post/body/content/youtube/index.tsx b/app/components/post_list/post/body/content/youtube/index.tsx index 34b5103b1..7d23054c7 100644 --- a/app/components/post_list/post/body/content/youtube/index.tsx +++ b/app/components/post_list/post/body/content/youtube/index.tsx @@ -18,7 +18,7 @@ import YouTubeLogo from './youtube.svg'; type YouTubeProps = { isReplyPost: boolean; layoutWidth?: number; - metadata: PostMetadata; + metadata: PostMetadata | undefined | null; } const MAX_YOUTUBE_IMAGE_HEIGHT = 280; @@ -61,7 +61,7 @@ const YouTube = ({isReplyPost, layoutWidth, metadata}: YouTubeProps) => { const isTablet = useIsTablet(); const theme = useTheme(); const styles = getStyleSheet(theme); - const link = metadata.embeds![0].url; + const link = metadata?.embeds![0].url; const videoId = getYouTubeVideoId(link); const dimensions = calculateDimensions( MAX_YOUTUBE_IMAGE_HEIGHT, @@ -70,6 +70,10 @@ const YouTube = ({isReplyPost, layoutWidth, metadata}: YouTubeProps) => { ); const playYouTubeVideo = useCallback(() => { + if (!link) { + return; + } + const onError = () => { Alert.alert( intl.formatMessage({ @@ -87,7 +91,7 @@ const YouTube = ({isReplyPost, layoutWidth, metadata}: YouTubeProps) => { }, [link, intl.locale]); let imgUrl; - if (metadata.images) { + if (metadata?.images) { imgUrl = Object.keys(metadata.images)[0]; } @@ -96,6 +100,10 @@ const YouTube = ({isReplyPost, layoutWidth, metadata}: YouTubeProps) => { imgUrl = `https://i.ytimg.com/vi/${videoId}/hqdefault.jpg`; } + if (!link) { + return null; + } + return ( { +export const calculateDimensions = (height?: number, width?: number, viewPortWidth = 0, viewPortHeight = 0) => { 'worklet'; if (!height || !width) { diff --git a/app/utils/url/index.ts b/app/utils/url/index.ts index 4208f2eee..c4af29937 100644 --- a/app/utils/url/index.ts +++ b/app/utils/url/index.ts @@ -150,7 +150,11 @@ export function getScheme(url: string) { return match && match[1]; } -export function getYouTubeVideoId(link: string) { +export function getYouTubeVideoId(link?: string) { + if (!link) { + return ''; + } + // https://youtube.com/watch?v= let match = (/youtube\.com\/watch\?\S*\bv=([a-zA-Z0-9_-]{6,11})/g).exec(link); if (match) { diff --git a/types/api/posts.d.ts b/types/api/posts.d.ts index 51da8a0bf..e75f9c479 100644 --- a/types/api/posts.d.ts +++ b/types/api/posts.d.ts @@ -41,7 +41,7 @@ type PostMetadata = { embeds?: PostEmbed[]; emojis?: CustomEmoji[]; files?: FileInfo[]; - images?: Dictionary; + images?: Dictionary; reactions?: Reaction[]; priority?: PostPriorityData; };