diff --git a/src/lib/msgUtils.js b/src/lib/msgUtils.js index 6212dd1..fa82325 100644 --- a/src/lib/msgUtils.js +++ b/src/lib/msgUtils.js @@ -266,9 +266,9 @@ export const whatsappMsgTypeMapped = { }, }, originText: msg.image?.caption || '', - onOpen: () => { - console.log('Open image', msg.image.link); - }, + // onOpen: () => { + // console.log('Open image', msg.image.link); + // }, }), renderForReply: (msg) => ({ id: msg.wamid, diff --git a/src/views/Conversations/Components/MessagesList.jsx b/src/views/Conversations/Components/MessagesList.jsx index cbc7ed2..6902482 100644 --- a/src/views/Conversations/Components/MessagesList.jsx +++ b/src/views/Conversations/Components/MessagesList.jsx @@ -1,60 +1,61 @@ -import { useEffect, useState, useRef, memo, createRef, forwardRef } from 'react'; -import { Image, Button } from 'antd'; -import { DownOutlined } from '@ant-design/icons'; +import { useEffect, useRef, useState, forwardRef, memo } from 'react'; import { MessageBox } from 'react-chat-elements'; -import useConversationStore from '@/stores/ConversationStore'; +import { Button } from 'antd'; +import { DownOutlined } from '@ant-design/icons'; import { useShallow } from 'zustand/react/shallow'; +import useConversationStore from '@/stores/ConversationStore'; import { isEmpty, olog } from '@/utils/utils'; -const MessagesList = ({ reference, contactsModalOpen, setContactsModalOpen, ...props }) => { +const MessagesList = ({ messages, handlePreview, reference }) => { const setReferenceMsg = useConversationStore(useShallow((state) => state.setReferenceMsg)); - olog('render message list'); - - const scrollToMessage = (id, index) => { - const _i = index || props.dataSource.findIndex((msg) => msg.id === id); - if (_i >= 0) { - messageRefs.current[_i].current.scrollIntoView({ behavior: 'smooth', block: 'center' }); - } - }; + // const messagesEndRef = useRef(null); const messageRefs = useRef([]); - messageRefs.current = props.dataSource.map((_, i) => messageRefs.current[i] ?? createRef()); + const [page, setPage] = useState(1); + let timeout = null; - const toBottom = (e) => { - if (!reference) return; - reference.current.scrollTop = reference.current.scrollHeight - reference.current.offsetHeight; + const fetchNextPage = async () => { + olog('fetchNextPage') + setPage(page + 1); + // Fetch next page of messages here }; - const prevProps = useRef(props); - useEffect(() => { - if (prevProps.current.dataSource.length !== props.dataSource.length) { - toBottom(); + const handleScroll = (e) => { + const { scrollTop } = e.target; + const delay = 1000; // 1 second + + if (scrollTop === 0) { + if (timeout) clearTimeout(timeout); + timeout = setTimeout(fetchNextPage, delay); } + }; - prevProps.current = props; - }, [prevProps, props]); + const scrollToBottom = () => { + if (reference.current) { + reference.current.scrollTop = reference.current.scrollHeight; + } + }; - const [previewVisible, setPreviewVisible] = useState(false); - const [previewSrc, setPreviewSrc] = useState(); - const onPreviewClose = () => { - setPreviewSrc(''); - setPreviewVisible(false); + const scrollToMessage = (id, index) => { + const _i = index || messages.findIndex((msg) => msg.id === id); + if (reference.current && messageRefs.current[_i]) { + reference.current.scrollTop = messageRefs.current[_i].offsetTop; + } }; - const handlePreview = (msg) => { - switch (msg.type) { - case 'photo': - setPreviewVisible(true); - setPreviewSrc(msg.data.uri); - return false; - case 'file': - window.open(msg.data.link || msg.data.uri, '_blank', 'noopener,noreferrer'); - return false; + useEffect(scrollToBottom, [messages]); - default: - return false; + useEffect(() => { + const messageList = reference.current; + if (messageList) { + messageList.addEventListener('scroll', handleScroll); } - }; + return () => { + if (messageList) { + messageList.removeEventListener('scroll', handleScroll); + } + }; + }, []); const RenderText = memo(function renderText({ str }) { const parts = str.split(/(https?:\/\/[^\s]+|\p{Emoji_Presentation})/gmu).filter((s) => s !== ''); @@ -88,6 +89,7 @@ const MessagesList = ({ reference, contactsModalOpen, setContactsModalOpen, ...p ); }); + // eslint-disable-next-line react/display-name const MessageBoxWithRef = forwardRef((props, ref) => (
@@ -96,27 +98,11 @@ const MessagesList = ({ reference, contactsModalOpen, setContactsModalOpen, ...p )); return ( -
-
- {props.dataSource.map((message, index) => ( - // { - // domEvent.stopPropagation(); - // switch (key) { - // case 'reply': - // return setReferenceMsg(message); - - // default: - // return; - // } - // }, - // }} - // trigger={['contextMenu']}> +
+
+ {messages.map((message, index) => ( (messageRefs.current[index] = el)} key={message.id} {...message} position={message.sender === 'me' ? 'right' : 'left'} @@ -149,11 +135,9 @@ const MessagesList = ({ reference, contactsModalOpen, setContactsModalOpen, ...p } : {})} /> - // ))}
-
); }; diff --git a/src/views/Conversations/Components/MessagesWrapper.jsx b/src/views/Conversations/Components/MessagesWrapper.jsx index 362bbbe..84b1323 100644 --- a/src/views/Conversations/Components/MessagesWrapper.jsx +++ b/src/views/Conversations/Components/MessagesWrapper.jsx @@ -1,15 +1,39 @@ -import { useRef } from 'react'; +import { useRef, useState } from 'react'; import useConversationStore from '@/stores/ConversationStore'; import { useShallow } from 'zustand/react/shallow'; +import { Image, } from 'antd'; import MessagesList from './MessagesList'; const MessagesWrapper = () => { const activeMessages = useConversationStore(useShallow((state) => (state.currentConversation.sn && state.activeConversations[state.currentConversation.sn] ? state.activeConversations[state.currentConversation.sn]: []))); const reference = useRef(null); + + const [previewVisible, setPreviewVisible] = useState(false); + const [previewSrc, setPreviewSrc] = useState(); + const onPreviewClose = () => { + setPreviewSrc(''); + setPreviewVisible(false); + }; + const handlePreview = (msg) => { + switch (msg.whatsapp_msg_type) { + case 'image': + setPreviewVisible(true); + setPreviewSrc(msg.data.uri); + return false; + + case 'document': + window.open(msg.data.link || msg.data.uri, '_blank', 'noopener,noreferrer'); + return false; + + default: + return false; + } + }; return ( <> - + + ); }; diff --git a/src/views/Conversations/Conversations.css b/src/views/Conversations/Conversations.css index d7efac4..c3654c4 100644 --- a/src/views/Conversations/Conversations.css +++ b/src/views/Conversations/Conversations.css @@ -67,7 +67,7 @@ .chatwindow-wrapper .rce-mbox-reply-message, .chatwindow-wrapper .emoji { - font-family: "Noto Color Emoji", 'Apple Color Emoji', 'Twemoji Mozilla', 'Segoe UI Emoji', 'Segoe UI Symbol', 'EmojiOne Color', 'Android Emoji', sans-serif; + font-family: "Noto Color Emoji", 'Apple Color Emoji', 'Twemoji Mozilla', 'Segoe UI Emoji', 'Segoe UI Symbol', 'EmojiOne Color', 'Android Emoji', Arial, sans-serif; font-weight: 500; } .chatwindow-wrapper .rce-mbox-text a{