stream-chat-react-native-core 5.28.0-beta.3 → 5.28.0-beta.5

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 (132) hide show
  1. package/lib/commonjs/components/AttachmentPicker/AttachmentPicker.js +10 -43
  2. package/lib/commonjs/components/AttachmentPicker/AttachmentPicker.js.map +1 -1
  3. package/lib/commonjs/components/AttachmentPicker/components/{AttachmentSelectionBar.js → AttachmentPickerSelectionBar.js} +6 -6
  4. package/lib/commonjs/components/AttachmentPicker/components/AttachmentPickerSelectionBar.js.map +1 -0
  5. package/lib/commonjs/components/ImageGallery/ImageGallery.js +29 -53
  6. package/lib/commonjs/components/ImageGallery/ImageGallery.js.map +1 -1
  7. package/lib/commonjs/components/ImageGallery/components/ImageGalleryHeader.js +2 -6
  8. package/lib/commonjs/components/ImageGallery/components/ImageGalleryHeader.js.map +1 -1
  9. package/lib/commonjs/components/MessageInput/MessageInput.js +6 -3
  10. package/lib/commonjs/components/MessageInput/MessageInput.js.map +1 -1
  11. package/lib/commonjs/components/MessageInput/hooks/useCountdown.js.map +1 -1
  12. package/lib/commonjs/components/MessageList/MessageList.js.map +1 -1
  13. package/lib/commonjs/components/index.js +4 -4
  14. package/lib/commonjs/components/index.js.map +1 -1
  15. package/lib/commonjs/contexts/attachmentPickerContext/AttachmentPickerContext.js +1 -2
  16. package/lib/commonjs/contexts/attachmentPickerContext/AttachmentPickerContext.js.map +1 -1
  17. package/lib/commonjs/contexts/overlayContext/OverlayContext.js.map +1 -1
  18. package/lib/commonjs/contexts/overlayContext/OverlayProvider.js +18 -9
  19. package/lib/commonjs/contexts/overlayContext/OverlayProvider.js.map +1 -1
  20. package/lib/commonjs/hooks/index.js +11 -0
  21. package/lib/commonjs/hooks/index.js.map +1 -1
  22. package/lib/commonjs/hooks/useScreenDimensions.js +47 -0
  23. package/lib/commonjs/hooks/useScreenDimensions.js.map +1 -0
  24. package/lib/commonjs/i18n/es.json +17 -17
  25. package/lib/commonjs/i18n/fr.json +17 -17
  26. package/lib/commonjs/i18n/he.json +17 -17
  27. package/lib/commonjs/i18n/hi.json +17 -17
  28. package/lib/commonjs/i18n/it.json +17 -17
  29. package/lib/commonjs/i18n/ja.json +17 -17
  30. package/lib/commonjs/i18n/ko.json +17 -17
  31. package/lib/commonjs/i18n/nl.json +17 -17
  32. package/lib/commonjs/i18n/pt-BR.json +14 -14
  33. package/lib/commonjs/i18n/ru.json +17 -17
  34. package/lib/commonjs/i18n/tr.json +14 -14
  35. package/lib/commonjs/version.json +1 -1
  36. package/lib/module/components/AttachmentPicker/AttachmentPicker.js +10 -43
  37. package/lib/module/components/AttachmentPicker/AttachmentPicker.js.map +1 -1
  38. package/lib/module/components/AttachmentPicker/components/{AttachmentSelectionBar.js → AttachmentPickerSelectionBar.js} +6 -6
  39. package/lib/module/components/AttachmentPicker/components/AttachmentPickerSelectionBar.js.map +1 -0
  40. package/lib/module/components/ImageGallery/ImageGallery.js +29 -53
  41. package/lib/module/components/ImageGallery/ImageGallery.js.map +1 -1
  42. package/lib/module/components/ImageGallery/components/ImageGalleryHeader.js +2 -6
  43. package/lib/module/components/ImageGallery/components/ImageGalleryHeader.js.map +1 -1
  44. package/lib/module/components/MessageInput/MessageInput.js +6 -3
  45. package/lib/module/components/MessageInput/MessageInput.js.map +1 -1
  46. package/lib/module/components/MessageInput/hooks/useCountdown.js.map +1 -1
  47. package/lib/module/components/MessageList/MessageList.js.map +1 -1
  48. package/lib/module/components/index.js +4 -4
  49. package/lib/module/components/index.js.map +1 -1
  50. package/lib/module/contexts/attachmentPickerContext/AttachmentPickerContext.js +1 -2
  51. package/lib/module/contexts/attachmentPickerContext/AttachmentPickerContext.js.map +1 -1
  52. package/lib/module/contexts/overlayContext/OverlayContext.js.map +1 -1
  53. package/lib/module/contexts/overlayContext/OverlayProvider.js +18 -9
  54. package/lib/module/contexts/overlayContext/OverlayProvider.js.map +1 -1
  55. package/lib/module/hooks/index.js +11 -0
  56. package/lib/module/hooks/index.js.map +1 -1
  57. package/lib/module/hooks/useScreenDimensions.js +47 -0
  58. package/lib/module/hooks/useScreenDimensions.js.map +1 -0
  59. package/lib/module/i18n/es.json +17 -17
  60. package/lib/module/i18n/fr.json +17 -17
  61. package/lib/module/i18n/he.json +17 -17
  62. package/lib/module/i18n/hi.json +17 -17
  63. package/lib/module/i18n/it.json +17 -17
  64. package/lib/module/i18n/ja.json +17 -17
  65. package/lib/module/i18n/ko.json +17 -17
  66. package/lib/module/i18n/nl.json +17 -17
  67. package/lib/module/i18n/pt-BR.json +14 -14
  68. package/lib/module/i18n/ru.json +17 -17
  69. package/lib/module/i18n/tr.json +14 -14
  70. package/lib/module/version.json +1 -1
  71. package/lib/typescript/components/AttachmentPicker/AttachmentPicker.d.ts +30 -12
  72. package/lib/typescript/components/AttachmentPicker/AttachmentPicker.d.ts.map +1 -1
  73. package/lib/typescript/components/AttachmentPicker/components/AttachmentPickerSelectionBar.d.ts +3 -0
  74. package/lib/typescript/components/AttachmentPicker/components/AttachmentPickerSelectionBar.d.ts.map +1 -0
  75. package/lib/typescript/components/Channel/hooks/useCreateInputMessageInputContext.d.ts +1 -1
  76. package/lib/typescript/components/ImageGallery/ImageGallery.d.ts.map +1 -1
  77. package/lib/typescript/components/ImageGallery/components/ImageGalleryHeader.d.ts.map +1 -1
  78. package/lib/typescript/components/MessageInput/MessageInput.d.ts +2 -1
  79. package/lib/typescript/components/MessageInput/MessageInput.d.ts.map +1 -1
  80. package/lib/typescript/components/index.d.ts +1 -1
  81. package/lib/typescript/components/index.d.ts.map +1 -1
  82. package/lib/typescript/contexts/attachmentPickerContext/AttachmentPickerContext.d.ts +32 -3
  83. package/lib/typescript/contexts/attachmentPickerContext/AttachmentPickerContext.d.ts.map +1 -1
  84. package/lib/typescript/contexts/overlayContext/OverlayContext.d.ts +2 -3
  85. package/lib/typescript/contexts/overlayContext/OverlayContext.d.ts.map +1 -1
  86. package/lib/typescript/contexts/overlayContext/OverlayProvider.d.ts.map +1 -1
  87. package/lib/typescript/hooks/index.d.ts +1 -0
  88. package/lib/typescript/hooks/index.d.ts.map +1 -1
  89. package/lib/typescript/hooks/useScreenDimensions.d.ts +12 -0
  90. package/lib/typescript/hooks/useScreenDimensions.d.ts.map +1 -0
  91. package/lib/typescript/i18n/es.json +17 -17
  92. package/lib/typescript/i18n/fr.json +17 -17
  93. package/lib/typescript/i18n/he.json +17 -17
  94. package/lib/typescript/i18n/hi.json +17 -17
  95. package/lib/typescript/i18n/it.json +17 -17
  96. package/lib/typescript/i18n/ja.json +17 -17
  97. package/lib/typescript/i18n/ko.json +17 -17
  98. package/lib/typescript/i18n/nl.json +17 -17
  99. package/lib/typescript/i18n/pt-BR.json +14 -14
  100. package/lib/typescript/i18n/ru.json +17 -17
  101. package/lib/typescript/i18n/tr.json +14 -14
  102. package/package.json +1 -1
  103. package/src/components/AttachmentPicker/AttachmentPicker.tsx +21 -69
  104. package/src/components/AttachmentPicker/components/{AttachmentSelectionBar.tsx → AttachmentPickerSelectionBar.tsx} +2 -2
  105. package/src/components/ImageGallery/ImageGallery.tsx +31 -79
  106. package/src/components/ImageGallery/components/ImageGalleryHeader.tsx +3 -19
  107. package/src/components/MessageInput/MessageInput.tsx +11 -7
  108. package/src/components/MessageInput/__tests__/MessageInput.test.js +2 -0
  109. package/src/components/MessageInput/hooks/useCountdown.ts +1 -1
  110. package/src/components/MessageList/MessageList.tsx +4 -4
  111. package/src/components/index.ts +1 -1
  112. package/src/contexts/attachmentPickerContext/AttachmentPickerContext.tsx +34 -10
  113. package/src/contexts/overlayContext/OverlayContext.tsx +5 -4
  114. package/src/contexts/overlayContext/OverlayProvider.tsx +11 -8
  115. package/src/hooks/index.ts +1 -0
  116. package/src/hooks/useScreenDimensions.ts +41 -0
  117. package/src/i18n/es.json +17 -17
  118. package/src/i18n/fr.json +17 -17
  119. package/src/i18n/he.json +17 -17
  120. package/src/i18n/hi.json +17 -17
  121. package/src/i18n/it.json +17 -17
  122. package/src/i18n/ja.json +17 -17
  123. package/src/i18n/ko.json +17 -17
  124. package/src/i18n/nl.json +17 -17
  125. package/src/i18n/pt-BR.json +14 -14
  126. package/src/i18n/ru.json +17 -17
  127. package/src/i18n/tr.json +14 -14
  128. package/src/version.json +1 -1
  129. package/lib/commonjs/components/AttachmentPicker/components/AttachmentSelectionBar.js.map +0 -1
  130. package/lib/module/components/AttachmentPicker/components/AttachmentSelectionBar.js.map +0 -1
  131. package/lib/typescript/components/AttachmentPicker/components/AttachmentSelectionBar.d.ts +0 -3
  132. package/lib/typescript/components/AttachmentPicker/components/AttachmentSelectionBar.d.ts.map +0 -1
