[IMPROVE] - migrating the message container (in progress)

This commit is contained in:
AlexAlexandre 2021-07-22 17:09:06 -03:00
parent 43c4234f73
commit 6db54e9920
12 changed files with 139 additions and 137 deletions

View File

@ -1,20 +1,27 @@
import React from 'react';
import { dequal } from 'dequal';
import PropTypes from 'prop-types';
import Image from './Image';
import Audio from './Audio';
import Video from './Video';
import Reply from './Reply';
interface IMessageAttachments {
attachments: any;
timeFormat: string;
showAttachment: Function;
getCustomEmoji: Function;
theme: string;
}
const Attachments = React.memo(({
attachments, timeFormat, showAttachment, getCustomEmoji, theme
}) => {
}: IMessageAttachments) => {
if (!attachments || attachments.length === 0) {
return null;
}
return attachments.map((file, index) => {
return attachments.map((file: any, index: number) => {
if (file.image_url) {
return <Image key={file.image_url} file={file} showAttachment={showAttachment} getCustomEmoji={getCustomEmoji} theme={theme} />;
}
@ -30,13 +37,6 @@ const Attachments = React.memo(({
});
}, (prevProps, nextProps) => dequal(prevProps.attachments, nextProps.attachments) && prevProps.theme === nextProps.theme);
Attachments.propTypes = {
attachments: PropTypes.array,
timeFormat: PropTypes.string,
showAttachment: PropTypes.func,
getCustomEmoji: PropTypes.func,
theme: PropTypes.string
};
Attachments.displayName = 'MessageAttachments';
export default Attachments;

View File

@ -1,15 +1,19 @@
import React from 'react';
import PropTypes from 'prop-types';
import { messageBlockWithContext } from '../UIKit/MessageBlock';
const Blocks = React.memo(({
blocks, id: mid, rid, blockAction
}) => {
interface IMessageBlocks {
blocks: any;
id: string;
rid: string;
blockAction: Function;
}
const Blocks = React.memo(({ blocks, id: mid, rid, blockAction }: IMessageBlocks) => {
if (blocks && blocks.length > 0) {
const appId = blocks[0]?.appId || '';
return React.createElement(
messageBlockWithContext({
action: async({ actionId, value, blockId }) => {
action: async({ actionId, value, blockId }: any) => {
await blockAction({
actionId,
appId,
@ -27,12 +31,6 @@ const Blocks = React.memo(({
return null;
});
Blocks.propTypes = {
blocks: PropTypes.array,
id: PropTypes.string,
rid: PropTypes.string,
blockAction: PropTypes.func
};
Blocks.displayName = 'MessageBlocks';
export default Blocks;

View File

@ -1,6 +1,5 @@
import React from 'react';
import { View, Text } from 'react-native';
import PropTypes from 'prop-types';
import Touchable from './Touchable';
import { BUTTON_HIT_SLOP } from './utils';
@ -9,9 +8,12 @@ import I18n from '../../i18n';
import { CustomIcon } from '../../lib/Icons';
import { themes } from '../../constants/colors';
const CallButton = React.memo(({
theme, callJitsi
}) => (
interface IMessageCallButton {
theme: string;
callJitsi: Function;
}
const CallButton = React.memo(({ theme, callJitsi }: IMessageCallButton) => (
<View style={styles.buttonContainer}>
<Touchable
onPress={callJitsi}
@ -27,10 +29,6 @@ const CallButton = React.memo(({
</View>
));
CallButton.propTypes = {
theme: PropTypes.string,
callJitsi: PropTypes.func
};
CallButton.displayName = 'CallButton';
export default CallButton;

View File

@ -25,7 +25,7 @@ type TMessageImage = {
interface IMessageImage {
file: { image_url: string; description: string; };
imageUrl: string;
imageUrl?: string;
showAttachment: Function;
theme: string;
getCustomEmoji: Function;

View File

@ -1,13 +1,26 @@
import React, { useContext } from 'react';
import PropTypes from 'prop-types';
import Avatar from '../Avatar';
import styles from './styles';
import MessageContext from './Context';
interface IMessageAvatar {
isHeader: boolean;
avatar: string;
emoji: string;
author: {
username: string
_id: string;
};
small: boolean;
navToRoomInfo: Function;
getCustomEmoji(): void;
theme: string;
}
const MessageAvatar = React.memo(({
isHeader, avatar, author, small, navToRoomInfo, emoji, getCustomEmoji, theme
}) => {
}: IMessageAvatar) => {
const { user } = useContext(MessageContext);
if (isHeader && author) {
const navParam = {
@ -31,16 +44,6 @@ const MessageAvatar = React.memo(({
return null;
});
MessageAvatar.propTypes = {
isHeader: PropTypes.bool,
avatar: PropTypes.string,
emoji: PropTypes.string,
author: PropTypes.obj,
small: PropTypes.bool,
navToRoomInfo: PropTypes.func,
getCustomEmoji: PropTypes.func,
theme: PropTypes.string
};
MessageAvatar.displayName = 'MessageAvatar';
export default MessageAvatar;

View File

@ -1,5 +1,4 @@
import React, { useContext } from 'react';
import PropTypes from 'prop-types';
import Touchable from './Touchable';
import { CustomIcon } from '../../lib/Icons';
@ -8,7 +7,12 @@ import { BUTTON_HIT_SLOP } from './utils';
import { themes } from '../../constants/colors';
import MessageContext from './Context';
const MessageError = React.memo(({ hasError, theme }) => {
interface IMessageError {
hasError: boolean;
theme: string;
}
const MessageError = React.memo(({ hasError, theme }: IMessageError) => {
if (!hasError) {
return null;
}
@ -20,10 +24,6 @@ const MessageError = React.memo(({ hasError, theme }) => {
);
}, (prevProps, nextProps) => prevProps.hasError === nextProps.hasError && prevProps.theme === nextProps.theme);
MessageError.propTypes = {
hasError: PropTypes.bool,
theme: PropTypes.string
};
MessageError.displayName = 'MessageError';
export default MessageError;

View File

@ -1,11 +1,16 @@
import React from 'react';
import PropTypes from 'prop-types';
import { themes } from '../../constants/colors';
import { CustomIcon } from '../../lib/Icons';
import styles from './styles';
const ReadReceipt = React.memo(({ isReadReceiptEnabled, unread, theme }) => {
interface IMessageReadReceipt {
isReadReceiptEnabled: boolean;
unread: boolean;
theme: string;
}
const ReadReceipt = React.memo(({ isReadReceiptEnabled, unread, theme }: IMessageReadReceipt) => {
if (isReadReceiptEnabled && !unread && unread !== null) {
return <CustomIcon name='check' color={themes[theme].tintColor} size={15} style={styles.readReceipt} />;
}
@ -13,10 +18,4 @@ const ReadReceipt = React.memo(({ isReadReceiptEnabled, unread, theme }) => {
});
ReadReceipt.displayName = 'MessageReadReceipt';
ReadReceipt.propTypes = {
isReadReceiptEnabled: PropTypes.bool,
unread: PropTypes.bool,
theme: PropTypes.bool
};
export default ReadReceipt;

View File

@ -1,6 +1,5 @@
import React, { memo, useEffect, useState } from 'react';
import { View } from 'react-native';
import PropTypes from 'prop-types';
import { CustomIcon } from '../../lib/Icons';
import styles from './styles';
@ -8,9 +7,19 @@ import { themes } from '../../constants/colors';
import I18n from '../../i18n';
import Markdown from '../markdown';
interface IMessageRepliedThread {
tmid: string;
tmsg: string;
id: string;
isHeader: boolean;
theme: string;
fetchThreadName: Function;
isEncrypted: boolean;
}
const RepliedThread = memo(({
tmid, tmsg, isHeader, fetchThreadName, id, isEncrypted, theme
}) => {
}: IMessageRepliedThread) => {
if (!tmid || !isHeader) {
return null;
}
@ -34,6 +43,7 @@ const RepliedThread = memo(({
return (
<View style={styles.repliedThread} testID={`message-thread-replied-on-${ msg }`}>
<CustomIcon name='threads' size={20} style={styles.repliedThreadIcon} color={themes[theme].tintColor} />
{/*@ts-ignore*/}
<Markdown
msg={msg}
theme={theme}
@ -52,15 +62,6 @@ const RepliedThread = memo(({
);
});
RepliedThread.propTypes = {
tmid: PropTypes.string,
tmsg: PropTypes.string,
id: PropTypes.string,
isHeader: PropTypes.bool,
theme: PropTypes.string,
fetchThreadName: PropTypes.func,
isEncrypted: PropTypes.bool
};
RepliedThread.displayName = 'MessageRepliedThread';
export default RepliedThread;

View File

@ -1,6 +1,5 @@
import React, { useContext } from 'react';
import { View, Text } from 'react-native';
import PropTypes from 'prop-types';
import styles from './styles';
import { themes } from '../../constants/colors';
@ -8,9 +7,16 @@ import MessageContext from './Context';
import ThreadDetails from '../ThreadDetails';
import I18n from '../../i18n';
const Thread = React.memo(({
msg, tcount, tlm, isThreadRoom, theme, id
}) => {
interface IMessageThread {
msg: string;
tcount: number;
theme: string;
tlm: string;
isThreadRoom: boolean;
id: string;
}
const Thread = React.memo(({ msg, tcount, tlm, isThreadRoom, theme, id }: IMessageThread) => {
if (!tlm || isThreadRoom || tcount === 0) {
return null;
}
@ -50,14 +56,6 @@ const Thread = React.memo(({
return true;
});
Thread.propTypes = {
msg: PropTypes.string,
tcount: PropTypes.string,
theme: PropTypes.string,
tlm: PropTypes.string,
isThreadRoom: PropTypes.bool,
id: PropTypes.string
};
Thread.displayName = 'MessageThread';
export default Thread;

View File

@ -1,8 +1,5 @@
import React, { useContext } from 'react';
import {
View, Text, StyleSheet, Clipboard
} from 'react-native';
import PropTypes from 'prop-types';
import { View, Text, StyleSheet, Clipboard } from 'react-native';
import FastImage from '@rocket.chat/react-native-fast-image';
import { dequal } from 'dequal';
@ -52,7 +49,30 @@ const styles = StyleSheet.create({
}
});
const UrlImage = React.memo(({ image }) => {
type TMessageUrlContent = {
title: string;
description: string;
theme: string;
};
type TMessageUrl = {
url: {
ignoreParse: boolean;
url: string;
image: string;
title: string;
description: string;
};
index: number;
theme: string;
};
interface IMessageUrls {
urls: any;
theme: string;
}
const UrlImage = React.memo(({ image }: {image: string}) => {
if (!image) {
return null;
}
@ -61,7 +81,7 @@ const UrlImage = React.memo(({ image }) => {
return <FastImage source={{ uri: image }} style={styles.image} resizeMode={FastImage.resizeMode.cover} />;
}, (prevProps, nextProps) => prevProps.image === nextProps.image);
const UrlContent = React.memo(({ title, description, theme }) => (
const UrlContent = React.memo(({ title, description, theme }: TMessageUrlContent) => (
<View style={styles.textContainer}>
{title ? <Text style={[styles.title, { color: themes[theme].tintColor }]} numberOfLines={2}>{title}</Text> : null}
{description ? <Text style={[styles.description, { color: themes[theme].auxiliaryText }]} numberOfLines={2}>{description}</Text> : null}
@ -79,7 +99,7 @@ const UrlContent = React.memo(({ title, description, theme }) => (
return true;
});
const Url = React.memo(({ url, index, theme }) => {
const Url = React.memo(({ url, index, theme }: TMessageUrl) => {
if (!url || url?.ignoreParse) {
return null;
}
@ -114,39 +134,19 @@ const Url = React.memo(({ url, index, theme }) => {
);
}, (oldProps, newProps) => dequal(oldProps.url, newProps.url) && oldProps.theme === newProps.theme);
const Urls = React.memo(({ urls, theme }) => {
const Urls = React.memo(({ urls, theme }: IMessageUrls) => {
if (!urls || urls.length === 0) {
return null;
}
return urls.map((url, index) => (
return urls.map((url: any, index: number) => (
<Url url={url} key={url.url} index={index} theme={theme} />
));
}, (oldProps, newProps) => dequal(oldProps.urls, newProps.urls) && oldProps.theme === newProps.theme);
UrlImage.propTypes = {
image: PropTypes.string
};
UrlImage.displayName = 'MessageUrlImage';
UrlContent.propTypes = {
title: PropTypes.string,
description: PropTypes.string,
theme: PropTypes.string
};
UrlContent.displayName = 'MessageUrlContent';
Url.propTypes = {
url: PropTypes.object.isRequired,
index: PropTypes.number,
theme: PropTypes.string
};
Url.displayName = 'MessageUrl';
Urls.propTypes = {
urls: PropTypes.array,
theme: PropTypes.string
};
Urls.displayName = 'MessageUrls';
export default withTheme(Urls);

View File

@ -1,8 +1,5 @@
import React, { useContext } from 'react';
import PropTypes from 'prop-types';
import {
View, Text, StyleSheet, TouchableOpacity
} from 'react-native';
import { View, Text, StyleSheet, TouchableOpacity } from 'react-native';
import moment from 'moment';
import { themes } from '../../constants/colors';
@ -41,9 +38,26 @@ const styles = StyleSheet.create({
}
});
interface IMessageUser {
isHeader: boolean;
hasError: boolean;
useRealName: boolean;
author: {
_id: string;
name: string;
username: string;
};
alias: string;
ts: Date;
timeFormat: string;
theme: string;
navToRoomInfo: Function;
type: string;
}
const User = React.memo(({
isHeader, useRealName, author, alias, ts, timeFormat, hasError, theme, navToRoomInfo, type, ...props
}) => {
}: IMessageUser) => {
if (isHeader || hasError) {
const navParam = {
t: 'd',
@ -68,6 +82,7 @@ const User = React.memo(({
<Text
style={[styles.usernameInfoMessage, { color: themes[theme].titleText }]}
onPress={onUserPress}
// @ts-ignore
disabled={isDisabled}
>
{textContent}
@ -94,18 +109,6 @@ const User = React.memo(({
return null;
});
User.propTypes = {
isHeader: PropTypes.bool,
hasError: PropTypes.bool,
useRealName: PropTypes.bool,
author: PropTypes.object,
alias: PropTypes.string,
ts: PropTypes.instanceOf(Date),
timeFormat: PropTypes.string,
theme: PropTypes.string,
navToRoomInfo: PropTypes.func,
type: PropTypes.string
};
User.displayName = 'MessageUser';
export default withTheme(User);

View File

@ -1,5 +1,4 @@
import React, { useContext } from 'react';
import PropTypes from 'prop-types';
import { StyleSheet } from 'react-native';
import { dequal } from 'dequal';
@ -13,7 +12,7 @@ import { themes } from '../../constants/colors';
import MessageContext from './Context';
const SUPPORTED_TYPES = ['video/quicktime', 'video/mp4', ...(isIOS ? [] : ['video/3gp', 'video/mkv'])];
const isTypeSupported = type => SUPPORTED_TYPES.indexOf(type) !== -1;
const isTypeSupported = (type: any) => SUPPORTED_TYPES.indexOf(type) !== -1;
const styles = StyleSheet.create({
button: {
@ -26,9 +25,18 @@ const styles = StyleSheet.create({
}
});
const Video = React.memo(({
file, showAttachment, getCustomEmoji, theme
}) => {
interface IMessageVideo {
file: {
video_type: string;
video_url: string;
description: string;
};
showAttachment: Function;
getCustomEmoji: Function;
theme: string;
}
const Video = React.memo(({ file, showAttachment, getCustomEmoji, theme }: IMessageVideo) => {
const { baseUrl, user } = useContext(MessageContext);
if (!baseUrl) {
return null;
@ -54,16 +62,10 @@ const Video = React.memo(({
color={themes[theme].buttonText}
/>
</Touchable>
{/*@ts-ignore*/}
<Markdown msg={file.description} baseUrl={baseUrl} username={user.username} getCustomEmoji={getCustomEmoji} theme={theme} />
</>
);
}, (prevProps, nextProps) => dequal(prevProps.file, nextProps.file) && prevProps.theme === nextProps.theme);
Video.propTypes = {
file: PropTypes.object,
showAttachment: PropTypes.func,
getCustomEmoji: PropTypes.func,
theme: PropTypes.string
};
export default Video;