Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
"start": "concurrently npm:server npm:dev",
"dev": "react-scripts start",
"build": "node ./scripts/build.js",
"test": "jest",
"test": "cross-env TZ=utc jest",
"eject": "react-scripts eject",
"lint": "eslint src",
"server": "node server.js",
Expand Down
8 changes: 5 additions & 3 deletions src/components/ChatWindow/ChatWindow.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import React from 'react';
import { makeStyles, createStyles, Theme } from '@material-ui/core/styles';
import ChatWindowHeader from './ChatWindowHeader/ChatWindowHeader';
import MessageList from './MessageList/MessageList';
import useChatContext from '../../hooks/useChatContext/useChatContext';

const useStyles = makeStyles((theme: Theme) =>
createStyles({
container: {
chatWindowContainer: {
overflowY: 'auto',
background: '#FFFFFF',
zIndex: 100,
Expand All @@ -22,14 +23,15 @@ const useStyles = makeStyles((theme: Theme) =>

export default function ChatWindow() {
const classes = useStyles();
const { isChatWindowOpen } = useChatContext();
const { isChatWindowOpen, messages } = useChatContext();

//if chat window is not open, don't render this component
if (!isChatWindowOpen) return null;

return (
<aside className={classes.container}>
<aside className={classes.chatWindowContainer}>
<ChatWindowHeader />
<MessageList messages={messages} />
</aside>
);
}
32 changes: 32 additions & 0 deletions src/components/ChatWindow/MessageList/MessageInfo/MessageInfo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import React from 'react';
import { makeStyles, createStyles } from '@material-ui/core/styles';

const useStyles = makeStyles(() =>
createStyles({
messageInfoContainer: {
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
padding: '1.425em 0 0.083em',
fontSize: '12px',
color: '#606B85',
},
})
);
Comment on lines +2 to +15
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
import { makeStyles, createStyles } from '@material-ui/core/styles';
const useStyles = makeStyles(() =>
createStyles({
messageInfoContainer: {
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
padding: '1.425em 0 0.083em',
fontSize: '12px',
color: '#606B85',
},
})
);
import { makeStyles } from '@material-ui/core/styles';
const useStyles = makeStyles({
messageInfoContainer: {
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
padding: '1.425em 0 0.083em',
fontSize: '12px',
color: '#606B85',
},
});


interface MessageInfoProps {
author: string;
dateCreated: string;
isLocalParticipant: boolean;
}

export default function MessageInfo({ author, dateCreated, isLocalParticipant }: MessageInfoProps) {
const classes = useStyles();

return (
<div className={classes.messageInfoContainer}>
<div>{isLocalParticipant ? `${author} (You)` : author}</div>
<div>{dateCreated}</div>
</div>
);
}
61 changes: 61 additions & 0 deletions src/components/ChatWindow/MessageList/MessageList.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import React from 'react';
import { render } from '@testing-library/react';
import MessageList from './MessageList';

jest.mock('../../../hooks/useVideoContext/useVideoContext', () => () => ({
room: { localParticipant: { identity: 'olivia' } },
}));

const arbitraryDate = new Date(1614635301000);

const messages: any = [
{
author: 'olivia',
dateCreated: arbitraryDate,
body: 'This is a message',
sid: 'IMXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
type: 'text',
},
{
author: 'tim',
dateCreated: arbitraryDate,
body: 'Hi Olivia!',
sid: 'IMXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX2',
type: 'text',
},
{
author: 'tim',
dateCreated: arbitraryDate,
body: 'That is pretty rad double line message! How did you do that?',
sid: 'IMXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX3',
type: 'text',
},
{
author: 'tim',
dateCreated: arbitraryDate,
body: '😉',
sid: 'IMXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX4',
type: 'text',
},
{
author: 'olivia',
dateCreated: new Date(1614635361000),
body: 'Magic',
sid: 'IMXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX5',
type: 'text',
},
{
author: 'olivia',
dateCreated: new Date(1614635361000),
body: 'lots of magic',
sid: 'IMXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX6',
type: 'text',
},
];

describe('the messageList component', () => {
it('should render correctly', () => {
const { container } = render(<MessageList messages={messages} />);
expect(container).toMatchSnapshot();
});
});
34 changes: 34 additions & 0 deletions src/components/ChatWindow/MessageList/MessageList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import React from 'react';
import TextMessage from './TextMessage/TextMessage';
import MessageInfo from './MessageInfo/MessageInfo';
import { Message } from '@twilio/conversations/lib/message';
import useVideoContext from '../../../hooks/useVideoContext/useVideoContext';

interface MessageListProps {
messages: Message[];
}

export default function MessageList({ messages }: MessageListProps) {
const { room } = useVideoContext();
const localParticipant = room!.localParticipant;

return (
<div style={{ padding: '0 1.2em' }}>
{messages.map((message, idx) => {
const time = message.dateCreated
.toLocaleTimeString('en-us', { hour: 'numeric', minute: 'numeric' })
.toLowerCase();
const isLocalParticipant = localParticipant.identity === message.author;

return (
<React.Fragment key={message.sid}>
{messages[idx - 1]?.author !== message.author && (
<MessageInfo author={message.author} isLocalParticipant={isLocalParticipant} dateCreated={time} />
)}
{message.type === 'text' && <TextMessage body={message.body} isLocalParticipant={isLocalParticipant} />}
</React.Fragment>
);
})}
</div>
);
}
40 changes: 40 additions & 0 deletions src/components/ChatWindow/MessageList/TextMessage/TextMessage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import React from 'react';
import clsx from 'clsx';
import { makeStyles } from '@material-ui/core/styles';

const useStyles = makeStyles({
messageContainer: {
borderRadius: '16px',
display: 'inline-flex',
alignItems: 'center',
padding: '0.5em 0.8em 0.6em',
margin: '0.3em 0 0',
wordBreak: 'break-word',
backgroundColor: '#E1E3EA',
hyphens: 'auto',
},
isLocalParticipant: {
backgroundColor: '#CCE4FF',
},
});

interface TextMessageProps {
body: string;
isLocalParticipant: boolean;
}

export default function TextMessage({ body, isLocalParticipant }: TextMessageProps) {
const classes = useStyles();

return (
<div>
<div
className={clsx(classes.messageContainer, {
[classes.isLocalParticipant]: isLocalParticipant,
})}
>
{body}
</div>
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`the messageList component should render correctly 1`] = `
<div>
<div
style="padding: 0px 1.2em;"
>
<div
class="makeStyles-messageInfoContainer-1"
>
<div>
olivia (You)
</div>
<div>
9:48 pm
</div>
</div>
<div>
<div
class="makeStyles-messageContainer-2 makeStyles-isLocalParticipant-3"
>
This is a message
</div>
</div>
<div
class="makeStyles-messageInfoContainer-1"
>
<div>
tim
</div>
<div>
9:48 pm
</div>
</div>
<div>
<div
class="makeStyles-messageContainer-2"
>
Hi Olivia!
</div>
</div>
<div>
<div
class="makeStyles-messageContainer-2"
>
That is pretty rad double line message! How did you do that?
</div>
</div>
<div>
<div
class="makeStyles-messageContainer-2"
>
😉
</div>
</div>
<div
class="makeStyles-messageInfoContainer-1"
>
<div>
olivia (You)
</div>
<div>
9:49 pm
</div>
</div>
<div>
<div
class="makeStyles-messageContainer-2 makeStyles-isLocalParticipant-3"
>
Magic
</div>
</div>
<div>
<div
class="makeStyles-messageContainer-2 makeStyles-isLocalParticipant-3"
>
lots of magic
</div>
</div>
</div>
</div>
`;