/* eslint-disable react/no-children-prop */ /* eslint-disable no-console */ // Copyright 2020-2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 import React, { useState, useEffect } from 'react'; import { InfiniteList, PopOverItem, Modal, ModalHeader, ModalBody, ModalButtonGroup, ModalButton, ChatBubble, ChatBubbleContainer, EditableChatBubble, formatDate, formatTime, } from 'amazon-chime-sdk-component-library-react'; import { AttachmentProcessor } from './AttachmentProcessor'; import { listChannelMessages, createMemberArn, updateChannelMessage, redactChannelMessage, } from '../../api/ChimeAPI'; import insertDateHeaders from '../../utilities/insertDateHeaders'; import './Messages.css'; import { useChatChannelState, useChatMessagingState, } from '../../providers/ChatMessagesProvider'; const Messages = ({ messages, messagesRef, setMessages, channelArn, channelName, userId, setChannelMessageToken, activeChannelRef, }) => { const { channelMessageTokenRef } = useChatChannelState(); const [isLoading, setIsLoading] = useState(false); const handleScrollTop = async () => { setIsLoading(true); if (!channelMessageTokenRef.current) { console.log('No new messages'); setIsLoading(false); return; } const oldMessages = await listChannelMessages( activeChannelRef.current.ChannelArn, userId, channelMessageTokenRef.current ); const newMessages = [...oldMessages.Messages, ...messagesRef.current]; setMessages(newMessages); setChannelMessageToken(oldMessages.NextToken); setIsLoading(false); }; const [showDiscardModal, setShowDiscardModal] = useState(false); const [showRedactModal, setShowRedactModal] = useState(false); const [editingMessageId, setEditingMessageId] = useState(''); const [redactingMessageId, setRedactingMessageId] = useState(''); const handleDiscardEdit = () => { setShowDiscardModal(false); setEditingMessageId(''); }; const discardModal = ( setShowDiscardModal(false)}>
You cannot undo this action.
, , ]} />
); const handleShowRedactModal = (messageId) => { setRedactingMessageId(messageId); setShowRedactModal(true); }; const handleCloseRedactModal = () => { setRedactingMessageId(''); setShowRedactModal(false); }; const redact = async () => { await redactChannelMessage(channelArn, redactingMessageId, userId); setShowRedactModal(false); }; const redactModal = (
You cannot undo this action.
, , ]} />
); const cancelEdit = (e) => { e.preventDefault(); setShowDiscardModal(true); }; const saveEdit = async (e, newText, metadata) => { e.preventDefault(); await updateChannelMessage( channelArn, editingMessageId, newText, metadata, userId ); setEditingMessageId(''); }; const flattenedMessages = messages.map((m) => { const content = !m.Content || m.Redacted ? '(Deleted)' : m.Content; let editedNote; if (m.LastEditedTimestamp && !m.Redacted) { const time = formatTime(m.LastEditedTimestamp); const date = formatDate( m.LastEditedTimestamp, undefined, undefined, 'today', 'yesterday' ); editedNote = ( {` (edited ${date} at ${time})`} ); } return { content: content, editedNote: editedNote, messageId: m.MessageId, createdTimestamp: m.CreatedTimestamp, redacted: m.Redacted, senderName: m.Sender.Name, senderId: m.Sender.Arn, metadata: m.Metadata, }; }); const listItems = insertDateHeaders(flattenedMessages); const messageList = listItems.map((m, i, self) => { if (!m.content) { return m; } if (m.Metadata) { let metadata = JSON.parse(m.Metadata); if (metadata.isMeetingInfo) { return m; } } const variant = createMemberArn(userId) === m.senderId ? 'outgoing' : 'incoming'; let actions = null; if (variant === 'outgoing') { actions = [ Edit} onClick={() => setEditingMessageId(m.messageId)} />, Delete} onClick={() => handleShowRedactModal(m.messageId)} />, ]; } const prevMessageSender = self[i - 1]?.senderId; const currMessageSender = m.senderId; const nextMessageSender = self[i + 1]?.senderId; let showTail = true; if ( currMessageSender && // it is a message nextMessageSender && // the item after is a message currMessageSender === nextMessageSender // the item after is from the same sender ) { showTail = false; } let showName = true; if ( currMessageSender && // it is a message prevMessageSender && // the item before is a message currMessageSender === prevMessageSender // the message before is from the same sender ) { showName = false; } const attachment = (metadata) => { try { const metadataJSON = JSON.parse(metadata); return metadataJSON?.attachments[0]; } catch (err) { // not an json object! ignoring } return false; }; return (
{editingMessageId === m.messageId && !m.redacted ? ( saveEdit(event, value, m.metadata)} cancel={cancelEdit} showName={showName} showTail={showTail} /> ) : (
{m.content} {m.editedNote}
{m.metadata && attachment(m.metadata) && (
)}
)}
); }); return (
{showDiscardModal && discardModal} {showRedactModal && redactModal}
{channelName}
); }; export default Messages;