@@ -1,14 +1,5 @@
1
1
  import React, { useEffect, useRef, useState } from 'react';
2
- import {
3
- Dimensions,
4
- Image,
5
- ImageStyle,
6
- Keyboard,
7
- Platform,
8
- StatusBar,
9
- StyleSheet,
10
- ViewStyle,
11
- } from 'react-native';
2
+ import { Image, ImageStyle, Keyboard, Platform, StyleSheet, ViewStyle } from 'react-native';
12
3
 
13
4
  import {
14
5
  PanGestureHandler,
@@ -26,7 +17,7 @@ import Animated, {
26
17
  withTiming,
27
18
  } from 'react-native-reanimated';
28
19
 
29
- import { BottomSheetModal, BottomSheetModalProvider, BottomSheetProps } from '@gorhom/bottom-sheet';
20
+ import { BottomSheetModal, BottomSheetModalProvider } from '@gorhom/bottom-sheet';
30
21
 
31
22
  import type { UserResponse } from 'stream-chat';
32
23
 
@@ -63,7 +54,6 @@ import { getUrlOfImageAttachment } from '../../utils/getUrlOfImageAttachment';
63
54
  import { getGiphyMimeType } from '../Attachment/utils/getGiphyMimeType';
64
55
 
65
56
  const isAndroid = Platform.OS === 'android';
66
- const fullScreenHeight = Dimensions.get('screen').height;
67
57
 
68
58
  const MARGIN = 32;
69
59
 
@@ -132,29 +122,6 @@ type Props<StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamC
132
122
  | 'autoPlayVideo'
133
123
  >;
134
124
 
135
- type SnapPoints = BottomSheetProps['snapPoints'];
136
-
137
- const normalizeSnapPoints = (input: SnapPoints): SnapPoints => {
138
- const snapPoints = input ? ('value' in input ? input.value : input) : [];
139
-
140
- return snapPoints.map((snapPoint) => {
141
- if (typeof snapPoint === 'number') {
142
- return Math.max(0, snapPoint);
143
- } else {
144
- const numericValue = Number(snapPoint.replace('%', ''));
145
- const isPercentage = snapPoint.includes('%');
146
-
147
- if (isNaN(numericValue)) {
148
- return 0;
149
- } else if (isPercentage) {
150
- return `${Math.max(0, numericValue)}%`;
151
- } else {
152
- return Math.max(0, numericValue);
153
- }
154
- }
155
- });
156
- };
157
-
158
125
  export const ImageGallery = <
159
126
  StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
160
127
  >(
@@ -179,35 +146,20 @@ export const ImageGallery = <
179
146
  },
180
147
  } = useTheme();
