Skip to content

Commit 55077fc

Browse files
Merge pull request #329 from GetStream/vishal/file-upload-preview-fix
Fixing issues with FileUploadPreview
2 parents f418e0a + e9212cd commit 55077fc

13 files changed

+1045
-640
lines changed

src/components/MessageInput/FileUploadPreview.js

Lines changed: 50 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import UploadProgressIndicator from './UploadProgressIndicator';
77

88
import FileIcon from '../Attachment/FileIcon';
99

10+
import closeRound from '../../images/icons/close-round.png';
1011
import { themed } from '../../styles/theme';
1112
import { FileState, ProgressIndicatorTypes } from '../../utils/utils';
1213

@@ -39,8 +40,23 @@ const Container = styled.View`
3940
${({ theme }) => theme.messageInput.fileUploadPreview.container.css};
4041
`;
4142

42-
const DismissText = styled.Text`
43-
${({ theme }) => theme.messageInput.fileUploadPreview.dismissText.css};
43+
const Dismiss = styled.TouchableOpacity`
44+
align-items: center;
45+
background-color: #fff;
46+
border-radius: 20px;
47+
height: 20px;
48+
justify-content: center;
49+
position: absolute;
50+
right: 5;
51+
top: 5;
52+
width: 20px;
53+
${({ theme }) => theme.messageInput.fileUploadPreview.dismiss.css};
54+
`;
55+
56+
const DismissImage = styled.Image`
57+
height: 10px;
58+
width: 10px;
59+
${({ theme }) => theme.messageInput.fileUploadPreview.dismissImage.css};
4460
`;
4561

4662
const FilenameText = styled.Text`
@@ -72,28 +88,38 @@ const FileUploadPreview = ({
7288
}
7389

7490
return (
75-
<UploadProgressIndicator
76-
action={() => (retryUpload ? retryUpload(item.id) : null)}
77-
active={item.state !== FileState.UPLOADED}
78-
type={type}
79-
>
80-
<AttachmentContainerView>
81-
<AttachmentView>
82-
<AttachmentFileIcon mimeType={item.file.type} size={20} />
83-
<FilenameText>
84-
{item.file.name.length > 35
85-
? item.file.name.substring(0, 35).concat('...')
86-
: item.file.name}
87-
</FilenameText>
88-
</AttachmentView>
89-
<DismissText
90-
onPress={() => removeFile(item.id)}
91-
testID='remove-file-upload-preview'
92-
>
93-
X
94-
</DismissText>
95-
</AttachmentContainerView>
96-
</UploadProgressIndicator>
91+
<>
92+
<UploadProgressIndicator
93+
action={() => {
94+
if (retryUpload) {
95+
retryUpload(item.id);
96+
}
97+
}}
98+
active={item.state !== FileState.UPLOADED}
99+
type={type}
100+
>
101+
<AttachmentContainerView>
102+
<AttachmentView>
103+
<AttachmentFileIcon mimeType={item.file.type} size={20} />
104+
<FilenameText>
105+
{item.file.name.length > 35
106+
? item.file.name.substring(0, 35).concat('...')
107+
: item.file.name}
108+
</FilenameText>
109+
</AttachmentView>
110+
</AttachmentContainerView>
111+
</UploadProgressIndicator>
112+
<Dismiss
113+
onPress={() => {
114+
if (removeFile) {
115+
removeFile(item.id);
116+
}
117+
}}
118+
testID='remove-file-upload-preview'
119+
>
120+
<DismissImage source={closeRound} />
121+
</Dismiss>
122+
</>
97123
);
98124
};
99125

