Skip to content

Commit b5a6f06

Browse files
authored
feat: Export getOutgoingMessageState util function (#327)
* Export the getOutgoingMessageState utils function * Remove getOutgoingMessageStates
1 parent f0ce5a2 commit b5a6f06

File tree

9 files changed

+208
-65
lines changed

9 files changed

+208
-65
lines changed

exports.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ export default {
1818
'handlers/UserEventHandler': 'src/lib/handlers/UserEventHandler.ts',
1919
'handlers/SessionHandler': 'src/lib/handlers/SessionHandler.ts',
2020

21+
// utils
22+
'utils/message/getOutgoingMessageState': 'src/utils/exports/getOutgoingMessageState.ts',
23+
2124
// ChannelList
2225
ChannelList: 'src/smart-components/ChannelList/index.tsx',
2326
'ChannelList/context': 'src/smart-components/ChannelList/context/ChannelListProvider.tsx',

scripts/index_d_ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -964,7 +964,7 @@ declare module '@sendbird/uikit-react/withSendbird' {
964964
export default withSendbird;
965965
}
966966

967-
// handlers
967+
/** handlers */
968968
declare module '@sendbird/uikit-react/handlers/ConnectionHandler' {
969969
import { ConnectionHandler } from '@sendbird/chat';
970970
export default ConnectionHandler;
@@ -986,6 +986,25 @@ declare module '@sendbird/uikit-react/handlers/UserEventHandler' {
986986
export default UserEventHandler;
987987
}
988988

989+
/** utils */
990+
declare module '@sendbird/uikit-react/utils/message/getOutgoingMessageState' {
991+
import { GroupChannel } from '@sendbird/chat/groupChannel';
992+
import { OpenChannel } from '@sendbird/chat/openChannel';
993+
import { UserMessage, FileMessage } from '@sendbird/chat/message';
994+
export enum OutgoingMessageStates {
995+
NONE = 'NONE',
996+
PENDING = 'PENDING',
997+
SENT = 'SENT',
998+
FAILED = 'FAILED',
999+
DELIVERED = 'DELIVERED',
1000+
READ = 'READ',
1001+
}
1002+
export function getOutgoingMessageState(
1003+
channel: GroupChannel | OpenChannel,
1004+
message: UserMessage | FileMessage,
1005+
): OutgoingMessageStates;
1006+
}
1007+
9891008
/** ChannelList */
9901009
declare module '@sendbird/uikit-react/ChannelList' {
9911010
import SendbirdUIKitGlobal from 'SendbirdUIKitGlobal';

src/index.d.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,21 @@ declare module '@sendbird/uikit-react/withSendBird' {
511511
export default withSendBird;
512512
}
513513

514+
declare module '@sendbird/uikit-react/utils/message/getOutgoingMessageState' {
515+
export enum OutgoingMessageStates {
516+
NONE = 'NONE',
517+
PENDING = 'PENDING',
518+
SENT = 'SENT',
519+
FAILED = 'FAILED',
520+
DELIVERED = 'DELIVERED',
521+
READ = 'READ',
522+
}
523+
export function getOutgoingMessageState(
524+
channel: GroupChannel | OpenChannel,
525+
message: UserMessage | FileMessage,
526+
): OutgoingMessageStates;
527+
}
528+
514529
declare module '@sendbird/uikit-react/ChannelList' {
515530
type ChannelList = React.FunctionComponent<ChannelListProps>;
516531
export default ChannelList;

src/smart-components/Channel/context/utils.js

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,9 @@ import format from 'date-fns/format';
22
import * as channelActions from './dux/actionTypes';
33
import * as topics from '../../../lib/pubSub/topics';
44

5-
import {
6-
getSendingMessageStatus,
7-
getOutgoingMessageStates,
8-
isReadMessage,
9-
} from '../../../utils';
5+
import { getSendingMessageStatus, isReadMessage } from '../../../utils';
6+
import { OutgoingMessageStates } from '../../../utils/exports/getOutgoingMessageState';
107

11-
const MessageStatusType = getOutgoingMessageStates();
128
const UNDEFINED = 'undefined';
139
const { SUCCEEDED, FAILED, PENDING } = getSendingMessageStatus();
1410

@@ -95,29 +91,29 @@ export const pubSubHandler = (channelUrl, pubSub, dispatcher) => {
9591

9692
export const getParsedStatus = (message, currentGroupChannel) => {
9793
if (message.requestState === FAILED) {
98-
return MessageStatusType.FAILED;
94+
return OutgoingMessageStates.FAILED;
9995
}
10096

10197
if (message.requestState === PENDING) {
102-
return MessageStatusType.PENDING;
98+
return OutgoingMessageStates.PENDING;
10399
}
104100

105101
if (message.requestState === SUCCEEDED) {
106102
if (!currentGroupChannel) {
107-
return MessageStatusType.SENT;
103+
return OutgoingMessageStates.SENT;
108104
}
109105

110106
const unreadMemberCount = currentGroupChannel?.getUnreadMemberCount(message);
111107
if (unreadMemberCount === 0) {
112-
return MessageStatusType.READ;
108+
return OutgoingMessageStates.READ;
113109
}
114110

115111
const isDelivered = currentGroupChannel?.getUndeliveredMemberCount(message) === 0;
116112
if (isDelivered) {
117-
return MessageStatusType.DELIVERED;
113+
return OutgoingMessageStates.DELIVERED;
118114
}
119115

120-
return MessageStatusType.SENT;
116+
return OutgoingMessageStates.SENT;
121117
}
122118

123119
return null;

src/ui/MessageStatus/__tests__/MessageStatus.spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from 'react';
2-
import { render, screen } from '@testing-library/react';
2+
import { render } from '@testing-library/react';
33

44
import MessageStatus, { MessageStatusTypes } from "../index";
55
import dummyMessage from '../messageDummyData.mock';

src/ui/MessageStatus/index.tsx

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
import './index.scss';
22
import React, { useMemo } from 'react';
33
import format from 'date-fns/format';
4-
import type { FileMessage, UserMessage } from '@sendbird/chat/message';
5-
import type { GroupChannel } from '@sendbird/chat/groupChannel';
4+
import { GroupChannel } from '@sendbird/chat/groupChannel';
5+
import { FileMessage, UserMessage } from '@sendbird/chat/message';
66

77
import Icon, { IconTypes, IconColors } from '../Icon';
88
import Label, { LabelColors, LabelTypography } from '../Label';
99
import Loader from '../Loader';
1010

11+
import { isSentStatus } from '../../utils';
1112
import {
1213
getOutgoingMessageState,
13-
getOutgoingMessageStates,
14-
isSentStatus,
15-
} from '../../utils';
14+
OutgoingMessageStates,
15+
} from '../../utils/exports/getOutgoingMessageState';
1616
import { useLocalization } from '../../lib/LocalizationContext';
1717

18-
export const MessageStatusTypes = getOutgoingMessageStates();
18+
export const MessageStatusTypes = OutgoingMessageStates;
1919

2020
interface MessageStatusProps {
2121
className?: string;
@@ -34,19 +34,19 @@ export default function MessageStatus({
3434
), [channel?.getUnreadMemberCount?.(message), channel?.getUndeliveredMemberCount?.(message)]);
3535
const hideMessageStatusIcon = channel?.isGroupChannel() && (
3636
(channel.isSuper || channel.isPublic || channel.isBroadcast)
37-
&& !(status === MessageStatusTypes.PENDING || status === MessageStatusTypes.FAILED)
37+
&& !(status === OutgoingMessageStates.PENDING || status === OutgoingMessageStates.FAILED)
3838
);
3939
const iconType = {
40-
[MessageStatusTypes.SENT]: IconTypes.DONE,
41-
[MessageStatusTypes.DELIVERED]: IconTypes.DONE_ALL,
42-
[MessageStatusTypes.READ]: IconTypes.DONE_ALL,
43-
[MessageStatusTypes.FAILED]: IconTypes.ERROR,
40+
[OutgoingMessageStates.SENT]: IconTypes.DONE,
41+
[OutgoingMessageStates.DELIVERED]: IconTypes.DONE_ALL,
42+
[OutgoingMessageStates.READ]: IconTypes.DONE_ALL,
43+
[OutgoingMessageStates.FAILED]: IconTypes.ERROR,
4444
};
4545
const iconColor = {
46-
[MessageStatusTypes.SENT]: IconColors.SENT,
47-
[MessageStatusTypes.DELIVERED]: IconColors.SENT,
48-
[MessageStatusTypes.READ]: IconColors.READ,
49-
[MessageStatusTypes.FAILED]: IconColors.ERROR,
46+
[OutgoingMessageStates.SENT]: IconColors.SENT,
47+
[OutgoingMessageStates.DELIVERED]: IconColors.SENT,
48+
[OutgoingMessageStates.READ]: IconColors.READ,
49+
[OutgoingMessageStates.FAILED]: IconColors.ERROR,
5050
};
5151

5252
return (
@@ -56,7 +56,7 @@ export default function MessageStatus({
5656
'sendbird-message-status',
5757
].join(' ')}
5858
>
59-
{(status === MessageStatusTypes.PENDING) ? (
59+
{(status === OutgoingMessageStates.PENDING) ? (
6060
<Loader
6161
className="sendbird-message-status__icon"
6262
width="16px"
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
/* eslint-disable @typescript-eslint/no-unused-vars */
2+
import { GroupChannel } from '@sendbird/chat/groupChannel';
3+
import { UserMessage } from '@sendbird/chat/message';
4+
import { getOutgoingMessageState, OutgoingMessageStates } from '../getOutgoingMessageState';
5+
6+
describe('Global-export-utils-getOutgoingMessageState', () => {
7+
test('OutgoingMessageStates should contain each types', () => {
8+
expect(OutgoingMessageStates.NONE).toBe('NONE');
9+
expect(OutgoingMessageStates.PENDING).toBe('PENDING');
10+
expect(OutgoingMessageStates.SENT).toBe('SENT');
11+
expect(OutgoingMessageStates.FAILED).toBe('FAILED');
12+
expect(OutgoingMessageStates.DELIVERED).toBe('DELIVERED');
13+
expect(OutgoingMessageStates.READ).toBe('READ');
14+
});
15+
16+
it('should return pending', () => {
17+
expect(
18+
getOutgoingMessageState(
19+
{} as GroupChannel,
20+
{ sendingStatus: 'pending' } as UserMessage,
21+
)
22+
).toBe(OutgoingMessageStates.PENDING);
23+
});
24+
it('should return failed', () => {
25+
expect(
26+
getOutgoingMessageState(
27+
{} as GroupChannel,
28+
{ sendingStatus: 'failed' } as UserMessage,
29+
)
30+
).toBe(OutgoingMessageStates.FAILED);
31+
});
32+
it('should return sent', () => {
33+
// when it's not a group channel
34+
expect(
35+
getOutgoingMessageState(
36+
{ isGroupChannel: () => false } as GroupChannel,
37+
{ sendingStatus: 'succeeded' } as UserMessage,
38+
)
39+
).toBe(OutgoingMessageStates.SENT);
40+
// when getUnreadMemberCount or getUndeliveredMemberCount doesn't exist
41+
expect(
42+
getOutgoingMessageState(
43+
{ isGroupChannel: () => true } as GroupChannel,
44+
{ sendingStatus: 'succeeded' } as UserMessage,
45+
)
46+
).toBe(OutgoingMessageStates.SENT);
47+
// when getUnreadMemberCount and getUndeliveredMemberCount return a number(0<)
48+
expect(
49+
getOutgoingMessageState(
50+
{
51+
isGroupChannel: () => true,
52+
getUnreadMemberCount: (_) => 1,
53+
getUndeliveredMemberCount: (_) => 1,
54+
} as GroupChannel,
55+
{ sendingStatus: 'succeeded' } as UserMessage,
56+
)
57+
).toBe(OutgoingMessageStates.SENT);
58+
});
59+
it('should return delivered', () => {
60+
// when getUnreadMemberCount doesn't exist & getUndeliveredMemberCount returns 0
61+
expect(
62+
getOutgoingMessageState(
63+
{
64+
isGroupChannel: () => true,
65+
getUndeliveredMemberCount: (_) => 0,
66+
} as GroupChannel,
67+
{ sendingStatus: 'succeeded' } as UserMessage,
68+
)
69+
).toBe(OutgoingMessageStates.DELIVERED);
70+
// when getUnreadMemberCount returns a number(0<) & getUndeliveredMemberCount returns 0
71+
expect(
72+
getOutgoingMessageState(
73+
{
74+
isGroupChannel: () => true,
75+
getUnreadMemberCount: (_) => 1,
76+
getUndeliveredMemberCount: (_) => 0,
77+
} as GroupChannel,
78+
{ sendingStatus: 'succeeded' } as UserMessage,
79+
)
80+
).toBe(OutgoingMessageStates.DELIVERED);
81+
});
82+
it('should return read', () => {
83+
// when getUnreadMemberCount returns 0
84+
expect(
85+
getOutgoingMessageState(
86+
{
87+
isGroupChannel: () => true,
88+
getUnreadMemberCount: (_) => 0,
89+
} as GroupChannel,
90+
{ sendingStatus: 'succeeded' } as UserMessage,
91+
)
92+
).toBe(OutgoingMessageStates.READ);
93+
// when getUnreadMemberCount returns 0
94+
expect(
95+
getOutgoingMessageState(
96+
{
97+
isGroupChannel: () => true,
98+
getUnreadMemberCount: (_) => 0,
99+
getUndeliveredMemberCount: (_) => 1,
100+
} as GroupChannel,
101+
{ sendingStatus: 'succeeded' } as UserMessage,
102+
)
103+
).toBe(OutgoingMessageStates.READ);
104+
})
105+
});
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { GroupChannel } from '@sendbird/chat/groupChannel';
2+
import { OpenChannel } from '@sendbird/chat/openChannel';
3+
import { UserMessage, FileMessage } from '@sendbird/chat/message';
4+
5+
export enum OutgoingMessageStates {
6+
NONE = 'NONE',
7+
PENDING = 'PENDING',
8+
SENT = 'SENT',
9+
FAILED = 'FAILED',
10+
DELIVERED = 'DELIVERED',
11+
READ = 'READ',
12+
}
13+
14+
export const getOutgoingMessageState = (channel: GroupChannel | OpenChannel, message: UserMessage | FileMessage): string => {
15+
if (message.sendingStatus === 'pending') {
16+
return OutgoingMessageStates.PENDING;
17+
}
18+
if (message.sendingStatus === 'failed') {
19+
return OutgoingMessageStates.FAILED
20+
}
21+
if (channel?.isGroupChannel?.()) {
22+
/* GroupChannel only */
23+
if ((channel as GroupChannel).getUnreadMemberCount?.(message) === 0) {
24+
return OutgoingMessageStates.READ;
25+
} else if ((channel as GroupChannel).getUndeliveredMemberCount?.(message) === 0) {
26+
return OutgoingMessageStates.DELIVERED;
27+
}
28+
}
29+
if (message.sendingStatus === 'succeeded') {
30+
return OutgoingMessageStates.SENT
31+
}
32+
return OutgoingMessageStates.NONE;
33+
};

src/utils/index.ts

Lines changed: 7 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import SendbirdChat, { Emoji, EmojiCategory, EmojiContainer, User } from '@sendbird/chat';
2-
import type { GroupChannel, Member, SendbirdGroupChat, GroupChannelListQuery } from '@sendbird/chat/groupChannel';
3-
import type { AdminMessage, FileMessage, MessageListParams, Reaction, UserMessage } from '@sendbird/chat/message';
4-
import type { OpenChannel, SendbirdOpenChat } from '@sendbird/chat/openChannel';
2+
import { GroupChannel, Member, SendbirdGroupChat, GroupChannelListQuery } from '@sendbird/chat/groupChannel';
3+
import { AdminMessage, FileMessage, MessageListParams, Reaction, UserMessage } from '@sendbird/chat/message';
4+
import { OpenChannel, SendbirdOpenChat } from '@sendbird/chat/openChannel';
5+
6+
import { getOutgoingMessageState, OutgoingMessageStates } from './exports/getOutgoingMessageState';
57
import { EveryMessage } from '../types';
68

79
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Complete_list_of_MIME_types
@@ -79,23 +81,7 @@ const SendingMessageStatus: SendingMessageStatus = {
7981
PENDING: 'pending',
8082
};
8183

82-
export interface OutgoingMessageStates {
83-
NONE: 'NONE',
84-
PENDING: 'PENDING',
85-
SENT: 'SENT',
86-
FAILED: 'FAILED',
87-
DELIVERED: 'DELIVERED',
88-
READ: 'READ',
89-
// delivered and read are only in group channel
90-
}
91-
export const OutgoingMessageStates: OutgoingMessageStates = {
92-
NONE: 'NONE',
93-
PENDING: 'PENDING',
94-
SENT: 'SENT',
95-
FAILED: 'FAILED',
96-
DELIVERED: 'DELIVERED',
97-
READ: 'READ',
98-
};
84+
9985

10086
export type CoreMessageType = EveryMessage;
10187

@@ -120,21 +106,7 @@ export const getUIKitFileType = (type: string): string => {
120106
if (isAudio(type)) return UIKitFileTypes.AUDIO;
121107
return UIKitFileTypes.OTHERS;
122108
};
123-
export const getOutgoingMessageStates = (): OutgoingMessageStates => ({ ...OutgoingMessageStates });
124-
export const getOutgoingMessageState = (channel: GroupChannel | OpenChannel, message: UserMessage | FileMessage): string => {
125-
if (message.sendingStatus === 'pending') return OutgoingMessageStates.PENDING;
126-
if (message.sendingStatus === 'failed') return OutgoingMessageStates.FAILED;
127-
if (channel?.isGroupChannel?.()) {
128-
/* GroupChannel only */
129-
if ((channel as GroupChannel).getUnreadMemberCount(message) === 0) {
130-
return OutgoingMessageStates.READ;
131-
} else if ((channel as GroupChannel).getUndeliveredMemberCount(message) === 0) {
132-
return OutgoingMessageStates.DELIVERED;
133-
}
134-
}
135-
if (message.sendingStatus === 'succeeded') return OutgoingMessageStates.SENT;
136-
return OutgoingMessageStates.NONE;
137-
};
109+
138110
export const isSentMessage = (message: UserMessage | FileMessage): boolean => (message.sendingStatus === 'succeeded');
139111
export const isDeliveredMessage = (channel: GroupChannel, message: UserMessage | FileMessage): boolean => (
140112
getOutgoingMessageState(channel, message) === OutgoingMessageStates.DELIVERED

0 commit comments

Comments
 (0)