Fix chat list

This commit is contained in:
Klaus 2017-07-12 13:47:58 -03:00
parent e1004b64d3
commit eb5712e96c
3 changed files with 108 additions and 116 deletions

View File

@ -1,13 +1,12 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import React from 'react';
import { defineMessages, injectIntl } from 'react-intl';
import { createContainer } from 'meteor/react-meteor-data';
import Chat from './component';
import ChatService from './service';
const CHAT_CONFIG = Meteor.settings.public.chat;
const PUBLIC_CHAT_KEY = CHAT_CONFIG.public_id;
import Chat from './component';
import ChatService from './service';
const intlMessages = defineMessages({
titlePublic: {
@ -24,19 +23,12 @@ const intlMessages = defineMessages({
},
});
class ChatContainer extends Component {
constructor(props) {
super(props);
}
render() {
return (
<Chat {...this.props}>
{this.props.children}
</Chat>
);
}
}
const ChatContainer = props =>
(
<Chat {...props}>
{props.children}
</Chat>
);
export default injectIntl(createContainer(({ params, intl }) => {
const chatID = params.chatID || PUBLIC_CHAT_KEY;
@ -60,20 +52,19 @@ export default injectIntl(createContainer(({ params, intl }) => {
partnerIsLoggedOut = !user.isOnline;
if (messages && chatID !== PUBLIC_CHAT_KEY) {
const userMessage = messages.find(m => m.sender !== null);
const user = ChatService.getUser(chatID, '{{NAME}}');
const chatUser = ChatService.getUser(chatID, '{{NAME}}');
title = intl.formatMessage(intlMessages.titlePrivate, { 0: user.name });
chatName = user.name;
title = intl.formatMessage(intlMessages.titlePrivate, { 0: chatUser.name });
chatName = chatUser.name;
if (!user.isOnline) {
if (!chatUser.isOnline) {
const time = Date.now();
const id = `partner-disconnected-${time}`;
const messagePartnerLoggedOut = {
id,
content: [{
id,
text: intl.formatMessage(intlMessages.partnerDisconnected, { 0: user.name }),
text: intl.formatMessage(intlMessages.partnerDisconnected, { 0: chatUser.name }),
time,
}],
time,
@ -103,7 +94,7 @@ export default injectIntl(createContainer(({ params, intl }) => {
minMessageLength: CHAT_CONFIG.min_message_length,
maxMessageLength: CHAT_CONFIG.max_message_length,
actions: {
handleClosePrivateChat: chatID => ChatService.closePrivateChat(chatID),
handleClosePrivateChat: chatId => ChatService.closePrivateChat(chatId),
handleSendMessage: (message) => {
ChatService.updateScrollPosition(chatID, null);

View File

@ -2,9 +2,8 @@ import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { defineMessages, injectIntl } from 'react-intl';
import _ from 'lodash';
import styles from './styles';
import Button from '/imports/ui/components/button/component';
import styles from './styles';
import MessageListItem from './message-list-item/component';
const propTypes = {
@ -34,71 +33,6 @@ class MessageList extends Component {
this.handleScrollUpdate = _.debounce(this.handleScrollUpdate.bind(this), 150);
}
scrollTo(position = null) {
const { scrollArea } = this;
if (position === null) {
position = scrollArea.scrollHeight - scrollArea.clientHeight;
}
scrollArea.scrollTop = position;
}
handleScrollUpdate(position, target) {
if (position !== null && position + target.offsetHeight === target.scrollHeight) {
position = null; // update with null so it keeps auto scrolling
}
this.props.handleScrollUpdate(position);
}
handleScrollChange(e) {
this.lastKnowScrollPosition = e.target.scrollTop;
if (!this.ticking) {
window.requestAnimationFrame(() => {
const position = this.lastKnowScrollPosition;
this.handleScrollUpdate(position, e.target);
this.ticking = false;
});
}
this.ticking = true;
}
componentWillReceiveProps(nextProps) {
if (this.props.chatId !== nextProps.chatId) {
const { scrollArea } = this;
this.handleScrollUpdate(scrollArea.scrollTop, scrollArea);
}
}
componentWillUpdate(nextProps) {
if (this.props.chatId !== nextProps.chatId) {
this.shouldScrollBottom = false;
return;
}
const { scrollArea } = this;
const position = scrollArea.scrollTop + scrollArea.offsetHeight;
// Compare with <1 to account for the chance scrollArea.scrollTop is a float
// value in some browsers.
this.shouldScrollBottom = position === scrollArea.scrollHeight ||
(scrollArea.scrollHeight - position < 1) ||
nextProps.scrollPosition === null;
}
componentDidUpdate(prevProps) {
const { scrollPosition, chatId } = this.props;
if (this.shouldScrollBottom) {
this.scrollTo();
} else if (prevProps.chatId !== chatId) {
this.scrollTo(scrollPosition);
}
}
componentDidMount() {
const { scrollArea } = this;
@ -107,11 +41,11 @@ class MessageList extends Component {
scrollArea.addEventListener('scroll', this.handleScrollChange, false);
}
componentWillUnmount() {
const { scrollArea } = this;
this.handleScrollUpdate(scrollArea.scrollTop, scrollArea);
scrollArea.removeEventListener('scroll', this.handleScrollChange, false);
componentWillReceiveProps(nextProps) {
if (this.props.chatId !== nextProps.chatId) {
const { scrollArea } = this;
this.handleScrollUpdate(scrollArea.scrollTop, scrollArea);
}
}
shouldComponentUpdate(nextProps) {
@ -136,6 +70,91 @@ class MessageList extends Component {
return false;
}
componentWillUpdate(nextProps) {
if (this.props.chatId !== nextProps.chatId) {
this.shouldScrollBottom = false;
return;
}
const { scrollArea } = this;
const position = scrollArea.scrollTop + scrollArea.offsetHeight;
// Compare with <1 to account for the chance scrollArea.scrollTop is a float
// value in some browsers.
this.shouldScrollBottom = position === scrollArea.scrollHeight ||
(scrollArea.scrollHeight - position < 1) ||
nextProps.scrollPosition === null;
}
componentDidUpdate(prevProps) {
const { scrollPosition, chatId } = this.props;
if (this.shouldScrollBottom) {
this.scrollTo();
} else if (prevProps.chatId !== chatId) {
this.scrollTo(scrollPosition);
}
}
componentWillUnmount() {
const { scrollArea } = this;
this.handleScrollUpdate(scrollArea.scrollTop, scrollArea);
scrollArea.removeEventListener('scroll', this.handleScrollChange, false);
}
handleScrollUpdate(position, target) {
if (position !== null && position + target.offsetHeight === target.scrollHeight) {
this.props.handleScrollUpdate(null);
}
this.props.handleScrollUpdate(position);
}
handleScrollChange(e) {
this.lastKnowScrollPosition = e.target.scrollTop;
if (!this.ticking) {
window.requestAnimationFrame(() => {
const position = this.lastKnowScrollPosition;
this.handleScrollUpdate(position, e.target);
this.ticking = false;
});
}
this.ticking = true;
}
scrollTo(position = null) {
const { scrollArea } = this;
if (position === null) {
scrollArea.scrollTop = scrollArea.scrollHeight - scrollArea.clientHeight;
return;
}
scrollArea.scrollTop = position;
}
renderUnreadNotification() {
const { intl, hasUnreadMessages, scrollPosition } = this.props;
if (hasUnreadMessages && scrollPosition !== null) {
return (
<Button
className={styles.unreadButton}
size={'sm'}
label={intl.formatMessage(intlMessages.moreMessages)}
onClick={() => this.scrollTo()}
/>
);
}
return null;
}
render() {
const { messages, intl } = this.props;
@ -143,7 +162,6 @@ class MessageList extends Component {
<div className={styles.messageListWrapper}>
<div
role="log"
tabIndex="0"
ref={(ref) => { this.scrollArea = ref; }}
id={this.props.id}
className={styles.messageList}
@ -169,23 +187,6 @@ class MessageList extends Component {
</div>
);
}
renderUnreadNotification() {
const { intl, hasUnreadMessages, scrollPosition } = this.props;
if (hasUnreadMessages && scrollPosition !== null) {
return (
<Button
className={styles.unreadButton}
size={'sm'}
label={intl.formatMessage(intlMessages.moreMessages)}
onClick={() => this.scrollTo()}
/>
);
}
return null;
}
}
MessageList.propTypes = propTypes;

View File

@ -63,7 +63,7 @@ const mapMessage = (messagePayload) => {
};
if (message.chat_type !== SYSTEM_CHAT_TYPE) {
mappedMessage.sender = getUser(message.fromUserid, message.fromUsername);
mappedMessage.sender = getUser(message.fromUserId, message.fromUsername);
}
return mappedMessage;
@ -93,7 +93,7 @@ const reduceMessages = (previous, current) => {
// between the two messages exceeds window and then group current message
// with the last one
if (lastPayload.fromUserid === currentPayload.fromUserid
if (lastPayload.fromUserId === currentPayload.fromUserId
&& (currentPayload.fromTime - lastPayload.fromTime) <= GROUPING_MESSAGES_WINDOW) {
lastMessage.content.push(reducedMessages.content.pop());
return previous;