stream-chat-react-native-core 3.9.0-next.4 → 3.9.0-next.8

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 (29) hide show
  1. package/README.md +0 -12
  2. package/lib/commonjs/components/Attachment/Gallery.js +25 -18
  3. package/lib/commonjs/components/Attachment/Gallery.js.map +1 -1
  4. package/lib/commonjs/components/Channel/Channel.js +24 -15
  5. package/lib/commonjs/components/Channel/Channel.js.map +1 -1
  6. package/lib/commonjs/components/ChannelList/hooks/usePaginatedChannels.js +14 -20
  7. package/lib/commonjs/components/ChannelList/hooks/usePaginatedChannels.js.map +1 -1
  8. package/lib/commonjs/utils/utils.js +23 -11
  9. package/lib/commonjs/utils/utils.js.map +1 -1
  10. package/lib/commonjs/version.json +1 -1
  11. package/lib/module/components/Attachment/Gallery.js +25 -18
  12. package/lib/module/components/Attachment/Gallery.js.map +1 -1
  13. package/lib/module/components/Channel/Channel.js +24 -15
  14. package/lib/module/components/Channel/Channel.js.map +1 -1
  15. package/lib/module/components/ChannelList/hooks/usePaginatedChannels.js +14 -20
  16. package/lib/module/components/ChannelList/hooks/usePaginatedChannels.js.map +1 -1
  17. package/lib/module/utils/utils.js +23 -11
  18. package/lib/module/utils/utils.js.map +1 -1
  19. package/lib/module/version.json +1 -1
  20. package/lib/typescript/components/Attachment/Gallery.d.ts +16 -1
  21. package/lib/typescript/components/Channel/Channel.d.ts +2 -2
  22. package/lib/typescript/utils/utils.d.ts +4 -1
  23. package/package.json +1 -1
  24. package/src/components/Attachment/Gallery.tsx +31 -9
  25. package/src/components/Channel/Channel.tsx +19 -2
  26. package/src/components/ChannelList/hooks/usePaginatedChannels.ts +1 -3
  27. package/src/utils/__tests__/utils.test.js +19 -0
  28. package/src/utils/utils.ts +14 -1
  29. package/src/version.json +1 -1
@@ -26,8 +26,9 @@ import {
26
26
  useOverlayContext,
27
27
  } from '../../contexts/overlayContext/OverlayContext';
28
28
  import { useTheme } from '../../contexts/themeContext/ThemeContext';
29
- import { makeImageCompatibleUrl } from '../../utils/utils';
29
+ import { getUrlWithoutParams, makeImageCompatibleUrl } from '../../utils/utils';
30
30
 
31
+ import type { MessageType } from '../../components/MessageList/hooks/useMessageList';
31
32
  import type {
32
33
  DefaultAttachmentType,
33
34
  DefaultChannelType,
@@ -104,7 +105,6 @@ export type GalleryPropsWithContext<
104
105
  | 'alignment'
105
106
  | 'groupStyles'
106
107
  | 'images'
107
- | 'message'
108
108
  | 'onLongPress'
109
109
  | 'onPress'
110
110
  | 'onPressIn'
@@ -116,7 +116,21 @@ export type GalleryPropsWithContext<
116
116
  'additionalTouchableProps' | 'legacyImageViewerSwipeBehaviour'
117
117
  > &
118
118
  Pick<OverlayContextValue, 'setBlurType' | 'setOverlay'> & {
119
+ /**
120
+ * `message` prop has been introduced here as part of `legacyImageViewerSwipeBehaviour` prop.
121
+ * https://github.com/GetStream/stream-chat-react-native/commit/d5eac6193047916f140efe8e396a671675c9a63f
122
+ * messageId and messageText may seem redundant now, but to avoid breaking change as part
123
+ * of minor release, we are keeping those props.
124
+ *
125
+ * Also `message` type should ideally be imported from MessageContextValue and not be explicitely mentioned
126
+ * here, but due to some circular dependencies within the SDK, it causes "exccesive deep nesting" issue with
127
+ * typescript within Channel component. We should take it as a mini-project and resolve all these circular imports.
128
+ *
129
+ * TODO[major]: remove messageId and messageText
130
+ * TODO: Fix circular dependencies of imports
131
+ */
119
132
  hasThreadReplies?: boolean;
133
+ message?: MessageType<At, Ch, Co, Ev, Me, Re, Us>;
120
134
  messageId?: string;
121
135
  messageText?: string;
122
136
  };
@@ -141,7 +155,7 @@ const GalleryWithContext = <
141
155
  legacyImageViewerSwipeBehaviour,
142
156
  message,
143
157
  messageId,
144
- messageText,
158
+ messageText: messageTextProp,
145
159
  onLongPress,
146
160
  onPress,
147
161
  onPressIn,
@@ -199,6 +213,7 @@ const GalleryWithContext = <
199
213
  }, [] as { height: number | string; url: string }[][]);
