fix(chat): fix auto-scrolling to bottom

Empower the parent.
This commit is contained in:
Leonard Kim 2019-05-06 15:07:16 -07:00 committed by virtuacoplenny
parent 504fadaf71
commit 5cd0b1a9be
2 changed files with 52 additions and 24 deletions

View File

@ -27,6 +27,12 @@ class Chat extends AbstractChat<Props> {
*/
_isExited: boolean;
/**
* Reference to the React Component for displaying chat messages. Used for
* scrolling to the end of the chat messages.
*/
_messageContainerRef: Object;
/**
* Initializes a new {@code Chat} instance.
*
@ -37,11 +43,34 @@ class Chat extends AbstractChat<Props> {
super(props);
this._isExited = true;
this._messageContainerRef = React.createRef();
// Bind event handlers so they are only bound once for every instance.
this._renderPanelContent = this._renderPanelContent.bind(this);
}
/**
* Implements {@code Component#componentDidMount}.
*
* @inheritdoc
*/
componentDidMount() {
this._scrollMessageContainerToBottom(true);
}
/**
* Implements {@code Component#componentDidUpdate}.
*
* @inheritdoc
*/
componentDidUpdate(prevProps) {
if (this.props._messages !== prevProps._messages) {
this._scrollMessageContainerToBottom(true);
} else if (this.props._isOpen && !prevProps._isOpen) {
this._scrollMessageContainerToBottom(false);
}
}
/**
* Implements React's {@link Component#render()}.
*
@ -99,7 +128,9 @@ class Chat extends AbstractChat<Props> {
_renderChat() {
return (
<>
<MessageContainer messages = { this.props._messages } />
<MessageContainer
messages = { this.props._messages }
ref = { this._messageContainerRef } />
<ChatInput />
</>
);
@ -162,6 +193,20 @@ class Chat extends AbstractChat<Props> {
</div>
);
}
/**
* Scrolls the chat messages so the latest message is visible.
*
* @param {boolean} withAnimation - Whether or not to show a scrolling
* animation.
* @private
* @returns {void}
*/
_scrollMessageContainerToBottom(withAnimation) {
if (this._messageContainerRef.current) {
this._messageContainerRef.current.scrollToBottom(withAnimation);
}
}
}
export default translate(connect(_mapStateToProps, _mapDispatchToProps)(Chat));

View File

@ -31,24 +31,6 @@ export default class MessageContainer extends AbstractMessageContainer<Props> {
this._messagesListEndRef = React.createRef();
}
/**
* Implements React's {@link Component#componentDidMount()}.
*
* @inheritdoc
*/
componentDidMount() {
this._scrollMessagesToBottom();
}
/**
* Updates chat input focus.
*
* @inheritdoc
*/
componentDidUpdate() {
this._scrollMessagesToBottom();
}
/**
* Implements {@code Component#render}.
*
@ -75,17 +57,18 @@ export default class MessageContainer extends AbstractMessageContainer<Props> {
);
}
_getMessagesGroupedBySender: () => Array<Array<Object>>;
/**
* Automatically scrolls the displayed chat messages down to the latest.
*
* @private
* @param {boolean} withAnimation - Whether or not to show a scrolling
* animation.
* @returns {void}
*/
_scrollMessagesToBottom() {
scrollToBottom(withAnimation: boolean) {
this._messagesListEndRef.current.scrollIntoView({
behavior: 'smooth'
behavior: withAnimation ? 'smooth' : 'auto'
});
}
_getMessagesGroupedBySender: () => Array<Array<Object>>;
}