@sendbird/uikit-react-native 1.0.2 → 1.1.1

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.
Files changed (185) hide show
  1. package/README.md +7 -7
  2. package/lib/commonjs/components/FileViewer.js +319 -0
  3. package/lib/commonjs/components/FileViewer.js.map +1 -0
  4. package/lib/commonjs/components/MessageRenderer/FileMessage/VideoFileMessage.js +116 -0
  5. package/lib/commonjs/components/MessageRenderer/FileMessage/VideoFileMessage.js.map +1 -0
  6. package/lib/commonjs/components/MessageRenderer/FileMessage/index.js +8 -0
  7. package/lib/commonjs/components/MessageRenderer/FileMessage/index.js.map +1 -1
  8. package/lib/commonjs/components/MessageRenderer/MessageOutgoingStatus.js +20 -65
  9. package/lib/commonjs/components/MessageRenderer/MessageOutgoingStatus.js.map +1 -1
  10. package/lib/commonjs/components/UserActionBar.js +1 -3
  11. package/lib/commonjs/components/UserActionBar.js.map +1 -1
  12. package/lib/commonjs/components/UserSelectableBar.js +1 -3
  13. package/lib/commonjs/components/UserSelectableBar.js.map +1 -1
  14. package/lib/commonjs/constants.js +7 -1
  15. package/lib/commonjs/constants.js.map +1 -1
  16. package/lib/commonjs/containers/GroupChannelPreviewContainer.js +157 -0
  17. package/lib/commonjs/containers/GroupChannelPreviewContainer.js.map +1 -0
  18. package/lib/commonjs/{InternalErrorBoundary.js → containers/InternalErrorBoundaryContainer.js} +5 -5
  19. package/lib/commonjs/containers/InternalErrorBoundaryContainer.js.map +1 -0
  20. package/lib/commonjs/{SendbirdUIKitContainer.js → containers/SendbirdUIKitContainer.js} +15 -12
  21. package/lib/commonjs/containers/SendbirdUIKitContainer.js.map +1 -0
  22. package/lib/commonjs/contexts/PlatformService.js +4 -2
  23. package/lib/commonjs/contexts/PlatformService.js.map +1 -1
  24. package/lib/commonjs/contexts/SendbirdChat.js +6 -2
  25. package/lib/commonjs/contexts/SendbirdChat.js.map +1 -1
  26. package/lib/commonjs/domain/groupChannel/component/GroupChannelInput/SendInput.js +1 -1
  27. package/lib/commonjs/domain/groupChannel/component/GroupChannelInput/SendInput.js.map +1 -1
  28. package/lib/commonjs/domain/groupChannel/component/GroupChannelMessageList.js +30 -7
  29. package/lib/commonjs/domain/groupChannel/component/GroupChannelMessageList.js.map +1 -1
  30. package/lib/commonjs/domain/groupChannel/module/moduleContext.js +2 -3
  31. package/lib/commonjs/domain/groupChannel/module/moduleContext.js.map +1 -1
  32. package/lib/commonjs/domain/groupChannel/types.js.map +1 -1
  33. package/lib/commonjs/domain/groupChannelList/types.js.map +1 -1
  34. package/lib/commonjs/domain/groupChannelSettings/module/moduleContext.js +1 -1
  35. package/lib/commonjs/domain/groupChannelSettings/module/moduleContext.js.map +1 -1
  36. package/lib/commonjs/fragments/createGroupChannelCreateFragment.js +3 -7
  37. package/lib/commonjs/fragments/createGroupChannelCreateFragment.js.map +1 -1
  38. package/lib/commonjs/fragments/createGroupChannelFragment.js +14 -12
  39. package/lib/commonjs/fragments/createGroupChannelFragment.js.map +1 -1
  40. package/lib/commonjs/fragments/createGroupChannelListFragment.js +10 -40
  41. package/lib/commonjs/fragments/createGroupChannelListFragment.js.map +1 -1
  42. package/lib/commonjs/fragments/createGroupChannelMembersFragment.js +1 -1
  43. package/lib/commonjs/fragments/createGroupChannelMembersFragment.js.map +1 -1
  44. package/lib/commonjs/hooks/useContext.js.map +1 -1
  45. package/lib/commonjs/index.js +30 -3
  46. package/lib/commonjs/index.js.map +1 -1
  47. package/lib/commonjs/{InternalLocalCacheStorage.js → libs/InternalLocalCacheStorage.js} +0 -0
  48. package/lib/commonjs/libs/InternalLocalCacheStorage.js.map +1 -0
  49. package/lib/commonjs/localization/StringSet.type.js +8 -0
  50. package/lib/commonjs/localization/StringSet.type.js.map +1 -1
  51. package/lib/commonjs/platform/createFileService.expo.js +21 -2
  52. package/lib/commonjs/platform/createFileService.expo.js.map +1 -1
  53. package/lib/commonjs/platform/createFileService.native.js +20 -3
  54. package/lib/commonjs/platform/createFileService.native.js.map +1 -1
  55. package/lib/commonjs/platform/createMediaService.expo.js +64 -0
  56. package/lib/commonjs/platform/createMediaService.expo.js.map +1 -0
  57. package/lib/commonjs/platform/createMediaService.native.js +67 -0
  58. package/lib/commonjs/platform/createMediaService.native.js.map +1 -0
  59. package/lib/commonjs/platform/createNotificationService.expo.js.map +1 -1
  60. package/lib/commonjs/platform/types.js.map +1 -1
  61. package/lib/commonjs/version.js +1 -1
  62. package/lib/commonjs/version.js.map +1 -1
  63. package/lib/module/components/FileViewer.js +300 -0
  64. package/lib/module/components/FileViewer.js.map +1 -0
  65. package/lib/module/components/MessageRenderer/FileMessage/VideoFileMessage.js +100 -0
  66. package/lib/module/components/MessageRenderer/FileMessage/VideoFileMessage.js.map +1 -0
  67. package/lib/module/components/MessageRenderer/FileMessage/index.js +6 -0
  68. package/lib/module/components/MessageRenderer/FileMessage/index.js.map +1 -1
  69. package/lib/module/components/MessageRenderer/MessageOutgoingStatus.js +17 -60
  70. package/lib/module/components/MessageRenderer/MessageOutgoingStatus.js.map +1 -1
  71. package/lib/module/components/UserActionBar.js +1 -1
  72. package/lib/module/components/UserActionBar.js.map +1 -1
  73. package/lib/module/components/UserSelectableBar.js +1 -1
  74. package/lib/module/components/UserSelectableBar.js.map +1 -1
  75. package/lib/module/constants.js +5 -0
  76. package/lib/module/constants.js.map +1 -1
  77. package/lib/module/containers/GroupChannelPreviewContainer.js +135 -0
  78. package/lib/module/containers/GroupChannelPreviewContainer.js.map +1 -0
  79. package/lib/module/{InternalErrorBoundary.js → containers/InternalErrorBoundaryContainer.js} +5 -5
  80. package/lib/module/containers/InternalErrorBoundaryContainer.js.map +1 -0
  81. package/lib/module/{SendbirdUIKitContainer.js → containers/SendbirdUIKitContainer.js} +15 -12
  82. package/lib/module/containers/SendbirdUIKitContainer.js.map +1 -0
  83. package/lib/module/contexts/PlatformService.js +4 -2
  84. package/lib/module/contexts/PlatformService.js.map +1 -1
  85. package/lib/module/contexts/SendbirdChat.js +6 -2
  86. package/lib/module/contexts/SendbirdChat.js.map +1 -1
  87. package/lib/module/domain/groupChannel/component/GroupChannelInput/SendInput.js +1 -1
  88. package/lib/module/domain/groupChannel/component/GroupChannelInput/SendInput.js.map +1 -1
  89. package/lib/module/domain/groupChannel/component/GroupChannelMessageList.js +28 -7
  90. package/lib/module/domain/groupChannel/component/GroupChannelMessageList.js.map +1 -1
  91. package/lib/module/domain/groupChannel/module/moduleContext.js +2 -3
  92. package/lib/module/domain/groupChannel/module/moduleContext.js.map +1 -1
  93. package/lib/module/domain/groupChannel/types.js.map +1 -1
  94. package/lib/module/domain/groupChannelList/types.js.map +1 -1
  95. package/lib/module/domain/groupChannelSettings/module/moduleContext.js +1 -1
  96. package/lib/module/domain/groupChannelSettings/module/moduleContext.js.map +1 -1
  97. package/lib/module/fragments/createGroupChannelCreateFragment.js +4 -4
  98. package/lib/module/fragments/createGroupChannelCreateFragment.js.map +1 -1
  99. package/lib/module/fragments/createGroupChannelFragment.js +16 -14
  100. package/lib/module/fragments/createGroupChannelFragment.js.map +1 -1
  101. package/lib/module/fragments/createGroupChannelListFragment.js +14 -41
  102. package/lib/module/fragments/createGroupChannelListFragment.js.map +1 -1
  103. package/lib/module/fragments/createGroupChannelMembersFragment.js +1 -1
  104. package/lib/module/fragments/createGroupChannelMembersFragment.js.map +1 -1
  105. package/lib/module/hooks/useContext.js.map +1 -1
  106. package/lib/module/index.js +5 -2
  107. package/lib/module/index.js.map +1 -1
  108. package/lib/module/{InternalLocalCacheStorage.js → libs/InternalLocalCacheStorage.js} +0 -0
  109. package/lib/module/libs/InternalLocalCacheStorage.js.map +1 -0
  110. package/lib/module/localization/StringSet.type.js +8 -0
  111. package/lib/module/localization/StringSet.type.js.map +1 -1
  112. package/lib/module/platform/createFileService.expo.js +21 -2
  113. package/lib/module/platform/createFileService.expo.js.map +1 -1
  114. package/lib/module/platform/createFileService.native.js +20 -3
  115. package/lib/module/platform/createFileService.native.js.map +1 -1
  116. package/lib/module/platform/createMediaService.expo.js +54 -0
  117. package/lib/module/platform/createMediaService.expo.js.map +1 -0
  118. package/lib/module/platform/createMediaService.native.js +57 -0
  119. package/lib/module/platform/createMediaService.native.js.map +1 -0
  120. package/lib/module/platform/createNotificationService.expo.js.map +1 -1
  121. package/lib/module/platform/types.js.map +1 -1
  122. package/lib/module/version.js +1 -1
  123. package/lib/module/version.js.map +1 -1
  124. package/lib/typescript/src/components/FileViewer.d.ts +12 -0
  125. package/lib/typescript/src/components/MessageRenderer/FileMessage/VideoFileMessage.d.ts +3 -0
  126. package/lib/typescript/src/components/UserActionBar.d.ts +2 -3
  127. package/lib/typescript/src/components/UserSelectableBar.d.ts +2 -3
  128. package/lib/typescript/src/constants.d.ts +5 -0
  129. package/lib/typescript/src/containers/GroupChannelPreviewContainer.d.ts +8 -0
  130. package/lib/typescript/src/{InternalErrorBoundary.d.ts → containers/InternalErrorBoundaryContainer.d.ts} +3 -3
  131. package/lib/typescript/src/{SendbirdUIKitContainer.d.ts → containers/SendbirdUIKitContainer.d.ts} +9 -5
  132. package/lib/typescript/src/contexts/PlatformService.d.ts +3 -2
  133. package/lib/typescript/src/contexts/SendbirdChat.d.ts +5 -1
  134. package/lib/typescript/src/domain/groupChannel/component/GroupChannelMessageList.d.ts +3 -2
  135. package/lib/typescript/src/domain/groupChannel/types.d.ts +6 -2
  136. package/lib/typescript/src/domain/groupChannelList/types.d.ts +2 -2
  137. package/lib/typescript/src/hooks/useContext.d.ts +7 -5
  138. package/lib/typescript/src/index.d.ts +4 -1
  139. package/lib/typescript/src/{InternalLocalCacheStorage.d.ts → libs/InternalLocalCacheStorage.d.ts} +2 -2
  140. package/lib/typescript/src/localization/StringSet.type.d.ts +4 -0
  141. package/lib/typescript/src/platform/createMediaService.expo.d.ts +9 -0
  142. package/lib/typescript/src/platform/createMediaService.native.d.ts +9 -0
  143. package/lib/typescript/src/platform/createNotificationService.expo.d.ts +1 -1
  144. package/lib/typescript/src/platform/types.d.ts +20 -1
  145. package/lib/typescript/src/version.d.ts +1 -1
  146. package/package.json +14 -5
  147. package/src/components/FileViewer.tsx +283 -0
  148. package/src/components/MessageRenderer/FileMessage/VideoFileMessage.tsx +91 -0
  149. package/src/components/MessageRenderer/FileMessage/index.tsx +6 -0
  150. package/src/components/MessageRenderer/MessageOutgoingStatus.tsx +14 -54
  151. package/src/components/UserActionBar.tsx +1 -1
  152. package/src/components/UserSelectableBar.tsx +1 -1
  153. package/src/constants.ts +5 -0
  154. package/src/containers/GroupChannelPreviewContainer.tsx +117 -0
  155. package/src/{InternalErrorBoundary.tsx → containers/InternalErrorBoundaryContainer.tsx} +4 -4
  156. package/src/{SendbirdUIKitContainer.tsx → containers/SendbirdUIKitContainer.tsx} +26 -14
  157. package/src/contexts/PlatformService.tsx +15 -3
  158. package/src/contexts/SendbirdChat.tsx +13 -5
  159. package/src/domain/groupChannel/component/GroupChannelInput/SendInput.tsx +1 -1
  160. package/src/domain/groupChannel/component/GroupChannelMessageList.tsx +23 -6
  161. package/src/domain/groupChannel/module/moduleContext.tsx +6 -13
  162. package/src/domain/groupChannel/types.ts +8 -2
  163. package/src/domain/groupChannelList/types.ts +3 -2
  164. package/src/domain/groupChannelSettings/module/moduleContext.tsx +5 -10
  165. package/src/fragments/createGroupChannelCreateFragment.tsx +38 -41
  166. package/src/fragments/createGroupChannelFragment.tsx +24 -34
  167. package/src/fragments/createGroupChannelListFragment.tsx +13 -35
  168. package/src/fragments/createGroupChannelMembersFragment.tsx +34 -39
  169. package/src/hooks/useContext.ts +3 -5
  170. package/src/index.ts +6 -2
  171. package/src/{InternalLocalCacheStorage.ts → libs/InternalLocalCacheStorage.ts} +1 -1
  172. package/src/localization/StringSet.type.ts +8 -0
  173. package/src/platform/createFileService.expo.ts +17 -2
  174. package/src/platform/createFileService.native.ts +16 -3
  175. package/src/platform/createMediaService.expo.tsx +30 -0
  176. package/src/platform/createMediaService.native.tsx +37 -0
  177. package/src/platform/createNotificationService.expo.ts +1 -1
  178. package/src/platform/types.ts +26 -1
  179. package/src/version.ts +1 -1
  180. package/lib/commonjs/InternalErrorBoundary.js.map +0 -1
  181. package/lib/commonjs/InternalLocalCacheStorage.js.map +0 -1
  182. package/lib/commonjs/SendbirdUIKitContainer.js.map +0 -1
  183. package/lib/module/InternalErrorBoundary.js.map +0 -1
  184. package/lib/module/InternalLocalCacheStorage.js.map +0 -1
  185. package/lib/module/SendbirdUIKitContainer.js.map +0 -1
