stream-chat-react-native-core 9.4.1-beta.1 → 9.5.0-beta.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 (133) hide show
  1. package/lib/commonjs/components/ChannelDetails/components/members/ChannelAddMembers.js +7 -4
  2. package/lib/commonjs/components/ChannelDetails/components/members/ChannelAddMembers.js.map +1 -1
  3. package/lib/commonjs/components/ChannelDetails/components/members/ChannelAllMembersModal.js +2 -23
  4. package/lib/commonjs/components/ChannelDetails/components/members/ChannelAllMembersModal.js.map +1 -1
  5. package/lib/commonjs/components/ChannelDetails/components/members/ChannelMemberList.js +124 -22
  6. package/lib/commonjs/components/ChannelDetails/components/members/ChannelMemberList.js.map +1 -1
  7. package/lib/commonjs/components/ChannelDetails/components/navigation-section/PinnedMessageItem.js +1 -1
  8. package/lib/commonjs/components/ChannelDetails/components/navigation-section/PinnedMessageItem.js.map +1 -1
  9. package/lib/commonjs/components/ChannelDetails/components/navigation-section/PinnedMessageList.js +1 -1
  10. package/lib/commonjs/components/ChannelDetails/components/navigation-section/PinnedMessageList.js.map +1 -1
  11. package/lib/commonjs/components/ChannelDetails/hooks/members/index.js +0 -11
  12. package/lib/commonjs/components/ChannelDetails/hooks/members/index.js.map +1 -1
  13. package/lib/commonjs/components/UIComponents/SearchInput.js +1 -3
  14. package/lib/commonjs/components/UIComponents/SearchInput.js.map +1 -1
  15. package/lib/commonjs/contexts/channelMemberListContext/ChannelMemberListContext.js +63 -0
  16. package/lib/commonjs/contexts/channelMemberListContext/ChannelMemberListContext.js.map +1 -0
  17. package/lib/commonjs/contexts/index.js +11 -0
  18. package/lib/commonjs/contexts/index.js.map +1 -1
  19. package/lib/commonjs/contexts/themeContext/utils/theme.js +8 -0
  20. package/lib/commonjs/contexts/themeContext/utils/theme.js.map +1 -1
  21. package/lib/commonjs/i18n/ar.json +3 -1
  22. package/lib/commonjs/i18n/en.json +2 -0
  23. package/lib/commonjs/i18n/es.json +3 -1
  24. package/lib/commonjs/i18n/fr.json +3 -1
  25. package/lib/commonjs/i18n/he.json +3 -1
  26. package/lib/commonjs/i18n/hi.json +3 -1
  27. package/lib/commonjs/i18n/it.json +3 -1
  28. package/lib/commonjs/i18n/ja.json +3 -1
  29. package/lib/commonjs/i18n/ko.json +3 -1
  30. package/lib/commonjs/i18n/nl.json +3 -1
  31. package/lib/commonjs/i18n/pt-br.json +3 -1
  32. package/lib/commonjs/i18n/ru.json +3 -1
  33. package/lib/commonjs/i18n/tr.json +3 -1
  34. package/lib/commonjs/version.json +1 -1
  35. package/lib/module/components/ChannelDetails/components/members/ChannelAddMembers.js +7 -4
  36. package/lib/module/components/ChannelDetails/components/members/ChannelAddMembers.js.map +1 -1
  37. package/lib/module/components/ChannelDetails/components/members/ChannelAllMembersModal.js +2 -23
  38. package/lib/module/components/ChannelDetails/components/members/ChannelAllMembersModal.js.map +1 -1
  39. package/lib/module/components/ChannelDetails/components/members/ChannelMemberList.js +124 -22
  40. package/lib/module/components/ChannelDetails/components/members/ChannelMemberList.js.map +1 -1
  41. package/lib/module/components/ChannelDetails/components/navigation-section/PinnedMessageItem.js +1 -1
  42. package/lib/module/components/ChannelDetails/components/navigation-section/PinnedMessageItem.js.map +1 -1
  43. package/lib/module/components/ChannelDetails/components/navigation-section/PinnedMessageList.js +1 -1
  44. package/lib/module/components/ChannelDetails/components/navigation-section/PinnedMessageList.js.map +1 -1
  45. package/lib/module/components/ChannelDetails/hooks/members/index.js +0 -11
  46. package/lib/module/components/ChannelDetails/hooks/members/index.js.map +1 -1
  47. package/lib/module/components/UIComponents/SearchInput.js +1 -3
  48. package/lib/module/components/UIComponents/SearchInput.js.map +1 -1
  49. package/lib/module/contexts/channelMemberListContext/ChannelMemberListContext.js +63 -0
  50. package/lib/module/contexts/channelMemberListContext/ChannelMemberListContext.js.map +1 -0
  51. package/lib/module/contexts/index.js +11 -0
  52. package/lib/module/contexts/index.js.map +1 -1
  53. package/lib/module/contexts/themeContext/utils/theme.js +8 -0
  54. package/lib/module/contexts/themeContext/utils/theme.js.map +1 -1
  55. package/lib/module/i18n/ar.json +3 -1
  56. package/lib/module/i18n/en.json +2 -0
  57. package/lib/module/i18n/es.json +3 -1
  58. package/lib/module/i18n/fr.json +3 -1
  59. package/lib/module/i18n/he.json +3 -1
  60. package/lib/module/i18n/hi.json +3 -1
  61. package/lib/module/i18n/it.json +3 -1
  62. package/lib/module/i18n/ja.json +3 -1
  63. package/lib/module/i18n/ko.json +3 -1
  64. package/lib/module/i18n/nl.json +3 -1
  65. package/lib/module/i18n/pt-br.json +3 -1
  66. package/lib/module/i18n/ru.json +3 -1
  67. package/lib/module/i18n/tr.json +3 -1
  68. package/lib/module/version.json +1 -1
  69. package/lib/typescript/components/ChannelDetails/components/members/ChannelAddMembers.d.ts.map +1 -1
  70. package/lib/typescript/components/ChannelDetails/components/members/ChannelAllMembersModal.d.ts +1 -1
  71. package/lib/typescript/components/ChannelDetails/components/members/ChannelAllMembersModal.d.ts.map +1 -1
  72. package/lib/typescript/components/ChannelDetails/components/members/ChannelMemberList.d.ts +4 -2
  73. package/lib/typescript/components/ChannelDetails/components/members/ChannelMemberList.d.ts.map +1 -1
  74. package/lib/typescript/components/ChannelDetails/hooks/members/index.d.ts +0 -1
  75. package/lib/typescript/components/ChannelDetails/hooks/members/index.d.ts.map +1 -1
  76. package/lib/typescript/contexts/channelMemberListContext/ChannelMemberListContext.d.ts +21 -0
  77. package/lib/typescript/contexts/channelMemberListContext/ChannelMemberListContext.d.ts.map +1 -0
  78. package/lib/typescript/contexts/componentsContext/defaultComponents.d.ts +1 -1
  79. package/lib/typescript/contexts/index.d.ts +1 -0
  80. package/lib/typescript/contexts/index.d.ts.map +1 -1
  81. package/lib/typescript/contexts/themeContext/ThemeContext.d.ts +8 -0
  82. package/lib/typescript/contexts/themeContext/ThemeContext.d.ts.map +1 -1
  83. package/lib/typescript/contexts/themeContext/utils/theme.d.ts +8 -0
  84. package/lib/typescript/contexts/themeContext/utils/theme.d.ts.map +1 -1
  85. package/lib/typescript/i18n/ar.json +3 -1
  86. package/lib/typescript/i18n/en.json +2 -0
  87. package/lib/typescript/i18n/es.json +3 -1
  88. package/lib/typescript/i18n/fr.json +3 -1
  89. package/lib/typescript/i18n/he.json +3 -1
  90. package/lib/typescript/i18n/hi.json +3 -1
  91. package/lib/typescript/i18n/it.json +3 -1
  92. package/lib/typescript/i18n/ja.json +3 -1
  93. package/lib/typescript/i18n/ko.json +3 -1
  94. package/lib/typescript/i18n/nl.json +3 -1
  95. package/lib/typescript/i18n/pt-br.json +3 -1
  96. package/lib/typescript/i18n/ru.json +3 -1
  97. package/lib/typescript/i18n/tr.json +3 -1
  98. package/lib/typescript/utils/i18n/Streami18n.d.ts +2 -0
  99. package/lib/typescript/utils/i18n/Streami18n.d.ts.map +1 -1
  100. package/package.json +1 -1
  101. package/src/components/ChannelDetails/__tests__/members/ChannelMemberList.test.tsx +265 -151
  102. package/src/components/ChannelDetails/components/members/ChannelAddMembers.tsx +10 -4
  103. package/src/components/ChannelDetails/components/members/ChannelAllMembersModal.tsx +4 -25
  104. package/src/components/ChannelDetails/components/members/ChannelMemberList.tsx +137 -23
  105. package/src/components/ChannelDetails/components/navigation-section/PinnedMessageItem.tsx +1 -1
  106. package/src/components/ChannelDetails/components/navigation-section/PinnedMessageList.tsx +1 -1
  107. package/src/components/ChannelDetails/hooks/members/index.ts +0 -1
  108. package/src/components/UIComponents/SearchInput.tsx +1 -3
  109. package/src/contexts/channelMemberListContext/ChannelMemberListContext.tsx +72 -0
  110. package/src/contexts/index.ts +1 -0
  111. package/src/contexts/themeContext/utils/theme.ts +16 -0
  112. package/src/i18n/ar.json +3 -1
  113. package/src/i18n/en.json +2 -0
  114. package/src/i18n/es.json +3 -1
  115. package/src/i18n/fr.json +3 -1
  116. package/src/i18n/he.json +3 -1
  117. package/src/i18n/hi.json +3 -1
  118. package/src/i18n/it.json +3 -1
  119. package/src/i18n/ja.json +3 -1
  120. package/src/i18n/ko.json +3 -1
  121. package/src/i18n/nl.json +3 -1
  122. package/src/i18n/pt-br.json +3 -1
  123. package/src/i18n/ru.json +3 -1
  124. package/src/i18n/tr.json +3 -1
  125. package/src/version.json +1 -1
  126. package/lib/commonjs/components/ChannelDetails/hooks/members/useChannelAllMembers.js +0 -139
  127. package/lib/commonjs/components/ChannelDetails/hooks/members/useChannelAllMembers.js.map +0 -1
  128. package/lib/module/components/ChannelDetails/hooks/members/useChannelAllMembers.js +0 -139
  129. package/lib/module/components/ChannelDetails/hooks/members/useChannelAllMembers.js.map +0 -1
  130. package/lib/typescript/components/ChannelDetails/hooks/members/useChannelAllMembers.d.ts +0 -14
  131. package/lib/typescript/components/ChannelDetails/hooks/members/useChannelAllMembers.d.ts.map +0 -1
  132. package/src/components/ChannelDetails/__tests__/members/useChannelAllMembers.test.tsx +0 -234
  133. package/src/components/ChannelDetails/hooks/members/useChannelAllMembers.ts +0 -131
