Skip to content

Commit

Permalink
[#2514] fixed ui bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
AudreyKj authored Oct 21, 2021
1 parent 835d881 commit 7b588f2
Show file tree
Hide file tree
Showing 13 changed files with 113 additions and 48 deletions.
41 changes: 30 additions & 11 deletions frontend/ui/src/pages/Inbox/MessageInput/InputSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,24 @@ import styles from './InputSelector.module.scss';
import {ReactComponent as Close} from 'assets/images/icons/close.svg';
import {SourceMessage} from 'render';
import {Source, Message} from 'model';
import {FileInfo} from './index';

type InputSelectorProps = {
messageType: 'template' | 'suggestedReplies' | 'message';
message: Message;
source: Source;
contentResizedHeight: number;
fileInfo: FileInfo | null;
removeElementFromInput: () => void;
};

export const InputSelector = (props: InputSelectorProps) => {
const {source, message, messageType, removeElementFromInput, contentResizedHeight} = props;
const {source, message, messageType, removeElementFromInput, contentResizedHeight, fileInfo} = props;
const [closeIconWidth, setCloseIconWidth] = useState('');
const [closeIconHeight, setCloseIconHeight] = useState('');
const [closeButtonSelector, setCloseButtonSelector] = useState(false);

const removeSelectedButton = useRef(null);
const fileSelectorDiv = useRef<HTMLDivElement>(null);
const fileSelectorDiv = useRef(null);
const removeFileButton = useRef(null);

const scaleInputSelector = () => {
Expand All @@ -32,15 +34,30 @@ export const InputSelector = (props: InputSelectorProps) => {

setCloseIconHeight(iconSize);
setCloseIconWidth(iconSize);
setCloseButtonSelector(true);

if (removeFileButton && removeFileButton.current) {
removeFileButton.current.style.width = buttonSize;
removeFileButton.current.style.height = buttonSize;
}
} else {
setCloseButtonSelector(true);
}

fileSelectorDiv.current.style.transform = `scale(${scaleRatio})`;
fileSelectorDiv.current.style.transformOrigin = 'left';
} else {
if (fileInfo && fileInfo?.size >= 1 && fileInfo?.type !== 'audio' && fileInfo?.type !== 'file') {
setTimeout(() => {
setCloseButtonSelector(true);
}, 1000);
} else if (fileInfo && fileInfo?.size < 1 && fileInfo?.type !== 'audio' && fileInfo?.type !== 'file') {
setTimeout(() => {
setCloseButtonSelector(true);
}, 500);
} else {
setCloseButtonSelector(true);
}
}
};

Expand All @@ -50,14 +67,16 @@ export const InputSelector = (props: InputSelectorProps) => {

return (
<div className={styles.container} ref={fileSelectorDiv}>
<button className={styles.removeButton} onClick={removeElementFromInput} ref={removeSelectedButton}>
<Close
style={{
width: closeIconWidth ?? '',
height: closeIconHeight ?? '',
}}
/>
</button>
{closeButtonSelector && (
<button className={styles.removeButton} onClick={removeElementFromInput} ref={removeFileButton}>
<Close
style={{
width: closeIconWidth ?? '',
height: closeIconHeight ?? '',
}}
/>
</button>
)}
<SourceMessage message={message} source={source} contentType={messageType} />
</div>
);
Expand Down
48 changes: 35 additions & 13 deletions frontend/ui/src/pages/Inbox/MessageInput/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,16 @@ import {sendMessages} from '../../../actions/messages';
import {withRouter} from 'react-router-dom';
import {Button, SimpleLoader} from 'components';
import {cyMessageSendButton, cyMessageTextArea, cySuggestionsButton} from 'handles';
import {getOutboundMapper} from 'render';
import {
getOutboundMapper,
getAttachmentType,
isSupportedByInstagramMessenger,
imageExtensions,
fileExtensions,
videoExtensions,
audioExtensions,
instagramImageExtensions,
} from 'render';
import {Message, SuggestedReply, Suggestions, Template, Source} from 'model';
import {isEmpty} from 'lodash-es';

Expand All @@ -24,15 +33,6 @@ import {InputOptions} from './InputOptions';
import styles from './index.module.scss';
import {HttpClientInstance} from '../../../httpClient';
import {FacebookMapper} from 'render/outbound/facebook';
import {
getAttachmentType,
isSupportedByInstagramMessenger,
imageExtensions,
fileExtensions,
videoExtensions,
audioExtensions,
instagramImageExtensions,
} from 'render/attachments';
import {InputSelector} from './InputSelector';
import {usePrevious} from '../../../services/hooks/usePrevious';

Expand All @@ -53,14 +53,20 @@ type Props = {
hideSuggestedReplies: () => void;
draggedAndDroppedFile: File;
setDraggedAndDroppedFile: React.Dispatch<React.SetStateAction<File | null>>;
setDragAndDropDisabled: React.Dispatch<React.SetStateAction<boolean>>;
} & ConnectedProps<typeof connector>;

interface SelectedTemplate {
message: Template;
source: Source;
}

interface SelectedSuggestedReply {
export interface FileInfo {
size: number;
type: string;
}

export interface SelectedSuggestedReply {
message: SuggestedReply;
}

Expand All @@ -74,6 +80,7 @@ const MessageInput = (props: Props) => {
sendMessages,
draggedAndDroppedFile,
setDraggedAndDroppedFile,
setDragAndDropDisabled,
config,
} = props;

Expand All @@ -90,6 +97,7 @@ const MessageInput = (props: Props) => {
const [uploadedFileUrl, setUploadedFileUrl] = useState<string | null>(null);
const [fileUploadErrorPopUp, setFileUploadErrorPopUp] = useState<string>('');
const [loadingSelector, setLoadingSelector] = useState(false);
const [fileInfo, setFileInfo] = useState<null | {size: number; type: string}>(null);
const prevConversationId = usePrevious(conversation.id);

const textAreaRef = useRef(null);
Expand Down Expand Up @@ -147,9 +155,18 @@ const MessageInput = (props: Props) => {
useEffect(() => {
if (fileToUpload) {
setLoadingSelector(true);
setDragAndDropDisabled(true);
}
}, [fileToUpload]);

useEffect(() => {
if (isElementSelected()) {
setDragAndDropDisabled(true);
} else if (config.components['media-resolver'].enabled && (source === 'facebook' || source === 'instagram')) {
setDragAndDropDisabled(false);
}
}, [selectedTemplate, selectedSuggestedReply, uploadedFileUrl]);

useEffect(() => {
if (textAreaRef && textAreaRef.current) {
textAreaRef.current.style.height = 'inherit';
Expand All @@ -170,6 +187,7 @@ const MessageInput = (props: Props) => {

const uploadFile = (file: File) => {
const fileSizeInMB = file.size / Math.pow(1024, 2);
const maxFileSizeAllowed = 15;

//instagram upload errors
if (source === 'instagram') {
Expand All @@ -186,8 +204,10 @@ const MessageInput = (props: Props) => {
}

//facebook upload errors
if (fileSizeInMB >= 25) {
return setFileUploadErrorPopUp('Failed to upload the file. The maximum file size allowed is 25MB.');
if (fileSizeInMB >= maxFileSizeAllowed) {
return setFileUploadErrorPopUp(
`Failed to upload the file. The maximum file size allowed is ${maxFileSizeAllowed}MB.`
);
}

if (!getAttachmentType(file.name)) {
Expand All @@ -198,6 +218,7 @@ const MessageInput = (props: Props) => {
return setFileUploadErrorPopUp(message);
}

setFileInfo({size: fileSizeInMB, type: getAttachmentType(file.name)});
setFileToUpload(file);
};

Expand Down Expand Up @@ -419,6 +440,7 @@ const MessageInput = (props: Props) => {
messageType={selectedTemplate ? 'template' : selectedSuggestedReply ? 'suggestedReplies' : 'message'}
removeElementFromInput={removeElementFromInput}
contentResizedHeight={contentResizedHeight}
fileInfo={fileInfo}
/>
</>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,32 +97,33 @@ const MessengerContainer = ({
};

const handleDragEnter = (event: React.DragEvent<HTMLDivElement>) => {
if (dragAndDropDisabled) return;

event.preventDefault();
event.stopPropagation();

if (dragAndDropDisabled) return;

dragCounter++;

setIsFileDragged(true);
};

const handleFileDrop = (event: React.DragEvent<HTMLDivElement>) => {
if (dragAndDropDisabled) return;

event.preventDefault();
event.stopPropagation();

if (dragAndDropDisabled) return;
dragCounter++;
const file = event.dataTransfer.files[0];
setDraggedAndDroppedFile(file);
setIsFileDragged(false);
};

const handleDragLeave = (event: React.DragEvent<HTMLDivElement>) => {
if (dragAndDropDisabled) return;
event.preventDefault();
event.stopPropagation();

if (dragAndDropDisabled) return;
dragCounter--;
if (dragCounter === 0) {
setIsFileDragged(false);
Expand Down Expand Up @@ -164,6 +165,7 @@ const MessengerContainer = ({
source={currentConversation.channel.source as Source}
draggedAndDroppedFile={draggedAndDroppedFile}
setDraggedAndDroppedFile={setDraggedAndDroppedFile}
setDragAndDropDisabled={setDragAndDropDisabled}
/>
</>
)}
Expand Down
1 change: 1 addition & 0 deletions lib/typescript/render/attachments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export const fileExtensions = [
'docx',
'rtf',
'tex',
'txt',
'wpd',
'psd',
'svg',
Expand Down
1 change: 1 addition & 0 deletions lib/typescript/render/components/Image/index.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@

.messageListItemImageBlock {
max-height: 200px;
max-width: 300px;
border-radius: 8px;
}
30 changes: 21 additions & 9 deletions lib/typescript/render/components/ImageWithFallback/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ type ImageRenderProps = {
src: string;
alt?: string;
className?: string;
isTemplate?: boolean;
};

/**
Expand All @@ -14,7 +15,7 @@ type ImageRenderProps = {
*/
const failedUrls = [];

export const ImageWithFallback = ({src, alt, className}: ImageRenderProps) => {
export const ImageWithFallback = ({src, alt, className, isTemplate}: ImageRenderProps) => {
const [imageFailed, setImageFailed] = useState(failedUrls.includes(src));

useEffect(() => {
Expand All @@ -27,13 +28,24 @@ export const ImageWithFallback = ({src, alt, className}: ImageRenderProps) => {
};

return (
<a href={src} target="_blank" rel="noopener noreferrer">
<img
className={className}
src={imageFailed ? 'https://s3.amazonaws.com/assets.airy.co/fallbackMediaImage.svg' : src}
alt={imageFailed ? 'The image failed to load' : alt}
onError={() => loadingFailed()}
/>
</a>
<>
{isTemplate ? (
<img
className={className}
src={imageFailed ? 'https://s3.amazonaws.com/assets.airy.co/fallbackMediaImage.svg' : src}
alt={imageFailed ? 'The image failed to load' : alt}
onError={() => loadingFailed()}
/>
) : (
<a href={src} target="_blank" rel="noopener noreferrer">
<img
className={className}
src={imageFailed ? 'https://s3.amazonaws.com/assets.airy.co/fallbackMediaImage.svg' : src}
alt={imageFailed ? 'The image failed to load' : alt}
onError={() => loadingFailed()}
/>
</a>
)}
</>
);
};
1 change: 1 addition & 0 deletions lib/typescript/render/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export * from './props';
export * from './SourceMessage';
export * from './SourceMessagePreview';
export * from './outbound';
export * from './attachments';
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,14 @@ export const QuickReplies = ({

<div className={styles.container}>
{quickReplies.map((reply: QuickReply) => (
<button key={reply.title} className={styles.replyButton} onClick={() => clickPostback(reply)}>
<button type="button" key={reply.title} className={styles.replyButton} onClick={() => clickPostback(reply)}>
{reply.image_url && (
<ImageWithFallback className={styles.quickReplyImage} alt={reply.title} src={reply.image_url} />
<ImageWithFallback
className={styles.quickReplyImage}
alt={reply.title}
src={reply.image_url}
isTemplate
/>
)}
<h1 key={reply.title} className={styles.title}>
{reply.title}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,5 @@ const getHeight = (height: MediaHeight): string => {
};

export const Media = ({height, contentInfo: {altText, fileUrl}}: MediaRenderProps) => (
<ImageWithFallback src={fileUrl} alt={altText} className={`${styles.mediaImage} ${getHeight(height)}`} />
<ImageWithFallback src={fileUrl} alt={altText} className={`${styles.mediaImage} ${getHeight(height)}`} isTemplate />
);
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ export const GenericTemplate = ({template}: GenericTemplateRendererProps) => {
<Carousel>
{template.elements.map((element, idx) => (
<div key={`template-${idx}`} className={styles.template}>
{element.image_url?.length && <ImageWithFallback className={styles.templateImage} src={element.image_url} />}
{element.image_url?.length && (
<ImageWithFallback className={styles.templateImage} src={element.image_url} isTemplate />
)}
<div className={styles.innerTemplate}>
<div className={styles.templateTitle}>{element.title}</div>
<div className={styles.templateSubtitle}>{element.subtitle}</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ export const QuickReplies = ({quickReplies, fromContact, text, attachment}: Quic

<div className={styles.container}>
{quickReplies.map(({title, image_url: imageUrl}) => (
<button key={title} className={styles.replyButton}>
{imageUrl && <ImageWithFallback className={styles.quickReplyImage} alt={title} src={imageUrl} />}
<button type="button" key={title} className={styles.replyButton}>
{imageUrl && <ImageWithFallback className={styles.quickReplyImage} alt={title} src={imageUrl} isTemplate />}
<h1 key={title} className={styles.title}>
{title}
</h1>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,5 @@ const getHeight = (height: MediaHeight): string => {
};

export const Media = ({height, contentInfo: {altText, fileUrl}}: MediaRenderProps) => (
<ImageWithFallback src={fileUrl} alt={altText} className={`${styles.mediaImage} ${getHeight(height)}`} />
<ImageWithFallback src={fileUrl} alt={altText} className={`${styles.mediaImage} ${getHeight(height)}`} isTemplate />
);
Loading

0 comments on commit 7b588f2

Please sign in to comment.