Rocket.Chat.ReactNative/app/containers/RoomHeader/RoomHeader.js

208 lines
4.5 KiB
JavaScript

import React, { useCallback } from 'react';
import PropTypes from 'prop-types';
import {
View, Text, StyleSheet, TouchableOpacity
} from 'react-native';
import I18n from '../../i18n';
import sharedStyles from '../../views/Styles';
import { themes } from '../../constants/colors';
import Markdown from '../markdown';
import RoomTypeIcon from '../RoomTypeIcon';
import { withTheme } from '../../theme';
const HIT_SLOP = {
top: 5, right: 5, bottom: 5, left: 5
};
const TITLE_SIZE = 16;
const SUBTITLE_SIZE = 12;
const getSubTitleSize = scale => SUBTITLE_SIZE * scale;
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center'
},
titleContainer: {
alignItems: 'center',
flexDirection: 'row'
},
title: {
flexShrink: 1,
...sharedStyles.textSemibold
},
subtitle: {
flexShrink: 1,
...sharedStyles.textRegular
},
typingUsers: {
...sharedStyles.textSemibold
}
});
const SubTitle = React.memo(({
usersTyping, subtitle, renderFunc, theme, scale
}) => {
const fontSize = getSubTitleSize(scale);
// typing
if (usersTyping.length) {
let usersText;
if (usersTyping.length === 2) {
usersText = usersTyping.join(` ${ I18n.t('and') } `);
} else {
usersText = usersTyping.join(', ');
}
return (
<Text style={[styles.subtitle, { fontSize, color: themes[theme].auxiliaryText }]} numberOfLines={1}>
<Text style={styles.typingUsers}>{usersText} </Text>
{ usersTyping.length > 1 ? I18n.t('are_typing') : I18n.t('is_typing') }...
</Text>
);
}
// renderFunc
if (renderFunc) {
return renderFunc();
}
// subtitle
if (subtitle) {
return (
<Markdown
preview
msg={subtitle}
style={[styles.subtitle, { fontSize, color: themes[theme].auxiliaryText }]}
numberOfLines={1}
theme={theme}
/>
);
}
return null;
});
SubTitle.propTypes = {
usersTyping: PropTypes.array,
theme: PropTypes.string,
subtitle: PropTypes.string,
renderFunc: PropTypes.func,
scale: PropTypes.number
};
const HeaderTitle = React.memo(({
title, tmid, prid, scale, theme, testID
}) => {
const titleStyle = { fontSize: TITLE_SIZE * scale, color: themes[theme].headerTitleColor };
if (!tmid && !prid) {
return (
<Text
style={[styles.title, titleStyle]}
numberOfLines={1}
testID={testID}
>
{title}
</Text>
);
}
return (
<Markdown
preview
msg={title}
style={[styles.title, titleStyle]}
numberOfLines={1}
theme={theme}
testID={testID}
/>
);
});
HeaderTitle.propTypes = {
title: PropTypes.string,
tmid: PropTypes.string,
prid: PropTypes.string,
scale: PropTypes.number,
theme: PropTypes.string,
testID: PropTypes.string
};
const Header = React.memo(({
title, subtitle, parentTitle, type, status, usersTyping, width, height, prid, tmid, onPress, theme, isGroupChat, teamMain, testID
}) => {
const portrait = height > width;
let scale = 1;
if (!portrait && !tmid) {
if (usersTyping.length > 0 || subtitle) {
scale = 0.8;
}
}
let renderFunc;
if (tmid) {
renderFunc = () => (
<View style={styles.titleContainer}>
<RoomTypeIcon type={prid ? 'discussion' : type} isGroupChat={isGroupChat} status={status} teamMain={teamMain} />
<Text style={[styles.subtitle, { color: themes[theme].auxiliaryText }]} numberOfLines={1}>{parentTitle}</Text>
</View>
);
}
const handleOnPress = useCallback(() => onPress(), []);
return (
<TouchableOpacity
testID='room-header'
accessibilityLabel={title}
onPress={handleOnPress}
style={styles.container}
disabled={tmid}
hitSlop={HIT_SLOP}
>
<View style={styles.titleContainer}>
{tmid ? null : <RoomTypeIcon type={prid ? 'discussion' : type} isGroupChat={isGroupChat} status={status} teamMain={teamMain} />}
<HeaderTitle
title={title}
tmid={tmid}
prid={prid}
scale={scale}
theme={theme}
testID={testID}
/>
</View>
<SubTitle
usersTyping={tmid ? [] : usersTyping}
subtitle={subtitle}
theme={theme}
renderFunc={renderFunc}
scale={scale}
/>
</TouchableOpacity>
);
});
Header.propTypes = {
title: PropTypes.string.isRequired,
subtitle: PropTypes.string,
type: PropTypes.string.isRequired,
width: PropTypes.number.isRequired,
height: PropTypes.number.isRequired,
prid: PropTypes.string,
tmid: PropTypes.string,
teamMain: PropTypes.bool,
status: PropTypes.string,
theme: PropTypes.string,
usersTyping: PropTypes.array,
isGroupChat: PropTypes.bool,
parentTitle: PropTypes.string,
onPress: PropTypes.func,
testID: PropTypes.string
};
Header.defaultProps = {
usersTyping: []
};
export default withTheme(Header);