@@ -1,16 +1,37 @@
1
- import React, { useCallback, useMemo, useState } from 'react';
2
- import { ActivityIndicator, FlatList, type FlatListProps } from 'react-native';
1
+ import React, { useCallback, useEffect, useRef, useState } from 'react';
2
+ import { ActivityIndicator, FlatList, type FlatListProps, StyleSheet, View } from 'react-native';
3
3
 
4
- import type { ChannelMemberResponse } from 'stream-chat';
4
+ import type { ChannelMemberResponse, SearchSourceState } from 'stream-chat';
5
5
 
6
6
  import { MemberListLoadingSkeleton } from './MemberListLoadingSkeleton';
7
7
 
8
8
  import { useChannelDetailsContext } from '../../../../contexts/channelDetailsContext/channelDetailsContext';
9
+ import {
10
+ ChannelMemberListProvider,
11
+ useChannelMemberListContext,
12
+ } from '../../../../contexts/channelMemberListContext/ChannelMemberListContext';
9
13
  import { useComponentsContext } from '../../../../contexts/componentsContext/ComponentsContext';
10
- import { useChannelAllMembers } from '../../hooks/members/useChannelAllMembers';
14
+ import { useTheme } from '../../../../contexts/themeContext/ThemeContext';
15
+ import { useTranslationContext } from '../../../../contexts/translationContext/TranslationContext';
16
+ import { getNotificationErrorOptions } from '../../../../hooks/actions/useChannelActions';
17
+ import { useStateStore } from '../../../../hooks/useStateStore';
18
+ import { primitives } from '../../../../theme';
19
+ import { useNotificationApi } from '../../../Notifications/hooks/useNotificationApi';
20
+ import { NotificationList } from '../../../Notifications/NotificationList';
21
+ import { NotificationTargetProvider } from '../../../Notifications/NotificationTargetContext';
22
+ import { EmptySearchResult } from '../../../UIComponents/EmptySearchResult';
23
+ import { SearchInput, SearchInputProps } from '../../../UIComponents/SearchInput';
11
24
 
