stream-chat-react-native-core 4.7.0-beta.2 → 4.7.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 (43) hide show
  1. package/README.md +1 -0
  2. package/lib/commonjs/components/Attachment/Card.js +23 -14
  3. package/lib/commonjs/components/Attachment/Card.js.map +1 -1
  4. package/lib/commonjs/components/AttachmentPicker/AttachmentPicker.js +23 -13
  5. package/lib/commonjs/components/AttachmentPicker/AttachmentPicker.js.map +1 -1
  6. package/lib/commonjs/components/Chat/hooks/useIsOnline.js +6 -6
  7. package/lib/commonjs/components/Chat/hooks/useIsOnline.js.map +1 -1
  8. package/lib/commonjs/components/Message/Message.js +6 -6
  9. package/lib/commonjs/components/Message/Message.js.map +1 -1
  10. package/lib/commonjs/components/Message/MessageSimple/utils/renderText.js +22 -15
  11. package/lib/commonjs/components/Message/MessageSimple/utils/renderText.js.map +1 -1
  12. package/lib/commonjs/components/Reply/Reply.js +5 -5
  13. package/lib/commonjs/components/Reply/Reply.js.map +1 -1
  14. package/lib/commonjs/contexts/messageInputContext/MessageInputContext.js +23 -13
  15. package/lib/commonjs/contexts/messageInputContext/MessageInputContext.js.map +1 -1
  16. package/lib/commonjs/version.json +1 -1
  17. package/lib/module/components/Attachment/Card.js +23 -14
  18. package/lib/module/components/Attachment/Card.js.map +1 -1
  19. package/lib/module/components/AttachmentPicker/AttachmentPicker.js +23 -13
  20. package/lib/module/components/AttachmentPicker/AttachmentPicker.js.map +1 -1
  21. package/lib/module/components/Chat/hooks/useIsOnline.js +6 -6
  22. package/lib/module/components/Chat/hooks/useIsOnline.js.map +1 -1
  23. package/lib/module/components/Message/Message.js +6 -6
  24. package/lib/module/components/Message/Message.js.map +1 -1
  25. package/lib/module/components/Message/MessageSimple/utils/renderText.js +22 -15
  26. package/lib/module/components/Message/MessageSimple/utils/renderText.js.map +1 -1
  27. package/lib/module/components/Reply/Reply.js +5 -5
  28. package/lib/module/components/Reply/Reply.js.map +1 -1
  29. package/lib/module/contexts/messageInputContext/MessageInputContext.js +23 -13
  30. package/lib/module/contexts/messageInputContext/MessageInputContext.js.map +1 -1
  31. package/lib/module/version.json +1 -1
  32. package/lib/typescript/components/AttachmentPicker/AttachmentPicker.d.ts +11 -0
  33. package/lib/typescript/components/Chat/hooks/useIsOnline.d.ts +1 -1
  34. package/lib/typescript/components/Message/Message.d.ts +9 -3
  35. package/package.json +2 -2
  36. package/src/components/Attachment/Card.tsx +3 -0
  37. package/src/components/AttachmentPicker/AttachmentPicker.tsx +19 -25
  38. package/src/components/Chat/hooks/useIsOnline.ts +7 -7
  39. package/src/components/Message/Message.tsx +8 -4
  40. package/src/components/Message/MessageSimple/utils/renderText.tsx +6 -1
  41. package/src/components/Reply/Reply.tsx +3 -1
  42. package/src/contexts/messageInputContext/MessageInputContext.tsx +13 -3
  43. package/src/version.json +1 -1
@@ -11,22 +11,28 @@ import { ThreadContextValue } from '../../contexts/threadContext/ThreadContext';
11
11
  import { TranslationContextValue } from '../../contexts/translationContext/TranslationContext';
12
12
  import type { DefaultStreamChatGenerics } from '../../types/types';
13
13
  import { MessageType } from '../MessageList/hooks/useMessageList';
14
- export declare type TouchableEmitter = 'card' | 'fileAttachment' | 'gallery' | 'giphy' | 'message' | 'messageContent' | 'messageReplies' | 'reactionList' | 'textLink';
14
+ export declare type TouchableEmitter = 'fileAttachment' | 'gallery' | 'giphy' | 'message' | 'messageContent' | 'messageReplies' | 'reactionList';
15
15
  export declare type TextMentionTouchableHandlerPayload<StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics> = {
16
16
  emitter: 'textMention';
17
17
  additionalInfo?: {
18
18
  user?: UserResponse<StreamChatGenerics>;
19
19
  };
20
20
  };
