diff --git a/example/App.jsx b/example/App.jsx index d6edca6..b547da8 100644 --- a/example/App.jsx +++ b/example/App.jsx @@ -14,14 +14,135 @@ import './App.css'; function App() { const [activeChannelId, setActiveChannelId] = useState(0); + const [triggerScrollToBottom, setTriggerScrollToBottom] = useState(false); + const [messagesModel, setMessagesModel] = useState([ + { + isMe: true, + message: 'This is a message', + }, + { + isMe: false, + message: 'This is a reply', + }, + { + isMe: false, + message: 'This is a reply', + }, + { + isMe: false, + message: 'This is a reply', + }, + { + isMe: false, + message: 'This is a reply', + }, + { + isMe: false, + message: 'This is a reply', + }, + { + isMe: false, + message: 'This is a reply', + }, + { + isMe: false, + message: 'This is a reply', + }, + { + isMe: false, + message: 'This is a reply', + }, + { + isMe: false, + message: 'This is a reply', + }, + { + isMe: false, + message: 'This is a reply', + }, + { + isMe: false, + message: 'This is a reply', + }, + { + isMe: false, + message: 'This is a reply', + }, + { + isMe: false, + message: 'This is a reply', + }, + { + isMe: false, + message: 'This is a reply', + }, + { + isMe: false, + message: 'This is a reply', + }, + { + isMe: false, + message: 'This is a reply', + }, + { + isMe: false, + message: 'This is a reply', + }, + { + isMe: false, + message: 'This is a reply', + }, + { + isMe: false, + message: 'End', + }, + + ]); const onItemClick = (id) => { setActiveChannelId(id); + setTriggerScrollToBottom(!triggerScrollToBottom); }; const onSend = (message) => { // eslint-disable-next-line no-console console.log(`onSend(${message})`); + setMessagesModel([ + { + isMe: true, + message: `${message}`, + }, + { + isMe: false, + message: `${message}`, + }, + { + isMe: false, + message: `${message}`, + }, + ...messagesModel, + ]); + }; + + const next = () => { + const message = 'new message'; + setTimeout(() => { + setMessagesModel([ + ...messagesModel, + { + isMe: true, + message: `${message}`, + }, + { + isMe: false, + message: `${message}`, + }, + { + isMe: false, + message: `${message}`, + }, + ]); + }, 1500); }; const channelsModel = [ @@ -39,17 +160,6 @@ function App() { }, ]; - const messagesModel = [ - { - isMe: true, - message: 'This is a message', - }, - { - isMe: false, - message: 'This is a reply', - }, - ]; - return (
@@ -70,8 +180,13 @@ function App() {
-
- +
+
diff --git a/package.json b/package.json index 4dae095..f2b5447 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-bootstrap-chat-ui", - "version": "0.0.7", + "version": "0.0.8", "description": "UIkit for chat application using react and bootstrap", "main": "dist/bundle/cjs/react-bootstrap-chat-ui.min.js", "module": "dist/esm/index.js", @@ -43,10 +43,11 @@ "react-dom": "^18.1.0" }, "dependencies": { + "@fortawesome/fontawesome-free": "^6.1.1", + "bootstrap": "4.6.0", "classnames": "^2.3.1", "prop-types": "^15.8.1", - "react-uuid": "^1.0.2", - "bootstrap": "4.6.0", - "@fortawesome/fontawesome-free": "^6.1.1" + "react-infinite-scroll-component": "^6.1.0", + "react-uuid": "^1.0.2" } } diff --git a/src/MessageList/MessageList.jsx b/src/MessageList/MessageList.jsx index 587a27f..323dc88 100644 --- a/src/MessageList/MessageList.jsx +++ b/src/MessageList/MessageList.jsx @@ -1,46 +1,63 @@ -import React, { useEffect, useRef } from 'react'; +import React, { useRef, useState } from 'react'; +import InfiniteScroll from 'react-infinite-scroll-component'; import PropTypes from 'prop-types'; -import uuid from 'react-uuid'; import MessageBubble from '../MessageBubble/MessageBubble'; import '../style.css'; function MessageList(props) { - const { dataSource } = props; + const { + dataSource, triggerScrollToBottom, next, + } = props; const messagesEnd = useRef(null); + const [prevTriggerScroll, setPrevTriggerScroll] = useState(null); const scrollToBottom = () => { messagesEnd.current?.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'start' }); }; - useEffect(() => { + if (triggerScrollToBottom !== prevTriggerScroll) { scrollToBottom(); - }); + setPrevTriggerScroll(triggerScrollToBottom); + } return ( -
-
+
+
+ Loading ...
} + scrollableTarget="scrollableDiv" + > { dataSource.map((item, i) => ( )) } -
-
+
); } MessageList.propTypes = { dataSource: PropTypes.arrayOf(MessageBubble.propTypes.data), + triggerScrollToBottom: PropTypes.bool, + next: PropTypes.func, }; MessageList.defaultProps = { dataSource: [], + triggerScrollToBottom: false, + next: null, }; export default MessageList;