2019-04-08 12:35:28 +00:00
|
|
|
import React from 'react';
|
|
|
|
import PropTypes from 'prop-types';
|
|
|
|
import {
|
|
|
|
View, Text, StyleSheet, ScrollView
|
|
|
|
} from 'react-native';
|
2019-04-17 17:01:03 +00:00
|
|
|
import { emojify } from 'react-emojione';
|
2019-04-25 17:18:49 +00:00
|
|
|
import removeMarkdown from 'remove-markdown';
|
2019-04-08 12:35:28 +00:00
|
|
|
|
|
|
|
import I18n from '../../../i18n';
|
|
|
|
import sharedStyles from '../../Styles';
|
2019-04-17 17:01:03 +00:00
|
|
|
import { isIOS, isAndroid } from '../../../utils/deviceInfo';
|
2019-04-08 12:35:28 +00:00
|
|
|
import Icon from './Icon';
|
|
|
|
import { COLOR_TEXT_DESCRIPTION, HEADER_TITLE, COLOR_WHITE } from '../../../constants/colors';
|
|
|
|
|
|
|
|
const TITLE_SIZE = 16;
|
|
|
|
const styles = StyleSheet.create({
|
|
|
|
container: {
|
2019-08-22 19:15:30 +00:00
|
|
|
flex: 1,
|
|
|
|
height: '100%',
|
|
|
|
marginRight: isAndroid ? 15 : 5,
|
|
|
|
marginLeft: isAndroid ? 10 : 0
|
2019-04-08 12:35:28 +00:00
|
|
|
},
|
|
|
|
titleContainer: {
|
|
|
|
flex: 6,
|
|
|
|
flexDirection: 'row'
|
|
|
|
},
|
2019-04-17 17:01:03 +00:00
|
|
|
threadContainer: {
|
|
|
|
marginRight: isAndroid ? 20 : undefined
|
|
|
|
},
|
2019-04-08 12:35:28 +00:00
|
|
|
title: {
|
|
|
|
...sharedStyles.textSemibold,
|
|
|
|
color: HEADER_TITLE,
|
|
|
|
fontSize: TITLE_SIZE
|
|
|
|
},
|
|
|
|
scroll: {
|
|
|
|
alignItems: 'center'
|
|
|
|
},
|
|
|
|
typing: {
|
|
|
|
...sharedStyles.textRegular,
|
|
|
|
color: isIOS ? COLOR_TEXT_DESCRIPTION : COLOR_WHITE,
|
|
|
|
fontSize: 12,
|
|
|
|
flex: 4
|
|
|
|
},
|
|
|
|
typingUsers: {
|
|
|
|
...sharedStyles.textSemibold
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
const Typing = React.memo(({ usersTyping }) => {
|
|
|
|
const users = usersTyping.map(item => item.username);
|
|
|
|
let usersText;
|
|
|
|
if (!users.length) {
|
|
|
|
return null;
|
|
|
|
} else if (users.length === 2) {
|
|
|
|
usersText = users.join(` ${ I18n.t('and') } `);
|
|
|
|
} else {
|
|
|
|
usersText = users.join(', ');
|
|
|
|
}
|
|
|
|
return (
|
|
|
|
<Text style={styles.typing} numberOfLines={1}>
|
|
|
|
<Text style={styles.typingUsers}>{usersText} </Text>
|
|
|
|
{ users.length > 1 ? I18n.t('are_typing') : I18n.t('is_typing') }...
|
|
|
|
</Text>
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
Typing.propTypes = {
|
|
|
|
usersTyping: PropTypes.array
|
|
|
|
};
|
|
|
|
|
2019-04-30 19:31:51 +00:00
|
|
|
const HeaderTitle = React.memo(({
|
2019-05-14 20:06:17 +00:00
|
|
|
title, scale, connecting
|
2019-04-30 19:31:51 +00:00
|
|
|
}) => {
|
|
|
|
if (connecting) {
|
|
|
|
title = I18n.t('Connecting');
|
|
|
|
}
|
|
|
|
return (
|
|
|
|
<Text
|
|
|
|
style={[styles.title, { fontSize: TITLE_SIZE * scale }]}
|
|
|
|
numberOfLines={1}
|
|
|
|
testID={`room-view-title-${ title }`}
|
|
|
|
>{title}
|
|
|
|
</Text>
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
HeaderTitle.propTypes = {
|
|
|
|
title: PropTypes.string,
|
|
|
|
scale: PropTypes.number,
|
2019-05-14 20:06:17 +00:00
|
|
|
connecting: PropTypes.bool
|
2019-04-30 19:31:51 +00:00
|
|
|
};
|
|
|
|
|
2019-04-08 12:35:28 +00:00
|
|
|
const Header = React.memo(({
|
2019-05-14 20:06:17 +00:00
|
|
|
title, type, status, usersTyping, width, height, prid, tmid, widthOffset, connecting
|
2019-04-08 12:35:28 +00:00
|
|
|
}) => {
|
|
|
|
const portrait = height > width;
|
|
|
|
let scale = 1;
|
|
|
|
|
|
|
|
if (!portrait) {
|
|
|
|
if (usersTyping.length > 0) {
|
|
|
|
scale = 0.8;
|
|
|
|
}
|
|
|
|
}
|
2019-04-17 17:01:03 +00:00
|
|
|
if (title) {
|
|
|
|
title = emojify(title, { output: 'unicode' });
|
2019-04-25 17:18:49 +00:00
|
|
|
if (tmid) {
|
|
|
|
title = removeMarkdown(title);
|
|
|
|
}
|
2019-04-17 17:01:03 +00:00
|
|
|
}
|
|
|
|
|
2019-04-08 12:35:28 +00:00
|
|
|
return (
|
2019-04-17 17:01:03 +00:00
|
|
|
<View style={[styles.container, { width: width - widthOffset }]}>
|
|
|
|
<View style={[styles.titleContainer, tmid && styles.threadContainer]}>
|
2019-04-08 12:35:28 +00:00
|
|
|
<ScrollView
|
|
|
|
showsHorizontalScrollIndicator={false}
|
|
|
|
horizontal
|
|
|
|
bounces={false}
|
|
|
|
contentContainerStyle={styles.scroll}
|
|
|
|
>
|
|
|
|
<Icon type={prid ? 'discussion' : type} status={status} />
|
2019-04-30 19:31:51 +00:00
|
|
|
<HeaderTitle
|
|
|
|
prid={prid}
|
|
|
|
type={type}
|
|
|
|
status={status}
|
|
|
|
title={title}
|
|
|
|
scale={scale}
|
|
|
|
connecting={connecting}
|
|
|
|
/>
|
2019-04-08 12:35:28 +00:00
|
|
|
</ScrollView>
|
|
|
|
</View>
|
2019-04-17 17:01:03 +00:00
|
|
|
{type === 'thread' ? null : <Typing usersTyping={usersTyping} />}
|
2019-04-08 12:35:28 +00:00
|
|
|
</View>
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
Header.propTypes = {
|
|
|
|
title: PropTypes.string.isRequired,
|
|
|
|
type: PropTypes.string.isRequired,
|
|
|
|
width: PropTypes.number.isRequired,
|
|
|
|
height: PropTypes.number.isRequired,
|
|
|
|
prid: PropTypes.string,
|
2019-04-17 17:01:03 +00:00
|
|
|
tmid: PropTypes.string,
|
2019-04-08 12:35:28 +00:00
|
|
|
status: PropTypes.string,
|
2019-04-17 17:01:03 +00:00
|
|
|
usersTyping: PropTypes.array,
|
2019-04-30 19:31:51 +00:00
|
|
|
widthOffset: PropTypes.number,
|
2019-05-14 20:06:17 +00:00
|
|
|
connecting: PropTypes.bool
|
2019-04-08 12:35:28 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
Header.defaultProps = {
|
|
|
|
usersTyping: []
|
|
|
|
};
|
|
|
|
|
|
|
|
export default Header;
|