Merge pull request #1534 from matrix-org/t3chguy/invite_in_memberinfo

Add invite button to MemberInfo if user has left or wasn't in room
pull/21833/head
David Baker 2017-10-26 11:35:45 +01:00 committed by GitHub
commit 5871a74228
2 changed files with 55 additions and 16 deletions

View File

@ -39,6 +39,7 @@ import { findReadReceiptFromUserId } from '../../../utils/Receipt';
import withMatrixClient from '../../../wrappers/withMatrixClient'; import withMatrixClient from '../../../wrappers/withMatrixClient';
import AccessibleButton from '../elements/AccessibleButton'; import AccessibleButton from '../elements/AccessibleButton';
import GeminiScrollbar from 'react-gemini-scrollbar'; import GeminiScrollbar from 'react-gemini-scrollbar';
import RoomViewStore from '../../../stores/RoomViewStore';
module.exports = withMatrixClient(React.createClass({ module.exports = withMatrixClient(React.createClass({
@ -81,6 +82,7 @@ module.exports = withMatrixClient(React.createClass({
cli.on("Room.receipt", this.onRoomReceipt); cli.on("Room.receipt", this.onRoomReceipt);
cli.on("RoomState.events", this.onRoomStateEvents); cli.on("RoomState.events", this.onRoomStateEvents);
cli.on("RoomMember.name", this.onRoomMemberName); cli.on("RoomMember.name", this.onRoomMemberName);
cli.on("RoomMember.membership", this.onRoomMemberMembership);
cli.on("accountData", this.onAccountData); cli.on("accountData", this.onAccountData);
this._checkIgnoreState(); this._checkIgnoreState();
@ -107,6 +109,7 @@ module.exports = withMatrixClient(React.createClass({
client.removeListener("Room.receipt", this.onRoomReceipt); client.removeListener("Room.receipt", this.onRoomReceipt);
client.removeListener("RoomState.events", this.onRoomStateEvents); client.removeListener("RoomState.events", this.onRoomStateEvents);
client.removeListener("RoomMember.name", this.onRoomMemberName); client.removeListener("RoomMember.name", this.onRoomMemberName);
client.removeListener("RoomMember.membership", this.onRoomMemberMembership);
client.removeListener("accountData", this.onAccountData); client.removeListener("accountData", this.onAccountData);
} }
if (this._cancelDeviceList) { if (this._cancelDeviceList) {
@ -186,6 +189,10 @@ module.exports = withMatrixClient(React.createClass({
this.forceUpdate(); this.forceUpdate();
}, },
onRoomMemberMembership: function(ev, member) {
if (this.props.member.userId === member.userId) this.forceUpdate();
},
onAccountData: function(ev) { onAccountData: function(ev) {
if (ev.getType() === 'm.direct') { if (ev.getType() === 'm.direct') {
this.forceUpdate(); this.forceUpdate();
@ -614,6 +621,7 @@ module.exports = withMatrixClient(React.createClass({
const member = this.props.member; const member = this.props.member;
let ignoreButton = null; let ignoreButton = null;
let inviteUserButton = null;
let readReceiptButton = null; let readReceiptButton = null;
// Only allow the user to ignore the user if its not ourselves // Only allow the user to ignore the user if its not ourselves
@ -644,9 +652,30 @@ module.exports = withMatrixClient(React.createClass({
</AccessibleButton> </AccessibleButton>
); );
} }
if (!member || !member.membership || member.membership === 'leave') {
const roomId = member && member.roomId ? member.roomId : RoomViewStore.getRoomId();
const onInviteUserButton = async () => {
try {
await cli.invite(roomId, member.userId);
} catch (err) {
const ErrorDialog = sdk.getComponent('dialogs.ErrorDialog');
Modal.createTrackedDialog('Failed to invite', '', ErrorDialog, {
title: _t('Failed to invite'),
description: ((err && err.message) ? err.message : "Operation failed"),
});
}
};
inviteUserButton = (
<AccessibleButton onClick={onInviteUserButton} className="mx_MemberInfo_field">
{ _t('Invite') }
</AccessibleButton>
);
}
} }
if (!ignoreButton && !readReceiptButton) return null; if (!ignoreButton && !readReceiptButton && !inviteUserButton) return null;
return ( return (
<div> <div>
@ -654,6 +683,7 @@ module.exports = withMatrixClient(React.createClass({
<div className="mx_MemberInfo_buttons"> <div className="mx_MemberInfo_buttons">
{ readReceiptButton } { readReceiptButton }
{ ignoreButton } { ignoreButton }
{ inviteUserButton }
</div> </div>
</div> </div>
); );
@ -759,9 +789,6 @@ module.exports = withMatrixClient(React.createClass({
</AccessibleButton>; </AccessibleButton>;
} }
// TODO: we should have an invite button if this MemberInfo is showing a user who isn't actually in the current room yet
// e.g. clicking on a linkified userid in a room
let adminTools; let adminTools;
if (kickButton || banButton || muteButton || giveModButton) { if (kickButton || banButton || muteButton || giveModButton) {
adminTools = adminTools =
@ -789,9 +816,29 @@ module.exports = withMatrixClient(React.createClass({
presenceCurrentlyActive = this.props.member.user.currentlyActive; presenceCurrentlyActive = this.props.member.user.currentlyActive;
} }
let roomMemberDetails = null;
if (this.props.member.roomId) { // is in room
const PowerSelector = sdk.getComponent('elements.PowerSelector');
const PresenceLabel = sdk.getComponent('rooms.PresenceLabel');
roomMemberDetails = <div>
<div className="mx_MemberInfo_profileField">
{ _t("Level:") } <b>
<PowerSelector controlled={true}
value={parseInt(this.props.member.powerLevel)}
disabled={!this.state.can.modifyLevel}
onChange={this.onPowerChange} />
</b>
</div>
<div className="mx_MemberInfo_profileField">
<PresenceLabel activeAgo={presenceLastActiveAgo}
currentlyActive={presenceCurrentlyActive}
presenceState={presenceState} />
</div>
</div>;
}
const MemberAvatar = sdk.getComponent('avatars.MemberAvatar'); const MemberAvatar = sdk.getComponent('avatars.MemberAvatar');
const PowerSelector = sdk.getComponent('elements.PowerSelector');
const PresenceLabel = sdk.getComponent('rooms.PresenceLabel');
const EmojiText = sdk.getComponent('elements.EmojiText'); const EmojiText = sdk.getComponent('elements.EmojiText');
return ( return (
<div className="mx_MemberInfo"> <div className="mx_MemberInfo">
@ -807,16 +854,7 @@ module.exports = withMatrixClient(React.createClass({
<div className="mx_MemberInfo_profileField"> <div className="mx_MemberInfo_profileField">
{ this.props.member.userId } { this.props.member.userId }
</div> </div>
<div className="mx_MemberInfo_profileField"> { roomMemberDetails }
{ _t("Level:") } <b>
<PowerSelector controlled={true} value={parseInt(this.props.member.powerLevel)} disabled={!this.state.can.modifyLevel} onChange={this.onPowerChange} />
</b>
</div>
<div className="mx_MemberInfo_profileField">
<PresenceLabel activeAgo={presenceLastActiveAgo}
currentlyActive={presenceCurrentlyActive}
presenceState={presenceState} />
</div>
</div> </div>
{ this._renderUserOptions() } { this._renderUserOptions() }

View File

@ -249,6 +249,7 @@
"Level:": "Level:", "Level:": "Level:",
"and %(count)s others...|other": "and %(count)s others...", "and %(count)s others...|other": "and %(count)s others...",
"and %(count)s others...|one": "and one other...", "and %(count)s others...|one": "and one other...",
"Invite": "Invite",
"Invited": "Invited", "Invited": "Invited",
"Filter room members": "Filter room members", "Filter room members": "Filter room members",
"%(userName)s (power %(powerLevelNumber)s)": "%(userName)s (power %(powerLevelNumber)s)", "%(userName)s (power %(powerLevelNumber)s)": "%(userName)s (power %(powerLevelNumber)s)",