Move sublist auto expand to out from layouts
Co-authored-by: Travis Ralston <travpc@gmail.com>pull/21833/head
parent
096cd482f1
commit
ade89ab4e9
|
@ -191,17 +191,6 @@ export default class RoomList2 extends React.Component<IProps, IState> {
|
||||||
show_room_tile: true, // to make sure the room gets scrolled into view
|
show_room_tile: true, // to make sure the room gets scrolled into view
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else if (payload.action === Action.StartRoomFilter) {
|
|
||||||
this.state.layouts.forEach(x => {
|
|
||||||
x.saveCollapsedState();
|
|
||||||
x.isCollapsed = false;
|
|
||||||
});
|
|
||||||
this.forceUpdate();
|
|
||||||
} else if (payload.action === Action.StopRoomFilter) {
|
|
||||||
this.state.layouts.forEach(x => {
|
|
||||||
x.restoreCollapsedState();
|
|
||||||
});
|
|
||||||
this.forceUpdate();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -304,6 +293,7 @@ export default class RoomList2 extends React.Component<IProps, IState> {
|
||||||
isMinimized={this.props.isMinimized}
|
isMinimized={this.props.isMinimized}
|
||||||
onResize={this.props.onResize}
|
onResize={this.props.onResize}
|
||||||
extraBadTilesThatShouldntExist={extraTiles}
|
extraBadTilesThatShouldntExist={extraTiles}
|
||||||
|
isFiltered={!!this.searchFilter.search}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,7 @@ import { Direction } from "re-resizable/lib/resizer";
|
||||||
import { polyfillTouchEvent } from "../../../@types/polyfill";
|
import { polyfillTouchEvent } from "../../../@types/polyfill";
|
||||||
import { RoomNotificationStateStore } from "../../../stores/notifications/RoomNotificationStateStore";
|
import { RoomNotificationStateStore } from "../../../stores/notifications/RoomNotificationStateStore";
|
||||||
import RoomListLayoutStore from "../../../stores/room-list/RoomListLayoutStore";
|
import RoomListLayoutStore from "../../../stores/room-list/RoomListLayoutStore";
|
||||||
|
import { Action } from "../../../dispatcher/actions";
|
||||||
|
|
||||||
// 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
|
||||||
|
@ -78,6 +79,7 @@ interface IProps {
|
||||||
isMinimized: boolean;
|
isMinimized: boolean;
|
||||||
tagId: TagID;
|
tagId: TagID;
|
||||||
onResize: () => void;
|
onResize: () => void;
|
||||||
|
isFiltered: boolean;
|
||||||
|
|
||||||
// TODO: Don't use this. It's for community invites, and community invites shouldn't be here.
|
// TODO: Don't use this. It's for community invites, and community invites shouldn't be here.
|
||||||
// You should feel bad if you use this.
|
// You should feel bad if you use this.
|
||||||
|
@ -92,6 +94,7 @@ interface IState {
|
||||||
notificationState: ListNotificationState;
|
notificationState: ListNotificationState;
|
||||||
contextMenuPosition: PartialDOMRect;
|
contextMenuPosition: PartialDOMRect;
|
||||||
isResizing: boolean;
|
isResizing: boolean;
|
||||||
|
isExpanded: boolean; // used for the for expand of the sublist when the room list is being filtered
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class RoomSublist2 extends React.Component<IProps, IState> {
|
export default class RoomSublist2 extends React.Component<IProps, IState> {
|
||||||
|
@ -109,6 +112,7 @@ export default class RoomSublist2 extends React.Component<IProps, IState> {
|
||||||
notificationState: RoomNotificationStateStore.instance.getListState(this.props.tagId),
|
notificationState: RoomNotificationStateStore.instance.getListState(this.props.tagId),
|
||||||
contextMenuPosition: null,
|
contextMenuPosition: null,
|
||||||
isResizing: false,
|
isResizing: false,
|
||||||
|
isExpanded: this.props.isFiltered ? this.props.isFiltered : !this.layout.isCollapsed
|
||||||
};
|
};
|
||||||
this.state.notificationState.setRooms(this.props.rooms);
|
this.state.notificationState.setRooms(this.props.rooms);
|
||||||
this.dispatcherRef = defaultDispatcher.register(this.onAction);
|
this.dispatcherRef = defaultDispatcher.register(this.onAction);
|
||||||
|
@ -123,8 +127,15 @@ export default class RoomSublist2 extends React.Component<IProps, IState> {
|
||||||
return Math.min(nVisible, this.numTiles);
|
return Math.min(nVisible, this.numTiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
public componentDidUpdate() {
|
public componentDidUpdate(prevProps: Readonly<IProps>) {
|
||||||
this.state.notificationState.setRooms(this.props.rooms);
|
this.state.notificationState.setRooms(this.props.rooms);
|
||||||
|
if (prevProps.isFiltered !== this.props.isFiltered) {
|
||||||
|
if (this.props.isFiltered) {
|
||||||
|
this.setState({isExpanded: true});
|
||||||
|
} else {
|
||||||
|
this.setState({isExpanded: !this.layout.isCollapsed});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public componentWillUnmount() {
|
public componentWillUnmount() {
|
||||||
|
@ -137,10 +148,9 @@ export default class RoomSublist2 extends React.Component<IProps, IState> {
|
||||||
// XXX: we have to do this a tick later because we have incorrect intermediate props during a room change
|
// 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.
|
// where we lose the room we are changing from temporarily and then it comes back in an update right after.
|
||||||
setImmediate(() => {
|
setImmediate(() => {
|
||||||
const isCollapsed = this.layout.isCollapsed;
|
|
||||||
const roomIndex = this.props.rooms.findIndex((r) => r.roomId === payload.room_id);
|
const roomIndex = this.props.rooms.findIndex((r) => r.roomId === payload.room_id);
|
||||||
|
|
||||||
if (isCollapsed && roomIndex > -1) {
|
if (!this.state.isExpanded && roomIndex > -1) {
|
||||||
this.toggleCollapsed();
|
this.toggleCollapsed();
|
||||||
}
|
}
|
||||||
// extend the visible section to include the room if it is entirely invisible
|
// extend the visible section to include the room if it is entirely invisible
|
||||||
|
@ -295,24 +305,23 @@ export default class RoomSublist2 extends React.Component<IProps, IState> {
|
||||||
};
|
};
|
||||||
|
|
||||||
private toggleCollapsed = () => {
|
private toggleCollapsed = () => {
|
||||||
this.layout.isCollapsed = !this.layout.isCollapsed;
|
this.layout.isCollapsed = this.state.isExpanded;
|
||||||
this.forceUpdate(); // because the layout doesn't trigger an update
|
this.setState({isExpanded: !this.layout.isCollapsed});
|
||||||
setImmediate(() => this.props.onResize()); // needs to happen when the DOM is updated
|
setImmediate(() => this.props.onResize()); // needs to happen when the DOM is updated
|
||||||
};
|
};
|
||||||
|
|
||||||
private onHeaderKeyDown = (ev: React.KeyboardEvent) => {
|
private onHeaderKeyDown = (ev: React.KeyboardEvent) => {
|
||||||
const isCollapsed = this.layout && this.layout.isCollapsed;
|
|
||||||
switch (ev.key) {
|
switch (ev.key) {
|
||||||
case Key.ARROW_LEFT:
|
case Key.ARROW_LEFT:
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
if (!isCollapsed) {
|
if (this.state.isExpanded) {
|
||||||
// On ARROW_LEFT collapse the room sublist if it isn't already
|
// On ARROW_LEFT collapse the room sublist if it isn't already
|
||||||
this.toggleCollapsed();
|
this.toggleCollapsed();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Key.ARROW_RIGHT: {
|
case Key.ARROW_RIGHT: {
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
if (isCollapsed) {
|
if (!this.state.isExpanded) {
|
||||||
// On ARROW_RIGHT expand the room sublist if it isn't already
|
// On ARROW_RIGHT expand the room sublist if it isn't already
|
||||||
this.toggleCollapsed();
|
this.toggleCollapsed();
|
||||||
} else if (this.sublistRef.current) {
|
} else if (this.sublistRef.current) {
|
||||||
|
@ -341,7 +350,7 @@ export default class RoomSublist2 extends React.Component<IProps, IState> {
|
||||||
};
|
};
|
||||||
|
|
||||||
private renderVisibleTiles(): React.ReactElement[] {
|
private renderVisibleTiles(): React.ReactElement[] {
|
||||||
if (this.layout && this.layout.isCollapsed) {
|
if (!this.state.isExpanded) {
|
||||||
// don't waste time on rendering
|
// don't waste time on rendering
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
@ -498,7 +507,7 @@ export default class RoomSublist2 extends React.Component<IProps, IState> {
|
||||||
|
|
||||||
const collapseClasses = classNames({
|
const collapseClasses = classNames({
|
||||||
'mx_RoomSublist2_collapseBtn': true,
|
'mx_RoomSublist2_collapseBtn': true,
|
||||||
'mx_RoomSublist2_collapseBtn_collapsed': this.layout && this.layout.isCollapsed,
|
'mx_RoomSublist2_collapseBtn_collapsed': !this.state.isExpanded,
|
||||||
});
|
});
|
||||||
|
|
||||||
const classes = classNames({
|
const classes = classNames({
|
||||||
|
@ -526,7 +535,7 @@ export default class RoomSublist2 extends React.Component<IProps, IState> {
|
||||||
tabIndex={tabIndex}
|
tabIndex={tabIndex}
|
||||||
className="mx_RoomSublist2_headerText"
|
className="mx_RoomSublist2_headerText"
|
||||||
role="treeitem"
|
role="treeitem"
|
||||||
aria-expanded={!this.layout.isCollapsed}
|
aria-expanded={this.state.isExpanded}
|
||||||
aria-level={1}
|
aria-level={1}
|
||||||
onClick={this.onHeaderClick}
|
onClick={this.onHeaderClick}
|
||||||
onContextMenu={this.onContextMenu}
|
onContextMenu={this.onContextMenu}
|
||||||
|
|
|
@ -26,14 +26,12 @@ interface ISerializedListLayout {
|
||||||
numTiles: number;
|
numTiles: number;
|
||||||
showPreviews: boolean;
|
showPreviews: boolean;
|
||||||
collapsed: boolean;
|
collapsed: boolean;
|
||||||
savedCollapsed: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ListLayout {
|
export class ListLayout {
|
||||||
private _n = 0;
|
private _n = 0;
|
||||||
private _previews = false;
|
private _previews = false;
|
||||||
private _collapsed = false;
|
private _collapsed = false;
|
||||||
private _savedCollapsed = false;
|
|
||||||
|
|
||||||
constructor(public readonly tagId: TagID) {
|
constructor(public readonly tagId: TagID) {
|
||||||
const serialized = localStorage.getItem(this.key);
|
const serialized = localStorage.getItem(this.key);
|
||||||
|
@ -43,7 +41,6 @@ export class ListLayout {
|
||||||
this._n = parsed.numTiles;
|
this._n = parsed.numTiles;
|
||||||
this._previews = parsed.showPreviews;
|
this._previews = parsed.showPreviews;
|
||||||
this._collapsed = parsed.collapsed;
|
this._collapsed = parsed.collapsed;
|
||||||
this._savedCollapsed = parsed.savedCollapsed;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,20 +133,11 @@ export class ListLayout {
|
||||||
localStorage.setItem(this.key, JSON.stringify(this.serialize()));
|
localStorage.setItem(this.key, JSON.stringify(this.serialize()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public saveCollapsedState() {
|
|
||||||
this._savedCollapsed = this.isCollapsed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public restoreCollapsedState() {
|
|
||||||
this.isCollapsed = this._savedCollapsed;
|
|
||||||
}
|
|
||||||
|
|
||||||
private serialize(): ISerializedListLayout {
|
private serialize(): ISerializedListLayout {
|
||||||
return {
|
return {
|
||||||
numTiles: this.visibleTiles,
|
numTiles: this.visibleTiles,
|
||||||
showPreviews: this.showPreviews,
|
showPreviews: this.showPreviews,
|
||||||
collapsed: this.isCollapsed,
|
collapsed: this.isCollapsed,
|
||||||
savedCollapsed: this._savedCollapsed,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue