import React, { useMemo } from 'react'; import { Image, ImageProps, StyleSheet, View } from 'react-native'; import type { Attachment } from 'stream-chat'; import { useComponentsContext } from '../../../contexts/componentsContext/ComponentsContext'; import { MessagesContextValue, useMessagesContext, } from '../../../contexts/messagesContext/MessagesContext'; import { useTheme } from '../../../contexts/themeContext/ThemeContext'; import { useLoadingImage } from '../../../hooks/useLoadingImage'; import { makeImageCompatibleUrl } from '../../../utils/utils'; import { GiphyBadge } from '../../ui/Badge/GiphyBadge'; export type GiphyImagePropsWithContext = Pick & { ImageComponent?: React.ComponentType; } & { attachment: Attachment; /** * Whether to render the preview image or the full image */ preview?: boolean; }; const GiphyImageWithContext = (props: GiphyImagePropsWithContext) => { const { attachment, giphyVersion, ImageComponent = Image, preview = false } = props; const { ImageLoadingFailedIndicator, ImageLoadingIndicator } = useComponentsContext(); const { giphy: giphyData, image_url, thumb_url, type } = attachment; const { isLoadingImage, isLoadingImageError, setLoadingImage, setLoadingImageError, onReloadImage, } = useLoadingImage(); const { theme: { messageItemView: { giphy: { giphyMask, giphy, imageIndicatorContainer }, }, }, } = useTheme(); const styles = useStyles(); const onLoadStart = () => { setLoadingImage(true); setLoadingImageError(false); }; const onLoadEnd = () => { setLoadingImage(false); }; const onError = () => { setLoadingImage(false); setLoadingImageError(true); }; let uri = image_url || thumb_url; const giphyDimensions: { height?: number; width?: number } = {}; if (type === 'giphy' && giphyData) { const giphyVersionInfo = giphyData[giphyVersion]; uri = giphyVersionInfo.url; giphyDimensions.height = parseFloat(giphyVersionInfo.height); giphyDimensions.width = parseFloat(giphyVersionInfo.width); } if (!uri) { return null; } return ( {isLoadingImageError && ( )} {isLoadingImage && ( )} ); }; const areEqual = (prevProps: GiphyImagePropsWithContext, nextProps: GiphyImagePropsWithContext) => { const { attachment: { actions: prevActions, image_url: prevImageUrl, thumb_url: prevThumbUrl }, giphyVersion: prevGiphyVersion, } = prevProps; const { attachment: { actions: nextActions, image_url: nextImageUrl, thumb_url: nextThumbUrl }, giphyVersion: nextGiphyVersion, } = nextProps; const imageUrlEqual = prevImageUrl === nextImageUrl; if (!imageUrlEqual) { return false; } const thumbUrlEqual = prevThumbUrl === nextThumbUrl; if (!thumbUrlEqual) { return false; } const actionsEqual = Array.isArray(prevActions) === Array.isArray(nextActions) && ((Array.isArray(prevActions) && Array.isArray(nextActions) && prevActions.length === nextActions.length) || prevActions === nextActions); if (!actionsEqual) { return false; } const giphyVersionEqual = prevGiphyVersion === nextGiphyVersion; if (!giphyVersionEqual) { return false; } return true; }; const MemoizedGiphyImage = React.memo( GiphyImageWithContext, areEqual, ) as typeof GiphyImageWithContext; export type GiphyImageProps = Partial & { attachment: Attachment; }; /** * UI component for card in attachments. */ export const GiphyImage = (props: GiphyImageProps) => { const { ImageComponent } = useComponentsContext(); const { giphyVersion } = useMessagesContext(); return ( ); }; GiphyImage.displayName = 'GiphyImage'; const useStyles = () => { return useMemo(() => { return StyleSheet.create({ giphyMask: { bottom: 8, left: 8, position: 'absolute', }, giphy: { alignSelf: 'center', }, imageContainer: {}, imageIndicatorContainer: { alignItems: 'center', justifyContent: 'center', }, }); }, []); };