From 0dcd52d88f9886860eba2d1b39a9a7379070f79b Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 1 Nov 2017 17:12:22 +0000 Subject: [PATCH 1/3] Fix some react warnings firing --- src/components/views/avatars/GroupAvatar.js | 4 ++-- src/components/views/rooms/RoomDetailList.js | 24 +++++++++++--------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/components/views/avatars/GroupAvatar.js b/src/components/views/avatars/GroupAvatar.js index 4f34cc2c16..5a18213eec 100644 --- a/src/components/views/avatars/GroupAvatar.js +++ b/src/components/views/avatars/GroupAvatar.js @@ -54,11 +54,11 @@ export default React.createClass({ // extract the props we use from props so we can pass any others through // should consider adding this as a global rule in js-sdk? /*eslint no-unused-vars: ["error", { "ignoreRestSiblings": true }]*/ - const {groupId, groupAvatarUrl, ...otherProps} = this.props; + const {groupId, groupAvatarUrl, groupName, ...otherProps} = this.props; return ( Date: Wed, 1 Nov 2017 17:13:00 +0000 Subject: [PATCH 2/3] Implement simple GroupRoomInfo which replaces the "X" on the GroupRoomTile with "Remove from community" under Admin Tools. --- src/components/views/groups/GroupRoomInfo.js | 170 +++++++++++++++++++ src/components/views/groups/GroupRoomTile.js | 76 +-------- src/groups.js | 3 + 3 files changed, 178 insertions(+), 71 deletions(-) create mode 100644 src/components/views/groups/GroupRoomInfo.js diff --git a/src/components/views/groups/GroupRoomInfo.js b/src/components/views/groups/GroupRoomInfo.js new file mode 100644 index 0000000000..647651a0d8 --- /dev/null +++ b/src/components/views/groups/GroupRoomInfo.js @@ -0,0 +1,170 @@ +/* +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'; +import { GroupRoomType } from '../../../groups'; +import GroupStoreCache from '../../../stores/GroupStoreCache'; +import GeminiScrollbar from 'react-gemini-scrollbar'; + +module.exports = React.createClass({ + displayName: 'GroupRoomInfo', + + contextTypes: { + matrixClient: PropTypes.instanceOf(MatrixClient), + }, + + propTypes: { + groupId: PropTypes.string, + groupRoom: GroupRoomType, + }, + + getInitialState: function() { + return { + removingRoom: false, + isUserPrivilegedInGroup: null, + }; + }, + + componentWillMount: function() { + this._initGroupStore(this.props.groupId); + }, + + componentWillReceiveProps(newProps) { + if (newProps.groupId !== this.props.groupId) { + this._unregisterGroupStore(); + this._initGroupStore(newProps.groupId); + } + }, + + _initGroupStore(groupId) { + this._groupStore = GroupStoreCache.getGroupStore( + this.context.matrixClient, this.props.groupId, + ); + this._groupStore.registerListener(this.onGroupStoreUpdated); + }, + + _unregisterGroupStore() { + if (this._groupStore) { + this._groupStore.unregisterListener(this.onGroupStoreUpdated); + } + }, + + onGroupStoreUpdated: function() { + this.setState({ + isUserPrivilegedInGroup: this._groupStore.isUserPrivileged(), + }); + }, + + _onRemove: function(e) { + const groupId = this.props.groupId; + const roomName = this.props.groupRoom.displayname; + 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; + this.setState({removingRoom: true}); + const groupId = this.props.groupId; + const roomId = this.props.groupRoom.roomId; + this._groupStore.removeRoomFromGroup(roomId).then(() => { + 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(() => { + this.setState({removingRoom: false}); + }); + }, + }); + }, + + _onCancel: function(e) { + dis.dispatch({ + action: "view_group_room_list", + }); + }, + + render: function() { + const BaseAvatar = sdk.getComponent('avatars.BaseAvatar'); + const EmojiText = sdk.getComponent('elements.EmojiText'); + const AccessibleButton = sdk.getComponent('elements.AccessibleButton'); + if (this.state.removingRoom) { + const Spinner = sdk.getComponent("elements.Spinner"); + return ; + } + + let adminTools; + if (this.state.isUserPrivilegedInGroup) { + adminTools = +
+

{ _t("Admin Tools") }

+
+ + { _t('Remove from community') } + +
+
; + } + + const avatarUrl = this.context.matrixClient.mxcUrlToHttp( + this.props.groupRoom.avatarUrl, + 36, 36, 'crop', + ); + + const groupRoomName = this.props.groupRoom.displayname; + const avatar = ; + return ( +
+ + + + +
+ { avatar } +
+ + { groupRoomName } + +
+
+ { this.props.groupRoom.canonical_alias } +
+
+ + { adminTools } +
+
+ ); + }, +}); diff --git a/src/components/views/groups/GroupRoomTile.js b/src/components/views/groups/GroupRoomTile.js index 94dc8e593f..e445f06044 100644 --- a/src/components/views/groups/GroupRoomTile.js +++ b/src/components/views/groups/GroupRoomTile.js @@ -16,13 +16,10 @@ limitations under the License. import React from 'react'; import {MatrixClient} from 'matrix-js-sdk'; -import { _t } from '../../../languageHandler'; import PropTypes from 'prop-types'; import sdk from '../../../index'; import dis from '../../../dispatcher'; import { GroupRoomType } from '../../../groups'; -import GroupStoreCache from '../../../stores/GroupStoreCache'; -import Modal from '../../../Modal'; const GroupRoomTile = React.createClass({ displayName: 'GroupRoomTile', @@ -32,68 +29,11 @@ const GroupRoomTile = React.createClass({ groupRoom: GroupRoomType.isRequired, }, - getInitialState: function() { - return { - name: this.calculateRoomName(this.props.groupRoom), - }; - }, - - componentWillReceiveProps: function(newProps) { - this.setState({ - name: this.calculateRoomName(newProps.groupRoom), - }); - }, - - calculateRoomName: function(groupRoom) { - return groupRoom.name || groupRoom.canonicalAlias || _t("Unnamed Room"); - }, - - removeRoomFromGroup: function() { - const groupId = this.props.groupId; - const groupStore = GroupStoreCache.getGroupStore(this.context.matrixClient, groupId); - const roomName = this.state.name; - const roomId = this.props.groupRoom.roomId; - groupStore.removeRoomFromGroup(roomId) - .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}), - }); - }); - }, - onClick: function(e) { - let roomId; - let roomAlias; - if (this.props.groupRoom.canonicalAlias) { - roomAlias = this.props.groupRoom.canonicalAlias; - } else { - roomId = this.props.groupRoom.roomId; - } dis.dispatch({ - action: 'view_room', - room_id: roomId, - room_alias: roomAlias, - }); - }, - - onDeleteClick: function(e) { - const groupId = this.props.groupId; - const roomName = this.state.name; - 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: (success) => { - if (success) { - this.removeRoomFromGroup(); - } - }, + action: 'view_group_room', + groupId: this.props.groupId, + groupRoom: this.props.groupRoom, }); }, @@ -106,7 +46,7 @@ const GroupRoomTile = React.createClass({ ); const av = ( - @@ -118,14 +58,8 @@ const GroupRoomTile = React.createClass({ { av }
- { this.state.name } + { this.props.groupRoom.displayname }
- - - ); }, diff --git a/src/groups.js b/src/groups.js index 06db5d067f..3c80677b0c 100644 --- a/src/groups.js +++ b/src/groups.js @@ -15,6 +15,7 @@ limitations under the License. */ import PropTypes from 'prop-types'; +import { _t } from './languageHandler.js'; export const GroupMemberType = PropTypes.shape({ userId: PropTypes.string.isRequired, @@ -23,6 +24,7 @@ export const GroupMemberType = PropTypes.shape({ }); export const GroupRoomType = PropTypes.shape({ + displayname: PropTypes.string, name: PropTypes.string, roomId: PropTypes.string.isRequired, canonicalAlias: PropTypes.string, @@ -39,6 +41,7 @@ export function groupMemberFromApiObject(apiObject) { export function groupRoomFromApiObject(apiObject) { return { + displayname: apiObject.name || apiObject.canonical_alias || _t("Unnamed Room"), name: apiObject.name, roomId: apiObject.room_id, canonicalAlias: apiObject.canonical_alias, From 80f79e6b8489d3343c03b4787989db598f73f61f Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 1 Nov 2017 17:58:45 +0000 Subject: [PATCH 3/3] Generate translations --- src/i18n/strings/en_EN.json | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index bffe3b3264..037f804447 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -158,6 +158,7 @@ "%(names)s and %(lastPerson)s are typing": "%(names)s and %(lastPerson)s are typing", "Failure to create room": "Failure to create room", "Server may be unavailable, overloaded, or you hit a bug.": "Server may be unavailable, overloaded, or you hit a bug.", + "Unnamed Room": "Unnamed Room", "Your browser does not support the required cryptography extensions": "Your browser does not support the required cryptography extensions", "Not a valid Riot keyfile": "Not a valid Riot keyfile", "Authentication check failed: incorrect password?": "Authentication check failed: incorrect password?", @@ -328,7 +329,6 @@ "Rooms": "Rooms", "Low priority": "Low priority", "Historical": "Historical", - "Unnamed Room": "Unnamed Room", "a room": "a room", "Unable to ascertain that the address this invite was sent to matches one associated with your account.": "Unable to ascertain that the address this invite was sent to matches one associated with your account.", "This invitation was sent to an email address which is not associated with this account:": "This invitation was sent to an email address which is not associated with this account:", @@ -491,13 +491,12 @@ "Failed to withdraw invitation": "Failed to withdraw invitation", "Failed to remove user from community": "Failed to remove user from community", "Filter community members": "Filter community members", - "Filter community rooms": "Filter community rooms", - "Failed to remove room from community": "Failed to remove room from community", - "Failed to remove '%(roomName)s' from %(groupId)s": "Failed to remove '%(roomName)s' from %(groupId)s", "Are you sure you want to remove '%(roomName)s' from %(groupId)s?": "Are you sure you want to remove '%(roomName)s' from %(groupId)s?", "Removing a room from the community will also remove it from the community page.": "Removing a room from the community will also remove it from the community page.", "Remove": "Remove", - "Remove this room from the community": "Remove this room from the community", + "Failed to remove room from community": "Failed to remove room from community", + "Failed to remove '%(roomName)s' from %(groupId)s": "Failed to remove '%(roomName)s' from %(groupId)s", + "Filter community rooms": "Filter community rooms", "Unknown Address": "Unknown Address", "NOTE: Apps are not end-to-end encrypted": "NOTE: Apps are not end-to-end encrypted", "Do you want to load widget from URL:": "Do you want to load widget from URL:",