WIP at turning MemberInfo into a ContextualMenu

This commit is contained in:
Matthew Hodgson 2015-09-21 19:22:29 +02:00
parent ce2632bbe6
commit 048260bb1b
7 changed files with 47 additions and 454 deletions

View file

@ -43,9 +43,39 @@ html {
overflow: -moz-scrollbars-none;
}
/* FIXME: why is all the dialog stuff in here rather than in per-component files? */
.mx_ContextualMenu_background {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 1.0;
z-index: 2000;
}
.mx_Dialog_Background {
.mx_ContextualMenu {
text-align: center;
border: 1px solid #a9dbf4;
border-radius: 8px;
background-color: #fff;
position: fixed;
z-index: 1000;
padding: 6px;
}
.mx_ContextualMenu_chevron {
padding: 12px;
position: absolute;
right: -21px;
top: 0px;
}
.mx_ContextualMenu_field {
padding: 6px;
}
.mx_Dialog_background {
position: fixed;
top: 0;
left: 0;
@ -56,7 +86,7 @@ html {
z-index: 2000;
}
.mx_Dialog_Wrapper {
.mx_Dialog_wrapper {
position: fixed;
top: 0;
left: 0;

View file

@ -14,60 +14,3 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_MemberInfo {
text-align: center;
border: 1px solid #a9dbf4;
border-radius: 8px;
background-color: #fff;
position: absolute;
width: 200px;
margin-left: -295px;
margin-top: 0px;
z-index: 1000;
padding: 6px;
}
.mx_MemberInfo_chevron {
padding: 12px;
position: absolute;
right: -21px;
top: 0px;
}
/*
* a hacky shim to extend the hitmask of the overlay to overlap
* better with the main menu itself
*/
.mx_MemberInfo_shim {
position: absolute;
left: 212px;
width: 40px;
height: 100%;
}
.mx_MemberInfo_avatar {
padding: 6px;
}
.mx_MemberInfo_avatarImg {
border-radius: 128px;
}
.mx_MemberInfo_field {
padding: 6px;
overflow: hidden;
text-overflow: ellipsis;
}
.mx_MemberInfo_button {
vertical-align: middle;
max-width: 100px;
height: 36px;
background-color: #50e3c2;
line-height: 36px;
border-radius: 36px;
color: #fff;
margin: auto;
margin-top: 6px;
margin-bottom: 6px;
}

View file

@ -27,84 +27,34 @@ module.exports = React.createClass({
displayName: 'MemberInfo',
mixins: [MemberInfoController],
componentDidMount: function() {
var self = this;
var memberInfo = this.getDOMNode();
var memberListScroll = document.getElementsByClassName("mx_MemberList_border")[0];
if (memberListScroll) {
memberInfo.style.top = (memberInfo.parentElement.offsetTop - memberListScroll.scrollTop) + "px";
}
},
getDuration: function(time) {
if (!time) return;
var t = parseInt(time / 1000);
var s = t % 60;
var m = parseInt(t / 60) % 60;
var h = parseInt(t / (60 * 60)) % 24;
var d = parseInt(t / (60 * 60 * 24));
if (t < 60) {
if (t < 0) {
return "0s";
}
return s + "s";
}
if (t < 60 * 60) {
return m + "m";
}
if (t < 24 * 60 * 60) {
return h + "h";
}
return d + "d ";
},
render: function() {
var activeAgo = "unknown";
if (this.state.active >= 0) {
activeAgo = this.getDuration(this.state.active);
}
var kickButton, banButton, muteButton, giveModButton;
if (this.state.can.kick) {
kickButton = <div className="mx_MemberInfo_button" onClick={this.onKick}>
kickButton = <div className="mx_ContextualMenu_field" onClick={this.onKick}>
Kick
</div>;
}
if (this.state.can.ban) {
banButton = <div className="mx_MemberInfo_button" onClick={this.onBan}>
banButton = <div className="mx_ContextualMenu_field" onClick={this.onBan}>
Ban
</div>;
}
if (this.state.can.mute) {
var muteLabel = this.state.muted ? "Unmute" : "Mute";
muteButton = <div className="mx_MemberInfo_button" onClick={this.onMuteToggle}>
muteButton = <div className="mx_ContextualMenu_field" onClick={this.onMuteToggle}>
{muteLabel}
</div>;
}
if (this.state.can.modifyLevel) {
var giveOpLabel = this.state.isTargetMod ? "Revoke Mod" : "Make Mod";
giveModButton = <div className="mx_MemberInfo_button" onClick={this.onModToggle}>
giveModButton = <div className="mx_ContextualMenu_field" onClick={this.onModToggle}>
{giveOpLabel}
</div>
}
var opLabel;
if (this.state.isTargetMod) {
var level = this.props.member.powerLevelNorm + "%";
opLabel = <div className="mx_MemberInfo_field">Moderator ({level})</div>
}
return (
<div className="mx_MemberInfo">
<img className="mx_MemberInfo_chevron" src="img/chevron-right.png" width="9" height="16" />
<div className="mx_MemberInfo_shim"></div>
<div className="mx_MemberInfo_avatar">
<MemberAvatar member={this.props.member} width={128} height={128} />
</div>
<div className="mx_MemberInfo_field">{this.props.member.userId}</div>
{opLabel}
<div className="mx_MemberInfo_field">Presence: {this.state.presence}</div>
<div className="mx_MemberInfo_field">Last active: {activeAgo}</div>
<div className="mx_MemberInfo_button" onClick={this.onChatClick}>Start chat</div>
<div>
<div className="mx_ContextualMenu_field" onClick={this.onChatClick}>Start chat</div>
{muteButton}
{kickButton}
{banButton}

View file

@ -21,6 +21,7 @@ var React = require('react');
var MatrixClientPeg = require("../../../../src/MatrixClientPeg");
var ComponentBroker = require('../../../../src/ComponentBroker');
var Modal = require("../../../../src/Modal");
var ContextualMenu = require("../../../../src/ContextualMenu");
var MemberTileController = require("../../../../src/controllers/molecules/MemberTile");
var MemberInfo = ComponentBroker.get('molecules/MemberInfo');
var ErrorDialog = ComponentBroker.get("organisms/ErrorDialog");
@ -43,8 +44,11 @@ module.exports = React.createClass({
},
onClick: function(e) {
this.setState({ 'menu': true });
this.setState(this._calculateOpsPermissions());
ContextualMenu.createMenu(MemberInfo, {
member: this.props.member,
right: window.innerWidth - e.pageX,
top: e.pageY,
});
},
getDuration: function(time) {
@ -118,41 +122,6 @@ module.exports = React.createClass({
nameClass += " mx_MemberTile_zalgo";
}
var menu;
if (this.state.menu) {
var kickButton, banButton, muteButton, giveModButton;
if (this.state.can.kick) {
kickButton = <div className="mx_MemberTile_menuItem" onClick={this.onKick}>
Kick
</div>;
}
if (this.state.can.ban) {
banButton = <div className="mx_MemberTile_menuItem" onClick={this.onBan}>
Ban
</div>;
}
if (this.state.can.mute) {
var muteLabel = this.state.muted ? "Unmute" : "Mute";
muteButton = <div className="mx_MemberTile_menuItem" onClick={this.onMuteToggle}>
{muteLabel}
</div>;
}
if (this.state.can.modifyLevel) {
var giveOpLabel = this.state.isTargetMod ? "Revoke Mod" : "Make Mod";
giveModButton = <div className="mx_MemberTile_menuItem" onClick={this.onModToggle}>
{giveOpLabel}
</div>
}
menu = <div className="mx_MemberTile_menu">
<img className="mx_MemberTile_chevron" src="img/chevron-right.png" width="9" height="16" />
<div className="mx_MemberTile_menuItem" onClick={this.onChatClick}>Chat</div>
{muteButton}
{kickButton}
{banButton}
{giveModButton}
</div>;
}
var nameEl;
if (this.state.hover) {
var presence;
@ -181,7 +150,6 @@ module.exports = React.createClass({
return (
<div className={mainClassName} title={ this.getPowerLabel() } onClick={ this.onClick } onMouseEnter={ this.mouseEnter } onMouseLeave={ this.mouseLeave }>
{ menu }
<div className="mx_MemberTile_avatar">
<MemberAvatar member={this.props.member} />
{ power }