2018-04-11 22:58:04 +00:00
|
|
|
/*
|
|
|
|
Copyright 2015, 2016 OpenMarket Ltd
|
|
|
|
Copyright 2017 Vector Creations Ltd
|
|
|
|
Copyright 2017 New Vector Ltd
|
2018-10-30 16:15:19 +00:00
|
|
|
Copyright 2018 New Vector Ltd
|
2018-04-11 22:58:04 +00:00
|
|
|
|
|
|
|
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.
|
|
|
|
*/
|
|
|
|
|
|
|
|
import React from 'react';
|
|
|
|
import PropTypes from 'prop-types';
|
|
|
|
import classNames from 'classnames';
|
2018-04-12 23:43:44 +00:00
|
|
|
import { _t } from '../../languageHandler';
|
|
|
|
import sdk from '../../index';
|
|
|
|
import dis from '../../dispatcher';
|
2018-04-11 22:58:04 +00:00
|
|
|
import { MatrixClient } from 'matrix-js-sdk';
|
2018-04-12 23:43:44 +00:00
|
|
|
import RateLimitedFunc from '../../ratelimitedfunc';
|
|
|
|
import AccessibleButton from '../../components/views/elements/AccessibleButton';
|
|
|
|
import { showGroupInviteDialog, showGroupAddRoomDialog } from '../../GroupAddressPicker';
|
2018-05-01 10:18:45 +00:00
|
|
|
import GroupStore from '../../stores/GroupStore';
|
2018-04-11 22:58:04 +00:00
|
|
|
|
2018-10-30 16:15:19 +00:00
|
|
|
export default class RightPanel extends React.Component {
|
2018-04-11 22:58:04 +00:00
|
|
|
|
2018-10-30 16:15:19 +00:00
|
|
|
static get propTypes() {
|
|
|
|
return {
|
|
|
|
roomId: React.PropTypes.string, // if showing panels for a given room, this is set
|
|
|
|
groupId: React.PropTypes.string, // if showing panels for a given group, this is set
|
|
|
|
};
|
2018-04-11 22:58:04 +00:00
|
|
|
}
|
|
|
|
|
2018-10-30 16:15:19 +00:00
|
|
|
static get contextTypes() {
|
|
|
|
return {
|
|
|
|
matrixClient: PropTypes.instanceOf(MatrixClient),
|
|
|
|
};
|
2018-04-11 22:58:04 +00:00
|
|
|
}
|
|
|
|
|
2018-10-30 16:15:19 +00:00
|
|
|
static Phase = Object.freeze({
|
2018-04-11 22:58:04 +00:00
|
|
|
RoomMemberList: 'RoomMemberList',
|
|
|
|
GroupMemberList: 'GroupMemberList',
|
|
|
|
GroupRoomList: 'GroupRoomList',
|
|
|
|
GroupRoomInfo: 'GroupRoomInfo',
|
|
|
|
FilePanel: 'FilePanel',
|
|
|
|
NotificationPanel: 'NotificationPanel',
|
|
|
|
RoomMemberInfo: 'RoomMemberInfo',
|
|
|
|
GroupMemberInfo: 'GroupMemberInfo',
|
2018-10-30 16:15:19 +00:00
|
|
|
});
|
2018-04-11 22:58:04 +00:00
|
|
|
|
2018-10-30 16:15:19 +00:00
|
|
|
constructor(props, context) {
|
|
|
|
super(props, context);
|
|
|
|
this.state = {
|
|
|
|
phase: this.props.groupId ? RightPanel.Phase.GroupMemberList : RightPanel.Phase.RoomMemberList,
|
|
|
|
isUserPrivilegedInGroup: null,
|
|
|
|
};
|
|
|
|
this.onAction = this.onAction.bind(this);
|
|
|
|
this.onRoomStateMember = this.onRoomStateMember.bind(this);
|
|
|
|
this.onGroupStoreUpdated = this.onGroupStoreUpdated.bind(this);
|
|
|
|
this.onInviteToGroupButtonClick = this.onInviteToGroupButtonClick.bind(this);
|
|
|
|
this.onAddRoomToGroupButtonClick = this.onAddRoomToGroupButtonClick.bind(this);
|
|
|
|
|
|
|
|
this._delayedUpdate = new RateLimitedFunc(() => {
|
|
|
|
this.forceUpdate();
|
|
|
|
}, 500);
|
|
|
|
}
|
|
|
|
|
|
|
|
componentWillMount() {
|
2018-04-11 22:58:04 +00:00
|
|
|
this.dispatcherRef = dis.register(this.onAction);
|
|
|
|
const cli = this.context.matrixClient;
|
|
|
|
cli.on("RoomState.members", this.onRoomStateMember);
|
|
|
|
this._initGroupStore(this.props.groupId);
|
2018-10-30 16:15:19 +00:00
|
|
|
}
|
2018-04-11 22:58:04 +00:00
|
|
|
|
2018-10-30 16:15:19 +00:00
|
|
|
componentWillUnmount() {
|
2018-04-11 22:58:04 +00:00
|
|
|
dis.unregister(this.dispatcherRef);
|
|
|
|
if (this.context.matrixClient) {
|
|
|
|
this.context.matrixClient.removeListener("RoomState.members", this.onRoomStateMember);
|
|
|
|
}
|
2018-05-01 10:18:45 +00:00
|
|
|
this._unregisterGroupStore(this.props.groupId);
|
2018-10-30 16:15:19 +00:00
|
|
|
}
|
2018-04-11 22:58:04 +00:00
|
|
|
|
|
|
|
componentWillReceiveProps(newProps) {
|
|
|
|
if (newProps.groupId !== this.props.groupId) {
|
2018-05-01 10:18:45 +00:00
|
|
|
this._unregisterGroupStore(this.props.groupId);
|
2018-04-11 22:58:04 +00:00
|
|
|
this._initGroupStore(newProps.groupId);
|
|
|
|
}
|
2018-10-30 16:15:19 +00:00
|
|
|
}
|
2018-04-11 22:58:04 +00:00
|
|
|
|
|
|
|
_initGroupStore(groupId) {
|
|
|
|
if (!groupId) return;
|
2018-05-01 10:18:45 +00:00
|
|
|
GroupStore.registerListener(groupId, this.onGroupStoreUpdated);
|
2018-10-30 16:15:19 +00:00
|
|
|
}
|
2018-04-11 22:58:04 +00:00
|
|
|
|
|
|
|
_unregisterGroupStore() {
|
2018-05-01 10:18:45 +00:00
|
|
|
GroupStore.unregisterListener(this.onGroupStoreUpdated);
|
2018-10-30 16:15:19 +00:00
|
|
|
}
|
2018-04-11 22:58:04 +00:00
|
|
|
|
2018-10-30 16:15:19 +00:00
|
|
|
onGroupStoreUpdated() {
|
2018-04-11 22:58:04 +00:00
|
|
|
this.setState({
|
2018-05-01 10:18:45 +00:00
|
|
|
isUserPrivilegedInGroup: GroupStore.isUserPrivileged(this.props.groupId),
|
2018-04-11 22:58:04 +00:00
|
|
|
});
|
2018-10-30 16:15:19 +00:00
|
|
|
}
|
2018-04-11 22:58:04 +00:00
|
|
|
|
2018-10-30 16:15:19 +00:00
|
|
|
onInviteToGroupButtonClick() {
|
2018-04-11 22:58:04 +00:00
|
|
|
showGroupInviteDialog(this.props.groupId).then(() => {
|
|
|
|
this.setState({
|
2018-10-30 16:15:19 +00:00
|
|
|
phase: RightPanel.Phase.GroupMemberList,
|
2018-04-11 22:58:04 +00:00
|
|
|
});
|
|
|
|
});
|
2018-10-30 16:15:19 +00:00
|
|
|
}
|
2018-04-11 22:58:04 +00:00
|
|
|
|
2018-10-30 16:15:19 +00:00
|
|
|
onAddRoomToGroupButtonClick() {
|
2018-04-11 22:58:04 +00:00
|
|
|
showGroupAddRoomDialog(this.props.groupId).then(() => {
|
|
|
|
this.forceUpdate();
|
|
|
|
});
|
2018-10-30 16:15:19 +00:00
|
|
|
}
|
2018-04-11 22:58:04 +00:00
|
|
|
|
2018-10-30 16:15:19 +00:00
|
|
|
onRoomStateMember(ev, state, member) {
|
2018-09-07 12:16:26 +00:00
|
|
|
if (member.roomId !== this.props.roomId) {
|
|
|
|
return;
|
|
|
|
}
|
2018-04-11 22:58:04 +00:00
|
|
|
// redraw the badge on the membership list
|
2018-10-30 16:15:19 +00:00
|
|
|
if (this.state.phase === RightPanel.Phase.RoomMemberList && member.roomId === this.props.roomId) {
|
2018-04-11 22:58:04 +00:00
|
|
|
this._delayedUpdate();
|
2018-10-30 16:15:19 +00:00
|
|
|
} else if (this.state.phase === RightPanel.Phase.RoomMemberInfo && member.roomId === this.props.roomId &&
|
2018-04-11 22:58:04 +00:00
|
|
|
member.userId === this.state.member.userId) {
|
|
|
|
// refresh the member info (e.g. new power level)
|
|
|
|
this._delayedUpdate();
|
|
|
|
}
|
2018-10-30 16:15:19 +00:00
|
|
|
}
|
2018-04-11 22:58:04 +00:00
|
|
|
|
2018-10-30 16:15:19 +00:00
|
|
|
onAction(payload) {
|
|
|
|
if (payload.action === "view_right_panel_phase") {
|
2018-04-11 22:58:04 +00:00
|
|
|
this.setState({
|
|
|
|
phase: payload.phase,
|
2018-10-30 16:15:19 +00:00
|
|
|
member: payload.member,
|
2018-04-11 22:58:04 +00:00
|
|
|
});
|
|
|
|
}
|
2018-10-30 16:15:19 +00:00
|
|
|
}
|
2018-04-11 22:58:04 +00:00
|
|
|
|
2018-10-30 16:15:19 +00:00
|
|
|
render() {
|
2018-04-11 22:58:04 +00:00
|
|
|
const MemberList = sdk.getComponent('rooms.MemberList');
|
|
|
|
const MemberInfo = sdk.getComponent('rooms.MemberInfo');
|
|
|
|
const NotificationPanel = sdk.getComponent('structures.NotificationPanel');
|
|
|
|
const FilePanel = sdk.getComponent('structures.FilePanel');
|
|
|
|
|
|
|
|
const GroupMemberList = sdk.getComponent('groups.GroupMemberList');
|
|
|
|
const GroupMemberInfo = sdk.getComponent('groups.GroupMemberInfo');
|
|
|
|
const GroupRoomList = sdk.getComponent('groups.GroupRoomList');
|
|
|
|
const GroupRoomInfo = sdk.getComponent('groups.GroupRoomInfo');
|
|
|
|
|
|
|
|
const TintableSvg = sdk.getComponent("elements.TintableSvg");
|
|
|
|
|
|
|
|
const isPhaseGroup = [
|
2018-10-30 16:15:19 +00:00
|
|
|
RightPanel.Phase.GroupMemberInfo,
|
|
|
|
RightPanel.Phase.GroupMemberList,
|
2018-04-11 22:58:04 +00:00
|
|
|
].includes(this.state.phase);
|
|
|
|
|
|
|
|
let panel = <div />;
|
|
|
|
|
2018-10-30 16:15:19 +00:00
|
|
|
if (this.props.roomId && this.state.phase === RightPanel.Phase.RoomMemberList) {
|
|
|
|
panel = <MemberList roomId={this.props.roomId} key={this.props.roomId} />;
|
|
|
|
} else if (this.props.groupId && this.state.phase === RightPanel.Phase.GroupMemberList) {
|
|
|
|
panel = <GroupMemberList groupId={this.props.groupId} key={this.props.groupId} />;
|
|
|
|
} else if (this.state.phase === RightPanel.Phase.GroupRoomList) {
|
|
|
|
panel = <GroupRoomList groupId={this.props.groupId} key={this.props.groupId} />;
|
|
|
|
} else if (this.state.phase === RightPanel.Phase.RoomMemberInfo) {
|
|
|
|
panel = <MemberInfo member={this.state.member} key={this.props.roomId || this.state.member.userId} />;
|
|
|
|
} else if (this.state.phase === RightPanel.Phase.GroupMemberInfo) {
|
|
|
|
panel = <GroupMemberInfo
|
|
|
|
groupMember={this.state.member}
|
|
|
|
groupId={this.props.groupId}
|
|
|
|
key={this.state.member.user_id} />;
|
|
|
|
} else if (this.state.phase === RightPanel.Phase.GroupRoomInfo) {
|
|
|
|
panel = <GroupRoomInfo
|
|
|
|
groupRoomId={this.state.groupRoomId}
|
|
|
|
groupId={this.props.groupId}
|
|
|
|
key={this.state.groupRoomId} />;
|
|
|
|
} else if (this.state.phase === RightPanel.Phase.NotificationPanel) {
|
|
|
|
panel = <NotificationPanel />;
|
|
|
|
} else if (this.state.phase === RightPanel.Phase.FilePanel) {
|
|
|
|
panel = <FilePanel roomId={this.props.roomId} />;
|
2018-04-11 22:58:04 +00:00
|
|
|
}
|
|
|
|
|
2018-10-30 16:15:19 +00:00
|
|
|
// TODO: either include this in the DOM again, or move it to other component
|
2018-04-11 22:58:04 +00:00
|
|
|
if (this.props.groupId && this.state.isUserPrivilegedInGroup) {
|
2018-10-31 11:20:10 +00:00
|
|
|
// inviteGroup =
|
|
|
|
isPhaseGroup ? (
|
2018-04-11 22:58:04 +00:00
|
|
|
<AccessibleButton className="mx_RightPanel_invite" onClick={this.onInviteToGroupButtonClick}>
|
|
|
|
<div className="mx_RightPanel_icon" >
|
|
|
|
<TintableSvg src="img/icon-invite-people.svg" width="35" height="35" />
|
|
|
|
</div>
|
|
|
|
<div className="mx_RightPanel_message">{ _t('Invite to this community') }</div>
|
|
|
|
</AccessibleButton>
|
|
|
|
) : (
|
|
|
|
<AccessibleButton className="mx_RightPanel_invite" onClick={this.onAddRoomToGroupButtonClick}>
|
|
|
|
<div className="mx_RightPanel_icon" >
|
|
|
|
<TintableSvg src="img/icons-room-add.svg" width="35" height="35" />
|
|
|
|
</div>
|
|
|
|
<div className="mx_RightPanel_message">{ _t('Add rooms to this community') }</div>
|
|
|
|
</AccessibleButton>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
const classes = classNames("mx_RightPanel", "mx_fadable", {
|
|
|
|
"collapsed": this.props.collapsed,
|
|
|
|
"mx_fadable_faded": this.props.disabled,
|
2018-11-06 14:29:47 +00:00
|
|
|
"dark-panel": true,
|
2018-04-11 22:58:04 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
return (
|
|
|
|
<aside className={classes}>
|
|
|
|
{ panel }
|
|
|
|
</aside>
|
|
|
|
);
|
2018-10-30 16:15:19 +00:00
|
|
|
}
|
|
|
|
}
|