@sendbird/uikit-react-native 1.0.2 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -7
- package/lib/commonjs/SendbirdUIKitContainer.js +5 -2
- package/lib/commonjs/SendbirdUIKitContainer.js.map +1 -1
- package/lib/commonjs/components/FileViewer.js +326 -0
- package/lib/commonjs/components/FileViewer.js.map +1 -0
- package/lib/commonjs/components/GroupChannelPreviewContainer.js +180 -0
- package/lib/commonjs/components/GroupChannelPreviewContainer.js.map +1 -0
- package/lib/commonjs/components/MessageRenderer/FileMessage/VideoFileMessage.js +116 -0
- package/lib/commonjs/components/MessageRenderer/FileMessage/VideoFileMessage.js.map +1 -0
- package/lib/commonjs/components/MessageRenderer/FileMessage/index.js +8 -0
- package/lib/commonjs/components/MessageRenderer/FileMessage/index.js.map +1 -1
- package/lib/commonjs/components/MessageRenderer/MessageOutgoingStatus.js +15 -24
- package/lib/commonjs/components/MessageRenderer/MessageOutgoingStatus.js.map +1 -1
- package/lib/commonjs/components/SBUPressable.js +45 -0
- package/lib/commonjs/components/SBUPressable.js.map +1 -0
- package/lib/commonjs/components/UserActionBar.js +1 -3
- package/lib/commonjs/components/UserActionBar.js.map +1 -1
- package/lib/commonjs/components/UserSelectableBar.js +1 -3
- package/lib/commonjs/components/UserSelectableBar.js.map +1 -1
- package/lib/commonjs/constants.js +7 -1
- package/lib/commonjs/constants.js.map +1 -1
- package/lib/commonjs/contexts/PlatformService.js +4 -2
- package/lib/commonjs/contexts/PlatformService.js.map +1 -1
- package/lib/commonjs/contexts/SendbirdChat.js +6 -2
- package/lib/commonjs/contexts/SendbirdChat.js.map +1 -1
- package/lib/commonjs/domain/groupChannel/component/GroupChannelInput/SendInput.js +1 -1
- package/lib/commonjs/domain/groupChannel/component/GroupChannelInput/SendInput.js.map +1 -1
- package/lib/commonjs/domain/groupChannel/component/GroupChannelMessageList.js +30 -7
- package/lib/commonjs/domain/groupChannel/component/GroupChannelMessageList.js.map +1 -1
- package/lib/commonjs/domain/groupChannel/module/moduleContext.js +2 -3
- package/lib/commonjs/domain/groupChannel/module/moduleContext.js.map +1 -1
- package/lib/commonjs/domain/groupChannel/types.js.map +1 -1
- package/lib/commonjs/domain/groupChannelList/types.js.map +1 -1
- package/lib/commonjs/domain/groupChannelSettings/module/moduleContext.js +1 -1
- package/lib/commonjs/domain/groupChannelSettings/module/moduleContext.js.map +1 -1
- package/lib/commonjs/fragments/createGroupChannelCreateFragment.js +3 -7
- package/lib/commonjs/fragments/createGroupChannelCreateFragment.js.map +1 -1
- package/lib/commonjs/fragments/createGroupChannelFragment.js +13 -11
- package/lib/commonjs/fragments/createGroupChannelFragment.js.map +1 -1
- package/lib/commonjs/fragments/createGroupChannelListFragment.js +7 -37
- package/lib/commonjs/fragments/createGroupChannelListFragment.js.map +1 -1
- package/lib/commonjs/fragments/createGroupChannelMembersFragment.js +1 -1
- package/lib/commonjs/fragments/createGroupChannelMembersFragment.js.map +1 -1
- package/lib/commonjs/hooks/useContext.js.map +1 -1
- package/lib/commonjs/index.js +29 -2
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/localization/StringSet.type.js +8 -0
- package/lib/commonjs/localization/StringSet.type.js.map +1 -1
- package/lib/commonjs/platform/createFileService.expo.js +21 -2
- package/lib/commonjs/platform/createFileService.expo.js.map +1 -1
- package/lib/commonjs/platform/createFileService.native.js +20 -3
- package/lib/commonjs/platform/createFileService.native.js.map +1 -1
- package/lib/commonjs/platform/createMediaService.expo.js +64 -0
- package/lib/commonjs/platform/createMediaService.expo.js.map +1 -0
- package/lib/commonjs/platform/createMediaService.native.js +67 -0
- package/lib/commonjs/platform/createMediaService.native.js.map +1 -0
- package/lib/commonjs/platform/createNotificationService.expo.js.map +1 -1
- package/lib/commonjs/platform/types.js.map +1 -1
- package/lib/commonjs/version.js +1 -1
- package/lib/commonjs/version.js.map +1 -1
- package/lib/module/SendbirdUIKitContainer.js +5 -2
- package/lib/module/SendbirdUIKitContainer.js.map +1 -1
- package/lib/module/components/FileViewer.js +304 -0
- package/lib/module/components/FileViewer.js.map +1 -0
- package/lib/module/components/GroupChannelPreviewContainer.js +158 -0
- package/lib/module/components/GroupChannelPreviewContainer.js.map +1 -0
- package/lib/module/components/MessageRenderer/FileMessage/VideoFileMessage.js +100 -0
- package/lib/module/components/MessageRenderer/FileMessage/VideoFileMessage.js.map +1 -0
- package/lib/module/components/MessageRenderer/FileMessage/index.js +6 -0
- package/lib/module/components/MessageRenderer/FileMessage/index.js.map +1 -1
- package/lib/module/components/MessageRenderer/MessageOutgoingStatus.js +17 -26
- package/lib/module/components/MessageRenderer/MessageOutgoingStatus.js.map +1 -1
- package/lib/module/components/SBUPressable.js +33 -0
- package/lib/module/components/SBUPressable.js.map +1 -0
- package/lib/module/components/UserActionBar.js +1 -1
- package/lib/module/components/UserActionBar.js.map +1 -1
- package/lib/module/components/UserSelectableBar.js +1 -1
- package/lib/module/components/UserSelectableBar.js.map +1 -1
- package/lib/module/constants.js +5 -0
- package/lib/module/constants.js.map +1 -1
- package/lib/module/contexts/PlatformService.js +4 -2
- package/lib/module/contexts/PlatformService.js.map +1 -1
- package/lib/module/contexts/SendbirdChat.js +6 -2
- package/lib/module/contexts/SendbirdChat.js.map +1 -1
- package/lib/module/domain/groupChannel/component/GroupChannelInput/SendInput.js +1 -1
- package/lib/module/domain/groupChannel/component/GroupChannelInput/SendInput.js.map +1 -1
- package/lib/module/domain/groupChannel/component/GroupChannelMessageList.js +28 -7
- package/lib/module/domain/groupChannel/component/GroupChannelMessageList.js.map +1 -1
- package/lib/module/domain/groupChannel/module/moduleContext.js +2 -3
- package/lib/module/domain/groupChannel/module/moduleContext.js.map +1 -1
- package/lib/module/domain/groupChannel/types.js.map +1 -1
- package/lib/module/domain/groupChannelList/types.js.map +1 -1
- package/lib/module/domain/groupChannelSettings/module/moduleContext.js +1 -1
- package/lib/module/domain/groupChannelSettings/module/moduleContext.js.map +1 -1
- package/lib/module/fragments/createGroupChannelCreateFragment.js +4 -4
- package/lib/module/fragments/createGroupChannelCreateFragment.js.map +1 -1
- package/lib/module/fragments/createGroupChannelFragment.js +15 -13
- package/lib/module/fragments/createGroupChannelFragment.js.map +1 -1
- package/lib/module/fragments/createGroupChannelListFragment.js +11 -38
- package/lib/module/fragments/createGroupChannelListFragment.js.map +1 -1
- package/lib/module/fragments/createGroupChannelMembersFragment.js +1 -1
- package/lib/module/fragments/createGroupChannelMembersFragment.js.map +1 -1
- package/lib/module/hooks/useContext.js.map +1 -1
- package/lib/module/index.js +4 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/localization/StringSet.type.js +8 -0
- package/lib/module/localization/StringSet.type.js.map +1 -1
- package/lib/module/platform/createFileService.expo.js +21 -2
- package/lib/module/platform/createFileService.expo.js.map +1 -1
- package/lib/module/platform/createFileService.native.js +20 -3
- package/lib/module/platform/createFileService.native.js.map +1 -1
- package/lib/module/platform/createMediaService.expo.js +54 -0
- package/lib/module/platform/createMediaService.expo.js.map +1 -0
- package/lib/module/platform/createMediaService.native.js +57 -0
- package/lib/module/platform/createMediaService.native.js.map +1 -0
- package/lib/module/platform/createNotificationService.expo.js.map +1 -1
- package/lib/module/platform/types.js.map +1 -1
- package/lib/module/version.js +1 -1
- package/lib/module/version.js.map +1 -1
- package/lib/typescript/src/SendbirdUIKitContainer.d.ts +7 -3
- package/lib/typescript/src/components/FileViewer.d.ts +12 -0
- package/lib/typescript/src/components/GroupChannelPreviewContainer.d.ts +8 -0
- package/lib/typescript/src/components/MessageRenderer/FileMessage/VideoFileMessage.d.ts +3 -0
- package/lib/typescript/src/components/SBUPressable.d.ts +18 -0
- package/lib/typescript/src/components/UserActionBar.d.ts +2 -3
- package/lib/typescript/src/components/UserSelectableBar.d.ts +2 -3
- package/lib/typescript/src/constants.d.ts +5 -0
- package/lib/typescript/src/contexts/PlatformService.d.ts +3 -2
- package/lib/typescript/src/contexts/SendbirdChat.d.ts +5 -1
- package/lib/typescript/src/domain/groupChannel/component/GroupChannelMessageList.d.ts +3 -2
- package/lib/typescript/src/domain/groupChannel/types.d.ts +6 -2
- package/lib/typescript/src/hooks/useContext.d.ts +7 -5
- package/lib/typescript/src/index.d.ts +3 -0
- package/lib/typescript/src/localization/StringSet.type.d.ts +4 -0
- package/lib/typescript/src/platform/createMediaService.expo.d.ts +9 -0
- package/lib/typescript/src/platform/createMediaService.native.d.ts +9 -0
- package/lib/typescript/src/platform/createNotificationService.expo.d.ts +1 -1
- package/lib/typescript/src/platform/types.d.ts +20 -1
- package/lib/typescript/src/version.d.ts +1 -1
- package/package.json +14 -5
- package/src/SendbirdUIKitContainer.tsx +14 -2
- package/src/components/FileViewer.tsx +284 -0
- package/src/components/GroupChannelPreviewContainer.tsx +134 -0
- package/src/components/MessageRenderer/FileMessage/VideoFileMessage.tsx +91 -0
- package/src/components/MessageRenderer/FileMessage/index.tsx +6 -0
- package/src/components/MessageRenderer/MessageOutgoingStatus.tsx +25 -32
- package/src/components/SBUPressable.tsx +40 -0
- package/src/components/UserActionBar.tsx +1 -1
- package/src/components/UserSelectableBar.tsx +1 -1
- package/src/constants.ts +5 -0
- package/src/contexts/PlatformService.tsx +15 -3
- package/src/contexts/SendbirdChat.tsx +13 -5
- package/src/domain/groupChannel/component/GroupChannelInput/SendInput.tsx +1 -1
- package/src/domain/groupChannel/component/GroupChannelMessageList.tsx +23 -6
- package/src/domain/groupChannel/module/moduleContext.tsx +6 -13
- package/src/domain/groupChannel/types.ts +8 -2
- package/src/domain/groupChannelList/types.ts +1 -0
- package/src/domain/groupChannelSettings/module/moduleContext.tsx +5 -10
- package/src/fragments/createGroupChannelCreateFragment.tsx +38 -41
- package/src/fragments/createGroupChannelFragment.tsx +23 -33
- package/src/fragments/createGroupChannelListFragment.tsx +10 -32
- package/src/fragments/createGroupChannelMembersFragment.tsx +34 -39
- package/src/hooks/useContext.ts +3 -5
- package/src/index.ts +5 -1
- package/src/localization/StringSet.type.ts +8 -0
- package/src/platform/createFileService.expo.ts +17 -2
- package/src/platform/createFileService.native.ts +16 -3
- package/src/platform/createMediaService.expo.tsx +30 -0
- package/src/platform/createMediaService.native.tsx +37 -0
- package/src/platform/createNotificationService.expo.ts +1 -1
- package/src/platform/types.ts +26 -1
- package/src/version.ts +1 -1
|
@@ -1,17 +1,29 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
|
|
3
|
-
import type {
|
|
3
|
+
import type {
|
|
4
|
+
ClipboardServiceInterface,
|
|
5
|
+
FileServiceInterface,
|
|
6
|
+
MediaServiceInterface,
|
|
7
|
+
NotificationServiceInterface,
|
|
8
|
+
} from '../platform/types';
|
|
4
9
|
|
|
5
10
|
type Props = React.PropsWithChildren<{
|
|
6
11
|
fileService: FileServiceInterface;
|
|
7
12
|
clipboardService: ClipboardServiceInterface;
|
|
8
13
|
notificationService: NotificationServiceInterface;
|
|
14
|
+
mediaService?: MediaServiceInterface;
|
|
9
15
|
}>;
|
|
10
16
|
|
|
11
17
|
export const PlatformServiceContext = React.createContext<Props | null>(null);
|
|
12
|
-
export const PlatformServiceProvider = ({
|
|
18
|
+
export const PlatformServiceProvider = ({
|
|
19
|
+
children,
|
|
20
|
+
fileService,
|
|
21
|
+
clipboardService,
|
|
22
|
+
notificationService,
|
|
23
|
+
mediaService,
|
|
24
|
+
}: Props) => {
|
|
13
25
|
return (
|
|
14
|
-
<PlatformServiceContext.Provider value={{ fileService, clipboardService, notificationService }}>
|
|
26
|
+
<PlatformServiceContext.Provider value={{ fileService, clipboardService, notificationService, mediaService }}>
|
|
15
27
|
{children}
|
|
16
28
|
</PlatformServiceContext.Provider>
|
|
17
29
|
);
|
|
@@ -11,8 +11,8 @@ type Props = React.PropsWithChildren<{
|
|
|
11
11
|
sdkInstance: SendbirdChatSDK;
|
|
12
12
|
|
|
13
13
|
enableAutoPushTokenRegistration: boolean;
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
enableChannelListTypingIndicator: boolean;
|
|
15
|
+
enableChannelListMessageReceiptStatus: boolean;
|
|
16
16
|
}>;
|
|
17
17
|
|
|
18
18
|
type Context = {
|
|
@@ -27,8 +27,8 @@ type Context = {
|
|
|
27
27
|
features: {
|
|
28
28
|
// UIKit features
|
|
29
29
|
autoPushTokenRegistrationEnabled: boolean;
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
channelListTypingIndicatorEnabled: boolean;
|
|
31
|
+
channelListMessageReceiptStatusEnabled: boolean;
|
|
32
32
|
|
|
33
33
|
// Sendbird application features
|
|
34
34
|
deliveryReceiptEnabled: boolean;
|
|
@@ -39,7 +39,13 @@ type Context = {
|
|
|
39
39
|
};
|
|
40
40
|
|
|
41
41
|
export const SendbirdChatContext = React.createContext<Context | null>(null);
|
|
42
|
-
export const SendbirdChatProvider = ({
|
|
42
|
+
export const SendbirdChatProvider = ({
|
|
43
|
+
children,
|
|
44
|
+
sdkInstance,
|
|
45
|
+
enableAutoPushTokenRegistration,
|
|
46
|
+
enableChannelListMessageReceiptStatus,
|
|
47
|
+
enableChannelListTypingIndicator,
|
|
48
|
+
}: Props) => {
|
|
43
49
|
const [currentUser, _setCurrentUser] = useState<SendbirdUser>();
|
|
44
50
|
const forceUpdate = useForceUpdate();
|
|
45
51
|
const appFeatures = useAppFeatures(sdkInstance);
|
|
@@ -103,6 +109,8 @@ export const SendbirdChatProvider = ({ children, sdkInstance, enableAutoPushToke
|
|
|
103
109
|
features: {
|
|
104
110
|
...appFeatures,
|
|
105
111
|
autoPushTokenRegistrationEnabled: enableAutoPushTokenRegistration,
|
|
112
|
+
channelListTypingIndicatorEnabled: enableChannelListTypingIndicator,
|
|
113
|
+
channelListMessageReceiptStatusEnabled: enableChannelListMessageReceiptStatus,
|
|
106
114
|
},
|
|
107
115
|
};
|
|
108
116
|
|
|
@@ -38,7 +38,7 @@ const SendInput = ({ onSendUserMessage, onSendFileMessage, text, setText, disabl
|
|
|
38
38
|
icon: 'camera',
|
|
39
39
|
onPress: async () => {
|
|
40
40
|
const photo = await fileService.openCamera({
|
|
41
|
-
mediaType: '
|
|
41
|
+
mediaType: 'all',
|
|
42
42
|
onOpenFailureWithToastMessage: () => toast.show(STRINGS.TOAST.OPEN_CAMERA_ERROR, 'error'),
|
|
43
43
|
});
|
|
44
44
|
|
|
@@ -19,11 +19,13 @@ import {
|
|
|
19
19
|
getFileType,
|
|
20
20
|
isMyMessage,
|
|
21
21
|
messageKeyExtractor,
|
|
22
|
+
toMegabyte,
|
|
22
23
|
useFreshCallback,
|
|
23
24
|
} from '@sendbird/uikit-utils';
|
|
24
25
|
|
|
25
26
|
import type { ChatFlatListRef } from '../../../components/ChatFlatList';
|
|
26
27
|
import ChatFlatList from '../../../components/ChatFlatList';
|
|
28
|
+
import { DEPRECATION_WARNING } from '../../../constants';
|
|
27
29
|
import { useLocalization, usePlatformService } from '../../../hooks/useContext';
|
|
28
30
|
import { GroupChannelContexts } from '../module/moduleContext';
|
|
29
31
|
import type { GroupChannelProps } from '../types';
|
|
@@ -44,6 +46,7 @@ const GroupChannelMessageList = ({
|
|
|
44
46
|
onResendFailedMessage,
|
|
45
47
|
onDeleteMessage,
|
|
46
48
|
onPressImageMessage,
|
|
49
|
+
onPressMediaMessage,
|
|
47
50
|
flatListProps,
|
|
48
51
|
enableMessageGrouping,
|
|
49
52
|
}: GroupChannelProps['MessageList']) => {
|
|
@@ -56,6 +59,7 @@ const GroupChannelMessageList = ({
|
|
|
56
59
|
const getMessagePressActions = useGetMessagePressActions({
|
|
57
60
|
onDeleteMessage,
|
|
58
61
|
onPressImageMessage,
|
|
62
|
+
onPressMediaMessage,
|
|
59
63
|
currentUserId,
|
|
60
64
|
onResendFailedMessage,
|
|
61
65
|
});
|
|
@@ -135,15 +139,15 @@ const GroupChannelMessageList = ({
|
|
|
135
139
|
};
|
|
136
140
|
|
|
137
141
|
type HandleableMessage = SendbirdUserMessage | SendbirdFileMessage;
|
|
138
|
-
const toMegabyte = (byte: number) => byte / 1024 / 1024;
|
|
139
142
|
const useGetMessagePressActions = ({
|
|
140
143
|
onPressImageMessage,
|
|
144
|
+
onPressMediaMessage,
|
|
141
145
|
onDeleteMessage,
|
|
142
146
|
onResendFailedMessage,
|
|
143
147
|
currentUserId,
|
|
144
148
|
}: Pick<
|
|
145
149
|
GroupChannelProps['MessageList'],
|
|
146
|
-
'onDeleteMessage' | 'onResendFailedMessage' | 'onPressImageMessage' | '
|
|
150
|
+
'onDeleteMessage' | 'onResendFailedMessage' | 'currentUserId' | 'onPressImageMessage' | 'onPressMediaMessage'
|
|
147
151
|
>) => {
|
|
148
152
|
const { colors } = useUIKitTheme();
|
|
149
153
|
const { STRINGS } = useLocalization();
|
|
@@ -253,10 +257,23 @@ const useGetMessagePressActions = ({
|
|
|
253
257
|
}
|
|
254
258
|
|
|
255
259
|
const fileType = getFileType(msg.type || getFileExtension(msg.name));
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
+
switch (fileType) {
|
|
261
|
+
case 'image':
|
|
262
|
+
case 'video':
|
|
263
|
+
case 'audio': {
|
|
264
|
+
response.onPress = () => {
|
|
265
|
+
if (onPressImageMessage && fileType === 'image') {
|
|
266
|
+
Logger.warn(DEPRECATION_WARNING.GROUP_CHANNEL.ON_PRESS_IMAGE_MESSAGE);
|
|
267
|
+
onPressImageMessage(msg, getAvailableUriFromFileMessage(msg));
|
|
268
|
+
}
|
|
269
|
+
onPressMediaMessage?.(msg, () => onDeleteMessage(msg), getAvailableUriFromFileMessage(msg));
|
|
270
|
+
};
|
|
271
|
+
break;
|
|
272
|
+
}
|
|
273
|
+
default: {
|
|
274
|
+
response.onPress = () => Linking.openURL(msg.url).catch();
|
|
275
|
+
break;
|
|
276
|
+
}
|
|
260
277
|
}
|
|
261
278
|
}
|
|
262
279
|
|
|
@@ -41,20 +41,13 @@ export const GroupChannelContextsProvider: GroupChannelModule['Provider'] = ({
|
|
|
41
41
|
const [typingUsers, setTypingUsers] = useState<SendbirdUser[]>([]);
|
|
42
42
|
const [editMessage, setEditMessage] = useState<SendbirdUserMessage | SendbirdFileMessage>();
|
|
43
43
|
|
|
44
|
-
useChannelHandler(
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
if (isDifferentChannel(channel, eventChannel)) return;
|
|
50
|
-
if (!enableTypingIndicator) return;
|
|
51
|
-
|
|
52
|
-
const usersWithoutMe = eventChannel.getTypingUsers().filter((u) => u.userId !== currentUser?.userId);
|
|
53
|
-
setTypingUsers(usersWithoutMe);
|
|
54
|
-
},
|
|
44
|
+
useChannelHandler(sdk, `GroupChannelContextsProvider_${id}`, {
|
|
45
|
+
onTypingStatusUpdated(eventChannel) {
|
|
46
|
+
if (isDifferentChannel(channel, eventChannel)) return;
|
|
47
|
+
if (!enableTypingIndicator) return;
|
|
48
|
+
setTypingUsers(eventChannel.getTypingUsers());
|
|
55
49
|
},
|
|
56
|
-
|
|
57
|
-
);
|
|
50
|
+
});
|
|
58
51
|
|
|
59
52
|
return (
|
|
60
53
|
<ProviderLayout>
|
|
@@ -28,7 +28,7 @@ export interface GroupChannelProps {
|
|
|
28
28
|
onBeforeSendUserMessage?: (
|
|
29
29
|
params: SendbirdUserMessageParams,
|
|
30
30
|
) => SendbirdUserMessageParams | Promise<SendbirdUserMessageParams>;
|
|
31
|
-
|
|
31
|
+
onPressMediaMessage?: GroupChannelProps['MessageList']['onPressMediaMessage'];
|
|
32
32
|
|
|
33
33
|
renderMessage?: GroupChannelProps['MessageList']['renderMessage'];
|
|
34
34
|
renderNewMessagesButton?: GroupChannelProps['MessageList']['renderNewMessagesButton'];
|
|
@@ -42,6 +42,9 @@ export interface GroupChannelProps {
|
|
|
42
42
|
sortComparator?: UseGroupChannelMessagesOptions['sortComparator'];
|
|
43
43
|
collectionCreator?: UseGroupChannelMessagesOptions['collectionCreator'];
|
|
44
44
|
queryCreator?: UseGroupChannelMessagesOptions['queryCreator'];
|
|
45
|
+
|
|
46
|
+
/** @deprecated `onPressImageMessage` is deprecated, please use `onPressMediaMessage` instead **/
|
|
47
|
+
onPressImageMessage?: GroupChannelProps['MessageList']['onPressImageMessage'];
|
|
45
48
|
};
|
|
46
49
|
Header: {
|
|
47
50
|
onPressHeaderLeft: () => void;
|
|
@@ -59,7 +62,7 @@ export interface GroupChannelProps {
|
|
|
59
62
|
|
|
60
63
|
onResendFailedMessage: (failedMessage: SendbirdUserMessage | SendbirdFileMessage) => Promise<void>;
|
|
61
64
|
onDeleteMessage: (message: SendbirdUserMessage | SendbirdFileMessage) => Promise<void>;
|
|
62
|
-
|
|
65
|
+
onPressMediaMessage?: (message: SendbirdFileMessage, deleteMessage: () => Promise<void>, uri: string) => void;
|
|
63
66
|
|
|
64
67
|
renderMessage: (props: {
|
|
65
68
|
message: SendbirdMessage;
|
|
@@ -81,6 +84,9 @@ export interface GroupChannelProps {
|
|
|
81
84
|
onPress: () => void;
|
|
82
85
|
}>;
|
|
83
86
|
flatListProps?: Omit<FlatListProps<SendbirdMessage>, 'data' | 'renderItem'>;
|
|
87
|
+
|
|
88
|
+
/** @deprecated `onPressImageMessage` is deprecated, please use `onPressMediaMessage` instead **/
|
|
89
|
+
onPressImageMessage?: (message: SendbirdFileMessage, uri: string) => void;
|
|
84
90
|
};
|
|
85
91
|
Input: {
|
|
86
92
|
channel: SendbirdGroupChannel;
|
|
@@ -42,6 +42,7 @@ export interface GroupChannelListProps {
|
|
|
42
42
|
groupChannels: SendbirdGroupChannel[];
|
|
43
43
|
/** Method to render GroupChannel preview **/
|
|
44
44
|
renderGroupChannelPreview: (
|
|
45
|
+
// FIXME/BREAKING: Changed to props object
|
|
45
46
|
channel: SendbirdGroupChannel,
|
|
46
47
|
onLongPressChannel: () => void,
|
|
47
48
|
) => React.ReactElement | null;
|
|
@@ -41,16 +41,11 @@ export const GroupChannelSettingsContextsProvider: GroupChannelSettingsModule['P
|
|
|
41
41
|
forceUpdate();
|
|
42
42
|
};
|
|
43
43
|
|
|
44
|
-
useChannelHandler(
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
onChannelFrozen: onChannelChanged,
|
|
50
|
-
onChannelUnfrozen: onChannelChanged,
|
|
51
|
-
},
|
|
52
|
-
[activeChannel],
|
|
53
|
-
);
|
|
44
|
+
useChannelHandler(sdk, `${HOOK_NAME}_${uniqId}`, {
|
|
45
|
+
onChannelChanged: onChannelChanged,
|
|
46
|
+
onChannelFrozen: onChannelChanged,
|
|
47
|
+
onChannelUnfrozen: onChannelChanged,
|
|
48
|
+
});
|
|
54
49
|
|
|
55
50
|
const toast = useToast();
|
|
56
51
|
const { openSheet } = useBottomSheet();
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import React
|
|
1
|
+
import React from 'react';
|
|
2
2
|
import { TouchableOpacity } from 'react-native';
|
|
3
3
|
|
|
4
4
|
import { useUserList } from '@sendbird/uikit-chat-hooks';
|
|
5
|
-
import { Logger, PASS, SendbirdUser } from '@sendbird/uikit-utils';
|
|
5
|
+
import { Logger, PASS, SendbirdUser, useFreshCallback } from '@sendbird/uikit-utils';
|
|
6
6
|
|
|
7
7
|
import StatusComposition from '../components/StatusComposition';
|
|
8
8
|
import UserSelectableBar from '../components/UserSelectableBar';
|
|
@@ -50,45 +50,42 @@ const createGroupChannelCreateFragment = <UserType,>(
|
|
|
50
50
|
sortComparator,
|
|
51
51
|
});
|
|
52
52
|
|
|
53
|
-
const _renderUser: NonNullable<typeof renderUser> =
|
|
54
|
-
(
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
},
|
|
90
|
-
[renderUser, queryCreator],
|
|
91
|
-
);
|
|
53
|
+
const _renderUser: NonNullable<typeof renderUser> = useFreshCallback((user, selectedUsers, setSelectedUsers) => {
|
|
54
|
+
if (queryCreator && !renderUser) {
|
|
55
|
+
throw new Error('You should provide "renderUser" when providing "queryCreator"');
|
|
56
|
+
}
|
|
57
|
+
if (renderUser) return renderUser(user, selectedUsers, setSelectedUsers);
|
|
58
|
+
|
|
59
|
+
const sbUser = user as unknown as SendbirdUser;
|
|
60
|
+
const sbSelectedUsers = selectedUsers as unknown as SendbirdUser[];
|
|
61
|
+
const sbSetSelectedUsers = setSelectedUsers as unknown as React.Dispatch<React.SetStateAction<SendbirdUser[]>>;
|
|
62
|
+
|
|
63
|
+
const isMe = sbUser.userId === currentUser?.userId;
|
|
64
|
+
if (isMe) return null;
|
|
65
|
+
|
|
66
|
+
const userIdx = sbSelectedUsers.findIndex((u) => u.userId === sbUser.userId);
|
|
67
|
+
const isSelected = userIdx > -1;
|
|
68
|
+
|
|
69
|
+
return (
|
|
70
|
+
<TouchableOpacity
|
|
71
|
+
activeOpacity={0.7}
|
|
72
|
+
onPress={() => {
|
|
73
|
+
sbSetSelectedUsers(([...draft]) => {
|
|
74
|
+
if (isSelected) draft.splice(userIdx, 1);
|
|
75
|
+
else draft.push(sbUser);
|
|
76
|
+
return draft;
|
|
77
|
+
});
|
|
78
|
+
}}
|
|
79
|
+
>
|
|
80
|
+
<UserSelectableBar
|
|
81
|
+
uri={sbUser.profileUrl}
|
|
82
|
+
name={sbUser.nickname || STRINGS.LABELS.USER_NO_NAME}
|
|
83
|
+
selected={isSelected}
|
|
84
|
+
disabled={false}
|
|
85
|
+
/>
|
|
86
|
+
</TouchableOpacity>
|
|
87
|
+
);
|
|
88
|
+
});
|
|
92
89
|
|
|
93
90
|
return (
|
|
94
91
|
<UserListModule.Provider
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, { useMemo } from 'react';
|
|
2
2
|
|
|
3
3
|
import { useGroupChannelMessages } from '@sendbird/uikit-chat-hooks';
|
|
4
|
-
import { NOOP, PASS, messageComparator } from '@sendbird/uikit-utils';
|
|
4
|
+
import { NOOP, PASS, messageComparator, useFreshCallback } from '@sendbird/uikit-utils';
|
|
5
5
|
|
|
6
6
|
import MessageRenderer from '../components/MessageRenderer';
|
|
7
7
|
import NewMessagesButton from '../components/NewMessagesButton';
|
|
@@ -22,7 +22,8 @@ const createGroupChannelFragment = (initModule?: Partial<GroupChannelModule>): G
|
|
|
22
22
|
enableTypingIndicator = true,
|
|
23
23
|
onPressHeaderLeft = NOOP,
|
|
24
24
|
onPressHeaderRight = NOOP,
|
|
25
|
-
onPressImageMessage
|
|
25
|
+
onPressImageMessage,
|
|
26
|
+
onPressMediaMessage = NOOP,
|
|
26
27
|
onChannelDeleted = NOOP,
|
|
27
28
|
onBeforeSendFileMessage = PASS,
|
|
28
29
|
onBeforeSendUserMessage = PASS,
|
|
@@ -57,13 +58,10 @@ const createGroupChannelFragment = (initModule?: Partial<GroupChannelModule>): G
|
|
|
57
58
|
enableCollectionWithoutLocalCache: true,
|
|
58
59
|
});
|
|
59
60
|
|
|
60
|
-
const _renderMessage: GroupChannelProps['MessageList']['renderMessage'] =
|
|
61
|
-
(
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
},
|
|
65
|
-
[renderMessage],
|
|
66
|
-
);
|
|
61
|
+
const _renderMessage: GroupChannelProps['MessageList']['renderMessage'] = useFreshCallback((props) => {
|
|
62
|
+
if (renderMessage) return renderMessage(props);
|
|
63
|
+
return <MessageRenderer {...props} />;
|
|
64
|
+
});
|
|
67
65
|
|
|
68
66
|
const memoizedFlatListProps = useMemo(
|
|
69
67
|
() => ({
|
|
@@ -74,42 +72,33 @@ const createGroupChannelFragment = (initModule?: Partial<GroupChannelModule>): G
|
|
|
74
72
|
[loading, flatListProps],
|
|
75
73
|
);
|
|
76
74
|
|
|
77
|
-
const onSendFileMessage: GroupChannelProps['Input']['onSendFileMessage'] =
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
params.message = text;
|
|
91
|
-
const processedParams = await onBeforeSendUserMessage(params);
|
|
92
|
-
await sendUserMessage(processedParams);
|
|
93
|
-
},
|
|
94
|
-
[sdk, sendUserMessage, onBeforeSendUserMessage],
|
|
95
|
-
);
|
|
96
|
-
const onUpdateFileMessage: GroupChannelProps['Input']['onUpdateFileMessage'] = useCallback(
|
|
75
|
+
const onSendFileMessage: GroupChannelProps['Input']['onSendFileMessage'] = useFreshCallback(async (file) => {
|
|
76
|
+
const params = new sdk.FileMessageParams();
|
|
77
|
+
params.file = file;
|
|
78
|
+
const processedParams = await onBeforeSendFileMessage(params);
|
|
79
|
+
await sendFileMessage(processedParams);
|
|
80
|
+
});
|
|
81
|
+
const onSendUserMessage: GroupChannelProps['Input']['onSendUserMessage'] = useFreshCallback(async (text) => {
|
|
82
|
+
const params = new sdk.UserMessageParams();
|
|
83
|
+
params.message = text;
|
|
84
|
+
const processedParams = await onBeforeSendUserMessage(params);
|
|
85
|
+
await sendUserMessage(processedParams);
|
|
86
|
+
});
|
|
87
|
+
const onUpdateFileMessage: GroupChannelProps['Input']['onUpdateFileMessage'] = useFreshCallback(
|
|
97
88
|
async (editedFile, message) => {
|
|
98
89
|
const params = new sdk.FileMessageParams();
|
|
99
90
|
params.file = editedFile;
|
|
100
91
|
const processedParams = await onBeforeSendFileMessage(params);
|
|
101
92
|
await updateFileMessage(message.messageId, processedParams);
|
|
102
93
|
},
|
|
103
|
-
[sdk, updateFileMessage, onBeforeSendFileMessage],
|
|
104
94
|
);
|
|
105
|
-
const onUpdateUserMessage: GroupChannelProps['Input']['onUpdateUserMessage'] =
|
|
95
|
+
const onUpdateUserMessage: GroupChannelProps['Input']['onUpdateUserMessage'] = useFreshCallback(
|
|
106
96
|
async (editedText, message) => {
|
|
107
97
|
const params = new sdk.UserMessageParams();
|
|
108
98
|
params.message = editedText;
|
|
109
99
|
const processedParams = await onBeforeSendUserMessage(params);
|
|
110
100
|
await updateUserMessage(message.messageId, processedParams);
|
|
111
101
|
},
|
|
112
|
-
[sdk, updateUserMessage, onBeforeSendUserMessage],
|
|
113
102
|
);
|
|
114
103
|
|
|
115
104
|
return (
|
|
@@ -135,6 +124,7 @@ const createGroupChannelFragment = (initModule?: Partial<GroupChannelModule>): G
|
|
|
135
124
|
onResendFailedMessage={resendMessage}
|
|
136
125
|
onDeleteMessage={deleteMessage}
|
|
137
126
|
onPressImageMessage={onPressImageMessage}
|
|
127
|
+
onPressMediaMessage={onPressMediaMessage}
|
|
138
128
|
flatListProps={memoizedFlatListProps}
|
|
139
129
|
/>
|
|
140
130
|
<GroupChannelModule.Input
|
|
@@ -1,22 +1,19 @@
|
|
|
1
|
-
import React, {
|
|
2
|
-
import { AppState
|
|
1
|
+
import React, { useEffect } from 'react';
|
|
2
|
+
import { AppState } from 'react-native';
|
|
3
3
|
|
|
4
4
|
import { useGroupChannelList } from '@sendbird/uikit-chat-hooks';
|
|
5
|
-
import {
|
|
6
|
-
import { Logger, PASS, channelComparator, getFileExtension, getFileType } from '@sendbird/uikit-utils';
|
|
5
|
+
import { Logger, PASS, channelComparator, useFreshCallback } from '@sendbird/uikit-utils';
|
|
7
6
|
|
|
8
|
-
import
|
|
7
|
+
import GroupChannelPreviewContainer from '../components/GroupChannelPreviewContainer';
|
|
9
8
|
import StatusComposition from '../components/StatusComposition';
|
|
10
|
-
import { DEFAULT_LONG_PRESS_DELAY } from '../constants';
|
|
11
9
|
import createGroupChannelListModule from '../domain/groupChannelList/module/createGroupChannelListModule';
|
|
12
10
|
import type {
|
|
13
11
|
GroupChannelListFragment,
|
|
14
12
|
GroupChannelListModule,
|
|
15
13
|
GroupChannelListProps,
|
|
16
14
|
} from '../domain/groupChannelList/types';
|
|
17
|
-
import {
|
|
15
|
+
import { useSendbirdChat } from '../hooks/useContext';
|
|
18
16
|
|
|
19
|
-
const iconMapper = { audio: 'file-audio', image: 'photo', video: 'play', file: 'file-document' } as const;
|
|
20
17
|
const createGroupChannelListFragment = (initModule?: Partial<GroupChannelListModule>): GroupChannelListFragment => {
|
|
21
18
|
const GroupChannelListModule = createGroupChannelListModule(initModule);
|
|
22
19
|
return ({
|
|
@@ -31,7 +28,6 @@ const createGroupChannelListFragment = (initModule?: Partial<GroupChannelListMod
|
|
|
31
28
|
menuItemCreator = PASS,
|
|
32
29
|
}) => {
|
|
33
30
|
const { sdk, currentUser, features, markAsDeliveredWithChannel } = useSendbirdChat();
|
|
34
|
-
const { STRINGS } = useLocalization();
|
|
35
31
|
const { groupChannels, next, loading } = useGroupChannelList(sdk, currentUser?.userId, {
|
|
36
32
|
queryCreator,
|
|
37
33
|
sortComparator,
|
|
@@ -47,35 +43,17 @@ const createGroupChannelListFragment = (initModule?: Partial<GroupChannelListMod
|
|
|
47
43
|
}, []);
|
|
48
44
|
}
|
|
49
45
|
|
|
50
|
-
const _renderGroupChannelPreview: GroupChannelListProps['List']['renderGroupChannelPreview'] =
|
|
46
|
+
const _renderGroupChannelPreview: GroupChannelListProps['List']['renderGroupChannelPreview'] = useFreshCallback(
|
|
51
47
|
(channel, onLongPressChannel) => {
|
|
52
48
|
if (renderGroupChannelPreview) return renderGroupChannelPreview(channel, onLongPressChannel);
|
|
53
49
|
return (
|
|
54
|
-
<
|
|
50
|
+
<GroupChannelPreviewContainer
|
|
51
|
+
channel={channel}
|
|
55
52
|
onPress={() => onPressChannel(channel)}
|
|
56
|
-
onLongPress={onLongPressChannel}
|
|
57
|
-
|
|
58
|
-
>
|
|
59
|
-
<GroupChannelPreview
|
|
60
|
-
customCover={<ChannelCover channel={channel} size={56} />}
|
|
61
|
-
coverUrl={channel.coverUrl}
|
|
62
|
-
title={STRINGS.GROUP_CHANNEL_LIST.CHANNEL_PREVIEW_TITLE(currentUser?.userId ?? '', channel)}
|
|
63
|
-
titleCaption={STRINGS.GROUP_CHANNEL_LIST.CHANNEL_PREVIEW_TITLE_CAPTION(channel)}
|
|
64
|
-
body={STRINGS.GROUP_CHANNEL_LIST.CHANNEL_PREVIEW_BODY(channel)}
|
|
65
|
-
badgeCount={channel.unreadMessageCount}
|
|
66
|
-
bodyIcon={
|
|
67
|
-
channel.lastMessage?.isFileMessage()
|
|
68
|
-
? iconMapper[getFileType(channel.lastMessage.type || getFileExtension(channel.lastMessage.name))]
|
|
69
|
-
: undefined
|
|
70
|
-
}
|
|
71
|
-
frozen={channel.isFrozen}
|
|
72
|
-
notificationOff={channel.myPushTriggerOption === 'off'}
|
|
73
|
-
memberCount={channel.memberCount > 2 ? channel.memberCount : undefined}
|
|
74
|
-
/>
|
|
75
|
-
</Pressable>
|
|
53
|
+
onLongPress={() => onLongPressChannel()}
|
|
54
|
+
/>
|
|
76
55
|
);
|
|
77
56
|
},
|
|
78
|
-
[STRINGS, onPressChannel, currentUser?.userId],
|
|
79
57
|
);
|
|
80
58
|
|
|
81
59
|
if (!currentUser) {
|
|
@@ -26,46 +26,41 @@ const createGroupChannelMembersFragment = (
|
|
|
26
26
|
|
|
27
27
|
const { STRINGS } = useLocalization();
|
|
28
28
|
|
|
29
|
-
useChannelHandler(
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
{
|
|
33
|
-
onUserEntered(channel) {
|
|
34
|
-
if (channel.url === activeChannel.url) forceUpdate();
|
|
35
|
-
},
|
|
36
|
-
onUserLeft(channel) {
|
|
37
|
-
if (channel.url === activeChannel.url) forceUpdate();
|
|
38
|
-
},
|
|
39
|
-
onUserJoined(channel) {
|
|
40
|
-
if (channel.url === activeChannel.url) forceUpdate();
|
|
41
|
-
},
|
|
42
|
-
onUserUnmuted(channel) {
|
|
43
|
-
if (channel.url === activeChannel.url) forceUpdate();
|
|
44
|
-
},
|
|
45
|
-
onUserUnbanned(channel) {
|
|
46
|
-
if (channel.url === activeChannel.url) forceUpdate();
|
|
47
|
-
},
|
|
48
|
-
onUserBanned(channel) {
|
|
49
|
-
if (channel.url === activeChannel.url) forceUpdate();
|
|
50
|
-
},
|
|
51
|
-
onUserMuted(channel) {
|
|
52
|
-
if (channel.url === activeChannel.url) forceUpdate();
|
|
53
|
-
},
|
|
54
|
-
onChannelMemberCountChanged(channels) {
|
|
55
|
-
if (channels.find((c) => c.url === channel.url)) forceUpdate();
|
|
56
|
-
},
|
|
57
|
-
onChannelChanged(channel) {
|
|
58
|
-
if (channel.url === activeChannel.url) forceUpdate();
|
|
59
|
-
},
|
|
60
|
-
onChannelFrozen(channel) {
|
|
61
|
-
if (channel.url === activeChannel.url) forceUpdate();
|
|
62
|
-
},
|
|
63
|
-
onChannelUnfrozen(channel) {
|
|
64
|
-
if (channel.url === activeChannel.url) forceUpdate();
|
|
65
|
-
},
|
|
29
|
+
useChannelHandler(sdk, `${name}_${uniqId}`, {
|
|
30
|
+
onUserEntered(channel) {
|
|
31
|
+
if (channel.url === activeChannel.url) forceUpdate();
|
|
66
32
|
},
|
|
67
|
-
|
|
68
|
-
|
|
33
|
+
onUserLeft(channel) {
|
|
34
|
+
if (channel.url === activeChannel.url) forceUpdate();
|
|
35
|
+
},
|
|
36
|
+
onUserJoined(channel) {
|
|
37
|
+
if (channel.url === activeChannel.url) forceUpdate();
|
|
38
|
+
},
|
|
39
|
+
onUserUnmuted(channel) {
|
|
40
|
+
if (channel.url === activeChannel.url) forceUpdate();
|
|
41
|
+
},
|
|
42
|
+
onUserUnbanned(channel) {
|
|
43
|
+
if (channel.url === activeChannel.url) forceUpdate();
|
|
44
|
+
},
|
|
45
|
+
onUserBanned(channel) {
|
|
46
|
+
if (channel.url === activeChannel.url) forceUpdate();
|
|
47
|
+
},
|
|
48
|
+
onUserMuted(channel) {
|
|
49
|
+
if (channel.url === activeChannel.url) forceUpdate();
|
|
50
|
+
},
|
|
51
|
+
onChannelMemberCountChanged(channels) {
|
|
52
|
+
if (channels.find((c) => c.url === channel.url)) forceUpdate();
|
|
53
|
+
},
|
|
54
|
+
onChannelChanged(channel) {
|
|
55
|
+
if (channel.url === activeChannel.url) forceUpdate();
|
|
56
|
+
},
|
|
57
|
+
onChannelFrozen(channel) {
|
|
58
|
+
if (channel.url === activeChannel.url) forceUpdate();
|
|
59
|
+
},
|
|
60
|
+
onChannelUnfrozen(channel) {
|
|
61
|
+
if (channel.url === activeChannel.url) forceUpdate();
|
|
62
|
+
},
|
|
63
|
+
});
|
|
69
64
|
|
|
70
65
|
const _renderUser: NonNullable<typeof renderUser> = useCallback(
|
|
71
66
|
(user, selectedUsers, setSelectedUsers) => {
|
package/src/hooks/useContext.ts
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { useContext } from 'react';
|
|
2
2
|
|
|
3
|
-
import { LocalizationContext
|
|
3
|
+
import { LocalizationContext } from '../contexts/Localization';
|
|
4
4
|
import { PlatformServiceContext } from '../contexts/PlatformService';
|
|
5
5
|
import { SendbirdChatContext } from '../contexts/SendbirdChat';
|
|
6
6
|
|
|
7
7
|
export const useLocalization = () => {
|
|
8
|
-
const value = useContext
|
|
9
|
-
LocalizationContext as React.Context<LocalizationContextType | null>,
|
|
10
|
-
);
|
|
8
|
+
const value = useContext(LocalizationContext);
|
|
11
9
|
if (!value) throw new Error('LocalizationContext is not provided');
|
|
12
10
|
return value;
|
|
13
11
|
};
|