UNPKG

@sendbird/uikit-react-native

Version:

Sendbird UIKit for React Native: A feature-rich and customizable chat UI kit with messaging, channel management, and user authentication.

307 lines 10.6 kB
import React, { useContext } from 'react'; import { TouchableOpacity, View } from 'react-native'; import { Avatar, Box, Divider, Icon, Text, createStyleSheet, useAlert, useBottomSheet, useToast, useUIKitTheme } from '@sendbird/uikit-react-native-foundation'; import { Logger, getAvailableUriFromFileMessage, getFileExtension, getFileType, isMyMessage, isVoiceMessage, shouldRenderReaction, toMegabyte } from '@sendbird/uikit-utils'; import ThreadParentMessageRenderer from '../../../components/ThreadParentMessageRenderer'; import { useLocalization, usePlatformService, useSBUHandlers, useSendbirdChat } from '../../../hooks/useContext'; import SBUUtils from '../../../libs/SBUUtils'; import { GroupChannelThreadContexts } from '../module/moduleContext'; import { ReactionAddons } from './../../../components/ReactionAddons'; const GroupChannelThreadParentMessageInfo = props => { var _parentMessage$sender, _parentMessage$thread; const { channel, parentMessage, setMessageToEdit } = useContext(GroupChannelThreadContexts.Fragment); const { STRINGS } = useLocalization(); const { colors } = useUIKitTheme(); const { sbOptions } = useSendbirdChat(); const nickName = ((_parentMessage$sender = parentMessage.sender) === null || _parentMessage$sender === void 0 ? void 0 : _parentMessage$sender.nickname) || STRINGS.LABELS.USER_NO_NAME; const messageTimestamp = STRINGS.GROUP_CHANNEL_THREAD.PARENT_MESSAGE_TIME(parentMessage); const replyCountText = STRINGS.GROUP_CHANNEL_THREAD.REPLY_COUNT(((_parentMessage$thread = parentMessage.threadInfo) === null || _parentMessage$thread === void 0 ? void 0 : _parentMessage$thread.replyCount) || 0); const createMessagePressActions = useCreateMessagePressActions({ channel: props.channel, currentUserId: props.currentUserId, onDeleteMessage: props.onDeleteMessage, onPressMediaMessage: props.onPressMediaMessage, onEditMessage: setMessageToEdit }); const { onPress, onLongPress, bottomSheetItem } = createMessagePressActions({ message: parentMessage }); const renderMessageInfoAndMenu = () => { var _parentMessage$sender2; return /*#__PURE__*/React.createElement(Box, { style: styles.infoAndMenuContainer }, /*#__PURE__*/React.createElement(Avatar, { size: 34, uri: (_parentMessage$sender2 = parentMessage.sender) === null || _parentMessage$sender2 === void 0 ? void 0 : _parentMessage$sender2.profileUrl }), /*#__PURE__*/React.createElement(Box, { style: styles.userNickAndTimeContainer, alignItems: 'flex-start' }, /*#__PURE__*/React.createElement(Text, { h2: true, color: colors.onBackground01, numberOfLines: 1, style: styles.userNickname }, nickName), /*#__PURE__*/React.createElement(Text, { caption2: true, color: colors.onBackground03, style: styles.messageTime }, messageTimestamp)), /*#__PURE__*/React.createElement(TouchableOpacity, { activeOpacity: 0.7, onPress: bottomSheetItem ? onLongPress : undefined }, /*#__PURE__*/React.createElement(Icon, { icon: 'more', color: colors.onBackground02 }))); }; const renderReplyCount = replyCountText => { if (replyCountText) { return /*#__PURE__*/React.createElement(Box, { style: styles.replyContainer, alignItems: 'flex-start' }, /*#__PURE__*/React.createElement(Text, { caption3: true, color: colors.onBackground03, style: styles.replyText, numberOfLines: 1 }, replyCountText), /*#__PURE__*/React.createElement(Divider, null)); } else { return null; } }; const renderReactionAddons = () => { const configs = sbOptions.uikitWithAppInfo.groupChannel.channel; if (shouldRenderReaction(channel, channel.isSuper ? configs.enableReactionsSupergroup : configs.enableReactions)) { return /*#__PURE__*/React.createElement(View, { style: styles.reactionButtonContainer }, /*#__PURE__*/React.createElement(ReactionAddons.Message, { channel: props.channel, message: parentMessage, reactionAddonType: 'thread_parent_message' })); } else { return null; } }; const messageProps = { parentMessage, onPress, onLongPress }; return /*#__PURE__*/React.createElement(View, null, /*#__PURE__*/React.createElement(View, { style: styles.container }, renderMessageInfoAndMenu()), /*#__PURE__*/React.createElement(View, { style: styles.messageContainer }, /*#__PURE__*/React.createElement(ThreadParentMessageRenderer, messageProps)), renderReactionAddons(), /*#__PURE__*/React.createElement(Divider, null), renderReplyCount(replyCountText)); }; const styles = createStyleSheet({ container: { flexDirection: 'column' }, infoAndMenuContainer: { flexDirection: 'row', height: 50, padding: 16, paddingBottom: 0 }, userNickAndTimeContainer: { flexDirection: 'column', flex: 1, marginStart: 8 }, userNickname: { marginBottom: 2 }, messageTime: { marginTop: 2 }, contextMenuButton: { width: 34, height: 34, justifyContent: 'flex-end' }, messageContainer: { paddingHorizontal: 16, paddingVertical: 8 }, reactionButtonContainer: { paddingStart: 16, marginBottom: 16 }, replyContainer: { flexDirection: 'column' }, replyText: { justifyContent: 'center', paddingHorizontal: 16, paddingVertical: 12 } }); const useCreateMessagePressActions = ({ channel, currentUserId, onDeleteMessage, onPressMediaMessage, onEditMessage }) => { const handlers = useSBUHandlers(); const { STRINGS } = useLocalization(); const toast = useToast(); const { openSheet } = useBottomSheet(); const { alert } = useAlert(); const { clipboardService, fileService } = usePlatformService(); const { sbOptions } = useSendbirdChat(); const onDeleteFailure = error => { toast.show(STRINGS.TOAST.DELETE_MSG_ERROR, 'error'); Logger.error(STRINGS.TOAST.DELETE_MSG_ERROR, error); }; const onCopyText = message => { if (message.isUserMessage()) { clipboardService.setString(message.message || ''); toast.show(STRINGS.TOAST.COPY_OK, 'success'); } }; const onDownloadFile = message => { if (message.isFileMessage()) { if (toMegabyte(message.size) > 4) { toast.show(STRINGS.TOAST.DOWNLOAD_START, 'success'); } fileService.save({ fileUrl: message.url, fileName: message.name, fileType: message.type }).then(response => { toast.show(STRINGS.TOAST.DOWNLOAD_OK, 'success'); Logger.log('File saved to', response); }).catch(err => { toast.show(STRINGS.TOAST.DOWNLOAD_ERROR, 'error'); Logger.log('File save failure', err); }); } }; const onOpenFile = message => { if (message.isFileMessage()) { const fileType = getFileType(message.type || getFileExtension(message.name)); if (['image', 'video', 'audio'].includes(fileType)) { var _handlers$onOpenFileU; onPressMediaMessage === null || onPressMediaMessage === void 0 || onPressMediaMessage(message, () => onDeleteMessage(message), getAvailableUriFromFileMessage(message)); (_handlers$onOpenFileU = handlers.onOpenFileURL) === null || _handlers$onOpenFileU === void 0 || _handlers$onOpenFileU.call(handlers, message.url); } else { const openFile = handlers.onOpenFileURL ?? SBUUtils.openURL; openFile(message.url); } } }; const alertForMessageDelete = message => { alert({ title: STRINGS.LABELS.CHANNEL_MESSAGE_DELETE_CONFIRM_TITLE, buttons: [{ text: STRINGS.LABELS.CHANNEL_MESSAGE_DELETE_CONFIRM_CANCEL }, { text: STRINGS.LABELS.CHANNEL_MESSAGE_DELETE_CONFIRM_OK, style: 'destructive', onPress: () => { onDeleteMessage(message).catch(onDeleteFailure); } }] }); }; return ({ message }) => { if (!message.isUserMessage() && !message.isFileMessage()) return {}; const sheetItems = []; const menu = { copy: message => ({ icon: 'copy', title: STRINGS.LABELS.CHANNEL_MESSAGE_COPY, onPress: () => onCopyText(message) }), edit: message => ({ icon: 'edit', title: STRINGS.LABELS.CHANNEL_MESSAGE_EDIT, onPress: () => onEditMessage === null || onEditMessage === void 0 ? void 0 : onEditMessage(message) }), delete: message => ({ disabled: message.threadInfo ? message.threadInfo.replyCount > 0 : undefined, icon: 'delete', title: STRINGS.LABELS.CHANNEL_MESSAGE_DELETE, onPress: () => alertForMessageDelete(message) }), download: message => ({ icon: 'download', title: STRINGS.LABELS.CHANNEL_MESSAGE_SAVE, onPress: () => onDownloadFile(message) }) }; if (message.isUserMessage()) { sheetItems.push(menu.copy(message)); if (!channel.isEphemeral) { if (isMyMessage(message, currentUserId) && message.sendingStatus === 'succeeded') { sheetItems.push(menu.edit(message)); sheetItems.push(menu.delete(message)); } } } if (message.isFileMessage()) { if (!isVoiceMessage(message)) { sheetItems.push(menu.download(message)); } if (!channel.isEphemeral) { if (isMyMessage(message, currentUserId) && message.sendingStatus === 'succeeded') { sheetItems.push(menu.delete(message)); } } } const configs = sbOptions.uikitWithAppInfo.groupChannel.channel; const bottomSheetItem = { sheetItems, HeaderComponent: shouldRenderReaction(channel, channel.isGroupChannel() && (channel.isSuper ? configs.enableReactionsSupergroup : configs.enableReactions)) ? ({ onClose }) => /*#__PURE__*/React.createElement(ReactionAddons.BottomSheet, { message: message, channel: channel, onClose: onClose }) : undefined }; if (message.isFileMessage()) { return { onPress: () => onOpenFile(message), onLongPress: () => openSheet(bottomSheetItem), bottomSheetItem }; } else { return { onPress: undefined, onLongPress: () => openSheet(bottomSheetItem), bottomSheetItem }; } }; }; export default /*#__PURE__*/React.memo(GroupChannelThreadParentMessageInfo); //# sourceMappingURL=GroupChannelThreadParentMessageInfo.js.map