import React from 'react'; import { Image, StyleSheet, Text, TouchableOpacity, View } from 'react-native'; import { MessageContextValue, useMessageContext, } from '../../contexts/messageContext/MessageContext'; import { MessagesContextValue, useMessagesContext, } from '../../contexts/messagesContext/MessagesContext'; import { useTheme } from '../../contexts/themeContext/ThemeContext'; import { Left } from '../../icons/Left'; import { Lightning } from '../../icons/Lightning'; import { Right } from '../../icons/Right'; import { makeImageCompatibleUrl } from '../../utils/utils'; import type { Attachment } from 'stream-chat'; import type { DefaultAttachmentType, DefaultChannelType, DefaultCommandType, DefaultEventType, DefaultMessageType, DefaultReactionType, DefaultUserType, UnknownType, } from '../../types/types'; const styles = StyleSheet.create({ cancel: { fontSize: 14, fontWeight: '600', paddingVertical: 16, }, cancelContainer: { alignItems: 'center', borderRightWidth: 1, flex: 1, justifyContent: 'center', }, container: { overflow: 'hidden', width: 256, }, giphy: { borderTopLeftRadius: 8, borderTopRightRadius: 8, height: 140, }, giphyContainer: { alignItems: 'center', borderRadius: 12, flexDirection: 'row', height: 24, justifyContent: 'center', width: 68, }, giphyMask: { bottom: 8, left: 8, position: 'absolute', }, giphyText: { fontSize: 11, fontWeight: '600' }, margin: { margin: 8, }, row: { flexDirection: 'row' }, selectionContainer: { borderRadius: 8, borderWidth: 1, overflow: 'hidden', width: 250, }, selector: { alignItems: 'center', borderBottomWidth: 1, flexDirection: 'row', justifyContent: 'space-between', paddingBottom: 8, paddingHorizontal: 8, }, send: { fontSize: 14, fontWeight: '600', paddingVertical: 16, }, sendContainer: { alignItems: 'center', flex: 1, justifyContent: 'center' }, shuffleButton: { alignItems: 'center', borderRadius: 16, borderWidth: 1, height: 32, justifyContent: 'center', width: 32, }, title: { fontSize: 14, fontStyle: 'italic', fontWeight: '500', }, }); export type GiphyPropsWithContext< At extends UnknownType = DefaultAttachmentType, Ch extends UnknownType = DefaultChannelType, Co extends string = DefaultCommandType, Ev extends UnknownType = DefaultEventType, Me extends UnknownType = DefaultMessageType, Re extends UnknownType = DefaultReactionType, Us extends UnknownType = DefaultUserType, > = Pick< MessageContextValue, 'handleAction' | 'onLongPress' | 'onPress' | 'onPressIn' | 'preventPress' > & Pick, 'additionalTouchableProps'> & { attachment: Attachment; }; const GiphyWithContext = < At extends UnknownType = DefaultAttachmentType, Ch extends UnknownType = DefaultChannelType, Co extends string = DefaultCommandType, Ev extends UnknownType = DefaultEventType, Me extends UnknownType = DefaultMessageType, Re extends UnknownType = DefaultReactionType, Us extends UnknownType = DefaultUserType, >( props: GiphyPropsWithContext, ) => { const { additionalTouchableProps, attachment, handleAction, onLongPress, onPress, onPressIn, preventPress, } = props; const { actions, image_url, thumb_url, title, type } = attachment; const { theme: { colors: { accent_blue, black, border, grey, overlay_dark, white }, messageSimple: { giphy: { cancel, cancelContainer, container, giphy, giphyContainer, giphyMask, giphyText, selectionContainer, selector, send, sendContainer, shuffleButton, title: titleStyle, }, }, }, } = useTheme(); const uri = image_url || thumb_url; if (!uri) return null; return actions ? ( {type?.toUpperCase()} handleAction('image_action', 'shuffle')} style={[styles.shuffleButton, { borderColor: border }, shuffleButton]} > {`"${title}"`} { if (actions?.[1].name && actions?.[1].value && handleAction) { handleAction(actions[1].name, actions[1].value); } }} style={[styles.shuffleButton, shuffleButton]} > { if (actions?.[2].name && actions?.[2].value && handleAction) { handleAction(actions[2].name, actions[2].value); } }} style={[styles.cancelContainer, { borderRightColor: border }, cancelContainer]} > {actions?.[2].text} { if (actions?.[0].name && actions?.[0].value && handleAction) { handleAction(actions[0].name, actions[0].value); } }} style={[styles.sendContainer, sendContainer]} > {actions?.[0].text} ) : ( { if (onLongPress) { onLongPress({ emitter: 'giphy', event, }); } }} onPress={(event) => { if (onPress) { onPress({ emitter: 'giphy', event, }); } }} onPressIn={(event) => { if (onPressIn) { onPressIn({ emitter: 'giphy', event, }); } }} style={[styles.container, container]} testID='giphy-attachment' {...additionalTouchableProps} > {type?.toUpperCase()} ); }; const areEqual = < At extends UnknownType = DefaultAttachmentType, Ch extends UnknownType = DefaultChannelType, Co extends string = DefaultCommandType, Ev extends UnknownType = DefaultEventType, Me extends UnknownType = DefaultMessageType, Re extends UnknownType = DefaultReactionType, Us extends UnknownType = DefaultUserType, >( prevProps: GiphyPropsWithContext, nextProps: GiphyPropsWithContext, ) => { const { attachment: { actions: prevActions, image_url: prevImageUrl, thumb_url: prevThumbUrl }, } = prevProps; const { attachment: { actions: nextActions, image_url: nextImageUrl, thumb_url: nextThumbUrl }, } = 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; return true; }; const MemoizedGiphy = React.memo(GiphyWithContext, areEqual) as typeof GiphyWithContext; export type GiphyProps< At extends UnknownType = DefaultAttachmentType, Ch extends UnknownType = DefaultChannelType, Co extends string = DefaultCommandType, Ev extends UnknownType = DefaultEventType, Me extends UnknownType = DefaultMessageType, Re extends UnknownType = DefaultReactionType, Us extends UnknownType = DefaultUserType, > = Partial< Pick, 'onLongPress' | 'onPressIn'> & Pick, 'additionalTouchableProps'> > & { attachment: Attachment; }; /** * UI component for card in attachments. */ export const Giphy = < At extends UnknownType = DefaultAttachmentType, Ch extends UnknownType = DefaultChannelType, Co extends string = DefaultCommandType, Ev extends UnknownType = DefaultEventType, Me extends UnknownType = DefaultMessageType, Re extends UnknownType = DefaultReactionType, Us extends UnknownType = DefaultUserType, >( props: GiphyProps, ) => { const { handleAction, onLongPress, onPress, onPressIn, preventPress } = useMessageContext(); const { additionalTouchableProps } = useMessagesContext(); return ( ); }; Giphy.displayName = 'Giphy{messageSimple{giphy}}';