Merge pull request #2478 from matrix-org/bwindels/jumptobottommakeover

Redesign: pull jump to bottom button out of room status bar
This commit is contained in:
Bruno Windels 2019-01-22 16:39:54 +00:00 committed by GitHub
commit d803005d1c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 147 additions and 58 deletions

View file

@ -98,6 +98,7 @@
@import "./views/rooms/_AuxPanel.scss";
@import "./views/rooms/_EntityTile.scss";
@import "./views/rooms/_EventTile.scss";
@import "./views/rooms/_JumpToBottomButton.scss";
@import "./views/rooms/_LinkPreviewWidget.scss";
@import "./views/rooms/_MemberDeviceInfo.scss";
@import "./views/rooms/_MemberInfo.scss";

View file

@ -0,0 +1,69 @@
/*
Copyright 2019 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
@charset "utf-8";
.mx_JumpToBottomButton {
z-index: 1000;
position: absolute;
// 12 because height is 50 but button is only 38 = 12+(50-38) = 24
bottom: 12px;
right: 24px;
width: 38px;
// give it a fixed height so the badge doesn't make
// it taller and pop upwards when visible
height: 50px;
text-align: center;
}
.mx_JumpToBottomButton_badge {
position: relative;
top: -12px;
border-radius: 16px;
font-weight: bold;
font-size: 12px;
line-height: 14px;
text-align: center;
// to be able to get it centered
// with text-align in parent
display: inline-block;
padding: 0 4px;
color: $secondary-accent-color;
background-color: $warning-color;
}
.mx_JumpToBottomButton_scrollDown {
position: relative;
height: 38px;
border-radius: 19px;
box-sizing: border-box;
background: $primary-bg-color;
border: 1.3px solid $roomtile-name-color;
cursor: pointer;
}
.mx_JumpToBottomButton_scrollDown:before {
content: "";
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
mask: url('$(res)/img/icon-jump-to-bottom.svg');
mask-repeat: no-repeat;
mask-position: 9px 14px;
background: $roomtile-name-color;
}

View file

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
id="svg4"
width="18.666187"
height="8.7375822"
viewBox="0 0 18.666187 8.7375818"
version="1.1"
style="fill:none">
<metadata
id="metadata8">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs8" />
<path
id="path2-8-3"
style="fill:none;stroke:#000000;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 17.909095,0.75599092 9.3330939,7.987602 0.75709259,0.75599092" />
</svg>

After

Width:  |  Height:  |  Size: 1,016 B

View file

@ -45,14 +45,6 @@ module.exports = React.createClass({
propTypes: {
// the room this statusbar is representing.
room: PropTypes.object.isRequired,
// the number of messages which have arrived since we've been scrolled up
numUnreadMessages: PropTypes.number,
// this is true if we are fully scrolled-down, and are looking at
// the end of the live timeline.
atEndOfLiveTimeline: PropTypes.bool,
// This is true when the user is alone in the room, but has also sent a message.
// Used to suggest to the user to invite someone
sentMessageAndIsAlone: PropTypes.bool,
@ -82,9 +74,6 @@ module.exports = React.createClass({
// 'you are alone' bar
onStopWarningClick: PropTypes.func,
// callback for when the user clicks on the 'scroll to bottom' button
onScrollToBottomClick: PropTypes.func,
// callback for when we do something that changes the size of the
// status bar. This is used to trigger a re-layout in the parent
// component.
@ -180,8 +169,6 @@ module.exports = React.createClass({
// indicate other sizes.
_getSize: function() {
if (this._shouldShowConnectionError() ||
this.props.numUnreadMessages ||
!this.props.atEndOfLiveTimeline ||
this.props.hasActiveCall ||
this.props.sentMessageAndIsAlone
) {
@ -194,28 +181,6 @@ module.exports = React.createClass({
// return suitable content for the image on the left of the status bar.
_getIndicator: function() {
if (this.props.numUnreadMessages) {
return (
<div className="mx_RoomStatusBar_scrollDownIndicator"
onClick={this.props.onScrollToBottomClick}>
<img src={require("../../../res/img/newmessages.svg")} width="24" height="24"
alt="" />
</div>
);
}
const AccessibleButton = sdk.getComponent("elements.AccessibleButton");
if (!this.props.atEndOfLiveTimeline) {
return (
<AccessibleButton className="mx_RoomStatusBar_scrollDownIndicator"
onClick={this.props.onScrollToBottomClick}>
<img src={require("../../../res/img/scrolldown.svg")} width="24" height="24"
alt={_t("Scroll to bottom of page")}
title={_t("Scroll to bottom of page")} />
</AccessibleButton>
);
}
if (this.props.hasActiveCall) {
const TintableSvg = sdk.getComponent("elements.TintableSvg");
return (
@ -231,9 +196,7 @@ module.exports = React.createClass({
},
_shouldShowConnectionError: function() {
// no conn bar trumps unread count since you can't get unread messages
// without a connection! (technically may already have some but meh)
// It also trumps the "some not sent" msg since you can't resend without
// no conn bar trumps the "some not sent" msg since you can't resend without
// a connection!
// There's one situation in which we don't show this 'no connection' bar, and that's
// if it's a resource limit exceeded error: those are shown in the top bar.
@ -363,20 +326,6 @@ module.exports = React.createClass({
return this._getUnsentMessageContent();
}
// unread count trumps who is typing since the unread count is only
// set when you've scrolled up
if (this.props.numUnreadMessages) {
// MUST use var name "count" for pluralization to kick in
const unreadMsgs = _t("%(count)s new messages", {count: this.props.numUnreadMessages});
return (
<div className="mx_RoomStatusBar_unreadMessagesBar"
onClick={this.props.onScrollToBottomClick}>
{ unreadMsgs }
</div>
);
}
if (this.props.hasActiveCall) {
return (
<div className="mx_RoomStatusBar_callBar">

View file

@ -1473,11 +1473,10 @@ module.exports = React.createClass({
onStatusBarHidden: function() {
// This is currently not desired as it is annoying if it keeps expanding and collapsing
// TODO: Find a less annoying way of hiding the status bar
/*if (this.unmounted) return;
if (this.unmounted) return;
this.setState({
statusBarVisible: false,
});*/
});
},
/**
@ -1651,14 +1650,11 @@ module.exports = React.createClass({
isStatusAreaExpanded = this.state.statusBarVisible;
statusBar = <RoomStatusBar
room={this.state.room}
numUnreadMessages={this.state.numUnreadMessages}
atEndOfLiveTimeline={this.state.atEndOfLiveTimeline}
sentMessageAndIsAlone={this.state.isAlone}
hasActiveCall={inCall}
isPeeking={myMembership !== "join"}
onInviteClick={this.onInviteButtonClick}
onStopWarningClick={this.onStopAloneWarningClick}
onScrollToBottomClick={this.jumpToLiveTimeline}
onResize={this.onChildResize}
onVisible={this.onStatusBarVisible}
onHidden={this.onStatusBarHidden}
@ -1864,6 +1860,14 @@ module.exports = React.createClass({
onCloseClick={this.forgetReadMarker}
/>);
}
let jumpToBottom;
if (!this.state.atEndOfLiveTimeline) {
const JumpToBottomButton = sdk.getComponent('rooms.JumpToBottomButton');
jumpToBottom = (<JumpToBottomButton
numUnreadMessages={this.state.numUnreadMessages}
onScrollToBottomClick={this.jumpToLiveTimeline}
/>);
}
const statusBarAreaClass = classNames(
"mx_RoomView_statusArea",
{
@ -1901,6 +1905,7 @@ module.exports = React.createClass({
{ auxPanel }
<div className="mx_RoomView_timeline">
{ topUnreadMessagesBar }
{ jumpToBottom }
{ messagePanel }
{ searchResultsPanel }
</div>

View file

@ -0,0 +1,32 @@
/*
Copyright 2019 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import { _t } from '../../../languageHandler';
import AccessibleButton from '../elements/AccessibleButton';
export default (props) => {
let badge;
if (props.numUnreadMessages) {
badge = (<div className="mx_JumpToBottomButton_badge">{props.numUnreadMessages}</div>);
}
return (<div className="mx_JumpToBottomButton">
<AccessibleButton className="mx_JumpToBottomButton_scrollDown"
title={_t("Scroll to bottom of page")}
onClick={props.onScrollToBottomClick}>
</AccessibleButton>
{ badge }
</div>);
};

View file

@ -1,6 +1,7 @@
/*
Copyright 2016 OpenMarket Ltd
Copyright 2017 Vector Creations Ltd
Copyright 2019 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.