diff --git a/src/components/ChatBox/index.jsx b/src/components/ChatBox/index.jsx
index 69c434c1..df2eec73 100644
--- a/src/components/ChatBox/index.jsx
+++ b/src/components/ChatBox/index.jsx
@@ -3,15 +3,32 @@ import { useSelector } from 'react-redux';
import PropTypes from 'prop-types';
import Message from '../Message';
import './ChatBox.scss';
+import MessageDivider from '../MessageDivider';
+
+function isToday(date) {
+ const today = new Date();
+ return (
+ date.getDate() === today.getDate()
+ && date.getMonth() === today.getMonth()
+ && date.getFullYear() === today.getFullYear()
+ );
+}
// container for all of the messages
const ChatBox = ({ chatboxContainerRef }) => {
const { messageList, apiIsLoading } = useSelector(state => state.learningAssistant);
+ const messagesBeforeToday = messageList.filter((m) => (!isToday(new Date(m.timestamp))));
+ const messagesToday = messageList.filter((m) => (isToday(new Date(m.timestamp))));
+ // message divider should not display if no messages or if all messages sent today.
return (
- {messageList.map(({ role, content, timestamp }) => (
-
+ {messagesBeforeToday.map(({ role, content, timestamp }) => (
+
+ ))}
+ {(messageList.length !== 0 && messagesBeforeToday.length !== 0) && (
)}
+ {messagesToday.map(({ role, content, timestamp }) => (
+
))}
{apiIsLoading && (
Xpert is thinking
diff --git a/src/components/ChatBox/index.test.jsx b/src/components/ChatBox/index.test.jsx
new file mode 100644
index 00000000..889ac6de
--- /dev/null
+++ b/src/components/ChatBox/index.test.jsx
@@ -0,0 +1,102 @@
+import React from 'react';
+import { screen, act } from '@testing-library/react';
+
+import { render as renderComponent } from '../../utils/utils.test';
+import { initialState } from '../../data/slice';
+
+import ChatBox from '.';
+
+const mockDispatch = jest.fn();
+jest.mock('react-redux', () => ({
+ ...jest.requireActual('react-redux'),
+ useDispatch: () => mockDispatch,
+}));
+
+const defaultProps = {
+ chatboxContainerRef: jest.fn(),
+};
+
+const render = async (props = {}, sliceState = {}) => {
+ const componentProps = {
+ ...defaultProps,
+ ...props,
+ };
+
+ const initState = {
+ preloadedState: {
+ learningAssistant: {
+ ...initialState,
+ ...sliceState,
+ },
+ },
+ };
+ return act(async () => renderComponent(
+
,
+ initState,
+ ));
+};
+
+describe('
', () => {
+ beforeEach(() => {
+ jest.resetAllMocks();
+ });
+ it('message divider does not appear when no messages', () => {
+ const messageList = [];
+ const sliceState = {
+ messageList,
+ };
+ render(undefined, sliceState);
+
+ expect(screen.queryByText('Today')).not.toBeInTheDocument();
+ });
+
+ it('message divider does not appear when all messages from today', () => {
+ const date = new Date();
+ const messageList = [
+ { role: 'user', content: 'hi', timestamp: date - 60 },
+ { role: 'user', content: 'hello', timestamp: date },
+ ];
+ const sliceState = {
+ messageList,
+ };
+ render(undefined, sliceState);
+
+ expect(screen.queryByText('hi')).toBeInTheDocument();
+ expect(screen.queryByText('hello')).toBeInTheDocument();
+ expect(screen.queryByText('Today')).not.toBeInTheDocument();
+ });
+
+ it('message divider shows when all messages from before today', () => {
+ const date = new Date();
+ const messageList = [
+ { role: 'user', content: 'hi', timestamp: date.setDate(date.getDate() - 1) },
+ { role: 'user', content: 'hello', timestamp: date + 1 },
+ ];
+ const sliceState = {
+ messageList,
+ };
+ render(undefined, sliceState);
+
+ expect(screen.queryByText('hi')).toBeInTheDocument();
+ expect(screen.queryByText('hello')).toBeInTheDocument();
+ expect(screen.queryByText('Today')).toBeInTheDocument();
+ });
+
+ it('correctly divides old and new messages', () => {
+ const today = new Date();
+ const messageList = [
+ { role: 'user', content: 'Today yesterday', timestamp: today.setDate(today.getDate() - 1) },
+ { role: 'user', content: 'Today today', timestamp: +Date.now() },
+ ];
+ const sliceState = {
+ messageList,
+ };
+ render(undefined, sliceState);
+
+ const results = screen.getAllByText('Today', { exact: false });
+ expect(results.length).toBe(3);
+ expect(results[0]).toHaveTextContent('Today yesterday');
+ expect(results[1]).toHaveTextContent('Today');
+ expect(results[2]).toHaveTextContent('Today today');
+ });
+});
diff --git a/src/components/MessageDivider/MessageDivider.scss b/src/components/MessageDivider/MessageDivider.scss
new file mode 100644
index 00000000..bb3ee7a0
--- /dev/null
+++ b/src/components/MessageDivider/MessageDivider.scss
@@ -0,0 +1,20 @@
+@use '../../utils/variables';
+
+.message-divider {
+ display: flex;
+ font-size: 15px;
+}
+.message-divider:before, .message-divider:after{
+ content: "";
+ flex: 1 1;
+ border-bottom: 1px solid;
+ margin: auto;
+}
+.message-divider:before {
+ margin-right: 10px;
+ margin-left: 10px;
+}
+.message-divider:after {
+ margin-right: 10px;
+ margin-left: 10px;
+}
diff --git a/src/components/MessageDivider/index.jsx b/src/components/MessageDivider/index.jsx
new file mode 100644
index 00000000..dc783d8d
--- /dev/null
+++ b/src/components/MessageDivider/index.jsx
@@ -0,0 +1,15 @@
+import React from 'react';
+import './MessageDivider.scss';
+import PropTypes from 'prop-types';
+
+const MessageDivider = ({ text }) => (
+
+ {text}
+
+);
+
+MessageDivider.propTypes = {
+ text: PropTypes.string.isRequired,
+};
+
+export default MessageDivider;