stream-chat-react-native-core 4.9.0-beta.3 → 4.9.0-beta.4
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/Gallery.js +11 -9
- package/lib/commonjs/components/Attachment/Gallery.js.map +1 -1
- package/lib/commonjs/components/Attachment/VideoThumbnail.js +11 -5
- package/lib/commonjs/components/Attachment/VideoThumbnail.js.map +1 -1
- package/lib/commonjs/components/Attachment/utils/buildGallery/buildThumbnail.js +1 -0
- package/lib/commonjs/components/Attachment/utils/buildGallery/buildThumbnail.js.map +1 -1
- package/lib/commonjs/components/Message/Message.js +7 -6
- package/lib/commonjs/components/Message/Message.js.map +1 -1
- package/lib/commonjs/contexts/messageInputContext/MessageInputContext.js +20 -27
- package/lib/commonjs/contexts/messageInputContext/MessageInputContext.js.map +1 -1
- package/lib/commonjs/mock-builders/generator/attachment.js +3 -2
- package/lib/commonjs/mock-builders/generator/attachment.js.map +1 -1
- package/lib/commonjs/utils/getUrlOfImageAttachment.js +1 -1
- package/lib/commonjs/utils/getUrlOfImageAttachment.js.map +1 -1
- package/lib/commonjs/version.json +1 -1
- package/lib/module/components/Attachment/Gallery.js +11 -9
- package/lib/module/components/Attachment/Gallery.js.map +1 -1
- package/lib/module/components/Attachment/VideoThumbnail.js +11 -5
- package/lib/module/components/Attachment/VideoThumbnail.js.map +1 -1
- package/lib/module/components/Attachment/utils/buildGallery/buildThumbnail.js +1 -0
- package/lib/module/components/Attachment/utils/buildGallery/buildThumbnail.js.map +1 -1
- package/lib/module/components/Message/Message.js +7 -6
- package/lib/module/components/Message/Message.js.map +1 -1
- package/lib/module/contexts/messageInputContext/MessageInputContext.js +20 -27
- package/lib/module/contexts/messageInputContext/MessageInputContext.js.map +1 -1
- package/lib/module/mock-builders/generator/attachment.js +3 -2
- package/lib/module/mock-builders/generator/attachment.js.map +1 -1
- package/lib/module/utils/getUrlOfImageAttachment.js +1 -1
- package/lib/module/utils/getUrlOfImageAttachment.js.map +1 -1
- package/lib/module/version.json +1 -1
- package/lib/typescript/components/Attachment/VideoThumbnail.d.ts +3 -1
- package/lib/typescript/components/Attachment/utils/buildGallery/types.d.ts +1 -0
- package/lib/typescript/contexts/messageInputContext/MessageInputContext.d.ts +1 -0
- package/lib/typescript/contexts/messageInputContext/__tests__/MessageInputContext.test.d.ts +1 -0
- package/lib/typescript/contexts/messageInputContext/__tests__/isValidMessage.test.d.ts +1 -0
- package/lib/typescript/contexts/messageInputContext/__tests__/pickFile.test.d.ts +1 -0
- package/lib/typescript/contexts/messageInputContext/__tests__/removeFile.test.d.ts +1 -0
- package/lib/typescript/contexts/messageInputContext/__tests__/removeImage.test.d.ts +1 -0
- package/lib/typescript/contexts/messageInputContext/__tests__/sendMessage.test.d.ts +1 -0
- package/lib/typescript/contexts/messageInputContext/__tests__/sendMessageAsync.test.d.ts +1 -0
- package/lib/typescript/contexts/messageInputContext/__tests__/updateMessage.test.d.ts +1 -0
- package/lib/typescript/contexts/messageInputContext/__tests__/uploadFile.test.d.ts +1 -0
- package/lib/typescript/contexts/messageInputContext/__tests__/uploadImage.test.d.ts +1 -0
- package/lib/typescript/contexts/messageInputContext/__tests__/useMessageDetailsForState.test.d.ts +1 -0
- package/lib/typescript/mock-builders/generator/attachment.d.ts +10 -0
- package/lib/typescript/mock-builders/generator/channel.d.ts +13 -13
- package/lib/typescript/mock-builders/generator/message.d.ts +38 -0
- package/lib/typescript/mock-builders/generator/user.d.ts +9 -9
- package/package.json +5 -4
- package/src/components/Attachment/Gallery.tsx +2 -1
- package/src/components/Attachment/VideoThumbnail.tsx +12 -5
- package/src/components/Attachment/__tests__/Attachment.test.js +12 -0
- package/src/components/Attachment/__tests__/Gallery.test.js +23 -1
- package/src/components/Attachment/utils/buildGallery/buildThumbnail.ts +1 -0
- package/src/components/Attachment/utils/buildGallery/types.ts +1 -0
- package/src/components/Message/Message.tsx +5 -1
- package/src/contexts/messageInputContext/MessageInputContext.tsx +3 -4
- package/src/contexts/messageInputContext/__tests__/MessageInputContext.test.tsx +208 -0
- package/src/contexts/messageInputContext/__tests__/__snapshots__/sendMessage.test.tsx.snap +109 -0
- package/src/contexts/messageInputContext/__tests__/__snapshots__/sendMessageAsync.test.tsx.snap +33 -0
- package/src/contexts/messageInputContext/__tests__/isValidMessage.test.tsx +71 -0
- package/src/contexts/messageInputContext/__tests__/pickFile.test.tsx +67 -0
- package/src/contexts/messageInputContext/__tests__/removeFile.test.tsx +82 -0
- package/src/contexts/messageInputContext/__tests__/removeImage.test.tsx +80 -0
- package/src/contexts/messageInputContext/__tests__/sendMessage.test.tsx +286 -0
- package/src/contexts/messageInputContext/__tests__/sendMessageAsync.test.tsx +124 -0
- package/src/contexts/messageInputContext/__tests__/updateMessage.test.tsx +92 -0
- package/src/contexts/messageInputContext/__tests__/uploadFile.test.tsx +76 -0
- package/src/contexts/messageInputContext/__tests__/uploadImage.test.tsx +55 -0
- package/src/contexts/messageInputContext/__tests__/useMessageDetailsForState.test.tsx +62 -0
- package/src/mock-builders/generator/attachment.js +4 -2
- package/src/utils/getUrlOfImageAttachment.ts +1 -1
- package/src/version.json +1 -1
|
@@ -31,20 +31,20 @@ export function generateChannel(customValues: any): {
|
|
|
31
31
|
created_by: {
|
|
32
32
|
banned: boolean;
|
|
33
33
|
created_at: string;
|
|
34
|
-
id:
|
|
35
|
-
image:
|
|
36
|
-
name:
|
|
34
|
+
id: string;
|
|
35
|
+
image: string;
|
|
36
|
+
name: string;
|
|
37
37
|
online: boolean;
|
|
38
38
|
role: string;
|
|
39
39
|
updated_at: string;
|
|
40
40
|
};
|
|
41
41
|
frozen: boolean;
|
|
42
|
-
id:
|
|
42
|
+
id: string;
|
|
43
43
|
own_capabilities: string[];
|
|
44
44
|
type: string;
|
|
45
45
|
updated_at: string;
|
|
46
46
|
};
|
|
47
|
-
id:
|
|
47
|
+
id: string;
|
|
48
48
|
state: {
|
|
49
49
|
members: {};
|
|
50
50
|
messages: never[];
|
|
@@ -54,18 +54,18 @@ export function generateChannel(customValues: any): {
|
|
|
54
54
|
};
|
|
55
55
|
export function generateChannelResponse(customValues?: {
|
|
56
56
|
channel: {};
|
|
57
|
-
id:
|
|
57
|
+
id: string;
|
|
58
58
|
type: string;
|
|
59
59
|
}): {
|
|
60
60
|
channel: {
|
|
61
|
-
id:
|
|
61
|
+
id: string;
|
|
62
62
|
type: string;
|
|
63
63
|
user: {
|
|
64
64
|
banned: boolean;
|
|
65
65
|
created_at: string;
|
|
66
|
-
id:
|
|
67
|
-
image:
|
|
68
|
-
name:
|
|
66
|
+
id: string;
|
|
67
|
+
image: string;
|
|
68
|
+
name: string;
|
|
69
69
|
online: boolean;
|
|
70
70
|
role: string;
|
|
71
71
|
updated_at: string;
|
|
@@ -100,9 +100,9 @@ export function generateChannelResponse(customValues?: {
|
|
|
100
100
|
created_by: {
|
|
101
101
|
banned: boolean;
|
|
102
102
|
created_at: string;
|
|
103
|
-
id:
|
|
104
|
-
image:
|
|
105
|
-
name:
|
|
103
|
+
id: string;
|
|
104
|
+
image: string;
|
|
105
|
+
name: string;
|
|
106
106
|
online: boolean;
|
|
107
107
|
role: string;
|
|
108
108
|
updated_at: string;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export function generateMessage(options?: {}): {
|
|
2
|
+
attachments: never[];
|
|
3
|
+
created_at: any;
|
|
4
|
+
html: string;
|
|
5
|
+
id: string;
|
|
6
|
+
text: string;
|
|
7
|
+
type: string;
|
|
8
|
+
updated_at: any;
|
|
9
|
+
user: {
|
|
10
|
+
banned: boolean;
|
|
11
|
+
created_at: string;
|
|
12
|
+
id: string;
|
|
13
|
+
image: string;
|
|
14
|
+
name: string;
|
|
15
|
+
online: boolean;
|
|
16
|
+
role: string;
|
|
17
|
+
updated_at: string;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
export function generateStaticMessage(seed: any, options: any, date: any): {
|
|
21
|
+
attachments: never[];
|
|
22
|
+
created_at: any;
|
|
23
|
+
html: string;
|
|
24
|
+
id: string;
|
|
25
|
+
text: string;
|
|
26
|
+
type: string;
|
|
27
|
+
updated_at: any;
|
|
28
|
+
user: {
|
|
29
|
+
banned: boolean;
|
|
30
|
+
created_at: string;
|
|
31
|
+
id: string;
|
|
32
|
+
image: string;
|
|
33
|
+
name: string;
|
|
34
|
+
online: boolean;
|
|
35
|
+
role: string;
|
|
36
|
+
updated_at: string;
|
|
37
|
+
};
|
|
38
|
+
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export function getUserDefaults(): {
|
|
2
2
|
banned: boolean;
|
|
3
3
|
created_at: string;
|
|
4
|
-
id:
|
|
5
|
-
image:
|
|
6
|
-
name:
|
|
4
|
+
id: string;
|
|
5
|
+
image: string;
|
|
6
|
+
name: string;
|
|
7
7
|
online: boolean;
|
|
8
8
|
role: string;
|
|
9
9
|
updated_at: string;
|
|
@@ -11,9 +11,9 @@ export function getUserDefaults(): {
|
|
|
11
11
|
export function generateUser(options?: {}): {
|
|
12
12
|
banned: boolean;
|
|
13
13
|
created_at: string;
|
|
14
|
-
id:
|
|
15
|
-
image:
|
|
16
|
-
name:
|
|
14
|
+
id: string;
|
|
15
|
+
image: string;
|
|
16
|
+
name: string;
|
|
17
17
|
online: boolean;
|
|
18
18
|
role: string;
|
|
19
19
|
updated_at: string;
|
|
@@ -21,9 +21,9 @@ export function generateUser(options?: {}): {
|
|
|
21
21
|
export function generateStaticUser(userNumber: any): {
|
|
22
22
|
banned: boolean;
|
|
23
23
|
created_at: string;
|
|
24
|
-
id:
|
|
25
|
-
image:
|
|
26
|
-
name:
|
|
24
|
+
id: string;
|
|
25
|
+
image: string;
|
|
26
|
+
name: string;
|
|
27
27
|
online: boolean;
|
|
28
28
|
role: string;
|
|
29
29
|
updated_at: string;
|
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.9.0-beta.
|
|
4
|
+
"version": "4.9.0-beta.4",
|
|
5
5
|
"author": {
|
|
6
6
|
"company": "Stream.io Inc",
|
|
7
7
|
"name": "Stream.io Inc"
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
"react-art": "^17.0.2",
|
|
81
81
|
"react-native-markdown-package": "1.8.1",
|
|
82
82
|
"react-native-url-polyfill": "^1.3.0",
|
|
83
|
-
"stream-chat": "6.
|
|
83
|
+
"stream-chat": "6.7.0"
|
|
84
84
|
},
|
|
85
85
|
"peerDependencies": {
|
|
86
86
|
"react-native-svg": "^12.1.0"
|
|
@@ -88,18 +88,18 @@
|
|
|
88
88
|
"devDependencies": {
|
|
89
89
|
"@babel/cli": "^7.12.17",
|
|
90
90
|
"@babel/core": "^7.12.9",
|
|
91
|
-
"@babel/runtime": "^7.12.5",
|
|
92
91
|
"@babel/plugin-proposal-object-rest-spread": "7.13.8",
|
|
93
92
|
"@babel/plugin-transform-runtime": "7.13.10",
|
|
94
93
|
"@babel/polyfill": "7.12.1",
|
|
95
94
|
"@babel/preset-env": "7.13.12",
|
|
96
95
|
"@babel/preset-typescript": "7.13.0",
|
|
96
|
+
"@babel/runtime": "^7.12.5",
|
|
97
97
|
"@react-native-community/eslint-config": "2.0.0",
|
|
98
98
|
"@react-native-community/eslint-plugin": "1.1.0",
|
|
99
99
|
"@react-native-community/netinfo": "6.0.0",
|
|
100
100
|
"@testing-library/jest-native": "4.0.4",
|
|
101
|
-
"@testing-library/react-native": "9.0.0",
|
|
102
101
|
"@testing-library/react-hooks": "7.0.2",
|
|
102
|
+
"@testing-library/react-native": "9.0.0",
|
|
103
103
|
"@types/eslint": "7.2.10",
|
|
104
104
|
"@types/jest": "26.0.23",
|
|
105
105
|
"@types/lodash": "4.14.169",
|
|
@@ -107,6 +107,7 @@
|
|
|
107
107
|
"@types/react": "17.0.5",
|
|
108
108
|
"@types/react-native": "0.67.3",
|
|
109
109
|
"@types/react-test-renderer": "17.0.1",
|
|
110
|
+
"@types/uuid": "^8.3.4",
|
|
110
111
|
"@typescript-eslint/eslint-plugin": "^5.7.0",
|
|
111
112
|
"@typescript-eslint/parser": "^5.7.0",
|
|
112
113
|
"babel-eslint": "10.1.0",
|
|
@@ -212,7 +212,7 @@ const GalleryWithContext = <
|
|
|
212
212
|
]}
|
|
213
213
|
testID={`gallery-${invertedDirections ? 'row' : 'column'}-${colIndex}`}
|
|
214
214
|
>
|
|
215
|
-
{rows.map(({ height, resizeMode, type, url, width }, rowIndex) => {
|
|
215
|
+
{rows.map(({ height, resizeMode, thumb_url, type, url, width }, rowIndex) => {
|
|
216
216
|
const openImageViewer = () => {
|
|
217
217
|
if (!legacyImageViewerSwipeBehaviour && message) {
|
|
218
218
|
// Added if-else to keep the logic readable, instead of DRY.
|
|
@@ -307,6 +307,7 @@ const GalleryWithContext = <
|
|
|
307
307
|
width: width - 1,
|
|
308
308
|
},
|
|
309
309
|
]}
|
|
310
|
+
thumb_url={thumb_url}
|
|
310
311
|
/>
|
|
311
312
|
) : (
|
|
312
313
|
<View style={styles.imageContainerStyle}>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { StyleSheet, View, ViewProps } from 'react-native';
|
|
2
|
+
import { ImageBackground, StyleSheet, View, ViewProps } from 'react-native';
|
|
3
3
|
|
|
4
4
|
import { useTheme } from '../../contexts/themeContext/ThemeContext';
|
|
5
5
|
import { Play } from '../../icons';
|
|
@@ -24,7 +24,9 @@ const styles = StyleSheet.create({
|
|
|
24
24
|
},
|
|
25
25
|
});
|
|
26
26
|
|
|
27
|
-
export type VideoThumbnailProps = ViewProps
|
|
27
|
+
export type VideoThumbnailProps = ViewProps & {
|
|
28
|
+
thumb_url?: string;
|
|
29
|
+
};
|
|
28
30
|
|
|
29
31
|
export const VideoThumbnail: React.FC<VideoThumbnailProps> = (props) => {
|
|
30
32
|
const {
|
|
@@ -34,12 +36,17 @@ export const VideoThumbnail: React.FC<VideoThumbnailProps> = (props) => {
|
|
|
34
36
|
},
|
|
35
37
|
},
|
|
36
38
|
} = useTheme();
|
|
37
|
-
const { style, ...rest } = props;
|
|
39
|
+
const { style, thumb_url, ...rest } = props;
|
|
38
40
|
return (
|
|
39
|
-
<
|
|
41
|
+
<ImageBackground
|
|
42
|
+
accessibilityLabel='video-thumbnail'
|
|
43
|
+
source={{ uri: thumb_url }}
|
|
44
|
+
{...rest}
|
|
45
|
+
style={[styles.container, container, style]}
|
|
46
|
+
>
|
|
40
47
|
<View style={[styles.roundedView, roundedView]}>
|
|
41
48
|
<Play height={24} pathFill={'#000'} width={24} />
|
|
42
49
|
</View>
|
|
43
|
-
</
|
|
50
|
+
</ImageBackground>
|
|
44
51
|
);
|
|
45
52
|
};
|
|
@@ -11,8 +11,10 @@ import {
|
|
|
11
11
|
generateAudioAttachment,
|
|
12
12
|
generateFileAttachment,
|
|
13
13
|
generateImageAttachment,
|
|
14
|
+
generateVideoAttachment,
|
|
14
15
|
} from '../../../mock-builders/generator/attachment';
|
|
15
16
|
import { generateMessage } from '../../../mock-builders/generator/message';
|
|
17
|
+
import * as NativeUtils from '../../../native';
|
|
16
18
|
|
|
17
19
|
import { ImageLoadingFailedIndicator } from '../../Attachment/ImageLoadingFailedIndicator';
|
|
18
20
|
import { ImageLoadingIndicator } from '../../Attachment/ImageLoadingIndicator';
|
|
@@ -47,6 +49,16 @@ describe('Attachment', () => {
|
|
|
47
49
|
});
|
|
48
50
|
});
|
|
49
51
|
|
|
52
|
+
it('should render File component for "video" type attachment', async () => {
|
|
53
|
+
jest.spyOn(NativeUtils, 'isVideoPackageAvailable').mockImplementation(jest.fn(() => false));
|
|
54
|
+
const attachment = generateVideoAttachment();
|
|
55
|
+
const { getByTestId } = render(getAttachmentComponent({ attachment }));
|
|
56
|
+
|
|
57
|
+
await waitFor(() => {
|
|
58
|
+
expect(getByTestId('file-attachment')).toBeTruthy();
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
|
|
50
62
|
it('should render File component for "file" type attachment', async () => {
|
|
51
63
|
const attachment = generateFileAttachment();
|
|
52
64
|
const { getByTestId } = render(getAttachmentComponent({ attachment }));
|
|
@@ -11,12 +11,16 @@ import { OverlayProvider } from '../../../contexts/overlayContext/OverlayProvide
|
|
|
11
11
|
|
|
12
12
|
import { getOrCreateChannelApi } from '../../../mock-builders/api/getOrCreateChannel';
|
|
13
13
|
import { useMockedApis } from '../../../mock-builders/api/useMockedApis';
|
|
14
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
generateImageAttachment,
|
|
16
|
+
generateVideoAttachment,
|
|
17
|
+
} from '../../../mock-builders/generator/attachment';
|
|
15
18
|
import { generateChannelResponse } from '../../../mock-builders/generator/channel';
|
|
16
19
|
import { generateMember } from '../../../mock-builders/generator/member';
|
|
17
20
|
import { generateMessage } from '../../../mock-builders/generator/message';
|
|
18
21
|
import { generateUser } from '../../../mock-builders/generator/user';
|
|
19
22
|
import { getTestClientWithUser } from '../../../mock-builders/mock';
|
|
23
|
+
import * as NativeUtils from '../../../native';
|
|
20
24
|
import { Channel } from '../../Channel/Channel';
|
|
21
25
|
import { Chat } from '../../Chat/Chat';
|
|
22
26
|
import { MessageList } from '../../MessageList/MessageList';
|
|
@@ -75,6 +79,24 @@ describe('Gallery', () => {
|
|
|
75
79
|
});
|
|
76
80
|
});
|
|
77
81
|
|
|
82
|
+
it('should render one image and one video attachment', async () => {
|
|
83
|
+
jest.spyOn(NativeUtils, 'isVideoPackageAvailable').mockImplementation(jest.fn(() => true));
|
|
84
|
+
const attachment1 = generateImageAttachment({
|
|
85
|
+
original_height: 600,
|
|
86
|
+
original_width: 400,
|
|
87
|
+
});
|
|
88
|
+
const attachment2 = generateVideoAttachment();
|
|
89
|
+
const component = await getComponent([attachment1, attachment2]);
|
|
90
|
+
const { getAllByA11yLabel, queryAllByTestId } = render(component);
|
|
91
|
+
|
|
92
|
+
await waitFor(() => {
|
|
93
|
+
expect(queryAllByTestId('gallery-row-0').length).toBe(1);
|
|
94
|
+
|
|
95
|
+
expect(queryAllByTestId('gallery-row-0-item-0').length).toBe(1);
|
|
96
|
+
expect(getAllByA11yLabel('video-thumbnail').length).toBe(1);
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
|
|
78
100
|
it('should render portrait and landscape image in two rows', async () => {
|
|
79
101
|
const attachment1 = generateImageAttachment({
|
|
80
102
|
original_height: 600,
|
|
@@ -36,6 +36,7 @@ export function buildThumbnail<
|
|
|
36
36
|
resizeMode: resizeMode
|
|
37
37
|
? resizeMode
|
|
38
38
|
: ((image.original_height && image.original_width ? 'contain' : 'cover') as ImageResizeMode),
|
|
39
|
+
thumb_url: image.thumb_url,
|
|
39
40
|
type: image.type,
|
|
40
41
|
url: shouldResize
|
|
41
42
|
? getResizedImageUrl({
|
|
@@ -333,7 +333,11 @@ const MessageWithContext = <
|
|
|
333
333
|
acc.files.push(cur);
|
|
334
334
|
acc.other = []; // remove other attachments if a file exists
|
|
335
335
|
} else if (cur.type === 'video' && !cur.og_scrape_url && isVideoPackageAvailable()) {
|
|
336
|
-
acc.videos.push({
|
|
336
|
+
acc.videos.push({
|
|
337
|
+
image_url: cur.asset_url,
|
|
338
|
+
thumb_url: cur.thumb_url,
|
|
339
|
+
type: 'video',
|
|
340
|
+
});
|
|
337
341
|
acc.other = [];
|
|
338
342
|
} else if (cur.type === 'video' && !cur.og_scrape_url) {
|
|
339
343
|
acc.files.push(cur);
|
|
@@ -62,6 +62,7 @@ export type FileUpload = {
|
|
|
62
62
|
file: File;
|
|
63
63
|
id: string;
|
|
64
64
|
state: FileStateValue;
|
|
65
|
+
thumb_url?: string;
|
|
65
66
|
url?: string;
|
|
66
67
|
};
|
|
67
68
|
|
|
@@ -710,6 +711,7 @@ export const MessageInputProvider = <
|
|
|
710
711
|
duration: file.file.duration,
|
|
711
712
|
file_size: file.file.size,
|
|
712
713
|
mime_type: file.file.type,
|
|
714
|
+
thumb_url: file.thumb_url,
|
|
713
715
|
title: file.file.name,
|
|
714
716
|
type: 'video',
|
|
715
717
|
} as Attachment<StreamChatGenerics>);
|
|
@@ -897,9 +899,6 @@ export const MessageInputProvider = <
|
|
|
897
899
|
};
|
|
898
900
|
|
|
899
901
|
const uploadFile = async ({ newFile }: { newFile: FileUpload }) => {
|
|
900
|
-
if (!newFile) {
|
|
901
|
-
return;
|
|
902
|
-
}
|
|
903
902
|
const { file, id } = newFile;
|
|
904
903
|
|
|
905
904
|
setFileUploads(getUploadSetStateAction(id, FileState.UPLOADING));
|
|
@@ -911,7 +910,7 @@ export const MessageInputProvider = <
|
|
|
911
910
|
} else if (channel && file.uri) {
|
|
912
911
|
response = await channel.sendFile(file.uri, file.name, file.type);
|
|
913
912
|
}
|
|
914
|
-
const extraData: Partial<FileUpload> = { url: response.file };
|
|
913
|
+
const extraData: Partial<FileUpload> = { thumb_url: response.thumb_url, url: response.file };
|
|
915
914
|
setFileUploads(getUploadSetStateAction(id, FileState.UPLOADED, extraData));
|
|
916
915
|
} catch (error: unknown) {
|
|
917
916
|
handleFileOrImageUploadError(error, false, id);
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import React, { PropsWithChildren } from 'react';
|
|
2
|
+
|
|
3
|
+
import type { TextInput } from 'react-native';
|
|
4
|
+
|
|
5
|
+
import { act, renderHook } from '@testing-library/react-hooks';
|
|
6
|
+
|
|
7
|
+
import type { AppSettingsAPIResponse, StreamChat } from 'stream-chat';
|
|
8
|
+
|
|
9
|
+
import { ChatContextValue, ChatProvider } from '../../../contexts/chatContext/ChatContext';
|
|
10
|
+
|
|
11
|
+
import {
|
|
12
|
+
generateFileAttachment,
|
|
13
|
+
generateImageAttachment,
|
|
14
|
+
} from '../../../mock-builders/generator/attachment';
|
|
15
|
+
|
|
16
|
+
import { generateMessage } from '../../../mock-builders/generator/message';
|
|
17
|
+
import { generateUser } from '../../../mock-builders/generator/user';
|
|
18
|
+
|
|
19
|
+
import * as NativeUtils from '../../../native';
|
|
20
|
+
import type { DefaultStreamChatGenerics } from '../../../types/types';
|
|
21
|
+
import { FileState } from '../../../utils/utils';
|
|
22
|
+
import {
|
|
23
|
+
InputMessageInputContextValue,
|
|
24
|
+
MessageInputContextValue,
|
|
25
|
+
MessageInputProvider,
|
|
26
|
+
useMessageInputContext,
|
|
27
|
+
} from '../MessageInputContext';
|
|
28
|
+
|
|
29
|
+
type WrapperType<StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics> =
|
|
30
|
+
Partial<InputMessageInputContextValue<StreamChatGenerics>>;
|
|
31
|
+
|
|
32
|
+
afterEach(jest.clearAllMocks);
|
|
33
|
+
|
|
34
|
+
describe('MessageInputContext', () => {
|
|
35
|
+
const Wrapper = <
|
|
36
|
+
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
|
|
37
|
+
>({
|
|
38
|
+
children,
|
|
39
|
+
...rest
|
|
40
|
+
}: PropsWithChildren<WrapperType<StreamChatGenerics>>) => (
|
|
41
|
+
<ChatProvider
|
|
42
|
+
value={
|
|
43
|
+
{
|
|
44
|
+
appSettings: {
|
|
45
|
+
app: {
|
|
46
|
+
file_upload_config: {
|
|
47
|
+
blocked_file_extensions: ['.mp3'],
|
|
48
|
+
blocked_mime_types: ['video/mp4'],
|
|
49
|
+
},
|
|
50
|
+
image_upload_config: {
|
|
51
|
+
blocked_file_extensions: ['.png'],
|
|
52
|
+
blocked_mime_types: ['image/png'],
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
} as unknown as AppSettingsAPIResponse<StreamChatGenerics>,
|
|
56
|
+
client: {
|
|
57
|
+
updateMessage: jest.fn().mockResolvedValue({ message: generateMessage() }),
|
|
58
|
+
} as unknown as StreamChat<StreamChatGenerics>,
|
|
59
|
+
} as ChatContextValue<StreamChatGenerics>
|
|
60
|
+
}
|
|
61
|
+
>
|
|
62
|
+
<MessageInputProvider
|
|
63
|
+
value={
|
|
64
|
+
{
|
|
65
|
+
...rest,
|
|
66
|
+
} as MessageInputContextValue<StreamChatGenerics>
|
|
67
|
+
}
|
|
68
|
+
>
|
|
69
|
+
{children}
|
|
70
|
+
</MessageInputProvider>
|
|
71
|
+
</ChatProvider>
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
it('appendText works', () => {
|
|
75
|
+
const { result } = renderHook(() => useMessageInputContext(), {
|
|
76
|
+
initialProps: {
|
|
77
|
+
editing: true,
|
|
78
|
+
hasImagePicker: true,
|
|
79
|
+
},
|
|
80
|
+
wrapper: Wrapper,
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
act(() => {
|
|
84
|
+
result.current.setFileUploads([]);
|
|
85
|
+
result.current.setImageUploads([]);
|
|
86
|
+
result.current.setMentionedUsers([]);
|
|
87
|
+
result.current.setText('dummy');
|
|
88
|
+
result.current.appendText('text');
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
expect(result.current.text).toBe('dummytext');
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it('uploadNewImage with blocked image extensions to be not supported', () => {
|
|
95
|
+
const { result } = renderHook(() => useMessageInputContext(), {
|
|
96
|
+
initialProps: {
|
|
97
|
+
editing: true,
|
|
98
|
+
maxNumberOfFiles: 2,
|
|
99
|
+
},
|
|
100
|
+
wrapper: Wrapper,
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
act(() => {
|
|
104
|
+
result.current.uploadNewImage(
|
|
105
|
+
generateImageAttachment({
|
|
106
|
+
uri: 'https://www.bastiaanmulder.nl/wp-content/uploads/2013/11/dummy-image-square.png',
|
|
107
|
+
}),
|
|
108
|
+
);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
expect(result.current.imageUploads[0].state).toBe(FileState.NOT_SUPPORTED);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it('onSelectItem works', () => {
|
|
115
|
+
const mentioned_user = generateUser();
|
|
116
|
+
const initialUsers = [mentioned_user.id];
|
|
117
|
+
|
|
118
|
+
const { result } = renderHook(() => useMessageInputContext(), {
|
|
119
|
+
initialProps: {
|
|
120
|
+
editing: true,
|
|
121
|
+
hasImagePicker: true,
|
|
122
|
+
},
|
|
123
|
+
wrapper: Wrapper,
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
act(() => {
|
|
127
|
+
result.current.setFileUploads([]);
|
|
128
|
+
result.current.setImageUploads([]);
|
|
129
|
+
result.current.setMentionedUsers(initialUsers);
|
|
130
|
+
result.current.onSelectItem(mentioned_user);
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
expect(result.current.mentionedUsers.length).toBe(2);
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
it('setInputBoxRef works', () => {
|
|
137
|
+
const setInputRefMock = jest.fn();
|
|
138
|
+
const inputRef = React.createRef<TextInput | null>();
|
|
139
|
+
const { result } = renderHook(() => useMessageInputContext(), {
|
|
140
|
+
initialProps: {
|
|
141
|
+
editing: true,
|
|
142
|
+
setInputRef: setInputRefMock,
|
|
143
|
+
},
|
|
144
|
+
wrapper: Wrapper,
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
act(() => {
|
|
148
|
+
result.current.setInputBoxRef(inputRef.current);
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
expect(setInputRefMock).toHaveBeenCalled();
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
it('openCommandsPicker works', () => {
|
|
155
|
+
const { result } = renderHook(() => useMessageInputContext(), {
|
|
156
|
+
initialProps: {
|
|
157
|
+
editing: true,
|
|
158
|
+
hasImagePicker: true,
|
|
159
|
+
},
|
|
160
|
+
wrapper: Wrapper,
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
act(() => {
|
|
164
|
+
result.current.openCommandsPicker();
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
expect(result.current.text).toBe('/');
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
it('openMentionPicker works', () => {
|
|
171
|
+
const { result } = renderHook(() => useMessageInputContext(), {
|
|
172
|
+
initialProps: {
|
|
173
|
+
editing: true,
|
|
174
|
+
hasImagePicker: true,
|
|
175
|
+
},
|
|
176
|
+
wrapper: Wrapper,
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
act(() => {
|
|
180
|
+
result.current.openMentionsPicker();
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
expect(result.current.text).toBe('@');
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
it('openAttachmentPicker works', async () => {
|
|
187
|
+
jest.spyOn(NativeUtils, 'pickDocument').mockImplementation(
|
|
188
|
+
jest.fn().mockResolvedValue({
|
|
189
|
+
cancelled: false,
|
|
190
|
+
docs: [generateFileAttachment(), generateImageAttachment()],
|
|
191
|
+
}),
|
|
192
|
+
);
|
|
193
|
+
const { result } = renderHook(() => useMessageInputContext(), {
|
|
194
|
+
initialProps: {
|
|
195
|
+
editing: true,
|
|
196
|
+
hasFilePicker: true,
|
|
197
|
+
hasImagePicker: false,
|
|
198
|
+
},
|
|
199
|
+
wrapper: Wrapper,
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
act(() => {
|
|
203
|
+
result.current.openAttachmentPicker();
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
expect(await result.current.pickFile()).toBe(undefined);
|
|
207
|
+
});
|
|
208
|
+
});
|