Revert "Revert "Merge pull request #3804 from vector-im/dbkr/left_panel_for_newbies_2""

This reverts commit 3cead032c2.
dbkr/leftpanel_new_users_2
David Baker 2017-05-17 10:28:02 +01:00
parent b3bd104a43
commit 894be95cd0
7 changed files with 111 additions and 170 deletions

View File

@ -1,5 +1,6 @@
/* /*
Copyright 2015, 2016 OpenMarket Ltd Copyright 2015, 2016 OpenMarket Ltd
Copyright 2017 Vector Creations Ltd
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -14,13 +15,8 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
'use strict'; import React from 'react';
import sdk from 'matrix-react-sdk';
var React = require('react');
var ReactDOM = require('react-dom');
var sdk = require('matrix-react-sdk')
var dis = require('matrix-react-sdk/lib/dispatcher');
var AccessibleButton = require('matrix-react-sdk/lib/components/views/elements/AccessibleButton');
module.exports = React.createClass({ module.exports = React.createClass({
displayName: 'BottomLeftMenu', displayName: 'BottomLeftMenu',
@ -30,121 +26,28 @@ module.exports = React.createClass({
teamToken: React.PropTypes.string, teamToken: React.PropTypes.string,
}, },
getInitialState: function() {
return({
directoryHover : false,
roomsHover : false,
homeHover: false,
peopleHover : false,
settingsHover : false,
});
},
// Room events
onDirectoryClick: function() {
dis.dispatch({ action: 'view_room_directory' });
},
onDirectoryMouseEnter: function() {
this.setState({ directoryHover: true });
},
onDirectoryMouseLeave: function() {
this.setState({ directoryHover: false });
},
onRoomsClick: function() {
dis.dispatch({ action: 'view_create_room' });
},
onRoomsMouseEnter: function() {
this.setState({ roomsHover: true });
},
onRoomsMouseLeave: function() {
this.setState({ roomsHover: false });
},
// Home button events
onHomeClick: function() {
dis.dispatch({ action: 'view_home_page' });
},
onHomeMouseEnter: function() {
this.setState({ homeHover: true });
},
onHomeMouseLeave: function() {
this.setState({ homeHover: false });
},
// People events
onPeopleClick: function() {
dis.dispatch({ action: 'view_create_chat' });
},
onPeopleMouseEnter: function() {
this.setState({ peopleHover: true });
},
onPeopleMouseLeave: function() {
this.setState({ peopleHover: false });
},
// Settings events
onSettingsClick: function() {
dis.dispatch({ action: 'view_user_settings' });
},
onSettingsMouseEnter: function() {
this.setState({ settingsHover: true });
},
onSettingsMouseLeave: function() {
this.setState({ settingsHover: false });
},
// Get the label/tooltip to show
getLabel: function(label, show) {
if (show) {
var RoomTooltip = sdk.getComponent("rooms.RoomTooltip");
return <RoomTooltip className="mx_BottomLeftMenu_tooltip" label={label} />;
}
},
render: function() { render: function() {
var TintableSvg = sdk.getComponent('elements.TintableSvg'); const HomeButton = sdk.getComponent('elements.HomeButton');
const StartChatButton = sdk.getComponent('elements.StartChatButton');
const RoomDirectoryButton = sdk.getComponent('elements.RoomDirectoryButton');
const CreateRoomButton = sdk.getComponent('elements.CreateRoomButton');
const SettingsButton = sdk.getComponent('elements.SettingsButton');
var homeButton; var homeButton;
if (this.props.teamToken) { if (this.props.teamToken) {
homeButton = ( homeButton = <HomeButton tooltip={true} />;
<AccessibleButton className="mx_BottomLeftMenu_homePage" onClick={ this.onHomeClick } onMouseEnter={ this.onHomeMouseEnter } onMouseLeave={ this.onHomeMouseLeave } >
<TintableSvg src="img/icons-home.svg" width="25" height="25" />
{ this.getLabel("Welcome page", this.state.homeHover) }
</AccessibleButton>
);
} }
return ( return (
<div className="mx_BottomLeftMenu"> <div className="mx_BottomLeftMenu">
<div className="mx_BottomLeftMenu_options"> <div className="mx_BottomLeftMenu_options">
{ homeButton } { homeButton }
<AccessibleButton className="mx_BottomLeftMenu_people" onClick={ this.onPeopleClick } onMouseEnter={ this.onPeopleMouseEnter } onMouseLeave={ this.onPeopleMouseLeave } > <StartChatButton tooltip={true} />
<TintableSvg src="img/icons-people.svg" width="25" height="25" /> <RoomDirectoryButton tooltip={true} />
{ this.getLabel("Start chat", this.state.peopleHover) } <CreateRoomButton tooltip={true} />
</AccessibleButton> <span className="mx_BottomLeftMenu_settings">
<AccessibleButton className="mx_BottomLeftMenu_directory" onClick={ this.onDirectoryClick } onMouseEnter={ this.onDirectoryMouseEnter } onMouseLeave={ this.onDirectoryMouseLeave } > <SettingsButton tooltip={true} />
<TintableSvg src="img/icons-directory.svg" width="25" height="25"/> </span>
{ this.getLabel("Room directory", this.state.directoryHover) }
</AccessibleButton>
<AccessibleButton className="mx_BottomLeftMenu_createRoom" onClick={ this.onRoomsClick } onMouseEnter={ this.onRoomsMouseEnter } onMouseLeave={ this.onRoomsMouseLeave } >
<TintableSvg src="img/icons-create-room.svg" width="25" height="25" />
{ this.getLabel("Create new room", this.state.roomsHover) }
</AccessibleButton>
<AccessibleButton className="mx_BottomLeftMenu_settings" onClick={ this.onSettingsClick } onMouseEnter={ this.onSettingsMouseEnter } onMouseLeave={ this.onSettingsMouseLeave } >
<TintableSvg src="img/icons-settings.svg" width="25" height="25" />
{ this.getLabel("Settings", this.state.settingsHover) }
</AccessibleButton>
</div> </div>
</div> </div>
); );

View File

@ -1,4 +1,5 @@
/* /*
Copyright 2017 Vector Creations Ltd
Copyright 2015, 2016 OpenMarket Ltd Copyright 2015, 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
@ -83,6 +84,8 @@ var RoomSubList = React.createClass({
incomingCall: React.PropTypes.object, incomingCall: React.PropTypes.object,
onShowMoreRooms: React.PropTypes.func, onShowMoreRooms: React.PropTypes.func,
searchFilter: React.PropTypes.string, searchFilter: React.PropTypes.string,
emptyContent: React.PropTypes.node, // content shown if the list is empty
headerItems: React.PropTypes.node, // content shown in the sublist header
}, },
getInitialState: function() { getInitialState: function() {
@ -469,16 +472,15 @@ var RoomSubList = React.createClass({
render: function() { render: function() {
var connectDropTarget = this.props.connectDropTarget; var connectDropTarget = this.props.connectDropTarget;
var RoomDropTarget = sdk.getComponent('rooms.RoomDropTarget');
var TruncatedList = sdk.getComponent('elements.TruncatedList'); var TruncatedList = sdk.getComponent('elements.TruncatedList');
var label = this.props.collapsed ? null : this.props.label; var label = this.props.collapsed ? null : this.props.label;
//console.log("render: " + JSON.stringify(this.state.sortedList)); let content;
if (this.state.sortedList.length == 0) {
var target; content = this.props.emptyContent;
if (this.state.sortedList.length == 0 && this.props.editable) { } else {
target = <RoomDropTarget label={ 'Drop here to ' + this.props.verb }/>; content = this.makeRoomTiles();
} }
var roomCount = this.props.list.length > 0 ? this.props.list.length : ''; var roomCount = this.props.list.length > 0 ? this.props.list.length : '';
@ -498,8 +500,7 @@ var RoomSubList = React.createClass({
if (!this.state.hidden) { if (!this.state.hidden) {
subList = <TruncatedList className={ classes } truncateAt={this.state.truncateAt} subList = <TruncatedList className={ classes } truncateAt={this.state.truncateAt}
createOverflowElement={this._createOverflowTile} > createOverflowElement={this._createOverflowTile} >
{ target } { content }
{ this.makeRoomTiles() }
</TruncatedList>; </TruncatedList>;
} }
else { else {
@ -521,6 +522,7 @@ var RoomSubList = React.createClass({
roomNotificationCount={ this.roomNotificationCount() } roomNotificationCount={ this.roomNotificationCount() }
onClick={ this.onClick } onClick={ this.onClick }
onHeaderClick={ this.props.onHeaderClick } onHeaderClick={ this.props.onHeaderClick }
headerItems={this.props.headerItems}
/> />
{ subList } { subList }
</div> </div>
@ -542,6 +544,7 @@ var RoomSubList = React.createClass({
roomNotificationCount={ this.roomNotificationCount() } roomNotificationCount={ this.roomNotificationCount() }
onClick={ this.onClick } onClick={ this.onClick }
onHeaderClick={ this.props.onHeaderClick } onHeaderClick={ this.props.onHeaderClick }
headerItems={this.props.headerItems}
/> />
: undefined } : undefined }
{ (this.props.showSpinner && !this.state.hidden) ? <Loader /> : undefined } { (this.props.showSpinner && !this.state.hidden) ? <Loader /> : undefined }

View File

@ -14,16 +14,11 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
'use strict'; import React from 'react';
import classNames from 'classnames';
var React = require('react'); import sdk from 'matrix-react-sdk';
var ReactDOM = require('react-dom'); import { formatCount } from 'matrix-react-sdk/lib/utils/FormattingUtils';
var classNames = require('classnames'); import AccessibleButton from 'matrix-react-sdk/lib/components/views/elements/AccessibleButton';
var sdk = require('matrix-react-sdk')
var FormattingUtils = require('matrix-react-sdk/lib/utils/FormattingUtils');
var RoomNotifs = require('matrix-react-sdk/lib/RoomNotifs');
var AccessibleButton = require('matrix-react-sdk/lib/components/views/elements/AccessibleButton');
var ConstantTimeDispatcher = require('matrix-react-sdk/lib/ConstantTimeDispatcher');
module.exports = React.createClass({ module.exports = React.createClass({
displayName: 'RoomSubListHeader', displayName: 'RoomSubListHeader',
@ -42,6 +37,7 @@ module.exports = React.createClass({
hidden: React.PropTypes.bool, hidden: React.PropTypes.bool,
onClick: React.PropTypes.func, onClick: React.PropTypes.func,
onHeaderClick: React.PropTypes.func, onHeaderClick: React.PropTypes.func,
headerItems: React.PropTypes.node, // content shown in the sublist header
}, },
getDefaultProps: function() { getDefaultProps: function() {
@ -63,35 +59,34 @@ module.exports = React.createClass({
// }, // },
render: function() { render: function() {
var TintableSvg = sdk.getComponent("elements.TintableSvg"); const TintableSvg = sdk.getComponent("elements.TintableSvg");
var subListNotifications = this.props.roomNotificationCount; const subListNotifications = this.props.roomNotificationCount;
var subListNotifCount = subListNotifications[0]; const subListNotifCount = subListNotifications[0];
var subListNotifHighlight = subListNotifications[1]; const subListNotifHighlight = subListNotifications[1];
var chevronClasses = classNames({ const chevronClasses = classNames({
'mx_RoomSubList_chevron': true, 'mx_RoomSubList_chevron': true,
'mx_RoomSubList_chevronRight': this.props.hidden, 'mx_RoomSubList_chevronRight': this.props.hidden,
'mx_RoomSubList_chevronDown': !this.props.hidden, 'mx_RoomSubList_chevronDown': !this.props.hidden,
}); });
var badgeClasses = classNames({ const badgeClasses = classNames({
'mx_RoomSubList_badge': true, 'mx_RoomSubList_badge': true,
'mx_RoomSubList_badgeHighlight': subListNotifHighlight, 'mx_RoomSubList_badgeHighlight': subListNotifHighlight,
}); });
var badge; let badge;
if (subListNotifCount > 0) { if (subListNotifCount > 0) {
badge = <div className={badgeClasses}>{ FormattingUtils.formatCount(subListNotifCount) }</div>; badge = <div className={badgeClasses}>{ formatCount(subListNotifCount) }</div>;
} } else if (subListNotifHighlight) {
else if (subListNotifHighlight) {
badge = <div className={badgeClasses}>!</div>; badge = <div className={badgeClasses}>!</div>;
} }
// When collapsed, allow a long hover on the header to show user // When collapsed, allow a long hover on the header to show user
// the full tag name and room count // the full tag name and room count
var title; let title;
var roomCount = this.props.roomCount; const roomCount = this.props.roomCount;
if (this.props.collapsed) { if (this.props.collapsed) {
title = this.props.label; title = this.props.label;
if (roomCount !== '') { if (roomCount !== '') {
@ -99,9 +94,9 @@ module.exports = React.createClass({
} }
} }
var incomingCall; let incomingCall;
if (this.props.isIncomingCallRoom) { if (this.props.isIncomingCallRoom) {
var IncomingCallBox = sdk.getComponent("voip.IncomingCallBox"); const IncomingCallBox = sdk.getComponent("voip.IncomingCallBox");
incomingCall = <IncomingCallBox className="mx_RoomSubList_incomingCall" incomingCall={ this.props.incomingCall }/>; incomingCall = <IncomingCallBox className="mx_RoomSubList_incomingCall" incomingCall={ this.props.incomingCall }/>;
} }
@ -109,6 +104,7 @@ module.exports = React.createClass({
<div className="mx_RoomSubList_labelContainer" title={ title } ref="header"> <div className="mx_RoomSubList_labelContainer" title={ title } ref="header">
<AccessibleButton onClick={ this.props.onClick } className="mx_RoomSubList_label" tabIndex="0"> <AccessibleButton onClick={ this.props.onClick } className="mx_RoomSubList_label" tabIndex="0">
{ this.props.collapsed ? '' : this.props.label } { this.props.collapsed ? '' : this.props.label }
{this.props.headerItems}
<div className="mx_RoomSubList_roomCount">{ roomCount }</div> <div className="mx_RoomSubList_roomCount">{ roomCount }</div>
<div className={chevronClasses}></div> <div className={chevronClasses}></div>
{ badge } { badge }

View File

@ -27,6 +27,7 @@
@import "./matrix-react-sdk/views/elements/_MemberEventListSummary.scss"; @import "./matrix-react-sdk/views/elements/_MemberEventListSummary.scss";
@import "./matrix-react-sdk/views/elements/_ProgressBar.scss"; @import "./matrix-react-sdk/views/elements/_ProgressBar.scss";
@import "./matrix-react-sdk/views/elements/_RichText.scss"; @import "./matrix-react-sdk/views/elements/_RichText.scss";
@import "./matrix-react-sdk/views/elements/_RoleButton.scss";
@import "./matrix-react-sdk/views/login/_InteractiveAuthEntryComponents.scss"; @import "./matrix-react-sdk/views/login/_InteractiveAuthEntryComponents.scss";
@import "./matrix-react-sdk/views/login/_ServerConfig.scss"; @import "./matrix-react-sdk/views/login/_ServerConfig.scss";
@import "./matrix-react-sdk/views/messages/_MEmoteBody.scss"; @import "./matrix-react-sdk/views/messages/_MEmoteBody.scss";

View File

@ -0,0 +1,33 @@
/*
Copyright 2107 Vector Creations Ltd
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.
*/
.mx_RoleButton {
margin-left: 4px;
margin-right: 4px;
cursor: pointer;
display: inline-block;
}
.mx_RoleButton object {
pointer-events: none;
}
.mx_RoleButton_tooltip {
display: inline-block;
position: relative;
top: -25px;
left: 6px;
}

