Skip to content

Commit e9e9f29

Browse files
committed
fix: show the message status only for the last own message when returnAllReadData is false
1 parent 60ca979 commit e9e9f29

16 files changed

+347
-136
lines changed

src/components/Channel/hooks/useCreateChannelStateContext.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,12 @@ export const useCreateChannelStateContext = (
4848
const notificationsLength = notifications.length;
4949
const readUsers = Object.values(read);
5050
const readUsersLength = readUsers.length;
51-
const readUsersLastReads = readUsers
52-
.map(({ last_read }) => last_read.toISOString())
53-
.join();
51+
const readUsersLastReadDateStrings: string[] = [];
52+
for (const { last_read } of readUsers) {
53+
if (!lastRead) continue;
54+
readUsersLastReadDateStrings.push(last_read?.toISOString());
55+
}
56+
const readUsersLastReads = readUsersLastReadDateStrings.join();
5457
const threadMessagesLength = threadMessages?.length;
5558

5659
const channelCapabilities: Record<string, boolean> = {};

src/components/Message/Message.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,7 @@ export const Message = (props: MessageProps) => {
288288
handleRetry={handleRetry}
289289
highlighted={highlighted}
290290
initialMessage={props.initialMessage}
291+
lastOwnMessage={props.lastOwnMessage}
291292
lastReceivedId={props.lastReceivedId}
292293
message={message}
293294
Message={props.Message}
@@ -302,6 +303,7 @@ export const Message = (props: MessageProps) => {
302303
reactionDetailsSort={reactionDetailsSort}
303304
readBy={props.readBy}
304305
renderText={props.renderText}
306+
returnAllReadData={props.returnAllReadData}
305307
sortReactionDetails={sortReactionDetails}
306308
sortReactions={sortReactions}
307309
threadList={props.threadList}

src/components/Message/MessageStatus.tsx

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,15 @@ const UnMemoizedMessageStatus = (props: MessageStatusProps) => {
4949

5050
const { client } = useChatContext('MessageStatus');
5151
const { Avatar: contextAvatar } = useComponentContext('MessageStatus');
52-
const { deliveredTo, isMyMessage, message, readBy, threadList } =
53-
useMessageContext('MessageStatus');
52+
const {
53+
deliveredTo,
54+
isMyMessage,
55+
lastOwnMessage,
56+
message,
57+
readBy,
58+
returnAllReadData,
59+
threadList,
60+
} = useMessageContext('MessageStatus');
5461
const { t } = useTranslationContext('MessageStatus');
5562
const [referenceElement, setReferenceElement] = useState<HTMLSpanElement | null>(null);
5663

@@ -64,7 +71,12 @@ const UnMemoizedMessageStatus = (props: MessageStatusProps) => {
6471
const sending = message.status === 'sending';
6572
const read = !!(readBy?.length && !justReadByMe && !threadList);
6673
const delivered = !!(deliveredTo?.length && !deliveredOnlyToMe && !read && !threadList);
67-
const sent = message.status === 'received' && !delivered && !read && !threadList;
74+
const sent =
75+
(returnAllReadData || lastOwnMessage?.id === message.id) &&
76+
message.status === 'received' &&
77+
!delivered &&
78+
!read &&
79+
!threadList;
6880

6981
const readersWithoutOwnUser = read
7082
? readBy.filter((item) => item.id !== client.user?.id)

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

Lines changed: 125 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -354,111 +354,146 @@ describe('<MessageSimple />', () => {
354354
expect(results).toHaveNoViolations();
355355
});
356356

357-
it('should render no status when message not from the current user', async () => {
358-
const message = generateBobMessage();
359-
const { container, queryByTestId } = await renderMessageSimple({ message });
360-
expect(queryByTestId(/message-status/)).not.toBeInTheDocument();
361-
const results = await axe(container);
362-
expect(results).toHaveNoViolations();
363-
});
357+
describe('delivery status', () => {
358+
it('should render no status when message not from the current user', async () => {
359+
const message = generateBobMessage();
360+
const { container, queryByTestId } = await renderMessageSimple({ message });
361+
expect(queryByTestId(/message-status/)).not.toBeInTheDocument();
362+
const results = await axe(container);
363+
expect(results).toHaveNoViolations();
364+
});
365+
366+
it('should not render status when message is an error message', async () => {
367+
const message = generateAliceMessage({ type: 'error' });
368+
const { container, queryByTestId } = await renderMessageSimple({
369+
message,
370+
props: {
371+
readBy: [alice, bob],
372+
},
373+
});
374+
expect(queryByTestId(/message-status/)).not.toBeInTheDocument();
375+
const results = await axe(container);
376+
expect(results).toHaveNoViolations();
377+
});
364378

365-
it('should not render status when message is an error message', async () => {
366-
const message = generateAliceMessage({ type: 'error' });
367-
const { container, queryByTestId } = await renderMessageSimple({ message });
368-
expect(queryByTestId(/message-status/)).not.toBeInTheDocument();
369-
const results = await axe(container);
370-
expect(results).toHaveNoViolations();
371-
});
379+
it('should render sending status when sending message', async () => {
380+
const message = generateAliceMessage({ status: 'sending' });
381+
const { container, getByTestId } = await renderMessageSimple({ message });
382+
expect(getByTestId('message-status-sending')).toBeInTheDocument();
383+
const results = await axe(container);
384+
expect(results).toHaveNoViolations();
385+
});
372386

373-
it('should render sending status when sending message', async () => {
374-
const message = generateAliceMessage({ status: 'sending' });
375-
const { container, getByTestId } = await renderMessageSimple({ message });
376-
expect(getByTestId('message-status-sending')).toBeInTheDocument();
377-
const results = await axe(container);
378-
expect(results).toHaveNoViolations();
379-
});
387+
it('should render the "read by" status when the message is not part of a thread and was read by another chat members', async () => {
388+
const message = generateAliceMessage();
389+
const { container, getByTestId } = await renderMessageSimple({
390+
message,
391+
props: {
392+
readBy: [alice, bob],
393+
},
394+
});
395+
expect(getByTestId('message-status-read-by')).toBeInTheDocument();
396+
const results = await axe(container);
397+
expect(results).toHaveNoViolations();
398+
});
380399

381-
it('should render the "read by" status when the message is not part of a thread and was read by another chat members', async () => {
382-
const message = generateAliceMessage();
383-
const { container, getByTestId } = await renderMessageSimple({
384-
message,
385-
props: {
386-
readBy: [alice, bob],
387-
},
400+
it('should render the "read by many" status when the message is not part of a thread and was read by more than one other chat members', async () => {
401+
const message = generateAliceMessage();
402+
const { container, getByTestId } = await renderMessageSimple({
403+
message,
404+
props: {
405+
readBy: [alice, bob, carol],
406+
},
407+
});
408+
expect(getByTestId('message-status-read-by-many')).toBeInTheDocument();
409+
const results = await axe(container);
410+
expect(results).toHaveNoViolations();
388411
});
389-
expect(getByTestId('message-status-read-by')).toBeInTheDocument();
390-
const results = await axe(container);
391-
expect(results).toHaveNoViolations();
392-
});
393412

394-
it('should render the "read by many" status when the message is not part of a thread and was read by more than one other chat members', async () => {
395-
const message = generateAliceMessage();
396-
const { container, getByTestId } = await renderMessageSimple({
397-
message,
398-
props: {
399-
readBy: [alice, bob, carol],
400-
},
413+
it('should render a sent status when the message has status "received" and was not delivered to others and returnAllReadData=true', async () => {
414+
const message = generateAliceMessage({ status: 'received' });
415+
const { container, getByTestId } = await renderMessageSimple({
416+
message,
417+
props: {
418+
deliveredTo: [alice],
419+
returnAllReadData: true,
420+
},
421+
});
422+
expect(getByTestId('message-status-sent')).toBeInTheDocument();
423+
const results = await axe(container);
424+
expect(results).toHaveNoViolations();
401425
});
402-
expect(getByTestId('message-status-read-by-many')).toBeInTheDocument();
403-
const results = await axe(container);
404-
expect(results).toHaveNoViolations();
405-
});
406426

407-
it('should render a sent status when the message has status "received" and was not delivered to others', async () => {
408-
const message = generateAliceMessage({ status: 'received' });
409-
const { container, getByTestId } = await renderMessageSimple({
410-
message,
411-
props: {
412-
deliveredTo: [alice],
413-
},
427+
it('should not render sent status when the message is not lastOwnMessage and returnAllReadData=false', async () => {
428+
const message = generateAliceMessage({ status: 'received' });
429+
const { container } = await renderMessageSimple({
430+
message,
431+
props: {
432+
deliveredTo: [alice],
433+
lastOwnMessage: generateAliceMessage({ status: 'received' }),
434+
},
435+
});
436+
expect(screen.queryByTestId('message-status-sent')).not.toBeInTheDocument();
437+
const results = await axe(container);
438+
expect(results).toHaveNoViolations();
414439
});
415-
expect(getByTestId('message-status-sent')).toBeInTheDocument();
416-
const results = await axe(container);
417-
expect(results).toHaveNoViolations();
418-
});
419440

420-
it('should render a delivered status when the message was delivered to others but not read', async () => {
421-
const message = generateAliceMessage({ status: 'received' });
422-
const { container, getByTestId } = await renderMessageSimple({
423-
message,
424-
props: {
425-
deliveredTo: [alice, bob],
426-
},
441+
it('should render sent status when the message is not lastOwnMessage and returnAllReadData=false', async () => {
442+
const message = generateAliceMessage({ status: 'received' });
443+
const { container } = await renderMessageSimple({
444+
message,
445+
props: {
446+
deliveredTo: [alice],
447+
lastOwnMessage: message,
448+
},
449+
});
450+
expect(screen.queryByTestId('message-status-sent')).toBeInTheDocument();
451+
const results = await axe(container);
452+
expect(results).toHaveNoViolations();
427453
});
428-
expect(getByTestId('message-status-delivered')).toBeInTheDocument();
429-
const results = await axe(container);
430-
expect(results).toHaveNoViolations();
431-
});
432454

433-
it('should not render status when rendered in a thread list and was delivered to other members', async () => {
434-
const message = generateAliceMessage();
435-
const { container, queryByTestId } = await renderMessageSimple({
436-
message,
437-
props: {
438-
deliveredTo: [alice, bob],
439-
readBy: [alice],
440-
threadList: true,
441-
},
455+
it('should render a delivered status when the message was delivered to others but not read', async () => {
456+
const message = generateAliceMessage({ status: 'received' });
457+
const { container, getByTestId } = await renderMessageSimple({
458+
message,
459+
props: {
460+
deliveredTo: [alice, bob],
461+
},
462+
});
463+
expect(getByTestId('message-status-delivered')).toBeInTheDocument();
464+
const results = await axe(container);
465+
expect(results).toHaveNoViolations();
442466
});
443-
expect(queryByTestId(/message-status/)).not.toBeInTheDocument();
444-
const results = await axe(container);
445-
expect(results).toHaveNoViolations();
446-
});
447467

448-
it('should not render status when rendered in a thread list and was read by other members', async () => {
449-
const message = generateAliceMessage();
450-
const { container, queryByTestId } = await renderMessageSimple({
451-
message,
452-
props: {
453-
readBy: [alice, bob, carol],
454-
threadList: true,
455-
},
468+
it('should not render status when rendered in a thread list and was delivered to other members', async () => {
469+
const message = generateAliceMessage();
470+
const { container, queryByTestId } = await renderMessageSimple({
471+
message,
472+
props: {
473+
deliveredTo: [alice, bob],
474+
readBy: [alice],
475+
threadList: true,
476+
},
477+
});
478+
expect(queryByTestId(/message-status/)).not.toBeInTheDocument();
479+
const results = await axe(container);
480+
expect(results).toHaveNoViolations();
456481
});
457-
expect(queryByTestId(/message-status/)).not.toBeInTheDocument();
458-
const results = await axe(container);
459-
expect(results).toHaveNoViolations();
460-
});
461482

483+
it('should not render status when rendered in a thread list and was read by other members', async () => {
484+
const message = generateAliceMessage();
485+
const { container, queryByTestId } = await renderMessageSimple({
486+
message,
487+
props: {
488+
readBy: [alice, bob, carol],
489+
threadList: true,
490+
},
491+
});
492+
expect(queryByTestId(/message-status/)).not.toBeInTheDocument();
493+
const results = await axe(container);
494+
expect(results).toHaveNoViolations();
495+
});
496+
});
462497
it("should render the message user's avatar", async () => {
463498
const message = generateBobMessage();
464499
const { container } = await renderMessageSimple({

0 commit comments

Comments
 (0)