Fix scrolling on browsers where gemini scrollbars don't kick in.

This commit is contained in:
David Baker 2015-11-12 17:18:22 +00:00
parent c12c716dc0
commit 1ac47f32fe
2 changed files with 41 additions and 31 deletions

View file

@ -60,12 +60,12 @@ module.exports = {
}, },
componentWillUnmount: function() { componentWillUnmount: function() {
if (this.refs.messageWrapper) { if (this.refs.messagePanel) {
var messageWrapper = ReactDOM.findDOMNode(this.refs.messageWrapper); var messagePanel = ReactDOM.findDOMNode(this.refs.messagePanel);
messageWrapper.removeEventListener('drop', this.onDrop); messagePanel.removeEventListener('drop', this.onDrop);
messageWrapper.removeEventListener('dragover', this.onDragOver); messagePanel.removeEventListener('dragover', this.onDragOver);
messageWrapper.removeEventListener('dragleave', this.onDragLeaveOrEnd); messagePanel.removeEventListener('dragleave', this.onDragLeaveOrEnd);
messageWrapper.removeEventListener('dragend', this.onDragLeaveOrEnd); messagePanel.removeEventListener('dragend', this.onDragLeaveOrEnd);
} }
dis.unregister(this.dispatcherRef); dis.unregister(this.dispatcherRef);
if (MatrixClientPeg.get()) { if (MatrixClientPeg.get()) {
@ -98,10 +98,9 @@ module.exports = {
// Call state has changed so we may be loading video elements // Call state has changed so we may be loading video elements
// which will obscure the message log. // which will obscure the message log.
// scroll to bottom // scroll to bottom
var messageWrapper = this.refs.messageWrapper; var scrollNode = this._getScrollNode();
if (messageWrapper) { if (scrollNode) {
var messageWrapperScroll = ReactDOM.findDOMNode(messageWrapper).children[2]; scrollNode.scrollTop = scrollNode.scrollHeight;
messageWrapperScroll.scrollTop = messageWrapperScroll.scrollHeight;
} }
} }
@ -112,6 +111,17 @@ module.exports = {
} }
}, },
_getScrollNode: function() {
var panel = ReactDOM.findDOMNode(this.refs.messagePanel);
if (!panel) return null;
if (panel.classList.contains('gm-prevented')) {
return panel;
} else {
return panel.children[2]; // XXX: Fragile!
}
},
onSyncStateChange: function(state) { onSyncStateChange: function(state) {
this.setState({ this.setState({
syncState: state syncState: state
@ -138,11 +148,11 @@ module.exports = {
if (this.state.joining) return; if (this.state.joining) return;
if (room.roomId != this.props.roomId) return; if (room.roomId != this.props.roomId) return;
if (this.refs.messageWrapper) { var scrollNode = this._getScrollNode();
var messageWrapperScroll = ReactDOM.findDOMNode(this.refs.messageWrapper).children[2]; if (scrollNode) {
this.atBottom = ( this.atBottom = (
messageWrapperScroll.scrollHeight - messageWrapperScroll.scrollTop <= scrollNode.scrollHeight - scrollNode.scrollTop <=
(messageWrapperScroll.clientHeight + 150) (scrollNode.clientHeight + 150) // 150?
); );
} }
@ -225,15 +235,15 @@ module.exports = {
}, },
componentDidMount: function() { componentDidMount: function() {
if (this.refs.messageWrapper) { if (this.refs.messagePanel) {
var messageWrapper = ReactDOM.findDOMNode(this.refs.messageWrapper); var messagePanel = ReactDOM.findDOMNode(this.refs.messagePanel);
messageWrapper.addEventListener('drop', this.onDrop); messagePanel.addEventListener('drop', this.onDrop);
messageWrapper.addEventListener('dragover', this.onDragOver); messagePanel.addEventListener('dragover', this.onDragOver);
messageWrapper.addEventListener('dragleave', this.onDragLeaveOrEnd); messagePanel.addEventListener('dragleave', this.onDragLeaveOrEnd);
messageWrapper.addEventListener('dragend', this.onDragLeaveOrEnd); messagePanel.addEventListener('dragend', this.onDragLeaveOrEnd);
var messageWrapperScroll = messageWrapper.children[2]; var messageWrapperScroll = this._getScrollNode();
messageWrapperScroll.scrollTop = messageWrapperScroll.scrollHeight; messageWrapperScroll.scrollTop = messageWrapperScroll.scrollHeight;
@ -244,9 +254,9 @@ module.exports = {
}, },
componentDidUpdate: function() { componentDidUpdate: function() {
if (!this.refs.messageWrapper) return; if (!this.refs.messagePanel) return;
var messageWrapperScroll = ReactDOM.findDOMNode(this.refs.messageWrapper).children[2]; var messageWrapperScroll = this._getScrollNode();
if (this.state.paginating && !this.waiting_for_paginate) { if (this.state.paginating && !this.waiting_for_paginate) {
var heightGained = messageWrapperScroll.scrollHeight - this.oldScrollHeight; var heightGained = messageWrapperScroll.scrollHeight - this.oldScrollHeight;
@ -264,8 +274,8 @@ module.exports = {
}, },
fillSpace: function() { fillSpace: function() {
if (!this.refs.messageWrapper) return; if (!this.refs.messagePanel) return;
var messageWrapperScroll = ReactDOM.findDOMNode(this.refs.messageWrapper).children[2]; var messageWrapperScroll = this._getScrollNode();
if (messageWrapperScroll.scrollTop < messageWrapperScroll.clientHeight && this.state.room.oldState.paginationToken) { if (messageWrapperScroll.scrollTop < messageWrapperScroll.clientHeight && this.state.room.oldState.paginationToken) {
this.setState({paginating: true}); this.setState({paginating: true});
@ -322,8 +332,8 @@ module.exports = {
}, },
onMessageListScroll: function(ev) { onMessageListScroll: function(ev) {
if (this.refs.messageWrapper) { if (this.refs.messagePanel) {
var messageWrapperScroll = ReactDOM.findDOMNode(this.refs.messageWrapper).children[2]; var messageWrapperScroll = this._getScrollNode();
var wasAtBottom = this.atBottom; var wasAtBottom = this.atBottom;
this.atBottom = messageWrapperScroll.scrollHeight - messageWrapperScroll.scrollTop <= messageWrapperScroll.clientHeight - 1; this.atBottom = messageWrapperScroll.scrollHeight - messageWrapperScroll.scrollTop <= messageWrapperScroll.clientHeight - 1;
if (this.atBottom && !wasAtBottom) { if (this.atBottom && !wasAtBottom) {

View file

@ -101,9 +101,9 @@ module.exports = React.createClass({
}, },
scrollToBottom: function() { scrollToBottom: function() {
if (!this.refs.messageWrapper) return; var scrollNode = this._getScrollNode();
var messageWrapper = ReactDOM.findDOMNode(this.refs.messageWrapper).children[2]; if (!scrollNode) return;
messageWrapper.scrollTop = messageWrapper.scrollHeight; scrollNode.scrollTop = scrollNode.scrollHeight;
}, },
render: function() { render: function() {
@ -299,7 +299,7 @@ module.exports = React.createClass({
{ conferenceCallNotification } { conferenceCallNotification }
{ aux } { aux }
</div> </div>
<GeminiScrollbar autoshow={true} ref="messageWrapper" className="mx_RoomView_messagePanel" onScroll={ this.onMessageListScroll }> <GeminiScrollbar autoshow={true} ref="messagePanel" className="mx_RoomView_messagePanel" onScroll={ this.onMessageListScroll }>
<div className="mx_RoomView_messageListWrapper"> <div className="mx_RoomView_messageListWrapper">
{ fileDropTarget } { fileDropTarget }
<ol className="mx_RoomView_MessageList" aria-live="polite"> <ol className="mx_RoomView_MessageList" aria-live="polite">