View File

@ -1,5 +1,6 @@
/* /*
Copyright 2015, 2016 OpenMarket Ltd Copyright 2015, 2016 OpenMarket Ltd
Copyright 2107 Vector Creations Ltd
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -37,3 +38,25 @@ limitations under the License.
.mx_RoomList_scrollbar .gm-scrollbar.-vertical { .mx_RoomList_scrollbar .gm-scrollbar.-vertical {
z-index: 6; z-index: 6;
} }
.mx_RoomList_emptySubListTip {
font-size: 13px;
margin-left: 18px;
margin-right: 18px;
margin-top: 8px;
margin-bottom: 7px;
padding: 5px;
border: 1px dashed $accent-color;
color: $primary-fg-color;
background-color: $droptarget-bg-color;
border-radius: 4px;
}
.mx_RoomList_emptySubListTip .mx_RoleButton {
vertical-align: -3px;
}
.mx_RoomList_headerButtons {
position: absolute;
right: 60px;
}

View File

@ -64,43 +64,25 @@ limitations under the License.
pointer-events: none; pointer-events: none;
} }
.mx_LeftPanel .mx_BottomLeftMenu_homePage, .collapsed .mx_RoleButton {
.mx_LeftPanel .mx_BottomLeftMenu_directory,
.mx_LeftPanel .mx_BottomLeftMenu_createRoom,
.mx_LeftPanel .mx_BottomLeftMenu_people,
.mx_LeftPanel .mx_BottomLeftMenu_settings {
display: inline-block;
cursor: pointer;
}
.collapsed .mx_BottomLeftMenu_homePage,
.collapsed .mx_BottomLeftMenu_directory,
.collapsed .mx_BottomLeftMenu_createRoom,
.collapsed .mx_BottomLeftMenu_people,
.collapsed .mx_BottomLeftMenu_settings {
margin-right: 0px ! important; margin-right: 0px ! important;
padding-top: 3px ! important; padding-top: 3px ! important;
padding-bottom: 3px ! important; padding-bottom: 3px ! important;
} }
.mx_LeftPanel .mx_BottomLeftMenu_homePage, .mx_BottomLeftMenu_options .mx_RoleButton {
.mx_LeftPanel .mx_BottomLeftMenu_directory, margin-left: 0px;
.mx_LeftPanel .mx_BottomLeftMenu_createRoom,
.mx_LeftPanel .mx_BottomLeftMenu_people {
margin-right: 10px; margin-right: 10px;
} }
.mx_LeftPanel .mx_BottomLeftMenu_settings { .mx_BottomLeftMenu_options .mx_BottomLeftMenu_settings {
float: right; float: right;
} }
.mx_BottomLeftMenu_options .mx_BottomLeftMenu_settings .mx_RoleButton {
margin-right: 0px;
}
.mx_LeftPanel.collapsed .mx_BottomLeftMenu_settings { .mx_LeftPanel.collapsed .mx_BottomLeftMenu_settings {
float: none; float: none;
} }
.mx_LeftPanel .mx_BottomLeftMenu_tooltip {
display: inline-block;
position: relative;
top: -25px;
left: 6px;
}