stream-chat-react-native-core 4.11.1-beta.4 → 4.12.0-beta.3
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/AudioAttachment.js +541 -0
- package/lib/commonjs/components/Attachment/AudioAttachment.js.map +1 -0
- package/lib/commonjs/components/Attachment/FileAttachmentGroup.js +113 -10
- package/lib/commonjs/components/Attachment/FileAttachmentGroup.js.map +1 -1
- package/lib/commonjs/components/Attachment/Gallery.js +2 -2
- package/lib/commonjs/components/Attachment/Gallery.js.map +1 -1
- package/lib/commonjs/components/Attachment/{GallaryImage.js → GalleryImage.js} +3 -3
- package/lib/{module/components/Attachment/GallaryImage.js.map → commonjs/components/Attachment/GalleryImage.js.map} +1 -1
- package/lib/commonjs/components/Attachment/Giphy.js +1 -1
- package/lib/commonjs/components/Attachment/Giphy.js.map +1 -1
- package/lib/commonjs/components/Attachment/VideoThumbnail.js +10 -5
- package/lib/commonjs/components/Attachment/VideoThumbnail.js.map +1 -1
- package/lib/commonjs/components/Avatar/Avatar.js +1 -1
- package/lib/commonjs/components/Avatar/Avatar.js.map +1 -1
- package/lib/commonjs/components/Avatar/GroupAvatar.js +1 -1
- package/lib/commonjs/components/Avatar/GroupAvatar.js.map +1 -1
- package/lib/commonjs/components/Channel/Channel.js +18 -13
- package/lib/commonjs/components/Channel/Channel.js.map +1 -1
- package/lib/commonjs/components/Channel/hooks/useCreateInputMessageInputContext.js +2 -0
- package/lib/commonjs/components/Channel/hooks/useCreateInputMessageInputContext.js.map +1 -1
- package/lib/commonjs/components/ImageGallery/ImageGallery.js +37 -30
- package/lib/commonjs/components/ImageGallery/ImageGallery.js.map +1 -1
- package/lib/commonjs/components/ImageGallery/components/AnimatedGalleryImage.js +5 -3
- package/lib/commonjs/components/ImageGallery/components/AnimatedGalleryImage.js.map +1 -1
- package/lib/commonjs/components/ImageGallery/components/AnimatedGalleryVideo.js +10 -6
- package/lib/commonjs/components/ImageGallery/components/AnimatedGalleryVideo.js.map +1 -1
- package/lib/commonjs/components/ImageGallery/components/ImageGalleryFooter.js +17 -14
- package/lib/commonjs/components/ImageGallery/components/ImageGalleryFooter.js.map +1 -1
- package/lib/commonjs/components/ImageGallery/components/ImageGalleryHeader.js +1 -0
- package/lib/commonjs/components/ImageGallery/components/ImageGalleryHeader.js.map +1 -1
- package/lib/commonjs/components/ImageGallery/components/ImageGalleryOverlay.js +2 -1
- package/lib/commonjs/components/ImageGallery/components/ImageGalleryOverlay.js.map +1 -1
- package/lib/commonjs/components/ImageGallery/components/ImageGalleryVideoControl.js +37 -18
- package/lib/commonjs/components/ImageGallery/components/ImageGalleryVideoControl.js.map +1 -1
- package/lib/commonjs/components/ImageGallery/components/ImageGrid.js +3 -1
- package/lib/commonjs/components/ImageGallery/components/ImageGrid.js.map +1 -1
- package/lib/commonjs/components/ImageGallery/components/ImageGridHandle.js +5 -4
- package/lib/commonjs/components/ImageGallery/components/ImageGridHandle.js.map +1 -1
- package/lib/commonjs/components/Message/Message.js +8 -6
- package/lib/commonjs/components/Message/Message.js.map +1 -1
- package/lib/commonjs/components/Message/MessageSimple/utils/parseLinks.js +1 -1
- package/lib/commonjs/components/Message/MessageSimple/utils/parseLinks.js.map +1 -1
- package/lib/commonjs/components/Message/MessageSimple/utils/parseLinks.test.js +1 -1
- package/lib/commonjs/components/Message/MessageSimple/utils/parseLinks.test.js.map +1 -1
- package/lib/commonjs/components/MessageInput/FileUploadPreview.js +125 -35
- package/lib/commonjs/components/MessageInput/FileUploadPreview.js.map +1 -1
- package/lib/{module/components/ImageGallery/components → commonjs/components/ProgressControl}/ProgressControl.js +37 -24
- package/lib/commonjs/components/ProgressControl/ProgressControl.js.map +1 -0
- package/lib/commonjs/components/index.js +26 -0
- package/lib/commonjs/components/index.js.map +1 -1
- package/lib/commonjs/contexts/messageInputContext/MessageInputContext.js +5 -2
- package/lib/commonjs/contexts/messageInputContext/MessageInputContext.js.map +1 -1
- package/lib/commonjs/contexts/messageInputContext/hooks/useCreateMessageInputContext.js +7 -2
- package/lib/commonjs/contexts/messageInputContext/hooks/useCreateMessageInputContext.js.map +1 -1
- package/lib/commonjs/contexts/themeContext/utils/theme.js +9 -0
- package/lib/commonjs/contexts/themeContext/utils/theme.js.map +1 -1
- package/lib/commonjs/icons/Pause.js +2 -2
- package/lib/commonjs/icons/Pause.js.map +1 -1
- package/lib/commonjs/mock-builders/api/channelMocks.js +1 -0
- package/lib/commonjs/mock-builders/api/channelMocks.js.map +1 -1
- package/lib/commonjs/native.js +13 -5
- package/lib/commonjs/native.js.map +1 -1
- package/lib/commonjs/version.json +1 -1
- package/lib/module/components/Attachment/AudioAttachment.js +541 -0
- package/lib/module/components/Attachment/AudioAttachment.js.map +1 -0
- package/lib/module/components/Attachment/FileAttachmentGroup.js +113 -10
- package/lib/module/components/Attachment/FileAttachmentGroup.js.map +1 -1
- package/lib/module/components/Attachment/Gallery.js +2 -2
- package/lib/module/components/Attachment/Gallery.js.map +1 -1
- package/lib/module/components/Attachment/{GallaryImage.js → GalleryImage.js} +3 -3
- package/lib/{commonjs/components/Attachment/GallaryImage.js.map → module/components/Attachment/GalleryImage.js.map} +1 -1
- package/lib/module/components/Attachment/Giphy.js +1 -1
- package/lib/module/components/Attachment/Giphy.js.map +1 -1
- package/lib/module/components/Attachment/VideoThumbnail.js +10 -5
- package/lib/module/components/Attachment/VideoThumbnail.js.map +1 -1
- package/lib/module/components/Avatar/Avatar.js +1 -1
- package/lib/module/components/Avatar/Avatar.js.map +1 -1
- package/lib/module/components/Avatar/GroupAvatar.js +1 -1
- package/lib/module/components/Avatar/GroupAvatar.js.map +1 -1
- package/lib/module/components/Channel/Channel.js +18 -13
- package/lib/module/components/Channel/Channel.js.map +1 -1
- package/lib/module/components/Channel/hooks/useCreateInputMessageInputContext.js +2 -0
- package/lib/module/components/Channel/hooks/useCreateInputMessageInputContext.js.map +1 -1
- package/lib/module/components/ImageGallery/ImageGallery.js +37 -30
- package/lib/module/components/ImageGallery/ImageGallery.js.map +1 -1
- package/lib/module/components/ImageGallery/components/AnimatedGalleryImage.js +5 -3
- package/lib/module/components/ImageGallery/components/AnimatedGalleryImage.js.map +1 -1
- package/lib/module/components/ImageGallery/components/AnimatedGalleryVideo.js +10 -6
- package/lib/module/components/ImageGallery/components/AnimatedGalleryVideo.js.map +1 -1
- package/lib/module/components/ImageGallery/components/ImageGalleryFooter.js +17 -14
- package/lib/module/components/ImageGallery/components/ImageGalleryFooter.js.map +1 -1
- package/lib/module/components/ImageGallery/components/ImageGalleryHeader.js +1 -0
- package/lib/module/components/ImageGallery/components/ImageGalleryHeader.js.map +1 -1
- package/lib/module/components/ImageGallery/components/ImageGalleryOverlay.js +2 -1
- package/lib/module/components/ImageGallery/components/ImageGalleryOverlay.js.map +1 -1
- package/lib/module/components/ImageGallery/components/ImageGalleryVideoControl.js +37 -18
- package/lib/module/components/ImageGallery/components/ImageGalleryVideoControl.js.map +1 -1
- package/lib/module/components/ImageGallery/components/ImageGrid.js +3 -1
- package/lib/module/components/ImageGallery/components/ImageGrid.js.map +1 -1
- package/lib/module/components/ImageGallery/components/ImageGridHandle.js +5 -4
- package/lib/module/components/ImageGallery/components/ImageGridHandle.js.map +1 -1
- package/lib/module/components/Message/Message.js +8 -6
- package/lib/module/components/Message/Message.js.map +1 -1
- package/lib/module/components/Message/MessageSimple/utils/parseLinks.js +1 -1
- package/lib/module/components/Message/MessageSimple/utils/parseLinks.js.map +1 -1
- package/lib/module/components/Message/MessageSimple/utils/parseLinks.test.js +1 -1
- package/lib/module/components/Message/MessageSimple/utils/parseLinks.test.js.map +1 -1
- package/lib/module/components/MessageInput/FileUploadPreview.js +125 -35
- package/lib/module/components/MessageInput/FileUploadPreview.js.map +1 -1
- package/lib/{commonjs/components/ImageGallery/components → module/components/ProgressControl}/ProgressControl.js +37 -24
- package/lib/module/components/ProgressControl/ProgressControl.js.map +1 -0
- package/lib/module/components/index.js +26 -0
- package/lib/module/components/index.js.map +1 -1
- package/lib/module/contexts/messageInputContext/MessageInputContext.js +5 -2
- package/lib/module/contexts/messageInputContext/MessageInputContext.js.map +1 -1
- package/lib/module/contexts/messageInputContext/hooks/useCreateMessageInputContext.js +7 -2
- package/lib/module/contexts/messageInputContext/hooks/useCreateMessageInputContext.js.map +1 -1
- package/lib/module/contexts/themeContext/utils/theme.js +9 -0
- package/lib/module/contexts/themeContext/utils/theme.js.map +1 -1
- package/lib/module/icons/Pause.js +2 -2
- package/lib/module/icons/Pause.js.map +1 -1
- package/lib/module/mock-builders/api/channelMocks.js +1 -0
- package/lib/module/mock-builders/api/channelMocks.js.map +1 -1
- package/lib/module/native.js +13 -5
- package/lib/module/native.js.map +1 -1
- package/lib/module/version.json +1 -1
- package/lib/typescript/components/Attachment/AudioAttachment.d.ts +26 -0
- package/lib/typescript/components/Attachment/FileAttachmentGroup.d.ts +2 -1
- package/lib/typescript/components/Attachment/{GallaryImage.d.ts → GalleryImage.d.ts} +0 -0
- package/lib/typescript/components/Channel/hooks/useCreateInputMessageInputContext.d.ts +1 -1
- package/lib/typescript/components/ImageGallery/__tests__/AnimatedVideoGallery.test.d.ts +1 -0
- package/lib/typescript/components/ImageGallery/__tests__/ImageGallery.test.d.ts +1 -0
- package/lib/typescript/components/ImageGallery/__tests__/ImageGalleryFooter.test.d.ts +1 -0
- package/lib/typescript/components/ImageGallery/__tests__/ImageGalleryGrid.test.d.ts +1 -0
- package/lib/typescript/components/ImageGallery/__tests__/ImageGalleryGridHandle.test.d.ts +1 -0
- package/lib/typescript/components/ImageGallery/__tests__/ImageGalleryHeader.test.d.ts +1 -0
- package/lib/typescript/components/ImageGallery/__tests__/ImageGalleryOverlay.test.d.ts +1 -0
- package/lib/typescript/components/ImageGallery/__tests__/ImageGalleryVideoControl.test.d.ts +1 -0
- package/lib/typescript/components/ImageGallery/components/AnimatedGalleryImage.d.ts +1 -0
- package/lib/typescript/components/ImageGallery/components/AnimatedGalleryVideo.d.ts +2 -3
- package/lib/typescript/components/ImageGallery/components/ImageGalleryFooter.d.ts +2 -1
- package/lib/typescript/components/ImageGallery/components/ImageGrid.d.ts +2 -3
- package/lib/typescript/components/Message/hooks/useMessageActionHandlers.d.ts +1 -1
- package/lib/typescript/components/Message/hooks/useMessageActions.d.ts +1 -1
- package/lib/typescript/components/MessageInput/FileUploadPreview.d.ts +1 -1
- package/lib/typescript/components/MessageInput/__tests__/AudioAttachmentUploadPreviewExpo.test.d.ts +1 -0
- package/lib/typescript/components/MessageInput/__tests__/AudioAttachmentUploadPreviewNative.test.d.ts +1 -0
- package/lib/typescript/components/ProgressControl/ProgressControl.d.ts +11 -0
- package/lib/typescript/components/index.d.ts +2 -0
- package/lib/typescript/contexts/messageContext/MessageContext.d.ts +1 -1
- package/lib/typescript/contexts/messageInputContext/MessageInputContext.d.ts +7 -1
- package/lib/typescript/contexts/messageInputContext/hooks/useCreateMessageInputContext.d.ts +1 -1
- package/lib/typescript/contexts/themeContext/utils/theme.d.ts +9 -0
- package/lib/typescript/native.d.ts +59 -2
- package/package.json +1 -1
- package/src/components/Attachment/AudioAttachment.tsx +357 -0
- package/src/components/Attachment/FileAttachmentGroup.tsx +96 -7
- package/src/components/Attachment/Gallery.tsx +1 -1
- package/src/components/Attachment/{GallaryImage.tsx → GalleryImage.tsx} +1 -1
- package/src/components/Attachment/Giphy.tsx +1 -1
- package/src/components/Attachment/VideoThumbnail.tsx +4 -4
- package/src/components/Attachment/__tests__/Gallery.test.js +6 -6
- package/src/components/Attachment/__tests__/Giphy.test.js +4 -4
- package/src/components/Avatar/Avatar.tsx +1 -1
- package/src/components/Avatar/GroupAvatar.tsx +1 -1
- package/src/components/Channel/Channel.tsx +3 -0
- package/src/components/Channel/hooks/useCreateInputMessageInputContext.ts +2 -0
- package/src/components/ImageGallery/ImageGallery.tsx +21 -11
- package/src/components/ImageGallery/__tests__/AnimatedVideoGallery.test.tsx +241 -0
- package/src/components/ImageGallery/__tests__/ImageGallery.test.tsx +192 -0
- package/src/components/ImageGallery/__tests__/ImageGalleryFooter.test.tsx +190 -0
- package/src/components/ImageGallery/__tests__/ImageGalleryGrid.test.tsx +98 -0
- package/src/components/ImageGallery/__tests__/ImageGalleryGridHandle.test.tsx +79 -0
- package/src/components/ImageGallery/__tests__/ImageGalleryHeader.test.tsx +172 -0
- package/src/components/ImageGallery/__tests__/ImageGalleryOverlay.test.tsx +94 -0
- package/src/components/ImageGallery/__tests__/ImageGalleryVideoControl.test.tsx +84 -0
- package/src/components/ImageGallery/components/AnimatedGalleryImage.tsx +3 -0
- package/src/components/ImageGallery/components/AnimatedGalleryVideo.tsx +11 -3
- package/src/components/ImageGallery/components/ImageGalleryFooter.tsx +9 -2
- package/src/components/ImageGallery/components/ImageGalleryHeader.tsx +1 -1
- package/src/components/ImageGallery/components/ImageGalleryOverlay.tsx +6 -1
- package/src/components/ImageGallery/components/ImageGalleryVideoControl.tsx +27 -9
- package/src/components/ImageGallery/components/ImageGrid.tsx +19 -17
- package/src/components/ImageGallery/components/ImageGridHandle.tsx +4 -1
- package/src/components/Message/Message.tsx +2 -1
- package/src/components/Message/MessageSimple/__tests__/MessageContent.test.js +11 -3
- package/src/components/Message/MessageSimple/__tests__/__snapshots__/MessageAvatar.test.js.snap +1 -1
- package/src/components/Message/MessageSimple/utils/parseLinks.test.ts +4 -0
- package/src/components/Message/MessageSimple/utils/parseLinks.ts +1 -1
- package/src/components/MessageInput/FileUploadPreview.tsx +162 -66
- package/src/components/MessageInput/__tests__/AudioAttachmentUploadPreviewExpo.test.tsx +196 -0
- package/src/components/MessageInput/__tests__/AudioAttachmentUploadPreviewNative.test.tsx +212 -0
- package/src/components/MessageInput/__tests__/FileUploadPreview.test.js +64 -0
- package/src/components/{ImageGallery/components → ProgressControl}/ProgressControl.tsx +37 -19
- package/src/components/Thread/__tests__/__snapshots__/Thread.test.js.snap +4 -4
- package/src/components/index.ts +3 -0
- package/src/contexts/messageInputContext/MessageInputContext.tsx +11 -0
- package/src/contexts/messageInputContext/hooks/useCreateMessageInputContext.ts +5 -1
- package/src/contexts/themeContext/utils/theme.ts +15 -0
- package/src/icons/Pause.tsx +2 -2
- package/src/mock-builders/api/channelMocks.tsx +1 -0
- package/src/native.ts +67 -7
- package/src/version.json +1 -1
- package/lib/commonjs/components/ImageGallery/components/ProgressControl.js.map +0 -1
- package/lib/module/components/ImageGallery/components/ProgressControl.js.map +0 -1
- package/lib/typescript/components/ImageGallery/components/ProgressControl.d.ts +0 -5
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
import React, { useEffect } from 'react';
|
|
2
|
+
import { I18nManager, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
|
|
3
|
+
|
|
4
|
+
import dayjs from 'dayjs';
|
|
5
|
+
import duration from 'dayjs/plugin/duration';
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
FileUpload,
|
|
9
|
+
MessageInputContextValue,
|
|
10
|
+
useMessageInputContext,
|
|
11
|
+
useTheme,
|
|
12
|
+
} from '../../contexts';
|
|
13
|
+
import { Pause, Play } from '../../icons';
|
|
14
|
+
import {
|
|
15
|
+
PlaybackStatus,
|
|
16
|
+
Sound,
|
|
17
|
+
SoundReturnType,
|
|
18
|
+
VideoPayloadData,
|
|
19
|
+
VideoProgressData,
|
|
20
|
+
} from '../../native';
|
|
21
|
+
import type { DefaultStreamChatGenerics } from '../../types/types';
|
|
22
|
+
import { ProgressControl } from '../ProgressControl/ProgressControl';
|
|
23
|
+
|
|
24
|
+
dayjs.extend(duration);
|
|
25
|
+
|
|
26
|
+
const FILE_PREVIEW_HEIGHT = 70;
|
|
27
|
+
|
|
28
|
+
const styles = StyleSheet.create({
|
|
29
|
+
fileContainer: {
|
|
30
|
+
borderRadius: 12,
|
|
31
|
+
borderWidth: 1,
|
|
32
|
+
flexDirection: 'row',
|
|
33
|
+
height: FILE_PREVIEW_HEIGHT,
|
|
34
|
+
paddingLeft: 8,
|
|
35
|
+
paddingRight: 8,
|
|
36
|
+
},
|
|
37
|
+
fileContentContainer: { flexDirection: 'row', paddingRight: 40 },
|
|
38
|
+
filenameText: {
|
|
39
|
+
fontSize: 14,
|
|
40
|
+
fontWeight: 'bold',
|
|
41
|
+
paddingLeft: 10,
|
|
42
|
+
},
|
|
43
|
+
fileTextContainer: {
|
|
44
|
+
justifyContent: 'space-around',
|
|
45
|
+
},
|
|
46
|
+
flatList: { marginBottom: 12, maxHeight: FILE_PREVIEW_HEIGHT * 2.5 + 16 },
|
|
47
|
+
overlay: {
|
|
48
|
+
borderRadius: 12,
|
|
49
|
+
marginLeft: 8,
|
|
50
|
+
marginRight: 8,
|
|
51
|
+
},
|
|
52
|
+
progressControlView: {
|
|
53
|
+
flex: 8,
|
|
54
|
+
},
|
|
55
|
+
progressDurationText: {
|
|
56
|
+
flex: 4,
|
|
57
|
+
fontSize: 12,
|
|
58
|
+
paddingLeft: 10,
|
|
59
|
+
paddingRight: 8,
|
|
60
|
+
},
|
|
61
|
+
roundedView: {
|
|
62
|
+
alignItems: 'center',
|
|
63
|
+
alignSelf: 'center',
|
|
64
|
+
borderRadius: 50,
|
|
65
|
+
display: 'flex',
|
|
66
|
+
elevation: 4,
|
|
67
|
+
height: 36,
|
|
68
|
+
justifyContent: 'center',
|
|
69
|
+
shadowOffset: {
|
|
70
|
+
height: 2,
|
|
71
|
+
width: 0,
|
|
72
|
+
},
|
|
73
|
+
shadowOpacity: 0.23,
|
|
74
|
+
shadowRadius: 2.62,
|
|
75
|
+
width: 36,
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
export type AudioAttachmentPropsWithContext<
|
|
80
|
+
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
|
|
81
|
+
> = Pick<
|
|
82
|
+
MessageInputContextValue<StreamChatGenerics>,
|
|
83
|
+
'fileUploads' | 'removeFile' | 'uploadFile'
|
|
84
|
+
> & {
|
|
85
|
+
index: number;
|
|
86
|
+
item: Omit<FileUpload, 'state'>;
|
|
87
|
+
onLoad: (index: string, duration: number) => void;
|
|
88
|
+
onPlayPause: (index: string, pausedStatus?: boolean) => void;
|
|
89
|
+
onProgress: (index: string, currentTime?: number, hasEnd?: boolean) => void;
|
|
90
|
+
testID?: string;
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
const AudioAttachmentWithContext = <
|
|
94
|
+
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
|
|
95
|
+
>(
|
|
96
|
+
props: AudioAttachmentPropsWithContext<StreamChatGenerics>,
|
|
97
|
+
) => {
|
|
98
|
+
const soundRef = React.useRef<SoundReturnType | null>(null);
|
|
99
|
+
const { fileUploads, index, item, onLoad, onPlayPause, onProgress } = props;
|
|
100
|
+
|
|
101
|
+
const handleLoad = (payload: VideoPayloadData) => {
|
|
102
|
+
onLoad(item.id, payload.duration);
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
const handleProgress = (data: VideoProgressData) => {
|
|
106
|
+
if (data.currentTime && data.seekableDuration) {
|
|
107
|
+
onProgress(item.id, data.currentTime);
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
const handlePlayPause = async (isPausedStatusAvailable?: boolean) => {
|
|
112
|
+
if (soundRef.current) {
|
|
113
|
+
if (isPausedStatusAvailable === undefined) {
|
|
114
|
+
if (item.progress === 1) {
|
|
115
|
+
// For native CLI
|
|
116
|
+
if (soundRef.current.seek) soundRef.current.seek(0);
|
|
117
|
+
// For expo CLI
|
|
118
|
+
if (soundRef.current.setPositionAsync) soundRef.current.setPositionAsync(0);
|
|
119
|
+
}
|
|
120
|
+
if (item.paused) {
|
|
121
|
+
if (soundRef.current.playAsync) await soundRef.current.playAsync();
|
|
122
|
+
onPlayPause(item.id, false);
|
|
123
|
+
} else {
|
|
124
|
+
if (soundRef.current.pauseAsync) await soundRef.current.pauseAsync();
|
|
125
|
+
onPlayPause(item.id, true);
|
|
126
|
+
}
|
|
127
|
+
} else {
|
|
128
|
+
onPlayPause(item.id, isPausedStatusAvailable);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
const handleProgressDrag = async (position: number) => {
|
|
134
|
+
onProgress(item.id, position);
|
|
135
|
+
if (soundRef.current?.seek) soundRef.current.seek(position);
|
|
136
|
+
if (soundRef.current?.setPositionAsync) {
|
|
137
|
+
await soundRef.current.setPositionAsync(position * 1000);
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
const handleEnd = () => {
|
|
142
|
+
onPlayPause(item.id, true);
|
|
143
|
+
onProgress(item.id, item.duration, true);
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
const onPlaybackStatusUpdate = (playbackStatus: PlaybackStatus) => {
|
|
147
|
+
if (!playbackStatus.isLoaded) {
|
|
148
|
+
// Update your UI for the unloaded state
|
|
149
|
+
if (playbackStatus.error) {
|
|
150
|
+
console.log(`Encountered a fatal error during playback: ${playbackStatus.error}`);
|
|
151
|
+
}
|
|
152
|
+
} else {
|
|
153
|
+
const { durationMillis, positionMillis } = playbackStatus;
|
|
154
|
+
onLoad(item.id, durationMillis / 1000);
|
|
155
|
+
// Update your UI for the loaded state
|
|
156
|
+
if (playbackStatus.isPlaying) {
|
|
157
|
+
// Update your UI for the playing state
|
|
158
|
+
onProgress(item.id, positionMillis / 1000);
|
|
159
|
+
} else {
|
|
160
|
+
// Update your UI for the paused state
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
if (playbackStatus.isBuffering) {
|
|
164
|
+
// Update your UI for the buffering state
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (playbackStatus.didJustFinish && !playbackStatus.isLooping) {
|
|
168
|
+
// The player has just finished playing and will stop. Maybe you want to play something else?
|
|
169
|
+
// status: opposite of pause,says i am playing
|
|
170
|
+
handleEnd();
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
useEffect(() => {
|
|
176
|
+
if (Sound.Player === null) {
|
|
177
|
+
const initiateSound = async () => {
|
|
178
|
+
if (item && item.file && item.file.uri) {
|
|
179
|
+
soundRef.current = await Sound.initializeSound(
|
|
180
|
+
{ uri: item.file.uri },
|
|
181
|
+
{},
|
|
182
|
+
onPlaybackStatusUpdate,
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
initiateSound();
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
return () => {
|
|
190
|
+
if (soundRef.current?.stopAsync && soundRef.current.unloadAsync) {
|
|
191
|
+
soundRef.current.stopAsync();
|
|
192
|
+
soundRef.current.unloadAsync();
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
}, []);
|
|
196
|
+
|
|
197
|
+
// This is needed for expo applications where the rerender doesn't occur on time thefore you need to update the state of the sound.
|
|
198
|
+
useEffect(() => {
|
|
199
|
+
const initalPlayPause = async () => {
|
|
200
|
+
if (soundRef.current) {
|
|
201
|
+
if (item.paused) {
|
|
202
|
+
if (soundRef.current.pauseAsync) await soundRef.current.pauseAsync();
|
|
203
|
+
} else {
|
|
204
|
+
if (soundRef.current.playAsync) await soundRef.current.playAsync();
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
if (!Sound.Player) {
|
|
209
|
+
initalPlayPause();
|
|
210
|
+
}
|
|
211
|
+
}, [item.paused]);
|
|
212
|
+
|
|
213
|
+
const {
|
|
214
|
+
theme: {
|
|
215
|
+
colors: { accent_blue, black, grey_dark, grey_whisper, static_black, static_white, white },
|
|
216
|
+
messageInput: {
|
|
217
|
+
fileUploadPreview: {
|
|
218
|
+
audioAttachment: { progressControlView, progressDurationText, roundedView },
|
|
219
|
+
fileContainer,
|
|
220
|
+
fileContentContainer,
|
|
221
|
+
filenameText,
|
|
222
|
+
fileTextContainer,
|
|
223
|
+
},
|
|
224
|
+
},
|
|
225
|
+
},
|
|
226
|
+
} = useTheme();
|
|
227
|
+
|
|
228
|
+
const progressValueInSeconds = (item.duration as number) * (item.progress as number);
|
|
229
|
+
|
|
230
|
+
const progressDuration = progressValueInSeconds
|
|
231
|
+
? progressValueInSeconds / 3600 >= 1
|
|
232
|
+
? dayjs.duration(progressValueInSeconds, 'second').format('HH:mm:ss')
|
|
233
|
+
: dayjs.duration(progressValueInSeconds, 'second').format('mm:ss')
|
|
234
|
+
: '00:00';
|
|
235
|
+
|
|
236
|
+
const lastIndexOfDot = item.file.name.lastIndexOf('.');
|
|
237
|
+
|
|
238
|
+
return (
|
|
239
|
+
<View
|
|
240
|
+
style={[
|
|
241
|
+
styles.fileContainer,
|
|
242
|
+
index === fileUploads.length - 1
|
|
243
|
+
? {
|
|
244
|
+
marginBottom: 0,
|
|
245
|
+
}
|
|
246
|
+
: {},
|
|
247
|
+
{
|
|
248
|
+
backgroundColor: white,
|
|
249
|
+
borderColor: grey_whisper,
|
|
250
|
+
width: -16,
|
|
251
|
+
},
|
|
252
|
+
fileContainer,
|
|
253
|
+
]}
|
|
254
|
+
testID='audio-attachment-upload-preview'
|
|
255
|
+
>
|
|
256
|
+
<View style={[styles.fileContentContainer, fileContentContainer]}>
|
|
257
|
+
<TouchableOpacity
|
|
258
|
+
accessibilityLabel='Play Pause Button'
|
|
259
|
+
onPress={() => handlePlayPause()}
|
|
260
|
+
style={[
|
|
261
|
+
styles.roundedView,
|
|
262
|
+
roundedView,
|
|
263
|
+
{ backgroundColor: static_white, shadowColor: black },
|
|
264
|
+
]}
|
|
265
|
+
>
|
|
266
|
+
{item.paused ? (
|
|
267
|
+
<Play height={24} pathFill={static_black} width={24} />
|
|
268
|
+
) : (
|
|
269
|
+
<Pause height={24} pathFill={static_black} width={24} />
|
|
270
|
+
)}
|
|
271
|
+
</TouchableOpacity>
|
|
272
|
+
<View style={[styles.fileTextContainer, fileTextContainer]}>
|
|
273
|
+
<Text
|
|
274
|
+
accessibilityLabel='File Name'
|
|
275
|
+
numberOfLines={1}
|
|
276
|
+
style={[
|
|
277
|
+
styles.filenameText,
|
|
278
|
+
{
|
|
279
|
+
color: black,
|
|
280
|
+
width:
|
|
281
|
+
16 - // 16 = horizontal padding
|
|
282
|
+
40 - // 40 = file icon size
|
|
283
|
+
24 - // 24 = close icon size
|
|
284
|
+
24, // 24 = internal padding
|
|
285
|
+
},
|
|
286
|
+
I18nManager.isRTL ? { writingDirection: 'rtl' } : { writingDirection: 'ltr' },
|
|
287
|
+
filenameText,
|
|
288
|
+
]}
|
|
289
|
+
>
|
|
290
|
+
{item.file.name.slice(0, 12) + '...' + item.file.name.slice(lastIndexOfDot)}
|
|
291
|
+
</Text>
|
|
292
|
+
<View
|
|
293
|
+
style={{
|
|
294
|
+
alignItems: 'center',
|
|
295
|
+
display: 'flex',
|
|
296
|
+
flexDirection: 'row',
|
|
297
|
+
}}
|
|
298
|
+
>
|
|
299
|
+
{/* <ExpoSoundPlayer filePaused={!!item.paused} soundRef={soundRef} /> */}
|
|
300
|
+
{Sound.Player && (
|
|
301
|
+
<Sound.Player
|
|
302
|
+
onEnd={handleEnd}
|
|
303
|
+
onLoad={handleLoad}
|
|
304
|
+
onProgress={handleProgress}
|
|
305
|
+
paused={item.paused as boolean}
|
|
306
|
+
soundRef={soundRef}
|
|
307
|
+
testID='sound-player'
|
|
308
|
+
uri={item.file.uri}
|
|
309
|
+
/>
|
|
310
|
+
)}
|
|
311
|
+
<Text style={[styles.progressDurationText, { color: grey_dark }, progressDurationText]}>
|
|
312
|
+
{progressDuration}
|
|
313
|
+
</Text>
|
|
314
|
+
<View style={[styles.progressControlView, progressControlView]}>
|
|
315
|
+
<ProgressControl
|
|
316
|
+
duration={item.duration as number}
|
|
317
|
+
filledColor={accent_blue}
|
|
318
|
+
onPlayPause={handlePlayPause}
|
|
319
|
+
onProgressDrag={handleProgressDrag}
|
|
320
|
+
progress={item.progress as number}
|
|
321
|
+
testID='progress-control'
|
|
322
|
+
width={120}
|
|
323
|
+
/>
|
|
324
|
+
</View>
|
|
325
|
+
</View>
|
|
326
|
+
</View>
|
|
327
|
+
</View>
|
|
328
|
+
</View>
|
|
329
|
+
);
|
|
330
|
+
};
|
|
331
|
+
|
|
332
|
+
export type AudioAttachmentProps<
|
|
333
|
+
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
|
|
334
|
+
> = Partial<AudioAttachmentPropsWithContext<StreamChatGenerics>> & {
|
|
335
|
+
index: number;
|
|
336
|
+
item: Omit<FileUpload, 'state'>;
|
|
337
|
+
onLoad: (index: string, duration: number) => void;
|
|
338
|
+
onPlayPause: (index: string, pausedStatus?: boolean) => void;
|
|
339
|
+
onProgress: (index: string, currentTime?: number, hasEnd?: boolean) => void;
|
|
340
|
+
testID: string;
|
|
341
|
+
};
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* AudioAttachment
|
|
345
|
+
* UI Component to preview the audio files
|
|
346
|
+
*/
|
|
347
|
+
export const AudioAttachment = <
|
|
348
|
+
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
|
|
349
|
+
>(
|
|
350
|
+
props: AudioAttachmentProps<StreamChatGenerics>,
|
|
351
|
+
) => {
|
|
352
|
+
const { fileUploads, removeFile, uploadFile } = useMessageInputContext<StreamChatGenerics>();
|
|
353
|
+
|
|
354
|
+
return <AudioAttachmentWithContext {...{ fileUploads, removeFile, uploadFile }} {...props} />;
|
|
355
|
+
};
|
|
356
|
+
|
|
357
|
+
AudioAttachment.displayName = 'AudioAttachment{messageInput{autoAttachment}}';
|
|
@@ -1,17 +1,24 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useEffect, useState } from 'react';
|
|
2
2
|
import { StyleProp, StyleSheet, View, ViewStyle } from 'react-native';
|
|
3
3
|
|
|
4
|
+
import type { Attachment } from 'stream-chat';
|
|
5
|
+
|
|
4
6
|
import { Attachment as AttachmentDefault } from './Attachment';
|
|
5
7
|
|
|
6
8
|
import {
|
|
7
9
|
MessageContextValue,
|
|
8
10
|
useMessageContext,
|
|
9
11
|
} from '../../contexts/messageContext/MessageContext';
|
|
12
|
+
import {
|
|
13
|
+
MessageInputContextValue,
|
|
14
|
+
useMessageInputContext,
|
|
15
|
+
} from '../../contexts/messageInputContext/MessageInputContext';
|
|
10
16
|
import {
|
|
11
17
|
MessagesContextValue,
|
|
12
18
|
useMessagesContext,
|
|
13
19
|
} from '../../contexts/messagesContext/MessagesContext';
|
|
14
20
|
import { useTheme } from '../../contexts/themeContext/ThemeContext';
|
|
21
|
+
import { isAudioPackageAvailable } from '../../native';
|
|
15
22
|
|
|
16
23
|
import type { DefaultStreamChatGenerics } from '../../types/types';
|
|
17
24
|
|
|
@@ -24,6 +31,7 @@ const styles = StyleSheet.create({
|
|
|
24
31
|
export type FileAttachmentGroupPropsWithContext<
|
|
25
32
|
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
|
|
26
33
|
> = Pick<MessageContextValue<StreamChatGenerics>, 'files'> &
|
|
34
|
+
Pick<MessageInputContextValue<StreamChatGenerics>, 'AudioAttachment'> &
|
|
27
35
|
Pick<MessagesContextValue<StreamChatGenerics>, 'Attachment'> & {
|
|
28
36
|
/**
|
|
29
37
|
* The unique id for the message with file attachments
|
|
@@ -35,12 +43,73 @@ export type FileAttachmentGroupPropsWithContext<
|
|
|
35
43
|
}>;
|
|
36
44
|
};
|
|
37
45
|
|
|
46
|
+
type FilesToDisplayType<
|
|
47
|
+
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
|
|
48
|
+
> = Attachment<StreamChatGenerics> & {
|
|
49
|
+
duration: number;
|
|
50
|
+
paused: boolean;
|
|
51
|
+
progress: number;
|
|
52
|
+
};
|
|
53
|
+
|
|
38
54
|
const FileAttachmentGroupWithContext = <
|
|
39
55
|
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
|
|
40
56
|
>(
|
|
41
57
|
props: FileAttachmentGroupPropsWithContext<StreamChatGenerics>,
|
|
42
58
|
) => {
|
|
43
|
-
const { Attachment, files, messageId, styles: stylesProp = {} } = props;
|
|
59
|
+
const { Attachment, AudioAttachment, files, messageId, styles: stylesProp = {} } = props;
|
|
60
|
+
const [filesToDisplay, setFilesToDisplay] = useState<FilesToDisplayType[]>([]);
|
|
61
|
+
|
|
62
|
+
useEffect(() => {
|
|
63
|
+
setFilesToDisplay(files.map((file) => ({ ...file, duration: 0, paused: true, progress: 0 })));
|
|
64
|
+
}, [files]);
|
|
65
|
+
|
|
66
|
+
// Handler triggered when an audio is loaded in the message input. The initial state is defined for the audio here and the duration is set.
|
|
67
|
+
const onLoad = (index: string, duration: number) => {
|
|
68
|
+
setFilesToDisplay((prevFilesToDisplay) =>
|
|
69
|
+
prevFilesToDisplay.map((fileToDisplay, id) => ({
|
|
70
|
+
...fileToDisplay,
|
|
71
|
+
duration: id.toString() === index ? duration : fileToDisplay.duration,
|
|
72
|
+
})),
|
|
73
|
+
);
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
// The handler which is triggered when the audio progresses/ the thumb is dragged in the progress control. The progressed duration is set here.
|
|
77
|
+
const onProgress = (index: string, currentTime?: number, hasEnd?: boolean) => {
|
|
78
|
+
setFilesToDisplay((prevFileUploads) =>
|
|
79
|
+
prevFileUploads.map((fileUpload, id) => ({
|
|
80
|
+
...fileUpload,
|
|
81
|
+
progress:
|
|
82
|
+
id.toString() === index
|
|
83
|
+
? hasEnd
|
|
84
|
+
? 1
|
|
85
|
+
: currentTime
|
|
86
|
+
? currentTime / (fileUpload.duration as number)
|
|
87
|
+
: 0
|
|
88
|
+
: fileUpload.progress,
|
|
89
|
+
})),
|
|
90
|
+
);
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
// The handler which controls or sets the paused/played state of the audio.
|
|
94
|
+
const onPlayPause = (index: string, pausedStatus?: boolean) => {
|
|
95
|
+
if (pausedStatus === false) {
|
|
96
|
+
// If the status is false we set the audio with the index as playing and the others as paused.
|
|
97
|
+
setFilesToDisplay((prevFileUploads) =>
|
|
98
|
+
prevFileUploads.map((fileUpload, id) => ({
|
|
99
|
+
...fileUpload,
|
|
100
|
+
paused: id.toString() === index ? false : true,
|
|
101
|
+
})),
|
|
102
|
+
);
|
|
103
|
+
} else {
|
|
104
|
+
// If the status is true we simply set all the audio's paused state as true.
|
|
105
|
+
setFilesToDisplay((prevFileUploads) =>
|
|
106
|
+
prevFileUploads.map((fileUpload) => ({
|
|
107
|
+
...fileUpload,
|
|
108
|
+
paused: true,
|
|
109
|
+
})),
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
};
|
|
44
113
|
|
|
45
114
|
const {
|
|
46
115
|
theme: {
|
|
@@ -52,7 +121,7 @@ const FileAttachmentGroupWithContext = <
|
|
|
52
121
|
|
|
53
122
|
return (
|
|
54
123
|
<View style={[styles.container, container, stylesProp.container]}>
|
|
55
|
-
{
|
|
124
|
+
{filesToDisplay.map((file, index) => (
|
|
56
125
|
<View
|
|
57
126
|
key={`${messageId}-${index}`}
|
|
58
127
|
style={[
|
|
@@ -60,7 +129,26 @@ const FileAttachmentGroupWithContext = <
|
|
|
60
129
|
stylesProp.attachmentContainer,
|
|
61
130
|
]}
|
|
62
131
|
>
|
|
63
|
-
|
|
132
|
+
{file.type === 'audio' && isAudioPackageAvailable() ? (
|
|
133
|
+
<View accessibilityLabel='audio-attachment-preview'>
|
|
134
|
+
<AudioAttachment
|
|
135
|
+
index={index}
|
|
136
|
+
item={{
|
|
137
|
+
duration: file.duration,
|
|
138
|
+
file: { name: file.title as string, uri: file.asset_url },
|
|
139
|
+
id: index.toString(),
|
|
140
|
+
paused: file.paused,
|
|
141
|
+
progress: file.progress,
|
|
142
|
+
}}
|
|
143
|
+
onLoad={onLoad}
|
|
144
|
+
onPlayPause={onPlayPause}
|
|
145
|
+
onProgress={onProgress}
|
|
146
|
+
testID='audio-attachment-preview'
|
|
147
|
+
/>
|
|
148
|
+
</View>
|
|
149
|
+
) : (
|
|
150
|
+
<Attachment attachment={file} />
|
|
151
|
+
)}
|
|
64
152
|
</View>
|
|
65
153
|
))}
|
|
66
154
|
</View>
|
|
@@ -74,9 +162,7 @@ const areEqual = <StreamChatGenerics extends DefaultStreamChatGenerics = Default
|
|
|
74
162
|
const { files: prevFiles } = prevProps;
|
|
75
163
|
const { files: nextFiles } = nextProps;
|
|
76
164
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
return filesEqual;
|
|
165
|
+
return prevFiles.length === nextFiles.length;
|
|
80
166
|
};
|
|
81
167
|
|
|
82
168
|
const MemoizedFileAttachmentGroup = React.memo(
|
|
@@ -100,6 +186,8 @@ export const FileAttachmentGroup = <
|
|
|
100
186
|
|
|
101
187
|
const { Attachment = AttachmentDefault } = useMessagesContext<StreamChatGenerics>();
|
|
102
188
|
|
|
189
|
+
const { AudioAttachment } = useMessageInputContext<StreamChatGenerics>();
|
|
190
|
+
|
|
103
191
|
const files = propFiles || contextFiles;
|
|
104
192
|
|
|
105
193
|
if (!files.length) return null;
|
|
@@ -108,6 +196,7 @@ export const FileAttachmentGroup = <
|
|
|
108
196
|
<MemoizedFileAttachmentGroup
|
|
109
197
|
{...{
|
|
110
198
|
Attachment,
|
|
199
|
+
AudioAttachment,
|
|
111
200
|
files,
|
|
112
201
|
messageId,
|
|
113
202
|
}}
|
|
@@ -3,7 +3,7 @@ import { StyleSheet, Text, TouchableOpacity, View } from 'react-native';
|
|
|
3
3
|
|
|
4
4
|
import type { Attachment } from 'stream-chat';
|
|
5
5
|
|
|
6
|
-
import { GalleryImage } from './
|
|
6
|
+
import { GalleryImage } from './GalleryImage';
|
|
7
7
|
import { useLoadingImage } from './hooks/useLoadingImage';
|
|
8
8
|
import { buildGallery } from './utils/buildGallery/buildGallery';
|
|
9
9
|
|
|
@@ -15,7 +15,6 @@ const styles = StyleSheet.create({
|
|
|
15
15
|
},
|
|
16
16
|
roundedView: {
|
|
17
17
|
alignItems: 'center',
|
|
18
|
-
backgroundColor: '#fff',
|
|
19
18
|
borderRadius: 50,
|
|
20
19
|
display: 'flex',
|
|
21
20
|
elevation: 6,
|
|
@@ -41,6 +40,7 @@ export type VideoThumbnailProps = {
|
|
|
41
40
|
export const VideoThumbnail: React.FC<VideoThumbnailProps> = (props) => {
|
|
42
41
|
const {
|
|
43
42
|
theme: {
|
|
43
|
+
colors: { static_black, static_white },
|
|
44
44
|
messageSimple: {
|
|
45
45
|
videoThumbnail: { container, roundedView },
|
|
46
46
|
},
|
|
@@ -49,13 +49,13 @@ export const VideoThumbnail: React.FC<VideoThumbnailProps> = (props) => {
|
|
|
49
49
|
const { imageStyle, style, thumb_url } = props;
|
|
50
50
|
return (
|
|
51
51
|
<ImageBackground
|
|
52
|
-
accessibilityLabel='
|
|
52
|
+
accessibilityLabel='Video Thumbnail'
|
|
53
53
|
imageStyle={imageStyle}
|
|
54
54
|
source={{ uri: thumb_url }}
|
|
55
55
|
style={[styles.container, container, style]}
|
|
56
56
|
>
|
|
57
|
-
<View style={[styles.roundedView, roundedView]}>
|
|
58
|
-
<Play height={24} pathFill={
|
|
57
|
+
<View style={[styles.roundedView, roundedView, { backgroundColor: static_white }]}>
|
|
58
|
+
<Play height={24} pathFill={static_black} width={24} />
|
|
59
59
|
</View>
|
|
60
60
|
</ImageBackground>
|
|
61
61
|
);
|
|
@@ -93,7 +93,7 @@ describe('Gallery', () => {
|
|
|
93
93
|
expect(queryAllByTestId('gallery-row-0').length).toBe(1);
|
|
94
94
|
|
|
95
95
|
expect(queryAllByTestId('gallery-row-0-item-0').length).toBe(1);
|
|
96
|
-
expect(getAllByA11yLabel('
|
|
96
|
+
expect(getAllByA11yLabel('Video Thumbnail').length).toBe(1);
|
|
97
97
|
});
|
|
98
98
|
});
|
|
99
99
|
|
|
@@ -267,7 +267,7 @@ describe('Gallery', () => {
|
|
|
267
267
|
const component = await getComponent([image1]);
|
|
268
268
|
const { getByA11yLabel, getByAccessibilityHint } = render(component);
|
|
269
269
|
|
|
270
|
-
fireEvent(getByA11yLabel('
|
|
270
|
+
fireEvent(getByA11yLabel('Gallery Image'), 'error');
|
|
271
271
|
expect(getByAccessibilityHint('image-loading-error')).toBeTruthy();
|
|
272
272
|
});
|
|
273
273
|
|
|
@@ -280,11 +280,11 @@ describe('Gallery', () => {
|
|
|
280
280
|
const component = await getComponent([image1]);
|
|
281
281
|
const { getByA11yLabel, getByAccessibilityHint } = render(component);
|
|
282
282
|
|
|
283
|
-
fireEvent(getByA11yLabel('
|
|
283
|
+
fireEvent(getByA11yLabel('Gallery Image'), 'onLoadStart');
|
|
284
284
|
expect(getByAccessibilityHint('image-loading')).toBeTruthy();
|
|
285
285
|
|
|
286
|
-
fireEvent(getByA11yLabel('
|
|
287
|
-
waitForElementToBeRemoved(() => getByAccessibilityHint('
|
|
288
|
-
expect(getByA11yLabel('
|
|
286
|
+
fireEvent(getByA11yLabel('Gallery Image'), 'onLoadFinish');
|
|
287
|
+
waitForElementToBeRemoved(() => getByAccessibilityHint('Image Loading'));
|
|
288
|
+
expect(getByA11yLabel('Gallery Image')).toBeTruthy();
|
|
289
289
|
});
|
|
290
290
|
});
|
|
@@ -285,7 +285,7 @@ describe('Giphy', () => {
|
|
|
285
285
|
</OverlayProvider>,
|
|
286
286
|
);
|
|
287
287
|
|
|
288
|
-
fireEvent(getByA11yLabel('
|
|
288
|
+
fireEvent(getByA11yLabel('Giphy Attachment Image'), 'error');
|
|
289
289
|
expect(getByAccessibilityHint('image-loading-error')).toBeTruthy();
|
|
290
290
|
});
|
|
291
291
|
|
|
@@ -302,13 +302,13 @@ describe('Giphy', () => {
|
|
|
302
302
|
|
|
303
303
|
expect(getByAccessibilityHint('image-loading')).toBeTruthy();
|
|
304
304
|
|
|
305
|
-
fireEvent(getByA11yLabel('
|
|
305
|
+
fireEvent(getByA11yLabel('Giphy Attachment Image'), 'onLoadStart');
|
|
306
306
|
|
|
307
307
|
expect(getByAccessibilityHint('image-loading')).toBeTruthy();
|
|
308
308
|
|
|
309
|
-
fireEvent(getByA11yLabel('
|
|
309
|
+
fireEvent(getByA11yLabel('Giphy Attachment Image'), 'onLoadFinish');
|
|
310
310
|
|
|
311
311
|
waitForElementToBeRemoved(() => getByAccessibilityHint('image-loading'));
|
|
312
|
-
expect(getByA11yLabel('
|
|
312
|
+
expect(getByA11yLabel('Giphy Attachment Image')).toBeTruthy();
|
|
313
313
|
});
|
|
314
314
|
});
|
|
@@ -127,7 +127,7 @@ export const GroupAvatar: React.FC<GroupAvatarProps> = (props) => {
|
|
|
127
127
|
>
|
|
128
128
|
{column.map(({ height, name, url, width }, rowIndex) => (
|
|
129
129
|
<Image
|
|
130
|
-
accessibilityLabel={testID || '
|
|
130
|
+
accessibilityLabel={testID || 'Avatar Image'}
|
|
131
131
|
key={`avatar-${url}-${rowIndex}`}
|
|
132
132
|
onError={() => setImageError(true)}
|
|
133
133
|
source={{
|