stream-chat-react-native-core 4.9.0-beta.1 → 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/AutoCompleteInput/AutoCompleteInput.js +3 -2
- package/lib/commonjs/components/AutoCompleteInput/AutoCompleteInput.js.map +1 -1
- package/lib/commonjs/components/AutoCompleteInput/AutoCompleteSuggestionItem.js +1 -1
- package/lib/commonjs/components/AutoCompleteInput/AutoCompleteSuggestionItem.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/components/MessageInput/FileUploadPreview.js +24 -18
- package/lib/commonjs/components/MessageInput/FileUploadPreview.js.map +1 -1
- package/lib/commonjs/components/MessageInput/ImageUploadPreview.js +2 -2
- package/lib/commonjs/components/MessageInput/ImageUploadPreview.js.map +1 -1
- package/lib/commonjs/components/RTLComponents/WritingDirectionAwareText.js +43 -0
- package/lib/commonjs/components/RTLComponents/WritingDirectionAwareText.js.map +1 -0
- package/lib/commonjs/components/Reply/Reply.js +7 -2
- package/lib/commonjs/components/Reply/Reply.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/AutoCompleteInput/AutoCompleteInput.js +3 -2
- package/lib/module/components/AutoCompleteInput/AutoCompleteInput.js.map +1 -1
- package/lib/module/components/AutoCompleteInput/AutoCompleteSuggestionItem.js +1 -1
- package/lib/module/components/AutoCompleteInput/AutoCompleteSuggestionItem.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/components/MessageInput/FileUploadPreview.js +24 -18
- package/lib/module/components/MessageInput/FileUploadPreview.js.map +1 -1
- package/lib/module/components/MessageInput/ImageUploadPreview.js +2 -2
- package/lib/module/components/MessageInput/ImageUploadPreview.js.map +1 -1
- package/lib/module/components/RTLComponents/WritingDirectionAwareText.js +43 -0
- package/lib/module/components/RTLComponents/WritingDirectionAwareText.js.map +1 -0
- package/lib/module/components/Reply/Reply.js +7 -2
- package/lib/module/components/Reply/Reply.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/components/RTLComponents/WritingDirectionAwareText.d.ts +4 -0
- package/lib/typescript/components/Reply/__tests__/Reply.test.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/api/getOrCreateChannel.d.ts +7 -0
- package/lib/typescript/mock-builders/api/useMockedApis.d.ts +1 -0
- package/lib/typescript/mock-builders/generator/attachment.d.ts +10 -0
- package/lib/typescript/mock-builders/generator/channel.d.ts +116 -0
- 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 +7 -5
- 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/AutoCompleteInput/AutoCompleteInput.tsx +2 -1
- package/src/components/AutoCompleteInput/AutoCompleteSuggestionItem.tsx +1 -1
- package/src/components/Message/Message.tsx +5 -1
- package/src/components/MessageInput/FileUploadPreview.tsx +7 -5
- package/src/components/MessageInput/ImageUploadPreview.tsx +2 -2
- package/src/components/MessageInput/__tests__/__snapshots__/MessageInput.test.js.snap +1 -0
- package/src/components/RTLComponents/WritingDirectionAwareText.tsx +17 -0
- package/src/components/Reply/Reply.tsx +19 -3
- package/src/components/Reply/__tests__/Reply.test.tsx +48 -0
- package/src/components/Thread/__tests__/__snapshots__/Thread.test.js.snap +1 -0
- 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
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
export function generateChannel(customValues: any): {
|
|
2
|
+
_client: {};
|
|
3
|
+
data: {
|
|
4
|
+
cid: string;
|
|
5
|
+
config: {
|
|
6
|
+
name: string;
|
|
7
|
+
type: string;
|
|
8
|
+
automod: string;
|
|
9
|
+
automod_behavior: string;
|
|
10
|
+
commands: {
|
|
11
|
+
args: string;
|
|
12
|
+
description: string;
|
|
13
|
+
name: string;
|
|
14
|
+
set: string;
|
|
15
|
+
}[];
|
|
16
|
+
connect_events: boolean;
|
|
17
|
+
created_at: string;
|
|
18
|
+
max_message_length: number;
|
|
19
|
+
message_retention: string;
|
|
20
|
+
mutes: boolean;
|
|
21
|
+
reactions: boolean;
|
|
22
|
+
read_events: boolean;
|
|
23
|
+
replies: boolean;
|
|
24
|
+
search: boolean;
|
|
25
|
+
typing_events: boolean;
|
|
26
|
+
updated_at: string;
|
|
27
|
+
uploads: boolean;
|
|
28
|
+
url_enrichment: boolean;
|
|
29
|
+
};
|
|
30
|
+
created_at: string;
|
|
31
|
+
created_by: {
|
|
32
|
+
banned: boolean;
|
|
33
|
+
created_at: string;
|
|
34
|
+
id: string;
|
|
35
|
+
image: string;
|
|
36
|
+
name: string;
|
|
37
|
+
online: boolean;
|
|
38
|
+
role: string;
|
|
39
|
+
updated_at: string;
|
|
40
|
+
};
|
|
41
|
+
frozen: boolean;
|
|
42
|
+
id: string;
|
|
43
|
+
own_capabilities: string[];
|
|
44
|
+
type: string;
|
|
45
|
+
updated_at: string;
|
|
46
|
+
};
|
|
47
|
+
id: string;
|
|
48
|
+
state: {
|
|
49
|
+
members: {};
|
|
50
|
+
messages: never[];
|
|
51
|
+
setIsUpToDate: jest.Mock<any, any>;
|
|
52
|
+
};
|
|
53
|
+
type: string;
|
|
54
|
+
};
|
|
55
|
+
export function generateChannelResponse(customValues?: {
|
|
56
|
+
channel: {};
|
|
57
|
+
id: string;
|
|
58
|
+
type: string;
|
|
59
|
+
}): {
|
|
60
|
+
channel: {
|
|
61
|
+
id: string;
|
|
62
|
+
type: string;
|
|
63
|
+
user: {
|
|
64
|
+
banned: boolean;
|
|
65
|
+
created_at: string;
|
|
66
|
+
id: string;
|
|
67
|
+
image: string;
|
|
68
|
+
name: string;
|
|
69
|
+
online: boolean;
|
|
70
|
+
role: string;
|
|
71
|
+
updated_at: string;
|
|
72
|
+
};
|
|
73
|
+
cid: string;
|
|
74
|
+
config: {
|
|
75
|
+
name: string;
|
|
76
|
+
type: string;
|
|
77
|
+
automod: string;
|
|
78
|
+
automod_behavior: string;
|
|
79
|
+
commands: {
|
|
80
|
+
args: string;
|
|
81
|
+
description: string;
|
|
82
|
+
name: string;
|
|
83
|
+
set: string;
|
|
84
|
+
}[];
|
|
85
|
+
connect_events: boolean;
|
|
86
|
+
created_at: string;
|
|
87
|
+
max_message_length: number;
|
|
88
|
+
message_retention: string;
|
|
89
|
+
mutes: boolean;
|
|
90
|
+
reactions: boolean;
|
|
91
|
+
read_events: boolean;
|
|
92
|
+
replies: boolean;
|
|
93
|
+
search: boolean;
|
|
94
|
+
typing_events: boolean;
|
|
95
|
+
updated_at: string;
|
|
96
|
+
uploads: boolean;
|
|
97
|
+
url_enrichment: boolean;
|
|
98
|
+
};
|
|
99
|
+
created_at: string;
|
|
100
|
+
created_by: {
|
|
101
|
+
banned: boolean;
|
|
102
|
+
created_at: string;
|
|
103
|
+
id: string;
|
|
104
|
+
image: string;
|
|
105
|
+
name: string;
|
|
106
|
+
online: boolean;
|
|
107
|
+
role: string;
|
|
108
|
+
updated_at: string;
|
|
109
|
+
};
|
|
110
|
+
frozen: boolean;
|
|
111
|
+
own_capabilities: string[];
|
|
112
|
+
updated_at: string;
|
|
113
|
+
};
|
|
114
|
+
members: never[];
|
|
115
|
+
messages: never[];
|
|
116
|
+
};
|
|
@@ -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"
|
|
@@ -34,7 +34,8 @@
|
|
|
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:
|
|
37
|
+
"test:coverage": "yarn test:unit --coverage",
|
|
38
|
+
"test:unit": "TZ=UTC jest",
|
|
38
39
|
"validate-translations": "node bin/validate-translations.js",
|
|
39
40
|
"get-version": "echo $npm_package_version",
|
|
40
41
|
"version": "bash ./bin/before-tag.sh",
|
|
@@ -79,7 +80,7 @@
|
|
|
79
80
|
"react-art": "^17.0.2",
|
|
80
81
|
"react-native-markdown-package": "1.8.1",
|
|
81
82
|
"react-native-url-polyfill": "^1.3.0",
|
|
82
|
-
"stream-chat": "6.
|
|
83
|
+
"stream-chat": "6.7.0"
|
|
83
84
|
},
|
|
84
85
|
"peerDependencies": {
|
|
85
86
|
"react-native-svg": "^12.1.0"
|
|
@@ -87,18 +88,18 @@
|
|
|
87
88
|
"devDependencies": {
|
|
88
89
|
"@babel/cli": "^7.12.17",
|
|
89
90
|
"@babel/core": "^7.12.9",
|
|
90
|
-
"@babel/runtime": "^7.12.5",
|
|
91
91
|
"@babel/plugin-proposal-object-rest-spread": "7.13.8",
|
|
92
92
|
"@babel/plugin-transform-runtime": "7.13.10",
|
|
93
93
|
"@babel/polyfill": "7.12.1",
|
|
94
94
|
"@babel/preset-env": "7.13.12",
|
|
95
95
|
"@babel/preset-typescript": "7.13.0",
|
|
96
|
+
"@babel/runtime": "^7.12.5",
|
|
96
97
|
"@react-native-community/eslint-config": "2.0.0",
|
|
97
98
|
"@react-native-community/eslint-plugin": "1.1.0",
|
|
98
99
|
"@react-native-community/netinfo": "6.0.0",
|
|
99
100
|
"@testing-library/jest-native": "4.0.4",
|
|
100
|
-
"@testing-library/react-native": "9.0.0",
|
|
101
101
|
"@testing-library/react-hooks": "7.0.2",
|
|
102
|
+
"@testing-library/react-native": "9.0.0",
|
|
102
103
|
"@types/eslint": "7.2.10",
|
|
103
104
|
"@types/jest": "26.0.23",
|
|
104
105
|
"@types/lodash": "4.14.169",
|
|
@@ -106,6 +107,7 @@
|
|
|
106
107
|
"@types/react": "17.0.5",
|
|
107
108
|
"@types/react-native": "0.67.3",
|
|
108
109
|
"@types/react-test-renderer": "17.0.1",
|
|
110
|
+
"@types/uuid": "^8.3.4",
|
|
109
111
|
"@typescript-eslint/eslint-plugin": "^5.7.0",
|
|
110
112
|
"@typescript-eslint/parser": "^5.7.0",
|
|
111
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({
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useEffect, useRef, useState } from 'react';
|
|
2
|
-
import { StyleSheet, TextInput, TextInputProps } from 'react-native';
|
|
2
|
+
import { I18nManager, StyleSheet, TextInput, TextInputProps } from 'react-native';
|
|
3
3
|
|
|
4
4
|
import throttle from 'lodash/throttle';
|
|
5
5
|
|
|
@@ -417,6 +417,7 @@ const AutoCompleteInputWithContext = <
|
|
|
417
417
|
{
|
|
418
418
|
color: black,
|
|
419
419
|
maxHeight: (textHeight || 17) * numberOfLines,
|
|
420
|
+
textAlign: I18nManager.isRTL ? 'right' : 'left',
|
|
420
421
|
},
|
|
421
422
|
inputBox,
|
|
422
423
|
]}
|
|
@@ -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);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useEffect, useRef, useState } from 'react';
|
|
2
|
-
import { FlatList, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
|
|
2
|
+
import { FlatList, I18nManager, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
|
|
3
3
|
|
|
4
4
|
import { UploadProgressIndicator } from './UploadProgressIndicator';
|
|
5
5
|
|
|
@@ -19,6 +19,7 @@ import { Warning } from '../../icons/Warning';
|
|
|
19
19
|
import type { DefaultStreamChatGenerics } from '../../types/types';
|
|
20
20
|
import { getIndicatorTypeForFileState, ProgressIndicatorTypes } from '../../utils/utils';
|
|
21
21
|
import { getFileSizeDisplayText } from '../Attachment/FileAttachment';
|
|
22
|
+
import { WritingDirectionAwareText } from '../RTLComponents/WritingDirectionAwareText';
|
|
22
23
|
|
|
23
24
|
const FILE_PREVIEW_HEIGHT = 60;
|
|
24
25
|
const WARNING_ICON_SIZE = 16;
|
|
@@ -71,7 +72,7 @@ const styles = StyleSheet.create({
|
|
|
71
72
|
},
|
|
72
73
|
warningIconStyle: {
|
|
73
74
|
borderRadius: 24,
|
|
74
|
-
marginTop:
|
|
75
|
+
marginTop: 2,
|
|
75
76
|
},
|
|
76
77
|
});
|
|
77
78
|
|
|
@@ -105,9 +106,9 @@ const UnsupportedFileTypeOrFileSizeIndicator = ({
|
|
|
105
106
|
</Text>
|
|
106
107
|
</View>
|
|
107
108
|
) : (
|
|
108
|
-
<
|
|
109
|
-
{item.file.duration
|
|
110
|
-
</
|
|
109
|
+
<WritingDirectionAwareText style={[styles.fileSizeText, { color: grey }, fileSizeText]}>
|
|
110
|
+
{item.file.duration || getFileSizeDisplayText(item.file.size)}
|
|
111
|
+
</WritingDirectionAwareText>
|
|
111
112
|
);
|
|
112
113
|
};
|
|
113
114
|
|
|
@@ -188,6 +189,7 @@ const FileUploadPreviewWithContext = <
|
|
|
188
189
|
24 - // 24 = close icon size
|
|
189
190
|
24, // 24 = internal padding
|
|
190
191
|
},
|
|
192
|
+
I18nManager.isRTL ? { writingDirection: 'rtl' } : { writingDirection: 'ltr' },
|
|
191
193
|
filenameText,
|
|
192
194
|
]}
|
|
193
195
|
>
|
|
@@ -27,7 +27,7 @@ const styles = StyleSheet.create({
|
|
|
27
27
|
},
|
|
28
28
|
fileSizeText: {
|
|
29
29
|
fontSize: 12,
|
|
30
|
-
|
|
30
|
+
paddingHorizontal: 10,
|
|
31
31
|
},
|
|
32
32
|
flatList: { paddingBottom: 12 },
|
|
33
33
|
iconContainer: {
|
|
@@ -54,7 +54,7 @@ const styles = StyleSheet.create({
|
|
|
54
54
|
},
|
|
55
55
|
warningIconStyle: {
|
|
56
56
|
borderRadius: 24,
|
|
57
|
-
marginTop:
|
|
57
|
+
marginTop: 6,
|
|
58
58
|
},
|
|
59
59
|
warningText: {
|
|
60
60
|
alignItems: 'center',
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { I18nManager, StyleSheet, Text, ViewProps } from 'react-native';
|
|
3
|
+
|
|
4
|
+
const styles = StyleSheet.create({
|
|
5
|
+
defaultStyle: { writingDirection: I18nManager.isRTL ? 'rtl' : 'ltr' },
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
export type WritingDirectionAwareTextProps = ViewProps;
|
|
9
|
+
|
|
10
|
+
export const WritingDirectionAwareText: React.FC<WritingDirectionAwareTextProps> = (props) => {
|
|
11
|
+
const { children, style, ...rest } = props;
|
|
12
|
+
return (
|
|
13
|
+
<Text {...rest} style={[style, styles.defaultStyle]}>
|
|
14
|
+
{children}
|
|
15
|
+
</Text>
|
|
16
|
+
);
|
|
17
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useState } from 'react';
|
|
1
|
+
import React, { useContext, useState } from 'react';
|
|
2
2
|
import { Image, ImageStyle, StyleSheet, View, ViewStyle } from 'react-native';
|
|
3
3
|
|
|
4
4
|
import merge from 'lodash/merge';
|
|
@@ -7,8 +7,8 @@ import type { Attachment } from 'stream-chat';
|
|
|
7
7
|
|
|
8
8
|
import { useMessageContext } from '../../contexts/messageContext/MessageContext';
|
|
9
9
|
import {
|
|
10
|
+
MessageInputContext,
|
|
10
11
|
MessageInputContextValue,
|
|
11
|
-
useMessageInputContext,
|
|
12
12
|
} from '../../contexts/messageInputContext/MessageInputContext';
|
|
13
13
|
import {
|
|
14
14
|
MessagesContextValue,
|
|
@@ -267,6 +267,22 @@ const ReplyWithContext = <
|
|
|
267
267
|
);
|
|
268
268
|
};
|
|
269
269
|
|
|
270
|
+
/**
|
|
271
|
+
* When a reply is rendered in a MessageSimple, it does
|
|
272
|
+
* not have a MessageInputContext. As this is deliberate,
|
|
273
|
+
* this function exists to avoid the error thrown when
|
|
274
|
+
* using a context outside of its provider.
|
|
275
|
+
* */
|
|
276
|
+
const useMessageInputContextIfAvailable = <
|
|
277
|
+
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
|
|
278
|
+
>() => {
|
|
279
|
+
const contextValue = useContext(
|
|
280
|
+
MessageInputContext,
|
|
281
|
+
) as unknown as MessageInputContextValue<StreamChatGenerics>;
|
|
282
|
+
|
|
283
|
+
return contextValue;
|
|
284
|
+
};
|
|
285
|
+
|
|
270
286
|
const areEqual = <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>(
|
|
271
287
|
prevProps: ReplyPropsWithContext<StreamChatGenerics>,
|
|
272
288
|
nextProps: ReplyPropsWithContext<StreamChatGenerics>,
|
|
@@ -307,7 +323,7 @@ export const Reply = <
|
|
|
307
323
|
const { FileAttachmentIcon = FileIconDefault, MessageAvatar = MessageAvatarDefault } =
|
|
308
324
|
useMessagesContext<StreamChatGenerics>();
|
|
309
325
|
|
|
310
|
-
const { editing, quotedMessage } =
|
|
326
|
+
const { editing, quotedMessage } = useMessageInputContextIfAvailable<StreamChatGenerics>();
|
|
311
327
|
|
|
312
328
|
const quotedEditingMessage = (
|
|
313
329
|
typeof editing !== 'boolean' ? editing?.quoted_message || false : false
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import { render, waitFor } from '@testing-library/react-native';
|
|
4
|
+
|
|
5
|
+
import { OverlayProvider } from '../../../contexts/overlayContext/OverlayProvider';
|
|
6
|
+
import { getOrCreateChannelApi } from '../../../mock-builders/api/getOrCreateChannel';
|
|
7
|
+
import { useMockedApis } from '../../../mock-builders/api/useMockedApis';
|
|
8
|
+
import { generateChannelResponse } from '../../../mock-builders/generator/channel';
|
|
9
|
+
import { getTestClientWithUser } from '../../../mock-builders/mock';
|
|
10
|
+
import { Channel } from '../../Channel/Channel';
|
|
11
|
+
import { Chat } from '../../Chat/Chat';
|
|
12
|
+
import { Reply } from '../Reply';
|
|
13
|
+
|
|
14
|
+
describe('<Reply/>', () => {
|
|
15
|
+
it('can be rendered outside of a MessageInputProvider', async () => {
|
|
16
|
+
const oldEnvironment = process.env;
|
|
17
|
+
process.env.NODE_ENV = 'not_test';
|
|
18
|
+
|
|
19
|
+
const chatClient = await getTestClientWithUser({ id: 'neil' });
|
|
20
|
+
|
|
21
|
+
const mockedChannel = generateChannelResponse();
|
|
22
|
+
useMockedApis(chatClient, [getOrCreateChannelApi(mockedChannel)]);
|
|
23
|
+
const channel = chatClient.channel('messaging', 'some-chat');
|
|
24
|
+
await channel.watch();
|
|
25
|
+
|
|
26
|
+
const TestComponent = () => (
|
|
27
|
+
<OverlayProvider>
|
|
28
|
+
<Chat client={chatClient}>
|
|
29
|
+
<Channel channel={channel} client={chatClient}>
|
|
30
|
+
<Reply />
|
|
31
|
+
</Channel>
|
|
32
|
+
</Chat>
|
|
33
|
+
</OverlayProvider>
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
try {
|
|
37
|
+
const { toJSON } = render(<TestComponent />);
|
|
38
|
+
|
|
39
|
+
await waitFor(() => {
|
|
40
|
+
expect(toJSON()).not.toBeNull();
|
|
41
|
+
});
|
|
42
|
+
} catch (error: unknown) {
|
|
43
|
+
throw new Error(`Error thrown while rendering Reply: ${error}`);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
process.env = oldEnvironment;
|
|
47
|
+
});
|
|
48
|
+
});
|
|
@@ -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);
|