Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 50 additions & 24 deletions src/components/MessageInput/FileUploadPreview.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import UploadProgressIndicator from './UploadProgressIndicator';

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

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

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

const DismissText = styled.Text`
${({ theme }) => theme.messageInput.fileUploadPreview.dismissText.css};
const Dismiss = styled.TouchableOpacity`
align-items: center;
background-color: #fff;
border-radius: 20px;
height: 20px;
justify-content: center;
position: absolute;
right: 5;
top: 5;
width: 20px;
${({ theme }) => theme.messageInput.fileUploadPreview.dismiss.css};
`;

const DismissImage = styled.Image`
height: 10px;
width: 10px;
${({ theme }) => theme.messageInput.fileUploadPreview.dismissImage.css};
`;

const FilenameText = styled.Text`
Expand Down Expand Up @@ -72,28 +88,38 @@ const FileUploadPreview = ({
}

return (
<UploadProgressIndicator
action={() => (retryUpload ? retryUpload(item.id) : null)}
active={item.state !== FileState.UPLOADED}
type={type}
>
<AttachmentContainerView>
<AttachmentView>
<AttachmentFileIcon mimeType={item.file.type} size={20} />
<FilenameText>
{item.file.name.length > 35
? item.file.name.substring(0, 35).concat('...')
: item.file.name}
</FilenameText>
</AttachmentView>
<DismissText
onPress={() => removeFile(item.id)}
testID='remove-file-upload-preview'
>
X
</DismissText>
</AttachmentContainerView>
</UploadProgressIndicator>
<>
<UploadProgressIndicator
action={() => {
if (retryUpload) {
retryUpload(item.id);
}
}}
active={item.state !== FileState.UPLOADED}
type={type}
>
<AttachmentContainerView>
<AttachmentView>
<AttachmentFileIcon mimeType={item.file.type} size={20} />
<FilenameText>
{item.file.name.length > 35
? item.file.name.substring(0, 35).concat('...')
: item.file.name}
</FilenameText>
</AttachmentView>
</AttachmentContainerView>
</UploadProgressIndicator>
<Dismiss
onPress={() => {
if (removeFile) {
removeFile(item.id);
}
}}
testID='remove-file-upload-preview'
>
<DismissImage source={closeRound} />
</Dismiss>
</>
);
};

