commit
5c7b7a89df
|
|
@ -1,14 +1,9 @@
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
|
import { compose } from 'redux';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import marked from 'marked';
|
import marked from 'marked';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
import scrollToBottom from './scrollToBottom';
|
||||||
const scrollToBottom = () =>
|
|
||||||
{
|
|
||||||
const messagesDiv = document.getElementById('messages');
|
|
||||||
|
|
||||||
messagesDiv.scrollTop = messagesDiv.scrollHeight;
|
|
||||||
};
|
|
||||||
|
|
||||||
const linkRenderer = new marked.Renderer();
|
const linkRenderer = new marked.Renderer();
|
||||||
|
|
||||||
|
|
@ -22,16 +17,6 @@ linkRenderer.link = (href, title, text) =>
|
||||||
|
|
||||||
class MessageList extends Component
|
class MessageList extends Component
|
||||||
{
|
{
|
||||||
componentDidMount()
|
|
||||||
{
|
|
||||||
scrollToBottom();
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidUpdate()
|
|
||||||
{
|
|
||||||
scrollToBottom();
|
|
||||||
}
|
|
||||||
|
|
||||||
getTimeString(time)
|
getTimeString(time)
|
||||||
{
|
{
|
||||||
return `${(time.getHours() < 10 ? '0' : '')}${time.getHours()}:${(time.getMinutes() < 10 ? '0' : '')}${time.getMinutes()}`;
|
return `${(time.getHours() < 10 ? '0' : '')}${time.getHours()}:${(time.getMinutes() < 10 ? '0' : '')}${time.getMinutes()}`;
|
||||||
|
|
@ -96,8 +81,9 @@ const mapStateToProps = (state) =>
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const MessageListContainer = connect(
|
const MessageListContainer = compose(
|
||||||
mapStateToProps
|
connect(mapStateToProps),
|
||||||
|
scrollToBottom()
|
||||||
)(MessageList);
|
)(MessageList);
|
||||||
|
|
||||||
export default MessageListContainer;
|
export default MessageListContainer;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,63 @@
|
||||||
|
import React, { Component } from 'react';
|
||||||
|
import { findDOMNode } from 'react-dom';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A higher order component which scrolls the user to the bottom of the
|
||||||
|
* wrapped component, provided that the user already was at the bottom
|
||||||
|
* of the wrapped component. Useful for chats and similar use cases.
|
||||||
|
* @param {number} treshold The required distance from the bottom required.
|
||||||
|
*/
|
||||||
|
const scrollToBottom = (treshold = 0) => (WrappedComponent) =>
|
||||||
|
{
|
||||||
|
return class AutoScroller extends Component
|
||||||
|
{
|
||||||
|
constructor(props)
|
||||||
|
{
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.ref = React.createRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
getSnapshotBeforeUpdate()
|
||||||
|
{
|
||||||
|
// Check if the user has scrolled close enough to the bottom for
|
||||||
|
// us to scroll to the bottom or not.
|
||||||
|
return this.elem.scrollHeight - this.elem.scrollTop <=
|
||||||
|
this.elem.clientHeight - treshold;
|
||||||
|
}
|
||||||
|
|
||||||
|
scrollToBottom = () =>
|
||||||
|
{
|
||||||
|
// Scroll the user to the bottom of the wrapped element.
|
||||||
|
this.elem.scrollTop = this.elem.scrollHeight;
|
||||||
|
};
|
||||||
|
|
||||||
|
componentDidMount()
|
||||||
|
{
|
||||||
|
// eslint-disable-next-line react/no-find-dom-node
|
||||||
|
this.elem = findDOMNode(this.ref.current);
|
||||||
|
|
||||||
|
this.scrollToBottom();
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidUpdate(prevProps, prevState, atBottom)
|
||||||
|
{
|
||||||
|
if (atBottom)
|
||||||
|
{
|
||||||
|
this.scrollToBottom();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render()
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
<WrappedComponent
|
||||||
|
ref={this.ref}
|
||||||
|
{...this.props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default scrollToBottom;
|
||||||
Loading…
Reference in New Issue