12
25
  const keyExtractor = (member: ChannelMemberResponse) => member.user?.id ?? member.user_id ?? '';
13
26
 
27
+ const listStateSelector = (state: SearchSourceState<ChannelMemberResponse>) => ({
28
+ error: state.lastQueryError,
29
+ hasNext: state.hasNext,
30
+ loading: state.isLoading,
31
+ members: state.items,
32
+ searchQuery: state.searchQuery,
33
+ });
34
+
14
35
  export type ChannelMemberListProps = {
15
36
  /**
16
37
  * Besides the existing default behavior of the members list, you can attach
@@ -19,18 +40,54 @@ export type ChannelMemberListProps = {
19
40
  * See https://reactnative.dev/docs/flatlist#props for the full list.
20
41
  */
21
42
  additionalFlatListProps?: Partial<FlatListProps<ChannelMemberResponse>>;
43
+ searchInputProps?: SearchInputProps;
22
44
  };
23
45
 
24
- /**
25
- * Lists all channel members.
26
- * @experimental This component is experimental and is subject to change.
27
- */
28
- export const ChannelMemberList = ({ additionalFlatListProps }: ChannelMemberListProps = {}) => {
29
- const { channel, onMemberPress } = useChannelDetailsContext();
46
+ const ChannelMemberListContent = ({
47
+ additionalFlatListProps,
48
+ searchInputProps,
49
+ }: ChannelMemberListProps) => {
50
+ const { t } = useTranslationContext();
51
+ const {
52
+ theme: {
53
+ channelDetails: { memberList },
54
+ },
55
+ } = useTheme();
56
+ const { onMemberPress } = useChannelDetailsContext();
30
57
  const { ChannelMemberActionsSheet, ChannelMemberItem } = useComponentsContext();
31
- const { hasMore, loading, loadMore, results } = useChannelAllMembers({ channel });
58
+ const { addNotification } = useNotificationApi();
59
+
60
+ const { channel, searchSource } = useChannelMemberListContext();
61
+ const { error, hasNext, loading, members, searchQuery } = useStateStore(
62
+ searchSource.state,
63
+ listStateSelector,
64
+ );
65
+
32
66
  const [selectedMember, setSelectedMember] = useState<ChannelMemberResponse | null>(null);
33
67
 
68
+ const initialized = useRef(false);
69
+ useEffect(() => {
70
+ if (!initialized.current) {
71
+ initialized.current = true;
72
+ searchSource.search();
73
+ }
74
+ }, [searchSource]);
75
+
76
+ useEffect(() => {
77
+ if (!error) {
78
+ return;
79
+ }
80
+ addNotification({
81
+ message: t('Failed to load members'),
82
+ options: {
83
+ ...getNotificationErrorOptions(error),
84
+ severity: 'error',
85
+ type: 'api:channel:query-members:failed',
86
+ },
87
+ origin: { context: { channel }, emitter: 'ChannelMemberList' },
88
+ });
89
+ }, [error, addNotification, channel, t]);
90
+
34
91
  const handleMemberActionsClose = useCallback(() => setSelectedMember(null), []);
35
92
 
36
93
  const handleMemberPress = useCallback(
@@ -51,24 +108,46 @@ export const ChannelMemberList = ({ additionalFlatListProps }: ChannelMemberList
51
108
  [ChannelMemberItem, handleMemberPress],
52
109
  );
53
110
 
54
- const ListFooterComponent = useMemo(
55
- () => (loading && results.length > 0 ? <ActivityIndicator /> : null),
56
- [loading, results.length],
57
- );
111
+ const loadMore = useCallback(() => {
112
+ // hasNext is true by default, !!members prevents calling search on initial load
113
+ if (hasNext && !!members) {
114
+ searchSource.search();
115
+ }
116
+ }, [hasNext, members, searchSource]);
58
117
 
59
- if (loading && results.length === 0) {
60
- return <MemberListLoadingSkeleton />;
61
- }
118
+ const emptyState =
119
+ loading && !members ? (
120
+ <MemberListLoadingSkeleton />
121
+ ) : (
122
+ <EmptySearchResult label={t('No members found')} />
123
+ );
62
124
 
63
125
  return (
64
- <>
126
+ <View style={[styles.container, memberList.container]}>
127
+ <SearchInput
128
+ accessibilityLabel={t('a11y/Search members')}
129
+ onChangeText={(text) => {
130
+ searchSource.state.partialNext({ searchQuery: text });
131
+ searchSource.search(text);
132
+ }}
133
+ value={searchQuery}
134
+ {...searchInputProps}
135
+ />
65
136
  <FlatList
66
- data={results}
137
+ contentContainerStyle={[styles.listContent, memberList.listContent]}
138
+ data={members}
139
+ keyboardDismissMode='interactive'
140
+ keyboardShouldPersistTaps='handled'
67
141
  keyExtractor={keyExtractor}
68
- ListFooterComponent={ListFooterComponent}
69
- onEndReached={hasMore ? loadMore : undefined}
142
+ ListEmptyComponent={emptyState}
143
+ ListFooterComponent={
144
+ loading && members && members.length > 0 ? <ActivityIndicator /> : null
145
+ }
146
+ onEndReached={loadMore}
70
147
  onEndReachedThreshold={0.2}
71
148
  renderItem={renderItem}
149
+ style={[styles.list, memberList.list]}
150
+ testID='channel-member-list'
72
151
  {...additionalFlatListProps}
73
152
  />
74
153
  {selectedMember ? (
@@ -78,6 +157,41 @@ export const ChannelMemberList = ({ additionalFlatListProps }: ChannelMemberList
78
157
  visible
79
158
  />
80
159
  ) : null}
81
- </>
160
+ <NotificationList />
161
+ </View>
162
+ );
163
+ };
164
+
165
+ /**
166
+ * Lists all channel members with the ability to search them.
167
+ * @experimental This component is experimental and is subject to change.
168
+ */
169
+ export const ChannelMemberList = (props: ChannelMemberListProps = {}) => {
170
+ const { channel } = useChannelDetailsContext();
171
+ const notificationHostId = channel?.cid ? `channel-member-list:${channel.cid}` : undefined;
172
+
173
+ if (!notificationHostId) {
174
+ return null;
175
+ }
176
+
177
+ return (
178
+ <ChannelMemberListProvider channel={channel}>
179
+ <NotificationTargetProvider hostId={notificationHostId} panel='channel-details'>
180
+ <ChannelMemberListContent {...props} />
181
+ </NotificationTargetProvider>
182
+ </ChannelMemberListProvider>
82
183
  );
83
184
  };
185
+
186
+ const styles = StyleSheet.create({
187
+ container: {
188
+ flex: 1,
189
+ },
190
+ list: {
191
+ flex: 1,
192
+ },
193
+ listContent: {
194
+ flexGrow: 1,
195
+ paddingBottom: primitives.spacing3xl,
196
+ },
197
+ });
@@ -69,7 +69,7 @@ const useStyles = () => {
69
69
  alignItems: 'center',
70
70
  flexDirection: 'row',
71
71
  gap: primitives.spacingSm,
72
- paddingHorizontal: primitives.spacingSm,
72
+ paddingHorizontal: primitives.spacingMd,
73
73
  paddingVertical: primitives.spacingMd,
74
74
  },
75
75
  content: {
@@ -190,7 +190,7 @@ const useStyles = () => {
190
190
  },
191
191
  listContent: {
192
192
  flexGrow: 1,
193
- paddingBottom: primitives.spacingXl,
193
+ paddingBottom: primitives.spacing3xl,
194
194
  },
195
195
  }),
196
196
  [],
@@ -1,2 +1 @@
1
- export * from './useChannelAllMembers';
2
1
  export * from './useMemberRoleLabel';
@@ -83,9 +83,7 @@ SearchInput.displayName = 'SearchInput{searchInput}';
83
83
 
84
84
  const styles = StyleSheet.create({
85
85
  container: {
86
- paddingBottom: primitives.spacingSm,
87
- paddingHorizontal: primitives.spacingMd,
88
- paddingTop: primitives.spacingXs,
86
+ padding: primitives.spacingMd,
89
87
  },
90
88
  input: {
91
89
  borderRadius: primitives.radiusMax,
@@ -0,0 +1,72 @@
1
+ import React, { PropsWithChildren, useContext, useState } from 'react';
2
+
3
+ import { Channel, ChannelMemberSearchSource } from 'stream-chat';
4
+
5
+ import { DEFAULT_BASE_CONTEXT_VALUE } from '../utils/defaultBaseContextValue';
6
+ import { isTestEnvironment } from '../utils/isTestEnvironment';
7
+
8
+ /**
9
+ * @experimental This API is experimental and is subject to change.
10
+ */
11
+ export type ChannelMemberListContextValue = {
12
+ channel: Channel;
13
+ searchSource: ChannelMemberSearchSource;
14
+ };
15
+
16
+ export const ChannelMemberListContext = React.createContext(
17
+ DEFAULT_BASE_CONTEXT_VALUE as ChannelMemberListContextValue,
18
+ );
19
+
20
+ /**
21
+ * @experimental This API is experimental and is subject to change.
22
+ */
23
+ export const ChannelMemberListProvider = ({
24
+ channel,
25
+ children,
26
+ }: PropsWithChildren<{ channel: Channel }>) => {
27
+ const [searchSource] = useState(() => {
28
+ const source = new ChannelMemberSearchSource(
29
+ channel,
30
+ {
31
+ allowEmptySearchString: true,
32
+ pageSize: 25,
33
+ resetOnNewSearchQuery: false,
34
+ },
35
+ {
36
+ initialFilterConfig: {
37
+ $or: {
38
+ enabled: true,
39
+ generate: ({ searchQuery }) =>
40
+ searchQuery ? { name: { $autocomplete: searchQuery } } : {},
41
+ },
42
+ },
43
+ },
44
+ );
45
+ source.sort = { name: 1 };
46
+ source.activate();
47
+ return source;
48
+ });
49
+
50
+ return (
51
+ <ChannelMemberListContext.Provider value={{ channel, searchSource }}>
52
+ {children}
53
+ </ChannelMemberListContext.Provider>
54
+ );
55
+ };
56
+
57
+ /**
58
+ * @experimental This API is experimental and is subject to change.
59
+ */
60
+ export const useChannelMemberListContext = () => {
61
+ const contextValue = useContext(
62
+ ChannelMemberListContext,
63
+ ) as unknown as ChannelMemberListContextValue;
64
+
65
+ if (contextValue === DEFAULT_BASE_CONTEXT_VALUE && !isTestEnvironment()) {
66
+ throw new Error(
67
+ 'The useChannelMemberListContext hook was called outside of the ChannelMemberListContext provider. Render the member list UI inside a ChannelMemberListProvider.',
68
+ );
69
+ }
70
+
71
+ return contextValue;
72
+ };
@@ -34,6 +34,7 @@ export * from './channelAddMembersContext/ChannelAddMembersContext';
34
34
  export * from './channelEditDetailsContext';
35
35
  export * from './channelFileAttachmentListContext/ChannelFileAttachmentListContext';
36
36
  export * from './channelPinnedMessageListContext/ChannelPinnedMessageListContext';
37
+ export * from './channelMemberListContext/ChannelMemberListContext';
37
38
  export * from './channelMediaListContext/ChannelMediaListContext';
38
39
  export * from './pollContext';
39
40
  export * from './liveLocationManagerContext';
@@ -219,6 +219,11 @@ export type Theme = {
219
219
  role: TextStyle;
220
220
  status: TextStyle;
221
221
  };
222
+ memberList: {
223
+ container: ViewStyle;
224
+ list: ViewStyle;
225
+ listContent: ViewStyle;
226
+ };
222
227
  memberActionsSheet: {
223
228
  actionsList: ViewStyle;
224
229
  container: ViewStyle;
@@ -236,6 +241,9 @@ export type Theme = {
236
241
  headerTitle: TextStyle;
237
242
  };
238
243
  addMembers: {
244
+ container: ViewStyle;
245
+ list: ViewStyle;
246
+ listContent: ViewStyle;
239
247
  searchResultItem: {
240
248
  alreadyMemberInfo: ViewStyle;
241
249
  memberLabel: TextStyle;
@@ -1326,6 +1334,11 @@ export const defaultTheme: Theme = {
1326
1334
  role: {},
1327
1335
  status: {},
1328
1336
  },
1337
+ memberList: {
1338
+ container: {},
1339
+ list: {},
1340
+ listContent: {},
1341
+ },
1329
1342
  memberActionsSheet: {
1330
1343
  actionsList: {},
1331
1344
  container: {},
@@ -1343,6 +1356,9 @@ export const defaultTheme: Theme = {
1343
1356
  headerTitle: {},
1344
1357
  },
1345
1358
  addMembers: {
1359
+ container: {},
1360
+ list: {},
1361
+ listContent: {},
1346
1362
  searchResultItem: {
1347
1363
  alreadyMemberInfo: {},
1348
1364
  memberLabel: {},
package/src/i18n/ar.json CHANGED
@@ -463,5 +463,7 @@
463
463
  "They won't be able to message or call you. You can unblock them later.": "لن يتمكن/تتمكن من مراسلتك أو الاتصال بك. يمكنك إلغاء الحظر لاحقًا.",
464
464
  "Leave": "مغادرة",
465
465
  "You'll stop receiving messages from {{ name }}. You can rejoin anytime.": "ستتوقف عن تلقي الرسائل من {{ name }}. يمكنك الانضمام مجددًا في أي وقت.",
466
- "group": "المجموعة"
466
+ "group": "المجموعة",
467
+ "No members found": "لم يتم العثور على أعضاء",
468
+ "a11y/Search members": "البحث عن الأعضاء"
467
469
  }
package/src/i18n/en.json CHANGED
@@ -99,6 +99,7 @@
99
99
  "No chats here yet…": "No chats here yet…",
100
100
  "No files": "No files",
101
101
  "No items exist": "No items exist",
102
+ "No members found": "No members found",
102
103
  "No photos or videos": "No photos or videos",
103
104
  "No pinned messages": "No pinned messages",
104
105
  "No threads here yet": "No threads here yet",
@@ -356,6 +357,7 @@
356
357
  "a11y/Select image": "Select image",
357
358
  "a11y/Select video": "Select video",
358
359
  "a11y/Send voice recording": "Send voice recording",
360
+ "a11y/Search members": "Search members",
359
361
  "a11y/Search pinned messages": "Search pinned messages",
360
362
  "a11y/Search users to add": "Search users to add",
361
363
  "a11y/Select {{name}}": "Select {{name}}",
package/src/i18n/es.json CHANGED
@@ -463,5 +463,7 @@
463
463
  "They won't be able to message or call you. You can unblock them later.": "No podrá enviarte mensajes ni llamarte. Puedes desbloquearlo más tarde.",
464
464
  "Leave": "Salir",
465
465
  "You'll stop receiving messages from {{ name }}. You can rejoin anytime.": "Dejarás de recibir mensajes de {{ name }}. Puedes volver a unirte cuando quieras.",
466
- "group": "el grupo"
466
+ "group": "el grupo",
467
+ "No members found": "No se encontraron miembros",
468
+ "a11y/Search members": "Buscar miembros"
467
469
  }
package/src/i18n/fr.json CHANGED
@@ -463,5 +463,7 @@
463
463
  "They won't be able to message or call you. You can unblock them later.": "Cette personne ne pourra plus vous envoyer de messages ni vous appeler. Vous pourrez la débloquer plus tard.",
464
464
  "Leave": "Quitter",
465
465
  "You'll stop receiving messages from {{ name }}. You can rejoin anytime.": "Vous ne recevrez plus de messages de {{ name }}. Vous pouvez rejoindre à tout moment.",
466
- "group": "ce groupe"
466
+ "group": "ce groupe",
467
+ "No members found": "Aucun membre trouvé",
468
+ "a11y/Search members": "Rechercher des membres"
467
469
  }
package/src/i18n/he.json CHANGED
@@ -463,5 +463,7 @@
463
463
  "They won't be able to message or call you. You can unblock them later.": "הוא/היא לא יוכל/תוכל לשלוח לך הודעות או להתקשר אליך. ניתן לבטל את החסימה מאוחר יותר.",
464
464
  "Leave": "צא/י",
465
465
  "You'll stop receiving messages from {{ name }}. You can rejoin anytime.": "תפסיק/תפסיקי לקבל הודעות מ-{{ name }}. ניתן להצטרף בחזרה בכל עת.",
466
- "group": "הקבוצה"
466
+ "group": "הקבוצה",
467
+ "No members found": "לא נמצאו חברים",
468
+ "a11y/Search members": "חיפוש חברים"
467
469
  }
package/src/i18n/hi.json CHANGED
@@ -463,5 +463,7 @@
463
463
  "They won't be able to message or call you. You can unblock them later.": "वे आपको संदेश या कॉल नहीं कर पाएंगे। आप उन्हें बाद में अनब्लॉक कर सकते हैं।",
464
464
  "Leave": "छोड़ें",
465
465
  "You'll stop receiving messages from {{ name }}. You can rejoin anytime.": "आपको {{ name }} से संदेश मिलना बंद हो जाएंगे। आप कभी भी दोबारा जुड़ सकते हैं।",
466
- "group": "ग्रुप"
466
+ "group": "ग्रुप",
467
+ "No members found": "कोई सदस्य नहीं मिला",
468
+ "a11y/Search members": "सदस्य खोजें"
467
469
  }
package/src/i18n/it.json CHANGED
@@ -463,5 +463,7 @@
463
463
  "They won't be able to message or call you. You can unblock them later.": "Non potrà inviarti messaggi né chiamarti. Potrai sbloccarlo in seguito.",
464
464
  "Leave": "Esci",
465
465
  "You'll stop receiving messages from {{ name }}. You can rejoin anytime.": "Non riceverai più messaggi da {{ name }}. Puoi rientrare in qualsiasi momento.",
466
- "group": "il gruppo"
466
+ "group": "il gruppo",
467
+ "No members found": "Nessun membro trovato",
468
+ "a11y/Search members": "Cerca membri"
467
469
  }
package/src/i18n/ja.json CHANGED
@@ -463,5 +463,7 @@
463
463
  "They won't be able to message or call you. You can unblock them later.": "メッセージや通話ができなくなります。あとでブロックを解除することもできます。",
464
464
  "Leave": "退出",
465
465
  "You'll stop receiving messages from {{ name }}. You can rejoin anytime.": "{{ name }} からのメッセージが届かなくなります。いつでも再参加できます。",
466
- "group": "グループ"
466
+ "group": "グループ",
467
+ "No members found": "メンバーが見つかりません",
468
+ "a11y/Search members": "メンバーを検索"
467
469
  }
package/src/i18n/ko.json CHANGED
@@ -463,5 +463,7 @@
463
463
  "They won't be able to message or call you. You can unblock them later.": "메시지를 보내거나 전화를 걸 수 없게 됩니다. 나중에 차단을 해제할 수 있습니다.",
464
464
  "Leave": "나가기",
465
465
  "You'll stop receiving messages from {{ name }}. You can rejoin anytime.": "{{ name }}에서 더 이상 메시지를 받지 않게 됩니다. 언제든지 다시 참여할 수 있습니다.",
466
- "group": "그룹"
466
+ "group": "그룹",
467
+ "No members found": "멤버를 찾을 수 없습니다",
468
+ "a11y/Search members": "멤버 검색"
467
469
  }
package/src/i18n/nl.json CHANGED
@@ -463,5 +463,7 @@
463
463
  "They won't be able to message or call you. You can unblock them later.": "Deze persoon kan je geen berichten sturen of bellen. Je kunt de blokkering later opheffen.",
464
464
  "Leave": "Verlaten",
465
465
  "You'll stop receiving messages from {{ name }}. You can rejoin anytime.": "Je ontvangt geen berichten meer van {{ name }}. Je kunt op elk moment opnieuw deelnemen.",
466
- "group": "de groep"
466
+ "group": "de groep",
467
+ "No members found": "Geen leden gevonden",
468
+ "a11y/Search members": "Zoek leden"
467
469
  }
@@ -463,5 +463,7 @@
463
463
  "They won't be able to message or call you. You can unblock them later.": "Essa pessoa não poderá enviar mensagens ou ligar para você. Você pode desbloqueá-la mais tarde.",
464
464
  "Leave": "Sair",
465
465
  "You'll stop receiving messages from {{ name }}. You can rejoin anytime.": "Você deixará de receber mensagens de {{ name }}. Pode entrar novamente a qualquer momento.",
466
- "group": "o grupo"
466
+ "group": "o grupo",
467
+ "No members found": "Nenhum membro encontrado",
468
+ "a11y/Search members": "Pesquisar membros"
467
469
  }
package/src/i18n/ru.json CHANGED
@@ -463,5 +463,7 @@
463
463
  "They won't be able to message or call you. You can unblock them later.": "Он не сможет писать вам и звонить. Вы сможете снять блокировку позже.",
464
464
  "Leave": "Покинуть",
465
465
  "You'll stop receiving messages from {{ name }}. You can rejoin anytime.": "Вы перестанете получать сообщения от {{ name }}. Вы можете присоединиться снова в любое время.",
466
- "group": "группы"
466
+ "group": "группы",
467
+ "No members found": "Участники не найдены",
468
+ "a11y/Search members": "Поиск участников"
467
469
  }
