Skip to content

Commit 34ac153

Browse files
author
jaapbakker88
authored
Merge branch 'master' into fix/mute-flag-livestream
2 parents 44ca8cf + 1379632 commit 34ac153

23 files changed

+158
-25
lines changed

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
11
# Changelog
22

3+
## [2.6.0](https://github.com/GetStream/stream-chat-react/releases/tag/v2.6.0) 2020-09-29
4+
5+
### Feature
6+
7+
- New messages date indicator in MessageList and VritualizedMessageList [#548](https://github.com/GetStream/stream-chat-react/pull/548)
8+
- Reply/Reactions are available in messageActions [#547](https://github.com/GetStream/stream-chat-react/pull/547)
9+
10+
### Fix
11+
12+
- Fix opacity on emoji in EditMessageForm [#540](https://github.com/GetStream/stream-chat-react/pull/540)
13+
- Sanitize URL image sources in Image component [#543](https://github.com/GetStream/stream-chat-react/pull/543)
14+
- Add first letter of display name to avatar [#545](https://github.com/GetStream/stream-chat-react/pull/545)
15+
316
## [2.5.0](https://github.com/GetStream/stream-chat-react/releases/tag/v2.5.0) 2020-09-24
417

518
### Feature

docs/build/bundle.282ea895.js renamed to docs/build/bundle.53b76c3b.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/build/bundle.282ea895.js.LICENSE.txt renamed to docs/build/bundle.53b76c3b.js.LICENSE.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
/*! exports provided: 0, 128, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 142, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 158, 159, default */
44

5-
/*! exports provided: 1 reply, Attach files, Cancel, Channel Missing, Close, Connection failure, reconnecting now..., Delete, Delivered, Edit Message, Empty message..., Error adding flag: Either the flag already exist or there is issue with network connection ..., Error connecting to chat, refresh the page to try again., Error muting a user ..., Error unmuting a user ..., Error · Unsent, Error: {{ errorMessage }}, Flag, Message Failed · Click to try again, Message deleted, Message failed. Click to try again., Message has been successfully flagged, Mute, New Messages!, Nothing yet..., Only visible to you, Open emoji picker, Pick your emoji, Send, Sending..., Start of a new thread, This message was deleted..., Thread, Type your message, Unmute, You have no channels currently, live, this content could not be displayed, {{ commaSeparatedUsers }} and {{ lastUser }} are typing..., {{ commaSeparatedUsers }} and {{ moreCount }} more, {{ commaSeparatedUsers }}, and {{ lastUser }}, {{ firstUser }} and {{ secondUser }}, {{ firstUser }} and {{ secondUser }} are typing..., {{ imageCount }} more, {{ memberCount }} members, {{ replyCount }} replies, {{ user }} has been muted, {{ user }} has been unmuted, {{ user }} is typing..., {{ watcherCount }} online, 🏙 Attachment..., default */
5+
/*! exports provided: 1 reply, Attach files, Cancel, Channel Missing, Close, Connection failure, reconnecting now..., Delete, Delivered, Edit Message, Empty message..., Error adding flag: Either the flag already exist or there is issue with network connection ..., Error connecting to chat, refresh the page to try again., Error muting a user ..., Error unmuting a user ..., Error · Unsent, Error: {{ errorMessage }}, Flag, Message Failed · Click to try again, Message deleted, Message failed. Click to try again., Message has been successfully flagged, Mute, New, New Messages!, Nothing yet..., Only visible to you, Open emoji picker, Pick your emoji, Send, Sending..., Start of a new thread, This message was deleted..., Thread, Type your message, Unmute, You have no channels currently, live, this content could not be displayed, {{ commaSeparatedUsers }} and {{ lastUser }} are typing..., {{ commaSeparatedUsers }} and {{ moreCount }} more, {{ commaSeparatedUsers }}, and {{ lastUser }}, {{ firstUser }} and {{ secondUser }}, {{ firstUser }} and {{ secondUser }} are typing..., {{ imageCount }} more, {{ memberCount }} members, {{ replyCount }} replies, {{ user }} has been muted, {{ user }} has been unmuted, {{ user }} is typing..., {{ watcherCount }} online, 🏙 Attachment..., default */
66

77
/*! exports provided: ACORN_OPTIONS, default */
88

docs/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@
99
</head>
1010
<body>
1111
<div id="rsg-root"></div>
12-
<script src="build/bundle.282ea895.js"></script>
12+
<script src="build/bundle.53b76c3b.js"></script>
1313
</body>
1414
</html>

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "stream-chat-react",
3-
"version": "2.5.0",
3+
"version": "2.6.0",
44
"description": "React components to create chat conversations or livestream style chat",
55
"author": "GetStream",
66
"homepage": "https://getstream.io/chat/",

src/components/DateSeparator/DateSeparator.js

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,21 @@ import { TranslationContext } from '../../context';
1010
* @example ../../docs/DateSeparator.md
1111
* @type {React.FC<import('types').DateSeparatorProps>}
1212
*/
13-
const DateSeparator = ({ position = 'right', formatDate, date }) => {
14-
const { tDateTimeParser } = useContext(TranslationContext);
13+
const DateSeparator = ({ position = 'right', formatDate, date, unread }) => {
14+
const { t, tDateTimeParser } = useContext(TranslationContext);
1515
if (typeof date === 'string') return null;
1616

17+
const formattedDate = formatDate
18+
? formatDate(date)
19+
: tDateTimeParser(date.toISOString()).calendar();
20+
1721
return (
1822
<div className="str-chat__date-separator">
1923
{(position === 'right' || position === 'center') && (
2024
<hr className="str-chat__date-separator-line" />
2125
)}
2226
<div className="str-chat__date-separator-date">
23-
{formatDate
24-
? formatDate(date)
25-
: tDateTimeParser(date.toISOString()).calendar()}
27+
{unread ? t('New') : formattedDate}
2628
</div>
2729
{(position === 'left' || position === 'center') && (
2830
<hr className="str-chat__date-separator-line" />
@@ -34,6 +36,8 @@ const DateSeparator = ({ position = 'right', formatDate, date }) => {
3436
DateSeparator.propTypes = {
3537
/** The date to format */
3638
date: PropTypes.instanceOf(Date).isRequired,
39+
/** If following messages are not new */
40+
unread: PropTypes.bool,
3741
/** Set the position of the date in the separator */
3842
position: PropTypes.oneOf(['left', 'center', 'right']),
3943
/** Override the default formatting of the date. This is a function that has access to the original date object. Returns a string or Node */

src/components/DateSeparator/__tests__/DateSeparator.test.js

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,33 @@
11
import React from 'react';
22
import renderer from 'react-test-renderer';
3+
import Dayjs from 'dayjs';
4+
import calendar from 'dayjs/plugin/calendar';
35
import { cleanup, render } from '@testing-library/react';
46
import '@testing-library/jest-dom';
57

68
import DateSeparator from '../DateSeparator';
9+
import { TranslationContext } from '../../../context';
10+
11+
Dayjs.extend(calendar);
712

813
afterEach(cleanup); // eslint-disable-line
914

1015
// this changes every time tests are run,
1116
// but by mocking the actual renderers tests are still deterministic
1217
const now = new Date();
1318

19+
const withContext = (props) => {
20+
const t = jest.fn((key) => key);
21+
const tDateTimeParser = jest.fn((input) => Dayjs(input));
22+
const Component = (
23+
<TranslationContext.Provider value={{ t, tDateTimeParser }}>
24+
<DateSeparator {...props} />
25+
</TranslationContext.Provider>
26+
);
27+
28+
return { Component, t, tDateTimeParser };
29+
};
30+
1431
describe('DateSeparator', () => {
1532
it('should use formatDate if it is provided', () => {
1633
const { queryByText } = render(
@@ -20,9 +37,42 @@ describe('DateSeparator', () => {
2037
expect(queryByText('the date')).toBeInTheDocument();
2138
});
2239

23-
it.todo(
24-
"should use tDateTimeParser's calendar method to format dates if formatDate prop is not specified",
25-
);
40+
it('should render New text if unread prop is true', () => {
41+
const { Component, t } = withContext({ date: now, unread: true });
42+
const { queryByText } = render(Component);
43+
44+
expect(queryByText('New')).toBeInTheDocument();
45+
expect(t).toHaveBeenCalledWith('New');
46+
});
47+
48+
it('should render properly for unread', () => {
49+
const { Component } = withContext({ date: now, unread: true });
50+
const tree = renderer.create(Component).toJSON();
51+
expect(tree).toMatchInlineSnapshot(`
52+
<div
53+
className="str-chat__date-separator"
54+
>
55+
<hr
56+
className="str-chat__date-separator-line"
57+
/>
58+
<div
59+
className="str-chat__date-separator-date"
60+
>
61+
New
62+
</div>
63+
</div>
64+
`);
65+
});
66+
67+
it("should use tDateTimeParser's calendar method by default", () => {
68+
const { Component, tDateTimeParser } = withContext({ date: now });
69+
const { queryByText } = render(Component);
70+
71+
expect(tDateTimeParser).toHaveBeenCalledWith(now.toISOString());
72+
expect(
73+
queryByText(Dayjs(now.toISOString()).calendar()),
74+
).toBeInTheDocument();
75+
});
2676

2777
describe('Position prop', () => {
2878
const renderWithPosition = (position) => (

src/components/Message/Message.js

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ const Message = (props) => {
7878
onUserHoverHandler: propOnUserHover,
7979
});
8080
const { isMyMessage, isAdmin, isModerator, isOwner } = useUserRole(message);
81+
const canReact = true;
82+
const canReply = true;
8183
const canEdit = isMyMessage || isModerator || isOwner || isAdmin;
8284
const canDelete = canEdit;
8385
const messageActionsHandler = useCallback(() => {
@@ -88,10 +90,21 @@ const Message = (props) => {
8890
return getMessageActions(messageActions, {
8991
canDelete,
9092
canEdit,
93+
canReply,
94+
canReact,
9195
canFlag: !isMyMessage,
9296
canMute: !isMyMessage && !!channelConfig?.mutes,
9397
});
94-
}, [channelConfig, message, messageActions, canDelete, canEdit, isMyMessage]);
98+
}, [
99+
channelConfig,
100+
message,
101+
messageActions,
102+
canDelete,
103+
canEdit,
104+
canReply,
105+
canReact,
106+
isMyMessage,
107+
]);
95108

96109
const actionsEnabled =
97110
message && message.type === 'regular' && message.status === 'received';

src/components/Message/MessageOptions.js

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import React, { useContext } from 'react';
33
import { useUserRole, useOpenThreadHandler } from './hooks';
44
import { ChannelContext } from '../../context';
55
import { MessageActions } from '../MessageActions';
6+
import { MESSAGE_ACTIONS } from './utils';
67
import { ThreadIcon, ReactionIcon } from './icons';
78

89
/**
@@ -28,9 +29,19 @@ const MessageOptionsComponent = (props) => {
2829
*/
2930
const { channel } = useContext(ChannelContext);
3031
const channelConfig = channel?.getConfig();
32+
const messageActions = props.getMessageActions();
33+
const shouldShowReactions =
34+
messageActions.indexOf(MESSAGE_ACTIONS.react) > -1 &&
35+
channelConfig &&
36+
channelConfig.reactions;
37+
3138
const shouldShowReplies =
32-
displayReplies && !threadList && channelConfig && channelConfig.replies;
33-
const shouldShowReactions = channelConfig && channelConfig.reactions;
39+
messageActions.indexOf(MESSAGE_ACTIONS.reply) > -1 &&
40+
displayReplies &&
41+
!threadList &&
42+
channelConfig &&
43+
channelConfig.replies;
44+
3445
if (
3546
!message ||
3647
message.type === 'error' ||
@@ -53,7 +64,7 @@ const MessageOptionsComponent = (props) => {
5364
<div
5465
data-testid="thread-action"
5566
onClick={propHandleOpenThread || handleOpenThread}
56-
className={`str-chat__message-${theme} str-chat__message-${theme}__actions__action--thread`}
67+
className={`str-chat__message-${theme}__actions__action str-chat__message-${theme}__actions__action--thread`}
5768
>
5869
<ThreadIcon />
5970
</div>

src/components/Message/__tests__/MessageCommerce.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ async function renderMessageCommerce(
3737
>
3838
<MessageCommerce
3939
message={message}
40-
getMessageActions={() => ['flag', 'mute']}
40+
getMessageActions={() => ['flag', 'mute', 'react', 'reply']}
4141
{...props}
4242
/>
4343
</ChannelContext.Provider>,

0 commit comments

Comments
 (0)