ref(chat): on native, show messages as grouped by sender

This commit is contained in:
Leonard Kim 2019-05-06 11:21:41 -07:00 committed by virtuacoplenny
parent 34dffbfc5e
commit 7187e540a8
5 changed files with 56 additions and 32 deletions

View File

@ -19,12 +19,24 @@ export type Props = {
*/ */
message: Object, message: Object,
/**
* Whether or not the avatar image of the participant which sent the message
* should be displayed.
*/
showAvatar: boolean,
/** /**
* Whether or not the name of the participant which sent the message should * Whether or not the name of the participant which sent the message should
* be displayed. * be displayed.
*/ */
showDisplayName: boolean, showDisplayName: boolean,
/**
* Whether or not the time at which the message was sent should be
* displayed.
*/
showTimestamp: boolean,
/** /**
* Invoked to receive translated strings. * Invoked to receive translated strings.
*/ */
@ -36,7 +48,9 @@ export type Props = {
*/ */
export default class AbstractChatMessage<P: Props> extends PureComponent<P> { export default class AbstractChatMessage<P: Props> extends PureComponent<P> {
static defaultProps = { static defaultProps = {
showDisplayName: true showAvatar: false,
showDisplayName: false,
showTimestamp: false
}; };
} }

View File

@ -39,7 +39,7 @@ export default class AbstractMessageContainer<P: Props> extends PureComponent<P>
if (message.id === currentGroupParticipantId) { if (message.id === currentGroupParticipantId) {
currentGrouping.push(message); currentGrouping.push(message);
} else { } else {
groups.push(currentGrouping); currentGrouping.length && groups.push(currentGrouping);
currentGrouping = [ message ]; currentGrouping = [ message ];
currentGroupParticipantId = message.id; currentGroupParticipantId = message.id;

View File

@ -13,11 +13,6 @@ import AbstractChatMessage, {
} from '../AbstractChatMessage'; } from '../AbstractChatMessage';
import styles from './styles'; import styles from './styles';
/**
* Size of the rendered avatar in the message.
*/
const AVATAR_SIZE = 32;
/** /**
* Formatter string to display the message timestamp. * Formatter string to display the message timestamp.
*/ */
@ -34,8 +29,6 @@ class ChatMessage extends AbstractChatMessage<Props> {
*/ */
render() { render() {
const { message } = this.props; const { message } = this.props;
const timeStamp = getLocalizedDateFormatter(
new Date(message.timestamp)).format(TIMESTAMP_FORMAT);
const localMessage = message.messageType === 'local'; const localMessage = message.messageType === 'local';
// Style arrays that need to be updated in various scenarios, such as // Style arrays that need to be updated in various scenarios, such as
@ -60,18 +53,12 @@ class ChatMessage extends AbstractChatMessage<Props> {
return ( return (
<View style = { styles.messageWrapper } > <View style = { styles.messageWrapper } >
{ { this._renderAvatar() }
// Avatar is only rendered for remote messages.
!localMessage && this._renderAvatar()
}
<View style = { detailsWrapperStyle }> <View style = { detailsWrapperStyle }>
<View style = { textWrapperStyle } > <View style = { textWrapperStyle } >
{ {
this.props.showDisplayName
// Display name is only rendered for remote && this._renderDisplayName()
// messages.
!localMessage && this._renderDisplayName()
} }
<Text style = { styles.messageText }> <Text style = { styles.messageText }>
{ message.messageType === 'error' { message.messageType === 'error'
@ -82,9 +69,7 @@ class ChatMessage extends AbstractChatMessage<Props> {
: message.message } : message.message }
</Text> </Text>
</View> </View>
<Text style = { styles.timeText }> { this.props.showTimestamp && this._renderTimestamp() }
{ timeStamp }
</Text>
</View> </View>
</View> </View>
); );
@ -96,13 +81,12 @@ class ChatMessage extends AbstractChatMessage<Props> {
* @returns {React$Element<*>} * @returns {React$Element<*>}
*/ */
_renderAvatar() { _renderAvatar() {
const { _avatarURL } = this.props;
return ( return (
<View style = { styles.avatarWrapper }> <View style = { styles.avatarWrapper }>
<Avatar { this.props.showAvatar && <Avatar
size = { AVATAR_SIZE } size = { styles.avatarWrapper.width }
uri = { _avatarURL } /> uri = { this.props._avatarURL } />
}
</View> </View>
); );
} }
@ -113,11 +97,26 @@ class ChatMessage extends AbstractChatMessage<Props> {
* @returns {React$Element<*>} * @returns {React$Element<*>}
*/ */
_renderDisplayName() { _renderDisplayName() {
const { message } = this.props;
return ( return (
<Text style = { styles.displayName }> <Text style = { styles.displayName }>
{ message.displayName } { this.props.message.displayName }
</Text>
);
}
/**
* Renders the time at which the message was sent.
*
* @returns {React$Element<*>}
*/
_renderTimestamp() {
return (
<Text style = { styles.timeText }>
{
getLocalizedDateFormatter(
new Date(this.props.message.timestamp)
).format(TIMESTAMP_FORMAT)
}
</Text> </Text>
); );
} }

View File

@ -68,9 +68,19 @@ export default class ChatMessageGroup extends Component<Props> {
* @param {Object} message - The chat message to render. * @param {Object} message - The chat message to render.
* @returns {React$Element<*>} * @returns {React$Element<*>}
*/ */
_renderMessage({ item: message }) { _renderMessage({ index, item: message }) {
return ( return (
<ChatMessage message = { message } /> <ChatMessage
message = { message }
showAvatar = {
this.props.messages[0].messageType !== 'local'
&& index === this.props.messages.length - 1
}
showDisplayName = {
this.props.messages[0].messageType === 'remote'
&& index === this.props.messages.length - 1
}
showTimestamp = { index === 0 } />
); );
} }
} }

View File

@ -16,7 +16,8 @@ export default {
* Wrapper View for the avatar. * Wrapper View for the avatar.
*/ */
avatarWrapper: { avatarWrapper: {
marginRight: 8 marginRight: 8,
width: 32
}, },
/** /**