@sendbird/uikit-react-native 2.0.0 → 2.0.2

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 (101) hide show
  1. package/README.md +2 -2
  2. package/lib/commonjs/components/MessageRenderer/MessageIncomingAvatar.js +9 -2
  3. package/lib/commonjs/components/MessageRenderer/MessageIncomingAvatar.js.map +1 -1
  4. package/lib/commonjs/components/UserActionBar.js +7 -4
  5. package/lib/commonjs/components/UserActionBar.js.map +1 -1
  6. package/lib/commonjs/containers/GroupChannelPreviewContainer.js +23 -4
  7. package/lib/commonjs/containers/GroupChannelPreviewContainer.js.map +1 -1
  8. package/lib/commonjs/containers/SendbirdUIKitContainer.js +13 -7
  9. package/lib/commonjs/containers/SendbirdUIKitContainer.js.map +1 -1
  10. package/lib/commonjs/contexts/{Localization.js → LocalizationCtx.js} +1 -1
  11. package/lib/commonjs/contexts/LocalizationCtx.js.map +1 -0
  12. package/lib/commonjs/contexts/{PlatformService.js → PlatformServiceCtx.js} +1 -1
  13. package/lib/commonjs/contexts/PlatformServiceCtx.js.map +1 -0
  14. package/lib/commonjs/contexts/ProfileCardCtx.js +119 -0
  15. package/lib/commonjs/contexts/ProfileCardCtx.js.map +1 -0
  16. package/lib/commonjs/contexts/{SendbirdChat.js → SendbirdChatCtx.js} +3 -3
  17. package/lib/commonjs/contexts/SendbirdChatCtx.js.map +1 -0
  18. package/lib/commonjs/domain/groupChannelList/types.js.map +1 -1
  19. package/lib/commonjs/fragments/createGroupChannelFragment.js +9 -1
  20. package/lib/commonjs/fragments/createGroupChannelFragment.js.map +1 -1
  21. package/lib/commonjs/fragments/createGroupChannelListFragment.js +2 -3
  22. package/lib/commonjs/fragments/createGroupChannelListFragment.js.map +1 -1
  23. package/lib/commonjs/fragments/createGroupChannelMembersFragment.js +11 -11
  24. package/lib/commonjs/fragments/createGroupChannelMembersFragment.js.map +1 -1
  25. package/lib/commonjs/hooks/useContext.js +17 -7
  26. package/lib/commonjs/hooks/useContext.js.map +1 -1
  27. package/lib/commonjs/index.js +32 -9
  28. package/lib/commonjs/index.js.map +1 -1
  29. package/lib/commonjs/localization/StringSet.type.js +6 -0
  30. package/lib/commonjs/localization/StringSet.type.js.map +1 -1
  31. package/lib/commonjs/platform/createFileService.native.js.map +1 -1
  32. package/lib/commonjs/version.js +1 -1
  33. package/lib/commonjs/version.js.map +1 -1
  34. package/lib/module/components/MessageRenderer/MessageIncomingAvatar.js +9 -3
  35. package/lib/module/components/MessageRenderer/MessageIncomingAvatar.js.map +1 -1
  36. package/lib/module/components/UserActionBar.js +8 -5
  37. package/lib/module/components/UserActionBar.js.map +1 -1
  38. package/lib/module/containers/GroupChannelPreviewContainer.js +23 -4
  39. package/lib/module/containers/GroupChannelPreviewContainer.js.map +1 -1
  40. package/lib/module/containers/SendbirdUIKitContainer.js +9 -4
  41. package/lib/module/containers/SendbirdUIKitContainer.js.map +1 -1
  42. package/lib/module/contexts/{Localization.js → LocalizationCtx.js} +1 -1
  43. package/lib/module/contexts/LocalizationCtx.js.map +1 -0
  44. package/lib/module/contexts/{PlatformService.js → PlatformServiceCtx.js} +1 -1
  45. package/lib/module/contexts/PlatformServiceCtx.js.map +1 -0
  46. package/lib/module/contexts/ProfileCardCtx.js +97 -0
  47. package/lib/module/contexts/ProfileCardCtx.js.map +1 -0
  48. package/lib/module/contexts/{SendbirdChat.js → SendbirdChatCtx.js} +3 -3
  49. package/lib/module/contexts/SendbirdChatCtx.js.map +1 -0
  50. package/lib/module/domain/groupChannelList/types.js.map +1 -1
  51. package/lib/module/fragments/createGroupChannelFragment.js +9 -1
  52. package/lib/module/fragments/createGroupChannelFragment.js.map +1 -1
  53. package/lib/module/fragments/createGroupChannelListFragment.js +2 -3
  54. package/lib/module/fragments/createGroupChannelListFragment.js.map +1 -1
  55. package/lib/module/fragments/createGroupChannelMembersFragment.js +13 -9
  56. package/lib/module/fragments/createGroupChannelMembersFragment.js.map +1 -1
  57. package/lib/module/hooks/useContext.js +9 -3
  58. package/lib/module/hooks/useContext.js.map +1 -1
  59. package/lib/module/index.js +5 -4
  60. package/lib/module/index.js.map +1 -1
  61. package/lib/module/localization/StringSet.type.js +6 -0
  62. package/lib/module/localization/StringSet.type.js.map +1 -1
  63. package/lib/module/platform/createFileService.native.js.map +1 -1
  64. package/lib/module/version.js +1 -1
  65. package/lib/module/version.js.map +1 -1
  66. package/lib/typescript/src/components/UserActionBar.d.ts +4 -2
  67. package/lib/typescript/src/containers/SendbirdUIKitContainer.d.ts +7 -3
  68. package/lib/typescript/src/contexts/{Localization.d.ts → LocalizationCtx.d.ts} +0 -0
  69. package/lib/typescript/src/contexts/{PlatformService.d.ts → PlatformServiceCtx.d.ts} +0 -0
  70. package/lib/typescript/src/contexts/ProfileCardCtx.d.ts +15 -0
  71. package/lib/typescript/src/contexts/{SendbirdChat.d.ts → SendbirdChatCtx.d.ts} +0 -0
  72. package/lib/typescript/src/domain/groupChannelList/types.d.ts +2 -0
  73. package/lib/typescript/src/hooks/useContext.d.ts +2 -1
  74. package/lib/typescript/src/index.d.ts +5 -4
  75. package/lib/typescript/src/localization/StringSet.type.d.ts +6 -1
  76. package/lib/typescript/src/platform/createFileService.native.d.ts +1 -1
  77. package/lib/typescript/src/version.d.ts +1 -1
  78. package/package.json +9 -9
  79. package/src/components/MessageRenderer/MessageIncomingAvatar.tsx +9 -2
  80. package/src/components/UserActionBar.tsx +10 -4
  81. package/src/containers/GroupChannelPreviewContainer.tsx +20 -1
  82. package/src/containers/SendbirdUIKitContainer.tsx +26 -6
  83. package/src/contexts/{Localization.tsx → LocalizationCtx.tsx} +0 -0
  84. package/src/contexts/{PlatformService.tsx → PlatformServiceCtx.tsx} +0 -0
  85. package/src/contexts/ProfileCardCtx.tsx +125 -0
  86. package/src/contexts/{SendbirdChat.tsx → SendbirdChatCtx.tsx} +2 -2
  87. package/src/domain/groupChannelList/types.ts +2 -2
  88. package/src/fragments/createGroupChannelFragment.tsx +18 -8
  89. package/src/fragments/createGroupChannelListFragment.tsx +2 -3
  90. package/src/fragments/createGroupChannelMembersFragment.tsx +25 -25
  91. package/src/hooks/useContext.ts +10 -3
  92. package/src/index.ts +5 -4
  93. package/src/localization/StringSet.type.ts +12 -0
  94. package/src/platform/createFileService.native.ts +1 -1
  95. package/src/version.ts +1 -1
  96. package/lib/commonjs/contexts/Localization.js.map +0 -1
  97. package/lib/commonjs/contexts/PlatformService.js.map +0 -1
  98. package/lib/commonjs/contexts/SendbirdChat.js.map +0 -1
  99. package/lib/module/contexts/Localization.js.map +0 -1
  100. package/lib/module/contexts/PlatformService.js.map +0 -1
  101. package/lib/module/contexts/SendbirdChat.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"names":["VERSION"],"sources":["version.ts"],"sourcesContent":["const VERSION = '2.0.0';\nexport default VERSION;\n"],"mappings":"AAAA,MAAMA,OAAO,GAAG,OAAhB;AACA,eAAeA,OAAf"}
