Merge pull request #4023 from vector-im/luke/new-guest-access-left-panel

Make left panel better for new users (mk III)
pull/4024/head
David Baker 2017-05-25 14:17:34 +01:00 committed by GitHub
commit 85aa390c8f
6 changed files with 159 additions and 61 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,15 @@ 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 ReactDOM from 'react-dom';
import sdk from 'matrix-react-sdk';
import dis from 'matrix-react-sdk/lib/dispatcher';
import AccessibleButton from 'matrix-react-sdk/lib/components/views/elements/AccessibleButton';
import Velocity from 'velocity-vector';
import 'velocity-vector/velocity.ui';
var React = require('react'); const CALLOUT_ANIM_DURATION = 1000;
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',
@ -39,6 +42,18 @@ module.exports = React.createClass({
}); });
}, },
componentWillMount: function() {
this._dispatcherRef = dis.register(this.onAction);
this._peopleButton = null;
this._directoryButton = null;
this._createRoomButton = null;
this._lastCallouts = {};
},
componentWillUnmount: function() {
dis.unregister(this._dispatcherRef);
},
// Room events // Room events
onDirectoryClick: function() { onDirectoryClick: function() {
dis.dispatch({ action: 'view_room_directory' }); dis.dispatch({ action: 'view_room_directory' });
@ -103,6 +118,30 @@ module.exports = React.createClass({
this.setState({ settingsHover: false }); this.setState({ settingsHover: false });
}, },
onAction: function(payload) {
let calloutElement;
switch (payload.action) {
// Incoming instruction: dance!
case 'callout_start_chat':
calloutElement = this._peopleButton;
break;
case 'callout_room_directory':
calloutElement = this._directoryButton;
break;
case 'callout_create_room':
calloutElement = this._createRoomButton;
break;
}
if (calloutElement) {
const lastCallout = this._lastCallouts[payload.action];
const now = Date.now();
if (lastCallout == undefined || lastCallout < now - CALLOUT_ANIM_DURATION) {
this._lastCallouts[payload.action] = now;
Velocity(ReactDOM.findDOMNode(calloutElement), "callout.bounce", CALLOUT_ANIM_DURATION);
}
}
},
// Get the label/tooltip to show // Get the label/tooltip to show
getLabel: function(label, show) { getLabel: function(label, show) {
if (show) { if (show) {
@ -111,31 +150,46 @@ module.exports = React.createClass({
} }
}, },
_collectPeopleButton: function(e) {
this._peopleButton = e;
},
_collectDirectoryButton: function(e) {
this._directoryButton = e;
},
_collectCreateRoomButton: function(e) {
this._createRoomButton = e;
},
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;
if (this.props.teamToken) {
homeButton = <HomeButton tooltip={true} />;
}
return ( return (
<div className="mx_BottomLeftMenu"> <div className="mx_BottomLeftMenu">
<div className="mx_BottomLeftMenu_options"> <div className="mx_BottomLeftMenu_options">
<AccessibleButton className="mx_BottomLeftMenu_homePage" onClick={ this.onHomeClick } onMouseEnter={ this.onHomeMouseEnter } onMouseLeave={ this.onHomeMouseLeave } > { homeButton }
<TintableSvg src="img/icons-home.svg" width="25" height="25" /> <div ref={this._collectPeopleButton}>
{ this.getLabel("Welcome page", this.state.homeHover) } <StartChatButton tooltip={true} />
</AccessibleButton> </div>
<AccessibleButton className="mx_BottomLeftMenu_people" onClick={ this.onPeopleClick } onMouseEnter={ this.onPeopleMouseEnter } onMouseLeave={ this.onPeopleMouseLeave } > <div ref={this._collectDirectoryButton}>
<TintableSvg src="img/icons-people.svg" width="25" height="25" /> <RoomDirectoryButton tooltip={true} />
{ this.getLabel("Start chat", this.state.peopleHover) } </div>
</AccessibleButton> <div ref={this._collectCreateRoomButton}>
<AccessibleButton className="mx_BottomLeftMenu_directory" onClick={ this.onDirectoryClick } onMouseEnter={ this.onDirectoryMouseEnter } onMouseLeave={ this.onDirectoryMouseLeave } > <CreateRoomButton tooltip={true} />
<TintableSvg src="img/icons-directory.svg" width="25" height="25"/> </div>
{ this.getLabel("Room directory", this.state.directoryHover) } <span className="mx_BottomLeftMenu_settings">
</AccessibleButton> <SettingsButton tooltip={true} />
<AccessibleButton className="mx_BottomLeftMenu_createRoom" onClick={ this.onRoomsClick } onMouseEnter={ this.onRoomsMouseEnter } onMouseLeave={ this.onRoomsMouseLeave } > </span>
<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() {
@ -521,16 +524,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();
} }
if (this.state.sortedList.length > 0 || this.props.editable) { if (this.state.sortedList.length > 0 || this.props.editable) {
@ -540,8 +542,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 {

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,29 @@ 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 > div {
.mx_LeftPanel .mx_BottomLeftMenu_directory, display: inline-block;
.mx_LeftPanel .mx_BottomLeftMenu_createRoom, }
.mx_LeftPanel .mx_BottomLeftMenu_people {
.mx_BottomLeftMenu_options .mx_RoleButton {
margin-left: 0px;
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;
}