2017-11-01 20:13:00 +03:00
|
|
|
/*
|
|
|
|
Copyright 2017 New Vector 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.
|
|
|
|
*/
|
|
|
|
|
|
|
|
import PropTypes from 'prop-types';
|
|
|
|
import React from 'react';
|
|
|
|
import { MatrixClient } from 'matrix-js-sdk';
|
|
|
|
import dis from '../../../dispatcher';
|
|
|
|
import Modal from '../../../Modal';
|
|
|
|
import sdk from '../../../index';
|
|
|
|
import { _t } from '../../../languageHandler';
|
2018-05-01 13:18:45 +03:00
|
|
|
import GroupStore from '../../../stores/GroupStore';
|
2017-11-01 20:13:00 +03:00
|
|
|
|
|
|
|
module.exports = React.createClass({
|
|
|
|
displayName: 'GroupRoomInfo',
|
|
|
|
|
|
|
|
contextTypes: {
|
|
|
|
matrixClient: PropTypes.instanceOf(MatrixClient),
|
|
|
|
},
|
|
|
|
|
|
|
|
propTypes: {
|
|
|
|
groupId: PropTypes.string,
|
2017-11-02 16:25:55 +03:00
|
|
|
groupRoomId: PropTypes.string,
|
2017-11-01 20:13:00 +03:00
|
|
|
},
|
|
|
|
|
|
|
|
getInitialState: function() {
|
|
|
|
return {
|
|
|
|
isUserPrivilegedInGroup: null,
|
2017-11-02 16:25:55 +03:00
|
|
|
groupRoom: null,
|
|
|
|
groupRoomPublicityLoading: false,
|
|
|
|
groupRoomRemoveLoading: false,
|
2017-11-01 20:13:00 +03:00
|
|
|
};
|
|
|
|
},
|
|
|
|
|
|
|
|
componentWillMount: function() {
|
|
|
|
this._initGroupStore(this.props.groupId);
|
|
|
|
},
|
|
|
|
|
|
|
|
componentWillReceiveProps(newProps) {
|
|
|
|
if (newProps.groupId !== this.props.groupId) {
|
2018-05-01 13:18:45 +03:00
|
|
|
this._unregisterGroupStore(this.props.groupId);
|
2017-11-01 20:13:00 +03:00
|
|
|
this._initGroupStore(newProps.groupId);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2017-11-02 16:25:55 +03:00
|
|
|
componentWillUnmount() {
|
2018-05-01 13:18:45 +03:00
|
|
|
this._unregisterGroupStore(this.props.groupId);
|
2017-11-02 16:25:55 +03:00
|
|
|
},
|
|
|
|
|
2017-11-01 20:13:00 +03:00
|
|
|
_initGroupStore(groupId) {
|
2018-05-01 13:18:45 +03:00
|
|
|
GroupStore.registerListener(groupId, this.onGroupStoreUpdated);
|
2017-11-01 20:13:00 +03:00
|
|
|
},
|
|
|
|
|
2018-05-01 13:18:45 +03:00
|
|
|
_unregisterGroupStore(groupId) {
|
|
|
|
GroupStore.unregisterListener(this.onGroupStoreUpdated);
|
2017-11-01 20:13:00 +03:00
|
|
|
},
|
|
|
|
|
2017-11-02 16:25:55 +03:00
|
|
|
_updateGroupRoom() {
|
|
|
|
this.setState({
|
2018-05-01 13:18:45 +03:00
|
|
|
groupRoom: GroupStore.getGroupRooms(this.props.groupId).find(
|
2017-11-02 16:25:55 +03:00
|
|
|
(r) => r.roomId === this.props.groupRoomId,
|
|
|
|
),
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
2017-11-01 20:13:00 +03:00
|
|
|
onGroupStoreUpdated: function() {
|
|
|
|
this.setState({
|
2018-05-01 13:18:45 +03:00
|
|
|
isUserPrivilegedInGroup: GroupStore.isUserPrivileged(this.props.groupId),
|
2017-11-01 20:13:00 +03:00
|
|
|
});
|
2017-11-02 16:25:55 +03:00
|
|
|
this._updateGroupRoom();
|
2017-11-01 20:13:00 +03:00
|
|
|
},
|
|
|
|
|
|
|
|
_onRemove: function(e) {
|
|
|
|
const groupId = this.props.groupId;
|
2017-11-02 16:25:55 +03:00
|
|
|
const roomName = this.state.groupRoom.displayname;
|
2017-11-01 20:13:00 +03:00
|
|
|
e.preventDefault();
|
|
|
|
e.stopPropagation();
|
|
|
|
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
|
|
|
Modal.createTrackedDialog('Confirm removal of group from room', '', QuestionDialog, {
|
|
|
|
title: _t("Are you sure you want to remove '%(roomName)s' from %(groupId)s?", {roomName, groupId}),
|
|
|
|
description: _t("Removing a room from the community will also remove it from the community page."),
|
|
|
|
button: _t("Remove"),
|
|
|
|
onFinished: (proceed) => {
|
|
|
|
if (!proceed) return;
|
2017-11-02 16:25:55 +03:00
|
|
|
this.setState({groupRoomRemoveLoading: true});
|
2017-11-01 20:13:00 +03:00
|
|
|
const groupId = this.props.groupId;
|
2017-11-02 16:25:55 +03:00
|
|
|
const roomId = this.props.groupRoomId;
|
2018-05-01 13:18:45 +03:00
|
|
|
GroupStore.removeRoomFromGroup(this.props.groupId, roomId).then(() => {
|
2017-11-01 20:13:00 +03:00
|
|
|
dis.dispatch({
|
|
|
|
action: "view_group_room_list",
|
|
|
|
});
|
|
|
|
}).catch((err) => {
|
|
|
|
console.error(`Error whilst removing ${roomId} from ${groupId}`, err);
|
|
|
|
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
|
|
|
Modal.createTrackedDialog('Failed to remove room from group', '', ErrorDialog, {
|
|
|
|
title: _t("Failed to remove room from community"),
|
|
|
|
description: _t(
|
|
|
|
"Failed to remove '%(roomName)s' from %(groupId)s", {groupId, roomName},
|
|
|
|
),
|
|
|
|
});
|
|
|
|
}).finally(() => {
|
2017-11-02 16:25:55 +03:00
|
|
|
this.setState({groupRoomRemoveLoading: false});
|
2017-11-01 20:13:00 +03:00
|
|
|
});
|
|
|
|
},
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
|
|
|
_onCancel: function(e) {
|
|
|
|
dis.dispatch({
|
|
|
|
action: "view_group_room_list",
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
2017-11-02 16:25:55 +03:00
|
|
|
_changeGroupRoomPublicity(e) {
|
|
|
|
const isPublic = e.target.value === "public";
|
|
|
|
this.setState({
|
|
|
|
groupRoomPublicityLoading: true,
|
|
|
|
});
|
|
|
|
const groupId = this.props.groupId;
|
|
|
|
const roomId = this.props.groupRoomId;
|
|
|
|
const roomName = this.state.groupRoom.displayname;
|
2018-05-01 13:18:45 +03:00
|
|
|
GroupStore.updateGroupRoomVisibility(this.props.groupId, roomId, isPublic).catch((err) => {
|
2017-11-02 16:25:55 +03:00
|
|
|
console.error(`Error whilst changing visibility of ${roomId} in ${groupId} to ${isPublic}`, err);
|
|
|
|
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
|
|
|
Modal.createTrackedDialog('Failed to remove room from group', '', ErrorDialog, {
|
|
|
|
title: _t("Something went wrong!"),
|
|
|
|
description: _t(
|
|
|
|
"The visibility of '%(roomName)s' in %(groupId)s could not be updated.",
|
|
|
|
{roomName, groupId},
|
|
|
|
),
|
|
|
|
});
|
|
|
|
}).finally(() => {
|
|
|
|
this.setState({
|
|
|
|
groupRoomPublicityLoading: false,
|
|
|
|
});
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
2017-11-01 20:13:00 +03:00
|
|
|
render: function() {
|
|
|
|
const BaseAvatar = sdk.getComponent('avatars.BaseAvatar');
|
|
|
|
const EmojiText = sdk.getComponent('elements.EmojiText');
|
|
|
|
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
|
2017-11-02 16:25:55 +03:00
|
|
|
const InlineSpinner = sdk.getComponent('elements.InlineSpinner');
|
2018-03-21 15:00:56 +03:00
|
|
|
const GeminiScrollbarWrapper = sdk.getComponent("elements.GeminiScrollbarWrapper");
|
2017-11-02 16:25:55 +03:00
|
|
|
if (this.state.groupRoomRemoveLoading || !this.state.groupRoom) {
|
2017-11-01 20:13:00 +03:00
|
|
|
const Spinner = sdk.getComponent("elements.Spinner");
|
2017-11-02 16:25:55 +03:00
|
|
|
return <div className="mx_MemberInfo">
|
|
|
|
<Spinner />
|
|
|
|
</div>;
|
2017-11-01 20:13:00 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
let adminTools;
|
|
|
|
if (this.state.isUserPrivilegedInGroup) {
|
|
|
|
adminTools =
|
|
|
|
<div className="mx_MemberInfo_adminTools">
|
|
|
|
<h3>{ _t("Admin Tools") }</h3>
|
|
|
|
<div className="mx_MemberInfo_buttons">
|
|
|
|
<AccessibleButton className="mx_MemberInfo_field" onClick={this._onRemove}>
|
|
|
|
{ _t('Remove from community') }
|
|
|
|
</AccessibleButton>
|
|
|
|
</div>
|
2017-11-02 16:25:55 +03:00
|
|
|
<h3>
|
|
|
|
{ _t('Visibility in Room List') }
|
|
|
|
{ this.state.groupRoomPublicityLoading ?
|
|
|
|
<InlineSpinner /> : <div />
|
|
|
|
}
|
|
|
|
</h3>
|
|
|
|
<div>
|
|
|
|
<label>
|
|
|
|
<input type="radio"
|
|
|
|
value="public"
|
|
|
|
checked={this.state.groupRoom.isPublic}
|
|
|
|
onClick={this._changeGroupRoomPublicity}
|
|
|
|
/>
|
2017-11-02 18:04:40 +03:00
|
|
|
<div className="mx_MemberInfo_label_text">
|
|
|
|
{ _t('Visible to everyone') }
|
|
|
|
</div>
|
2017-11-02 16:25:55 +03:00
|
|
|
</label>
|
|
|
|
</div>
|
|
|
|
<div>
|
|
|
|
<label>
|
|
|
|
<input type="radio"
|
|
|
|
value="private"
|
|
|
|
checked={!this.state.groupRoom.isPublic}
|
|
|
|
onClick={this._changeGroupRoomPublicity}
|
|
|
|
/>
|
2017-11-02 18:04:40 +03:00
|
|
|
<div className="mx_MemberInfo_label_text">
|
|
|
|
{ _t('Only visible to community members') }
|
|
|
|
</div>
|
2017-11-02 16:25:55 +03:00
|
|
|
</label>
|
|
|
|
</div>
|
2017-11-01 20:13:00 +03:00
|
|
|
</div>;
|
|
|
|
}
|
|
|
|
|
|
|
|
const avatarUrl = this.context.matrixClient.mxcUrlToHttp(
|
2017-11-02 16:25:55 +03:00
|
|
|
this.state.groupRoom.avatarUrl,
|
2017-11-01 20:13:00 +03:00
|
|
|
36, 36, 'crop',
|
|
|
|
);
|
|
|
|
|
2017-11-02 16:25:55 +03:00
|
|
|
const groupRoomName = this.state.groupRoom.displayname;
|
2017-11-01 20:13:00 +03:00
|
|
|
const avatar = <BaseAvatar name={groupRoomName} width={36} height={36} url={avatarUrl} />;
|
|
|
|
return (
|
|
|
|
<div className="mx_MemberInfo">
|
2018-03-21 15:00:56 +03:00
|
|
|
<GeminiScrollbarWrapper autoshow={true}>
|
2017-11-02 16:25:55 +03:00
|
|
|
<AccessibleButton className="mx_MemberInfo_cancel" onClick={this._onCancel}>
|
2019-01-11 04:37:28 +03:00
|
|
|
<img src={require("../../../../res/img/cancel.svg")} width="18" height="18" className="mx_filterFlipColor" />
|
2017-11-01 20:13:00 +03:00
|
|
|
</AccessibleButton>
|
|
|
|
<div className="mx_MemberInfo_avatar">
|
|
|
|
{ avatar }
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<EmojiText element="h2">{ groupRoomName }</EmojiText>
|
|
|
|
|
|
|
|
<div className="mx_MemberInfo_profile">
|
|
|
|
<div className="mx_MemberInfo_profileField">
|
2017-11-02 16:25:55 +03:00
|
|
|
{ this.state.groupRoom.canonical_alias }
|
2017-11-01 20:13:00 +03:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
{ adminTools }
|
2018-03-21 15:00:56 +03:00
|
|
|
</GeminiScrollbarWrapper>
|
2017-11-01 20:13:00 +03:00
|
|
|
</div>
|
|
|
|
);
|
|
|
|
},
|
|
|
|
});
|