Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Commit

Permalink
Merge pull request #2842 from matrix-org/bwindels/bacat-scrolling-mer…
Browse files Browse the repository at this point in the history
…ged-develop

BACAT Scrolling
  • Loading branch information
bwindels authored Mar 29, 2019
2 parents 3cd4b69 + f157838 commit a326c83
Show file tree
Hide file tree
Showing 28 changed files with 569 additions and 907 deletions.
1 change: 1 addition & 0 deletions res/css/_components.scss
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
@import "./structures/_RoomStatusBar.scss";
@import "./structures/_RoomSubList.scss";
@import "./structures/_RoomView.scss";
@import "./structures/_ScrollPanel.scss";
@import "./structures/_SearchBox.scss";
@import "./structures/_TabbedView.scss";
@import "./structures/_TagPanel.scss";
Expand Down
6 changes: 6 additions & 0 deletions res/css/structures/_MainSplit.scss
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,9 @@ limitations under the License.
flex-direction: row;
min-width: 0;
}

// move hit area 5px to the right so it doesn't overlap with the timeline scrollbar
.mx_MainSplit > .mx_ResizeHandle.mx_ResizeHandle_horizontal {
margin: 0 -10px 0 0;
padding: 0 10px 0 0;
}
3 changes: 3 additions & 0 deletions res/css/structures/_RoomView.scss
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ limitations under the License.
display: flex;
flex-direction: column;
flex: 1;
min-width: 0;
}