181
148
  const [gridPhotos, setGridPhotos] = useState<Photo<StreamChatGenerics>[]>([]);
182
- const { overlay, translucentStatusBar } = useOverlayContext();
149
+ const { overlay } = useOverlayContext();
183
150
  const { messages, selectedMessage, setSelectedMessage } =
184
151
  useImageGalleryContext<StreamChatGenerics>();
185
152
 
186
153
  const { vh, vw } = useViewport();
187
154
 
188
- const measuredScreenHeight = vh(100);
189
- const screenWidth = vw(100);
190
- const halfScreenWidth = vw(50);
155
+ const fullWindowHeight = vh(100);
156
+ const fullWindowWidth = vw(100);
157
+ const halfScreenWidth = fullWindowWidth / 2;
191
158
 
192
- /**
193
- * Height constants
194
- */
195
- const statusBarHeight = StatusBar.currentHeight ?? 0;
196
- const bottomBarHeight = fullScreenHeight - measuredScreenHeight - statusBarHeight;
197
- const androidScreenHeightAdjustment = translucentStatusBar
198
- ? bottomBarHeight === statusBarHeight || bottomBarHeight < 0
199
- ? 0
200
- : statusBarHeight
201
- : bottomBarHeight === statusBarHeight || bottomBarHeight < 0
202
- ? -statusBarHeight
203
- : 0;
204
- const screenHeight = isAndroid
205
- ? Dimensions.get('window').height + androidScreenHeightAdjustment
206
- : vh(100);
207
- const halfScreenHeight = screenHeight / 2;
208
- const quarterScreenHeight = screenHeight / 4;
159
+ const halfScreenHeight = fullWindowHeight / 2;
160
+ const quarterScreenHeight = fullWindowHeight / 4;
209
161
  const snapPoints = React.useMemo(
210
- () => [(screenHeight * 3) / 4, screenHeight - (imageGalleryGridHandleHeight ?? 40)],
162
+ () => [(fullWindowHeight * 3) / 4, fullWindowHeight - imageGalleryGridHandleHeight],
211
163
  [],
212
164
  );
213
165
 
@@ -226,7 +178,7 @@ export const ImageGallery = <
226
178
  * Fade animation for screen, it is always rendered with pointerEvents
227
179
  * set to none for fast opening
228
180
  */
