From a06ecb87bc4c0d10a5d516e3a89395a437327283 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Mon, 23 Jan 2017 16:01:39 +0100 Subject: [PATCH] Hide RoomStatusBar when it displays nothing (#615) Use CSS class `mx_RoomView_statusArea_expanded` to indicate an expanded status bar. Without this, the status bar may be hidden from view. A 10s debounce will prevent it from bouncing frequently. --- src/components/structures/RoomStatusBar.js | 67 +++++++++++++--------- src/components/structures/RoomView.js | 24 +++++++- 2 files changed, 62 insertions(+), 29 deletions(-) diff --git a/src/components/structures/RoomStatusBar.js b/src/components/structures/RoomStatusBar.js index d6d41f21d8..0eb50161ec 100644 --- a/src/components/structures/RoomStatusBar.js +++ b/src/components/structures/RoomStatusBar.js @@ -23,6 +23,11 @@ const MemberAvatar = require("../views/avatars/MemberAvatar"); const TYPING_AVATARS_LIMIT = 2; +const HIDE_DEBOUNCE_MS = 10000; +const STATUS_BAR_HIDDEN = 0; +const STATUS_BAR_EXPANDED = 1; +const STATUS_BAR_EXPANDED_LARGE = 2; + module.exports = React.createClass({ displayName: 'RoomStatusBar', @@ -63,6 +68,13 @@ module.exports = React.createClass({ // status bar. This is used to trigger a re-layout in the parent // component. onResize: React.PropTypes.func, + + // callback for when the status bar can be hidden from view, as it is + // not displaying anything + onHidden: React.PropTypes.func, + // callback for when the status bar is displaying something and should + // be visible + onVisible: React.PropTypes.func, }, getInitialState: function() { @@ -81,6 +93,18 @@ module.exports = React.createClass({ if(this.props.onResize && this._checkForResize(prevProps, prevState)) { this.props.onResize(); } + + const size = this._getSize(this.state, this.props); + if (size > 0) { + this.props.onVisible(); + } else { + if (this.hideDebouncer) { + clearTimeout(this.hideDebouncer); + } + this.hideDebouncer = setTimeout(() => { + this.props.onHidden(); + }, HIDE_DEBOUNCE_MS); + } }, componentWillUnmount: function() { @@ -107,35 +131,24 @@ module.exports = React.createClass({ }); }, + // We don't need the actual height - just whether it is likely to have + // changed - so we use '0' to indicate normal size, and other values to + // indicate other sizes. + _getSize: function(state, props) { + if (state.syncState === "ERROR" || state.whoisTypingString) { + return STATUS_BAR_EXPANDED; + } else if (props.tabCompleteEntries) { + return STATUS_BAR_HIDDEN; + } else if (props.hasUnsentMessages) { + return STATUS_BAR_EXPANDED_LARGE; + } + return STATUS_BAR_HIDDEN; + }, + // determine if we need to call onResize _checkForResize: function(prevProps, prevState) { - // figure out the old height and the new height of the status bar. We - // don't need the actual height - just whether it is likely to have - // changed - so we use '0' to indicate normal size, and other values to - // indicate other sizes. - var oldSize, newSize; - - if (prevState.syncState === "ERROR") { - oldSize = 1; - } else if (prevProps.tabCompleteEntries) { - oldSize = 0; - } else if (prevProps.hasUnsentMessages) { - oldSize = 2; - } else { - oldSize = 0; - } - - if (this.state.syncState === "ERROR") { - newSize = 1; - } else if (this.props.tabCompleteEntries) { - newSize = 0; - } else if (this.props.hasUnsentMessages) { - newSize = 2; - } else { - newSize = 0; - } - - return newSize != oldSize; + // figure out the old height and the new height of the status bar. + return this._getSize(prevProps, prevState) !== this._getSize(this.props, this.state); }, // return suitable content for the image on the left of the status bar. diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 1f35e41817..8753540e48 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -146,6 +146,8 @@ module.exports = React.createClass({ showTopUnreadMessagesBar: false, auxPanelMaxHeight: undefined, + + statusBarVisible: false, }; }, @@ -1333,6 +1335,18 @@ module.exports = React.createClass({ // no longer anything to do here }, + onStatusBarVisible: function() { + this.setState({ + statusBarVisible: true, + }); + }, + + onStatusBarHidden: function() { + this.setState({ + statusBarVisible: false, + }); + }, + showSettings: function(show) { // XXX: this is a bit naughty; we should be doing this via props if (show) { @@ -1515,7 +1529,9 @@ module.exports = React.createClass({ onCancelAllClick={this.onCancelAllClick} onScrollToBottomClick={this.jumpToLiveTimeline} onResize={this.onChildResize} - />; + onVisible={this.onStatusBarVisible} + onHidden={this.onStatusBarHidden} + />; } var aux = null; @@ -1669,6 +1685,10 @@ module.exports = React.createClass({ ); } + let statusBarAreaClass = "mx_RoomView_statusArea mx_fadable"; + if (this.state.statusBarVisible) { + statusBarAreaClass += " mx_RoomView_statusArea_expanded"; + } return (
@@ -1691,7 +1711,7 @@ module.exports = React.createClass({ { topUnreadMessagesBar } { messagePanel } { searchResultsPanel } -
+
{ statusBar }