use AutoHideScrollbar in ScrollPanel

This commit is contained in:
Bruno Windels 2019-03-12 16:30:06 +01:00
parent 5409db418c
commit 30d848b86e
3 changed files with 23 additions and 20 deletions

View file

@ -84,6 +84,7 @@ limitations under the License.
display: flex; display: flex;
flex-direction: column; flex-direction: column;
flex: 1; flex: 1;
min-width: 0;
} }
.mx_RoomView_body .mx_RoomView_timeline { .mx_RoomView_body .mx_RoomView_timeline {
@ -111,6 +112,7 @@ limitations under the License.
.mx_RoomView_messagePanel { .mx_RoomView_messagePanel {
width: 100%; width: 100%;
overflow-y: auto; overflow-y: auto;
flex: 1 1 0;
} }
.mx_RoomView_messagePanelSearchSpinner { .mx_RoomView_messagePanelSearchSpinner {

View file

@ -121,6 +121,7 @@ export default class AutoHideScrollbar extends React.Component {
render() { render() {
return (<div return (<div
ref={this._collectContainerRef} ref={this._collectContainerRef}
style={this.props.style}
className={["mx_AutoHideScrollbar", this.props.className].join(" ")} className={["mx_AutoHideScrollbar", this.props.className].join(" ")}
onScroll={this.props.onScroll} onScroll={this.props.onScroll}
> >

View file

@ -15,14 +15,13 @@ limitations under the License.
*/ */
const React = require("react"); const React = require("react");
const ReactDOM = require("react-dom");
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import Promise from 'bluebird'; import Promise from 'bluebird';
import { KeyCode } from '../../Keyboard'; import { KeyCode } from '../../Keyboard';
import sdk from '../../index.js'; import AutoHideScrollbar from "./AutoHideScrollbar";
const DEBUG_SCROLL = false; const DEBUG_SCROLL = false;
// var DEBUG_SCROLL = true; // const DEBUG_SCROLL = true;
// The amount of extra scroll distance to allow prior to unfilling. // The amount of extra scroll distance to allow prior to unfilling.
// See _getExcessHeight. // See _getExcessHeight.
@ -129,11 +128,6 @@ module.exports = React.createClass({
*/ */
onScroll: PropTypes.func, onScroll: PropTypes.func,
/* onResize: a callback which is called whenever the Gemini scroll
* panel is resized
*/
onResize: PropTypes.func,
/* className: classnames to add to the top-level div /* className: classnames to add to the top-level div
*/ */
className: PropTypes.string, className: PropTypes.string,
@ -150,7 +144,6 @@ module.exports = React.createClass({
onFillRequest: function(backwards) { return Promise.resolve(false); }, onFillRequest: function(backwards) { return Promise.resolve(false); },
onUnfillRequest: function(backwards, scrollToken) {}, onUnfillRequest: function(backwards, scrollToken) {},
onScroll: function() {}, onScroll: function() {},
onResize: function() {},
}; };
}, },
@ -185,6 +178,16 @@ module.exports = React.createClass({
debuglog("Scroll event: offset now:", sn.scrollTop, debuglog("Scroll event: offset now:", sn.scrollTop,
"_lastSetScroll:", this._lastSetScroll); "_lastSetScroll:", this._lastSetScroll);
// ignore scroll events where scrollTop hasn't changed,
// appears to happen when the layout changes outside
// of the scroll container, like resizing the right panel.
if (sn.scrollTop === this._lastEventScroll) {
debuglog("ignore scroll event with same scrollTop as before");
return;
}
this._lastEventScroll = sn.scrollTop;
// Sometimes we see attempts to write to scrollTop essentially being // Sometimes we see attempts to write to scrollTop essentially being
// ignored. (Or rather, it is successfully written, but on the next // ignored. (Or rather, it is successfully written, but on the next
// scroll event, it's been reset again). // scroll event, it's been reset again).
@ -225,9 +228,7 @@ module.exports = React.createClass({
onResize: function() { onResize: function() {
this.clearBlockShrinking(); this.clearBlockShrinking();
this.props.onResize();
this.checkScroll(); this.checkScroll();
if (this._gemScroll) this._gemScroll.forceUpdate();
}, },
// after an update to the contents of the panel, check that the scroll is // after an update to the contents of the panel, check that the scroll is
@ -672,17 +673,17 @@ module.exports = React.createClass({
throw new Error("ScrollPanel._getScrollNode called when unmounted"); throw new Error("ScrollPanel._getScrollNode called when unmounted");
} }
if (!this._gemScroll) { if (!this._divScroll) {
// Likewise, we should have the ref by this point, but if not // Likewise, we should have the ref by this point, but if not
// turn the NPE into something meaningful. // turn the NPE into something meaningful.
throw new Error("ScrollPanel._getScrollNode called before gemini ref collected"); throw new Error("ScrollPanel._getScrollNode called before gemini ref collected");
} }
return this._gemScroll.scrollbar.getViewElement(); return this._divScroll;
}, },
_collectGeminiScroll: function(gemScroll) { _collectScroll: function(divScroll) {
this._gemScroll = gemScroll; this._divScroll = divScroll;
}, },
/** /**
@ -724,19 +725,18 @@ module.exports = React.createClass({
}, },
render: function() { render: function() {
const GeminiScrollbarWrapper = sdk.getComponent("elements.GeminiScrollbarWrapper");
// TODO: the classnames on the div and ol could do with being updated to // TODO: the classnames on the div and ol could do with being updated to
// reflect the fact that we don't necessarily contain a list of messages. // reflect the fact that we don't necessarily contain a list of messages.
// it's not obvious why we have a separate div and ol anyway. // it's not obvious why we have a separate div and ol anyway.
return (<GeminiScrollbarWrapper autoshow={true} wrappedRef={this._collectGeminiScroll} return (<AutoHideScrollbar wrappedRef={this._collectScroll}
onScroll={this.onScroll} onResize={this.onResize} onScroll={this.onScroll}
className={this.props.className} style={this.props.style}> className={this.props.className} style={this.props.style}>
<div className="mx_RoomView_messageListWrapper"> <div className="mx_RoomView_messageListWrapper">
<ol ref="itemlist" className="mx_RoomView_MessageList" aria-live="polite"> <ol ref="itemlist" className="mx_RoomView_MessageList" aria-live="polite">
{ this.props.children } { this.props.children }
</ol> </ol>
</div> </div>
</GeminiScrollbarWrapper> </AutoHideScrollbar>
); );
}, },
}); });