mirror of https://github.com/vector-im/riot-web
Merge pull request #4908 from matrix-org/t3chguy/room-list/12345
New room list view_room show_room_tile supportpull/21833/head
commit
5d23e4216e
|
@ -21,6 +21,10 @@ limitations under the License.
|
||||||
margin-bottom: 4px;
|
margin-bottom: 4px;
|
||||||
padding: 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
|
// The tile is also a flexbox row itself
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
|
@ -165,6 +169,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
|
// We use these both in context menus and the room tiles
|
||||||
.mx_RoomTile2_iconBell::before {
|
.mx_RoomTile2_iconBell::before {
|
||||||
mask-image: url('$(res)/img/feather-customised/bell.svg');
|
mask-image: url('$(res)/img/feather-customised/bell.svg');
|
||||||
|
|
|
@ -42,6 +42,8 @@ import { ListNotificationState } from "../../../stores/notifications/ListNotific
|
||||||
import AccessibleTooltipButton from "../elements/AccessibleTooltipButton";
|
import AccessibleTooltipButton from "../elements/AccessibleTooltipButton";
|
||||||
import { Key } from "../../../Keyboard";
|
import { Key } from "../../../Keyboard";
|
||||||
import StyledCheckbox from "../elements/StyledCheckbox";
|
import StyledCheckbox from "../elements/StyledCheckbox";
|
||||||
|
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
|
||||||
|
@ -90,6 +92,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);
|
||||||
|
@ -100,6 +103,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 {
|
||||||
|
@ -118,8 +122,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 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
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private onAddRoom = (e) => {
|
private onAddRoom = (e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
if (this.props.onAddRoom) this.props.onAddRoom();
|
if (this.props.onAddRoom) this.props.onAddRoom();
|
||||||
|
|
|
@ -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";
|
||||||
|
@ -51,6 +51,8 @@ import { INotificationState } from "../../../stores/notifications/INotificationS
|
||||||
import NotificationBadge from "./NotificationBadge";
|
import NotificationBadge from "./NotificationBadge";
|
||||||
import { NotificationColor } from "../../../stores/notifications/NotificationColor";
|
import { NotificationColor } from "../../../stores/notifications/NotificationColor";
|
||||||
import { Volume } from "../../../RoomNotifsTypes";
|
import { Volume } from "../../../RoomNotifsTypes";
|
||||||
|
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,10 @@ 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
|
||||||
|
|
||||||
constructor(props: IProps) {
|
constructor(props: IProps) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
|
@ -131,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 {
|
||||||
|
@ -141,12 +148,36 @@ 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 = () => {
|
||||||
|
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});
|
||||||
};
|
};
|
||||||
|
@ -160,7 +191,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)),
|
||||||
|
@ -478,7 +508,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}
|
||||||
|
|
Loading…
Reference in New Issue