[FIX] Remove some unnecessary re-renders on Messagebox (#1341)
This commit is contained in:
parent
66222a3f9a
commit
fcb420a773
|
@ -1,47 +0,0 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { TouchableOpacity, ActivityIndicator } from 'react-native';
|
||||
import FastImage from 'react-native-fast-image';
|
||||
|
||||
import styles from './styles';
|
||||
import { CustomIcon } from '../../lib/Icons';
|
||||
import { COLOR_PRIMARY } from '../../constants/colors';
|
||||
|
||||
export default class CommandPreview extends React.PureComponent {
|
||||
static propTypes = {
|
||||
onPress: PropTypes.func,
|
||||
item: PropTypes.object
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = { loading: true };
|
||||
}
|
||||
|
||||
render() {
|
||||
const { onPress, item } = this.props;
|
||||
const { loading } = this.state;
|
||||
return (
|
||||
<TouchableOpacity
|
||||
style={styles.commandPreview}
|
||||
onPress={() => onPress(item)}
|
||||
testID={`command-preview-item${ item.id }`}
|
||||
>
|
||||
{item.type === 'image'
|
||||
? (
|
||||
<FastImage
|
||||
style={styles.commandPreviewImage}
|
||||
source={{ uri: item.value }}
|
||||
resizeMode={FastImage.resizeMode.cover}
|
||||
onLoadStart={() => this.setState({ loading: true })}
|
||||
onLoad={() => this.setState({ loading: false })}
|
||||
>
|
||||
{ loading ? <ActivityIndicator /> : null }
|
||||
</FastImage>
|
||||
)
|
||||
: <CustomIcon name='file-generic' size={36} color={COLOR_PRIMARY} />
|
||||
}
|
||||
</TouchableOpacity>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
import React, { useContext, useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { TouchableOpacity, ActivityIndicator } from 'react-native';
|
||||
import FastImage from 'react-native-fast-image';
|
||||
|
||||
import styles from '../styles';
|
||||
import { CustomIcon } from '../../../lib/Icons';
|
||||
import { COLOR_PRIMARY } from '../../../constants/colors';
|
||||
import MessageboxContext from '../Context';
|
||||
|
||||
const Item = ({ item }) => {
|
||||
const context = useContext(MessageboxContext);
|
||||
const { onPressCommandPreview } = context;
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
return (
|
||||
<TouchableOpacity
|
||||
style={styles.commandPreview}
|
||||
onPress={() => onPressCommandPreview(item)}
|
||||
testID={`command-preview-item${ item.id }`}
|
||||
>
|
||||
{item.type === 'image'
|
||||
? (
|
||||
<FastImage
|
||||
style={styles.commandPreviewImage}
|
||||
source={{ uri: item.value }}
|
||||
resizeMode={FastImage.resizeMode.cover}
|
||||
onLoadStart={() => setLoading(true)}
|
||||
onLoad={() => setLoading(false)}
|
||||
>
|
||||
{ loading ? <ActivityIndicator /> : null }
|
||||
</FastImage>
|
||||
)
|
||||
: <CustomIcon name='file-generic' size={36} color={COLOR_PRIMARY} />
|
||||
}
|
||||
</TouchableOpacity>
|
||||
);
|
||||
};
|
||||
|
||||
Item.propTypes = {
|
||||
item: PropTypes.object
|
||||
};
|
||||
|
||||
export default Item;
|
|
@ -0,0 +1,40 @@
|
|||
import React from 'react';
|
||||
import { FlatList } from 'react-native';
|
||||
import PropTypes from 'prop-types';
|
||||
import equal from 'deep-equal';
|
||||
|
||||
import Item from './Item';
|
||||
import styles from '../styles';
|
||||
|
||||
const CommandsPreview = React.memo(({ commandPreview, showCommandPreview }) => {
|
||||
if (!showCommandPreview) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<FlatList
|
||||
testID='commandbox-container'
|
||||
style={styles.mentionList}
|
||||
data={commandPreview}
|
||||
renderItem={({ item }) => <Item item={item} />}
|
||||
keyExtractor={item => item.id}
|
||||
keyboardShouldPersistTaps='always'
|
||||
horizontal
|
||||
showsHorizontalScrollIndicator={false}
|
||||
/>
|
||||
);
|
||||
}, (prevProps, nextProps) => {
|
||||
if (prevProps.showCommandPreview !== nextProps.showCommandPreview) {
|
||||
return false;
|
||||
}
|
||||
if (!equal(prevProps.commandPreview, nextProps.commandPreview)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
CommandsPreview.propTypes = {
|
||||
commandPreview: PropTypes.array,
|
||||
showCommandPreview: PropTypes.bool
|
||||
};
|
||||
|
||||
export default CommandsPreview;
|
|
@ -0,0 +1,4 @@
|
|||
import React from 'react';
|
||||
|
||||
const MessageboxContext = React.createContext();
|
||||
export default MessageboxContext;
|
|
@ -0,0 +1,23 @@
|
|||
import React from 'react';
|
||||
import { TouchableOpacity, Text } from 'react-native';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import styles from '../styles';
|
||||
import I18n from '../../../i18n';
|
||||
|
||||
const FixedMentionItem = ({ item, onPress }) => (
|
||||
<TouchableOpacity
|
||||
style={styles.mentionItem}
|
||||
onPress={() => onPress(item)}
|
||||
>
|
||||
<Text style={styles.fixedMentionAvatar}>{item.username}</Text>
|
||||
<Text style={styles.mentionText}>{item.username === 'here' ? I18n.t('Notify_active_in_this_room') : I18n.t('Notify_all_in_this_room')}</Text>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
|
||||
FixedMentionItem.propTypes = {
|
||||
item: PropTypes.object,
|
||||
onPress: PropTypes.func
|
||||
};
|
||||
|
||||
export default FixedMentionItem;
|
|
@ -0,0 +1,34 @@
|
|||
import React, { useContext } from 'react';
|
||||
import { Text } from 'react-native';
|
||||
import PropTypes from 'prop-types';
|
||||
import { shortnameToUnicode } from 'emoji-toolkit';
|
||||
|
||||
import styles from '../styles';
|
||||
import MessageboxContext from '../Context';
|
||||
import CustomEmoji from '../../EmojiPicker/CustomEmoji';
|
||||
|
||||
const MentionEmoji = ({ item }) => {
|
||||
const context = useContext(MessageboxContext);
|
||||
const { baseUrl } = context;
|
||||
|
||||
if (item.name) {
|
||||
return (
|
||||
<CustomEmoji
|
||||
style={styles.mentionItemCustomEmoji}
|
||||
emoji={item}
|
||||
baseUrl={baseUrl}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Text style={styles.mentionItemEmoji}>
|
||||
{shortnameToUnicode(`:${ item }:`)}
|
||||
</Text>
|
||||
);
|
||||
};
|
||||
|
||||
MentionEmoji.propTypes = {
|
||||
item: PropTypes.object
|
||||
};
|
||||
|
||||
export default MentionEmoji;
|
|
@ -0,0 +1,87 @@
|
|||
import React, { useContext } from 'react';
|
||||
import { TouchableOpacity, Text } from 'react-native';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import styles from '../styles';
|
||||
import Avatar from '../../Avatar';
|
||||
import MessageboxContext from '../Context';
|
||||
import FixedMentionItem from './FixedMentionItem';
|
||||
import MentionEmoji from './MentionEmoji';
|
||||
import {
|
||||
MENTIONS_TRACKING_TYPE_EMOJIS,
|
||||
MENTIONS_TRACKING_TYPE_COMMANDS
|
||||
} from '../constants';
|
||||
|
||||
const MentionItem = ({
|
||||
item, trackingType
|
||||
}) => {
|
||||
const context = useContext(MessageboxContext);
|
||||
const { baseUrl, user, onPressMention } = context;
|
||||
|
||||
const defineTestID = (type) => {
|
||||
switch (type) {
|
||||
case MENTIONS_TRACKING_TYPE_EMOJIS:
|
||||
return `mention-item-${ item.name || item }`;
|
||||
case MENTIONS_TRACKING_TYPE_COMMANDS:
|
||||
return `mention-item-${ item.command || item }`;
|
||||
default:
|
||||
return `mention-item-${ item.username || item.name || item }`;
|
||||
}
|
||||
};
|
||||
|
||||
const testID = defineTestID(trackingType);
|
||||
|
||||
if (item.username === 'all' || item.username === 'here') {
|
||||
return <FixedMentionItem item={item} onPress={onPressMention} />;
|
||||
}
|
||||
|
||||
let content = (
|
||||
<>
|
||||
<Avatar
|
||||
style={styles.avatar}
|
||||
text={item.username || item.name}
|
||||
size={30}
|
||||
type={item.t}
|
||||
baseUrl={baseUrl}
|
||||
userId={user.id}
|
||||
token={user.token}
|
||||
/>
|
||||
<Text style={styles.mentionText}>{ item.username || item.name || item }</Text>
|
||||
</>
|
||||
);
|
||||
|
||||
if (trackingType === MENTIONS_TRACKING_TYPE_EMOJIS) {
|
||||
content = (
|
||||
<>
|
||||
<MentionEmoji item={item} />
|
||||
<Text style={styles.mentionText}>:{ item.name || item }:</Text>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
if (trackingType === MENTIONS_TRACKING_TYPE_COMMANDS) {
|
||||
content = (
|
||||
<>
|
||||
<Text style={styles.slash}>/</Text>
|
||||
<Text>{ item.command}</Text>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<TouchableOpacity
|
||||
style={styles.mentionItem}
|
||||
onPress={() => onPressMention(item)}
|
||||
testID={testID}
|
||||
>
|
||||
{content}
|
||||
</TouchableOpacity>
|
||||
);
|
||||
};
|
||||
|
||||
MentionItem.propTypes = {
|
||||
item: PropTypes.object,
|
||||
trackingType: PropTypes.string
|
||||
};
|
||||
|
||||
export default MentionItem;
|
|
@ -0,0 +1,39 @@
|
|||
import React from 'react';
|
||||
import { FlatList } from 'react-native';
|
||||
import PropTypes from 'prop-types';
|
||||
import equal from 'deep-equal';
|
||||
|
||||
import styles from '../styles';
|
||||
import MentionItem from './MentionItem';
|
||||
|
||||
const Mentions = React.memo(({ mentions, trackingType }) => {
|
||||
if (!trackingType) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<FlatList
|
||||
testID='messagebox-container'
|
||||
style={styles.mentionList}
|
||||
data={mentions}
|
||||
extraData={mentions}
|
||||
renderItem={({ item }) => <MentionItem item={item} trackingType={trackingType} />}
|
||||
keyExtractor={item => item.id || item.username || item.command || item}
|
||||
keyboardShouldPersistTaps='always'
|
||||
/>
|
||||
);
|
||||
}, (prevProps, nextProps) => {
|
||||
if (prevProps.trackingType !== nextProps.trackingType) {
|
||||
return false;
|
||||
}
|
||||
if (!equal(prevProps.mentions, nextProps.mentions)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
Mentions.propTypes = {
|
||||
mentions: PropTypes.array,
|
||||
trackingType: PropTypes.string
|
||||
};
|
||||
|
||||
export default Mentions;
|
|
@ -1,4 +1,4 @@
|
|||
import React, { Component } from 'react';
|
||||
import React from 'react';
|
||||
import { View, Text, StyleSheet } from 'react-native';
|
||||
import PropTypes from 'prop-types';
|
||||
import moment from 'moment';
|
||||
|
@ -47,45 +47,38 @@ const styles = StyleSheet.create({
|
|||
}
|
||||
});
|
||||
|
||||
class ReplyPreview extends Component {
|
||||
static propTypes = {
|
||||
useMarkdown: PropTypes.bool,
|
||||
message: PropTypes.object.isRequired,
|
||||
Message_TimeFormat: PropTypes.string.isRequired,
|
||||
close: PropTypes.func.isRequired,
|
||||
baseUrl: PropTypes.string.isRequired,
|
||||
username: PropTypes.string.isRequired,
|
||||
getCustomEmoji: PropTypes.func
|
||||
const ReplyPreview = React.memo(({
|
||||
message, Message_TimeFormat, baseUrl, username, useMarkdown, replying, getCustomEmoji, close
|
||||
}) => {
|
||||
if (!replying) {
|
||||
return null;
|
||||
}
|
||||
|
||||
shouldComponentUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
close = () => {
|
||||
const { close } = this.props;
|
||||
close();
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
message, Message_TimeFormat, baseUrl, username, useMarkdown, getCustomEmoji
|
||||
} = this.props;
|
||||
const time = moment(message.ts).format(Message_TimeFormat);
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<View style={styles.messageContainer}>
|
||||
<View style={styles.header}>
|
||||
<Text style={styles.username}>{message.u.username}</Text>
|
||||
<Text style={styles.time}>{time}</Text>
|
||||
</View>
|
||||
<Markdown msg={message.msg} baseUrl={baseUrl} username={username} getCustomEmoji={getCustomEmoji} numberOfLines={1} useMarkdown={useMarkdown} preview />
|
||||
const time = moment(message.ts).format(Message_TimeFormat);
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<View style={styles.messageContainer}>
|
||||
<View style={styles.header}>
|
||||
<Text style={styles.username}>{message.u.username}</Text>
|
||||
<Text style={styles.time}>{time}</Text>
|
||||
</View>
|
||||
<CustomIcon name='cross' color={COLOR_TEXT_DESCRIPTION} size={20} style={styles.close} onPress={this.close} />
|
||||
<Markdown msg={message.msg} baseUrl={baseUrl} username={username} getCustomEmoji={getCustomEmoji} numberOfLines={1} useMarkdown={useMarkdown} preview />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
<CustomIcon name='cross' color={COLOR_TEXT_DESCRIPTION} size={20} style={styles.close} onPress={close} />
|
||||
</View>
|
||||
);
|
||||
}, (prevProps, nextProps) => prevProps.replying === nextProps.replying);
|
||||
|
||||
ReplyPreview.propTypes = {
|
||||
replying: PropTypes.bool,
|
||||
useMarkdown: PropTypes.bool,
|
||||
message: PropTypes.object.isRequired,
|
||||
Message_TimeFormat: PropTypes.string.isRequired,
|
||||
close: PropTypes.func.isRequired,
|
||||
baseUrl: PropTypes.string.isRequired,
|
||||
username: PropTypes.string.isRequired,
|
||||
getCustomEmoji: PropTypes.func
|
||||
};
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
useMarkdown: state.markdown.useMarkdown,
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
export const MENTIONS_TRACKING_TYPE_USERS = '@';
|
||||
export const MENTIONS_TRACKING_TYPE_EMOJIS = ':';
|
||||
export const MENTIONS_TRACKING_TYPE_COMMANDS = '/';
|
||||
export const MENTIONS_COUNT_TO_DISPLAY = 4;
|
|
@ -1,10 +1,9 @@
|
|||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {
|
||||
View, TextInput, FlatList, Text, TouchableOpacity, Alert, ScrollView
|
||||
View, TextInput, Alert
|
||||
} from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
import { shortnameToUnicode } from 'emoji-toolkit';
|
||||
import { KeyboardAccessoryView } from 'react-native-keyboard-input';
|
||||
import ImagePicker from 'react-native-image-crop-picker';
|
||||
import equal from 'deep-equal';
|
||||
|
@ -16,8 +15,6 @@ import { userTyping as userTypingAction } from '../../actions/room';
|
|||
import RocketChat from '../../lib/rocketchat';
|
||||
import styles from './styles';
|
||||
import database from '../../lib/database';
|
||||
import Avatar from '../Avatar';
|
||||
import CustomEmoji from '../EmojiPicker/CustomEmoji';
|
||||
import { emojis } from '../../emojis';
|
||||
import Recording from './Recording';
|
||||
import UploadModal from './UploadModal';
|
||||
|
@ -29,13 +26,16 @@ import { COLOR_TEXT_DESCRIPTION } from '../../constants/colors';
|
|||
import LeftButtons from './LeftButtons';
|
||||
import RightButtons from './RightButtons';
|
||||
import { isAndroid } from '../../utils/deviceInfo';
|
||||
import CommandPreview from './CommandPreview';
|
||||
import { canUploadFile } from '../../utils/media';
|
||||
|
||||
const MENTIONS_TRACKING_TYPE_USERS = '@';
|
||||
const MENTIONS_TRACKING_TYPE_EMOJIS = ':';
|
||||
const MENTIONS_TRACKING_TYPE_COMMANDS = '/';
|
||||
const MENTIONS_COUNT_TO_DISPLAY = 4;
|
||||
import Mentions from './Mentions';
|
||||
import MessageboxContext from './Context';
|
||||
import {
|
||||
MENTIONS_TRACKING_TYPE_EMOJIS,
|
||||
MENTIONS_TRACKING_TYPE_COMMANDS,
|
||||
MENTIONS_COUNT_TO_DISPLAY,
|
||||
MENTIONS_TRACKING_TYPE_USERS
|
||||
} from './constants';
|
||||
import CommandsPreview from './CommandsPreview';
|
||||
|
||||
const imagePickerConfig = {
|
||||
cropping: true,
|
||||
|
@ -545,7 +545,6 @@ class MessageBox extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
showUploadModal = (file) => {
|
||||
this.setState({ file: { ...file, isVisible: true } });
|
||||
}
|
||||
|
@ -726,175 +725,29 @@ class MessageBox extends Component {
|
|||
});
|
||||
}
|
||||
|
||||
renderFixedMentionItem = item => (
|
||||
<TouchableOpacity
|
||||
style={styles.mentionItem}
|
||||
onPress={() => this.onPressMention(item)}
|
||||
>
|
||||
<Text style={styles.fixedMentionAvatar}>{item.username}</Text>
|
||||
<Text style={styles.mentionText}>{item.username === 'here' ? I18n.t('Notify_active_in_this_room') : I18n.t('Notify_all_in_this_room')}</Text>
|
||||
</TouchableOpacity>
|
||||
)
|
||||
|
||||
renderMentionEmoji = (item) => {
|
||||
const { baseUrl } = this.props;
|
||||
|
||||
if (item.name) {
|
||||
return (
|
||||
<CustomEmoji
|
||||
key='mention-item-avatar'
|
||||
style={styles.mentionItemCustomEmoji}
|
||||
emoji={item}
|
||||
baseUrl={baseUrl}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Text
|
||||
key='mention-item-avatar'
|
||||
style={styles.mentionItemEmoji}
|
||||
>
|
||||
{shortnameToUnicode(`:${ item }:`)}
|
||||
</Text>
|
||||
);
|
||||
}
|
||||
|
||||
renderMentionItem = ({ item }) => {
|
||||
const { trackingType } = this.state;
|
||||
const { baseUrl, user } = this.props;
|
||||
|
||||
if (item.username === 'all' || item.username === 'here') {
|
||||
return this.renderFixedMentionItem(item);
|
||||
}
|
||||
const defineTestID = (type) => {
|
||||
switch (type) {
|
||||
case MENTIONS_TRACKING_TYPE_EMOJIS:
|
||||
return `mention-item-${ item.name || item }`;
|
||||
case MENTIONS_TRACKING_TYPE_COMMANDS:
|
||||
return `mention-item-${ item.command || item }`;
|
||||
default:
|
||||
return `mention-item-${ item.username || item.name || item }`;
|
||||
}
|
||||
};
|
||||
|
||||
const testID = defineTestID(trackingType);
|
||||
|
||||
return (
|
||||
<TouchableOpacity
|
||||
style={styles.mentionItem}
|
||||
onPress={() => this.onPressMention(item)}
|
||||
testID={testID}
|
||||
>
|
||||
|
||||
{(() => {
|
||||
switch (trackingType) {
|
||||
case MENTIONS_TRACKING_TYPE_EMOJIS:
|
||||
return (
|
||||
<>
|
||||
{this.renderMentionEmoji(item)}
|
||||
<Text key='mention-item-name' style={styles.mentionText}>:{ item.name || item }:</Text>
|
||||
</>
|
||||
);
|
||||
case MENTIONS_TRACKING_TYPE_COMMANDS:
|
||||
return (
|
||||
<>
|
||||
<Text key='mention-item-command' style={styles.slash}>/</Text>
|
||||
<Text key='mention-item-param'>{ item.command}</Text>
|
||||
</>
|
||||
);
|
||||
default:
|
||||
return (
|
||||
<>
|
||||
<Avatar
|
||||
key='mention-item-avatar'
|
||||
style={styles.avatar}
|
||||
text={item.username || item.name}
|
||||
size={30}
|
||||
type={item.t}
|
||||
baseUrl={baseUrl}
|
||||
userId={user.id}
|
||||
token={user.token}
|
||||
/>
|
||||
<Text key='mention-item-name' style={styles.mentionText}>{ item.username || item.name || item }</Text>
|
||||
</>
|
||||
);
|
||||
}
|
||||
})()
|
||||
}
|
||||
</TouchableOpacity>
|
||||
);
|
||||
}
|
||||
|
||||
renderMentions = () => {
|
||||
const { mentions, trackingType } = this.state;
|
||||
if (!trackingType) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<ScrollView
|
||||
testID='messagebox-container'
|
||||
style={styles.scrollViewMention}
|
||||
keyboardShouldPersistTaps='always'
|
||||
>
|
||||
<FlatList
|
||||
style={styles.mentionList}
|
||||
data={mentions}
|
||||
extraData={mentions}
|
||||
renderItem={this.renderMentionItem}
|
||||
keyExtractor={item => item.id || item.username || item.command || item}
|
||||
keyboardShouldPersistTaps='always'
|
||||
/>
|
||||
</ScrollView>
|
||||
);
|
||||
};
|
||||
|
||||
renderCommandPreviewItem = ({ item }) => (
|
||||
<CommandPreview item={item} onPress={this.onPressCommandPreview} />
|
||||
);
|
||||
|
||||
renderCommandPreview = () => {
|
||||
const { commandPreview, showCommandPreview } = this.state;
|
||||
if (!showCommandPreview) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<View key='commandbox-container' testID='commandbox-container'>
|
||||
<FlatList
|
||||
style={styles.mentionList}
|
||||
data={commandPreview}
|
||||
renderItem={this.renderCommandPreviewItem}
|
||||
keyExtractor={item => item.id}
|
||||
keyboardShouldPersistTaps='always'
|
||||
horizontal
|
||||
showsHorizontalScrollIndicator={false}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
renderReplyPreview = () => {
|
||||
const {
|
||||
message, replying, replyCancel, user, getCustomEmoji
|
||||
} = this.props;
|
||||
if (!replying) {
|
||||
return null;
|
||||
}
|
||||
return <ReplyPreview key='reply-preview' message={message} close={replyCancel} username={user.username} getCustomEmoji={getCustomEmoji} />;
|
||||
};
|
||||
|
||||
renderContent = () => {
|
||||
const { recording, showEmojiKeyboard, showSend } = this.state;
|
||||
const { editing } = this.props;
|
||||
const {
|
||||
recording, showEmojiKeyboard, showSend, mentions, trackingType, commandPreview, showCommandPreview
|
||||
} = this.state;
|
||||
const {
|
||||
editing, message, replying, replyCancel, user, getCustomEmoji
|
||||
} = this.props;
|
||||
|
||||
if (recording) {
|
||||
return (<Recording onFinish={this.finishAudioMessage} />);
|
||||
return <Recording onFinish={this.finishAudioMessage} />;
|
||||
}
|
||||
return (
|
||||
<>
|
||||
{this.renderCommandPreview()}
|
||||
{this.renderMentions()}
|
||||
<View style={styles.composer} key='messagebox'>
|
||||
{this.renderReplyPreview()}
|
||||
<CommandsPreview commandPreview={commandPreview} showCommandPreview={showCommandPreview} />
|
||||
<Mentions mentions={mentions} trackingType={trackingType} />
|
||||
<View style={styles.composer}>
|
||||
<ReplyPreview
|
||||
message={message}
|
||||
close={replyCancel}
|
||||
username={user.username}
|
||||
replying={replying}
|
||||
getCustomEmoji={getCustomEmoji}
|
||||
/>
|
||||
<View
|
||||
style={[styles.textArea, editing && styles.editing]}
|
||||
testID='messagebox'
|
||||
|
@ -936,8 +789,16 @@ class MessageBox extends Component {
|
|||
render() {
|
||||
console.count(`${ this.constructor.name }.render calls`);
|
||||
const { showEmojiKeyboard, file } = this.state;
|
||||
const { user, baseUrl } = this.props;
|
||||
return (
|
||||
<>
|
||||
<MessageboxContext.Provider
|
||||
value={{
|
||||
user,
|
||||
baseUrl,
|
||||
onPressMention: this.onPressMention,
|
||||
onPressCommandPreview: this.onPressCommandPreview
|
||||
}}
|
||||
>
|
||||
<KeyboardAccessoryView
|
||||
renderContent={this.renderContent}
|
||||
kbInputRef={this.component}
|
||||
|
@ -955,7 +816,7 @@ class MessageBox extends Component {
|
|||
close={() => this.setState({ file: {} })}
|
||||
submit={this.sendMediaMessage}
|
||||
/>
|
||||
</>
|
||||
</MessageboxContext.Provider>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue