diff --git a/res/css/_components.scss b/res/css/_components.scss index 92070483f56..6532fcd74c6 100644 --- a/res/css/_components.scss +++ b/res/css/_components.scss @@ -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"; diff --git a/res/css/views/rooms/_JumpToBottomButton.scss b/res/css/views/rooms/_JumpToBottomButton.scss new file mode 100644 index 00000000000..968139671f4 --- /dev/null +++ b/res/css/views/rooms/_JumpToBottomButton.scss @@ -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; +} diff --git a/res/img/icon-jump-to-bottom.svg b/res/img/icon-jump-to-bottom.svg new file mode 100644 index 00000000000..c4210b4ebef --- /dev/null +++ b/res/img/icon-jump-to-bottom.svg @@ -0,0 +1,32 @@ + + + + + + image/svg+xml + + + + + + + + diff --git a/src/components/structures/RoomStatusBar.js b/src/components/structures/RoomStatusBar.js index 12888769ffe..b57bac805ec 100644 --- a/src/components/structures/RoomStatusBar.js +++ b/src/components/structures/RoomStatusBar.js @@ -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 ( -
- -
- ); - } - - const AccessibleButton = sdk.getComponent("elements.AccessibleButton"); - if (!this.props.atEndOfLiveTimeline) { - return ( - - {_t("Scroll - - ); - } - 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 ( -
- { unreadMsgs } -
- ); - } - if (this.props.hasActiveCall) { return (
diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index f63e5b3273e..ea01c9bcae5 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -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 = ); } + let jumpToBottom; + if (!this.state.atEndOfLiveTimeline) { + const JumpToBottomButton = sdk.getComponent('rooms.JumpToBottomButton'); + jumpToBottom = (); + } const statusBarAreaClass = classNames( "mx_RoomView_statusArea", { @@ -1901,6 +1905,7 @@ module.exports = React.createClass({ { auxPanel }
{ topUnreadMessagesBar } + { jumpToBottom } { messagePanel } { searchResultsPanel }
diff --git a/src/components/views/rooms/JumpToBottomButton.js b/src/components/views/rooms/JumpToBottomButton.js new file mode 100644 index 00000000000..487071855f5 --- /dev/null +++ b/src/components/views/rooms/JumpToBottomButton.js @@ -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 = (
{props.numUnreadMessages}
); + } + return (
+ + + { badge } +
); +}; diff --git a/src/components/views/rooms/TopUnreadMessagesBar.js b/src/components/views/rooms/TopUnreadMessagesBar.js index ed04ce594db..99f3b7fb23d 100644 --- a/src/components/views/rooms/TopUnreadMessagesBar.js +++ b/src/components/views/rooms/TopUnreadMessagesBar.js @@ -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.