[IMPROVE] - migrating the message container (in progress)
This commit is contained in:
parent
43c4234f73
commit
6db54e9920
|
@ -1,20 +1,27 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { dequal } from 'dequal';
|
import { dequal } from 'dequal';
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
|
|
||||||
import Image from './Image';
|
import Image from './Image';
|
||||||
import Audio from './Audio';
|
import Audio from './Audio';
|
||||||
import Video from './Video';
|
import Video from './Video';
|
||||||
import Reply from './Reply';
|
import Reply from './Reply';
|
||||||
|
|
||||||
|
interface IMessageAttachments {
|
||||||
|
attachments: any;
|
||||||
|
timeFormat: string;
|
||||||
|
showAttachment: Function;
|
||||||
|
getCustomEmoji: Function;
|
||||||
|
theme: string;
|
||||||
|
}
|
||||||
|
|
||||||
const Attachments = React.memo(({
|
const Attachments = React.memo(({
|
||||||
attachments, timeFormat, showAttachment, getCustomEmoji, theme
|
attachments, timeFormat, showAttachment, getCustomEmoji, theme
|
||||||
}) => {
|
}: IMessageAttachments) => {
|
||||||
if (!attachments || attachments.length === 0) {
|
if (!attachments || attachments.length === 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return attachments.map((file, index) => {
|
return attachments.map((file: any, index: number) => {
|
||||||
if (file.image_url) {
|
if (file.image_url) {
|
||||||
return <Image key={file.image_url} file={file} showAttachment={showAttachment} getCustomEmoji={getCustomEmoji} theme={theme} />;
|
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);
|
}, (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';
|
Attachments.displayName = 'MessageAttachments';
|
||||||
|
|
||||||
export default Attachments;
|
export default Attachments;
|
|
@ -1,15 +1,19 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import { messageBlockWithContext } from '../UIKit/MessageBlock';
|
import { messageBlockWithContext } from '../UIKit/MessageBlock';
|
||||||
|
|
||||||
const Blocks = React.memo(({
|
interface IMessageBlocks {
|
||||||
blocks, id: mid, rid, blockAction
|
blocks: any;
|
||||||
}) => {
|
id: string;
|
||||||
|
rid: string;
|
||||||
|
blockAction: Function;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Blocks = React.memo(({ blocks, id: mid, rid, blockAction }: IMessageBlocks) => {
|
||||||
if (blocks && blocks.length > 0) {
|
if (blocks && blocks.length > 0) {
|
||||||
const appId = blocks[0]?.appId || '';
|
const appId = blocks[0]?.appId || '';
|
||||||
return React.createElement(
|
return React.createElement(
|
||||||
messageBlockWithContext({
|
messageBlockWithContext({
|
||||||
action: async({ actionId, value, blockId }) => {
|
action: async({ actionId, value, blockId }: any) => {
|
||||||
await blockAction({
|
await blockAction({
|
||||||
actionId,
|
actionId,
|
||||||
appId,
|
appId,
|
||||||
|
@ -27,12 +31,6 @@ const Blocks = React.memo(({
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
||||||
Blocks.propTypes = {
|
|
||||||
blocks: PropTypes.array,
|
|
||||||
id: PropTypes.string,
|
|
||||||
rid: PropTypes.string,
|
|
||||||
blockAction: PropTypes.func
|
|
||||||
};
|
|
||||||
Blocks.displayName = 'MessageBlocks';
|
Blocks.displayName = 'MessageBlocks';
|
||||||
|
|
||||||
export default Blocks;
|
export default Blocks;
|
|
@ -1,6 +1,5 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { View, Text } from 'react-native';
|
import { View, Text } from 'react-native';
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
|
|
||||||
import Touchable from './Touchable';
|
import Touchable from './Touchable';
|
||||||
import { BUTTON_HIT_SLOP } from './utils';
|
import { BUTTON_HIT_SLOP } from './utils';
|
||||||
|
@ -9,9 +8,12 @@ import I18n from '../../i18n';
|
||||||
import { CustomIcon } from '../../lib/Icons';
|
import { CustomIcon } from '../../lib/Icons';
|
||||||
import { themes } from '../../constants/colors';
|
import { themes } from '../../constants/colors';
|
||||||
|
|
||||||
const CallButton = React.memo(({
|
interface IMessageCallButton {
|
||||||
theme, callJitsi
|
theme: string;
|
||||||
}) => (
|
callJitsi: Function;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CallButton = React.memo(({ theme, callJitsi }: IMessageCallButton) => (
|
||||||
<View style={styles.buttonContainer}>
|
<View style={styles.buttonContainer}>
|
||||||
<Touchable
|
<Touchable
|
||||||
onPress={callJitsi}
|
onPress={callJitsi}
|
||||||
|
@ -27,10 +29,6 @@ const CallButton = React.memo(({
|
||||||
</View>
|
</View>
|
||||||
));
|
));
|
||||||
|
|
||||||
CallButton.propTypes = {
|
|
||||||
theme: PropTypes.string,
|
|
||||||
callJitsi: PropTypes.func
|
|
||||||
};
|
|
||||||
CallButton.displayName = 'CallButton';
|
CallButton.displayName = 'CallButton';
|
||||||
|
|
||||||
export default CallButton;
|
export default CallButton;
|
|
@ -25,7 +25,7 @@ type TMessageImage = {
|
||||||
|
|
||||||
interface IMessageImage {
|
interface IMessageImage {
|
||||||
file: { image_url: string; description: string; };
|
file: { image_url: string; description: string; };
|
||||||
imageUrl: string;
|
imageUrl?: string;
|
||||||
showAttachment: Function;
|
showAttachment: Function;
|
||||||
theme: string;
|
theme: string;
|
||||||
getCustomEmoji: Function;
|
getCustomEmoji: Function;
|
||||||
|
|
|
@ -1,13 +1,26 @@
|
||||||
import React, { useContext } from 'react';
|
import React, { useContext } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
|
|
||||||
import Avatar from '../Avatar';
|
import Avatar from '../Avatar';
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
import MessageContext from './Context';
|
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(({
|
const MessageAvatar = React.memo(({
|
||||||
isHeader, avatar, author, small, navToRoomInfo, emoji, getCustomEmoji, theme
|
isHeader, avatar, author, small, navToRoomInfo, emoji, getCustomEmoji, theme
|
||||||
}) => {
|
}: IMessageAvatar) => {
|
||||||
const { user } = useContext(MessageContext);
|
const { user } = useContext(MessageContext);
|
||||||
if (isHeader && author) {
|
if (isHeader && author) {
|
||||||
const navParam = {
|
const navParam = {
|
||||||
|
@ -31,16 +44,6 @@ const MessageAvatar = React.memo(({
|
||||||
return null;
|
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';
|
MessageAvatar.displayName = 'MessageAvatar';
|
||||||
|
|
||||||
export default MessageAvatar;
|
export default MessageAvatar;
|
|
@ -1,5 +1,4 @@
|
||||||
import React, { useContext } from 'react';
|
import React, { useContext } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
|
|
||||||
import Touchable from './Touchable';
|
import Touchable from './Touchable';
|
||||||
import { CustomIcon } from '../../lib/Icons';
|
import { CustomIcon } from '../../lib/Icons';
|
||||||
|
@ -8,7 +7,12 @@ import { BUTTON_HIT_SLOP } from './utils';
|
||||||
import { themes } from '../../constants/colors';
|
import { themes } from '../../constants/colors';
|
||||||
import MessageContext from './Context';
|
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) {
|
if (!hasError) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -20,10 +24,6 @@ const MessageError = React.memo(({ hasError, theme }) => {
|
||||||
);
|
);
|
||||||
}, (prevProps, nextProps) => prevProps.hasError === nextProps.hasError && prevProps.theme === nextProps.theme);
|
}, (prevProps, nextProps) => prevProps.hasError === nextProps.hasError && prevProps.theme === nextProps.theme);
|
||||||
|
|
||||||
MessageError.propTypes = {
|
|
||||||
hasError: PropTypes.bool,
|
|
||||||
theme: PropTypes.string
|
|
||||||
};
|
|
||||||
MessageError.displayName = 'MessageError';
|
MessageError.displayName = 'MessageError';
|
||||||
|
|
||||||
export default MessageError;
|
export default MessageError;
|
|
@ -1,11 +1,16 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
|
|
||||||
import { themes } from '../../constants/colors';
|
import { themes } from '../../constants/colors';
|
||||||
import { CustomIcon } from '../../lib/Icons';
|
import { CustomIcon } from '../../lib/Icons';
|
||||||
import styles from './styles';
|
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) {
|
if (isReadReceiptEnabled && !unread && unread !== null) {
|
||||||
return <CustomIcon name='check' color={themes[theme].tintColor} size={15} style={styles.readReceipt} />;
|
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.displayName = 'MessageReadReceipt';
|
||||||
|
|
||||||
ReadReceipt.propTypes = {
|
|
||||||
isReadReceiptEnabled: PropTypes.bool,
|
|
||||||
unread: PropTypes.bool,
|
|
||||||
theme: PropTypes.bool
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ReadReceipt;
|
export default ReadReceipt;
|
|
@ -1,6 +1,5 @@
|
||||||
import React, { memo, useEffect, useState } from 'react';
|
import React, { memo, useEffect, useState } from 'react';
|
||||||
import { View } from 'react-native';
|
import { View } from 'react-native';
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
|
|
||||||
import { CustomIcon } from '../../lib/Icons';
|
import { CustomIcon } from '../../lib/Icons';
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
|
@ -8,9 +7,19 @@ import { themes } from '../../constants/colors';
|
||||||
import I18n from '../../i18n';
|
import I18n from '../../i18n';
|
||||||
import Markdown from '../markdown';
|
import Markdown from '../markdown';
|
||||||
|
|
||||||
|
interface IMessageRepliedThread {
|
||||||
|
tmid: string;
|
||||||
|
tmsg: string;
|
||||||
|
id: string;
|
||||||
|
isHeader: boolean;
|
||||||
|
theme: string;
|
||||||
|
fetchThreadName: Function;
|
||||||
|
isEncrypted: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
const RepliedThread = memo(({
|
const RepliedThread = memo(({
|
||||||
tmid, tmsg, isHeader, fetchThreadName, id, isEncrypted, theme
|
tmid, tmsg, isHeader, fetchThreadName, id, isEncrypted, theme
|
||||||
}) => {
|
}: IMessageRepliedThread) => {
|
||||||
if (!tmid || !isHeader) {
|
if (!tmid || !isHeader) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -34,6 +43,7 @@ const RepliedThread = memo(({
|
||||||
return (
|
return (
|
||||||
<View style={styles.repliedThread} testID={`message-thread-replied-on-${ msg }`}>
|
<View style={styles.repliedThread} testID={`message-thread-replied-on-${ msg }`}>
|
||||||
<CustomIcon name='threads' size={20} style={styles.repliedThreadIcon} color={themes[theme].tintColor} />
|
<CustomIcon name='threads' size={20} style={styles.repliedThreadIcon} color={themes[theme].tintColor} />
|
||||||
|
{/*@ts-ignore*/}
|
||||||
<Markdown
|
<Markdown
|
||||||
msg={msg}
|
msg={msg}
|
||||||
theme={theme}
|
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';
|
RepliedThread.displayName = 'MessageRepliedThread';
|
||||||
|
|
||||||
export default RepliedThread;
|
export default RepliedThread;
|
|
@ -1,6 +1,5 @@
|
||||||
import React, { useContext } from 'react';
|
import React, { useContext } from 'react';
|
||||||
import { View, Text } from 'react-native';
|
import { View, Text } from 'react-native';
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
|
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
import { themes } from '../../constants/colors';
|
import { themes } from '../../constants/colors';
|
||||||
|
@ -8,9 +7,16 @@ import MessageContext from './Context';
|
||||||
import ThreadDetails from '../ThreadDetails';
|
import ThreadDetails from '../ThreadDetails';
|
||||||
import I18n from '../../i18n';
|
import I18n from '../../i18n';
|
||||||
|
|
||||||
const Thread = React.memo(({
|
interface IMessageThread {
|
||||||
msg, tcount, tlm, isThreadRoom, theme, id
|
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) {
|
if (!tlm || isThreadRoom || tcount === 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -50,14 +56,6 @@ const Thread = React.memo(({
|
||||||
return true;
|
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';
|
Thread.displayName = 'MessageThread';
|
||||||
|
|
||||||
export default Thread;
|
export default Thread;
|
|
@ -1,8 +1,5 @@
|
||||||
import React, { useContext } from 'react';
|
import React, { useContext } from 'react';
|
||||||
import {
|
import { View, Text, StyleSheet, Clipboard } from 'react-native';
|
||||||
View, Text, StyleSheet, Clipboard
|
|
||||||
} from 'react-native';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import FastImage from '@rocket.chat/react-native-fast-image';
|
import FastImage from '@rocket.chat/react-native-fast-image';
|
||||||
import { dequal } from 'dequal';
|
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) {
|
if (!image) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -61,7 +81,7 @@ const UrlImage = React.memo(({ image }) => {
|
||||||
return <FastImage source={{ uri: image }} style={styles.image} resizeMode={FastImage.resizeMode.cover} />;
|
return <FastImage source={{ uri: image }} style={styles.image} resizeMode={FastImage.resizeMode.cover} />;
|
||||||
}, (prevProps, nextProps) => prevProps.image === nextProps.image);
|
}, (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}>
|
<View style={styles.textContainer}>
|
||||||
{title ? <Text style={[styles.title, { color: themes[theme].tintColor }]} numberOfLines={2}>{title}</Text> : null}
|
{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}
|
{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;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
const Url = React.memo(({ url, index, theme }) => {
|
const Url = React.memo(({ url, index, theme }: TMessageUrl) => {
|
||||||
if (!url || url?.ignoreParse) {
|
if (!url || url?.ignoreParse) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -114,39 +134,19 @@ const Url = React.memo(({ url, index, theme }) => {
|
||||||
);
|
);
|
||||||
}, (oldProps, newProps) => dequal(oldProps.url, newProps.url) && oldProps.theme === newProps.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) {
|
if (!urls || urls.length === 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return urls.map((url, index) => (
|
return urls.map((url: any, index: number) => (
|
||||||
<Url url={url} key={url.url} index={index} theme={theme} />
|
<Url url={url} key={url.url} index={index} theme={theme} />
|
||||||
));
|
));
|
||||||
}, (oldProps, newProps) => dequal(oldProps.urls, newProps.urls) && oldProps.theme === newProps.theme);
|
}, (oldProps, newProps) => dequal(oldProps.urls, newProps.urls) && oldProps.theme === newProps.theme);
|
||||||
|
|
||||||
UrlImage.propTypes = {
|
|
||||||
image: PropTypes.string
|
|
||||||
};
|
|
||||||
UrlImage.displayName = 'MessageUrlImage';
|
UrlImage.displayName = 'MessageUrlImage';
|
||||||
|
|
||||||
UrlContent.propTypes = {
|
|
||||||
title: PropTypes.string,
|
|
||||||
description: PropTypes.string,
|
|
||||||
theme: PropTypes.string
|
|
||||||
};
|
|
||||||
UrlContent.displayName = 'MessageUrlContent';
|
UrlContent.displayName = 'MessageUrlContent';
|
||||||
|
|
||||||
Url.propTypes = {
|
|
||||||
url: PropTypes.object.isRequired,
|
|
||||||
index: PropTypes.number,
|
|
||||||
theme: PropTypes.string
|
|
||||||
};
|
|
||||||
Url.displayName = 'MessageUrl';
|
Url.displayName = 'MessageUrl';
|
||||||
|
|
||||||
Urls.propTypes = {
|
|
||||||
urls: PropTypes.array,
|
|
||||||
theme: PropTypes.string
|
|
||||||
};
|
|
||||||
Urls.displayName = 'MessageUrls';
|
Urls.displayName = 'MessageUrls';
|
||||||
|
|
||||||
export default withTheme(Urls);
|
export default withTheme(Urls);
|
|
@ -1,8 +1,5 @@
|
||||||
import React, { useContext } from 'react';
|
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 moment from 'moment';
|
||||||
|
|
||||||
import { themes } from '../../constants/colors';
|
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(({
|
const User = React.memo(({
|
||||||
isHeader, useRealName, author, alias, ts, timeFormat, hasError, theme, navToRoomInfo, type, ...props
|
isHeader, useRealName, author, alias, ts, timeFormat, hasError, theme, navToRoomInfo, type, ...props
|
||||||
}) => {
|
}: IMessageUser) => {
|
||||||
if (isHeader || hasError) {
|
if (isHeader || hasError) {
|
||||||
const navParam = {
|
const navParam = {
|
||||||
t: 'd',
|
t: 'd',
|
||||||
|
@ -68,6 +82,7 @@ const User = React.memo(({
|
||||||
<Text
|
<Text
|
||||||
style={[styles.usernameInfoMessage, { color: themes[theme].titleText }]}
|
style={[styles.usernameInfoMessage, { color: themes[theme].titleText }]}
|
||||||
onPress={onUserPress}
|
onPress={onUserPress}
|
||||||
|
// @ts-ignore
|
||||||
disabled={isDisabled}
|
disabled={isDisabled}
|
||||||
>
|
>
|
||||||
{textContent}
|
{textContent}
|
||||||
|
@ -94,18 +109,6 @@ const User = React.memo(({
|
||||||
return null;
|
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';
|
User.displayName = 'MessageUser';
|
||||||
|
|
||||||
export default withTheme(User);
|
export default withTheme(User);
|
|
@ -1,5 +1,4 @@
|
||||||
import React, { useContext } from 'react';
|
import React, { useContext } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import { StyleSheet } from 'react-native';
|
import { StyleSheet } from 'react-native';
|
||||||
import { dequal } from 'dequal';
|
import { dequal } from 'dequal';
|
||||||
|
|
||||||
|
@ -13,7 +12,7 @@ import { themes } from '../../constants/colors';
|
||||||
import MessageContext from './Context';
|
import MessageContext from './Context';
|
||||||
|
|
||||||
const SUPPORTED_TYPES = ['video/quicktime', 'video/mp4', ...(isIOS ? [] : ['video/3gp', 'video/mkv'])];
|
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({
|
const styles = StyleSheet.create({
|
||||||
button: {
|
button: {
|
||||||
|
@ -26,9 +25,18 @@ const styles = StyleSheet.create({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const Video = React.memo(({
|
interface IMessageVideo {
|
||||||
file, showAttachment, getCustomEmoji, theme
|
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);
|
const { baseUrl, user } = useContext(MessageContext);
|
||||||
if (!baseUrl) {
|
if (!baseUrl) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -54,16 +62,10 @@ const Video = React.memo(({
|
||||||
color={themes[theme].buttonText}
|
color={themes[theme].buttonText}
|
||||||
/>
|
/>
|
||||||
</Touchable>
|
</Touchable>
|
||||||
|
{/*@ts-ignore*/}
|
||||||
<Markdown msg={file.description} baseUrl={baseUrl} username={user.username} getCustomEmoji={getCustomEmoji} theme={theme} />
|
<Markdown msg={file.description} baseUrl={baseUrl} username={user.username} getCustomEmoji={getCustomEmoji} theme={theme} />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}, (prevProps, nextProps) => dequal(prevProps.file, nextProps.file) && prevProps.theme === nextProps.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;
|
export default Video;
|
Loading…
Reference in New Issue