@@ -14,18 +14,23 @@ import {
14
14
  } from '@sendbird/uikit-react-native-foundation';
15
15
  import type { SendbirdChatSDK } from '@sendbird/uikit-utils';
16
16
 
17
- import InternalErrorBoundary from './InternalErrorBoundary';
18
- import InternalLocalCacheStorage from './InternalLocalCacheStorage';
19
- import { LocalizationProvider } from './contexts/Localization';
20
- import { PlatformServiceProvider } from './contexts/PlatformService';
21
- import { SendbirdChatProvider } from './contexts/SendbirdChat';
22
- import { useLocalization } from './hooks/useContext';
23
- import StringSetEn from './localization/StringSet.en';
24
- import type { StringSet } from './localization/StringSet.type';
25
- import SBUDynamicModule from './platform/dynamicModule';
26
- import type { ClipboardServiceInterface, FileServiceInterface, NotificationServiceInterface } from './platform/types';
27
- import type { ErrorBoundaryProps, LocalCacheStorage } from './types';
28
- import VERSION from './version';
17
+ import { LocalizationProvider } from '../contexts/Localization';
18
+ import { PlatformServiceProvider } from '../contexts/PlatformService';
19
+ import { SendbirdChatProvider } from '../contexts/SendbirdChat';
20
+ import { useLocalization } from '../hooks/useContext';
21
+ import InternalLocalCacheStorage from '../libs/InternalLocalCacheStorage';
22
+ import StringSetEn from '../localization/StringSet.en';
23
+ import type { StringSet } from '../localization/StringSet.type';
24
+ import SBUDynamicModule from '../platform/dynamicModule';
25
+ import type {
26
+ ClipboardServiceInterface,
27
+ FileServiceInterface,
28
+ MediaServiceInterface,
29
+ NotificationServiceInterface,
30
+ } from '../platform/types';
31
+ import type { ErrorBoundaryProps, LocalCacheStorage } from '../types';
32
+ import VERSION from '../version';
33
+ import InternalErrorBoundaryContainer from './InternalErrorBoundaryContainer';
29
34
 
