Fix chat list
This commit is contained in:
parent
e1004b64d3
commit
eb5712e96c
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user