stream-chat-react-native-core 4.7.0-beta.4 → 4.7.0

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 (71) hide show
  1. package/lib/commonjs/components/Attachment/Attachment.js +23 -13
  2. package/lib/commonjs/components/Attachment/Attachment.js.map +1 -1
  3. package/lib/commonjs/components/Attachment/Card.js +17 -24
  4. package/lib/commonjs/components/Attachment/Card.js.map +1 -1
  5. package/lib/commonjs/components/Attachment/FileAttachment.js +10 -17
  6. package/lib/commonjs/components/Attachment/FileAttachment.js.map +1 -1
  7. package/lib/commonjs/components/Attachment/Gallery.js +22 -10
  8. package/lib/commonjs/components/Attachment/Gallery.js.map +1 -1
  9. package/lib/commonjs/components/Attachment/utils/openUrlSafely.js +54 -0
  10. package/lib/commonjs/components/Attachment/utils/openUrlSafely.js.map +1 -0
  11. package/lib/commonjs/components/AttachmentPicker/AttachmentPicker.js +101 -57
  12. package/lib/commonjs/components/AttachmentPicker/AttachmentPicker.js.map +1 -1
  13. package/lib/commonjs/components/ImageGallery/ImageGallery.js +23 -22
  14. package/lib/commonjs/components/ImageGallery/ImageGallery.js.map +1 -1
  15. package/lib/commonjs/components/ImageGallery/components/AnimatedGalleryVideo.js +8 -8
  16. package/lib/commonjs/components/ImageGallery/components/AnimatedGalleryVideo.js.map +1 -1
  17. package/lib/commonjs/components/Message/Message.js +10 -7
  18. package/lib/commonjs/components/Message/Message.js.map +1 -1
  19. package/lib/commonjs/contexts/messageInputContext/MessageInputContext.js +12 -11
  20. package/lib/commonjs/contexts/messageInputContext/MessageInputContext.js.map +1 -1
  21. package/lib/commonjs/native.js +8 -2
  22. package/lib/commonjs/native.js.map +1 -1
  23. package/lib/commonjs/version.json +1 -1
  24. package/lib/module/components/Attachment/Attachment.js +23 -13
  25. package/lib/module/components/Attachment/Attachment.js.map +1 -1
  26. package/lib/module/components/Attachment/Card.js +17 -24
  27. package/lib/module/components/Attachment/Card.js.map +1 -1
  28. package/lib/module/components/Attachment/FileAttachment.js +10 -17
  29. package/lib/module/components/Attachment/FileAttachment.js.map +1 -1
  30. package/lib/module/components/Attachment/Gallery.js +22 -10
  31. package/lib/module/components/Attachment/Gallery.js.map +1 -1
  32. package/lib/module/components/Attachment/utils/openUrlSafely.js +54 -0
  33. package/lib/module/components/Attachment/utils/openUrlSafely.js.map +1 -0
  34. package/lib/module/components/AttachmentPicker/AttachmentPicker.js +101 -57
  35. package/lib/module/components/AttachmentPicker/AttachmentPicker.js.map +1 -1
  36. package/lib/module/components/ImageGallery/ImageGallery.js +23 -22
  37. package/lib/module/components/ImageGallery/ImageGallery.js.map +1 -1
  38. package/lib/module/components/ImageGallery/components/AnimatedGalleryVideo.js +8 -8
  39. package/lib/module/components/ImageGallery/components/AnimatedGalleryVideo.js.map +1 -1
  40. package/lib/module/components/Message/Message.js +10 -7
  41. package/lib/module/components/Message/Message.js.map +1 -1
  42. package/lib/module/contexts/messageInputContext/MessageInputContext.js +12 -11
  43. package/lib/module/contexts/messageInputContext/MessageInputContext.js.map +1 -1
  44. package/lib/module/native.js +8 -2
  45. package/lib/module/native.js.map +1 -1
  46. package/lib/module/version.json +1 -1
  47. package/lib/typescript/components/Attachment/__tests__/openUrlSafely.test.d.ts +1 -0
  48. package/lib/typescript/components/Attachment/utils/openUrlSafely.d.ts +1 -0
  49. package/lib/typescript/components/AttachmentPicker/AttachmentPicker.d.ts +11 -0
  50. package/lib/typescript/native.d.ts +1 -0
  51. package/package.json +1 -1
  52. package/src/components/Attachment/Attachment.tsx +4 -1
  53. package/src/components/Attachment/Card.tsx +2 -4
  54. package/src/components/Attachment/FileAttachment.tsx +2 -4
  55. package/src/components/Attachment/Gallery.tsx +17 -4
  56. package/src/components/Attachment/__tests__/Attachment.test.js +0 -39
  57. package/src/components/Attachment/__tests__/openUrlSafely.test.ts +48 -0
  58. package/src/components/Attachment/utils/openUrlSafely.ts +17 -0
  59. package/src/components/AttachmentPicker/AttachmentPicker.tsx +24 -28
  60. package/src/components/ImageGallery/ImageGallery.tsx +7 -3
  61. package/src/components/ImageGallery/components/AnimatedGalleryVideo.tsx +16 -13
  62. package/src/components/Message/Message.tsx +5 -2
  63. package/src/contexts/messageInputContext/MessageInputContext.tsx +4 -3
  64. package/src/native.ts +3 -1
  65. package/src/version.json +1 -1
  66. package/lib/commonjs/components/Attachment/hooks/useGoToURL.js +0 -42
  67. package/lib/commonjs/components/Attachment/hooks/useGoToURL.js.map +0 -1
  68. package/lib/module/components/Attachment/hooks/useGoToURL.js +0 -42
  69. package/lib/module/components/Attachment/hooks/useGoToURL.js.map +0 -1
  70. package/lib/typescript/components/Attachment/hooks/useGoToURL.d.ts +0 -2
  71. package/src/components/Attachment/hooks/useGoToURL.ts +0 -27