Expand Down
12 changes: 10 additions & 2 deletions src/components/MessageInput/ImageUploadPreview.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,11 @@ const ImageUploadPreview = ({ imageUploads, removeImage, retryUpload }) => {
return (
<ItemContainer>
<UploadProgressIndicator
action={() => (retryUpload ? retryUpload(item.id) : null)}
action={() => {
if (retryUpload) {
retryUpload(item.id);
}
}}
active={item.state !== FileState.UPLOADED}
type={type}
>
Expand All @@ -79,7 +83,11 @@ const ImageUploadPreview = ({ imageUploads, removeImage, retryUpload }) => {
/>
</UploadProgressIndicator>
<Dismiss
onPress={() => removeImage(item.id)}
onPress={() => {
if (removeImage) {
removeImage(item.id);
}
}}
testID='remove-image-upload-preview'
>
<DismissImage source={closeRound} />
Expand Down
22 changes: 20 additions & 2 deletions src/components/MessageInput/MessageInput.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import { logChatPromiseExecution } from 'stream-chat';

import ActionSheetAttachmentDefault from './ActionSheetAttachment';
import AttachButtonDefault from './AttachButton';
import FileUploadPreview from './FileUploadPreview';
import ImageUploadPreview from './ImageUploadPreview';
import FileUploadPreviewDefault from './FileUploadPreview';
import ImageUploadPreviewDefault from './ImageUploadPreview';
import SendButtonDefault from './SendButton';

import { useMessageDetailsForState } from './hooks/useMessageDetailsForState';
Expand Down Expand Up @@ -123,8 +123,10 @@ const MessageInput = (props) => {
compressImageQuality,
doDocUploadRequest,
doImageUploadRequest,
FileUploadPreview = FileUploadPreviewDefault,
hasFilePicker = true,
hasImagePicker = true,
ImageUploadPreview = ImageUploadPreviewDefault,
initialValue,
Input,
maxNumberOfFiles,
Expand Down Expand Up @@ -870,10 +872,26 @@ MessageInput.propTypes = {
* @param channel Current channel object
* */
doImageUploadRequest: PropTypes.func,
/**
* Custom UI component for FileUploadPreview.
* Defaults to and accepts same props as: https://github.com/GetStream/stream-chat-react-native/blob/master/src/components/MessageInput/FileUploadPreview.js
*/
FileUploadPreview: PropTypes.oneOfType([
PropTypes.node,
PropTypes.elementType,
]),
/** If component should have file picker functionality */
hasFilePicker: PropTypes.bool,
/** If component should have image picker functionality */
hasImagePicker: PropTypes.bool,
/**
* Custom UI component for ImageUploadPreview.
* Defaults to and accepts same props as: https://github.com/GetStream/stream-chat-react-native/blob/master/src/components/MessageInput/ImageUploadPreview.js
*/
ImageUploadPreview: PropTypes.oneOfType([
PropTypes.node,
PropTypes.elementType,
]),
/** Initial value to set on input */
initialValue: PropTypes.string,
/** Limit on allowed number of files to attach at a time. */
Expand Down
57 changes: 33 additions & 24 deletions src/components/MessageInput/UploadProgressIndicator.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { ActivityIndicator, Image, TouchableOpacity, View } from 'react-native';
import { ActivityIndicator, Image, View } from 'react-native';
import styled from '@stream-io/styled-components';
import PropTypes from 'prop-types';

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

const ActivityIndicatorContainer = styled.View`
align-items: center;
bottom: 0;
justify-content: center;
left: 0;
position: absolute;
right: 0;
top: 0;
`;

const RetryButtonContainer = styled.TouchableOpacity`
align-items: center;
bottom: 0;
justify-content: center;
left: 0;
position: absolute;
right: 0;
top: 0;
`;

const UploadProgressIndicator = ({ action, active, children, type }) =>
!active ? (
<View testID='inactive-upload-progress-indicator'>{children}</View>
) : (
<TouchableOpacity
onPress={action}
testID='active-upload-progress-indicator'
>
<View testID='active-upload-progress-indicator'>
{children}
<Overlay />
<Container>
{type === ProgressIndicatorTypes.IN_PROGRESS && (
<View
style={{
alignItems: 'center',
bottom: 0,
justifyContent: 'center',
left: 0,
position: 'absolute',
right: 0,
top: 0,
}}
>
<ActivityIndicatorContainer>
<ActivityIndicator
color='white'
color='grey'
testID='upload-progress-indicator'
/>
</View>
</ActivityIndicatorContainer>
)}
{type === ProgressIndicatorTypes.RETRY && (
<Image
source={iconReload}
style={{ height: 18, width: 18 }}
testID='retry-upload-progress-indicator'
/>
<RetryButtonContainer onPress={action}>
<Image
source={iconReload}
style={{ height: 18, width: 18 }}
testID='retry-upload-progress-indicator'
/>
</RetryButtonContainer>
)}
</Container>
</TouchableOpacity>
</View>
);

UploadProgressIndicator.propTypes = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,6 @@ describe('FileUploadPreview', () => {
expect(retryUpload).toHaveBeenCalledTimes(0);
});

fireEvent.press(getAllByTestId('active-upload-progress-indicator')[0]);

await waitFor(() => {
expect(removeFile).toHaveBeenCalledTimes(1);
expect(retryUpload).toHaveBeenCalledTimes(1);
});

rerender(
<FileUploadPreview
fileUploads={fileUploads.map((file, index) => ({
Expand Down Expand Up @@ -170,7 +163,7 @@ describe('FileUploadPreview', () => {
expect(retryUpload).toHaveBeenCalledTimes(0);
});

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

await waitFor(() => {
expect(removeFile).toHaveBeenCalledTimes(1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,6 @@ describe('ImageUploadPreview', () => {
expect(retryUpload).toHaveBeenCalledTimes(0);
});

fireEvent.press(getAllByTestId('active-upload-progress-indicator')[0]);

await waitFor(() => {
expect(removeImage).toHaveBeenCalledTimes(1);
expect(retryUpload).toHaveBeenCalledTimes(1);
});

rerender(
<ImageUploadPreview
imageUploads={imageUploads.map((image, index) => ({
Expand Down Expand Up @@ -170,7 +163,7 @@ describe('ImageUploadPreview', () => {
expect(retryUpload).toHaveBeenCalledTimes(0);
});

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

await waitFor(() => {
expect(removeImage).toHaveBeenCalledTimes(1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ describe('UploadProgressIndicator', () => {
it('should render an active IN_PROGRESS UploadProgressIndicator', async () => {
const action = jest.fn();

const { getByTestId, queryByTestId, toJSON } = render(
const { queryByTestId, toJSON } = render(
<UploadProgressIndicator
action={action}
active
Expand All @@ -66,13 +66,11 @@ describe('UploadProgressIndicator', () => {
await waitFor(() => {
expect(queryByTestId('active-upload-progress-indicator')).toBeTruthy();
expect(queryByTestId('inactive-upload-progress-indicator')).toBeFalsy();
expect(queryByTestId('upload-progress-indicator')).toBeTruthy();
expect(queryByTestId('retry-upload-progress-indicator')).toBeFalsy();
expect(action).toHaveBeenCalledTimes(0);
});

fireEvent.press(getByTestId('active-upload-progress-indicator'));

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

const snapshot = toJSON();

await waitFor(() => {
Expand All @@ -94,10 +92,12 @@ describe('UploadProgressIndicator', () => {
await waitFor(() => {
expect(queryByTestId('active-upload-progress-indicator')).toBeTruthy();
expect(queryByTestId('inactive-upload-progress-indicator')).toBeFalsy();
expect(queryByTestId('upload-progress-indicator')).toBeFalsy();
expect(queryByTestId('retry-upload-progress-indicator')).toBeTruthy();
expect(action).toHaveBeenCalledTimes(0);
});

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

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

Expand Down
Loading