2020-06-03 04:26:07 +03:00
|
|
|
/*
|
|
|
|
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";
|
2020-06-05 01:34:04 +03:00
|
|
|
import { MatrixClientPeg } from "../../MatrixClientPeg";
|
|
|
|
import BaseAvatar from '../views/avatars/BaseAvatar';
|
|
|
|
import RoomBreadcrumbs from "../views/rooms/RoomBreadcrumbs";
|
2020-06-03 04:26:07 +03:00
|
|
|
|
|
|
|
/*******************************************************************
|
|
|
|
* 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});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-05 01:34:04 +03:00
|
|
|
private renderHeader(): React.ReactNode {
|
2020-06-05 23:08:20 +03:00
|
|
|
// TODO: Update when profile info changes
|
2020-06-05 01:34:04 +03:00
|
|
|
// TODO: Presence
|
|
|
|
// TODO: Breadcrumbs toggle
|
|
|
|
// TODO: Menu button
|
|
|
|
const avatarSize = 32;
|
2020-06-05 23:08:20 +03:00
|
|
|
// TODO: Don't do this profile lookup in render()
|
|
|
|
const client = MatrixClientPeg.get();
|
|
|
|
let displayName = client.getUserId();
|
|
|
|
let avatarUrl: string = null;
|
|
|
|
const myUser = client.getUser(client.getUserId());
|
|
|
|
if (myUser) {
|
|
|
|
displayName = myUser.rawDisplayName;
|
|
|
|
avatarUrl = myUser.avatarUrl;
|
|
|
|
}
|
2020-06-05 01:34:04 +03:00
|
|
|
return (
|
|
|
|
<div className="mx_LeftPanel2_userHeader">
|
|
|
|
<div className="mx_LeftPanel2_headerRow">
|
|
|
|
<span className="mx_LeftPanel2_userAvatarContainer">
|
|
|
|
<BaseAvatar
|
|
|
|
idName={MatrixClientPeg.get().getUserId()}
|
2020-06-05 23:08:20 +03:00
|
|
|
name={displayName}
|
|
|
|
url={avatarUrl}
|
2020-06-05 01:34:04 +03:00
|
|
|
width={avatarSize}
|
|
|
|
height={avatarSize}
|
|
|
|
resizeMethod="crop"
|
|
|
|
className="mx_LeftPanel2_userAvatar"
|
|
|
|
/>
|
|
|
|
</span>
|
2020-06-05 23:08:20 +03:00
|
|
|
<span className="mx_LeftPanel2_userName">{displayName}</span>
|
2020-06-05 01:34:04 +03:00
|
|
|
</div>
|
|
|
|
<div className="mx_LeftPanel2_headerRow mx_LeftPanel2_breadcrumbsContainer">
|
|
|
|
<RoomBreadcrumbs />
|
|
|
|
</div>
|
2020-06-03 04:26:07 +03:00
|
|
|
</div>
|
|
|
|
);
|
2020-06-05 01:34:04 +03:00
|
|
|
}
|
2020-06-03 04:26:07 +03:00
|
|
|
|
2020-06-05 01:34:04 +03:00
|
|
|
public render(): React.ReactNode {
|
|
|
|
const tagPanel = (
|
|
|
|
<div className="mx_LeftPanel2_tagPanelContainer">
|
|
|
|
<TagPanel/>
|
2020-06-03 04:26:07 +03:00
|
|
|
</div>
|
|
|
|
);
|
|
|
|
|
|
|
|
const searchBox = (<SearchBox
|
2020-06-05 01:34:04 +03:00
|
|
|
className="mx_LeftPanel2_TODO_filterRooms"
|
2020-06-03 04:26:07 +03:00
|
|
|
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({
|
2020-06-05 01:34:04 +03:00
|
|
|
"mx_LeftPanel2": true,
|
2020-06-03 04:26:07 +03:00
|
|
|
});
|
|
|
|
|
|
|
|
return (
|
|
|
|
<div className={containerClasses}>
|
|
|
|
{tagPanel}
|
2020-06-05 01:34:04 +03:00
|
|
|
<aside className="mx_LeftPanel2_roomListContainer">
|
|
|
|
{this.renderHeader()}
|
2020-06-03 04:26:07 +03:00
|
|
|
<div
|
2020-06-05 01:34:04 +03:00
|
|
|
className="mx_LeftPanel2_filterContainer"
|
2020-06-03 04:26:07 +03:00
|
|
|
onKeyDown={() => {/*TODO*/}}
|
|
|
|
onFocus={() => {/*TODO*/}}
|
|
|
|
onBlur={() => {/*TODO*/}}
|
|
|
|
>
|
|
|
|
{searchBox}
|
|
|
|
</div>
|
2020-06-05 01:34:04 +03:00
|
|
|
<div className="mx_LeftPanel2_actualRoomListContainer">
|
|
|
|
{roomList}
|
|
|
|
</div>
|
2020-06-03 04:26:07 +03:00
|
|
|
</aside>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|