forked from matrix/element-web
improve collapsed LHS implementation - split the tooltip into its own component; position it with javascript as overflow-y + position absolute = clipping hell; preserve the collapse state between MatrixChat re-renders; fix positioning of the 'show' button; switch to dispatcher for show/hide LHS; remove errant scrollbars
This commit is contained in:
parent
8bdb5c0745
commit
93de2307c1
|
@ -52,6 +52,11 @@ module.exports = {
|
||||||
case 'call_state':
|
case 'call_state':
|
||||||
this._recheckCallElement(this.props.selectedRoom);
|
this._recheckCallElement(this.props.selectedRoom);
|
||||||
break;
|
break;
|
||||||
|
case 'view_tooltip':
|
||||||
|
this.tooltip = payload.tooltip;
|
||||||
|
this._repositionTooltip();
|
||||||
|
if (this.tooltip) this.tooltip.style.display = 'block';
|
||||||
|
break
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -150,6 +155,13 @@ module.exports = {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_repositionTooltip: function(e) {
|
||||||
|
if (this.tooltip && this.tooltip.parentElement) {
|
||||||
|
var scroll = this.getDOMNode();
|
||||||
|
this.tooltip.style.top = (scroll.parentElement.offsetTop + this.tooltip.parentElement.offsetTop - scroll.scrollTop) + "px";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
makeRoomTiles: function() {
|
makeRoomTiles: function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
var RoomTile = sdk.getComponent("molecules.RoomTile");
|
var RoomTile = sdk.getComponent("molecules.RoomTile");
|
||||||
|
|
|
@ -16,7 +16,7 @@ limitations under the License.
|
||||||
|
|
||||||
.mx_RoomTile {
|
.mx_RoomTile {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
display: table-row;
|
/* display: table-row; */
|
||||||
color: #818794;
|
color: #818794;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,27 +45,6 @@ limitations under the License.
|
||||||
padding-right: 16px;
|
padding-right: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_RoomTile_tooltip {
|
|
||||||
border: 1px solid #a9dbf4;
|
|
||||||
border-radius: 8px;
|
|
||||||
background-color: #fff;
|
|
||||||
position: absolute;
|
|
||||||
z-index: 1000;
|
|
||||||
margin-top: 6px;
|
|
||||||
left: 64px;
|
|
||||||
padding: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_RoomTile_chevron {
|
|
||||||
position: absolute;
|
|
||||||
left: -9px;
|
|
||||||
top: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_RoomTile_tooltip {
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
|
|
||||||
.collapsed .mx_RoomTile_name {
|
.collapsed .mx_RoomTile_name {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
Copyright 2015 OpenMarket 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_RoomTooltip {
|
||||||
|
display: none;
|
||||||
|
position: fixed;
|
||||||
|
border: 1px solid #a9dbf4;
|
||||||
|
border-radius: 8px;
|
||||||
|
background-color: #fff;
|
||||||
|
z-index: 1000;
|
||||||
|
margin-top: 6px;
|
||||||
|
left: 64px;
|
||||||
|
padding: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_RoomTooltip_chevron {
|
||||||
|
position: absolute;
|
||||||
|
left: -9px;
|
||||||
|
top: 8px;
|
||||||
|
}
|
|
@ -33,13 +33,6 @@ limitations under the License.
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_LeftPanel_showButton {
|
|
||||||
position: absolute;
|
|
||||||
top: 18px;
|
|
||||||
left: 16px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_LeftPanel .mx_RoomList {
|
.mx_LeftPanel .mx_RoomList {
|
||||||
-webkit-box-ordinal-group: 1;
|
-webkit-box-ordinal-group: 1;
|
||||||
-moz-box-ordinal-group: 1;
|
-moz-box-ordinal-group: 1;
|
||||||
|
@ -47,7 +40,7 @@ limitations under the License.
|
||||||
-webkit-order: 1;
|
-webkit-order: 1;
|
||||||
order: 1;
|
order: 1;
|
||||||
|
|
||||||
overflow-y: scroll;
|
overflow-y: auto;
|
||||||
-webkit-flex: 1 1 0;
|
-webkit-flex: 1 1 0;
|
||||||
flex: 1 1 0;
|
flex: 1 1 0;
|
||||||
}
|
}
|
||||||
|
@ -69,10 +62,6 @@ limitations under the License.
|
||||||
color: #378bb4;
|
color: #378bb4;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_LeftPanel .mx_BottomLeftMenu .mx_RoomTile_avatar {
|
|
||||||
padding-left: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_LeftPanel .mx_BottomLeftMenu .mx_BottomLeftMenu_options {
|
.mx_LeftPanel .mx_BottomLeftMenu .mx_BottomLeftMenu_options {
|
||||||
margin-top: 12px;
|
margin-top: 12px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
|
@ -57,7 +57,7 @@ limitations under the License.
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_RoomDirectory_tableWrapper {
|
.mx_RoomDirectory_tableWrapper {
|
||||||
overflow-y: scroll;
|
overflow-y: auto;
|
||||||
-webkit-flex: 1 1 0;
|
-webkit-flex: 1 1 0;
|
||||||
flex: 1 1 0;
|
flex: 1 1 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,7 +109,7 @@ limitations under the License.
|
||||||
margin-top: 18px;
|
margin-top: 18px;
|
||||||
margin-bottom: 18px;
|
margin-bottom: 18px;
|
||||||
|
|
||||||
overflow-y: scroll;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_RoomView_messageListWrapper {
|
.mx_RoomView_messageListWrapper {
|
||||||
|
|
|
@ -57,6 +57,7 @@ skin['molecules.RoomDropTarget'] = require('./views/molecules/RoomDropTarget');
|
||||||
skin['molecules.RoomHeader'] = require('./views/molecules/RoomHeader');
|
skin['molecules.RoomHeader'] = require('./views/molecules/RoomHeader');
|
||||||
skin['molecules.RoomSettings'] = require('./views/molecules/RoomSettings');
|
skin['molecules.RoomSettings'] = require('./views/molecules/RoomSettings');
|
||||||
skin['molecules.RoomTile'] = require('./views/molecules/RoomTile');
|
skin['molecules.RoomTile'] = require('./views/molecules/RoomTile');
|
||||||
|
skin['molecules.RoomTooltip'] = require('./views/molecules/RoomTooltip');
|
||||||
skin['molecules.SenderProfile'] = require('./views/molecules/SenderProfile');
|
skin['molecules.SenderProfile'] = require('./views/molecules/SenderProfile');
|
||||||
skin['molecules.ServerConfig'] = require('./views/molecules/ServerConfig');
|
skin['molecules.ServerConfig'] = require('./views/molecules/ServerConfig');
|
||||||
skin['molecules.UnknownMessageTile'] = require('./views/molecules/UnknownMessageTile');
|
skin['molecules.UnknownMessageTile'] = require('./views/molecules/UnknownMessageTile');
|
||||||
|
|
|
@ -71,15 +71,13 @@ module.exports = React.createClass({
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var nameElement;
|
var label;
|
||||||
if (!this.props.collapsed) {
|
if (!this.props.collapsed) {
|
||||||
nameElement = <div className="mx_RoomTile_name">{name}</div>;
|
label = <div className="mx_RoomTile_name">{name}</div>;
|
||||||
}
|
}
|
||||||
else if (this.state.hover) {
|
else if (this.state.hover) {
|
||||||
nameElement = <div className="mx_RoomTile_tooltip">
|
var RoomTooltip = sdk.getComponent("molecules.RoomTooltip");
|
||||||
<img className="mx_RoomTile_chevron" src="img/chevron-left.png" width="9" height="16"/>
|
label = <RoomTooltip room={this.props.room} ref="roomTooltip"/>;
|
||||||
{ name }
|
|
||||||
</div>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var RoomAvatar = sdk.getComponent('atoms.RoomAvatar');
|
var RoomAvatar = sdk.getComponent('atoms.RoomAvatar');
|
||||||
|
@ -89,7 +87,7 @@ module.exports = React.createClass({
|
||||||
<RoomAvatar room={this.props.room} />
|
<RoomAvatar room={this.props.room} />
|
||||||
{ badge }
|
{ badge }
|
||||||
</div>
|
</div>
|
||||||
{ nameElement }
|
{ label }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
Copyright 2015 OpenMarket 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var React = require('react');
|
||||||
|
var classNames = require('classnames');
|
||||||
|
|
||||||
|
var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
|
||||||
|
|
||||||
|
var sdk = require('matrix-react-sdk')
|
||||||
|
var dis = require('matrix-react-sdk/lib/dispatcher');
|
||||||
|
|
||||||
|
module.exports = React.createClass({
|
||||||
|
displayName: 'RoomTooltip',
|
||||||
|
|
||||||
|
componentDidMount: function() {
|
||||||
|
// tell the roomlist about us
|
||||||
|
dis.dispatch({
|
||||||
|
action: 'view_tooltip',
|
||||||
|
tooltip: this.getDOMNode(),
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
componentDidUnmount: function() {
|
||||||
|
dis.dispatch({
|
||||||
|
action: 'view_tooltip',
|
||||||
|
tooltip: null,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
render: function() {
|
||||||
|
return (
|
||||||
|
<div className="mx_RoomTooltip">
|
||||||
|
<img className="mx_RoomTooltip_chevron" src="img/chevron-left.png" width="9" height="16"/>
|
||||||
|
{ this.props.room.name }
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
|
@ -18,22 +18,15 @@ limitations under the License.
|
||||||
|
|
||||||
var React = require('react');
|
var React = require('react');
|
||||||
var sdk = require('matrix-react-sdk')
|
var sdk = require('matrix-react-sdk')
|
||||||
|
var dis = require('matrix-react-sdk/lib/dispatcher');
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
displayName: 'LeftPanel',
|
displayName: 'LeftPanel',
|
||||||
|
|
||||||
getInitialState: function() {
|
|
||||||
return {
|
|
||||||
collapsed: false,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
onShowClick: function() {
|
|
||||||
this.setState({ collapsed : false });
|
|
||||||
},
|
|
||||||
|
|
||||||
onHideClick: function() {
|
onHideClick: function() {
|
||||||
this.setState({ collapsed : true });
|
dis.dispatch({
|
||||||
|
action: 'hide_left_panel',
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
|
@ -43,9 +36,8 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
var collapseButton;
|
var collapseButton;
|
||||||
var classes = "mx_LeftPanel";
|
var classes = "mx_LeftPanel";
|
||||||
if (this.state.collapsed) {
|
if (this.props.collapsed) {
|
||||||
classes += " collapsed";
|
classes += " collapsed";
|
||||||
collapseButton = <img className="mx_LeftPanel_showButton" onClick={ this.onShowClick } src="img/menu.png" width="27" height="20" alt=">"/>
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
collapseButton = <img className="mx_LeftPanel_hideButton" onClick={ this.onHideClick } src="img/hide.png" width="12" height="20" alt="<"/>
|
collapseButton = <img className="mx_LeftPanel_hideButton" onClick={ this.onHideClick } src="img/hide.png" width="12" height="20" alt="<"/>
|
||||||
|
@ -55,7 +47,7 @@ module.exports = React.createClass({
|
||||||
<aside className={classes}>
|
<aside className={classes}>
|
||||||
{ collapseButton }
|
{ collapseButton }
|
||||||
<IncomingCallBox />
|
<IncomingCallBox />
|
||||||
<RoomList selectedRoom={this.props.selectedRoom} collapsed={this.state.collapsed}/>
|
<RoomList selectedRoom={this.props.selectedRoom} collapsed={this.props.collapsed}/>
|
||||||
<BottomLeftMenu />
|
<BottomLeftMenu />
|
||||||
</aside>
|
</aside>
|
||||||
);
|
);
|
||||||
|
|
|
@ -18,6 +18,7 @@ limitations under the License.
|
||||||
|
|
||||||
var React = require('react');
|
var React = require('react');
|
||||||
var sdk = require('matrix-react-sdk')
|
var sdk = require('matrix-react-sdk')
|
||||||
|
var dis = require('matrix-react-sdk/lib/dispatcher');
|
||||||
|
|
||||||
var RoomListController = require('../../../../controllers/organisms/RoomList')
|
var RoomListController = require('../../../../controllers/organisms/RoomList')
|
||||||
|
|
||||||
|
@ -25,6 +26,12 @@ module.exports = React.createClass({
|
||||||
displayName: 'RoomList',
|
displayName: 'RoomList',
|
||||||
mixins: [RoomListController],
|
mixins: [RoomListController],
|
||||||
|
|
||||||
|
onShowClick: function() {
|
||||||
|
dis.dispatch({
|
||||||
|
action: 'show_left_panel',
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var CallView = sdk.getComponent('molecules.voip.CallView');
|
var CallView = sdk.getComponent('molecules.voip.CallView');
|
||||||
var RoomDropTarget = sdk.getComponent('molecules.RoomDropTarget');
|
var RoomDropTarget = sdk.getComponent('molecules.RoomDropTarget');
|
||||||
|
@ -34,15 +41,17 @@ module.exports = React.createClass({
|
||||||
callElement = <CallView className="mx_MatrixChat_callView"/>
|
callElement = <CallView className="mx_MatrixChat_callView"/>
|
||||||
}
|
}
|
||||||
|
|
||||||
var recentsLabel = this.props.collapsed ? "" : "Recents";
|
var recentsLabel = this.props.collapsed ?
|
||||||
|
<img onClick={ this.onShowClick } src="img/menu.png" width="27" height="20" alt=">"/> :
|
||||||
|
"Recents";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx_RoomList">
|
<div className="mx_RoomList" onScroll={this._repositionTooltip}>
|
||||||
{callElement}
|
{callElement}
|
||||||
<h2 className="mx_RoomList_favourites_label">Favourites</h2>
|
<h2 className="mx_RoomList_favourites_label">Favourites</h2>
|
||||||
<RoomDropTarget text="Drop here to favourite"/>
|
<RoomDropTarget text="Drop here to favourite"/>
|
||||||
|
|
||||||
<h2 className="mx_RoomList_recents_label">{ recentsLabel } </h2>
|
<h2 className="mx_RoomList_recents_label">{ recentsLabel }</h2>
|
||||||
<div className="mx_RoomList_recents">
|
<div className="mx_RoomList_recents">
|
||||||
{this.makeRoomTiles()}
|
{this.makeRoomTiles()}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -79,7 +79,7 @@ module.exports = React.createClass({
|
||||||
<div className="mx_MatrixChat_wrapper">
|
<div className="mx_MatrixChat_wrapper">
|
||||||
<MatrixToolbar />
|
<MatrixToolbar />
|
||||||
<div className="mx_MatrixChat mx_MatrixChat_toolbarShowing">
|
<div className="mx_MatrixChat mx_MatrixChat_toolbarShowing">
|
||||||
<LeftPanel selectedRoom={this.state.currentRoom} />
|
<LeftPanel selectedRoom={this.state.currentRoom} collapsed={this.state.collapse_lhs} />
|
||||||
<main className="mx_MatrixChat_middlePanel">
|
<main className="mx_MatrixChat_middlePanel">
|
||||||
{page_element}
|
{page_element}
|
||||||
</main>
|
</main>
|
||||||
|
@ -91,7 +91,7 @@ module.exports = React.createClass({
|
||||||
else {
|
else {
|
||||||
return (
|
return (
|
||||||
<div className="mx_MatrixChat">
|
<div className="mx_MatrixChat">
|
||||||
<LeftPanel selectedRoom={this.state.currentRoom} />
|
<LeftPanel selectedRoom={this.state.currentRoom} collapsed={this.state.collapse_lhs} />
|
||||||
<main className="mx_MatrixChat_middlePanel">
|
<main className="mx_MatrixChat_middlePanel">
|
||||||
{page_element}
|
{page_element}
|
||||||
</main>
|
</main>
|
||||||
|
|
Loading…
Reference in New Issue