.mx_RoomView_body .mx_RoomView_timeline {
Expand Down Expand Up @@ -118,6 +119,8 @@ limitations under the License.
.mx_RoomView_messagePanel {
width: 100%;
overflow-y: auto;
flex: 1 1 0;
overflow-anchor: none;
}

.mx_RoomView_messagePanelSearchSpinner {
Expand Down
26 changes: 26 additions & 0 deletions res/css/structures/_ScrollPanel.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
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.
*/

.mx_ScrollPanel {

.mx_RoomView_MessageList {
position: relative;
display: flex;
flex-direction: column;
justify-content: flex-end;
overflow-y: hidden;
}
}
5 changes: 5 additions & 0 deletions res/css/views/rooms/_MemberList.scss
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ limitations under the License.
flex: 1;
display: flex;
flex-direction: column;
min-height: 0;

.mx_Spinner {
flex: 1 0 auto;
Expand All @@ -35,6 +36,10 @@ limitations under the License.
margin-top: 8px;
margin-bottom: 4px;
}

.mx_AutoHideScrollbar {
flex: 1 1 0;
}
}

.mx_MemberList_chevron {
Expand Down
12 changes: 11 additions & 1 deletion src/Notifier.js
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,17 @@ const Notifier = {
}
},

isToolbarHidden: function() {
shouldShowToolbar: function() {
const client = MatrixClientPeg.get();
if (!client) {
return false;
}
const isGuest = client.isGuest();
return !isGuest && Notifier.supportsDesktopNotifications() &&
!Notifier.isEnabled() && !Notifier._isToolbarHidden();
},

_isToolbarHidden: function() {
// Check localStorage for any such meta data
if (global.localStorage) {
return global.localStorage.getItem("notifications_hidden") === "true";
Expand Down
1 change: 1 addition & 0 deletions src/components/structures/AutoHideScrollbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ export default class AutoHideScrollbar extends React.Component {
render() {
return (<div
ref={this._collectContainerRef}
style={this.props.style}
className={["mx_AutoHideScrollbar", this.props.className].join(" ")}
onScroll={this.props.onScroll}
>
Expand Down
1 change: 1 addition & 0 deletions src/components/structures/FilePanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ const FilePanel = React.createClass({
timelineSet={this.state.timelineSet}
showUrlPreview = {false}
tileShape="file_grid"
resizeNotifier={this.props.resizeNotifier}
empty={_t('There are no visible files in this room')}
/>
);
Expand Down
2 changes: 1 addition & 1 deletion src/components/structures/LeftPanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ const LeftPanel = React.createClass({
<CallPreview ConferenceHandler={VectorConferenceHandler} />
<RoomList
ref={this.collectRoomList}
toolbarShown={this.props.toolbarShown}
resizeNotifier={this.props.resizeNotifier}
collapsed={this.props.collapsed}
searchFilter={this.state.searchFilter}
ConferenceHandler={VectorConferenceHandler} />
Expand Down
23 changes: 16 additions & 7 deletions src/components/structures/LoggedInView.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import PropTypes from 'prop-types';
import { DragDropContext } from 'react-beautiful-dnd';

import { KeyCode, isOnlyCtrlOrCmdKeyEvent } from '../../Keyboard';
import Notifier from '../../Notifier';
import PageTypes from '../../PageTypes';
import CallMediaHandler from '../../CallMediaHandler';
import sdk from '../../index';
Expand Down Expand Up @@ -121,6 +120,18 @@ const LoggedInView = React.createClass({
this._matrixClient.on("RoomState.events", this.onRoomStateEvents);
},

componentDidUpdate(prevProps) {
// attempt to guess when a banner was opened or closed
if (
(prevProps.showCookieBar !== this.props.showCookieBar) ||
(prevProps.hasNewVersion !== this.props.hasNewVersion) ||
(prevProps.userHasGeneratedPassword !== this.props.userHasGeneratedPassword) ||
(prevProps.showNotifierToolbar !== this.props.showNotifierToolbar)
) {
this.props.resizeNotifier.notifyBannersChanged();
}
},

componentWillUnmount: function() {
document.removeEventListener('keydown', this._onKeyDown);
this._matrixClient.removeListener("accountData", this.onAccountData);
Expand Down Expand Up @@ -173,6 +184,7 @@ const LoggedInView = React.createClass({
},
onResized: (size) => {
window.localStorage.setItem("mx_lhs_size", '' + size);
this.props.resizeNotifier.notifyLeftHandleResized();
},
};
const resizer = new Resizer(
Expand Down Expand Up @@ -448,6 +460,7 @@ const LoggedInView = React.createClass({
disabled={this.props.middleDisabled}
collapsedRhs={this.props.collapsedRhs}
ConferenceHandler={this.props.ConferenceHandler}
resizeNotifier={this.props.resizeNotifier}
/>;
break;

Expand Down Expand Up @@ -489,7 +502,6 @@ const LoggedInView = React.createClass({
});

let topBar;
const isGuest = this.props.matrixClient.isGuest();
if (this.state.syncErrorData && this.state.syncErrorData.error.errcode === 'M_RESOURCE_LIMIT_EXCEEDED') {
topBar = <ServerLimitBar kind='hard'
adminContact={this.state.syncErrorData.error.data.admin_contact}
Expand All @@ -513,10 +525,7 @@ const LoggedInView = React.createClass({
topBar = <UpdateCheckBar {...this.props.checkingForUpdate} />;
} else if (this.state.userHasGeneratedPassword) {
topBar = <PasswordNagBar />;
} else if (
!isGuest && Notifier.supportsDesktopNotifications() &&
!Notifier.isEnabled() && !Notifier.isToolbarHidden()
) {
} else if (this.props.showNotifierToolbar) {
topBar = <MatrixToolbar />;
}

Expand All @@ -534,7 +543,7 @@ const LoggedInView = React.createClass({
<DragDropContext onDragEnd={this._onDragEnd}>
<div ref={this._setResizeContainerRef} className={bodyClasses}>
<LeftPanel
toolbarShown={!!topBar}
resizeNotifier={this.props.resizeNotifier}
collapsed={this.props.collapseLhs || false}
disabled={this.props.leftDisabled}
/>
Expand Down
3 changes: 3 additions & 0 deletions src/components/structures/MainSplit.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ export default class MainSplit extends React.Component {

_onResized(size) {
window.localStorage.setItem("mx_rhs_size", size);
if (this.props.resizeNotifier) {
this.props.resizeNotifier.notifyRightHandleResized();
}
}

_createResizer() {
Expand Down
19 changes: 17 additions & 2 deletions src/components/structures/MatrixChat.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import PlatformPeg from "../../PlatformPeg";
import SdkConfig from "../../SdkConfig";
import * as RoomListSorter from "../../RoomListSorter";
import dis from "../../dispatcher";
import Notifier from '../../Notifier';

import Modal from "../../Modal";
import Tinter from "../../Tinter";
Expand All @@ -48,6 +49,7 @@ import { _t, getCurrentLanguage } from '../../languageHandler';
import SettingsStore, {SettingLevel} from "../../settings/SettingsStore";
import { startAnyRegistrationFlow } from "../../Registration.js";
import { messageForSyncError } from '../../utils/ErrorUtils';
import ResizeNotifier from "../../utils/ResizeNotifier";
import TimelineExplosionDialog from "../views/dialogs/TimelineExplosionDialog";

const AutoDiscovery = Matrix.AutoDiscovery;
Expand Down Expand Up @@ -195,6 +197,8 @@ export default React.createClass({
hideToSRUsers: false,

syncError: null, // If the current syncing status is ERROR, the error object, otherwise null.
resizeNotifier: new ResizeNotifier(),
showNotifierToolbar: Notifier.shouldShowToolbar(),
};
return s;
},
Expand Down Expand Up @@ -317,6 +321,9 @@ export default React.createClass({
// N.B. we don't call the whole of setTheme() here as we may be
// racing with the theme CSS download finishing from index.js
Tinter.tint();

// For PersistentElement
this.state.resizeNotifier.on("middlePanelResized", this._dispatchTimelineResize);
},

componentDidMount: function() {
Expand Down Expand Up @@ -399,6 +406,7 @@ export default React.createClass({
dis.unregister(this.dispatcherRef);
window.removeEventListener("focus", this.onFocus);
window.removeEventListener('resize', this.handleResize);
this.state.resizeNotifier.removeListener("middlePanelResized", this._dispatchTimelineResize);
},

componentWillUpdate: function(props, state) {
Expand Down Expand Up @@ -639,8 +647,9 @@ export default React.createClass({
case 'view_invite':
showRoomInviteDialog(payload.roomId);
break;
case 'notifier_enabled':
this.forceUpdate();
case 'notifier_enabled': {
this.setState({showNotifierToolbar: Notifier.shouldShowToolbar()});
}
break;
case 'hide_left_panel':
this.setState({
Expand Down Expand Up @@ -1189,6 +1198,7 @@ export default React.createClass({
*/
_onLoggedIn: async function() {
this.setStateForNewView({view: VIEWS.LOGGED_IN});
this.setState({showNotifierToolbar: Notifier.shouldShowToolbar()});
if (this._is_registered) {
this._is_registered = false;

Expand Down Expand Up @@ -1696,9 +1706,14 @@ export default React.createClass({
dis.dispatch({ action: 'show_right_panel' });
}

this.state.resizeNotifier.notifyWindowResized();
this._windowWidth = window.innerWidth;
},

_dispatchTimelineResize() {
dis.dispatch({ action: 'timeline_resize' });
},

onRoomCreated: function(roomId) {
dis.dispatch({
action: "view_room",
Expand Down
42 changes: 28 additions & 14 deletions src/components/structures/MessagePanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import PropTypes from 'prop-types';
import classNames from 'classnames';
import shouldHideEvent from '../../shouldHideEvent';
import {wantsDateSeparator} from '../../DateUtils';
import dis from "../../dispatcher";
import sdk from '../../index';

import MatrixClientPeg from '../../MatrixClientPeg';
Expand Down Expand Up @@ -628,16 +627,29 @@ module.exports = React.createClass({
_onHeightChanged: function() {
const scrollPanel = this.refs.scrollPanel;
if (scrollPanel) {
scrollPanel.forceUpdate();
scrollPanel.checkScroll();
}
},

_onTypingVisible: function() {
_onTypingShown: function() {
const scrollPanel = this.refs.scrollPanel;
// this will make the timeline grow, so checkScroll
scrollPanel.checkScroll();
if (scrollPanel && scrollPanel.getScrollState().stuckAtBottom) {
// scroll down if at bottom
scrollPanel.preventShrinking();
}
},

_onTypingHidden: function() {
const scrollPanel = this.refs.scrollPanel;
if (scrollPanel) {
// as hiding the typing notifications doesn't
// update the scrollPanel, we tell it to apply
// the shrinking prevention once the typing notifs are hidden
scrollPanel.updatePreventShrinking();
// order is important here as checkScroll will scroll down to
// reveal added padding to balance the notifs disappearing.
scrollPanel.checkScroll();
scrollPanel.blockShrinking();
}
},

Expand All @@ -653,22 +665,18 @@ module.exports = React.createClass({
// update the min-height, so once the last
// person stops typing, no jumping occurs
if (isAtBottom && isTypingVisible) {
scrollPanel.blockShrinking();
scrollPanel.preventShrinking();
}
}
},

clearTimelineHeight: function() {
onTimelineReset: function() {
const scrollPanel = this.refs.scrollPanel;
if (scrollPanel) {
scrollPanel.clearBlockShrinking();
scrollPanel.clearPreventShrinking();
}
},

onResize: function() {
dis.dispatch({ action: 'timeline_resize' }, true);
},

render: function() {
const ScrollPanel = sdk.getComponent("structures.ScrollPanel");
const WhoIsTypingTile = sdk.getComponent("rooms.WhoIsTypingTile");
Expand All @@ -693,7 +701,12 @@ module.exports = React.createClass({

let whoIsTyping;
if (this.props.room) {
whoIsTyping = (<WhoIsTypingTile room={this.props.room} onVisible={this._onTypingVisible} ref="whoIsTyping" />);
whoIsTyping = (<WhoIsTypingTile
room={this.props.room}
onShown={this._onTypingShown}
onHidden={this._onTypingHidden}
ref="whoIsTyping" />
);
}

return (
Expand All @@ -703,7 +716,8 @@ module.exports = React.createClass({
onFillRequest={this.props.onFillRequest}
onUnfillRequest={this.props.onUnfillRequest}
style={style}
stickyBottom={this.props.stickyBottom}>
stickyBottom={this.props.stickyBottom}
resizeNotifier={this.props.resizeNotifier}>
{ topSpinner }
{ this._getEventTiles() }
{ whoIsTyping }
Expand Down
2 changes: 1 addition & 1 deletion src/components/structures/RightPanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ export default class RightPanel extends React.Component {
} else if (this.state.phase === RightPanel.Phase.NotificationPanel) {
panel = <NotificationPanel />;
} else if (this.state.phase === RightPanel.Phase.FilePanel) {
panel = <FilePanel roomId={this.props.roomId} />;
panel = <FilePanel roomId={this.props.roomId} resizeNotifier={this.props.resizeNotifier} />;
}

const classes = classNames("mx_RightPanel", "mx_fadable", {
Expand Down
1 change: 0 additions & 1 deletion src/components/structures/RoomDirectory.js
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,6 @@ module.exports = React.createClass({
onFillRequest={ this.onFillRequest }
stickyBottom={false}
startAtBottom={false}
onResize={function() {}}
>
{ scrollpanel_content }
</ScrollPanel>;
Expand Down
Loading

0 comments on commit a326c83

Please sign in to comment.