200
214
 
201
215
  const groupStyle = `${alignment}_${groupStyles?.[0]?.toLowerCase?.()}`;
216
+ const messageText = messageTextProp || message?.text;
202
217
 
203
218
  return (
204
219
  <View
@@ -224,12 +239,19 @@ const GalleryWithContext = <
224
239
  >
225
240
  {column.map(({ height, url }, rowIndex) => {
226
241
  const defaultOnPress = () => {
227
- if (!legacyImageViewerSwipeBehaviour) {
242
+ // Added if-else to keep the logic readable, instead of DRY.
243
+ // if - legacyImageViewerSwipeBehaviour is disabled
244
+ // else - legacyImageViewerSwipeBehaviour is enabled
245
+ if (!legacyImageViewerSwipeBehaviour && message) {
228
246
  setImages([message]);
247
+ setImage({ messageId: messageId || message.id, url });
248
+ setBlurType(blurType);
249
+ setOverlay('gallery');
250
+ } else if (legacyImageViewerSwipeBehaviour) {
251
+ setImage({ messageId: messageId || message?.id, url });
252
+ setBlurType(blurType);
253
+ setOverlay('gallery');
229
254
  }
230
- setImage({ messageId, url });
231
- setBlurType(blurType);
232
- setOverlay('gallery');
233
255
  };
234
256
 
235
257
  return (
@@ -371,8 +393,8 @@ const areEqual = <
371
393
  prevImages.length === nextImages.length &&
372
394
  prevImages.every(
373
395
  (image, index) =>
374
- image.image_url === nextImages[index].image_url &&
375
- image.thumb_url === nextImages[index].thumb_url,
396
+ getUrlWithoutParams(image.image_url) === getUrlWithoutParams(nextImages[index].image_url) &&
397
+ getUrlWithoutParams(image.thumb_url) === getUrlWithoutParams(nextImages[index].thumb_url),
376
398
  );
377
399
  if (!imagesEqual) return false;
378
400
 
@@ -160,7 +160,7 @@ const scrollToFirstUnreadThreshold = 4;
160
160
  const defaultThrottleInterval = 500;
161
161
  const defaultDebounceInterval = 500;
162
162
  const throttleOptions = {
163
- leading: false,
163
+ leading: true,
164
164
  trailing: true,
165
165
  };
166
166
  const debounceOptions = {
@@ -252,6 +252,7 @@ export type ChannelPropsWithContext<
252
252
  | 'handleThreadReply'
253
253
  | 'InlineDateSeparator'
254
254
  | 'InlineUnreadIndicator'
255
+ | 'legacyImageViewerSwipeBehaviour'
255
256
  | 'markdownRules'
256
257
  | 'Message'
257
258
  | 'messageActions'
@@ -362,7 +363,6 @@ export type ChannelPropsWithContext<
362
363
  */
363
364
  KeyboardCompatibleView?: React.ComponentType<KeyboardAvoidingViewProps>;
364
365
  keyboardVerticalOffset?: number;
365
- legacyImageViewerSwipeBehaviour?: boolean;
366
366
  /**
367
367
  * Custom loading error indicator to override the Stream default
368
368
  */
@@ -370,6 +370,7 @@ export type ChannelPropsWithContext<
370
370
  maxMessageLength?: number;
371
371
  messageId?: string;
372
372
  mutesEnabled?: boolean;
373
+ newMessageStateUpdateThrottleInterval?: number;
373
374
  quotedRepliesEnabled?: boolean;
374
375
  reactionsEnabled?: boolean;
375
376
  readEventsEnabled?: boolean;
@@ -465,6 +466,7 @@ const ChannelWithContext = <
465
466
  keyboardBehavior,
466
467
  KeyboardCompatibleView = KeyboardCompatibleViewDefault,
467
468
  keyboardVerticalOffset,
469
+ // TODO[major]: switch to false.
468
470
  legacyImageViewerSwipeBehaviour = true,
469
471
  LoadingErrorIndicator = LoadingErrorIndicatorDefault,
470
472
  LoadingIndicator = LoadingIndicatorDefault,
@@ -497,6 +499,7 @@ const ChannelWithContext = <
497
499
  mutesEnabled: mutesEnabledProp,
498
500
  muteUser,
499
501
  myMessageTheme,
502
+ newMessageStateUpdateThrottleInterval = defaultThrottleInterval,
500
503
  NetworkDownIndicator = NetworkDownIndicatorDefault,
501
504
  numberOfLines = 5,
502
505
  onChangeText,
@@ -682,6 +685,18 @@ const ChannelWithContext = <
682
685
  ),
683
686
  ).current;
684
687
 
688
+ const copyMessagesState = useRef(
689
+ throttle(
690
+ () => {
691
+ if (channel) {
692
+ setMessages([...channel.state.messages]);
693
+ }
694
+ },
695
+ newMessageStateUpdateThrottleInterval,
696
+ throttleOptions,
697
+ ),
698
+ ).current;
699
+
685
700
  const copyTypingState = useRef(
686
701
  throttle(
687
702
  () => {
@@ -755,6 +770,8 @@ const ChannelWithContext = <
755
770
  copyTypingState();
756
771
  } else if (event.type === 'message.read') {
757
772
  copyReadState();
773
+ } else if (event.type === 'message.new') {
774
+ copyMessagesState();
758
775
  } else if (channel) {
759
776
  copyChannelState();
760
777
  }
@@ -57,7 +57,6 @@ export const usePaginatedChannels = <
57
57
  const lastRefresh = useRef(Date.now());
58
58
  const [loadingChannels, setLoadingChannels] = useState(false);
59
59
  const [loadingNextPage, setLoadingNextPage] = useState(false);
60
- const [offset, setOffset] = useState(0);
61
60
  const [refreshing, setRefreshing] = useState(false);
62
61
 
63
62
  const queryChannels = async (queryType = '', retryCount = 0): Promise<void> => {
@@ -73,7 +72,7 @@ export const usePaginatedChannels = <
73
72
 
74
73
  const newOptions = {
75
74
  limit: options?.limit ?? MAX_QUERY_CHANNELS_LIMIT,
76
- offset: queryType === 'reload' || queryType === 'refresh' ? 0 : offset,
75
+ offset: queryType === 'reload' || queryType === 'refresh' ? 0 : channels.length,
77
76
  ...options,
78
77
  };
79
78
 
@@ -89,7 +88,6 @@ export const usePaginatedChannels = <
89
88
 
90
89
  setChannels(newChannels);
91
90
  setHasNextPage(channelQueryResponse.length >= newOptions.limit);
92
- setOffset(newChannels.length);
93
91
  setError(false);
94
92
  } catch (err) {
95
93
  await wait(2000);
@@ -0,0 +1,19 @@
1
+ import { getUrlWithoutParams } from '../utils';
2
+
3
+ describe('getUrlWithoutParams', () => {
4
+ const testUrlMap = {
5
+ 'http://foo.com/blah_(wikipedia)#cite-1': 'http://foo.com/blah_(wikipedia)#cite-1',
6
+ 'https://us-east.stream-io-cdn.com/102401/images/418dc024-b587-48cd-84fb-252418e14391.FB_IMG_1633228094526.jpg?Key-Pair-Id=APKAIHG36VEWPDULE23Q&Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiaHR0cHM6Ly91cy1lYXN0LnN0cmVhbS1pby1jZG4uY29tLzEwMjQwMS9pbWFnZXMvNDE4ZGMwMjQtYjU4Ny00OGNkLTg0ZmItMjUyNDE4ZTE0MzkxLkZCX0lNR18xNjMzMjI4MDk0NTI2LmpwZz9jcm9wPSomaD0qJnJlc2l6ZT0qJnJvPTAmdz0qIiwiQ29uZGl0aW9uIjp7IkRhdGVMZXNzVGhhbiI6eyJBV1M6RXBvY2hUaW1lIjoxNjM1MTUwMDM5fX19XX0_&Signature=Yi8XTsAVYiEh2IDSkH4IK1zNEvPvgUkfYx9oJb2VrJMMVrBz2oPurbcFOHuQSk74RQTSE6LPZ-wplayHZxaSVeX4Q6IwwjE7vmnU~-UYPttxnClpRWFUKLJx79auz5sjkhwFte7uzby7oQSRRDRl3g3ritN~NRzU4cjZ0tnLFnn0AwnLDmfEk8VdjgGXm84PeqpAUujyDmSqm1TY7QJQBRnJMQ-MV7AA3Gj8ec9yxWunIOK8xn5FJTRvKAVqEcu~lnmEAMS5RXQ5oDCjp2~w7M7sNSyqgJVe7jRJ0kctRqJeOPlsDfQJB38JwLv6v-5piSt2kTYsPBXUu4EiALwVaQ__&crop=*&h=*&resize=*&ro=0&w=*':
7
+ 'https://us-east.stream-io-cdn.com/102401/images/418dc024-b587-48cd-84fb-252418e14391.FB_IMG_1633228094526.jpg',
8
+ 'https://us-east.stream-io-cdn.com/62344/images/69c62680-45ba-4c6c-af49-66f3acee39cf.C8B8DF8D-A326-44A6-8030-C2B1C61116A5.jpg?Key-Pair-Id=APKAIHG36VEWPDULE23Q&Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiaHR0cHM6Ly91cy1lYXN0LnN0cmVhbS1pby1jZG4uY29tLzYyMzQ0L2ltYWdlcy82OWM2MjY4MC00NWJhLTRjNmMtYWY0OS02NmYzYWNlZTM5Y2YuQzhCOERGOEQtQTMyNi00NEE2LTgwMzAtQzJCMUM2MTExNkE1LmpwZz9jcm9wPSomaD0qJnJlc2l6ZT0qJnJvPTAmdz0qIiwiQ29uZGl0aW9uIjp7IkRhdGVMZXNzVGhhbiI6eyJBV1M6RXBvY2hUaW1lIjoxNjE3OTU5MTk2fX19XX0_&Signature=b0DMJSOQmRO2AMemtlo-yhnUNuPtwC90QG5kn23Oaw13o8jlcFs93i2NgDarmJzanjHgOBsqv6dc-troCV2tTfUIz77CeAPjMXvPjmrUUgHUsBJrdr5DbjnhjfFIC9MTJxV9qkJNsD22M0qdR8MHzhHPNF~ZD76M-e~JZ7QuiUOG9Nw1YscXnYxn0x1RDjm8jKObPd0T3qTqPAADbfIYSxAxrInnUAj5CtYMyTVsV2zyxJpWfzm6gYs5lW0mvPUuCQ77AECTGiHCrfxdRI8LJFEmxrr1-KC8iCysAFPx-kPLYyQRosevtpnwoZDQqNPeYReiQG2SnW3I4TQWqjw-Pw__&crop=*&h=*&resize=*&ro=0&w=*':
9
+ 'https://us-east.stream-io-cdn.com/62344/images/69c62680-45ba-4c6c-af49-66f3acee39cf.C8B8DF8D-A326-44A6-8030-C2B1C61116A5.jpg',
10
+ };
11
+
12
+ it('should return a url without params', () => {
13
+ const urls = Object.keys(testUrlMap);
14
+
15
+ urls.forEach((url) => {
16
+ expect(getUrlWithoutParams(url)).toBe(testUrlMap[url]);
17
+ });
18
+ });
19
+ });
@@ -153,8 +153,12 @@ const queryMembers = async <
153
153
  channel: Channel<At, Ch, Co, Ev, Me, Re, Us>,
154
154
  query: SuggestionUser<Us>['name'],
155
155
  onReady?: (users: SuggestionUser<Us>[]) => void,
156
- limit = defaultAutoCompleteSuggestionsLimit,
156
+ options: {
157
+ limit?: number;
158
+ } = {},
157
159
  ): Promise<void> => {
160
+ const { limit = defaultAutoCompleteSuggestionsLimit } = options;
161
+
158
162
  if (typeof query === 'string') {
159
163
  const response = (await (channel as unknown as Channel).queryMembers(
160
164
  {
@@ -535,6 +539,15 @@ export const ACITriggerSettings = <
535
539
  export const makeImageCompatibleUrl = (url: string) =>
536
540
  (url.indexOf('//') === 0 ? `https:${url}` : url).trim();
537
541
 
542
+ export const getUrlWithoutParams = (url?: string) => {
543
+ if (!url) return url;
544
+
545
+ const indexOfQuestion = url.indexOf('?');
546
+ if (indexOfQuestion === -1) return url;
547
+
548
+ return url.substring(0, url.indexOf('?'));
549
+ };
550
+
538
551
  export const vw = (percentageWidth: number, rounded = false) => {
539
552
  const value = Dimensions.get('window').width * (percentageWidth / 100);
540
553
  return rounded ? Math.round(value) : value;
package/src/version.json CHANGED
@@ -1,3 +1,3 @@
1
1
  {
2
- "version": "3.9.0-next.4"
2
+ "version": "3.9.0-next.8"
3
3
  }