@@ -1,8 +1,5 @@
1
1
  import React from 'react';
2
2
 
3
- import { Linking } from 'react-native';
4
-
5
- import { act, renderHook } from '@testing-library/react-hooks';
6
3
  import { fireEvent, render, waitFor } from '@testing-library/react-native';
7
4
  import { v4 as uuidv4 } from 'uuid';
8
5
 
@@ -18,7 +15,6 @@ import {
18
15
  import { generateMessage } from '../../../mock-builders/generator/message';
19
16
  import { Attachment } from '../Attachment';
20
17
  import { AttachmentActions } from '../AttachmentActions';
21
- import { useGoToURL } from '../hooks/useGoToURL';
22
18
 
23
19
  const getAttachmentComponent = (props) => {
24
20
  const message = generateMessage();
@@ -124,39 +120,4 @@ describe('Attachment', () => {
124
120
  expect(getByTestId('card-attachment')).toBeTruthy();
125
121
  });
126
122
  });
127
-
128
- it('should open the URL in the browser', async () => {
129
- jest.spyOn(Linking, 'canOpenURL').mockImplementation(jest.fn().mockResolvedValue(true));
130
-
131
- jest.spyOn(Linking, 'openURL').mockImplementation(jest.fn().mockResolvedValue(false));
132
-
133
- const { result, waitFor } = renderHook(() => useGoToURL('www.google.com'));
134
-
135
- const [error, openURL] = result.current;
136
-
137
- await act(openURL);
138
-
139
- await waitFor(() => {
140
- expect(Linking.canOpenURL).toHaveBeenCalled();
141
- expect(error).not.toBeTruthy();
142
- expect(Linking.openURL).toHaveBeenCalled();
143
- });
144
- });
145
-
146
- it('should open the URL in the browser when no url', async () => {
147
- jest.spyOn(Linking, 'canOpenURL').mockImplementation(jest.fn().mockResolvedValue(false));
148
-
149
- jest.spyOn(Linking, 'openURL').mockImplementation(jest.fn().mockResolvedValue(true));
150
-
151
- const { result, waitForNextUpdate } = await renderHook(() => useGoToURL());
152
- const [error, openURL] = result.current;
153
-
154
- act(openURL);
155
-
156
- await waitForNextUpdate(() => {
157
- expect(Linking.canOpenURL).toHaveBeenCalled();
158
- expect(error).toBeTruthy();
159
- expect(Linking.openURL).not.toHaveBeenCalled();
160
- });
161
- });
162
123
  });
