stream-chat-react-native-core 4.5.1-beta.1 → 4.6.0-beta.1
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/FileIcon.js +9 -1
- package/lib/commonjs/components/Attachment/FileIcon.js.map +1 -1
- package/lib/commonjs/components/AttachmentPicker/AttachmentPicker.js +208 -31
- package/lib/commonjs/components/AttachmentPicker/AttachmentPicker.js.map +1 -1
- package/lib/commonjs/components/Message/MessageSimple/MessageContent.js +39 -21
- package/lib/commonjs/components/Message/MessageSimple/MessageContent.js.map +1 -1
- package/lib/commonjs/components/MessageInput/FileUploadPreview.js +1 -1
- package/lib/commonjs/components/MessageInput/FileUploadPreview.js.map +1 -1
- package/lib/commonjs/components/MessageInput/MessageInput.js +129 -44
- package/lib/commonjs/components/MessageInput/MessageInput.js.map +1 -1
- package/lib/commonjs/components/Reply/Reply.js +25 -9
- package/lib/commonjs/components/Reply/Reply.js.map +1 -1
- package/lib/commonjs/contexts/attachmentPickerContext/AttachmentPickerContext.js +15 -8
- package/lib/commonjs/contexts/attachmentPickerContext/AttachmentPickerContext.js.map +1 -1
- package/lib/commonjs/contexts/messageInputContext/MessageInputContext.js +10 -7
- package/lib/commonjs/contexts/messageInputContext/MessageInputContext.js.map +1 -1
- package/lib/commonjs/contexts/messageInputContext/hooks/useMessageDetailsForState.js +16 -1
- package/lib/commonjs/contexts/messageInputContext/hooks/useMessageDetailsForState.js.map +1 -1
- package/lib/commonjs/contexts/themeContext/utils/theme.js +1 -0
- package/lib/commonjs/contexts/themeContext/utils/theme.js.map +1 -1
- package/lib/commonjs/icons/Recorder.js +47 -0
- package/lib/commonjs/icons/Recorder.js.map +1 -0
- package/lib/commonjs/icons/Video.js +82 -0
- package/lib/commonjs/icons/Video.js.map +1 -0
- package/lib/commonjs/icons/index.js +26 -0
- package/lib/commonjs/icons/index.js.map +1 -1
- package/lib/commonjs/native.js.map +1 -1
- package/lib/commonjs/version.json +1 -1
- package/lib/module/components/Attachment/FileIcon.js +9 -1
- package/lib/module/components/Attachment/FileIcon.js.map +1 -1
- package/lib/module/components/AttachmentPicker/AttachmentPicker.js +208 -31
- package/lib/module/components/AttachmentPicker/AttachmentPicker.js.map +1 -1
- package/lib/module/components/Message/MessageSimple/MessageContent.js +39 -21
- package/lib/module/components/Message/MessageSimple/MessageContent.js.map +1 -1
- package/lib/module/components/MessageInput/FileUploadPreview.js +1 -1
- package/lib/module/components/MessageInput/FileUploadPreview.js.map +1 -1
- package/lib/module/components/MessageInput/MessageInput.js +129 -44
- package/lib/module/components/MessageInput/MessageInput.js.map +1 -1
- package/lib/module/components/Reply/Reply.js +25 -9
- package/lib/module/components/Reply/Reply.js.map +1 -1
- package/lib/module/contexts/attachmentPickerContext/AttachmentPickerContext.js +15 -8
- package/lib/module/contexts/attachmentPickerContext/AttachmentPickerContext.js.map +1 -1
- package/lib/module/contexts/messageInputContext/MessageInputContext.js +10 -7
- package/lib/module/contexts/messageInputContext/MessageInputContext.js.map +1 -1
- package/lib/module/contexts/messageInputContext/hooks/useMessageDetailsForState.js +16 -1
- package/lib/module/contexts/messageInputContext/hooks/useMessageDetailsForState.js.map +1 -1
- package/lib/module/contexts/themeContext/utils/theme.js +1 -0
- package/lib/module/contexts/themeContext/utils/theme.js.map +1 -1
- package/lib/module/icons/Recorder.js +47 -0
- package/lib/module/icons/Recorder.js.map +1 -0
- package/lib/module/icons/Video.js +82 -0
- package/lib/module/icons/Video.js.map +1 -0
- package/lib/module/icons/index.js +26 -0
- package/lib/module/icons/index.js.map +1 -1
- package/lib/module/native.js.map +1 -1
- package/lib/module/version.json +1 -1
- package/lib/typescript/components/MessageInput/MessageInput.d.ts +1 -1
- package/lib/typescript/contexts/attachmentPickerContext/AttachmentPickerContext.d.ts +3 -2
- package/lib/typescript/contexts/messageInputContext/MessageInputContext.d.ts +4 -15
- package/lib/typescript/contexts/themeContext/utils/theme.d.ts +1 -0
- package/lib/typescript/icons/Recorder.d.ts +3 -0
- package/lib/typescript/icons/Video.d.ts +3 -0
- package/lib/typescript/icons/index.d.ts +2 -0
- package/lib/typescript/native.d.ts +3 -14
- package/lib/typescript/types/types.d.ts +24 -0
- package/package.json +1 -1
- package/src/components/Attachment/FileIcon.tsx +45 -0
- package/src/components/AttachmentPicker/AttachmentPicker.tsx +172 -22
- package/src/components/Message/MessageSimple/MessageContent.tsx +23 -12
- package/src/components/MessageInput/FileUploadPreview.tsx +1 -1
- package/src/components/MessageInput/MessageInput.tsx +106 -19
- package/src/components/Reply/Reply.tsx +31 -14
- package/src/components/Thread/__tests__/__snapshots__/Thread.test.js.snap +12 -0
- package/src/contexts/attachmentPickerContext/AttachmentPickerContext.tsx +6 -2
- package/src/contexts/messageInputContext/MessageInputContext.tsx +17 -24
- package/src/contexts/messageInputContext/hooks/useMessageDetailsForState.ts +17 -1
- package/src/contexts/themeContext/utils/theme.ts +2 -0
- package/src/icons/Recorder.tsx +16 -0
- package/src/icons/Video.tsx +37 -0
- package/src/icons/index.ts +2 -0
- package/src/native.ts +4 -14
- package/src/types/types.ts +27 -0
- package/src/version.json +1 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { FlatList as DefaultFlatList } from 'react-native';
|
|
2
2
|
import type { NetInfoSubscription } from '@react-native-community/netinfo';
|
|
3
|
+
import type { Asset, File } from './types/types';
|
|
3
4
|
declare type CompressImage = ({ compressImageQuality, height, uri, width, }: {
|
|
4
5
|
compressImageQuality: number;
|
|
5
6
|
height: number;
|
|
@@ -11,15 +12,8 @@ declare type DeleteFile = ({ uri }: {
|
|
|
11
12
|
uri: string;
|
|
12
13
|
}) => Promise<boolean> | never;
|
|
13
14
|
export declare let deleteFile: DeleteFile;
|
|
14
|
-
declare type GetLocalAssetUri = (uriOrAssetId: string) =>
|
|
15
|
+
declare type GetLocalAssetUri = (uriOrAssetId: string) => never;
|
|
15
16
|
export declare let getLocalAssetUri: GetLocalAssetUri;
|
|
16
|
-
export declare type Asset = {
|
|
17
|
-
height: number;
|
|
18
|
-
source: 'camera' | 'picker';
|
|
19
|
-
uri: string;
|
|
20
|
-
width: number;
|
|
21
|
-
id?: string;
|
|
22
|
-
};
|
|
23
17
|
declare type GetPhotos = ({ after, first }: {
|
|
24
18
|
first: number;
|
|
25
19
|
after?: string;
|
|
@@ -41,12 +35,7 @@ declare type PickDocument = ({ maxNumberOfFiles }: {
|
|
|
41
35
|
maxNumberOfFiles?: number;
|
|
42
36
|
}) => Promise<{
|
|
43
37
|
cancelled: boolean;
|
|
44
|
-
docs?:
|
|
45
|
-
name: string;
|
|
46
|
-
size?: number | string;
|
|
47
|
-
type?: string;
|
|
48
|
-
uri?: string;
|
|
49
|
-
}[];
|
|
38
|
+
docs?: File[];
|
|
50
39
|
}> | never;
|
|
51
40
|
export declare let pickDocument: PickDocument;
|
|
52
41
|
declare type SaveFileOptions = {
|
|
@@ -1,4 +1,28 @@
|
|
|
1
1
|
import type { ExtendableGenerics, LiteralStringForUnion } from 'stream-chat';
|
|
2
|
+
export declare type Asset = {
|
|
3
|
+
duration: number | null;
|
|
4
|
+
filename: string;
|
|
5
|
+
fileSize: string;
|
|
6
|
+
height: number;
|
|
7
|
+
playableDuration: number | null;
|
|
8
|
+
source: 'camera' | 'picker';
|
|
9
|
+
type: string;
|
|
10
|
+
uri: string;
|
|
11
|
+
width: number;
|
|
12
|
+
id?: string;
|
|
13
|
+
size?: number | string;
|
|
14
|
+
};
|
|
15
|
+
export declare type File = {
|
|
16
|
+
name: string;
|
|
17
|
+
duration?: string | null;
|
|
18
|
+
size?: number | string;
|
|
19
|
+
type?: string;
|
|
20
|
+
uri?: string;
|
|
21
|
+
};
|
|
22
|
+
export declare type DefaultAttachmentType = UnknownType & {
|
|
23
|
+
file_size?: number | string;
|
|
24
|
+
mime_type?: string;
|
|
25
|
+
};
|
|
2
26
|
interface DefaultUserType extends UnknownType {
|
|
3
27
|
image?: string;
|
|
4
28
|
}
|
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.
|
|
4
|
+
"version": "4.6.0-beta.1",
|
|
5
5
|
"author": {
|
|
6
6
|
"company": "Stream.io Inc",
|
|
7
7
|
"name": "Stream.io Inc"
|
|
@@ -19,6 +19,7 @@ import { SEVEN_Z } from '../../icons/SEVEN_Z';
|
|
|
19
19
|
import { TAR } from '../../icons/TAR';
|
|
20
20
|
import { TXT } from '../../icons/TXT';
|
|
21
21
|
import type { IconProps } from '../../icons/utils/base';
|
|
22
|
+
import { Video } from '../../icons/Video';
|
|
22
23
|
import { XLS } from '../../icons/XLS';
|
|
23
24
|
import { XLSX } from '../../icons/XLSX';
|
|
24
25
|
import { ZIP } from '../../icons/ZIP';
|
|
@@ -320,6 +321,46 @@ const zipFileTypes = [
|
|
|
320
321
|
'application/zip',
|
|
321
322
|
];
|
|
322
323
|
|
|
324
|
+
const videoFileTypes = [
|
|
325
|
+
'video/3g2',
|
|
326
|
+
'video/3gp',
|
|
327
|
+
'video/aaf',
|
|
328
|
+
'video/asf',
|
|
329
|
+
'video/avchd',
|
|
330
|
+
'video/avi',
|
|
331
|
+
'video/drc',
|
|
332
|
+
'video/flv',
|
|
333
|
+
'video/m2v',
|
|
334
|
+
'video/m3u8',
|
|
335
|
+
'video/m4p',
|
|
336
|
+
'video/m4v',
|
|
337
|
+
'video/mkv',
|
|
338
|
+
'video/mng',
|
|
339
|
+
'video/mov',
|
|
340
|
+
'video/mp2',
|
|
341
|
+
'video/mp4',
|
|
342
|
+
'video/mpe',
|
|
343
|
+
'video/mpeg',
|
|
344
|
+
'video/mpg',
|
|
345
|
+
'video/mpv',
|
|
346
|
+
'video/mxf',
|
|
347
|
+
'video/nsv',
|
|
348
|
+
'video/ogg',
|
|
349
|
+
'video/ogv',
|
|
350
|
+
'video/qt',
|
|
351
|
+
'video/rm',
|
|
352
|
+
'video/rmvb',
|
|
353
|
+
'video/roq',
|
|
354
|
+
'video/svi',
|
|
355
|
+
'video/vob',
|
|
356
|
+
'video/webm',
|
|
357
|
+
'video/wmv',
|
|
358
|
+
'video/yuv',
|
|
359
|
+
'video/quicktime',
|
|
360
|
+
'video/webm',
|
|
361
|
+
'video/x-flv',
|
|
362
|
+
];
|
|
363
|
+
|
|
323
364
|
const mimeTypeToIconMap: Record<string, React.FC<IconProps>> = {
|
|
324
365
|
'application/pdf': PDF, // .pdf
|
|
325
366
|
'application/rtf': RTF, // .rtf
|
|
@@ -371,6 +412,10 @@ for (const type of zipFileTypes) {
|
|
|
371
412
|
mimeTypeToIconMap[type] = ZIP;
|
|
372
413
|
}
|
|
373
414
|
|
|
415
|
+
for (const type of videoFileTypes) {
|
|
416
|
+
mimeTypeToIconMap[type] = Video;
|
|
417
|
+
}
|
|
418
|
+
|
|
374
419
|
function mimeTypeToIcon(mimeType?: string): React.FC<IconProps> {
|
|
375
420
|
if (!mimeType) return GenericFile;
|
|
376
421
|
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
Platform,
|
|
8
8
|
StatusBar,
|
|
9
9
|
StyleSheet,
|
|
10
|
+
Text,
|
|
10
11
|
View,
|
|
11
12
|
} from 'react-native';
|
|
12
13
|
|
|
@@ -15,42 +16,161 @@ import BottomSheet, {
|
|
|
15
16
|
BottomSheetHandleProps,
|
|
16
17
|
TouchableOpacity,
|
|
17
18
|
} from '@gorhom/bottom-sheet';
|
|
19
|
+
import dayjs from 'dayjs';
|
|
20
|
+
import duration from 'dayjs/plugin/duration';
|
|
21
|
+
import { lookup } from 'mime-types';
|
|
18
22
|
|
|
19
23
|
import type { AttachmentPickerErrorProps } from './components/AttachmentPickerError';
|
|
20
24
|
|
|
21
25
|
import { useAttachmentPickerContext } from '../../contexts/attachmentPickerContext/AttachmentPickerContext';
|
|
22
26
|
import { useTheme } from '../../contexts/themeContext/ThemeContext';
|
|
23
|
-
import {
|
|
27
|
+
import { Recorder } from '../../icons';
|
|
28
|
+
import { getPhotos } from '../../native';
|
|
29
|
+
import type { Asset, File } from '../../types/types';
|
|
24
30
|
import { vh, vw } from '../../utils/utils';
|
|
25
31
|
|
|
32
|
+
dayjs.extend(duration);
|
|
33
|
+
|
|
26
34
|
const styles = StyleSheet.create({
|
|
27
35
|
container: {
|
|
28
36
|
flexGrow: 1,
|
|
29
37
|
},
|
|
38
|
+
durationText: {
|
|
39
|
+
fontWeight: 'bold',
|
|
40
|
+
},
|
|
30
41
|
overlay: {
|
|
31
42
|
alignItems: 'flex-end',
|
|
32
43
|
flex: 1,
|
|
33
44
|
},
|
|
45
|
+
videoView: {
|
|
46
|
+
bottom: 5,
|
|
47
|
+
display: 'flex',
|
|
48
|
+
flexDirection: 'row',
|
|
49
|
+
justifyContent: 'space-between',
|
|
50
|
+
paddingHorizontal: 5,
|
|
51
|
+
position: 'absolute',
|
|
52
|
+
width: '100%',
|
|
53
|
+
},
|
|
34
54
|
});
|
|
35
55
|
|
|
36
56
|
const screenHeight = vh(100);
|
|
37
57
|
const fullScreenHeight = Dimensions.get('window').height;
|
|
38
58
|
|
|
39
59
|
type AttachmentImageProps = {
|
|
60
|
+
asset: Asset;
|
|
61
|
+
ImageOverlaySelectedComponent: React.ComponentType;
|
|
62
|
+
maxNumberOfFiles: number;
|
|
63
|
+
selected: boolean;
|
|
64
|
+
setSelectedImages: React.Dispatch<React.SetStateAction<Asset[]>>;
|
|
65
|
+
numberOfAttachmentPickerImageColumns?: number;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
type AttachmentVideoProps = {
|
|
69
|
+
asset: Asset;
|
|
40
70
|
ImageOverlaySelectedComponent: React.ComponentType;
|
|
41
|
-
|
|
71
|
+
maxNumberOfFiles: number;
|
|
42
72
|
selected: boolean;
|
|
43
|
-
|
|
73
|
+
setSelectedFiles: React.Dispatch<React.SetStateAction<File[]>>;
|
|
44
74
|
numberOfAttachmentPickerImageColumns?: number;
|
|
45
75
|
};
|
|
46
76
|
|
|
77
|
+
const AttachmentVideo: React.FC<AttachmentVideoProps> = (props) => {
|
|
78
|
+
const {
|
|
79
|
+
asset,
|
|
80
|
+
ImageOverlaySelectedComponent,
|
|
81
|
+
maxNumberOfFiles,
|
|
82
|
+
numberOfAttachmentPickerImageColumns,
|
|
83
|
+
selected,
|
|
84
|
+
setSelectedFiles,
|
|
85
|
+
} = props;
|
|
86
|
+
|
|
87
|
+
const {
|
|
88
|
+
theme: {
|
|
89
|
+
attachmentPicker: { durationText, image, imageOverlay },
|
|
90
|
+
colors: { overlay, white },
|
|
91
|
+
},
|
|
92
|
+
} = useTheme();
|
|
93
|
+
|
|
94
|
+
const { duration, playableDuration, uri } = asset;
|
|
95
|
+
|
|
96
|
+
const videoDuration = duration ? duration : playableDuration;
|
|
97
|
+
|
|
98
|
+
const ONE_HOUR_IN_SECONDS = 3600;
|
|
99
|
+
|
|
100
|
+
let durationLabel = '00:00';
|
|
101
|
+
|
|
102
|
+
if (videoDuration) {
|
|
103
|
+
const isDurationLongerThanHour = videoDuration / ONE_HOUR_IN_SECONDS >= 1;
|
|
104
|
+
const formattedDurationParam = isDurationLongerThanHour ? 'HH:mm:ss' : 'mm:ss';
|
|
105
|
+
const formattedVideoDuration = dayjs
|
|
106
|
+
.duration(videoDuration, 'second')
|
|
107
|
+
.format(formattedDurationParam);
|
|
108
|
+
durationLabel = formattedVideoDuration;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const size = vw(100) / (numberOfAttachmentPickerImageColumns || 3) - 2;
|
|
112
|
+
|
|
113
|
+
const onPressVideo = () => {
|
|
114
|
+
if (selected) {
|
|
115
|
+
setSelectedFiles((files) => files.filter((file) => file.uri !== asset.uri));
|
|
116
|
+
} else {
|
|
117
|
+
setSelectedFiles((files) => {
|
|
118
|
+
if (files.length >= maxNumberOfFiles) {
|
|
119
|
+
return files;
|
|
120
|
+
}
|
|
121
|
+
return [
|
|
122
|
+
...files,
|
|
123
|
+
{
|
|
124
|
+
duration: durationLabel,
|
|
125
|
+
name: asset.filename,
|
|
126
|
+
size: asset.fileSize,
|
|
127
|
+
type: 'video',
|
|
128
|
+
uri: asset.uri,
|
|
129
|
+
},
|
|
130
|
+
];
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
return (
|
|
136
|
+
<TouchableOpacity onPress={onPressVideo}>
|
|
137
|
+
<ImageBackground
|
|
138
|
+
source={{ uri }}
|
|
139
|
+
style={[
|
|
140
|
+
{
|
|
141
|
+
height: size,
|
|
142
|
+
margin: 1,
|
|
143
|
+
width: size,
|
|
144
|
+
},
|
|
145
|
+
image,
|
|
146
|
+
]}
|
|
147
|
+
>
|
|
148
|
+
{selected && (
|
|
149
|
+
<View style={[styles.overlay, { backgroundColor: overlay }, imageOverlay]}>
|
|
150
|
+
<ImageOverlaySelectedComponent />
|
|
151
|
+
</View>
|
|
152
|
+
)}
|
|
153
|
+
<View style={styles.videoView}>
|
|
154
|
+
<Recorder height={20} pathFill={white} width={25} />
|
|
155
|
+
{videoDuration ? (
|
|
156
|
+
<Text style={[styles.durationText, durationText, { color: white }]}>
|
|
157
|
+
{durationLabel}
|
|
158
|
+
</Text>
|
|
159
|
+
) : null}
|
|
160
|
+
</View>
|
|
161
|
+
</ImageBackground>
|
|
162
|
+
</TouchableOpacity>
|
|
163
|
+
);
|
|
164
|
+
};
|
|
165
|
+
|
|
47
166
|
const AttachmentImage: React.FC<AttachmentImageProps> = (props) => {
|
|
48
167
|
const {
|
|
168
|
+
asset,
|
|
49
169
|
ImageOverlaySelectedComponent,
|
|
170
|
+
maxNumberOfFiles,
|
|
50
171
|
numberOfAttachmentPickerImageColumns,
|
|
51
|
-
onPress,
|
|
52
172
|
selected,
|
|
53
|
-
|
|
173
|
+
setSelectedImages,
|
|
54
174
|
} = props;
|
|
55
175
|
const {
|
|
56
176
|
theme: {
|
|
@@ -61,8 +181,23 @@ const AttachmentImage: React.FC<AttachmentImageProps> = (props) => {
|
|
|
61
181
|
|
|
62
182
|
const size = vw(100) / (numberOfAttachmentPickerImageColumns || 3) - 2;
|
|
63
183
|
|
|
184
|
+
const { uri } = asset;
|
|
185
|
+
|
|
186
|
+
const onPressImage = () => {
|
|
187
|
+
if (selected) {
|
|
188
|
+
setSelectedImages((images) => images.filter((image) => image.uri !== asset.uri));
|
|
189
|
+
} else {
|
|
190
|
+
setSelectedImages((images) => {
|
|
191
|
+
if (images.length >= maxNumberOfFiles) {
|
|
192
|
+
return images;
|
|
193
|
+
}
|
|
194
|
+
return [...images, asset];
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
|
|
64
199
|
return (
|
|
65
|
-
<TouchableOpacity onPress={
|
|
200
|
+
<TouchableOpacity onPress={onPressImage}>
|
|
66
201
|
<ImageBackground
|
|
67
202
|
source={{ uri }}
|
|
68
203
|
style={[
|
|
@@ -92,6 +227,7 @@ const renderImage = ({
|
|
|
92
227
|
ImageOverlaySelectedComponent: React.ComponentType;
|
|
93
228
|
maxNumberOfFiles: number;
|
|
94
229
|
selected: boolean;
|
|
230
|
+
setSelectedFiles: React.Dispatch<React.SetStateAction<File[]>>;
|
|
95
231
|
setSelectedImages: React.Dispatch<React.SetStateAction<Asset[]>>;
|
|
96
232
|
numberOfAttachmentPickerImageColumns?: number;
|
|
97
233
|
};
|
|
@@ -102,28 +238,37 @@ const renderImage = ({
|
|
|
102
238
|
maxNumberOfFiles,
|
|
103
239
|
numberOfAttachmentPickerImageColumns,
|
|
104
240
|
selected,
|
|
241
|
+
setSelectedFiles,
|
|
105
242
|
setSelectedImages,
|
|
106
243
|
} = item;
|
|
107
|
-
const onPress = () => {
|
|
108
|
-
if (selected) {
|
|
109
|
-
setSelectedImages((images) => images.filter((image) => image.uri !== asset.uri));
|
|
110
|
-
} else {
|
|
111
|
-
setSelectedImages((images) => {
|
|
112
|
-
if (images.length >= maxNumberOfFiles) {
|
|
113
|
-
return images;
|
|
114
|
-
}
|
|
115
|
-
return [...images, asset];
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
|
-
};
|
|
119
244
|
|
|
120
|
-
|
|
245
|
+
const contentType = lookup(asset.filename) || 'multipart/form-data';
|
|
246
|
+
|
|
247
|
+
const fileType = asset.filename
|
|
248
|
+
? contentType.startsWith('image/')
|
|
249
|
+
? 'image'
|
|
250
|
+
: 'video'
|
|
251
|
+
: asset.type === 'video'
|
|
252
|
+
? 'video'
|
|
253
|
+
: 'image';
|
|
254
|
+
|
|
255
|
+
return fileType === 'image' ? (
|
|
121
256
|
<AttachmentImage
|
|
257
|
+
asset={asset}
|
|
258
|
+
ImageOverlaySelectedComponent={ImageOverlaySelectedComponent}
|
|
259
|
+
maxNumberOfFiles={maxNumberOfFiles}
|
|
260
|
+
numberOfAttachmentPickerImageColumns={numberOfAttachmentPickerImageColumns}
|
|
261
|
+
selected={selected}
|
|
262
|
+
setSelectedImages={setSelectedImages}
|
|
263
|
+
/>
|
|
264
|
+
) : (
|
|
265
|
+
<AttachmentVideo
|
|
266
|
+
asset={asset}
|
|
122
267
|
ImageOverlaySelectedComponent={ImageOverlaySelectedComponent}
|
|
268
|
+
maxNumberOfFiles={maxNumberOfFiles}
|
|
123
269
|
numberOfAttachmentPickerImageColumns={numberOfAttachmentPickerImageColumns}
|
|
124
|
-
onPress={onPress}
|
|
125
270
|
selected={selected}
|
|
126
|
-
|
|
271
|
+
setSelectedFiles={setSelectedFiles}
|
|
127
272
|
/>
|
|
128
273
|
);
|
|
129
274
|
};
|
|
@@ -187,8 +332,10 @@ export const AttachmentPicker = React.forwardRef(
|
|
|
187
332
|
const {
|
|
188
333
|
closePicker,
|
|
189
334
|
maxNumberOfFiles,
|
|
335
|
+
selectedFiles,
|
|
190
336
|
selectedImages,
|
|
191
337
|
selectedPicker,
|
|
338
|
+
setSelectedFiles,
|
|
192
339
|
setSelectedImages,
|
|
193
340
|
setSelectedPicker,
|
|
194
341
|
topInset,
|
|
@@ -306,7 +453,10 @@ export const AttachmentPicker = React.forwardRef(
|
|
|
306
453
|
ImageOverlaySelectedComponent,
|
|
307
454
|
maxNumberOfFiles,
|
|
308
455
|
numberOfAttachmentPickerImageColumns,
|
|
309
|
-
selected:
|
|
456
|
+
selected:
|
|
457
|
+
selectedImages.some((image) => image.uri === asset.uri) ||
|
|
458
|
+
selectedFiles.some((file) => file.uri === asset.uri),
|
|
459
|
+
setSelectedFiles,
|
|
310
460
|
setSelectedImages,
|
|
311
461
|
}));
|
|
312
462
|
|
|
@@ -143,7 +143,7 @@ const MessageContentWithContext = <
|
|
|
143
143
|
colors: { accent_red, blue_alice, grey_gainsboro, grey_whisper, transparent, white },
|
|
144
144
|
messageSimple: {
|
|
145
145
|
content: {
|
|
146
|
-
container: { borderRadiusL, borderRadiusS, ...container },
|
|
146
|
+
container: { borderRadius, borderRadiusL, borderRadiusS, ...container },
|
|
147
147
|
containerInner,
|
|
148
148
|
errorContainer,
|
|
149
149
|
errorIcon,
|
|
@@ -223,6 +223,22 @@ const MessageContentWithContext = <
|
|
|
223
223
|
|
|
224
224
|
const repliesCurveColor = isMyMessage && !error ? backgroundColor : grey_whisper;
|
|
225
225
|
|
|
226
|
+
const isBorderColor = isMyMessage && !error;
|
|
227
|
+
|
|
228
|
+
const shouldApplyBorderRadius = (firstGroupStyle: string, secondGroupStyle: string): boolean =>
|
|
229
|
+
(groupStyle === firstGroupStyle || groupStyle === secondGroupStyle) &&
|
|
230
|
+
(!hasThreadReplies || threadList);
|
|
231
|
+
|
|
232
|
+
const applyBorderRadius = (
|
|
233
|
+
firstGroupStyle: string,
|
|
234
|
+
secondGroupStyle: string,
|
|
235
|
+
): number | undefined => {
|
|
236
|
+
if (shouldApplyBorderRadius(firstGroupStyle, secondGroupStyle)) {
|
|
237
|
+
return borderRadiusS;
|
|
238
|
+
}
|
|
239
|
+
return borderRadiusL;
|
|
240
|
+
};
|
|
241
|
+
|
|
226
242
|
return (
|
|
227
243
|
<TouchableOpacity
|
|
228
244
|
activeOpacity={0.7}
|
|
@@ -297,17 +313,12 @@ const MessageContentWithContext = <
|
|
|
297
313
|
styles.containerInner,
|
|
298
314
|
{
|
|
299
315
|
backgroundColor,
|
|
300
|
-
borderBottomLeftRadius:
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
(groupStyle === 'right_bottom' || groupStyle === 'right_single') &&
|
|
307
|
-
(!hasThreadReplies || threadList)
|
|
308
|
-
? borderRadiusS
|
|
309
|
-
: borderRadiusL,
|
|
310
|
-
borderColor: isMyMessage && !error ? backgroundColor : grey_whisper,
|
|
316
|
+
borderBottomLeftRadius: applyBorderRadius('left_bottom', 'left_single'),
|
|
317
|
+
borderBottomRightRadius: applyBorderRadius('right_bottom', 'right_single'),
|
|
318
|
+
borderColor: isBorderColor ? backgroundColor : grey_whisper,
|
|
319
|
+
borderRadius,
|
|
320
|
+
borderTopLeftRadius: applyBorderRadius('left_top', 'right_single'),
|
|
321
|
+
borderTopRightRadius: applyBorderRadius('right_top', 'right_single'),
|
|
311
322
|
},
|
|
312
323
|
noBorder ? { borderWidth: 0 } : {},
|
|
313
324
|
containerInner,
|
|
@@ -105,7 +105,7 @@ const UnsupportedFileTypeOrFileSizeIndicator = ({
|
|
|
105
105
|
</View>
|
|
106
106
|
) : (
|
|
107
107
|
<Text style={[styles.fileSizeText, { color: grey }, fileSizeText]}>
|
|
108
|
-
{getFileSizeDisplayText(item.file.size)}
|
|
108
|
+
{item.file.duration ? item.file.duration : getFileSizeDisplayText(item.file.size)}
|
|
109
109
|
</Text>
|
|
110
110
|
);
|
|
111
111
|
};
|