1
+ {"version":3,"names":["VERSION"],"sources":["version.ts"],"sourcesContent":["const VERSION = '2.0.2';\nexport default VERSION;\n"],"mappings":"AAAA,MAAMA,OAAO,GAAG,OAAhB;AACA,eAAeA,OAAf"}
@@ -1,10 +1,12 @@
1
+ import type { GestureResponderEvent } from 'react-native';
1
2
  declare type Props = {
2
3
  uri: string;
3
4
  name: string;
4
5
  label?: string;
5
6
  muted: boolean;
6
7
  disabled: boolean;
7
- onPressActionMenu?: () => void;
8
+ onPressActionMenu?: (ev: GestureResponderEvent) => void;
9
+ onPressAvatar?: (ev: GestureResponderEvent) => void;
8
10
  };
9
- declare const UserActionBar: ({ muted, uri, name, disabled, onPressActionMenu, label }: Props) => JSX.Element;
11
+ declare const UserActionBar: ({ muted, uri, name, disabled, label, onPressActionMenu, onPressAvatar }: Props) => JSX.Element;
10
12
  export default UserActionBar;
@@ -1,11 +1,11 @@
1
1
  import React from 'react';
2
2
  import type { HeaderStyleContextType, UIKitTheme } from '@sendbird/uikit-react-native-foundation';
