From 64237c9f4ecd44e1696e4d3a5cc3db51f9408ec2 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 7 Jul 2020 00:11:32 +0100 Subject: [PATCH 1/4] Apply scroll margins to RoomTile so that they don't scroll under the "sticky" headers Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- res/css/views/rooms/_RoomTile2.scss | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/res/css/views/rooms/_RoomTile2.scss b/res/css/views/rooms/_RoomTile2.scss index 7b606ab947..23cecff477 100644 --- a/res/css/views/rooms/_RoomTile2.scss +++ b/res/css/views/rooms/_RoomTile2.scss @@ -21,6 +21,10 @@ limitations under the License. margin-bottom: 4px; padding: 4px; + // allow scrollIntoView to ignore the sticky headers, must match combined height of .mx_RoomSublist2_headerContainer + scroll-margin-top: 32px; + scroll-margin-bottom: 32px; + // The tile is also a flexbox row itself display: flex; @@ -164,6 +168,11 @@ limitations under the License. } } +// do not apply scroll-margin-bottom to the sublist which will not have a sticky header below it +.mx_RoomSublist2:last-child .mx_RoomTile2 { + scroll-margin-bottom: 0; +} + // We use these both in context menus and the room tiles .mx_RoomTile2_iconBell::before { mask-image: url('$(res)/img/feather-customised/bell.svg'); From 63ec793fadda6bfa09d5fa019850d35102d79b79 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 7 Jul 2020 10:34:42 +0100 Subject: [PATCH 2/4] Support view_room's show_room_tile in the new room list Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/rooms/RoomSublist2.tsx | 25 +++++++++++++++ src/components/views/rooms/RoomTile2.tsx | 35 +++++++++++++++++++-- 2 files changed, 57 insertions(+), 3 deletions(-) diff --git a/src/components/views/rooms/RoomSublist2.tsx b/src/components/views/rooms/RoomSublist2.tsx index 9a36ea00e9..5dce3f769f 100644 --- a/src/components/views/rooms/RoomSublist2.tsx +++ b/src/components/views/rooms/RoomSublist2.tsx @@ -40,6 +40,8 @@ import NotificationBadge from "./NotificationBadge"; import { ListNotificationState } from "../../../stores/notifications/ListNotificationState"; import AccessibleTooltipButton from "../elements/AccessibleTooltipButton"; import { Key } from "../../../Keyboard"; +import defaultDispatcher from "../../../dispatcher/dispatcher"; +import {ActionPayload} from "../../../dispatcher/payloads"; // TODO: Remove banner on launch: https://github.com/vector-im/riot-web/issues/14231 // TODO: Rename on launch: https://github.com/vector-im/riot-web/issues/14231 @@ -88,6 +90,7 @@ interface IState { export default class RoomSublist2 extends React.Component { private headerButton = createRef(); private sublistRef = createRef(); + private dispatcherRef: string; constructor(props: IProps) { super(props); @@ -98,6 +101,7 @@ export default class RoomSublist2 extends React.Component { isResizing: false, }; this.state.notificationState.setRooms(this.props.rooms); + this.dispatcherRef = defaultDispatcher.register(this.onAction); } private get numTiles(): number { @@ -116,8 +120,29 @@ export default class RoomSublist2 extends React.Component { public componentWillUnmount() { this.state.notificationState.destroy(); + defaultDispatcher.unregister(this.dispatcherRef); } + private onAction = (payload: ActionPayload) => { + if (payload.action === "view_room" && payload.show_room_tile && this.props.rooms) { + // XXX: we have to do this a tick later because we have incorrect intermediate props during a room change + // where we lose the room we are changing from temporarily and then it comes back in an update right after. + setImmediate(() => { + const isCollapsed = this.props.layout.isCollapsed; + const roomIndex = this.props.rooms.findIndex((r) => r.roomId === payload.room_id); + + if (isCollapsed && roomIndex > -1) { + this.toggleCollapsed(); + } + // extend the visible section to include the room + if (roomIndex >= this.numVisibleTiles) { + this.props.layout.visibleTiles = this.props.layout.tilesWithPadding(roomIndex + 1, MAX_PADDING_HEIGHT); + this.forceUpdate(); // because the layout doesn't trigger a re-render + } + }); + } + }; + private onAddRoom = (e) => { e.stopPropagation(); if (this.props.onAddRoom) this.props.onAddRoom(); diff --git a/src/components/views/rooms/RoomTile2.tsx b/src/components/views/rooms/RoomTile2.tsx index 8ee838fbba..21901026a5 100644 --- a/src/components/views/rooms/RoomTile2.tsx +++ b/src/components/views/rooms/RoomTile2.tsx @@ -17,7 +17,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import React from "react"; +import React, {createRef} from "react"; import { Room } from "matrix-js-sdk/src/models/room"; import classNames from "classnames"; import { RovingTabIndexWrapper } from "../../../accessibility/RovingTabIndex"; @@ -49,6 +49,8 @@ import { TagSpecificNotificationState } from "../../../stores/notifications/TagS import { INotificationState } from "../../../stores/notifications/INotificationState"; import NotificationBadge from "./NotificationBadge"; import { NotificationColor } from "../../../stores/notifications/NotificationColor"; +import defaultDispatcher from "../../../dispatcher/dispatcher"; +import {ActionPayload} from "../../../dispatcher/payloads"; // TODO: Remove banner on launch: https://github.com/vector-im/riot-web/issues/14231 // TODO: Rename on launch: https://github.com/vector-im/riot-web/issues/14231 @@ -119,6 +121,8 @@ const NotifOption: React.FC = ({active, onClick, iconClassNam }; export default class RoomTile2 extends React.Component { + private dispatcherRef: string; + private roomTileRef = createRef(); // TODO: a11y: https://github.com/vector-im/riot-web/issues/14180 constructor(props: IProps) { @@ -133,6 +137,7 @@ export default class RoomTile2 extends React.Component { }; ActiveRoomObserver.addListener(this.props.room.roomId, this.onActiveRoomUpdate); + this.dispatcherRef = defaultDispatcher.register(this.onAction); } private get showContextMenu(): boolean { @@ -143,12 +148,37 @@ export default class RoomTile2 extends React.Component { return !this.props.isMinimized && this.props.showMessagePreview; } + public componentDidMount() { + // when we're first rendered (or our sublist is expanded) make sure we are visible if we're active + if (this.state.selected) { + this.scrollIntoView(); + } + } + public componentWillUnmount() { if (this.props.room) { ActiveRoomObserver.removeListener(this.props.room.roomId, this.onActiveRoomUpdate); } + defaultDispatcher.unregister(this.dispatcherRef); } + private onAction = (payload: ActionPayload) => { + if (payload.action === "view_room" && payload.room_id === this.props.room.roomId && payload.show_room_tile) { + setImmediate(() => { + this.scrollIntoView(); + }); + } + }; + + private scrollIntoView = () => { + console.log("DEBUG scrollIntoView", this.roomTileRef.current); + if (!this.roomTileRef.current) return; + this.roomTileRef.current.scrollIntoView({ + block: "nearest", + behavior: "auto", + }); + }; + private onTileMouseEnter = () => { this.setState({hover: true}); }; @@ -162,7 +192,6 @@ export default class RoomTile2 extends React.Component { ev.stopPropagation(); dis.dispatch({ action: 'view_room', - // TODO: Support show_room_tile in new room list: https://github.com/vector-im/riot-web/issues/14233 show_room_tile: true, // make sure the room is visible in the list room_id: this.props.room.roomId, clear_search: (ev && (ev.key === Key.ENTER || ev.key === Key.SPACE)), @@ -481,7 +510,7 @@ export default class RoomTile2 extends React.Component { return ( - + {({onFocus, isActive, ref}) => Date: Tue, 7 Jul 2020 10:35:16 +0100 Subject: [PATCH 3/4] update comment Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/rooms/RoomSublist2.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/rooms/RoomSublist2.tsx b/src/components/views/rooms/RoomSublist2.tsx index 5dce3f769f..4dc2097421 100644 --- a/src/components/views/rooms/RoomSublist2.tsx +++ b/src/components/views/rooms/RoomSublist2.tsx @@ -134,7 +134,7 @@ export default class RoomSublist2 extends React.Component { if (isCollapsed && roomIndex > -1) { this.toggleCollapsed(); } - // extend the visible section to include the room + // extend the visible section to include the room if it is entirely invisible if (roomIndex >= this.numVisibleTiles) { this.props.layout.visibleTiles = this.props.layout.tilesWithPadding(roomIndex + 1, MAX_PADDING_HEIGHT); this.forceUpdate(); // because the layout doesn't trigger a re-render From ec54d509e52e225e47406b3ed52085a00c3f0d5c Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 8 Jul 2020 13:24:40 +0100 Subject: [PATCH 4/4] remove stale debug log Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/rooms/RoomTile2.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/views/rooms/RoomTile2.tsx b/src/components/views/rooms/RoomTile2.tsx index 90edbfb895..67d7ae34ba 100644 --- a/src/components/views/rooms/RoomTile2.tsx +++ b/src/components/views/rooms/RoomTile2.tsx @@ -170,7 +170,6 @@ export default class RoomTile2 extends React.Component { }; private scrollIntoView = () => { - console.log("DEBUG scrollIntoView", this.roomTileRef.current); if (!this.roomTileRef.current) return; this.roomTileRef.current.scrollIntoView({ block: "nearest",