diff --git a/src/components/views/groups/GroupMemberInfo.js b/src/components/views/groups/GroupMemberInfo.js
new file mode 100644
index 0000000000..70aa7d4504
--- /dev/null
+++ b/src/components/views/groups/GroupMemberInfo.js
@@ -0,0 +1,158 @@
+/*
+Copyright 2017 Vector Creations 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 classNames from 'classnames';
+import dis from '../../../dispatcher';
+import Modal from '../../../Modal';
+import sdk from '../../../index';
+import { _t } from '../../../languageHandler';
+import createRoom from '../../../createRoom';
+import DMRoomMap from '../../../utils/DMRoomMap';
+import Unread from '../../../Unread';
+import { GroupMemberType } from '../../../groups';
+import { findReadReceiptFromUserId } from '../../../utils/Receipt';
+import withMatrixClient from '../../../wrappers/withMatrixClient';
+import AccessibleButton from '../elements/AccessibleButton';
+import GeminiScrollbar from 'react-gemini-scrollbar';
+
+
+module.exports = withMatrixClient(React.createClass({
+ displayName: 'GroupMemberInfo',
+
+ propTypes: {
+ matrixClient: PropTypes.object.isRequired,
+ groupId: PropTypes.string,
+ member: GroupMemberType,
+ },
+
+ componentWillMount: function() {
+ this._fetchMembers();
+ },
+
+ _fetchMembers: function() {
+ this.setState({fetching: true});
+ this.props.matrixClient.getGroupUsers(this.props.groupId).then((result) => {
+ this.setState({
+ members: result.chunk,
+ fetching: false,
+ });
+ }).catch((e) => {
+ this.setState({fetching: false});
+ console.error("Failed to get group member list: " + e);
+ });
+ },
+
+ _onKick: function() {
+ const ConfirmUserActionDialog = sdk.getComponent("dialogs.ConfirmUserActionDialog");
+ Modal.createDialog(ConfirmUserActionDialog, {
+ groupMember: this.props.member,
+ action: _t('Remove from group'),
+ danger: true,
+ onFinished: (proceed) => {
+ },
+ });
+ },
+
+ onCancel: function(e) {
+ dis.dispatch({
+ action: "view_user",
+ member: null
+ });
+ },
+
+ onRoomTileClick(roomId) {
+ dis.dispatch({
+ action: 'view_room',
+ room_id: roomId,
+ });
+ },
+
+ render: function() {
+ if (this.state.fetching) {
+ const Loader = sdk.getComponent("elements.Spinner");
+ return
;
+ }
+ if (!this.state.members) return null;
+
+ let targetIsInGroup = false;
+ for (const m of this.state.members) {
+ if (m.user_id == this.props.member.userId) {
+ targetIsInGroup = true;
+ }
+ }
+
+ let kickButton, adminButton;
+
+ if (targetIsInGroup) {
+ kickButton = (
+
+ {_t('Remove from group')}
+
+ );
+
+ // No make/revoke admin API yet
+ /*const opLabel = this.state.isTargetMod ? _t("Revoke Moderator") : _t("Make Moderator");
+ giveModButton =
+ {giveOpLabel}
+ ;*/
+ }
+
+ let adminTools;
+ if (kickButton || adminButton) {
+ adminTools =
+
+
{_t("Admin tools")}
+
+
+ {kickButton}
+ {adminButton}
+
+
;
+ }
+
+ const BaseAvatar = sdk.getComponent('avatars.BaseAvatar');
+ const avatar = (
+
+ );
+
+ const memberName = this.props.member.userId;
+
+ const EmojiText = sdk.getComponent('elements.EmojiText');
+ return (
+
+
+
+
+ {avatar}
+
+
+ {memberName}
+
+
+
+ { this.props.member.userId }
+
+
+
+ { adminTools }
+
+
+ );
+ }
+}));
diff --git a/src/components/views/groups/GroupMemberList.js b/src/components/views/groups/GroupMemberList.js
index 48d49dc04b..0f74ff5eed 100644
--- a/src/components/views/groups/GroupMemberList.js
+++ b/src/components/views/groups/GroupMemberList.js
@@ -17,6 +17,7 @@ import React from 'react';
import { _t } from '../../../languageHandler';
import Promise from 'bluebird';
import sdk from '../../../index';
+import { groupMemberFromApiObject } from '../../../groups';
import GeminiScrollbar from 'react-gemini-scrollbar';
import PropTypes from 'prop-types';
import withMatrixClient from '../../../wrappers/withMatrixClient';
@@ -47,7 +48,9 @@ export default withMatrixClient(React.createClass({
this.setState({fetching: true});
this.props.matrixClient.getGroupUsers(this.props.groupId).then((result) => {
this.setState({
- members: result.chunk,
+ members: result.chunk.map((apiMember) => {
+ return groupMemberFromApiObject(apiMember);
+ }),
fetching: false,
});
}).catch((e) => {
@@ -86,7 +89,7 @@ export default withMatrixClient(React.createClass({
const memberList = this.state.members.filter((m) => {
if (query) {
//const matchesName = m.name.toLowerCase().indexOf(query) !== -1;
- const matchesId = m.user_id.toLowerCase().indexOf(query) !== -1;
+ const matchesId = m.userId.toLowerCase().indexOf(query) !== -1;
if (/*!matchesName &&*/ !matchesId) {
return false;
@@ -94,9 +97,9 @@ export default withMatrixClient(React.createClass({
}
return true;
- }).map(function(m) {
+ }).map((m) => {
return (
-
+
);
});
diff --git a/src/components/views/groups/GroupMemberTile.js b/src/components/views/groups/GroupMemberTile.js
index 1ef59fb1a6..d129fb9440 100644
--- a/src/components/views/groups/GroupMemberTile.js
+++ b/src/components/views/groups/GroupMemberTile.js
@@ -19,6 +19,7 @@ import PropTypes from 'prop-types';
import sdk from '../../../index';
import dis from '../../../dispatcher';
import { _t } from '../../../languageHandler';
+import { GroupMemberType } from '../../../groups';
import withMatrixClient from '../../../wrappers/withMatrixClient';
import Matrix from "matrix-js-sdk";
@@ -27,9 +28,8 @@ export default withMatrixClient(React.createClass({
propTypes: {
matrixClient: PropTypes.object,
- member: PropTypes.shape({
- user_id: PropTypes.string.isRequired,
- }).isRequired,
+ groupId: PropTypes.string.isRequired,
+ member: GroupMemberType.isRequired,
},
getInitialState: function() {
@@ -37,10 +37,10 @@ export default withMatrixClient(React.createClass({
},
onClick: function(e) {
- const member = new Matrix.RoomMember(null, this.props.member.user_id);
dis.dispatch({
- action: 'view_user',
- member: member,
+ action: 'view_group_user',
+ member: this.props.member,
+ groupId: this.props.groupId,
});
},
@@ -52,10 +52,10 @@ export default withMatrixClient(React.createClass({
const BaseAvatar = sdk.getComponent('avatars.BaseAvatar');
const EntityTile = sdk.getComponent('rooms.EntityTile');
- const name = this.props.member.user_id;
+ const name = this.props.member.userId;
const av = (
-
+
);
return (
diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json
index a12d277a92..82e10bf3d1 100644
--- a/src/i18n/strings/en_EN.json
+++ b/src/i18n/strings/en_EN.json
@@ -963,5 +963,6 @@
"Failed to upload image": "Failed to upload image",
"Failed to update group": "Failed to update group",
"Description": "Description",
- "Filter group members": "Filter group members"
+ "Filter group members": "Filter group members",
+ "Remove from group": "Remove from group"
}