@@ -0,0 +1,48 @@
1
+ import { Linking } from 'react-native';
2
+
3
+ import { waitFor } from '@testing-library/react-native';
4
+
5
+ import { openUrlSafely } from '../utils/openUrlSafely';
6
+
7
+ describe('openUrlSafely', () => {
8
+ afterEach(() => {
9
+ jest.clearAllMocks();
10
+ });
11
+
12
+ it('should open a valid url', async () => {
13
+ jest.spyOn(Linking, 'canOpenURL').mockImplementation(jest.fn().mockResolvedValue(true));
14
+ jest.spyOn(Linking, 'openURL').mockImplementation(jest.fn());
15
+
16
+ const url = 'https://www.google.com';
17
+ await openUrlSafely(url);
18
+ await waitFor(() => {
19
+ expect(Linking.canOpenURL).toHaveBeenCalled();
20
+ expect(Linking.openURL).toHaveBeenCalled();
21
+ });
22
+ });
23
+
24
+ it('should not call openUrl if url is not supported', async () => {
25
+ jest.spyOn(Linking, 'canOpenURL').mockImplementation(jest.fn().mockResolvedValue(false));
26
+ jest.spyOn(Linking, 'openURL').mockImplementation(jest.fn());
27
+
28
+ Linking.openURL = jest.fn();
29
+ const url = 'basjkdbkjasbdkjabskdjabsjkdbasjkda---asdkjasjkdabsk';
30
+ await openUrlSafely(url);
31
+ await waitFor(() => {
32
+ expect(Linking.canOpenURL).toHaveBeenCalled();
33
+ expect(Linking.openURL).not.toHaveBeenCalled();
34
+ });
35
+ });
36
+
37
+ it('should append http if missing', async () => {
38
+ jest.spyOn(Linking, 'canOpenURL').mockImplementation(jest.fn());
39
+ jest.spyOn(Linking, 'openURL').mockImplementation(jest.fn());
40
+
41
+ Linking.openURL = jest.fn();
42
+ const url = 'google.com';
43
+ await openUrlSafely(url);
44
+ await waitFor(() => {
45
+ expect(Linking.canOpenURL).toHaveBeenCalledWith('http://google.com');
46
+ });
47
+ });
48
+ });
@@ -0,0 +1,17 @@
1
+ import { Linking } from 'react-native';
2
+
3
+ export const openUrlSafely = async (url?: string) => {
4
+ let finalUrl = url as string;
5
+ const pattern = new RegExp(/^\S+:\/\//);
6
+
7
+ if (!pattern.test(finalUrl)) {
8
+ finalUrl = 'http://' + url;
9
+ }
10
+ const supported = await Linking.canOpenURL(finalUrl);
11
+
12
+ if (supported) {
13
+ Linking.openURL(finalUrl);
14
+ } else {
15
+ console.warn(`Don't know how to open URI: ${finalUrl}`);
16
+ }
17
+ };
@@ -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,
@@ -25,7 +26,7 @@ import type { AttachmentPickerErrorProps } from './components/AttachmentPickerEr
25
26
  import { useAttachmentPickerContext } from '../../contexts/attachmentPickerContext/AttachmentPickerContext';
26
27
  import { useTheme } from '../../contexts/themeContext/ThemeContext';
27
28
  import { Recorder } from '../../icons';
28
- import { getPhotos } from '../../native';
29
+ import { getLocalAssetUri, getPhotos } from '../../native';
29
30
  import type { Asset, File } from '../../types/types';
30
31
  import { vh, vw } from '../../utils/utils';
31
32
 
@@ -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;
@@ -110,12 +109,15 @@ const AttachmentVideo: React.FC<AttachmentVideoProps> = (props) => {
110
109
 
111
110
  const size = vw(100) / (numberOfAttachmentPickerImageColumns || 3) - 2;
112
111
 
113
- const onPressVideo = () => {
112
+ const onPressVideo = async () => {
113
+ // For the case of expo messaging app where you need to fetch the asset uri from asset id
114
+ const localAssetURI = asset.id && (await getLocalAssetUri(asset.id));
114
115
  if (selected) {
115
116
  setSelectedFiles((files) => files.filter((file) => file.uri !== asset.uri));
116
117
  } else {
117
118
  setSelectedFiles((files) => {
118
- if (files.length >= maxNumberOfFiles) {
119
+ if (numberOfUploads >= maxNumberOfFiles) {
120
+ Alert.alert('Maximum number of files reached');
119
121
  return files;
120
122
  }
121
123
  return [
@@ -125,7 +127,7 @@ const AttachmentVideo: React.FC<AttachmentVideoProps> = (props) => {
125
127
  name: asset.filename,
126
128
  size: asset.fileSize,
127
129
  type: 'video',
128
- uri: asset.uri,
130
+ uri: localAssetURI || asset.uri,
129
131
  },
130
132
  ];
131
133
  });
@@ -169,6 +171,7 @@ const AttachmentImage: React.FC<AttachmentImageProps> = (props) => {
169
171
  ImageOverlaySelectedComponent,
170
172
  maxNumberOfFiles,
171
173
  numberOfAttachmentPickerImageColumns,
174
+ numberOfUploads,
172
175
  selected,
173
176
  setSelectedImages,
174
177
  } = props;
@@ -188,7 +191,8 @@ const AttachmentImage: React.FC<AttachmentImageProps> = (props) => {
188
191
  setSelectedImages((images) => images.filter((image) => image.uri !== asset.uri));
189
192
  } else {
190
193
  setSelectedImages((images) => {
191
- if (images.length >= maxNumberOfFiles) {
194
+ if (numberOfUploads >= maxNumberOfFiles) {
195
+ Alert.alert('Maximum number of files reached');
192
196
  return images;
193
197
  }
194
198
  return [...images, asset];
@@ -219,24 +223,13 @@ const AttachmentImage: React.FC<AttachmentImageProps> = (props) => {
219
223
  );
220
224
  };
221
225
 
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
- }) => {
226
+ const renderItem = ({ item }: { item: AttachmentPickerItemType }) => {
235
227
  const {
236
228
  asset,
237
229
  ImageOverlaySelectedComponent,
238
230
  maxNumberOfFiles,
239
231
  numberOfAttachmentPickerImageColumns,
232
+ numberOfUploads,
240
233
  selected,
241
234
  setSelectedFiles,
242
235
  setSelectedImages,
@@ -258,6 +251,7 @@ const renderImage = ({
258
251
  ImageOverlaySelectedComponent={ImageOverlaySelectedComponent}
259
252
  maxNumberOfFiles={maxNumberOfFiles}
260
253
  numberOfAttachmentPickerImageColumns={numberOfAttachmentPickerImageColumns}
254
+ numberOfUploads={numberOfUploads}
261
255
  selected={selected}
262
256
  setSelectedImages={setSelectedImages}
263
257
  />
@@ -267,6 +261,7 @@ const renderImage = ({
267
261
  ImageOverlaySelectedComponent={ImageOverlaySelectedComponent}
268
262
  maxNumberOfFiles={maxNumberOfFiles}
269
263
  numberOfAttachmentPickerImageColumns={numberOfAttachmentPickerImageColumns}
264
+ numberOfUploads={numberOfUploads}
270
265
  selected={selected}
271
266
  setSelectedFiles={setSelectedFiles}
272
267
  />
@@ -453,6 +448,7 @@ export const AttachmentPicker = React.forwardRef(
453
448
  ImageOverlaySelectedComponent,
454
449
  maxNumberOfFiles,
455
450
  numberOfAttachmentPickerImageColumns,
451
+ numberOfUploads: selectedFiles.length + selectedImages.length,
456
452
  selected:
457
453
  selectedImages.some((image) => image.uri === asset.uri) ||
458
454
  selectedFiles.some((file) => file.uri === asset.uri),
@@ -535,7 +531,7 @@ export const AttachmentPicker = React.forwardRef(
535
531
  keyExtractor={(item) => item.asset.uri}
536
532
  numColumns={numberOfAttachmentPickerImageColumns ?? 3}
537
533
  onEndReached={getMorePhotos}
538
- renderItem={renderImage}
534
+ renderItem={renderItem}
539
535
  />
540
536
  </BottomSheet>
541
537
  {selectedPicker === 'images' && photoError && (
@@ -55,7 +55,12 @@ import {
55
55
  useOverlayContext,
56
56
  } from '../../contexts/overlayContext/OverlayContext';
57
57
  import { useTheme } from '../../contexts/themeContext/ThemeContext';
58
- import type { VideoPayloadData, VideoProgressData, VideoType } from '../../native';
58
+ import {
59
+ isVideoPackageAvailable,
60
+ VideoPayloadData,
61
+ VideoProgressData,
62
+ VideoType,
63
+ } from '../../native';
59
64
  import type { DefaultStreamChatGenerics } from '../../types/types';
60
65
  import { getResizedImageUrl } from '../../utils/getResizedImageUrl';
61
66
  import { getUrlOfImageAttachment } from '../../utils/getUrlOfImageAttachment';
@@ -252,7 +257,6 @@ export const ImageGallery = <
252
257
  */
253
258
 
254
259
  const photos = images.reduce((acc: Photo<StreamChatGenerics>[], cur) => {
255
- console.log(cur);
256
260
  const attachmentImages =
257
261
  cur.attachments?.filter(
258
262
  (attachment) =>
@@ -264,7 +268,7 @@ export const ImageGallery = <
264
268
  !attachment.title_link &&
265
269
  !attachment.og_scrape_url &&
266
270
  getUrlOfImageAttachment(attachment)) ||
267
- attachment.type === 'video',
271
+ (isVideoPackageAvailable() && attachment.type === 'video'),
268
272
  ) || [];
269
273
 
270
274
  const attachmentPhotos = attachmentImages.map((a) => {
@@ -4,6 +4,7 @@ import type { StyleProp } from 'react-native';
4
4
  import Animated, { useAnimatedStyle } from 'react-native-reanimated';
5
5
 
6
6
  import {
7
+ isVideoPackageAvailable,
7
8
  PlaybackStatus,
8
9
  Video,
9
10
  VideoPayloadData,
@@ -173,19 +174,21 @@ export const AnimatedGalleryVideo: React.FC<Props> = React.memo(
173
174
  },
174
175
  ]}
175
176
  >
176
- <Video
177
- onBuffer={onBuffer}
178
- onEnd={onEnd}
179
- onLoad={onLoad}
180
- onLoadStart={onLoadStart}
181
- onPlaybackStatusUpdate={onPlayBackStatusUpdate}
182
- onProgress={onProgress}
183
- paused={paused}
184
- resizeMode='cover'
185
- style={style}
186
- uri={source.uri}
187
- videoRef={videoRef}
188
- />
177
+ {isVideoPackageAvailable() && (
178
+ <Video
179
+ onBuffer={onBuffer}
180
+ onEnd={onEnd}
181
+ onLoad={onLoad}
182
+ onLoadStart={onLoadStart}
183
+ onPlaybackStatusUpdate={onPlayBackStatusUpdate}
184
+ onProgress={onProgress}
185
+ paused={paused}
186
+ resizeMode='contain'
187
+ style={style}
188
+ uri={source.uri}
189
+ videoRef={videoRef}
190
+ />
191
+ )}
189
192
  <Animated.View
190
193
  style={[
191
194
  styles.activityIndicator,
@@ -42,7 +42,7 @@ import {
42
42
  useTranslationContext,
43
43
  } from '../../contexts/translationContext/TranslationContext';
44
44
 
45
- import { triggerHaptic } from '../../native';
45
+ import { isVideoPackageAvailable, triggerHaptic } from '../../native';
46
46
  import type { DefaultStreamChatGenerics } from '../../types/types';
47
47
  import { emojiRegex, MessageStatusTypes } from '../../utils/utils';
48
48
 
@@ -332,9 +332,12 @@ const MessageWithContext = <
332
332
  if (cur.type === 'file') {
333
333
  acc.files.push(cur);
334
334
  acc.other = []; // remove other attachments if a file exists
335
- } else if (cur.type === 'video' && !cur.og_scrape_url) {
335
+ } else if (cur.type === 'video' && !cur.og_scrape_url && isVideoPackageAvailable()) {
336
336
  acc.videos.push({ image_url: cur.asset_url, type: 'video' });
337
337
  acc.other = [];
338
+ } else if (cur.type === 'video' && !cur.og_scrape_url) {
339
+ acc.files.push(cur);
340
+ acc.other = []; // remove other attachments if a file exists
338
341
  } else if (cur.type === 'image' && !cur.title_link && !cur.og_scrape_url) {
339
342
  /**
340
343
  * this next if is not combined with the above one for cases where we have
@@ -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
 
package/src/native.ts CHANGED
@@ -145,7 +145,7 @@ export type VideoType = {
145
145
  style?: StyleProp<ViewStyle>;
146
146
  };
147
147
 
148
- export let Video: React.ComponentType<VideoType> = fail;
148
+ export let Video: React.ComponentType<VideoType>;
149
149
 
150
150
  type Handlers = {
151
151
  compressImage?: CompressImage;
@@ -219,3 +219,5 @@ export const registerNativeHandlers = (handlers: Handlers) => {
219
219
  Video = handlers.Video;
220
220
  }
221
221
  };
222
+
223
+ export const isVideoPackageAvailable = () => !!Video;
package/src/version.json CHANGED
@@ -1,3 +1,3 @@
1
1
  {
2
- "version": "4.7.0-beta.4"
2
+ "version": "4.7.0"
3
3
  }
@@ -1,42 +0,0 @@
1
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.useGoToURL = void 0;
7
-
8
- var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
9
-
10
- var _react = require("react");
11
-
12
- var _reactNative = require("react-native");
13
-
14
- var useGoToURL = function useGoToURL(url) {
15
- var _useState = (0, _react.useState)(false),
16
- _useState2 = (0, _slicedToArray2["default"])(_useState, 2),
17
- error = _useState2[0],
18
- setError = _useState2[1];
19
-
20
- var finalUrl = url;
21
- var pattern = new RegExp(/^\S+:\/\//);
22
-
23
- if (!pattern.test(finalUrl)) {
24
- finalUrl = 'http://' + url;
25
- }
26
-
27
- var openURL = function openURL() {
28
- return _reactNative.Linking.canOpenURL(finalUrl).then(function (supported) {
29
- if (supported) {
30
- _reactNative.Linking.openURL(finalUrl);
31
- } else {
32
- setError(true);
33
- console.warn("Don't know how to open URI: " + finalUrl);
34
- }
35
- });
36
- };
37
-
38
- return [error, openURL];
39
- };
40
-
41
- exports.useGoToURL = useGoToURL;
42
- //# sourceMappingURL=useGoToURL.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["useGoToURL.ts"],"names":["useGoToURL","url","error","setError","finalUrl","pattern","RegExp","test","openURL","Linking","canOpenURL","then","supported","console","warn"],"mappings":";;;;;;;;;AAAA;;AACA;;AAIO,IAAMA,UAA0B,GAAG,SAA7BA,UAA6B,CAACC,GAAD,EAAkB;AAC1D,kBAA0B,qBAAkB,KAAlB,CAA1B;AAAA;AAAA,MAAOC,KAAP;AAAA,MAAcC,QAAd;;AAEA,MAAIC,QAAQ,GAAGH,GAAf;AACA,MAAMI,OAAO,GAAG,IAAIC,MAAJ,CAAW,WAAX,CAAhB;;AAEA,MAAI,CAACD,OAAO,CAACE,IAAR,CAAaH,QAAb,CAAL,EAA6B;AAC3BA,IAAAA,QAAQ,GAAG,YAAYH,GAAvB;AACD;;AAED,MAAMO,OAAO,GAAG,SAAVA,OAAU;AAAA,WACdC,qBAAQC,UAAR,CAAmBN,QAAnB,EAA6BO,IAA7B,CAAkC,UAACC,SAAD,EAAe;AAC/C,UAAIA,SAAJ,EAAe;AACbH,6BAAQD,OAAR,CAAgBJ,QAAhB;AACD,OAFD,MAEO;AACLD,QAAAA,QAAQ,CAAC,IAAD,CAAR;AACAU,QAAAA,OAAO,CAACC,IAAR,kCAA4CV,QAA5C;AACD;AACF,KAPD,CADc;AAAA,GAAhB;;AAUA,SAAO,CAACF,KAAD,EAAQM,OAAR,CAAP;AACD,CArBM","sourcesContent":["import { useState } from 'react';\nimport { Linking } from 'react-native';\n\nexport type UseGoToURLType = (url?: string) => [boolean, () => Promise<void>];\n\nexport const useGoToURL: UseGoToURLType = (url?: string) => {\n const [error, setError] = useState<boolean>(false);\n\n let finalUrl = url as string;\n const pattern = new RegExp(/^\\S+:\\/\\//);\n\n if (!pattern.test(finalUrl)) {\n finalUrl = 'http://' + url;\n }\n\n const openURL = () =>\n Linking.canOpenURL(finalUrl).then((supported) => {\n if (supported) {\n Linking.openURL(finalUrl);\n } else {\n setError(true);\n console.warn(`Don't know how to open URI: ${finalUrl}`);\n }\n });\n\n return [error, openURL];\n};\n"]}
@@ -1,42 +0,0 @@
1
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.useGoToURL = void 0;
7
-
8
- var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
9
-
10
- var _react = require("react");
11
-
12
- var _reactNative = require("react-native");
13
-
14
- var useGoToURL = function useGoToURL(url) {
15
- var _useState = (0, _react.useState)(false),
16
- _useState2 = (0, _slicedToArray2["default"])(_useState, 2),
17
- error = _useState2[0],
18
- setError = _useState2[1];
19
-
20
- var finalUrl = url;
21
- var pattern = new RegExp(/^\S+:\/\//);
22
-
23
- if (!pattern.test(finalUrl)) {
24
- finalUrl = 'http://' + url;
25
- }
26
-
27
- var openURL = function openURL() {
28
- return _reactNative.Linking.canOpenURL(finalUrl).then(function (supported) {
29
- if (supported) {
30
- _reactNative.Linking.openURL(finalUrl);
31
- } else {
32
- setError(true);
33
- console.warn("Don't know how to open URI: " + finalUrl);
34
- }
35
- });
36
- };
37
-
38
- return [error, openURL];
39
- };
40
-
41
- exports.useGoToURL = useGoToURL;
42
- //# sourceMappingURL=useGoToURL.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["useGoToURL.ts"],"names":["useGoToURL","url","error","setError","finalUrl","pattern","RegExp","test","openURL","Linking","canOpenURL","then","supported","console","warn"],"mappings":";;;;;;;;;AAAA;;AACA;;AAIO,IAAMA,UAA0B,GAAG,SAA7BA,UAA6B,CAACC,GAAD,EAAkB;AAC1D,kBAA0B,qBAAkB,KAAlB,CAA1B;AAAA;AAAA,MAAOC,KAAP;AAAA,MAAcC,QAAd;;AAEA,MAAIC,QAAQ,GAAGH,GAAf;AACA,MAAMI,OAAO,GAAG,IAAIC,MAAJ,CAAW,WAAX,CAAhB;;AAEA,MAAI,CAACD,OAAO,CAACE,IAAR,CAAaH,QAAb,CAAL,EAA6B;AAC3BA,IAAAA,QAAQ,GAAG,YAAYH,GAAvB;AACD;;AAED,MAAMO,OAAO,GAAG,SAAVA,OAAU;AAAA,WACdC,qBAAQC,UAAR,CAAmBN,QAAnB,EAA6BO,IAA7B,CAAkC,UAACC,SAAD,EAAe;AAC/C,UAAIA,SAAJ,EAAe;AACbH,6BAAQD,OAAR,CAAgBJ,QAAhB;AACD,OAFD,MAEO;AACLD,QAAAA,QAAQ,CAAC,IAAD,CAAR;AACAU,QAAAA,OAAO,CAACC,IAAR,kCAA4CV,QAA5C;AACD;AACF,KAPD,CADc;AAAA,GAAhB;;AAUA,SAAO,CAACF,KAAD,EAAQM,OAAR,CAAP;AACD,CArBM","sourcesContent":["import { useState } from 'react';\nimport { Linking } from 'react-native';\n\nexport type UseGoToURLType = (url?: string) => [boolean, () => Promise<void>];\n\nexport const useGoToURL: UseGoToURLType = (url?: string) => {\n const [error, setError] = useState<boolean>(false);\n\n let finalUrl = url as string;\n const pattern = new RegExp(/^\\S+:\\/\\//);\n\n if (!pattern.test(finalUrl)) {\n finalUrl = 'http://' + url;\n }\n\n const openURL = () =>\n Linking.canOpenURL(finalUrl).then((supported) => {\n if (supported) {\n Linking.openURL(finalUrl);\n } else {\n setError(true);\n console.warn(`Don't know how to open URI: ${finalUrl}`);\n }\n });\n\n return [error, openURL];\n};\n"]}
@@ -1,2 +0,0 @@
1
- export declare type UseGoToURLType = (url?: string) => [boolean, () => Promise<void>];
2
- export declare const useGoToURL: UseGoToURLType;
@@ -1,27 +0,0 @@
1
- import { useState } from 'react';
2
- import { Linking } from 'react-native';
3
-
4
- export type UseGoToURLType = (url?: string) => [boolean, () => Promise<void>];
5
-
6
- export const useGoToURL: UseGoToURLType = (url?: string) => {
7
- const [error, setError] = useState<boolean>(false);
8
-
9
- let finalUrl = url as string;
10
- const pattern = new RegExp(/^\S+:\/\//);
11
-
12
- if (!pattern.test(finalUrl)) {
13
- finalUrl = 'http://' + url;
14
- }
15
-
16
- const openURL = () =>
17
- Linking.canOpenURL(finalUrl).then((supported) => {
18
- if (supported) {
19
- Linking.openURL(finalUrl);
20
- } else {
21
- setError(true);
22
- console.warn(`Don't know how to open URI: ${finalUrl}`);
23
- }
24
- });
25
-
26
- return [error, openURL];
27
- };