21
+ export declare type UrlTouchableHandlerPayload = {
22
+ emitter: 'textLink' | 'card';
23
+ additionalInfo?: {
24
+ url?: string;
25
+ };
26
+ };
21
27
  export declare type TouchableHandlerPayload = {
22
28
  defaultHandler?: () => void;
23
29
  event?: GestureResponderEvent;
24
30
  } & ({
25
- additionalInfo?: Record<string, unknown>;
26
31
  emitter?: TouchableEmitter;
27
- } | TextMentionTouchableHandlerPayload);
32
+ } | TextMentionTouchableHandlerPayload | UrlTouchableHandlerPayload);
28
33
  export declare type MessageTouchableHandlerPayload<StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics> = TouchableHandlerPayload & {
29
34
  actionHandlers?: MessageActionHandlers;
35
+ additionalInfo?: Record<string, unknown>;
30
36
  message?: MessageType<StreamChatGenerics>;
31
37
  };
32
38
  export declare type MessageActionHandlers = {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "stream-chat-react-native-core",
3
3
  "description": "The official React Native and Expo components for Stream Chat, a service for building chat applications",
4
- "version": "4.7.0-beta.2",
4
+ "version": "4.7.0-beta.5",
5
5
  "author": {
6
6
  "company": "Stream.io Inc",
7
7
  "name": "Stream.io Inc"
@@ -34,7 +34,7 @@
34
34
  "prepare-distribution": "cd examples/SampleApp && npm version patch && react-native-version && git add ./ && git commit -m 'Bump build version' --no-verify",
35
35
  "prettier": "prettier --list-different '**/*.{js,ts,tsx,md,json}' .eslintrc.json ../.prettierrc .babelrc",
36
36
  "prettier-fix": "prettier --write '**/*.{js,ts,tsx,md,json}' .eslintrc.json ../.prettierrc .babelrc",
37
- "test:unit": "TZ=UTC jest",
37
+ "test:unit": "TZ=UTC jest --coverage",
38
38
  "validate-translations": "node bin/validate-translations.js",
39
39
  "get-version": "echo $npm_package_version",
40
40
  "version": "bash ./bin/before-tag.sh",
@@ -149,6 +149,7 @@ const CardWithContext = <
149
149
  onLongPress={(event) => {
150
150
  if (onLongPress) {
151
151
  onLongPress({
152
+ additionalInfo: { url: og_scrape_url },
152
153
  emitter: 'card',
153
154
  event,
154
155
  });
@@ -157,6 +158,7 @@ const CardWithContext = <
157
158
  onPress={(event) => {
158
159
  if (onPress) {
159
160
  onPress({
161
+ additionalInfo: { url: og_scrape_url },
160
162
  defaultHandler: defaultOnPress,
161
163
  emitter: 'card',
162
164
  event,
@@ -166,6 +168,7 @@ const CardWithContext = <
166
168
  onPressIn={(event) => {
167
169
  if (onPressIn) {
168
170
  onPressIn({
171
+ additionalInfo: { url: og_scrape_url },
169
172
  defaultHandler: defaultOnPress,
170
173
  emitter: 'card',
171
174
  event,
@@ -1,5 +1,6 @@
1
1
  import React, { useEffect, useMemo, useRef, useState } from 'react';
2
2
  import {
3
+ Alert,
3
4
  BackHandler,
4
5
  Dimensions,
5
6
  ImageBackground,
@@ -56,23 +57,20 @@ const styles = StyleSheet.create({
56
57
  const screenHeight = vh(100);
57
58
  const fullScreenHeight = Dimensions.get('window').height;
58
59
 
59
- type AttachmentImageProps = {
60
+ export type AttachmentPickerItemType = {
60
61
  asset: Asset;
61
62
  ImageOverlaySelectedComponent: React.ComponentType;
62
63
  maxNumberOfFiles: number;
64
+ numberOfUploads: number;
63
65
  selected: boolean;
66
+ setSelectedFiles: React.Dispatch<React.SetStateAction<File[]>>;
64
67
  setSelectedImages: React.Dispatch<React.SetStateAction<Asset[]>>;
65
68
  numberOfAttachmentPickerImageColumns?: number;
66
69
  };
67
70
 
68
- type AttachmentVideoProps = {
69
- asset: Asset;
70
- ImageOverlaySelectedComponent: React.ComponentType;
71
- maxNumberOfFiles: number;
72
- selected: boolean;
73
- setSelectedFiles: React.Dispatch<React.SetStateAction<File[]>>;
74
- numberOfAttachmentPickerImageColumns?: number;
75
- };
71
+ type AttachmentImageProps = Omit<AttachmentPickerItemType, 'setSelectedFiles'>;
72
+
73
+ type AttachmentVideoProps = Omit<AttachmentPickerItemType, 'setSelectedImages'>;
76
74
 
77
75
  const AttachmentVideo: React.FC<AttachmentVideoProps> = (props) => {
78
76
  const {
@@ -80,6 +78,7 @@ const AttachmentVideo: React.FC<AttachmentVideoProps> = (props) => {
80
78
  ImageOverlaySelectedComponent,
81
79
  maxNumberOfFiles,
82
80
  numberOfAttachmentPickerImageColumns,
81
+ numberOfUploads,
83
82
  selected,
84
83
  setSelectedFiles,
85
84
  } = props;
@@ -115,7 +114,8 @@ const AttachmentVideo: React.FC<AttachmentVideoProps> = (props) => {
115
114
  setSelectedFiles((files) => files.filter((file) => file.uri !== asset.uri));
116
115
  } else {
117
116
  setSelectedFiles((files) => {
118
- if (files.length >= maxNumberOfFiles) {
117
+ if (numberOfUploads >= maxNumberOfFiles) {
118
+ Alert.alert('Maximum number of files reached');
119
119
  return files;
120
120
  }
121
121
  return [
@@ -169,6 +169,7 @@ const AttachmentImage: React.FC<AttachmentImageProps> = (props) => {
169
169
  ImageOverlaySelectedComponent,
170
170
  maxNumberOfFiles,
171
171
  numberOfAttachmentPickerImageColumns,
172
+ numberOfUploads,
172
173
  selected,
173
174
  setSelectedImages,
174
175
  } = props;
@@ -188,7 +189,8 @@ const AttachmentImage: React.FC<AttachmentImageProps> = (props) => {
188
189
  setSelectedImages((images) => images.filter((image) => image.uri !== asset.uri));
189
190
  } else {
190
191
  setSelectedImages((images) => {
191
- if (images.length >= maxNumberOfFiles) {
192
+ if (numberOfUploads >= maxNumberOfFiles) {
193
+ Alert.alert('Maximum number of files reached');
192
194
  return images;
193
195
  }
194
196
  return [...images, asset];
@@ -219,24 +221,13 @@ const AttachmentImage: React.FC<AttachmentImageProps> = (props) => {
219
221
  );
220
222
  };
221
223
 
222
- const renderImage = ({
223
- item,
224
- }: {
225
- item: {
226
- asset: Asset;
227
- ImageOverlaySelectedComponent: React.ComponentType;
228
- maxNumberOfFiles: number;
229
- selected: boolean;
230
- setSelectedFiles: React.Dispatch<React.SetStateAction<File[]>>;
231
- setSelectedImages: React.Dispatch<React.SetStateAction<Asset[]>>;
232
- numberOfAttachmentPickerImageColumns?: number;
233
- };
234
- }) => {
224
+ const renderItem = ({ item }: { item: AttachmentPickerItemType }) => {
235
225
  const {
236
226
  asset,
237
227
  ImageOverlaySelectedComponent,
238
228
  maxNumberOfFiles,
239
229
  numberOfAttachmentPickerImageColumns,
230
+ numberOfUploads,
240
231
  selected,
241
232
  setSelectedFiles,
242
233
  setSelectedImages,
@@ -258,6 +249,7 @@ const renderImage = ({
258
249
  ImageOverlaySelectedComponent={ImageOverlaySelectedComponent}
259
250
  maxNumberOfFiles={maxNumberOfFiles}
260
251
  numberOfAttachmentPickerImageColumns={numberOfAttachmentPickerImageColumns}
252
+ numberOfUploads={numberOfUploads}
261
253
  selected={selected}
262
254
  setSelectedImages={setSelectedImages}
263
255
  />
@@ -267,6 +259,7 @@ const renderImage = ({
267
259
  ImageOverlaySelectedComponent={ImageOverlaySelectedComponent}
268
260
  maxNumberOfFiles={maxNumberOfFiles}
269
261
  numberOfAttachmentPickerImageColumns={numberOfAttachmentPickerImageColumns}
262
+ numberOfUploads={numberOfUploads}
270
263
  selected={selected}
271
264
  setSelectedFiles={setSelectedFiles}
272
265
  />
@@ -453,6 +446,7 @@ export const AttachmentPicker = React.forwardRef(
453
446
  ImageOverlaySelectedComponent,
454
447
  maxNumberOfFiles,
455
448
  numberOfAttachmentPickerImageColumns,
449
+ numberOfUploads: selectedFiles.length + selectedImages.length,
456
450
  selected:
457
451
  selectedImages.some((image) => image.uri === asset.uri) ||
458
452
  selectedFiles.some((file) => file.uri === asset.uri),
@@ -535,7 +529,7 @@ export const AttachmentPicker = React.forwardRef(
535
529
  keyExtractor={(item) => item.asset.uri}
536
530
  numColumns={numberOfAttachmentPickerImageColumns ?? 3}
537
531
  onEndReached={getMorePhotos}
538
- renderItem={renderImage}
532
+ renderItem={renderItem}
539
533
  />
540
534
  </BottomSheet>
541
535
  {selectedPicker === 'images' && photoError && (
@@ -13,7 +13,7 @@ import type { DefaultStreamChatGenerics } from '../../../types/types';
13
13
  /**
14
14
  * Disconnect the websocket connection when app goes to background,
15
15
  * and reconnect when app comes to foreground.
16
- * We do this to make sure, user receives push notifications when app is in the background.
16
+ * We do this to make sure the user receives push notifications when app is in the background.
17
17
  * You can't receive push notification until you have active websocket connection.
18
18
  */
19
19
  export const useIsOnline = <
@@ -25,10 +25,10 @@ export const useIsOnline = <
25
25
  const [isOnline, setIsOnline] = useState(true);
26
26
  const [connectionRecovering, setConnectionRecovering] = useState(false);
27
27
  const isMounted = useIsMountedRef();
28
- const clientExits = !!client;
28
+ const clientExists = !!client;
29
29
 
30
30
  const onBackground = useCallback(() => {
31
- if (!closeConnectionOnBackground) return;
31
+ if (!closeConnectionOnBackground || !clientExists) return;
32
32
 
33
33
  for (const cid in client.activeChannels) {
34
34
  const channel = client.activeChannels[cid];
@@ -37,13 +37,13 @@ export const useIsOnline = <
37
37
 
38
38
  client.closeConnection();
39
39
  setIsOnline(false);
40
- }, [closeConnectionOnBackground, client]);
40
+ }, [closeConnectionOnBackground, client, clientExists]);
41
41
 
42
42
  const onForeground = useCallback(() => {
43
- if (!closeConnectionOnBackground) return;
43
+ if (!closeConnectionOnBackground || !clientExists) return;
44
44
 
45
45
  client.openConnection();
46
- }, [closeConnectionOnBackground, client]);
46
+ }, [closeConnectionOnBackground, client, clientExists]);
47
47
 
48
48
  useAppStateListener(onForeground, onBackground);
49
49
 
@@ -101,7 +101,7 @@ export const useIsOnline = <
101
101
  chatListeners.forEach((listener) => listener.unsubscribe?.());
102
102
  unsubscribeNetInfo?.();
103
103
  };
104
- }, [clientExits]);
104
+ }, [clientExists]);
105
105
 
106
106
  return { connectionRecovering, isOnline };
107
107
  };
@@ -53,15 +53,13 @@ import {
53
53
  import type { MessageActionListItemProps } from '../MessageOverlay/MessageActionListItem';
54
54
 
55
55
  export type TouchableEmitter =
56
- | 'card'
57
56
  | 'fileAttachment'
58
57
  | 'gallery'
59
58
  | 'giphy'
60
59
  | 'message'
61
60
  | 'messageContent'
62
61
  | 'messageReplies'
63
- | 'reactionList'
64
- | 'textLink';
62
+ | 'reactionList';
65
63
 
66
64
  export type TextMentionTouchableHandlerPayload<
67
65
  StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
@@ -70,21 +68,27 @@ export type TextMentionTouchableHandlerPayload<
70
68
  additionalInfo?: { user?: UserResponse<StreamChatGenerics> };
71
69
  };
72
70
 
71
+ export type UrlTouchableHandlerPayload = {
72
+ emitter: 'textLink' | 'card';
73
+ additionalInfo?: { url?: string };
74
+ };
75
+
73
76
  export type TouchableHandlerPayload = {
74
77
  defaultHandler?: () => void;
75
78
  event?: GestureResponderEvent;
76
79
  } & (
77
80
  | {
78
- additionalInfo?: Record<string, unknown>;
79
81
  emitter?: TouchableEmitter;
80
82
  }
81
83
  | TextMentionTouchableHandlerPayload
84
+ | UrlTouchableHandlerPayload
82
85
  );
83
86
 
84
87
  export type MessageTouchableHandlerPayload<
85
88
  StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
86
89
  > = TouchableHandlerPayload & {
87
90
  actionHandlers?: MessageActionHandlers;
91
+ additionalInfo?: Record<string, unknown>;
88
92
  message?: MessageType<StreamChatGenerics>;
89
93
  };
90
94
 
@@ -161,10 +161,14 @@ export const renderText = <
161
161
  };
162
162
 
163
163
  const link: ReactNodeOutput = (node, output, { ...state }) => {
164
+ const url = node.target;
164
165
  const onPress = (event: GestureResponderEvent) => {
165
166
  if (!preventPress && onPressParam) {
166
167
  onPressParam({
167
- defaultHandler: () => onLink(node.target),
168
+ additionalInfo: { url },
169
+ defaultHandler: () => {
170
+ onLink(url);
171
+ },
168
172
  emitter: 'textLink',
169
173
  event,
170
174
  });
@@ -174,6 +178,7 @@ export const renderText = <
174
178
  const onLongPress = (event: GestureResponderEvent) => {
175
179
  if (!preventPress && onLongPressParam) {
176
180
  onLongPressParam({
181
+ additionalInfo: { url },
177
182
  emitter: 'textLink',
178
183
  event,
179
184
  });
@@ -203,7 +203,9 @@ const ReplyWithContext = <
203
203
  />
204
204
  ) : null
205
205
  ) : null}
206
- {messageType === 'video' ? <VideoThumbnail style={[styles.videoAttachment]} /> : null}
206
+ {messageType === 'video' && !lastAttachment.og_scrape_url ? (
207
+ <VideoThumbnail style={[styles.videoAttachment]} />
208
+ ) : null}
207
209
  <MessageTextContainer<StreamChatGenerics>
208
210
  markdownStyles={
209
211
  quotedMessage.deleted_at
@@ -447,7 +447,7 @@ export const MessageInputProvider = <
447
447
  }>({});
448
448
  const [giphyActive, setGiphyActive] = useState(false);
449
449
  const [sendThreadMessageInChannel, setSendThreadMessageInChannel] = useState(false);
450
- const { editing, hasFilePicker, hasImagePicker, initialValue, maxNumberOfFiles } = value;
450
+ const { editing, hasFilePicker, hasImagePicker, initialValue } = value;
451
451
  const {
452
452
  fileUploads,
453
453
  imageUploads,
@@ -536,7 +536,7 @@ export const MessageInputProvider = <
536
536
  };
537
537
 
538
538
  const openAttachmentPicker = () => {
539
- if (hasImagePicker && !fileUploads.length) {
539
+ if (hasImagePicker) {
540
540
  Keyboard.dismiss();
541
541
  openPicker();
542
542
  setSelectedPicker('images');
@@ -548,7 +548,7 @@ export const MessageInputProvider = <
548
548
  * https://github.com/gorhom/react-native-bottom-sheet/issues/446
549
549
  */
550
550
  setTimeout(openPicker, 600);
551
- } else if (hasFilePicker && numberOfUploads < maxNumberOfFiles) {
551
+ } else if (hasFilePicker) {
552
552
  pickFile();
553
553
  }
554
554
  };
@@ -572,6 +572,7 @@ export const MessageInputProvider = <
572
572
 
573
573
  const pickFile = async () => {
574
574
  if (numberOfUploads >= value.maxNumberOfFiles) {
575
+ Alert.alert('Maximum number of files reached');
575
576
  return;
576
577
  }
577
578
 
@@ -688,6 +689,15 @@ export const MessageInputProvider = <
688
689
  image_url: file.url,
689
690
  type: 'image',
690
691
  } as Attachment<StreamChatGenerics>);
692
+ } else if (file.file.type?.startsWith('audio/')) {
693
+ attachments.push({
694
+ asset_url: file.url,
695
+ duration: file.file.duration,
696
+ file_size: file.file.size,
697
+ mime_type: file.file.type,
698
+ title: file.file.name,
699
+ type: 'audio',
700
+ } as Attachment<StreamChatGenerics>);
691
701
  } else if (file.file.type?.startsWith('video/')) {
692
702
  attachments.push({
693
703
  asset_url: file.url,
package/src/version.json CHANGED
@@ -1,3 +1,3 @@
1
1
  {
2
- "version": "4.7.0-beta.2"
2
+ "version": "4.7.0-beta.5"
3
3
  }