[IMPROVE] - migrating the message container (finished)
This commit is contained in:
parent
6db54e9920
commit
024c744615
|
@ -3,7 +3,7 @@ import { ActivityIndicator, ActivityIndicatorProps, StyleSheet } from 'react-nat
|
||||||
import { themes } from '../constants/colors';
|
import { themes } from '../constants/colors';
|
||||||
|
|
||||||
interface IActivityIndicator extends ActivityIndicatorProps{
|
interface IActivityIndicator extends ActivityIndicatorProps{
|
||||||
theme?: 'light' | 'dark' | 'black',
|
theme?: 'light' | 'dark' | 'black' | string,
|
||||||
absolute?: boolean,
|
absolute?: boolean,
|
||||||
props?: object
|
props?: object
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ import Audio from './Audio';
|
||||||
import Video from './Video';
|
import Video from './Video';
|
||||||
import Reply from './Reply';
|
import Reply from './Reply';
|
||||||
|
|
||||||
interface IMessageAttachments {
|
export interface IMessageAttachments {
|
||||||
attachments: any;
|
attachments: any;
|
||||||
timeFormat: string;
|
timeFormat: string;
|
||||||
showAttachment: Function;
|
showAttachment: Function;
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import { View, StyleSheet, Text, Easing } from 'react-native';
|
||||||
import {
|
|
||||||
View, StyleSheet, Text, Easing
|
|
||||||
} from 'react-native';
|
|
||||||
import { Audio } from 'expo-av';
|
import { Audio } from 'expo-av';
|
||||||
import Slider from '@react-native-community/slider';
|
import Slider from '@react-native-community/slider';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
|
@ -19,6 +16,30 @@ import MessageContext from './Context';
|
||||||
import ActivityIndicator from '../ActivityIndicator';
|
import ActivityIndicator from '../ActivityIndicator';
|
||||||
import { withDimensions } from '../../dimensions';
|
import { withDimensions } from '../../dimensions';
|
||||||
|
|
||||||
|
type TButton = {
|
||||||
|
loading: boolean;
|
||||||
|
paused: boolean;
|
||||||
|
theme: string;
|
||||||
|
onPress: Function;
|
||||||
|
};
|
||||||
|
|
||||||
|
interface IMessageAudioProps {
|
||||||
|
file: {
|
||||||
|
audio_url: string;
|
||||||
|
description: string;
|
||||||
|
};
|
||||||
|
theme: string;
|
||||||
|
getCustomEmoji: Function;
|
||||||
|
scale: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IMessageAudioState {
|
||||||
|
loading: boolean,
|
||||||
|
currentTime: number,
|
||||||
|
duration: number,
|
||||||
|
paused: boolean
|
||||||
|
}
|
||||||
|
|
||||||
const mode = {
|
const mode = {
|
||||||
allowsRecordingIOS: false,
|
allowsRecordingIOS: false,
|
||||||
playsInSilentModeIOS: true,
|
playsInSilentModeIOS: true,
|
||||||
|
@ -57,19 +78,17 @@ const styles = StyleSheet.create({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const formatTime = seconds => moment.utc(seconds * 1000).format('mm:ss');
|
const formatTime = (seconds: number) => moment.utc(seconds * 1000).format('mm:ss');
|
||||||
const BUTTON_HIT_SLOP = {
|
|
||||||
top: 12, right: 12, bottom: 12, left: 12
|
const BUTTON_HIT_SLOP = { top: 12, right: 12, bottom: 12, left: 12 };
|
||||||
};
|
|
||||||
const sliderAnimationConfig = {
|
const sliderAnimationConfig = {
|
||||||
duration: 250,
|
duration: 250,
|
||||||
easing: Easing.linear,
|
easing: Easing.linear,
|
||||||
delay: 0
|
delay: 0
|
||||||
};
|
};
|
||||||
|
|
||||||
const Button = React.memo(({
|
const Button = React.memo(({ loading, paused, onPress, theme }: TButton) => (
|
||||||
loading, paused, onPress, theme
|
|
||||||
}) => (
|
|
||||||
<Touchable
|
<Touchable
|
||||||
style={styles.playPauseButton}
|
style={styles.playPauseButton}
|
||||||
onPress={onPress}
|
onPress={onPress}
|
||||||
|
@ -84,25 +103,13 @@ const Button = React.memo(({
|
||||||
</Touchable>
|
</Touchable>
|
||||||
));
|
));
|
||||||
|
|
||||||
Button.propTypes = {
|
|
||||||
loading: PropTypes.bool,
|
|
||||||
paused: PropTypes.bool,
|
|
||||||
theme: PropTypes.string,
|
|
||||||
onPress: PropTypes.func
|
|
||||||
};
|
|
||||||
Button.displayName = 'MessageAudioButton';
|
Button.displayName = 'MessageAudioButton';
|
||||||
|
|
||||||
class MessageAudio extends React.Component {
|
class MessageAudio extends React.Component<IMessageAudioProps, IMessageAudioState> {
|
||||||
static contextType = MessageContext;
|
static contextType = MessageContext;
|
||||||
|
private sound: any;
|
||||||
|
|
||||||
static propTypes = {
|
constructor(props: IMessageAudioProps) {
|
||||||
file: PropTypes.object.isRequired,
|
|
||||||
theme: PropTypes.string,
|
|
||||||
getCustomEmoji: PropTypes.func,
|
|
||||||
scale: PropTypes.number
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
loading: false,
|
loading: false,
|
||||||
|
@ -133,7 +140,7 @@ class MessageAudio extends React.Component {
|
||||||
this.setState({ loading: false });
|
this.setState({ loading: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
shouldComponentUpdate(nextProps, nextState) {
|
shouldComponentUpdate(nextProps: any, nextState: any) {
|
||||||
const {
|
const {
|
||||||
currentTime, duration, paused, loading
|
currentTime, duration, paused, loading
|
||||||
} = this.state;
|
} = this.state;
|
||||||
|
@ -176,7 +183,7 @@ class MessageAudio extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onPlaybackStatusUpdate = (status) => {
|
onPlaybackStatusUpdate = (status: any) => {
|
||||||
if (status) {
|
if (status) {
|
||||||
this.onLoad(status);
|
this.onLoad(status);
|
||||||
this.onProgress(status);
|
this.onProgress(status);
|
||||||
|
@ -184,12 +191,12 @@ class MessageAudio extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onLoad = (data) => {
|
onLoad = (data: any) => {
|
||||||
const duration = data.durationMillis / 1000;
|
const duration = data.durationMillis / 1000;
|
||||||
this.setState({ duration: duration > 0 ? duration : 0 });
|
this.setState({ duration: duration > 0 ? duration : 0 });
|
||||||
}
|
}
|
||||||
|
|
||||||
onProgress = (data) => {
|
onProgress = (data: any) => {
|
||||||
const { duration } = this.state;
|
const { duration } = this.state;
|
||||||
const currentTime = data.positionMillis / 1000;
|
const currentTime = data.positionMillis / 1000;
|
||||||
if (currentTime <= duration) {
|
if (currentTime <= duration) {
|
||||||
|
@ -197,7 +204,7 @@ class MessageAudio extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onEnd = async(data) => {
|
onEnd = async(data: any) => {
|
||||||
if (data.didJustFinish) {
|
if (data.didJustFinish) {
|
||||||
try {
|
try {
|
||||||
await this.sound.stopAsync();
|
await this.sound.stopAsync();
|
||||||
|
@ -232,7 +239,7 @@ class MessageAudio extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onValueChange = async(value) => {
|
onValueChange = async(value: any) => {
|
||||||
try {
|
try {
|
||||||
this.setState({ currentTime: value });
|
this.setState({ currentTime: value });
|
||||||
await this.sound.setPositionAsync(value * 1000);
|
await this.sound.setPositionAsync(value * 1000);
|
||||||
|
@ -275,10 +282,12 @@ class MessageAudio extends React.Component {
|
||||||
minimumTrackTintColor={themes[theme].tintColor}
|
minimumTrackTintColor={themes[theme].tintColor}
|
||||||
maximumTrackTintColor={themes[theme].auxiliaryText}
|
maximumTrackTintColor={themes[theme].auxiliaryText}
|
||||||
onValueChange={this.onValueChange}
|
onValueChange={this.onValueChange}
|
||||||
|
/*@ts-ignore*/
|
||||||
thumbImage={isIOS && { uri: 'audio_thumb', scale }}
|
thumbImage={isIOS && { uri: 'audio_thumb', scale }}
|
||||||
/>
|
/>
|
||||||
<Text style={[styles.duration, { color: themes[theme].auxiliaryText }]}>{this.duration}</Text>
|
<Text style={[styles.duration, { color: themes[theme].auxiliaryText }]}>{this.duration}</Text>
|
||||||
</View>
|
</View>
|
||||||
|
{/*@ts-ignore*/}
|
||||||
<Markdown msg={description} baseUrl={baseUrl} username={user.username} getCustomEmoji={getCustomEmoji} theme={theme} />
|
<Markdown msg={description} baseUrl={baseUrl} username={user.username} getCustomEmoji={getCustomEmoji} theme={theme} />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { messageBlockWithContext } from '../UIKit/MessageBlock';
|
import { messageBlockWithContext } from '../UIKit/MessageBlock';
|
||||||
|
|
||||||
interface IMessageBlocks {
|
export interface IMessageBlocks {
|
||||||
blocks: any;
|
blocks: any;
|
||||||
id: string;
|
id: string;
|
||||||
rid: string;
|
rid: string;
|
||||||
|
|
|
@ -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 Touchable from './Touchable';
|
import Touchable from './Touchable';
|
||||||
import { CustomIcon } from '../../lib/Icons';
|
import { CustomIcon } from '../../lib/Icons';
|
||||||
|
@ -10,9 +9,15 @@ import I18n from '../../i18n';
|
||||||
import { themes } from '../../constants/colors';
|
import { themes } from '../../constants/colors';
|
||||||
import MessageContext from './Context';
|
import MessageContext from './Context';
|
||||||
|
|
||||||
const Broadcast = React.memo(({
|
export interface IMessageBroadcast {
|
||||||
author, broadcast, theme
|
author: {
|
||||||
}) => {
|
_id: string
|
||||||
|
};
|
||||||
|
broadcast: boolean;
|
||||||
|
theme: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const Broadcast = React.memo(({ author, broadcast, theme }: IMessageBroadcast) => {
|
||||||
const { user, replyBroadcast } = useContext(MessageContext);
|
const { user, replyBroadcast } = useContext(MessageContext);
|
||||||
const isOwn = author._id === user.id;
|
const isOwn = author._id === user.id;
|
||||||
if (broadcast && !isOwn) {
|
if (broadcast && !isOwn) {
|
||||||
|
@ -36,11 +41,6 @@ const Broadcast = React.memo(({
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
||||||
Broadcast.propTypes = {
|
|
||||||
author: PropTypes.object,
|
|
||||||
broadcast: PropTypes.bool,
|
|
||||||
theme: PropTypes.string
|
|
||||||
};
|
|
||||||
Broadcast.displayName = 'MessageBroadcast';
|
Broadcast.displayName = 'MessageBroadcast';
|
||||||
|
|
||||||
export default Broadcast;
|
export default Broadcast;
|
|
@ -8,7 +8,7 @@ import I18n from '../../i18n';
|
||||||
import { CustomIcon } from '../../lib/Icons';
|
import { CustomIcon } from '../../lib/Icons';
|
||||||
import { themes } from '../../constants/colors';
|
import { themes } from '../../constants/colors';
|
||||||
|
|
||||||
interface IMessageCallButton {
|
export interface IMessageCallButton {
|
||||||
theme: string;
|
theme: string;
|
||||||
callJitsi: Function;
|
callJitsi: Function;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import React, { useContext } from 'react';
|
import React, { useContext } from 'react';
|
||||||
import { Text, View } from 'react-native';
|
import { Text, View } from 'react-native';
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import { dequal } from 'dequal';
|
import { dequal } from 'dequal';
|
||||||
|
|
||||||
import I18n from '../../i18n';
|
import I18n from '../../i18n';
|
||||||
|
@ -12,9 +11,29 @@ import { themes } from '../../constants/colors';
|
||||||
import MessageContext from './Context';
|
import MessageContext from './Context';
|
||||||
import Encrypted from './Encrypted';
|
import Encrypted from './Encrypted';
|
||||||
import { E2E_MESSAGE_TYPE } from '../../lib/encryption/constants';
|
import { E2E_MESSAGE_TYPE } from '../../lib/encryption/constants';
|
||||||
|
import {TChannel} from "../markdown/Hashtag";
|
||||||
|
|
||||||
const Content = React.memo((props) => {
|
export interface IMessageContent {
|
||||||
|
isTemp: boolean;
|
||||||
|
isInfo: boolean;
|
||||||
|
tmid: string;
|
||||||
|
isThreadRoom: boolean;
|
||||||
|
msg: string;
|
||||||
|
theme: string;
|
||||||
|
isEdited: boolean;
|
||||||
|
isEncrypted: boolean;
|
||||||
|
getCustomEmoji: Function;
|
||||||
|
channels: TChannel[];
|
||||||
|
mentions: object[];
|
||||||
|
navToRoomInfo: Function;
|
||||||
|
useRealName: boolean;
|
||||||
|
isIgnored: boolean;
|
||||||
|
type: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Content = React.memo((props: IMessageContent) => {
|
||||||
if (props.isInfo) {
|
if (props.isInfo) {
|
||||||
|
// @ts-ignore
|
||||||
const infoMessage = getInfoMessage({ ...props });
|
const infoMessage = getInfoMessage({ ...props });
|
||||||
|
|
||||||
const renderMessageContent = (
|
const renderMessageContent = (
|
||||||
|
@ -37,7 +56,7 @@ const Content = React.memo((props) => {
|
||||||
return renderMessageContent;
|
return renderMessageContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
const isPreview = props.tmid && !props.isThreadRoom;
|
const isPreview: any = props.tmid && !props.isThreadRoom;
|
||||||
let content = null;
|
let content = null;
|
||||||
|
|
||||||
if (props.tmid && !props.msg) {
|
if (props.tmid && !props.msg) {
|
||||||
|
@ -47,6 +66,7 @@ const Content = React.memo((props) => {
|
||||||
} else {
|
} else {
|
||||||
const { baseUrl, user, onLinkPress } = useContext(MessageContext);
|
const { baseUrl, user, onLinkPress } = useContext(MessageContext);
|
||||||
content = (
|
content = (
|
||||||
|
// @ts-ignore
|
||||||
<Markdown
|
<Markdown
|
||||||
msg={props.msg}
|
msg={props.msg}
|
||||||
baseUrl={baseUrl}
|
baseUrl={baseUrl}
|
||||||
|
@ -118,23 +138,6 @@ const Content = React.memo((props) => {
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
Content.propTypes = {
|
|
||||||
isTemp: PropTypes.bool,
|
|
||||||
isInfo: PropTypes.bool,
|
|
||||||
tmid: PropTypes.string,
|
|
||||||
isThreadRoom: PropTypes.bool,
|
|
||||||
msg: PropTypes.string,
|
|
||||||
theme: PropTypes.string,
|
|
||||||
isEdited: PropTypes.bool,
|
|
||||||
isEncrypted: PropTypes.bool,
|
|
||||||
getCustomEmoji: PropTypes.func,
|
|
||||||
channels: PropTypes.oneOfType([PropTypes.array, PropTypes.object]),
|
|
||||||
mentions: PropTypes.oneOfType([PropTypes.array, PropTypes.object]),
|
|
||||||
navToRoomInfo: PropTypes.func,
|
|
||||||
useRealName: PropTypes.bool,
|
|
||||||
isIgnored: PropTypes.bool,
|
|
||||||
type: PropTypes.string
|
|
||||||
};
|
|
||||||
Content.displayName = 'MessageContent';
|
Content.displayName = 'MessageContent';
|
||||||
|
|
||||||
export default Content;
|
export default Content;
|
|
@ -1,4 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
|
|
||||||
const MessageContext = React.createContext();
|
|
||||||
export default MessageContext;
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
const MessageContext = React.createContext<any>();
|
||||||
|
export default MessageContext;
|
|
@ -11,7 +11,7 @@ import { themes } from '../../constants/colors';
|
||||||
import MessageContext from './Context';
|
import MessageContext from './Context';
|
||||||
import { formatDateThreads } from '../../utils/room';
|
import { formatDateThreads } from '../../utils/room';
|
||||||
|
|
||||||
interface IMessageDiscussion {
|
export interface IMessageDiscussion {
|
||||||
msg: string;
|
msg: string;
|
||||||
dcount: number;
|
dcount: number;
|
||||||
dlm: string;
|
dlm: string;
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import React, { useContext } from 'react';
|
import React, { useContext } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import { View } from 'react-native';
|
import { View } from 'react-native';
|
||||||
import Touchable from 'react-native-platform-touchable';
|
import Touchable from 'react-native-platform-touchable';
|
||||||
|
|
||||||
|
@ -7,21 +6,59 @@ import MessageContext from './Context';
|
||||||
|
|
||||||
import User from './User';
|
import User from './User';
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
import RepliedThread from './RepliedThread';
|
import RepliedThread, {IMessageRepliedThread} from './RepliedThread';
|
||||||
import MessageAvatar from './MessageAvatar';
|
import MessageAvatar, {IMessageAvatar} from './MessageAvatar';
|
||||||
import Attachments from './Attachments';
|
import Attachments, {IMessageAttachments} from './Attachments';
|
||||||
import Urls from './Urls';
|
import Urls from './Urls';
|
||||||
import Thread from './Thread';
|
import Thread, {IMessageThread} from './Thread';
|
||||||
import Blocks from './Blocks';
|
import Blocks, {IMessageBlocks} from './Blocks';
|
||||||
import Reactions from './Reactions';
|
import Reactions from './Reactions';
|
||||||
import Broadcast from './Broadcast';
|
import Broadcast, {IMessageBroadcast} from './Broadcast';
|
||||||
import Discussion from './Discussion';
|
import Discussion, {IMessageDiscussion} from './Discussion';
|
||||||
import Content from './Content';
|
import Content, {IMessageContent} from './Content';
|
||||||
import ReadReceipt from './ReadReceipt';
|
import ReadReceipt from './ReadReceipt';
|
||||||
import CallButton from './CallButton';
|
import CallButton, {IMessageCallButton} from './CallButton';
|
||||||
import { themes } from '../../constants/colors';
|
import { themes } from '../../constants/colors';
|
||||||
|
|
||||||
const MessageInner = React.memo((props) => {
|
|
||||||
|
type TMessageInner = {
|
||||||
|
type: string;
|
||||||
|
blocks: [];
|
||||||
|
} & IMessageDiscussion & IMessageContent & IMessageCallButton & IMessageBlocks
|
||||||
|
& IMessageThread & IMessageAttachments & IMessageBroadcast;
|
||||||
|
|
||||||
|
type TMessage = {
|
||||||
|
isThreadReply: boolean;
|
||||||
|
isThreadSequential: boolean;
|
||||||
|
isInfo: boolean;
|
||||||
|
isTemp: boolean;
|
||||||
|
isHeader: boolean;
|
||||||
|
hasError: boolean;
|
||||||
|
style: any;
|
||||||
|
onLongPress: Function;
|
||||||
|
isReadReceiptEnabled: boolean;
|
||||||
|
unread: boolean;
|
||||||
|
theme: string;
|
||||||
|
isIgnored: boolean;
|
||||||
|
} & IMessageRepliedThread & IMessageAvatar & IMessageContent & TMessageInner;
|
||||||
|
|
||||||
|
interface IMessageTouchable {
|
||||||
|
hasError: boolean;
|
||||||
|
isInfo: boolean;
|
||||||
|
isThreadReply: boolean;
|
||||||
|
isTemp: boolean;
|
||||||
|
archived: boolean;
|
||||||
|
highlighted: boolean;
|
||||||
|
theme: string;
|
||||||
|
ts?: any
|
||||||
|
urls?: any;
|
||||||
|
reactions?: any;
|
||||||
|
alias?: any;
|
||||||
|
role?: any;
|
||||||
|
drid?: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
const MessageInner = React.memo((props: TMessageInner) => {
|
||||||
if (props.type === 'discussion-created') {
|
if (props.type === 'discussion-created') {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -63,7 +100,7 @@ const MessageInner = React.memo((props) => {
|
||||||
});
|
});
|
||||||
MessageInner.displayName = 'MessageInner';
|
MessageInner.displayName = 'MessageInner';
|
||||||
|
|
||||||
const Message = React.memo((props) => {
|
const Message = React.memo((props: TMessage) => {
|
||||||
if (props.isThreadReply || props.isThreadSequential || props.isInfo || props.isIgnored) {
|
if (props.isThreadReply || props.isThreadSequential || props.isInfo || props.isIgnored) {
|
||||||
const thread = props.isThreadReply ? <RepliedThread {...props} /> : null;
|
const thread = props.isThreadReply ? <RepliedThread {...props} /> : null;
|
||||||
return (
|
return (
|
||||||
|
@ -107,7 +144,7 @@ const Message = React.memo((props) => {
|
||||||
});
|
});
|
||||||
Message.displayName = 'Message';
|
Message.displayName = 'Message';
|
||||||
|
|
||||||
const MessageTouchable = React.memo((props) => {
|
const MessageTouchable = React.memo((props: IMessageTouchable & TMessage) => {
|
||||||
if (props.hasError) {
|
if (props.hasError) {
|
||||||
return (
|
return (
|
||||||
<View>
|
<View>
|
||||||
|
@ -129,36 +166,7 @@ const MessageTouchable = React.memo((props) => {
|
||||||
</Touchable>
|
</Touchable>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
MessageTouchable.displayName = 'MessageTouchable';
|
MessageTouchable.displayName = 'MessageTouchable';
|
||||||
|
|
||||||
MessageTouchable.propTypes = {
|
|
||||||
hasError: PropTypes.bool,
|
|
||||||
isInfo: PropTypes.bool,
|
|
||||||
isThreadReply: PropTypes.bool,
|
|
||||||
isTemp: PropTypes.bool,
|
|
||||||
archived: PropTypes.bool,
|
|
||||||
highlighted: PropTypes.bool,
|
|
||||||
theme: PropTypes.string
|
|
||||||
};
|
|
||||||
|
|
||||||
Message.propTypes = {
|
|
||||||
isThreadReply: PropTypes.bool,
|
|
||||||
isThreadSequential: PropTypes.bool,
|
|
||||||
isInfo: PropTypes.bool,
|
|
||||||
isTemp: PropTypes.bool,
|
|
||||||
isHeader: PropTypes.bool,
|
|
||||||
hasError: PropTypes.bool,
|
|
||||||
style: PropTypes.any,
|
|
||||||
onLongPress: PropTypes.func,
|
|
||||||
isReadReceiptEnabled: PropTypes.bool,
|
|
||||||
unread: PropTypes.bool,
|
|
||||||
theme: PropTypes.string,
|
|
||||||
isIgnored: PropTypes.bool
|
|
||||||
};
|
|
||||||
|
|
||||||
MessageInner.propTypes = {
|
|
||||||
type: PropTypes.string,
|
|
||||||
blocks: PropTypes.array
|
|
||||||
};
|
|
||||||
|
|
||||||
export default MessageTouchable;
|
export default MessageTouchable;
|
|
@ -4,7 +4,7 @@ import Avatar from '../Avatar';
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
import MessageContext from './Context';
|
import MessageContext from './Context';
|
||||||
|
|
||||||
interface IMessageAvatar {
|
export interface IMessageAvatar {
|
||||||
isHeader: boolean;
|
isHeader: boolean;
|
||||||
avatar: string;
|
avatar: string;
|
||||||
emoji: string;
|
emoji: string;
|
||||||
|
@ -12,7 +12,7 @@ interface IMessageAvatar {
|
||||||
username: string
|
username: string
|
||||||
_id: string;
|
_id: string;
|
||||||
};
|
};
|
||||||
small: boolean;
|
small?: boolean;
|
||||||
navToRoomInfo: Function;
|
navToRoomInfo: Function;
|
||||||
getCustomEmoji(): void;
|
getCustomEmoji(): void;
|
||||||
theme: string;
|
theme: string;
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { themes } from '../../constants/colors';
|
||||||
import I18n from '../../i18n';
|
import I18n from '../../i18n';
|
||||||
import Markdown from '../markdown';
|
import Markdown from '../markdown';
|
||||||
|
|
||||||
interface IMessageRepliedThread {
|
export interface IMessageRepliedThread {
|
||||||
tmid: string;
|
tmid: string;
|
||||||
tmsg: string;
|
tmsg: string;
|
||||||
id: string;
|
id: string;
|
||||||
|
|
|
@ -7,7 +7,7 @@ import MessageContext from './Context';
|
||||||
import ThreadDetails from '../ThreadDetails';
|
import ThreadDetails from '../ThreadDetails';
|
||||||
import I18n from '../../i18n';
|
import I18n from '../../i18n';
|
||||||
|
|
||||||
interface IMessageThread {
|
export interface IMessageThread {
|
||||||
msg: string;
|
msg: string;
|
||||||
tcount: number;
|
tcount: number;
|
||||||
theme: string;
|
theme: string;
|
||||||
|
|
|
@ -11,75 +11,62 @@ import messagesStatus from '../../constants/messagesStatus';
|
||||||
import { withTheme } from '../../theme';
|
import { withTheme } from '../../theme';
|
||||||
import openLink from '../../utils/openLink';
|
import openLink from '../../utils/openLink';
|
||||||
|
|
||||||
class MessageContainer extends React.Component {
|
interface IMessageContainerProps {
|
||||||
static propTypes = {
|
item: any;
|
||||||
item: PropTypes.object.isRequired,
|
user: {
|
||||||
user: PropTypes.shape({
|
id: string;
|
||||||
id: PropTypes.string.isRequired,
|
username: string;
|
||||||
username: PropTypes.string.isRequired,
|
token: string;
|
||||||
token: PropTypes.string.isRequired
|
};
|
||||||
}),
|
rid: string;
|
||||||
rid: PropTypes.string,
|
timeFormat: string;
|
||||||
timeFormat: PropTypes.string,
|
style: any;
|
||||||
style: PropTypes.any,
|
archived: boolean;
|
||||||
archived: PropTypes.bool,
|
broadcast: boolean;
|
||||||
broadcast: PropTypes.bool,
|
previousItem: {
|
||||||
previousItem: PropTypes.object,
|
ts: any;
|
||||||
baseUrl: PropTypes.string,
|
u: any;
|
||||||
Message_GroupingPeriod: PropTypes.number,
|
groupable: any;
|
||||||
isReadReceiptEnabled: PropTypes.bool,
|
id: any;
|
||||||
isThreadRoom: PropTypes.bool,
|
tmid: any;
|
||||||
useRealName: PropTypes.bool,
|
status: any
|
||||||
autoTranslateRoom: PropTypes.bool,
|
};
|
||||||
autoTranslateLanguage: PropTypes.string,
|
baseUrl: string;
|
||||||
status: PropTypes.number,
|
Message_GroupingPeriod: number;
|
||||||
isIgnored: PropTypes.bool,
|
isReadReceiptEnabled: boolean;
|
||||||
highlighted: PropTypes.bool,
|
isThreadRoom: boolean;
|
||||||
getCustomEmoji: PropTypes.func,
|
useRealName: boolean;
|
||||||
onLongPress: PropTypes.func,
|
autoTranslateRoom: boolean;
|
||||||
onReactionPress: PropTypes.func,
|
autoTranslateLanguage: string;
|
||||||
onEncryptedPress: PropTypes.func,
|
status: number;
|
||||||
onDiscussionPress: PropTypes.func,
|
isIgnored: boolean;
|
||||||
onThreadPress: PropTypes.func,
|
highlighted: boolean;
|
||||||
errorActionsShow: PropTypes.func,
|
getCustomEmoji(): void;
|
||||||
replyBroadcast: PropTypes.func,
|
onLongPress: Function;
|
||||||
reactionInit: PropTypes.func,
|
onReactionPress: Function;
|
||||||
fetchThreadName: PropTypes.func,
|
onEncryptedPress: Function;
|
||||||
showAttachment: PropTypes.func,
|
onDiscussionPress: Function;
|
||||||
onReactionLongPress: PropTypes.func,
|
onThreadPress: Function;
|
||||||
navToRoomInfo: PropTypes.func,
|
errorActionsShow: Function;
|
||||||
callJitsi: PropTypes.func,
|
replyBroadcast: Function;
|
||||||
blockAction: PropTypes.func,
|
reactionInit: Function;
|
||||||
theme: PropTypes.string,
|
fetchThreadName: Function;
|
||||||
threadBadgeColor: PropTypes.string,
|
showAttachment: Function;
|
||||||
toggleFollowThread: PropTypes.func,
|
onReactionLongPress: Function;
|
||||||
jumpToMessage: PropTypes.func,
|
navToRoomInfo: Function;
|
||||||
onPress: PropTypes.func
|
callJitsi: Function;
|
||||||
|
blockAction: Function;
|
||||||
|
theme: string;
|
||||||
|
threadBadgeColor: string;
|
||||||
|
toggleFollowThread: Function;
|
||||||
|
jumpToMessage: Function;
|
||||||
|
onPress: Function;
|
||||||
}
|
}
|
||||||
|
|
||||||
static defaultProps = {
|
class MessageContainer extends React.Component<IMessageContainerProps, any> {
|
||||||
getCustomEmoji: () => {},
|
|
||||||
onLongPress: () => {},
|
|
||||||
onReactionPress: () => {},
|
|
||||||
onEncryptedPress: () => {},
|
|
||||||
onDiscussionPress: () => {},
|
|
||||||
onThreadPress: () => {},
|
|
||||||
errorActionsShow: () => {},
|
|
||||||
replyBroadcast: () => {},
|
|
||||||
reactionInit: () => {},
|
|
||||||
fetchThreadName: () => {},
|
|
||||||
showAttachment: () => {},
|
|
||||||
onReactionLongPress: () => {},
|
|
||||||
navToRoomInfo: () => {},
|
|
||||||
callJitsi: () => {},
|
|
||||||
blockAction: () => {},
|
|
||||||
archived: false,
|
|
||||||
broadcast: false,
|
|
||||||
isIgnored: false,
|
|
||||||
theme: 'light'
|
|
||||||
}
|
|
||||||
|
|
||||||
state = { isManualUnignored: false };
|
state = { isManualUnignored: false };
|
||||||
|
private subscription: any;
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
const { item } = this.props;
|
const { item } = this.props;
|
||||||
|
@ -91,7 +78,7 @@ class MessageContainer extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
shouldComponentUpdate(nextProps, nextState) {
|
shouldComponentUpdate(nextProps: any, nextState: any) {
|
||||||
const { isManualUnignored } = this.state;
|
const { isManualUnignored } = this.state;
|
||||||
const {
|
const {
|
||||||
theme, threadBadgeColor, isIgnored, highlighted
|
theme, threadBadgeColor, isIgnored, highlighted
|
||||||
|
@ -155,7 +142,7 @@ class MessageContainer extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onReactionPress = (emoji) => {
|
onReactionPress = (emoji: any) => {
|
||||||
const { onReactionPress, item } = this.props;
|
const { onReactionPress, item } = this.props;
|
||||||
if (onReactionPress) {
|
if (onReactionPress) {
|
||||||
onReactionPress(emoji, item.id);
|
onReactionPress(emoji, item.id);
|
||||||
|
@ -195,9 +182,7 @@ class MessageContainer extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
get isHeader() {
|
get isHeader() {
|
||||||
const {
|
const { item, previousItem, broadcast, Message_GroupingPeriod } = this.props;
|
||||||
item, previousItem, broadcast, Message_GroupingPeriod
|
|
||||||
} = this.props;
|
|
||||||
if (this.hasError || (previousItem && previousItem.status === messagesStatus.ERROR)) {
|
if (this.hasError || (previousItem && previousItem.status === messagesStatus.ERROR)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -218,9 +203,7 @@ class MessageContainer extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
get isThreadReply() {
|
get isThreadReply() {
|
||||||
const {
|
const { item, previousItem, isThreadRoom } = this.props;
|
||||||
item, previousItem, isThreadRoom
|
|
||||||
} = this.props;
|
|
||||||
if (isThreadRoom) {
|
if (isThreadRoom) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -279,9 +262,9 @@ class MessageContainer extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onLinkPress = (link) => {
|
onLinkPress = (link: any) => {
|
||||||
const { item, theme, jumpToMessage } = this.props;
|
const { item, theme, jumpToMessage } = this.props;
|
||||||
const isMessageLink = item?.attachments?.findIndex(att => att?.message_link === link) !== -1;
|
const isMessageLink = item?.attachments?.findIndex((att: any) => att?.message_link === link) !== -1;
|
||||||
if (isMessageLink) {
|
if (isMessageLink) {
|
||||||
return jumpToMessage(link);
|
return jumpToMessage(link);
|
||||||
}
|
}
|
||||||
|
@ -372,6 +355,7 @@ class MessageContainer extends React.Component {
|
||||||
replies
|
replies
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
{/*@ts-ignore*/}
|
||||||
<Message
|
<Message
|
||||||
id={id}
|
id={id}
|
||||||
msg={message}
|
msg={message}
|
|
@ -2,4 +2,5 @@ declare module 'rn-extensions-share';
|
||||||
declare module 'commonmark';
|
declare module 'commonmark';
|
||||||
declare module 'commonmark-react-renderer';
|
declare module 'commonmark-react-renderer';
|
||||||
declare module 'remove-markdown';
|
declare module 'remove-markdown';
|
||||||
declare module 'react-native-image-progress'
|
declare module 'react-native-image-progress';
|
||||||
|
declare module 'react-native-platform-touchable';
|
||||||
|
|
Loading…
Reference in New Issue