229
- const screenTranslateY = useSharedValue(screenHeight);
181
+ const screenTranslateY = useSharedValue(fullWindowHeight);
230
182
  const showScreen = () => {
231
183
  'worklet';
232
184
  screenTranslateY.value = withTiming(0, {
@@ -246,7 +198,7 @@ export const ImageGallery = <
246
198
  /**
247
199
  * Image height from URL or default to full screen height
248
200
  */
249
- const [currentImageHeight, setCurrentImageHeight] = useState<number>(screenHeight);
201
+ const [currentImageHeight, setCurrentImageHeight] = useState<number>(fullWindowHeight);
250
202
 
251
203
  /**
252
204
  * JS and UI index values, the JS follows the UI but is needed
@@ -321,9 +273,9 @@ export const ImageGallery = <
321
273
  a.type === 'giphy'
322
274
  ? giphyURL
323
275
  : getResizedImageUrl({
324
- height: screenHeight,
276
+ height: fullWindowHeight,
325
277
  url: imageUrl,
326
- width: screenWidth,
278
+ width: fullWindowWidth,
327
279
  }),
328
280
  user: cur.user,
329
281
  user_id: cur.user_id,
@@ -360,7 +312,7 @@ export const ImageGallery = <
360
312
 
361
313
  if (newIndex > -1) {
362
314
  index.value = newIndex;
363
- translationX.value = -(screenWidth + MARGIN) * newIndex;
315
+ translationX.value = -(fullWindowWidth + MARGIN) * newIndex;
364
316
  runOnJS(setSelectedIndex)(newIndex);
365
317
  }
366
318
  };
@@ -383,19 +335,19 @@ export const ImageGallery = <
383
335
  const uriForCurrentImage = imageGalleryAttachments[selectedIndex]?.uri;
384
336
 
385
337
  useEffect(() => {
386
- setCurrentImageHeight(screenHeight);
338
+ setCurrentImageHeight(fullWindowHeight);
387
339
  const photo = imageGalleryAttachments[index.value];
388
340
  const height = photo?.original_height;
389
341
  const width = photo?.original_width;
390
342
 
391
343
  if (height && width) {
392
- const imageHeight = Math.floor(height * (screenWidth / width));
393
- setCurrentImageHeight(imageHeight > screenHeight ? screenHeight : imageHeight);
344
+ const imageHeight = Math.floor(height * (fullWindowWidth / width));
345
+ setCurrentImageHeight(imageHeight > fullWindowHeight ? fullWindowHeight : imageHeight);
394
346
  } else if (photo?.uri) {
395
347
  if (photo.type === 'image') {
396
348
  Image.getSize(photo.uri, (width, height) => {
397
- const imageHeight = Math.floor(height * (screenWidth / width));
398
- setCurrentImageHeight(imageHeight > screenHeight ? screenHeight : imageHeight);
349
+ const imageHeight = Math.floor(height * (fullWindowWidth / width));
350
+ setCurrentImageHeight(imageHeight > fullWindowHeight ? fullWindowHeight : imageHeight);
399
351
  });
400
352
  }
401
353
  }
@@ -410,8 +362,8 @@ export const ImageGallery = <
410
362
  overlayOpacity,
411
363
  photoLength,
412
364
  scale,
413
- screenHeight,
414
- screenWidth,
365
+ screenHeight: fullWindowHeight,
366
+ screenWidth: fullWindowWidth,
415
367
  selectedIndex,
416
368
  setSelectedIndex,
417
369
  translateX,
@@ -425,9 +377,9 @@ export const ImageGallery = <
425
377
  */
426
378
  const headerFooterOpacity = useDerivedValue(
427
379
  () =>
428
- currentImageHeight * scale.value < screenHeight && translateY.value > 0
380
+ currentImageHeight * scale.value < fullWindowHeight && translateY.value > 0
429
381
  ? 1 - translateY.value / quarterScreenHeight
430
- : currentImageHeight * scale.value > screenHeight &&
382
+ : currentImageHeight * scale.value > fullWindowHeight &&
431
383
  translateY.value > (currentImageHeight / 2) * scale.value - halfScreenHeight
432
384
  ? 1 -
433
385
  (translateY.value - ((currentImageHeight / 2) * scale.value - halfScreenHeight)) /
@@ -614,15 +566,15 @@ export const ImageGallery = <
614
566
  previous={selectedIndex > i}
615
567
  repeat={true}
616
568
  scale={scale}
617
- screenHeight={screenHeight}
569
+ screenHeight={fullWindowHeight}
618
570
  selected={selectedIndex === i}
619
571
  shouldRender={Math.abs(selectedIndex - i) < 4}
620
572
  source={{ uri: photo.uri }}
621
573
  style={[
622
574
  {
623
- height: screenHeight * 8,
575
+ height: fullWindowHeight * 8,
624
576
  marginRight: MARGIN,
625
- width: screenWidth * 8,
577
+ width: fullWindowWidth * 8,
626
578
  },
627
579
  slide,
628
580
  ]}
@@ -639,14 +591,14 @@ export const ImageGallery = <
639
591
  photo={photo}
640
592
  previous={selectedIndex > i}
641
593
  scale={scale}
642
- screenHeight={screenHeight}
594
+ screenHeight={fullWindowHeight}
643
595
  selected={selectedIndex === i}
644
596
  shouldRender={Math.abs(selectedIndex - i) < 4}
645
597
  style={[
646
598
  {
647
- height: screenHeight * 8,
599
+ height: fullWindowHeight * 8,
648
600
  marginRight: MARGIN,
649
- width: screenWidth * 8,
601
+ width: fullWindowWidth * 8,
650
602
  },
651
603
  slide,
652
604
  ]}
@@ -704,11 +656,11 @@ export const ImageGallery = <
704
656
  {...imageGalleryCustomComponents?.gridHandle}
705
657
  />
706
658
  )}
707
- handleHeight={imageGalleryGridHandleHeight ?? 40}
659
+ handleHeight={imageGalleryGridHandleHeight}
708
660
  index={0}
709
661
  onChange={(index: number) => setCurrentBottomSheetIndex(index)}
710
662
  ref={bottomSheetModalRef}
711
- snapPoints={normalizeSnapPoints(imageGalleryGridSnapPoints || snapPoints)}
663
+ snapPoints={imageGalleryGridSnapPoints || snapPoints}
712
664
  >
713
665
  <ImageGrid
714
666
  closeGridView={closeGridView}
@@ -1,14 +1,5 @@
1
1
  import React, { useState } from 'react';
2
- import {
3
- Platform,
4
- Pressable,
5
- SafeAreaView,
6
- StatusBar,
7
- StyleSheet,
8
- Text,
9
- View,
10
- ViewStyle,
11
- } from 'react-native';
2
+ import { Pressable, SafeAreaView, StyleSheet, Text, View, ViewStyle } from 'react-native';
12
3
  import Animated, { Extrapolate, interpolate, useAnimatedStyle } from 'react-native-reanimated';
13
4
 
14
5
  import { useOverlayContext } from '../../../contexts/overlayContext/OverlayContext';
@@ -108,7 +99,7 @@ export const ImageGalleryHeader = <
108
99
  },
109
100
  } = useTheme();
