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.
- package/lib/commonjs/components/Attachment/Attachment.js +23 -13
- package/lib/commonjs/components/Attachment/Attachment.js.map +1 -1
- package/lib/commonjs/components/Attachment/Card.js +17 -24
- package/lib/commonjs/components/Attachment/Card.js.map +1 -1
- package/lib/commonjs/components/Attachment/FileAttachment.js +10 -17
- package/lib/commonjs/components/Attachment/FileAttachment.js.map +1 -1
- package/lib/commonjs/components/Attachment/Gallery.js +22 -10
- package/lib/commonjs/components/Attachment/Gallery.js.map +1 -1
- package/lib/commonjs/components/Attachment/utils/openUrlSafely.js +54 -0
- package/lib/commonjs/components/Attachment/utils/openUrlSafely.js.map +1 -0
- package/lib/commonjs/components/AttachmentPicker/AttachmentPicker.js +101 -57
- package/lib/commonjs/components/AttachmentPicker/AttachmentPicker.js.map +1 -1
- package/lib/commonjs/components/ImageGallery/ImageGallery.js +23 -22
- package/lib/commonjs/components/ImageGallery/ImageGallery.js.map +1 -1
- package/lib/commonjs/components/ImageGallery/components/AnimatedGalleryVideo.js +8 -8
- package/lib/commonjs/components/ImageGallery/components/AnimatedGalleryVideo.js.map +1 -1
- package/lib/commonjs/components/Message/Message.js +10 -7
- package/lib/commonjs/components/Message/Message.js.map +1 -1
- package/lib/commonjs/contexts/messageInputContext/MessageInputContext.js +12 -11
- package/lib/commonjs/contexts/messageInputContext/MessageInputContext.js.map +1 -1
- package/lib/commonjs/native.js +8 -2
- package/lib/commonjs/native.js.map +1 -1
- package/lib/commonjs/version.json +1 -1
- package/lib/module/components/Attachment/Attachment.js +23 -13
- package/lib/module/components/Attachment/Attachment.js.map +1 -1
- package/lib/module/components/Attachment/Card.js +17 -24
- package/lib/module/components/Attachment/Card.js.map +1 -1
- package/lib/module/components/Attachment/FileAttachment.js +10 -17
- package/lib/module/components/Attachment/FileAttachment.js.map +1 -1
- package/lib/module/components/Attachment/Gallery.js +22 -10
- package/lib/module/components/Attachment/Gallery.js.map +1 -1
- package/lib/module/components/Attachment/utils/openUrlSafely.js +54 -0
- package/lib/module/components/Attachment/utils/openUrlSafely.js.map +1 -0
- package/lib/module/components/AttachmentPicker/AttachmentPicker.js +101 -57
- package/lib/module/components/AttachmentPicker/AttachmentPicker.js.map +1 -1
- package/lib/module/components/ImageGallery/ImageGallery.js +23 -22
- package/lib/module/components/ImageGallery/ImageGallery.js.map +1 -1
- package/lib/module/components/ImageGallery/components/AnimatedGalleryVideo.js +8 -8
- package/lib/module/components/ImageGallery/components/AnimatedGalleryVideo.js.map +1 -1
- package/lib/module/components/Message/Message.js +10 -7
- package/lib/module/components/Message/Message.js.map +1 -1
- package/lib/module/contexts/messageInputContext/MessageInputContext.js +12 -11
- package/lib/module/contexts/messageInputContext/MessageInputContext.js.map +1 -1
- package/lib/module/native.js +8 -2
- package/lib/module/native.js.map +1 -1
- package/lib/module/version.json +1 -1
- package/lib/typescript/components/Attachment/__tests__/openUrlSafely.test.d.ts +1 -0
- package/lib/typescript/components/Attachment/utils/openUrlSafely.d.ts +1 -0
- package/lib/typescript/components/AttachmentPicker/AttachmentPicker.d.ts +11 -0
- package/lib/typescript/native.d.ts +1 -0
- package/package.json +1 -1
- package/src/components/Attachment/Attachment.tsx +4 -1
- package/src/components/Attachment/Card.tsx +2 -4
- package/src/components/Attachment/FileAttachment.tsx +2 -4
- package/src/components/Attachment/Gallery.tsx +17 -4
- package/src/components/Attachment/__tests__/Attachment.test.js +0 -39
- package/src/components/Attachment/__tests__/openUrlSafely.test.ts +48 -0
- package/src/components/Attachment/utils/openUrlSafely.ts +17 -0
- package/src/components/AttachmentPicker/AttachmentPicker.tsx +24 -28
- package/src/components/ImageGallery/ImageGallery.tsx +7 -3
- package/src/components/ImageGallery/components/AnimatedGalleryVideo.tsx +16 -13
- package/src/components/Message/Message.tsx +5 -2
- package/src/contexts/messageInputContext/MessageInputContext.tsx +4 -3
- package/src/native.ts +3 -1
- package/src/version.json +1 -1
- package/lib/commonjs/components/Attachment/hooks/useGoToURL.js +0 -42
- package/lib/commonjs/components/Attachment/hooks/useGoToURL.js.map +0 -1
- package/lib/module/components/Attachment/hooks/useGoToURL.js +0 -42
- package/lib/module/components/Attachment/hooks/useGoToURL.js.map +0 -1
- package/lib/typescript/components/Attachment/hooks/useGoToURL.d.ts +0 -2
- 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
|
|
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
|
|
69
|
-
|
|
70
|
-
|
|
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 (
|
|
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 (
|
|
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
|
|
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={
|
|
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
|
|
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
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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,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,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
|
-
};
|