src/components/MessageInput/ImageUploadPreview.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,11 @@ const ImageUploadPreview = ({ imageUploads, removeImage, retryUpload }) => {
6969
return (
7070
<ItemContainer>
7171
<UploadProgressIndicator
72-
action={() => (retryUpload ? retryUpload(item.id) : null)}
72+
action={() => {
73+
if (retryUpload) {
74+
retryUpload(item.id);
75+
}
76+
}}
7377
active={item.state !== FileState.UPLOADED}
7478
type={type}
7579
>
@@ -79,7 +83,11 @@ const ImageUploadPreview = ({ imageUploads, removeImage, retryUpload }) => {
7983
/>
8084
</UploadProgressIndicator>
8185
<Dismiss
82-
onPress={() => removeImage(item.id)}
86+
onPress={() => {
87+
if (removeImage) {
88+
removeImage(item.id);
89+
}
90+
}}
8391
testID='remove-image-upload-preview'
8492
>
8593
<DismissImage source={closeRound} />

src/components/MessageInput/MessageInput.js

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ import { logChatPromiseExecution } from 'stream-chat';
88

99
import ActionSheetAttachmentDefault from './ActionSheetAttachment';
1010
import AttachButtonDefault from './AttachButton';
11-
import FileUploadPreview from './FileUploadPreview';
12-
import ImageUploadPreview from './ImageUploadPreview';
11+
import FileUploadPreviewDefault from './FileUploadPreview';
12+
import ImageUploadPreviewDefault from './ImageUploadPreview';
1313
import SendButtonDefault from './SendButton';
1414

1515
import { useMessageDetailsForState } from './hooks/useMessageDetailsForState';
@@ -123,8 +123,10 @@ const MessageInput = (props) => {
123123
compressImageQuality,
124124
doDocUploadRequest,
125125
doImageUploadRequest,
126+
FileUploadPreview = FileUploadPreviewDefault,
126127
hasFilePicker = true,
127128
hasImagePicker = true,
129+
ImageUploadPreview = ImageUploadPreviewDefault,
128130
initialValue,
129131
Input,
130132
maxNumberOfFiles,
@@ -870,10 +872,26 @@ MessageInput.propTypes = {
870872
* @param channel Current channel object
871873
* */
872874
doImageUploadRequest: PropTypes.func,
875+
/**
876+
* Custom UI component for FileUploadPreview.
877+
* Defaults to and accepts same props as: https://github.com/GetStream/stream-chat-react-native/blob/master/src/components/MessageInput/FileUploadPreview.js
878+
*/
879+
FileUploadPreview: PropTypes.oneOfType([
880+
PropTypes.node,
881+
PropTypes.elementType,
882+
]),
873883
/** If component should have file picker functionality */
874884
hasFilePicker: PropTypes.bool,
875885
/** If component should have image picker functionality */
876886
hasImagePicker: PropTypes.bool,
887+
/**
888+
* Custom UI component for ImageUploadPreview.
889+
* Defaults to and accepts same props as: https://github.com/GetStream/stream-chat-react-native/blob/master/src/components/MessageInput/ImageUploadPreview.js
890+
*/
891+
ImageUploadPreview: PropTypes.oneOfType([
892+
PropTypes.node,
893+
PropTypes.elementType,
894+
]),
877895
/** Initial value to set on input */
878896
initialValue: PropTypes.string,
879897
/** Limit on allowed number of files to attach at a time. */

src/components/MessageInput/UploadProgressIndicator.js

Lines changed: 33 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from 'react';
2-
import { ActivityIndicator, Image, TouchableOpacity, View } from 'react-native';
2+
import { ActivityIndicator, Image, View } from 'react-native';
33
import styled from '@stream-io/styled-components';
44
import PropTypes from 'prop-types';
55

@@ -28,44 +28,53 @@ const Overlay = styled.View`
2828
${({ theme }) => theme.messageInput.uploadProgressIndicator.overlay.css};
2929
`;
3030

31+
const ActivityIndicatorContainer = styled.View`
32+
align-items: center;
33+
bottom: 0;
34+
justify-content: center;
35+
left: 0;
36+
position: absolute;
37+
right: 0;
38+
top: 0;
39+
`;
40+
41+
const RetryButtonContainer = styled.TouchableOpacity`
42+
align-items: center;
43+
bottom: 0;
44+
justify-content: center;
45+
left: 0;
46+
position: absolute;
47+
right: 0;
48+
top: 0;
49+
`;
50+
3151
const UploadProgressIndicator = ({ action, active, children, type }) =>
3252
!active ? (
3353
<View testID='inactive-upload-progress-indicator'>{children}</View>
3454
) : (
35-
<TouchableOpacity
36-
onPress={action}
37-
testID='active-upload-progress-indicator'
38-
>
55+
<View testID='active-upload-progress-indicator'>
3956
{children}
4057
<Overlay />
4158
<Container>
4259
{type === ProgressIndicatorTypes.IN_PROGRESS && (
43-
<View
44-
style={{
45-
alignItems: 'center',
46-
bottom: 0,
47-
justifyContent: 'center',
48-
left: 0,
49-
position: 'absolute',
50-
right: 0,
51-
top: 0,
52-
}}
53-
>
60+
<ActivityIndicatorContainer>
5461
<ActivityIndicator
55-
color='white'
62+
color='grey'
5663
testID='upload-progress-indicator'
5764
/>
58-
</View>
65+
</ActivityIndicatorContainer>
5966
)}
6067
{type === ProgressIndicatorTypes.RETRY && (
61-
<Image
62-
source={iconReload}
63-
style={{ height: 18, width: 18 }}
64-
testID='retry-upload-progress-indicator'
65-
/>
68+
<RetryButtonContainer onPress={action}>
69+
<Image
70+
source={iconReload}
71+
style={{ height: 18, width: 18 }}
72+
testID='retry-upload-progress-indicator'
73+
/>
74+
</RetryButtonContainer>
6675
)}
6776
</Container>
68-
</TouchableOpacity>
77+
</View>
6978
);
7079

7180
UploadProgressIndicator.propTypes = {

src/components/MessageInput/__tests__/FileUploadPreview.test.js

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,6 @@ describe('FileUploadPreview', () => {
4949
expect(retryUpload).toHaveBeenCalledTimes(0);
5050
});
5151

52-
fireEvent.press(getAllByTestId('active-upload-progress-indicator')[0]);
53-
54-
await waitFor(() => {
55-
expect(removeFile).toHaveBeenCalledTimes(1);
56-
expect(retryUpload).toHaveBeenCalledTimes(1);
57-
});
58-
5952
rerender(
6053
<FileUploadPreview
6154
fileUploads={fileUploads.map((file, index) => ({
@@ -170,7 +163,7 @@ describe('FileUploadPreview', () => {
170163
expect(retryUpload).toHaveBeenCalledTimes(0);
171164
});
172165

173-
fireEvent.press(getAllByTestId('active-upload-progress-indicator')[0]);
166+
fireEvent.press(getAllByTestId('retry-upload-progress-indicator')[0]);
174167

175168
await waitFor(() => {
176169
expect(removeFile).toHaveBeenCalledTimes(1);

src/components/MessageInput/__tests__/ImageUploadPreview.test.js

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,6 @@ describe('ImageUploadPreview', () => {
4949
expect(retryUpload).toHaveBeenCalledTimes(0);
5050
});
5151

52-
fireEvent.press(getAllByTestId('active-upload-progress-indicator')[0]);
53-
54-
await waitFor(() => {
55-
expect(removeImage).toHaveBeenCalledTimes(1);
56-
expect(retryUpload).toHaveBeenCalledTimes(1);
57-
});
58-
5952
rerender(
6053
<ImageUploadPreview
6154
imageUploads={imageUploads.map((image, index) => ({
@@ -170,7 +163,7 @@ describe('ImageUploadPreview', () => {
170163
expect(retryUpload).toHaveBeenCalledTimes(0);
171164
});
172165

173-
fireEvent.press(getAllByTestId('active-upload-progress-indicator')[0]);
166+
fireEvent.press(getAllByTestId('retry-upload-progress-indicator')[0]);
174167

175168
await waitFor(() => {
176169
expect(removeImage).toHaveBeenCalledTimes(1);

src/components/MessageInput/__tests__/UploadProgressIndicator.test.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ describe('UploadProgressIndicator', () => {
5555
it('should render an active IN_PROGRESS UploadProgressIndicator', async () => {
5656
const action = jest.fn();
5757

58-
const { getByTestId, queryByTestId, toJSON } = render(
58+
const { queryByTestId, toJSON } = render(
5959
<UploadProgressIndicator
6060
action={action}
6161
active
@@ -66,13 +66,11 @@ describe('UploadProgressIndicator', () => {
6666
await waitFor(() => {
6767
expect(queryByTestId('active-upload-progress-indicator')).toBeTruthy();
6868
expect(queryByTestId('inactive-upload-progress-indicator')).toBeFalsy();
69+
expect(queryByTestId('upload-progress-indicator')).toBeTruthy();
70+
expect(queryByTestId('retry-upload-progress-indicator')).toBeFalsy();
6971
expect(action).toHaveBeenCalledTimes(0);
7072
});
7173

72-
fireEvent.press(getByTestId('active-upload-progress-indicator'));
73-
74-
await waitFor(() => expect(action).toHaveBeenCalledTimes(1));
75-
7674
const snapshot = toJSON();
7775

7876
await waitFor(() => {
@@ -94,10 +92,12 @@ describe('UploadProgressIndicator', () => {
9492
await waitFor(() => {
9593
expect(queryByTestId('active-upload-progress-indicator')).toBeTruthy();
9694
expect(queryByTestId('inactive-upload-progress-indicator')).toBeFalsy();
95+
expect(queryByTestId('upload-progress-indicator')).toBeFalsy();
96+
expect(queryByTestId('retry-upload-progress-indicator')).toBeTruthy();
9797
expect(action).toHaveBeenCalledTimes(0);
9898
});
9999

100-
fireEvent.press(getByTestId('active-upload-progress-indicator'));
100+
fireEvent.press(getByTestId('retry-upload-progress-indicator'));
101101

102102
await waitFor(() => expect(action).toHaveBeenCalledTimes(1));
103103

0 commit comments

Comments
 (0)