30
35
  const NetInfo = SBUDynamicModule.get('@react-native-community/netinfo', 'warn');
31
36
 
@@ -40,11 +45,14 @@ export type SendbirdUIKitContainerProps = React.PropsWithChildren<{
40
45
  file: FileServiceInterface;
41
46
  notification: NotificationServiceInterface;
42
47
  clipboard: ClipboardServiceInterface;
48
+ media?: MediaServiceInterface;
43
49
  };
44
50
  chatOptions?: {
45
51
  localCacheStorage?: LocalCacheStorage;
46
- enableAutoPushTokenRegistration?: boolean;
47
52
  onInitialized?: (sdkInstance: SendbirdChatSDK) => SendbirdChatSDK;
53
+ enableAutoPushTokenRegistration?: boolean;
54
+ enableChannelListTypingIndicator?: boolean;
55
+ enableChannelListMessageReceiptStatus?: boolean;
48
56
  };
49
57
  localization?: {
50
58
  stringSet?: StringSet;
@@ -53,6 +61,7 @@ export type SendbirdUIKitContainerProps = React.PropsWithChildren<{
53
61
  theme?: UIKitTheme;
54
62
  statusBarTranslucent?: boolean;
55
63
  defaultHeaderTitleAlign?: 'left' | 'center';
64
+ defaultHeaderHeight?: number;
56
65
  HeaderComponent?: HeaderStyleContextType['HeaderComponent'];
57
66
  };
58
67
  toast?: {
@@ -132,12 +141,15 @@ const SendbirdUIKitContainer = ({
132
141
  <SendbirdChatProvider
133
142
  sdkInstance={sdkInstance}
134
143
  enableAutoPushTokenRegistration={chatOptions?.enableAutoPushTokenRegistration ?? true}
144
+ enableChannelListTypingIndicator={chatOptions?.enableChannelListTypingIndicator ?? false}
145
+ enableChannelListMessageReceiptStatus={chatOptions?.enableChannelListMessageReceiptStatus ?? false}
135
146
  >
136
147
  <LocalizationProvider stringSet={localization?.stringSet ?? StringSetEn}>
137
148
  <PlatformServiceProvider
138
149
  fileService={platformServices.file}
139
150
  notificationService={platformServices.notification}
140
151
  clipboardService={platformServices.clipboard}
152
+ mediaService={platformServices.media}
141
153
  >
142
154
  <UIKitThemeProvider theme={styles?.theme ?? LightUIKitTheme}>
143
155
  <HeaderStyleProvider
@@ -147,7 +159,7 @@ const SendbirdUIKitContainer = ({
147
159
  >
148
160
  <LocalizedDialogProvider>
149
161
  <ToastProvider dismissTimeout={toast?.dismissTimeout}>
150
- <InternalErrorBoundary {...errorBoundary}>{children}</InternalErrorBoundary>
162
+ <InternalErrorBoundaryContainer {...errorBoundary}>{children}</InternalErrorBoundaryContainer>
151
163
  </ToastProvider>
152
164
  </LocalizedDialogProvider>
153
165
  </HeaderStyleProvider>
@@ -1,17 +1,29 @@
1
1
  import React from 'react';
2
2
 
3
- import type { ClipboardServiceInterface, FileServiceInterface, NotificationServiceInterface } from '../platform/types';
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 = ({ children, fileService, clipboardService, notificationService }: Props) => {
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
- // enableChannelListTypingIndicator: boolean;
15
- // enableChannelListMessageReceiptStatus: boolean;
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
- // channelListTypingIndicatorEnabled: boolean;
31
- // channelListMessageReceiptStateEnabled: boolean;
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 = ({ children, sdkInstance, enableAutoPushTokenRegistration }: Props) => {
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: 'photo',
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' | 'currentUserId'
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
- if (fileType === 'image') {
257
- response.onPress = () => onPressImageMessage?.(msg, getAvailableUriFromFileMessage(msg));
258
- } else {
259
- response.onPress = () => Linking.openURL(msg.url).catch();
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
- sdk,
46
- `GroupChannelContextsProvider_${id}`,
47
- {
48
- onTypingStatusUpdated(eventChannel) {
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
- [channel, currentUser?.userId, enableTypingIndicator],
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
- onPressImageMessage?: GroupChannelProps['MessageList']['onPressImageMessage'];
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
- onPressImageMessage?: (message: SendbirdFileMessage, uri: string) => void;
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;
@@ -27,8 +27,8 @@ export interface GroupChannelListProps {
27
27
  // skipTypeSelection?: boolean;
28
28
  /** Custom Query creator for channels query **/
29
29
  queryCreator?: UseGroupChannelListOptions['queryCreator'];
30
- /** Sort comparator for sort channels **/
31
- sortComparator?: UseGroupChannelListOptions['sortComparator'];
30
+ /** Custom Collection creator for group channel collection **/
31
+ collectionCreator?: UseGroupChannelListOptions['collectionCreator'];
32
32
  /** FlatList props for GroupChannelList.List **/
33
33
  flatListProps?: GroupChannelListProps['List']['flatListProps'];
34
34
  /** Action menu item creator for onLongPress **/
@@ -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
- sdk,
46
- `${HOOK_NAME}_${uniqId}`,
47
- {
48
- onChannelChanged: onChannelChanged,
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, { useCallback } from '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> = useCallback(
54
- (user, selectedUsers, setSelectedUsers) => {
55
- if (queryCreator && !renderUser) {
56
- throw new Error('You should provide "renderUser" when providing "queryCreator"');
57
- }
58
- if (renderUser) return renderUser(user, selectedUsers, setSelectedUsers);
59
-
60
- const sbUser = user as unknown as SendbirdUser;
61
- const sbSelectedUsers = selectedUsers as unknown as SendbirdUser[];
62
- const sbSetSelectedUsers = setSelectedUsers as unknown as React.Dispatch<React.SetStateAction<SendbirdUser[]>>;
63
-
64
- const isMe = sbUser.userId === currentUser?.userId;
65
- if (isMe) return null;
66
-
67
- const userIdx = sbSelectedUsers.findIndex((u) => u.userId === sbUser.userId);
68
- const isSelected = userIdx > -1;
69
-
70
- return (
71
- <TouchableOpacity
72
- activeOpacity={0.7}
73
- onPress={() => {
74
- sbSetSelectedUsers(([...draft]) => {
75
- if (isSelected) draft.splice(userIdx, 1);
76
- else draft.push(sbUser);
77
- return draft;
78
- });
79
- }}
80
- >
81
- <UserSelectableBar
82
- uri={sbUser.profileUrl}
83
- name={sbUser.nickname || STRINGS.LABELS.USER_NO_NAME}
84
- selected={isSelected}
85
- disabled={false}
86
- />
87
- </TouchableOpacity>
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, { useCallback, useMemo } from '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 = NOOP,
25
+ onPressImageMessage,
26
+ onPressMediaMessage = NOOP,
26
27
  onChannelDeleted = NOOP,
27
28
  onBeforeSendFileMessage = PASS,
28
29
  onBeforeSendUserMessage = PASS,
@@ -54,16 +55,13 @@ const createGroupChannelFragment = (initModule?: Partial<GroupChannelModule>): G
54
55
  queryCreator,
55
56
  sortComparator,
56
57
  onChannelDeleted,
57
- enableCollectionWithoutLocalCache: true,
58
+ enableCollectionWithoutLocalCache: !queryCreator,
58
59
  });
59
60
 
60
- const _renderMessage: GroupChannelProps['MessageList']['renderMessage'] = useCallback(
61
- (props) => {
62
- if (renderMessage) return renderMessage(props);
63
- return <MessageRenderer {...props} />;
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'] = useCallback(
78
- async (file) => {
79
- const params = new sdk.FileMessageParams();
80
- params.file = file;
81
- const processedParams = await onBeforeSendFileMessage(params);
82
- await sendFileMessage(processedParams);
83
- },
84
- [sdk, sendFileMessage, onBeforeSendFileMessage],
85
- );
86
-
87
- const onSendUserMessage: GroupChannelProps['Input']['onSendUserMessage'] = useCallback(
88
- async (text) => {
89
- const params = new sdk.UserMessageParams();
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'] = useCallback(
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, { useCallback, useEffect } from 'react';
2
- import { AppState, Pressable } from 'react-native';
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 { GroupChannelPreview } from '@sendbird/uikit-react-native-foundation';
6
- import { Logger, PASS, channelComparator, getFileExtension, getFileType } from '@sendbird/uikit-utils';
5
+ import { Logger, PASS, useFreshCallback } from '@sendbird/uikit-utils';
7
6
 
8
- import ChannelCover from '../components/ChannelCover';
9
7
  import StatusComposition from '../components/StatusComposition';
10
- import { DEFAULT_LONG_PRESS_DELAY } from '../constants';
8
+ import GroupChannelPreviewContainer from '../containers/GroupChannelPreviewContainer';
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 { useLocalization, useSendbirdChat } from '../hooks/useContext';
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 ({
@@ -24,18 +21,17 @@ const createGroupChannelListFragment = (initModule?: Partial<GroupChannelListMod
24
21
  onPressChannel,
25
22
  onPressCreateChannel,
26
23
  queryCreator,
27
- sortComparator = channelComparator,
24
+ collectionCreator,
28
25
  renderGroupChannelPreview,
29
26
  // skipTypeSelection = true,
30
27
  flatListProps = {},
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
- sortComparator,
38
- enableCollectionWithoutLocalCache: true,
33
+ collectionCreator,
34
+ enableCollectionWithoutLocalCache: !queryCreator,
39
35
  });
40
36
 
41
37
  if (features.deliveryReceiptEnabled) {
@@ -47,35 +43,17 @@ const createGroupChannelListFragment = (initModule?: Partial<GroupChannelListMod
47
43
  }, []);
48
44
  }
49
45
 
50
- const _renderGroupChannelPreview: GroupChannelListProps['List']['renderGroupChannelPreview'] = useCallback(
46
+ const _renderGroupChannelPreview: GroupChannelListProps['List']['renderGroupChannelPreview'] = useFreshCallback(
51
47
  (channel, onLongPressChannel) => {
52
48
  if (renderGroupChannelPreview) return renderGroupChannelPreview(channel, onLongPressChannel);
53
49
  return (
54
- <Pressable
50
+ <GroupChannelPreviewContainer
51
+ channel={channel}
55
52
  onPress={() => onPressChannel(channel)}
56
- onLongPress={onLongPressChannel}
57
- delayLongPress={DEFAULT_LONG_PRESS_DELAY}
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) {