3
- import type { SendbirdChatSDK } from '@sendbird/uikit-utils';
3
+ import type { SendbirdChatSDK, SendbirdGroupChannel, SendbirdGroupChannelCreateParams, SendbirdMember, SendbirdUser } from '@sendbird/uikit-utils';
4
4
  import type { StringSet } from '../localization/StringSet.type';
5
5
  import type { ClipboardServiceInterface, FileServiceInterface, MediaServiceInterface, NotificationServiceInterface } from '../platform/types';
6
6
  import type { ErrorBoundaryProps, LocalCacheStorage } from '../types';
7
7
  export declare const SendbirdUIKit: Readonly<{
8
- VERSION: "2.0.0";
8
+ VERSION: "2.0.2";
9
9
  PLATFORM: string;
10
10
  }>;
11
11
  export declare type SendbirdUIKitContainerProps = React.PropsWithChildren<{
@@ -36,10 +36,14 @@ export declare type SendbirdUIKitContainerProps = React.PropsWithChildren<{
36
36
  toast?: {
37
37
  dismissTimeout?: number;
38
38
  };
39
+ profileCard?: {
40
+ onCreateChannel: (channel: SendbirdGroupChannel) => void;
41
+ onBeforeCreateChannel?: (channelParams: SendbirdGroupChannelCreateParams, users: SendbirdUser[] | SendbirdMember[]) => SendbirdGroupChannelCreateParams | Promise<SendbirdGroupChannelCreateParams>;
42
+ };
39
43
  errorBoundary?: {
40
44
  onError?: (props: ErrorBoundaryProps) => void;
41
45
  ErrorInfoComponent?: (props: ErrorBoundaryProps) => JSX.Element;
42
46
  };
43
47
  }>;
44
- declare const SendbirdUIKitContainer: ({ children, appId, chatOptions, platformServices, localization, styles, toast, errorBoundary, }: SendbirdUIKitContainerProps) => JSX.Element;
48
+ declare const SendbirdUIKitContainer: ({ children, appId, chatOptions, platformServices, localization, styles, toast, profileCard, errorBoundary, }: SendbirdUIKitContainerProps) => JSX.Element;
45
49
  export default SendbirdUIKitContainer;
@@ -0,0 +1,15 @@
1
+ import React from 'react';
2
+ import type { SendbirdGroupChannel, SendbirdGroupChannelCreateParams, SendbirdMember, SendbirdUser } from '@sendbird/uikit-utils';
3
+ declare type OnCreateChannel = (channel: SendbirdGroupChannel) => void;
4
+ declare type OnBeforeCreateChannel = (channelParams: SendbirdGroupChannelCreateParams, users: SendbirdUser[] | SendbirdMember[]) => SendbirdGroupChannelCreateParams | Promise<SendbirdGroupChannelCreateParams>;
5
+ export declare type ProfileCardContextType = {
6
+ show(user: SendbirdUser | SendbirdMember): void;
7
+ hide(): void;
8
+ };
9
+ declare type Props = React.PropsWithChildren<{
10
+ onCreateChannel?: OnCreateChannel;
11
+ onBeforeCreateChannel?: OnBeforeCreateChannel;
12
+ }>;
13
+ export declare const ProfileCardContext: React.Context<ProfileCardContextType | null>;
14
+ export declare const ProfileCardProvider: ({ children, onCreateChannel, onBeforeCreateChannel }: Props) => JSX.Element;
15
+ export {};
@@ -19,6 +19,8 @@ export interface GroupChannelListProps {
19
19
  }>>;
20
20
  /** Method to render GroupChannel preview **/
21
21
  renderGroupChannelPreview?: (channel: SendbirdGroupChannel, onLongPressChannel: () => void) => React.ReactElement | null;
22
+ /** Skip type selection, When this is set to true 'channelType' only receive 'GROUP' type **/
23
+ skipTypeSelection?: boolean;
22
24
  /** Custom Query creator for channels query **/
23
25
  queryCreator?: UseGroupChannelListOptions['queryCreator'];
24
26
  /** Custom Collection creator for group channel collection **/
@@ -1,5 +1,5 @@
1
1
  /// <reference types="react" />
2
- export declare const useLocalization: () => import("../contexts/Localization").LocalizationContextType;
2
+ export declare const useLocalization: () => import("../contexts/LocalizationCtx").LocalizationContextType;
3
3
  export declare const usePlatformService: () => {
4
4
  fileService: import("..").FileServiceInterface;
5
5
  clipboardService: import("..").ClipboardServiceInterface;
@@ -24,3 +24,4 @@ export declare const useSendbirdChat: () => {
24
24
  reactionEnabled: boolean;
25
25
  };
26
26
  };
27
+ export declare const useProfileCard: () => import("../contexts/ProfileCardCtx").ProfileCardContextType;
@@ -17,13 +17,14 @@ export { default as createGroupChannelInviteFragment } from './fragments/createG
17
17
  export { default as createGroupChannelListFragment } from './fragments/createGroupChannelListFragment';
18
18
  export { default as createGroupChannelMembersFragment } from './fragments/createGroupChannelMembersFragment';
19
19
  /** Context **/
20
- export { SendbirdChatContext, SendbirdChatProvider } from './contexts/SendbirdChat';
21
- export { PlatformServiceContext, PlatformServiceProvider } from './contexts/PlatformService';
22
- export { LocalizationContext, LocalizationProvider } from './contexts/Localization';
20
+ export { SendbirdChatContext, SendbirdChatProvider } from './contexts/SendbirdChatCtx';
21
+ export { PlatformServiceContext, PlatformServiceProvider } from './contexts/PlatformServiceCtx';
22
+ export { ProfileCardContext, ProfileCardProvider } from './contexts/ProfileCardCtx';
23
+ export { LocalizationContext, LocalizationProvider } from './contexts/LocalizationCtx';
23
24
  /** Hooks **/
24
25
  export { default as useConnection } from './hooks/useConnection';
25
26
  export { default as usePushTokenRegistration } from './hooks/usePushTokenRegistration';
26
- export { useLocalization, usePlatformService, useSendbirdChat } from './hooks/useContext';
27
+ export { useLocalization, usePlatformService, useSendbirdChat, useProfileCard } from './hooks/useContext';
27
28
  /** Localization **/
28
29
  export { default as StringSetEn } from './localization/StringSet.en';
29
30
  export { createBaseStringSet } from './localization/StringSet.type';
@@ -1,5 +1,5 @@
1
1
  import type { Locale } from 'date-fns';
2
- import type { PartialDeep, SendbirdFileMessage, SendbirdGroupChannel, SendbirdMessage, SendbirdUser } from '@sendbird/uikit-utils';
2
+ import type { PartialDeep, SendbirdFileMessage, SendbirdGroupChannel, SendbirdMember, SendbirdMessage, SendbirdUser } from '@sendbird/uikit-utils';
3
3
  /**
4
4
  * StringSet interface
5
5
  * Do not configure over 3 depths (for overrides easy)
@@ -148,6 +148,11 @@ export interface StringSet {
148
148
  TURN_OFF_NOTIFICATIONS_ERROR: string;
149
149
  LEAVE_CHANNEL_ERROR: string;
150
150
  };
151
+ PROFILE_CARD: {
152
+ BUTTON_MESSAGE: string;
153
+ BODY_LABEL: string;
154
+ BODY: (user: SendbirdUser | SendbirdMember) => string;
155
+ };
151
156
  }
152
157
  declare type StringSetCreateOptions = {
153
158
  dateLocale: Locale;
@@ -1,4 +1,4 @@
1
- import type CameraRoll from '@react-native-community/cameraroll';
1
+ import type { CameraRoll } from '@react-native-camera-roll/camera-roll';
2
2
  import type * as DocumentPicker from 'react-native-document-picker';
3
3
  import type * as FileAccess from 'react-native-file-access';
4
4
  import type * as ImagePicker from 'react-native-image-picker';
@@ -1,2 +1,2 @@
1
- declare const VERSION = "2.0.0";
1
+ declare const VERSION = "2.0.2";
2
2
  export default VERSION;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sendbird/uikit-react-native",
3
- "version": "2.0.0",
3
+ "version": "2.0.2",
4
4
  "description": "react-native-uikit",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",
@@ -41,13 +41,13 @@
41
41
  "access": "public"
42
42
  },
43
43
  "dependencies": {
44
- "@sendbird/uikit-chat-hooks": "2.0.0",
45
- "@sendbird/uikit-react-native-foundation": "2.0.0",
46
- "@sendbird/uikit-utils": "2.0.0"
44
+ "@sendbird/uikit-chat-hooks": "2.0.2",
45
+ "@sendbird/uikit-react-native-foundation": "2.0.2",
46
+ "@sendbird/uikit-utils": "2.0.2"
47
47
  },
48
48
  "devDependencies": {
49
+ "@react-native-camera-roll/camera-roll": "^5.0.4",
49
50
  "@react-native-clipboard/clipboard": "^1.8.5",
50
- "@react-native-community/cameraroll": "^4.1.2",
51
51
  "@react-native-community/netinfo": "^9.3.0",
52
52
  "@react-native-firebase/app": "^14.4.0",
53
53
  "@react-native-firebase/messaging": "^14.4.0",
@@ -79,8 +79,8 @@
79
79
  "typescript": "^4.1.3"
80
80
  },
81
81
  "peerDependencies": {
82
+ "@react-native-camera-roll/camera-roll": ">=5.0.0",
82
83
  "@react-native-clipboard/clipboard": ">=1.8.5",
83
- "@react-native-community/cameraroll": ">=4.1.2",
84
84
  "@react-native-community/netinfo": ">=9.3.0",
85
85
  "@react-native-firebase/messaging": ">=14.4.0",
86
86
  "@sendbird/chat": "^4.0.13",
@@ -103,10 +103,10 @@
103
103
  "react-native-video": ">=5.2.0"
104
104
  },
105
105
  "peerDependenciesMeta": {
106
- "@react-native-clipboard/clipboard": {
106
+ "@react-native-camera-roll/camera-roll": {
107
107
  "optional": true
108
108
  },
109
- "@react-native-community/cameraroll": {
109
+ "@react-native-clipboard/clipboard": {
110
110
  "optional": true
111
111
  },
112
112
  "@react-native-firebase/messaging": {
@@ -171,5 +171,5 @@
171
171
  "readmeFile": "./README.md",
172
172
  "displayName": "@sendbird/uikit-react-native"
173
173
  },
174
- "gitHead": "955f7adf0891976d8553d9c3b4c171225c775bc9"
174
+ "gitHead": "95323825da753f20b931b4a8b7e187cd8dc6284e"
175
175
  }
@@ -1,18 +1,25 @@
1
1
  import React from 'react';
2
- import { View } from 'react-native';
2
+ import { Pressable, View } from 'react-native';
3
3
 
4
4
  import { Avatar, createStyleSheet } from '@sendbird/uikit-react-native-foundation';
5
5
  import type { SendbirdMessage } from '@sendbird/uikit-utils';
6
6
 
7
+ import { useProfileCard } from '../../hooks/useContext';
8
+
7
9
  type Props = {
8
10
  message: SendbirdMessage;
9
11
  grouping: boolean;
10
12
  };
11
13
  const MessageIncomingAvatar = ({ message, grouping }: Props) => {
14
+ const { show } = useProfileCard();
12
15
  if (grouping) return <View style={styles.avatar} />;
13
16
  return (
14
17
  <View style={styles.avatar}>
15
- {(message.isFileMessage() || message.isUserMessage()) && <Avatar size={26} uri={message.sender?.profileUrl} />}
18
+ {(message.isFileMessage() || message.isUserMessage()) && (
19
+ <Pressable onPress={() => show(message.sender)}>
20
+ <Avatar size={26} uri={message.sender?.profileUrl} />
21
+ </Pressable>
22
+ )}
16
23
  </View>
17
24
  );
18
25
  };
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
- import { TouchableOpacity, View } from 'react-native';
2
+ import { Pressable, TouchableOpacity, View } from 'react-native';
3
+ import type { GestureResponderEvent } from 'react-native';
3
4
 
4
5
  import { Avatar, Icon, Text, createStyleSheet, useUIKitTheme } from '@sendbird/uikit-react-native-foundation';
5
6
  import { conditionChaining } from '@sendbird/uikit-utils';
@@ -8,18 +9,23 @@ type Props = {
8
9
  uri: string;
9
10
  name: string;
10
11
  label?: string;
12
+
11
13
  muted: boolean;
12
14
  disabled: boolean;
13
- onPressActionMenu?: () => void;
15
+
16
+ onPressActionMenu?: (ev: GestureResponderEvent) => void;
17
+ onPressAvatar?: (ev: GestureResponderEvent) => void;
14
18
  };
15
- const UserActionBar = ({ muted, uri, name, disabled, onPressActionMenu, label }: Props) => {
19
+ const UserActionBar = ({ muted, uri, name, disabled, label, onPressActionMenu, onPressAvatar }: Props) => {
16
20
  const { colors } = useUIKitTheme();
17
21
 
18
22
  const iconColor = conditionChaining([disabled], [colors.onBackground04, colors.onBackground01]);
19
23
 
20
24
  return (
21
25
  <View style={styles.container}>
22
- <Avatar muted={muted} size={36} uri={uri} containerStyle={styles.avatar} />
26
+ <Pressable onPress={onPressAvatar} style={styles.avatar}>
27
+ <Avatar muted={muted} size={36} uri={uri} />
28
+ </Pressable>
23
29
  <View style={[styles.infoContainer, { borderBottomColor: colors.onBackground04 }]}>
24
30
  <Text subtitle2 numberOfLines={1} style={styles.name} color={colors.onBackground01}>
25
31
  {name}
@@ -89,10 +89,24 @@ const GroupChannelPreviewContainer = ({ onPress, onLongPress, channel }: Props)
89
89
  return undefined;
90
90
  });
91
91
 
92
+ const customCover = useIIFE(() => {
93
+ if (channel.isBroadcast) {
94
+ return (
95
+ <Icon
96
+ icon={'broadcast'}
97
+ size={32}
98
+ color={colors.onBackgroundReverse01}
99
+ containerStyle={[styles.broadcastCover, { backgroundColor: colors.secondary }]}
100
+ />
101
+ );
102
+ }
103
+ return <ChannelCover channel={channel} size={56} />;
104
+ });
105
+
92
106
  return (
93
107
  <Pressable delayLongPress={DEFAULT_LONG_PRESS_DELAY} onPress={onPress} onLongPress={onLongPress}>
94
108
  <GroupChannelPreview
95
- customCover={<ChannelCover channel={channel} size={56} />}
109
+ customCover={customCover}
96
110
  coverUrl={channel.coverUrl}
97
111
  title={STRINGS.GROUP_CHANNEL_LIST.CHANNEL_PREVIEW_TITLE(currentUser?.userId ?? '', channel)}
98
112
  titleCaptionLeft={titleCaptionIcon}
@@ -102,6 +116,7 @@ const GroupChannelPreviewContainer = ({ onPress, onLongPress, channel }: Props)
102
116
  badgeCount={channel.unreadMessageCount}
103
117
  memberCount={channel.memberCount > 2 ? channel.memberCount : undefined}
104
118
  frozen={channel.isFrozen}
119
+ broadcast={channel.isBroadcast}
105
120
  notificationOff={channel.myPushTriggerOption === 'off'}
106
121
  />
107
122
  </Pressable>
@@ -112,6 +127,10 @@ const styles = createStyleSheet({
112
127
  titleCaptionIcon: {
113
128
  marginRight: 4,
114
129
  },
130
+ broadcastCover: {
131
+ padding: 12,
132
+ borderRadius: 28,
133
+ },
115
134
  });
116
135
 
117
136
  export default GroupChannelPreviewContainer;
@@ -14,11 +14,18 @@ import {
14
14
  ToastProvider,
15
15
  UIKitThemeProvider,
16
16
  } from '@sendbird/uikit-react-native-foundation';
17
- import type { SendbirdChatSDK } from '@sendbird/uikit-utils';
18
-
19
- import { LocalizationProvider } from '../contexts/Localization';
20
- import { PlatformServiceProvider } from '../contexts/PlatformService';
21
- import { SendbirdChatProvider } from '../contexts/SendbirdChat';
17
+ import type {
18
+ SendbirdChatSDK,
19
+ SendbirdGroupChannel,
20
+ SendbirdGroupChannelCreateParams,
21
+ SendbirdMember,
22
+ SendbirdUser,
23
+ } from '@sendbird/uikit-utils';
24
+
25
+ import { LocalizationProvider } from '../contexts/LocalizationCtx';
26
+ import { PlatformServiceProvider } from '../contexts/PlatformServiceCtx';
27
+ import { ProfileCardProvider } from '../contexts/ProfileCardCtx';
28
+ import { SendbirdChatProvider } from '../contexts/SendbirdChatCtx';
22
29
  import { useLocalization } from '../hooks/useContext';
23
30
  import InternalLocalCacheStorage from '../libs/InternalLocalCacheStorage';
24
31
  import StringSetEn from '../localization/StringSet.en';
@@ -69,6 +76,13 @@ export type SendbirdUIKitContainerProps = React.PropsWithChildren<{
69
76
  toast?: {
70
77
  dismissTimeout?: number;
71
78
  };
79
+ profileCard?: {
80
+ onCreateChannel: (channel: SendbirdGroupChannel) => void;
81
+ onBeforeCreateChannel?: (
82
+ channelParams: SendbirdGroupChannelCreateParams,
83
+ users: SendbirdUser[] | SendbirdMember[],
84
+ ) => SendbirdGroupChannelCreateParams | Promise<SendbirdGroupChannelCreateParams>;
85
+ };
72
86
  errorBoundary?: {
73
87
  onError?: (props: ErrorBoundaryProps) => void;
74
88
  ErrorInfoComponent?: (props: ErrorBoundaryProps) => JSX.Element;
@@ -83,6 +97,7 @@ const SendbirdUIKitContainer = ({
83
97
  localization,
84
98
  styles,
85
99
  toast,
100
+ profileCard,
86
101
  errorBoundary,
87
102
  }: SendbirdUIKitContainerProps) => {
88
103
  const unsubscribes = useRef<(() => void)[]>([]).current;
@@ -163,7 +178,12 @@ const SendbirdUIKitContainer = ({
163
178
  >
164
179
  <LocalizedDialogProvider>
165
180
  <ToastProvider dismissTimeout={toast?.dismissTimeout}>
166
- <InternalErrorBoundaryContainer {...errorBoundary}>{children}</InternalErrorBoundaryContainer>
181
+ <ProfileCardProvider
182
+ onCreateChannel={profileCard?.onCreateChannel}
183
+ onBeforeCreateChannel={profileCard?.onBeforeCreateChannel}
184
+ >
185
+ <InternalErrorBoundaryContainer {...errorBoundary}>{children}</InternalErrorBoundaryContainer>
186
+ </ProfileCardProvider>
167
187
  </ToastProvider>
168
188
  </LocalizedDialogProvider>
169
189
  </HeaderStyleProvider>
@@ -0,0 +1,125 @@
1
+ import React, { useContext, useState } from 'react';
2
+ import { useSafeAreaInsets } from 'react-native-safe-area-context';
3
+
4
+ import { Modal, OutlinedButton, ProfileCard, createStyleSheet } from '@sendbird/uikit-react-native-foundation';
5
+ import type {
6
+ SendbirdGroupChannel,
7
+ SendbirdGroupChannelCreateParams,
8
+ SendbirdMember,
9
+ SendbirdUser,
10
+ } from '@sendbird/uikit-utils';
11
+ import { Logger, PASS, useIIFE } from '@sendbird/uikit-utils';
12
+
13
+ import { LocalizationContext } from '../contexts/LocalizationCtx';
14
+ import { SendbirdChatContext } from '../contexts/SendbirdChatCtx';
15
+
16
+ type OnCreateChannel = (channel: SendbirdGroupChannel) => void;
17
+ type OnBeforeCreateChannel = (
18
+ channelParams: SendbirdGroupChannelCreateParams,
19
+ users: SendbirdUser[] | SendbirdMember[],
20
+ ) => SendbirdGroupChannelCreateParams | Promise<SendbirdGroupChannelCreateParams>;
21
+
22
+ export type ProfileCardContextType = {
23
+ show(user: SendbirdUser | SendbirdMember): void;
24
+ hide(): void;
25
+ };
26
+
27
+ type Props = React.PropsWithChildren<{
28
+ onCreateChannel?: OnCreateChannel;
29
+ onBeforeCreateChannel?: OnBeforeCreateChannel;
30
+ }>;
31
+
32
+ export const ProfileCardContext = React.createContext<ProfileCardContextType | null>(null);
33
+ export const ProfileCardProvider = ({ children, onCreateChannel, onBeforeCreateChannel = PASS }: Props) => {
34
+ const chatContext = useContext(SendbirdChatContext);
35
+ const localizationContext = useContext(LocalizationContext);
36
+ const { bottom, left, right } = useSafeAreaInsets();
37
+
38
+ const [user, setUser] = useState<SendbirdUser | SendbirdMember>();
39
+ const [visible, setVisible] = useState(false);
40
+
41
+ const show: ProfileCardContextType['show'] = (user) => {
42
+ setUser(user);
43
+ setVisible(true);
44
+ };
45
+
46
+ const hide: ProfileCardContextType['hide'] = () => {
47
+ setVisible(false);
48
+ };
49
+
50
+ if (!chatContext) throw new Error('SendbirdChatContext is not provided');
51
+ if (!localizationContext) throw new Error('LocalizationContext is not provided');
52
+
53
+ const profileCardButton = useIIFE(() => {
54
+ const isMe = chatContext.currentUser && user?.userId === chatContext.currentUser.userId;
55
+ if (isMe) return undefined;
56
+
57
+ const onPressMessageButton = async () => {
58
+ if (user) {
59
+ const params: SendbirdGroupChannelCreateParams = {
60
+ invitedUserIds: [user.userId],
61
+ name: '',
62
+ coverUrl: '',
63
+ isDistinct: false,
64
+ };
65
+
66
+ if (chatContext.currentUser) params.operatorUserIds = [chatContext.currentUser.userId];
67
+ const processedParams = await onBeforeCreateChannel(params, [user]);
68
+
69
+ hide();
70
+ const channel = await chatContext.sdk.groupChannel.createChannel(processedParams);
71
+
72
+ if (onCreateChannel) {
73
+ onCreateChannel(channel);
74
+ } else {
75
+ Logger.warn(
76
+ 'Please set `onCreateChannel` before message to user from profile card, see `profileCard` prop in the `SendbirdUIKitContainer` props',
77
+ );
78
+ }
79
+ }
80
+ };
81
+
82
+ return (
83
+ <OutlinedButton onPress={onPressMessageButton}>
84
+ {localizationContext.STRINGS.PROFILE_CARD.BUTTON_MESSAGE}
85
+ </OutlinedButton>
86
+ );
87
+ });
88
+
89
+ return (
90
+ <ProfileCardContext.Provider value={{ show, hide }}>
91
+ {children}
92
+ <Modal
93
+ type={'slide'}
94
+ onClose={hide}
95
+ onDismiss={() => setUser(undefined)}
96
+ visible={visible && Boolean(user)}
97
+ backgroundStyle={styles.modal}
98
+ >
99
+ {user && (
100
+ <ProfileCard
101
+ containerStyle={[
102
+ styles.profileCardContainer,
103
+ { paddingLeft: left, paddingRight: right, paddingBottom: bottom },
104
+ ]}
105
+ uri={user.profileUrl}
106
+ username={user.nickname || localizationContext.STRINGS.LABELS.USER_NO_NAME}
107
+ bodyLabel={localizationContext.STRINGS.PROFILE_CARD.BODY_LABEL}
108
+ body={localizationContext.STRINGS.PROFILE_CARD.BODY(user)}
109
+ button={profileCardButton}
110
+ />
111
+ )}
112
+ </Modal>
113
+ </ProfileCardContext.Provider>
114
+ );
115
+ };
116
+
117
+ const styles = createStyleSheet({
118
+ modal: {
119
+ justifyContent: 'flex-end',
120
+ },
121
+ profileCardContainer: {
122
+ borderTopLeftRadius: 8,
123
+ borderTopRightRadius: 8,
124
+ },
125
+ });
@@ -87,7 +87,7 @@ export const SendbirdChatProvider = ({
87
87
 
88
88
  const markAsDeliveredWithChannel: Context['markAsDeliveredWithChannel'] = useCallback(
89
89
  (channel: SendbirdGroupChannel) => {
90
- if (appFeatures.deliveryReceiptEnabled) confirmAndMarkAsDelivered(sdkInstance, channel);
90
+ if (appFeatures.deliveryReceiptEnabled) confirmAndMarkAsDelivered([channel]);
91
91
  },
92
92
  [sdkInstance, appFeatures.deliveryReceiptEnabled],
93
93
  );
@@ -96,7 +96,7 @@ export const SendbirdChatProvider = ({
96
96
  const listener = (status: AppStateStatus) => {
97
97
  // 'active' | 'background' | 'inactive' | 'unknown' | 'extension';
98
98
  if (status === 'active') sdkInstance.connectionState === 'CLOSED' && sdkInstance.setForegroundState();
99
- else sdkInstance.connectionState === 'OPEN' && sdkInstance.setBackgroundState();
99
+ else if (status === 'background') sdkInstance.connectionState === 'OPEN' && sdkInstance.setBackgroundState();
100
100
  };
101
101
 
102
102
  const subscriber = AppState.addEventListener('change', listener);
@@ -23,8 +23,8 @@ export interface GroupChannelListProps {
23
23
  channel: SendbirdGroupChannel,
24
24
  onLongPressChannel: () => void,
25
25
  ) => React.ReactElement | null;
26
- // /** Skip type selection, When this is set to true 'channelType' only receive 'GROUP' type **/
27
- // skipTypeSelection?: boolean;
26
+ /** Skip type selection, When this is set to true 'channelType' only receive 'GROUP' type **/
27
+ skipTypeSelection?: boolean;
28
28
  /** Custom Query creator for channels query **/
29
29
  queryCreator?: UseGroupChannelListOptions['queryCreator'];
30
30
  /** Custom Collection creator for group channel collection **/
@@ -1,7 +1,7 @@
1
1
  import React, { useMemo } from 'react';
2
2
 
3
3
  import { useGroupChannelMessages } from '@sendbird/uikit-chat-hooks';
4
- import { NOOP, PASS, messageComparator, useFreshCallback } from '@sendbird/uikit-utils';
4
+ import { NOOP, PASS, SendbirdGroupChannel, messageComparator, useFreshCallback } from '@sendbird/uikit-utils';
5
5
 
6
6
  import MessageRenderer from '../components/MessageRenderer';
7
7
  import NewMessagesButton from '../components/NewMessagesButton';
@@ -119,17 +119,27 @@ const createGroupChannelFragment = (initModule?: Partial<GroupChannelModule>): G
119
119
  onPressMediaMessage={onPressMediaMessage}
120
120
  flatListProps={memoizedFlatListProps}
121
121
  />
122
- <GroupChannelModule.Input
123
- channel={activeChannel}
124
- onSendFileMessage={onSendFileMessage}
125
- onSendUserMessage={onSendUserMessage}
126
- onUpdateFileMessage={onUpdateFileMessage}
127
- onUpdateUserMessage={onUpdateUserMessage}
128
- />
122
+ {shouldRenderInput(channel) && (
123
+ <GroupChannelModule.Input
124
+ channel={activeChannel}
125
+ onSendFileMessage={onSendFileMessage}
126
+ onSendUserMessage={onSendUserMessage}
127
+ onUpdateFileMessage={onUpdateFileMessage}
128
+ onUpdateUserMessage={onUpdateUserMessage}
129
+ />
130
+ )}
129
131
  </StatusComposition>
130
132
  </GroupChannelModule.Provider>
131
133
  );
132
134
  };
133
135
  };
134
136
 
137
+ function shouldRenderInput(channel: SendbirdGroupChannel) {
138
+ if (channel.isBroadcast) {
139
+ return channel.myRole === 'operator';
140
+ }
141
+
142
+ return true;
143
+ }
144
+
135
145
  export default createGroupChannelFragment;
@@ -23,7 +23,7 @@ const createGroupChannelListFragment = (initModule?: Partial<GroupChannelListMod
23
23
  queryCreator,
24
24
  collectionCreator,
25
25
  renderGroupChannelPreview,
26
- // skipTypeSelection = true,
26
+ skipTypeSelection = false,
27
27
  flatListProps = {},
28
28
  menuItemCreator = PASS,
29
29
  }) => {
@@ -78,8 +78,7 @@ const createGroupChannelListFragment = (initModule?: Partial<GroupChannelListMod
78
78
  />
79
79
  </StatusComposition>
80
80
  <GroupChannelListModule.TypeSelector
81
- // NOTE: not included in first iteration
82
- skipTypeSelection
81
+ skipTypeSelection={skipTypeSelection}
83
82
  Header={TypeSelectorHeader}
84
83
  onSelectType={onPressCreateChannel}
85
84
  />