110
101
  const { t, tDateTimeParser } = useTranslationContext();
111
- const { setOverlay, translucentStatusBar } = useOverlayContext();
102
+ const { setOverlay } = useOverlayContext();
112
103
 
113
104
  const parsedDate = photo ? tDateTimeParser(photo?.created_at) : null;
114
105
 
@@ -146,11 +137,6 @@ export const ImageGalleryHeader = <
146
137
  ],
147
138
  }));
148
139
 
149
- const androidTranslucentHeaderStyle = {
150
- paddingTop:
151
- Platform.OS === 'android' && translucentStatusBar ? StatusBar.currentHeight : undefined,
152
- };
153
-
154
140
  const hideOverlay = () => {
155
141
  setOverlay('none');
156
142
  };
@@ -160,9 +146,7 @@ export const ImageGalleryHeader = <
160
146
  onLayout={(event) => setHeight(event.nativeEvent.layout.height)}
161
147
  pointerEvents={'box-none'}
162
148
  >
163
- <ReanimatedSafeAreaView
164
- style={[{ backgroundColor: white }, androidTranslucentHeaderStyle, container, headerStyle]}
165
- >
149
+ <ReanimatedSafeAreaView style={[{ backgroundColor: white }, container, headerStyle]}>
166
150
  <View style={[styles.innerContainer, innerContainer]}>
