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.
This commit is contained in:
Luke Barnard 2017-01-23 16:01:39 +01:00 committed by GitHub
parent 7a445e05f8
commit a06ecb87bc
2 changed files with 62 additions and 29 deletions

View file

@ -23,6 +23,11 @@ const MemberAvatar = require("../views/avatars/MemberAvatar");
const TYPING_AVATARS_LIMIT = 2; 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({ module.exports = React.createClass({
displayName: 'RoomStatusBar', displayName: 'RoomStatusBar',
@ -63,6 +68,13 @@ module.exports = React.createClass({
// status bar. This is used to trigger a re-layout in the parent // status bar. This is used to trigger a re-layout in the parent
// component. // component.
onResize: React.PropTypes.func, 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() { getInitialState: function() {
@ -81,6 +93,18 @@ module.exports = React.createClass({
if(this.props.onResize && this._checkForResize(prevProps, prevState)) { if(this.props.onResize && this._checkForResize(prevProps, prevState)) {
this.props.onResize(); 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() { componentWillUnmount: function() {
@ -107,35 +131,24 @@ module.exports = React.createClass({
}); });
}, },
// determine if we need to call onResize // We don't need the actual height - just whether it is likely to have
_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 // changed - so we use '0' to indicate normal size, and other values to
// indicate other sizes. // indicate other sizes.
var oldSize, newSize; _getSize: function(state, props) {
if (state.syncState === "ERROR" || state.whoisTypingString) {
if (prevState.syncState === "ERROR") { return STATUS_BAR_EXPANDED;
oldSize = 1; } else if (props.tabCompleteEntries) {
} else if (prevProps.tabCompleteEntries) { return STATUS_BAR_HIDDEN;
oldSize = 0; } else if (props.hasUnsentMessages) {
} else if (prevProps.hasUnsentMessages) { return STATUS_BAR_EXPANDED_LARGE;
oldSize = 2;
} else {
oldSize = 0;
} }
return STATUS_BAR_HIDDEN;
},
if (this.state.syncState === "ERROR") { // determine if we need to call onResize
newSize = 1; _checkForResize: function(prevProps, prevState) {
} else if (this.props.tabCompleteEntries) { // figure out the old height and the new height of the status bar.
newSize = 0; return this._getSize(prevProps, prevState) !== this._getSize(this.props, this.state);
} else if (this.props.hasUnsentMessages) {
newSize = 2;
} else {
newSize = 0;
}
return newSize != oldSize;
}, },
// return suitable content for the image on the left of the status bar. // return suitable content for the image on the left of the status bar.

View file

@ -146,6 +146,8 @@ module.exports = React.createClass({
showTopUnreadMessagesBar: false, showTopUnreadMessagesBar: false,
auxPanelMaxHeight: undefined, auxPanelMaxHeight: undefined,
statusBarVisible: false,
}; };
}, },
@ -1333,6 +1335,18 @@ module.exports = React.createClass({
// no longer anything to do here // no longer anything to do here
}, },
onStatusBarVisible: function() {
this.setState({
statusBarVisible: true,
});
},
onStatusBarHidden: function() {
this.setState({
statusBarVisible: false,
});
},
showSettings: function(show) { showSettings: function(show) {
// XXX: this is a bit naughty; we should be doing this via props // XXX: this is a bit naughty; we should be doing this via props
if (show) { if (show) {
@ -1515,6 +1529,8 @@ module.exports = React.createClass({
onCancelAllClick={this.onCancelAllClick} onCancelAllClick={this.onCancelAllClick}
onScrollToBottomClick={this.jumpToLiveTimeline} onScrollToBottomClick={this.jumpToLiveTimeline}
onResize={this.onChildResize} onResize={this.onChildResize}
onVisible={this.onStatusBarVisible}
onHidden={this.onStatusBarHidden}
/>; />;
} }
@ -1669,6 +1685,10 @@ module.exports = React.createClass({
</div> </div>
); );
} }
let statusBarAreaClass = "mx_RoomView_statusArea mx_fadable";
if (this.state.statusBarVisible) {
statusBarAreaClass += " mx_RoomView_statusArea_expanded";
}
return ( return (
<div className={ "mx_RoomView" + (inCall ? " mx_RoomView_inCall" : "") } ref="roomView"> <div className={ "mx_RoomView" + (inCall ? " mx_RoomView_inCall" : "") } ref="roomView">
@ -1691,7 +1711,7 @@ module.exports = React.createClass({
{ topUnreadMessagesBar } { topUnreadMessagesBar }
{ messagePanel } { messagePanel }
{ searchResultsPanel } { searchResultsPanel }
<div className="mx_RoomView_statusArea mx_fadable" style={{ opacity: this.props.opacity }}> <div className={statusBarAreaClass} style={{opacity: this.props.opacity}}>
<div className="mx_RoomView_statusAreaBox"> <div className="mx_RoomView_statusAreaBox">
<div className="mx_RoomView_statusAreaBox_line"></div> <div className="mx_RoomView_statusAreaBox_line"></div>
{ statusBar } { statusBar }