From ad2541299f9bd12c2f3bd52d5a3f42f4dcf71021 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 21 Jun 2016 16:47:40 +0100 Subject: [PATCH 1/3] Add ability to delete an alias from room directory Hidden behind shift-click for now, but we're going to need to do this a lot to moderate the public room list. --- src/components/structures/RoomDirectory.js | 57 ++++++++++++++++++---- 1 file changed, 48 insertions(+), 9 deletions(-) diff --git a/src/components/structures/RoomDirectory.js b/src/components/structures/RoomDirectory.js index cc16e3c6e6..3e3d295986 100644 --- a/src/components/structures/RoomDirectory.js +++ b/src/components/structures/RoomDirectory.js @@ -52,6 +52,18 @@ module.exports = React.createClass({ }, componentDidMount: function() { + this.getPublicRooms(); + }, + + componentWillUnmount: function() { + // dis.dispatch({ + // action: 'ui_opacity', + // sideOpacity: 1.0, + // middleOpacity: 1.0, + // }); + }, + + getPublicRooms: function() { var self = this; MatrixClientPeg.get().publicRooms(function (err, data) { if (err) { @@ -68,20 +80,43 @@ module.exports = React.createClass({ publicRooms: data.chunk, loading: false, }); - self.forceUpdate(); } }); }, - componentWillUnmount: function() { - // dis.dispatch({ - // action: 'ui_opacity', - // sideOpacity: 1.0, - // middleOpacity: 1.0, - // }); + deleteAliasClicked: function(roomAlias) { + var QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); + var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); + Modal.createDialog(QuestionDialog, { + title: "Delete Alias", + description: `Are you sure you want to remove the alias '${roomAlias}'?`, + onFinished: (should_delete) => { + if (should_delete) { + var Loader = sdk.getComponent("elements.Spinner"); + var modal = Modal.createDialog(Loader); + + MatrixClientPeg.get().deleteAlias(roomAlias).done(() => { + modal.close(); + this.getPublicRooms(); + }, function(err) { + modal.close(); + Modal.createDialog(ErrorDialog, { + title: "Failed to delete alias", + description: err.toString() + }); + }); + } + } + }); }, - showRoom: function(roomId, roomAlias) { + showRoom: function(roomId, roomAlias, ev) { + if (ev.shiftKey) { + ev.preventDefault(); + this.deleteAliasClicked(roomAlias); + return; + } + // extract the metadata from the publicRooms structure to pass // as out-of-band data to view_room, because we get information // here that we can't get other than by joining the room in some @@ -175,7 +210,11 @@ module.exports = React.createClass({ topic = linkifyString(sanitizeHtml(topic)); rows.unshift( - + {ev.preventDefault();}} + > Date: Wed, 22 Jun 2016 14:52:55 +0100 Subject: [PATCH 2/3] Mark the room as private (unlisted) too Also clean up RoomDirectory a bit and just pass the room object around rather than the name / alias, so now we don't have to look up the room by ID again. --- src/components/structures/RoomDirectory.js | 123 +++++++++++---------- 1 file changed, 66 insertions(+), 57 deletions(-) diff --git a/src/components/structures/RoomDirectory.js b/src/components/structures/RoomDirectory.js index 3e3d295986..2b96caec74 100644 --- a/src/components/structures/RoomDirectory.js +++ b/src/components/structures/RoomDirectory.js @@ -84,73 +84,77 @@ module.exports = React.createClass({ }); }, - deleteAliasClicked: function(roomAlias) { + /** + * A limited interface for removing rooms from the directory. + * Will set the room to not be publicly visible and delete the + * default alias. In the long term, it would be better to allow + * HS admins to do this through the RoomSettings interface, but + * this needs SPEC-417. + */ + removeFromDirectory: function(room) { + var alias = get_display_alias_for_room(room); + var name = room.name || alias || "Unnamed room"; + var QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(QuestionDialog, { - title: "Delete Alias", - description: `Are you sure you want to remove the alias '${roomAlias}'?`, - onFinished: (should_delete) => { - if (should_delete) { - var Loader = sdk.getComponent("elements.Spinner"); - var modal = Modal.createDialog(Loader); - MatrixClientPeg.get().deleteAlias(roomAlias).done(() => { - modal.close(); - this.getPublicRooms(); - }, function(err) { - modal.close(); - Modal.createDialog(ErrorDialog, { - title: "Failed to delete alias", - description: err.toString() - }); + var room_alias = get_display_alias_for_room(room); + + Modal.createDialog(QuestionDialog, { + title: "Remove from Directory", + description: `Delete the room alias '${room_alias}' and remove '${name}' from the directory?`, + onFinished: (should_delete) => { + if (!should_delete) return; + + var Loader = sdk.getComponent("elements.Spinner"); + var modal = Modal.createDialog(Loader); + var step = `remove '${name}' from the directory.`; + + MatrixClientPeg.get().setRoomDirectoryVisibility(room.room_id, 'private').then(() => { + step = 'delete the alias.'; + MatrixClientPeg.get().deleteAlias(room_alias); + }).done(() => { + modal.close(); + this.getPublicRooms(); + }, function(err) { + modal.close(); + Modal.createDialog(ErrorDialog, { + title: "Failed to "+step, + description: err.toString() }); - } + }); } }); }, - showRoom: function(roomId, roomAlias, ev) { + showRoom: function(room, ev) { if (ev.shiftKey) { ev.preventDefault(); - this.deleteAliasClicked(roomAlias); + this.removeFromDirectory(room); return; } - // extract the metadata from the publicRooms structure to pass - // as out-of-band data to view_room, because we get information - // here that we can't get other than by joining the room in some - // cases. - var room; - if (roomId) { - for (var i = 0; i < this.state.publicRooms.length; ++i) { - if (this.state.publicRooms[i].room_id == roomId) { - room = this.state.publicRooms[i]; - break; - } - } - } var oob_data = {}; - if (room) { - if (MatrixClientPeg.get().isGuest()) { - if (!room.world_readable && !room.guest_can_join) { - var NeedToRegisterDialog = sdk.getComponent("dialogs.NeedToRegisterDialog"); - Modal.createDialog(NeedToRegisterDialog, { - title: "Failed to join the room", - description: "This room is inaccessible to guests. You may be able to join if you register." - }); - return; - } + if (MatrixClientPeg.get().isGuest()) { + if (!room.world_readable && !room.guest_can_join) { + var NeedToRegisterDialog = sdk.getComponent("dialogs.NeedToRegisterDialog"); + Modal.createDialog(NeedToRegisterDialog, { + title: "Failed to join the room", + description: "This room is inaccessible to guests. You may be able to join if you register." + }); + return; } - - oob_data = { - avatarUrl: room.avatar_url, - // XXX: This logic is duplicated from the JS SDK which - // would normally decide what the name is. - name: room.name || room.canonical_alias || (room.aliases ? room.aliases[0] : "Unnamed room"), - }; } + var room_alias = get_display_alias_for_room(room); + + oob_data = { + avatarUrl: room.avatar_url, + // XXX: This logic is duplicated from the JS SDK which + // would normally decide what the name is. + name: room.name || room_alias || "Unnamed room", + }; + var payload = { oob_data: oob_data, action: 'view_room', @@ -159,10 +163,10 @@ module.exports = React.createClass({ // which servers to start querying. However, there's no other way to join rooms in // this list without aliases at present, so if roomAlias isn't set here we have no // choice but to supply the ID. - if (roomAlias) { - payload.room_alias = roomAlias; + if (room_alias) { + payload.room_alias = room_alias; } else { - payload.room_id = roomId; + payload.room_id = room.room_id; } dis.dispatch(payload); }, @@ -185,8 +189,7 @@ module.exports = React.createClass({ var self = this; var guestRead, guestJoin, perms; for (var i = 0; i < rooms.length; i++) { - var alias = rooms[i].canonical_alias || (rooms[i].aliases ? rooms[i].aliases[0] : ""); - var name = rooms[i].name || alias || "Unnamed room"; + var name = rooms[i].name || get_display_alias_for_room(rooms[i]) || "Unnamed room"; guestRead = null; guestJoin = null; @@ -211,7 +214,7 @@ module.exports = React.createClass({ rows.unshift( {ev.preventDefault();}} > @@ -228,7 +231,7 @@ module.exports = React.createClass({
-
{ alias }
+
{ get_display_alias_for_room(rooms[i]) }
{ rooms[i].num_joined_members } @@ -276,3 +279,9 @@ module.exports = React.createClass({ ); } }); + +// Similar to matrix-react-sdk's MatrixTools.getDisplayAliasForRoom +// but works with the objects we get from the public room list +function get_display_alias_for_room(room) { + return room.canonical_alias || (room.aliases ? room.aliases[0] : ""); +} From c35c9f7c3afe606b18a6082e84db314bbbddbcaa Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 22 Jun 2016 16:20:06 +0100 Subject: [PATCH 3/3] PR feedback --- src/components/structures/RoomDirectory.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/components/structures/RoomDirectory.js b/src/components/structures/RoomDirectory.js index 2b96caec74..7bcc5397d2 100644 --- a/src/components/structures/RoomDirectory.js +++ b/src/components/structures/RoomDirectory.js @@ -98,11 +98,9 @@ module.exports = React.createClass({ var QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - var room_alias = get_display_alias_for_room(room); - Modal.createDialog(QuestionDialog, { title: "Remove from Directory", - description: `Delete the room alias '${room_alias}' and remove '${name}' from the directory?`, + description: `Delete the room alias '${alias}' and remove '${name}' from the directory?`, onFinished: (should_delete) => { if (!should_delete) return; @@ -112,12 +110,13 @@ module.exports = React.createClass({ MatrixClientPeg.get().setRoomDirectoryVisibility(room.room_id, 'private').then(() => { step = 'delete the alias.'; - MatrixClientPeg.get().deleteAlias(room_alias); + return MatrixClientPeg.get().deleteAlias(alias); }).done(() => { modal.close(); this.getPublicRooms(); }, function(err) { modal.close(); + this.getPublicRooms(); Modal.createDialog(ErrorDialog, { title: "Failed to "+step, description: err.toString()