@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
JavaScript
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