Support view_room's show_room_tile in the new room list

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
Michael Telatynski 2020-07-07 10:34:42 +01:00
parent 1259a8e1af
commit 63ec793fad
2 changed files with 57 additions and 3 deletions

View file

@ -40,6 +40,8 @@ import NotificationBadge from "./NotificationBadge";
import { ListNotificationState } from "../../../stores/notifications/ListNotificationState"; import { ListNotificationState } from "../../../stores/notifications/ListNotificationState";
import AccessibleTooltipButton from "../elements/AccessibleTooltipButton"; import AccessibleTooltipButton from "../elements/AccessibleTooltipButton";
import { Key } from "../../../Keyboard"; 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: 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 // 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<IProps, IState> { export default class RoomSublist2 extends React.Component<IProps, IState> {
private headerButton = createRef<HTMLDivElement>(); private headerButton = createRef<HTMLDivElement>();
private sublistRef = createRef<HTMLDivElement>(); private sublistRef = createRef<HTMLDivElement>();
private dispatcherRef: string;
constructor(props: IProps) { constructor(props: IProps) {
super(props); super(props);
@ -98,6 +101,7 @@ export default class RoomSublist2 extends React.Component<IProps, IState> {
isResizing: false, isResizing: false,
}; };
this.state.notificationState.setRooms(this.props.rooms); this.state.notificationState.setRooms(this.props.rooms);
this.dispatcherRef = defaultDispatcher.register(this.onAction);
} }
private get numTiles(): number { private get numTiles(): number {
@ -116,8 +120,29 @@ export default class RoomSublist2 extends React.Component<IProps, IState> {
public componentWillUnmount() { public componentWillUnmount() {
this.state.notificationState.destroy(); 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) => { private onAddRoom = (e) => {
e.stopPropagation(); e.stopPropagation();
if (this.props.onAddRoom) this.props.onAddRoom(); if (this.props.onAddRoom) this.props.onAddRoom();

View file

@ -17,7 +17,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
import React from "react"; import React, {createRef} from "react";
import { Room } from "matrix-js-sdk/src/models/room"; import { Room } from "matrix-js-sdk/src/models/room";
import classNames from "classnames"; import classNames from "classnames";
import { RovingTabIndexWrapper } from "../../../accessibility/RovingTabIndex"; import { RovingTabIndexWrapper } from "../../../accessibility/RovingTabIndex";
@ -49,6 +49,8 @@ import { TagSpecificNotificationState } from "../../../stores/notifications/TagS
import { INotificationState } from "../../../stores/notifications/INotificationState"; import { INotificationState } from "../../../stores/notifications/INotificationState";
import NotificationBadge from "./NotificationBadge"; import NotificationBadge from "./NotificationBadge";
import { NotificationColor } from "../../../stores/notifications/NotificationColor"; 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: 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 // TODO: Rename on launch: https://github.com/vector-im/riot-web/issues/14231
@ -119,6 +121,8 @@ const NotifOption: React.FC<INotifOptionProps> = ({active, onClick, iconClassNam
}; };
export default class RoomTile2 extends React.Component<IProps, IState> { export default class RoomTile2 extends React.Component<IProps, IState> {
private dispatcherRef: string;
private roomTileRef = createRef<HTMLDivElement>();
// TODO: a11y: https://github.com/vector-im/riot-web/issues/14180 // TODO: a11y: https://github.com/vector-im/riot-web/issues/14180
constructor(props: IProps) { constructor(props: IProps) {
@ -133,6 +137,7 @@ export default class RoomTile2 extends React.Component<IProps, IState> {
}; };
ActiveRoomObserver.addListener(this.props.room.roomId, this.onActiveRoomUpdate); ActiveRoomObserver.addListener(this.props.room.roomId, this.onActiveRoomUpdate);
this.dispatcherRef = defaultDispatcher.register(this.onAction);
} }
private get showContextMenu(): boolean { private get showContextMenu(): boolean {
@ -143,12 +148,37 @@ export default class RoomTile2 extends React.Component<IProps, IState> {
return !this.props.isMinimized && this.props.showMessagePreview; 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() { public componentWillUnmount() {
if (this.props.room) { if (this.props.room) {
ActiveRoomObserver.removeListener(this.props.room.roomId, this.onActiveRoomUpdate); 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 = () => { private onTileMouseEnter = () => {
this.setState({hover: true}); this.setState({hover: true});
}; };
@ -162,7 +192,6 @@ export default class RoomTile2 extends React.Component<IProps, IState> {
ev.stopPropagation(); ev.stopPropagation();
dis.dispatch({ dis.dispatch({
action: 'view_room', 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 show_room_tile: true, // make sure the room is visible in the list
room_id: this.props.room.roomId, room_id: this.props.room.roomId,
clear_search: (ev && (ev.key === Key.ENTER || ev.key === Key.SPACE)), clear_search: (ev && (ev.key === Key.ENTER || ev.key === Key.SPACE)),
@ -481,7 +510,7 @@ export default class RoomTile2 extends React.Component<IProps, IState> {
return ( return (
<React.Fragment> <React.Fragment>
<RovingTabIndexWrapper> <RovingTabIndexWrapper inputRef={this.roomTileRef}>
{({onFocus, isActive, ref}) => {({onFocus, isActive, ref}) =>
<AccessibleButton <AccessibleButton
onFocus={onFocus} onFocus={onFocus}