package/src/i18n/tr.json CHANGED
@@ -463,5 +463,7 @@
463
463
  "They won't be able to message or call you. You can unblock them later.": "Size mesaj gönderemez veya sizi arayamaz. Engeli daha sonra kaldırabilirsiniz.",
464
464
  "Leave": "Ayrıl",
465
465
  "You'll stop receiving messages from {{ name }}. You can rejoin anytime.": "{{ name }} kanalından mesaj almayı bırakacaksınız. İstediğiniz zaman tekrar katılabilirsiniz.",
466
- "group": "grup"
466
+ "group": "grup",
467
+ "No members found": "Üye bulunamadı",
468
+ "a11y/Search members": "Üye ara"
467
469
  }
package/src/version.json CHANGED
@@ -1,3 +1,3 @@
1
1
  {
2
- "version": "9.4.1-beta.1"
2
+ "version": "9.5.0-beta.1"
3
3
  }
@@ -1,139 +0,0 @@
1
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
2
- Object.defineProperty(exports, "__esModule", {
3
- value: true
4
- });
5
- exports.useChannelAllMembers = void 0;
6
- var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
7
- var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
8
- var _react = require("react");
9
- var _contexts = require("../../../../contexts");
10
- var _useChannelActions = require("../../../../hooks/actions/useChannelActions");
11
- var _useChannelMembersState = require("../../../ChannelList/hooks/useChannelMembersState");
12
- var _useNotificationApi2 = require("../../../Notifications/hooks/useNotificationApi");
13
- var PAGE_SIZE = 25;
14
- var noop = () => undefined;
15
- var useChannelAllMembers = ({
16
- channel
17
- }) => {
18
- var _useNotificationApi = (0, _useNotificationApi2.useNotificationApi)(),
19
- addNotification = _useNotificationApi.addNotification;
20
- var _useTranslationContex = (0, _contexts.useTranslationContext)(),
21
- t = _useTranslationContex.t;
22
- var localMembers = (0, _useChannelMembersState.useChannelMembersState)(channel);
23
- var _useState = (0, _react.useState)(() => {
24
- var memberCount = channel.data?.member_count;
25
- var loadedCount = Object.keys(channel.state.members).length;
26
- return memberCount == null || loadedCount >= memberCount ? 'local' : 'paginated';
27
- }),
28
- _useState2 = (0, _slicedToArray2.default)(_useState, 1),
29
- mode = _useState2[0];
30
- var _useState3 = (0, _react.useState)([]),
31
- _useState4 = (0, _slicedToArray2.default)(_useState3, 2),
32
- results = _useState4[0],
33
- setResults = _useState4[1];
34
- var _useState5 = (0, _react.useState)(mode === 'paginated'),
35
- _useState6 = (0, _slicedToArray2.default)(_useState5, 2),
36
- loading = _useState6[0],
37
- setLoading = _useState6[1];
38
- var _useState7 = (0, _react.useState)(mode === 'paginated'),
39
- _useState8 = (0, _slicedToArray2.default)(_useState7, 2),
40
- hasMore = _useState8[0],
41
- setHasMore = _useState8[1];
42
- var offsetRef = (0, _react.useRef)(0);
43
- var requestIdRef = (0, _react.useRef)(0);
44
- var inFlightRef = (0, _react.useRef)(false);
45
- var fetchPage = (0, _react.useCallback)(function () {
46
- var _ref = (0, _asyncToGenerator2.default)(function* ({
47
- append
48
- }) {
49
- var requestId = ++requestIdRef.current;
50
- inFlightRef.current = true;
51
- setLoading(true);
52
- if (!append) {
53
- offsetRef.current = 0;
54
- setHasMore(true);
55
- }
56
- try {
57
- var filter = {};
58
- var sort = {
59
- created_at: 1
60
- };
61
- var response = yield channel.queryMembers(filter, sort, {
62
- limit: PAGE_SIZE,
63
- offset: offsetRef.current
64
- });
65
- if (requestId !== requestIdRef.current) return;
66
- var fetched = response.members ?? [];
67
- setResults(prev => {
68
- if (!append) return fetched;
69
- var seen = new Set(prev.map(m => m.user_id ?? m.user?.id));
70
- var deduped = fetched.filter(m => !seen.has(m.user_id ?? m.user?.id));
71
- return deduped.length ? [...prev, ...deduped] : prev;
72
- });
73
- offsetRef.current += fetched.length;
74
- if (fetched.length < PAGE_SIZE) {
75
- setHasMore(false);
76
- }
77
- } catch (err) {
78
- if (requestId !== requestIdRef.current) return;
79
- addNotification({
80
- message: t('Failed to load members'),
81
- options: {
82
- ...(0, _useChannelActions.getNotificationErrorOptions)(err),
83
- severity: 'error',
84
- type: 'api:channel:query-members:failed'
85
- },
86
- origin: {
87
- context: {
88
- channel
89
- },
90
- emitter: 'ChannelAllMembers'
91
- }
92
- });
93
- } finally {
94
- if (requestId === requestIdRef.current) {
95
- inFlightRef.current = false;
96
- setLoading(false);
97
- }
98
- }
99
- });
100
- return function (_x) {
101
- return _ref.apply(this, arguments);
102
- };
103
- }(), [addNotification, channel, t]);
104
- var fetchPageRef = (0, _react.useRef)(fetchPage);
105
- fetchPageRef.current = fetchPage;
106
- (0, _react.useEffect)(() => {
107
- if (mode !== 'paginated') return;
108
- fetchPageRef.current({
109
- append: false
110
- });
111
- return () => {
112
- requestIdRef.current += 1;
113
- };
114
- }, [mode]);
115
- var loadMore = (0, _react.useCallback)(() => {
116
- if (mode !== 'paginated') return;
117
- if (inFlightRef.current || !hasMore || loading) return;
118
- fetchPageRef.current({
119
- append: true
120
- });
121
- }, [mode, hasMore, loading]);
122
- var localResults = (0, _react.useMemo)(() => Object.values(localMembers), [localMembers]);
123
- if (mode === 'local') {
124
- return {
125
- hasMore: false,
126
- loading: false,
127
- loadMore: noop,
128
- results: localResults
129
- };
130
- }
131
- return {
132
- hasMore,
133
- loading,
134
- loadMore,
135
- results
136
- };
137
- };
138
- exports.useChannelAllMembers = useChannelAllMembers;
139
- //# sourceMappingURL=useChannelAllMembers.js.map