167
151
  {leftElement ? (
168
152
  leftElement({ hideOverlay, photo })
@@ -12,7 +12,10 @@ import type { UserResponse } from 'stream-chat';
12
12
  import { useCountdown } from './hooks/useCountdown';
13
13
 
14
14
  import { ChatContextValue, useChatContext } from '../../contexts';
15
- import { useAttachmentPickerContext } from '../../contexts/attachmentPickerContext/AttachmentPickerContext';
15
+ import {
16
+ AttachmentPickerContextValue,
17
+ useAttachmentPickerContext,
18
+ } from '../../contexts/attachmentPickerContext/AttachmentPickerContext';
16
19
  import {
17
20
  ChannelContextValue,
18
21
  useChannelContext,
@@ -38,7 +41,6 @@ import {
38
41
  } from '../../contexts/translationContext/TranslationContext';
39
42
 
40
43
  import type { Asset, DefaultStreamChatGenerics } from '../../types/types';
41
- import { AttachmentSelectionBar } from '../AttachmentPicker/components/AttachmentSelectionBar';
42
44
  import { AutoCompleteInput } from '../AutoCompleteInput/AutoCompleteInput';
43
45
 
44
46
  const styles = StyleSheet.create({
@@ -80,7 +82,8 @@ const styles = StyleSheet.create({
80
82
 
81
83
  type MessageInputPropsWithContext<
82
84
  StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
83
- > = Pick<ChatContextValue<StreamChatGenerics>, 'isOnline'> &
85
+ > = Pick<AttachmentPickerContextValue, 'AttachmentPickerSelectionBar'> &
86
+ Pick<ChatContextValue<StreamChatGenerics>, 'isOnline'> &
84
87
  Pick<
85
88
  ChannelContextValue<StreamChatGenerics>,
86
89
  'disabled' | 'members' | 'threadList' | 'watchers'
@@ -146,6 +149,7 @@ const MessageInputWithContext = <
146
149
  additionalTextInputProps,
147
150
  asyncIds,
148
151
  asyncUploads,
152
+ AttachmentPickerSelectionBar,
149
153
  AutoCompleteSuggestionList,
150
154
  closeAttachmentPicker,
151
155
  cooldownEndsAt,
@@ -637,14 +641,12 @@ const MessageInputWithContext = <
637
641
  {
638
642
  backgroundColor: white_smoke,
639
643
  height:
640
- (attachmentPickerBottomSheetHeight
641
- ? attachmentPickerBottomSheetHeight + (attachmentSelectionBarHeight ?? 52)
642
- : 360) - bottomInset,
644
+ attachmentPickerBottomSheetHeight + attachmentSelectionBarHeight - bottomInset,
643
645
  },
644
646
  attachmentSelectionBar,
645
647
  ]}
646
648
  >
647
- <AttachmentSelectionBar />
649
+ <AttachmentPickerSelectionBar />
648
650
  </View>
649
651
  )}
650
652
  </>
@@ -789,6 +791,7 @@ export const MessageInput = <
789
791
  >(
790
792
  props: MessageInputProps<StreamChatGenerics>,
791
793
  ) => {
794
+ const { AttachmentPickerSelectionBar } = useAttachmentPickerContext();
792
795
  const { isOnline } = useChatContext();
793
796
  const ownCapabilities = useOwnCapabilitiesContext();
794
797
 
@@ -859,6 +862,7 @@ export const MessageInput = <
859
862
  additionalTextInputProps,
860
863
  asyncIds,
861
864
  asyncUploads,
865
+ AttachmentPickerSelectionBar,
862
866
  AutoCompleteSuggestionHeader,
863
867
  AutoCompleteSuggestionItem,
864
868
  AutoCompleteSuggestionList,
@@ -16,6 +16,7 @@ import {
16
16
  import { generateChannelResponse } from '../../../mock-builders/generator/channel';
17
17
  import { generateUser } from '../../../mock-builders/generator/user';
18
18
  import { getTestClientWithUser } from '../../../mock-builders/mock';
19
+ import { AttachmentPickerSelectionBar } from '../../AttachmentPicker/components/AttachmentPickerSelectionBar';
19
20
  import { CameraSelectorIcon } from '../../AttachmentPicker/components/CameraSelectorIcon';
20
21
  import { FileSelectorIcon } from '../../AttachmentPicker/components/FileSelectorIcon';
21
22
  import { ImageSelectorIcon } from '../../AttachmentPicker/components/ImageSelectorIcon';
@@ -27,6 +28,7 @@ describe('MessageInput', () => {
27
28
  jest.spyOn(Alert, 'alert');
28
29
  jest.spyOn(AttachmentPickerUtils, 'useAttachmentPickerContext').mockImplementation(
29
30
  jest.fn(() => ({
31
+ AttachmentPickerSelectionBar,
30
32
  CameraSelectorIcon,
31
33
  closePicker: jest.fn(),
32
34
  FileSelectorIcon,
@@ -15,7 +15,7 @@ export const useCountdown = (end: Date) => {
15
15
  * the `end` is in the future.
16
16
  **/
17
17
  useEffect(() => {
18
- let intervalId: NodeJS.Timeout;
18
+ let intervalId: ReturnType<typeof setInterval>;
19
19
 
20
20
  const startCountdown = (seconds: number) => {
21
21
  setSeconds(seconds);
@@ -352,17 +352,17 @@ const MessageListWithContext = <
352
352
  /**
353
353
  * The timeout id used to debounce our scrollToIndex calls on messageList updates
354
354
  */
355
- const scrollToDebounceTimeoutRef = useRef<NodeJS.Timeout>();
355
+ const scrollToDebounceTimeoutRef = useRef<ReturnType<typeof setTimeout>>();
356
356
 
357
357
  /**
358
358
  * The timeout id used to lazier load the initial scroll set flag
359
359
  */
360
- const initialScrollSettingTimeoutRef = useRef<NodeJS.Timeout>();
360
+ const initialScrollSettingTimeoutRef = useRef<ReturnType<typeof setTimeout>>();
361
361
 
362
362
  /**
363
363
  * The timeout id used to temporarily load the initial scroll set flag
364
364
  */
365
- const onScrollEventTimeoutRef = useRef<NodeJS.Timeout>();
365
+ const onScrollEventTimeoutRef = useRef<ReturnType<typeof setTimeout>>();
366
366
 
367
367
  /**
368
368
  * Last messageID that was scrolled to after loading a new message list,
@@ -861,7 +861,7 @@ const MessageListWithContext = <
861
861
  };
862
862
 
863
863
  const scrollToIndexFailedRetryCountRef = useRef<number>(0);
864
- const failScrollTimeoutId = useRef<NodeJS.Timeout>();
864
+ const failScrollTimeoutId = useRef<ReturnType<typeof setTimeout>>();
865
865
  const onScrollToIndexFailedRef = useRef<
866
866
  FlatListProps<MessageType<StreamChatGenerics>>['onScrollToIndexFailed']
867
867
  >((info) => {
@@ -14,7 +14,7 @@ export * from './AttachmentPicker/AttachmentPicker';
14
14
  export * from './AttachmentPicker/components/AttachmentPickerBottomSheetHandle';
15
15
  export * from './AttachmentPicker/components/AttachmentPickerError';
16
16
  export * from './AttachmentPicker/components/AttachmentPickerErrorImage';
17
- export * from './AttachmentPicker/components/AttachmentSelectionBar';
17
+ export * from './AttachmentPicker/components/AttachmentPickerSelectionBar';
18
18
  export * from './AttachmentPicker/components/CameraSelectorIcon';
19
19
  export * from './AttachmentPicker/components/FileSelectorIcon';
20
20
  export * from './AttachmentPicker/components/ImageOverlaySelectedComponent';
@@ -1,5 +1,7 @@
1
1
  import React, { PropsWithChildren, useContext, useEffect, useState } from 'react';
2
2
 
3
+ import { BottomSheetHandleProps } from '@gorhom/bottom-sheet';
4
+
3
5
  import type { Asset, DefaultStreamChatGenerics, File } from '../../types/types';
4
6
  import { DEFAULT_BASE_CONTEXT_VALUE } from '../utils/defaultBaseContextValue';
5
7
 
@@ -12,6 +14,36 @@ export type AttachmentPickerIconProps = {
12
14
  };
13
15
 
14
16
  export type AttachmentPickerContextValue = {
17
+ /**
18
+ * Custom UI component to render [draggable handle](https://github.com/GetStream/stream-chat-react-native/blob/main/screenshots/docs/1.png) of attachment picker.
19
+ *
20
+ * **Default** [AttachmentPickerBottomSheetHandle](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/AttachmentPicker/components/AttachmentPickerBottomSheetHandle.tsx)
21
+ */
22
+ AttachmentPickerBottomSheetHandle: React.FC<BottomSheetHandleProps>;
23
+ /**
24
+ * Height of the image picker bottom sheet handle.
25
+ * @type number
26
+ * @default 20
27
+ */
28
+ attachmentPickerBottomSheetHandleHeight: number;
29
+ /**
30
+ * Height of the image picker bottom sheet when opened.
31
+ * @type number
32
+ * @default 40% of window height
33
+ */
34
+ attachmentPickerBottomSheetHeight: number;
35
+ /**
36
+ * Custom UI component for AttachmentPickerSelectionBar
37
+ *
38
+ * **Default: ** [AttachmentPickerSelectionBar](https://github.com/GetStream/stream-chat-react-native/blob/develop/package/src/components/AttachmentPicker/components/AttachmentPickerSelectionBar.tsx)
39
+ */
40
+ AttachmentPickerSelectionBar: React.ComponentType;
41
+ /**
42
+ * Height of the attachment selection bar displayed on the attachment picker.
43
+ * @type number
44
+ * @default 52
45
+ */
46
+ attachmentSelectionBarHeight: number;
15
47
  /**
16
48
  * `bottomInset` determine the height of the `AttachmentPicker` and the underlying shift to the `MessageList` when it is opened.
17
49
  * This can also be set via the `setBottomInset` function provided by the `useAttachmentPickerContext` hook.
@@ -53,8 +85,6 @@ export type AttachmentPickerContextValue = {
53
85
  setSelectedPicker: React.Dispatch<React.SetStateAction<'images' | undefined>>;
54
86
  setTopInset: React.Dispatch<React.SetStateAction<number>>;
55
87
  topInset: number;
56
- attachmentPickerBottomSheetHeight?: number;
57
- attachmentSelectionBarHeight?: number;
58
88
  selectedPicker?: 'images';
59
89
  };
60
90
 
@@ -68,13 +98,7 @@ export const AttachmentPickerProvider = ({
68
98
  }: PropsWithChildren<{
69
99
  value?: Pick<
70
100
  AttachmentPickerContextValue,
71
- | 'attachmentSelectionBarHeight'
72
- | 'attachmentPickerBottomSheetHeight'
73
- | 'CameraSelectorIcon'
74
- | 'closePicker'
75
- | 'FileSelectorIcon'
76
- | 'ImageSelectorIcon'
77
- | 'openPicker'
101
+ 'CameraSelectorIcon' | 'closePicker' | 'FileSelectorIcon' | 'ImageSelectorIcon' | 'openPicker'
78
102
  > &
79
103
  Partial<Pick<AttachmentPickerContextValue, 'bottomInset' | 'topInset'>>;
80
104
  }>) => {
@@ -86,7 +110,7 @@ export const AttachmentPickerProvider = ({
86
110
  const [selectedImages, setSelectedImages] = useState<Asset[]>([]);
87
111
  const [selectedFiles, setSelectedFiles] = useState<File[]>([]);
88
112
  const [selectedPicker, setSelectedPicker] = useState<'images'>();
89
- const [topInset, setTopInset] = useState<number>(value?.topInset ?? 0);
113
+ const [topInset, setTopInset] = useState<number>(topInsetValue ?? 0);
90
114
 
91
115
  useEffect(() => {
92
116
  setBottomInset(bottomInsetValue ?? 0);
@@ -24,7 +24,6 @@ export type OverlayContextValue = {
24
24
  overlay: Overlay;
25
25
  setOverlay: React.Dispatch<React.SetStateAction<Overlay>>;
26
26
  style?: DeepPartial<Theme>;
27
- translucentStatusBar?: boolean;
28
27
  };
29
28
 
30
29
  export const OverlayContext = React.createContext(
@@ -37,7 +36,10 @@ export type OverlayProviderProps<
37
36
  Partial<
38
37
  Pick<
39
38
  AttachmentPickerContextValue,
39
+ | 'AttachmentPickerBottomSheetHandle'
40
+ | 'attachmentPickerBottomSheetHandleHeight'
40
41
  | 'attachmentPickerBottomSheetHeight'
42
+ | 'AttachmentPickerSelectionBar'
41
43
  | 'attachmentSelectionBarHeight'
42
44
  | 'bottomInset'
43
45
  | 'CameraSelectorIcon'
@@ -56,8 +58,8 @@ export type OverlayProviderProps<
56
58
  | 'OverlayReactions'
57
59
  | 'OverlayReactionsAvatar'
58
60
  >
59
- > &
60
- Pick<OverlayContextValue, 'translucentStatusBar'> & {
61
+ > & {
62
+ imageGalleryGridHandleHeight: number;
61
63
  autoPlayVideo?: boolean;
62
64
  /**
63
65
  * The giphy version to render - check the keys of the [Image Object](https://developers.giphy.com/docs/api/schema#image-object) for possible values. Uses 'fixed_height' by default
@@ -67,7 +69,6 @@ export type OverlayProviderProps<
67
69
  giphyVersion?: keyof NonNullable<Attachment['giphy']>;
68
70
  /** https://github.com/GetStream/stream-chat-react-native/wiki/Internationalization-(i18n) */
69
71
  i18nInstance?: Streami18n;
70
- imageGalleryGridHandleHeight?: number;
71
72
  imageGalleryGridSnapPoints?: [string | number, string | number];
72
73
  isMyMessage?: boolean;
73
74
  isThreadMessage?: boolean;
@@ -19,6 +19,7 @@ import { AttachmentPickerBottomSheetHandle as DefaultAttachmentPickerBottomSheet
19
19
  import { AttachmentPickerError as DefaultAttachmentPickerError } from '../../components/AttachmentPicker/components/AttachmentPickerError';
20
20
  import { AttachmentPickerErrorImage as DefaultAttachmentPickerErrorImage } from '../../components/AttachmentPicker/components/AttachmentPickerErrorImage';
21
21
  import { AttachmentPickerIOSSelectMorePhotos as DefaultAttachmentPickerIOSSelectMorePhotos } from '../../components/AttachmentPicker/components/AttachmentPickerIOSSelectMorePhotos';
22
+ import { AttachmentPickerSelectionBar as DefaultAttachmentPickerSelectionBar } from '../../components/AttachmentPicker/components/AttachmentPickerSelectionBar';
22
23
  import { CameraSelectorIcon as DefaultCameraSelectorIcon } from '../../components/AttachmentPicker/components/CameraSelectorIcon';
23
24
  import { FileSelectorIcon as DefaultFileSelectorIcon } from '../../components/AttachmentPicker/components/FileSelectorIcon';
24
25
  import { ImageOverlaySelectedComponent as DefaultImageOverlaySelectedComponent } from '../../components/AttachmentPicker/components/ImageOverlaySelectedComponent';
@@ -28,6 +29,7 @@ import { MessageOverlay } from '../../components/MessageOverlay/MessageOverlay';
28
29
  import { OverlayBackdrop } from '../../components/MessageOverlay/OverlayBackdrop';
29
30
  import { useStreami18n } from '../../hooks/useStreami18n';
30
31
 
32
+ import { useViewport } from '../../hooks/useViewport';
31
33
  import type { DefaultStreamChatGenerics } from '../../types/types';
32
34
  import { AttachmentPickerProvider } from '../attachmentPickerContext/AttachmentPickerContext';
33
35
  import { ImageGalleryProvider } from '../imageGalleryContext/ImageGalleryContext';
@@ -63,17 +65,19 @@ export const OverlayProvider = <
63
65
  >(
64
66
  props: PropsWithChildren<OverlayProviderProps<StreamChatGenerics>>,
65
67
  ) => {
66
- const bottomSheetCloseTimeoutRef = useRef<NodeJS.Timeout>();
68
+ const { vh } = useViewport();
69
+ const bottomSheetCloseTimeoutRef = useRef<ReturnType<typeof setTimeout>>();
67
70
  const {
68
71
  AttachmentPickerBottomSheetHandle = DefaultAttachmentPickerBottomSheetHandle,
69
- attachmentPickerBottomSheetHandleHeight,
70
- attachmentPickerBottomSheetHeight,
72
+ attachmentPickerBottomSheetHandleHeight = 20,
73
+ attachmentPickerBottomSheetHeight = vh(45),
71
74
  AttachmentPickerError = DefaultAttachmentPickerError,
72
75
  attachmentPickerErrorButtonText,
73
76
  AttachmentPickerErrorImage = DefaultAttachmentPickerErrorImage,
74
77
  attachmentPickerErrorText,
75
78
  AttachmentPickerIOSSelectMorePhotos = DefaultAttachmentPickerIOSSelectMorePhotos,
76
- attachmentSelectionBarHeight,
79
+ AttachmentPickerSelectionBar = DefaultAttachmentPickerSelectionBar,
80
+ attachmentSelectionBarHeight = 52,
77
81
  autoPlayVideo,
78
82
  bottomInset,
79
83
  CameraSelectorIcon = DefaultCameraSelectorIcon,
@@ -98,7 +102,7 @@ export const OverlayProvider = <
98
102
  giphyVersion,
99
103
  i18nInstance,
100
104
  imageGalleryCustomComponents,
101
- imageGalleryGridHandleHeight,
105
+ imageGalleryGridHandleHeight = 40,
102
106
  imageGalleryGridSnapPoints,
103
107
  ImageOverlaySelectedComponent = DefaultImageOverlaySelectedComponent,
104
108
  ImageSelectorIcon = DefaultImageSelectorIcon,
@@ -122,7 +126,6 @@ export const OverlayProvider = <
122
126
  OverlayReactions,
123
127
  OverlayReactionsAvatar,
124
128
  topInset,
125
- translucentStatusBar,
126
129
  value,
127
130
  } = props;
128
131
 
@@ -139,7 +142,6 @@ export const OverlayProvider = <
139
142
  ImageOverlaySelectedComponent,
140
143
  numberOfAttachmentImagesToLoadPerCall,
141
144
  numberOfAttachmentPickerImageColumns,
142
- translucentStatusBar,
143
145
  };
144
146
 
145
147
  const bottomSheetRef = useRef<BottomSheet>(null);
@@ -189,7 +191,9 @@ export const OverlayProvider = <
189
191
  }, [overlay]);
190
192
 
191
193
  const attachmentPickerContext = {
194
+ AttachmentPickerBottomSheetHandle,
192
195
  attachmentPickerBottomSheetHeight,
196
+ AttachmentPickerSelectionBar,
193
197
  attachmentSelectionBarHeight,
194
198
  bottomInset,
195
199
  CameraSelectorIcon,
@@ -211,7 +215,6 @@ export const OverlayProvider = <
211
215
  overlay,
212
216
  setOverlay,
213
217
  style: value?.style,
214
- translucentStatusBar,
215
218
  };
216
219
 
217
220
  return (
@@ -1,3 +1,4 @@
1
1
  export * from './useAppStateListener';
2
2
  export * from './useStreami18n';
3
3
  export * from './useViewport';
4
+ export * from './useScreenDimensions';
@@ -0,0 +1,41 @@
1
+ import { useEffect, useMemo, useState } from 'react';
2
+ import { Dimensions } from 'react-native';
3
+
4
+ /**
5
+ * A custom hook that provides functions to calculate dimensions based on
6
+ * a percentage of the screen height (vh) and viewport width (vw). It
7
+ * dynamically updates dimensions on changes in device orientation.
8
+ *
9
+ * @returns {Object} An object containing functions vh and vw.
10
+ */
11
+ export const useScreenDimensions = (rounded?: boolean) => {
12
+ const [screenDimensions, setScreenDimensions] = useState(Dimensions.get('screen'));
13
+
14
+ useEffect(() => {
15
+ const subscriptions = Dimensions.addEventListener('change', ({ screen }) => {
16
+ setScreenDimensions((prev) => {
17
+ const { height, width } = screen;
18
+ if (prev.height !== height || prev.width !== width) {
19
+ return screen;
20
+ }
21
+ return prev;
22
+ });
23
+ });
24
+
25
+ return () => subscriptions?.remove();
26
+ }, []);
27
+
28
+ const vw = (percentageWidth: number) => {
29
+ const value = screenDimensions.width * (percentageWidth / 100);
30
+ return rounded ? Math.round(value) : value;
31
+ };
32
+
33
+ const vh = (percentageHeight: number) => {
34
+ const value = screenDimensions.height * (percentageHeight / 100);
35
+ return rounded ? Math.round(value) : value;
36
+ };
37
+
38
+ const screenDimensionFunctions = useMemo(() => ({ vh, vw }), [vh, vw]);
39
+
40
+ return screenDimensionFunctions;
41
+ };