Split the left panel into new and old for new room list designs

Though we consider the "room list" to mean the RoomList component specifically, the room list is actually the entire left panel as far as the user is concerned. 

The new proposed designs for the room list modify the whole left panel, so we had might as well break it into new and old now instead of later. This "new" left panel is a bare-bones implementation and meant to only provide the absolute basic feature set to function for those who enable the experimental room list, for whatever reason. This is not intended to be a final implementation, or even remotely close to what it could be. An example of this is the lack of breadcrumbs. Given they are likely to change, they are excluded from this temporary skeleton completely.

This also includes a purple/pink bar between the tag panel and left panel. This is so we can, if needed, differentiate between people who made the mistake of turning on the experimental room list while the overall aesthetic makes it indistinguishable. Once the designs are moderately approved, we can (and definitely should) remove the hideous indicator.
This commit is contained in:
Travis Ralston 2020-06-02 19:26:07 -06:00
parent 1f1f613777
commit 6d96d66c03
4 changed files with 187 additions and 28 deletions

View file

@ -22,6 +22,14 @@ limitations under the License.
flex: 0 0 auto;
}
// TODO: Remove temporary indicator of new room list implementation.
// This border is meant to visually distinguish between the two components when the
// user has turned on the new room list implementation, at least until the designs
// themselves give it away.
.mx_LeftPanel2 .mx_LeftPanel {
border-left: 5px #e26dff solid;
}
.mx_LeftPanel_container.collapsed {
min-width: unset;
/* Collapsed LeftPanel 50px */

View file

@ -26,7 +26,6 @@ import * as VectorConferenceHandler from '../../VectorConferenceHandler';
import SettingsStore from '../../settings/SettingsStore';
import {_t} from "../../languageHandler";
import Analytics from "../../Analytics";
import RoomList2 from "../views/rooms/RoomList2";
import {Action} from "../../dispatcher/actions";
@ -275,19 +274,7 @@ const LeftPanel = createReactClass({
breadcrumbs = (<RoomBreadcrumbs collapsed={this.props.collapsed} />);
}
let roomList = null;
if (SettingsStore.isFeatureEnabled("feature_new_room_list")) {
roomList = <RoomList2
onKeyDown={this._onKeyDown}
resizeNotifier={this.props.resizeNotifier}
collapsed={this.props.collapsed}
searchFilter={this.state.searchFilter}
ref={this.collectRoomList}
onFocus={this._onFocus}
onBlur={this._onBlur}
/>;
} else {
roomList = <RoomList
const roomList = <RoomList
onKeyDown={this._onKeyDown}
onFocus={this._onFocus}
onBlur={this._onBlur}
@ -296,7 +283,6 @@ const LeftPanel = createReactClass({
collapsed={this.props.collapsed}
searchFilter={this.state.searchFilter}
ConferenceHandler={VectorConferenceHandler} />;
}
return (
<div className={containerClasses}>

View file

@ -0,0 +1,154 @@
/*
Copyright 2020 The Matrix.org Foundation C.I.C.
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.
*/
import * as React from "react";
import TagPanel from "./TagPanel";
import classNames from "classnames";
import dis from "../../dispatcher/dispatcher";
import AccessibleButton from "../views/elements/AccessibleButton";
import { _t } from "../../languageHandler";
import SearchBox from "./SearchBox";
import RoomList2 from "../views/rooms/RoomList2";
import TopLeftMenuButton from "./TopLeftMenuButton";
import { Action } from "../../dispatcher/actions";
/*******************************************************************
* CAUTION *
*******************************************************************
* This is a work in progress implementation and isn't complete or *
* even useful as a component. Please avoid using it until this *
* warning disappears. *
*******************************************************************/
interface IProps {
// TODO: Support collapsed state
}
interface IState {
searchExpanded: boolean;
searchFilter: string; // TODO: Move search into room list?
}
export default class LeftPanel2 extends React.Component<IProps, IState> {
// TODO: Properly support TagPanel
// TODO: Properly support searching/filtering
// TODO: Properly support breadcrumbs
// TODO: Properly support TopLeftMenu (User Settings)
// TODO: a11y
// TODO: actually make this useful in general (match design proposals)
// TODO: Fadable support (is this still needed?)
constructor(props: IProps) {
super(props);
this.state = {
searchExpanded: false,
searchFilter: "",
};
}
private onSearch = (term: string): void => {
this.setState({searchFilter: term});
};
private onSearchCleared = (source: string): void => {
if (source === "keyboard") {
dis.fire(Action.FocusComposer);
}
this.setState({searchExpanded: false});
}
private onSearchFocus = (): void => {
this.setState({searchExpanded: true});
};
private onSearchBlur = (event: FocusEvent): void => {
const target = event.target as HTMLInputElement;
if (target.value.length === 0) {
this.setState({searchExpanded: false});
}
}
public render(): React.ReactNode {
const tagPanel = (
<div className="mx_LeftPanel_tagPanelContainer">
<TagPanel/>
</div>
);
const exploreButton = (
<div
className={classNames("mx_LeftPanel_explore", {"mx_LeftPanel_explore_hidden": this.state.searchExpanded})}>
<AccessibleButton onClick={() => dis.dispatch({action: 'view_room_directory'})}>
{_t("Explore")}
</AccessibleButton>
</div>
);
const searchBox = (<SearchBox
className="mx_LeftPanel_filterRooms"
enableRoomSearchFocus={true}
blurredPlaceholder={_t('Filter')}
placeholder={_t('Filter rooms…')}
onKeyDown={() => {/*TODO*/}}
onSearch={this.onSearch}
onCleared={this.onSearchCleared}
onFocus={this.onSearchFocus}
onBlur={this.onSearchBlur}
collapsed={false}/>); // TODO: Collapsed support
// TODO: Improve props for RoomList2
const roomList = <RoomList2
onKeyDown={() => {/*TODO*/}}
resizeNotifier={null}
collapsed={false}
searchFilter={this.state.searchFilter}
onFocus={() => {/*TODO*/}}
onBlur={() => {/*TODO*/}}
/>;
// TODO: Breadcrumbs
// TODO: Conference handling / calls
const containerClasses = classNames({
"mx_LeftPanel_container": true,
"mx_fadable": true,
"collapsed": false, // TODO: Collapsed support
"mx_LeftPanel_container_hasTagPanel": true, // TODO: TagPanel support
"mx_fadable_faded": false,
"mx_LeftPanel2": true, // TODO: Remove flag when RoomList2 ships (used as an indicator)
});
return (
<div className={containerClasses}>
{tagPanel}
<aside className="mx_LeftPanel dark-panel">
<TopLeftMenuButton collapsed={false}/>
<div
className="mx_LeftPanel_exploreAndFilterRow"
onKeyDown={() => {/*TODO*/}}
onFocus={() => {/*TODO*/}}
onBlur={() => {/*TODO*/}}
>
{exploreButton}
{searchBox}
</div>
{roomList}
</aside>
</div>
);
}
}

View file

@ -52,6 +52,7 @@ import {
hideToast as hideServerLimitToast
} from "../../toasts/ServerLimitToast";
import { Action } from "../../dispatcher/actions";
import LeftPanel2 from "./LeftPanel2";
// We need to fetch each pinned message individually (if we don't already have it)
// so each pinned message may trigger a request. Limit the number per room for sanity.
@ -656,6 +657,20 @@ class LoggedInView extends React.PureComponent<IProps, IState> {
bodyClasses += ' mx_MatrixChat_useCompactLayout';
}
let leftPanel = (
<LeftPanel
resizeNotifier={this.props.resizeNotifier}
collapsed={this.props.collapseLhs || false}
disabled={this.props.leftDisabled}
/>
);
if (SettingsStore.isFeatureEnabled("feature_new_room_list")) {
// TODO: Supply props like collapsed and disabled to LeftPanel2
leftPanel = (
<LeftPanel2 />
);
}
return (
<MatrixClientContext.Provider value={this._matrixClient}>
<div
@ -669,11 +684,7 @@ class LoggedInView extends React.PureComponent<IProps, IState> {
<ToastContainer />
<DragDropContext onDragEnd={this._onDragEnd}>
<div ref={this._resizeContainer} className={bodyClasses}>
<LeftPanel
resizeNotifier={this.props.resizeNotifier}
collapsed={this.props.collapseLhs || false}
disabled={this.props.leftDisabled}
/>
{ leftPanel }
<ResizeHandle />
{ pageElement }
</div>