From 72b3ce200d7d35bd9fa41b37e1c930e9fa18daea Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 9 Jun 2016 18:49:06 +0100 Subject: [PATCH 1/6] Make the room directory join rooms by alias Also makes some improvement on the multiple code path mess for joining rooms --- src/components/structures/MatrixChat.js | 59 +++++++++---------------- src/components/structures/RoomView.js | 10 ++++- 2 files changed, 30 insertions(+), 39 deletions(-) diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index 39deb57d8c..e94be4d9ed 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -424,40 +424,10 @@ module.exports = React.createClass({ } break; case 'view_room_alias': - if (!this.state.logged_in) { - this.starting_room_alias_payload = payload; - // Login is the default screen, so we'd do this anyway, - // but this will set the URL bar appropriately. - dis.dispatch({ action: 'start_login' }); - return; - } - - var foundRoom = MatrixTools.getRoomForAlias( - MatrixClientPeg.get().getRooms(), payload.room_alias + this._viewRoom( + undefined, payload.room_alias, undefined, payload.event_id, + payload.third_party_invite, payload.oob_data ); - if (foundRoom) { - dis.dispatch({ - action: 'view_room', - room_id: foundRoom.roomId, - room_alias: payload.room_alias, - event_id: payload.event_id, - third_party_invite: payload.third_party_invite, - oob_data: payload.oob_data, - }); - return; - } - // resolve the alias and *then* view it - MatrixClientPeg.get().getRoomIdForAlias(payload.room_alias).done( - function(result) { - dis.dispatch({ - action: 'view_room', - room_id: result.room_id, - room_alias: payload.room_alias, - event_id: payload.event_id, - third_party_invite: payload.third_party_invite, - oob_data: payload.oob_data, - }); - }); break; case 'view_user_settings': this._setPage(this.PageTypes.UserSettings); @@ -818,22 +788,35 @@ module.exports = React.createClass({ inviterName: params.inviter_name, }; + var payload; if (roomString[0] == '#') { - dis.dispatch({ + payload = { action: 'view_room_alias', room_alias: roomString, event_id: eventId, third_party_invite: third_party_invite, oob_data: oob_data, - }); + }; } else { - dis.dispatch({ + payload = { action: 'view_room', room_id: roomString, event_id: eventId, third_party_invite: third_party_invite, oob_data: oob_data, - }); + }; + } + + // we can't view a room unless we're logged in + // (a guest account is fine) + if (!this.state.logged_in) { + this.starting_room_alias_payload = payload; + // Login is the default screen, so we'd do this anyway, + // but this will set the URL bar appropriately. + dis.dispatch({ action: 'start_login' }); + return; + } else { + dis.dispatch(payload); } } else { @@ -1044,7 +1027,7 @@ module.exports = React.createClass({ oobData={this.state.roomOobData} highlightedEventId={this.state.highlightedEventId} eventPixelOffset={this.state.initialEventPixelOffset} - key={this.state.currentRoom} + key={this.state.currentRoom || this.state.currentRoomAlias} opacity={this.state.middleOpacity} ConferenceHandler={this.props.ConferenceHandler} /> ); diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 77080b5a75..b7df2527f3 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -39,6 +39,7 @@ var dis = require("../../dispatcher"); var Tinter = require("../../Tinter"); var rate_limited_func = require('../../ratelimitedfunc'); var ObjectUtils = require('../../ObjectUtils'); +var MatrixTools = require('../../MatrixTools'); var DEBUG = false; @@ -100,7 +101,14 @@ module.exports = React.createClass({ }, getInitialState: function() { - var room = MatrixClientPeg.get().getRoom(this.props.roomAddress); + var room; + if (this.props.roomAddress[0] == '!') { + room = MatrixClientPeg.get().getRoom(this.props.roomAddress); + } else { + room = MatrixTools.getRoomForAlias( + MatrixClientPeg.get().getRooms(), this.props.roomAddress + ); + } return { room: room, roomLoading: !room, From b60ab9d6957656935f3056fd10591b4160e8af98 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 9 Jun 2016 18:50:18 +0100 Subject: [PATCH 2/6] Remove XXX now it's fixed (yay!) --- src/components/structures/RoomView.js | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index b7df2527f3..9fc335236c 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -56,13 +56,6 @@ module.exports = React.createClass({ ConferenceHandler: React.PropTypes.any, // the ID for this room (or, if we don't know it, an alias for it) - // - // XXX: if this is an alias, we will display a 'join' dialogue, - // regardless of whether we are already a member, or if the room is - // peekable. Currently there is a big mess, where at least four - // different components (RoomView, MatrixChat, RoomDirectory, - // SlashCommands) have logic for turning aliases into rooms, and each - // of them do it differently and have different edge cases. roomAddress: React.PropTypes.string.isRequired, // An object representing a third party invite to join this room From 719928f389853363450be4a9b8006b2b6ab42750 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 10 Jun 2016 15:12:42 +0100 Subject: [PATCH 3/6] Remove view_room_alias As it was basically the same as view_room. Use view_room instead which will handle whether we pass an ID or an alias into RoomView --- src/components/structures/MatrixChat.js | 49 +++++++++++++------------ 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index e94be4d9ed..b70c89e2d8 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -392,6 +392,10 @@ module.exports = React.createClass({ }); break; case 'view_room': + // Takes both room ID and room alias: if switching to a room the client is already + // know to be in (eg. user clicks on a room in the recents panel), supply only the + // ID. If the user is clicking on a room in the context of the alias being presented + // to them, supply the room alias and optionally the room ID. this._viewRoom( payload.room_id, payload.room_alias, payload.show_settings, payload.event_id, payload.third_party_invite, payload.oob_data @@ -423,12 +427,6 @@ module.exports = React.createClass({ this._viewRoom(allRooms[roomIndex].roomId); } break; - case 'view_room_alias': - this._viewRoom( - undefined, payload.room_alias, undefined, payload.event_id, - payload.third_party_invite, payload.oob_data - ); - break; case 'view_user_settings': this._setPage(this.PageTypes.UserSettings); this.notifyNewScreen('settings'); @@ -502,8 +500,6 @@ module.exports = React.createClass({ this.focusComposer = true; var newState = { - currentRoom: roomId, - currentRoomAlias: roomAlias, initialEventId: eventId, highlightedEventId: eventId, initialEventPixelOffset: undefined, @@ -512,6 +508,18 @@ module.exports = React.createClass({ roomOobData: oob_data, }; + // If an alias has been provided, we use that and only that, + // since otherwise we'll prefer to pass in an ID to RoomView + // but if we're not in the room, we should join by alias rather + // than ID. + if (roomAlias) { + newState.currentRoomAlias = roomAlias; + newState.currentRoom = null; + } else { + newState.currentRoomAlias = null; + newState.currentRoom = roomId; + } + // if we aren't given an explicit event id, look for one in the // scrollStateMap. if (!eventId) { @@ -788,23 +796,16 @@ module.exports = React.createClass({ inviterName: params.inviter_name, }; - var payload; + var payload = { + action: 'view_room', + event_id: eventId, + third_party_invite: third_party_invite, + oob_data: oob_data, + }; if (roomString[0] == '#') { - payload = { - action: 'view_room_alias', - room_alias: roomString, - event_id: eventId, - third_party_invite: third_party_invite, - oob_data: oob_data, - }; + payload.room_alias = roomString; } else { - payload = { - action: 'view_room', - room_id: roomString, - event_id: eventId, - third_party_invite: third_party_invite, - oob_data: oob_data, - }; + payload.room_id = roomString; } // we can't view a room unless we're logged in @@ -832,7 +833,7 @@ module.exports = React.createClass({ onAliasClick: function(event, alias) { event.preventDefault(); - dis.dispatch({action: 'view_room_alias', room_alias: alias}); + dis.dispatch({action: 'view_room', room_alias: alias}); }, onUserClick: function(event, userId) { From c3a96583928305e42a5bb5f5296dde4cd1a0583d Mon Sep 17 00:00:00 2001 From: Aviral Dasgupta Date: Mon, 13 Jun 2016 22:04:12 +0530 Subject: [PATCH 4/6] Add experimental "Labs" section to settings --- src/UserSettingsStore.js | 10 +++++++ src/components/structures/UserSettings.js | 33 +++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/src/UserSettingsStore.js b/src/UserSettingsStore.js index 9bb1388e76..f9c8a3ed2d 100644 --- a/src/UserSettingsStore.js +++ b/src/UserSettingsStore.js @@ -112,4 +112,14 @@ module.exports = { append: true, // We always append for email pushers since we don't want to stop other accounts notifying to the same email address }); }, + + isFeatureEnabled: function(feature: string): boolean { + feature = feature.match(/\w+/g).join('_').toLowerCase(); + return localStorage.getItem(`mx_labs_feature_${feature}`) === 'true'; + }, + + setFeatureEnabled: function(feature: string, enabled: boolean) { + feature = feature.match(/\w+/g).join('_').toLowerCase(); + localStorage.setItem(`mx_labs_feature_${feature}`, enabled); + } }; diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index 635f9c5413..fcb1254af0 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -26,6 +26,11 @@ var GeminiScrollbar = require('react-gemini-scrollbar'); var Email = require('../../email'); var AddThreepid = require('../../AddThreepid'); +const LABS_FEATURES = [ + 'Rich Text Editor', + 'End-to-End Encryption' +]; + module.exports = React.createClass({ displayName: 'UserSettings', @@ -357,6 +362,32 @@ module.exports = React.createClass({ ); } + this._renderLabs = function () { + let features = LABS_FEATURES.map(feature => ( +
+ UserSettingsStore.setFeatureEnabled(feature, e.target.checked)} /> + +
+ )); + return ( +
+

Labs

+ +
+

These experimental features may change, break or disappear at any time. We make absolutely no guarantees about what may happen if you turn one of these experiments on, and your client may even spontaneously combust. Jokes aside, your client may delete all your data or your security and privacy could be compromised in unexpected ways. Please proceed with caution.

+ {features} +
+
window.location.reload()}>Restart Vector
+
+
+ ) + }; + return (
@@ -411,6 +442,8 @@ module.exports = React.createClass({ {this._renderDeviceInfo()} + {this._renderLabs()} +

Advanced

From 727e6daaae62a7f80e36333e46c3ad001f10f857 Mon Sep 17 00:00:00 2001 From: Aviral Dasgupta Date: Mon, 13 Jun 2016 22:11:21 +0530 Subject: [PATCH 5/6] Fix key attr placement in UserSettings --- src/components/structures/UserSettings.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index fcb1254af0..2023082422 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -364,8 +364,8 @@ module.exports = React.createClass({ this._renderLabs = function () { let features = LABS_FEATURES.map(feature => ( -
- + Date: Mon, 13 Jun 2016 23:25:31 +0530 Subject: [PATCH 6/6] Labs improvements --- src/UserSettingsStore.js | 2 -- src/components/structures/UserSettings.js | 26 +++++++++++++---------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/UserSettingsStore.js b/src/UserSettingsStore.js index f9c8a3ed2d..305994aa0e 100644 --- a/src/UserSettingsStore.js +++ b/src/UserSettingsStore.js @@ -114,12 +114,10 @@ module.exports = { }, isFeatureEnabled: function(feature: string): boolean { - feature = feature.match(/\w+/g).join('_').toLowerCase(); return localStorage.getItem(`mx_labs_feature_${feature}`) === 'true'; }, setFeatureEnabled: function(feature: string, enabled: boolean) { - feature = feature.match(/\w+/g).join('_').toLowerCase(); localStorage.setItem(`mx_labs_feature_${feature}`, enabled); } }; diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index 2023082422..a320a02da8 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -27,8 +27,14 @@ var Email = require('../../email'); var AddThreepid = require('../../AddThreepid'); const LABS_FEATURES = [ - 'Rich Text Editor', - 'End-to-End Encryption' + { + name: 'Rich Text Editor', + id: 'rich_text_editor' + }, + { + name: 'End-to-End Encryption', + id: 'e2e_encryption' + } ]; module.exports = React.createClass({ @@ -364,14 +370,14 @@ module.exports = React.createClass({ this._renderLabs = function () { let features = LABS_FEATURES.map(feature => ( -
+
UserSettingsStore.setFeatureEnabled(feature, e.target.checked)} /> - + id={feature.id} + name={feature.id} + defaultChecked={UserSettingsStore.isFeatureEnabled(feature.id)} + onChange={e => UserSettingsStore.setFeatureEnabled(feature.id, e.target.checked)} /> +
)); return ( @@ -379,10 +385,8 @@ module.exports = React.createClass({

Labs

-

These experimental features may change, break or disappear at any time. We make absolutely no guarantees about what may happen if you turn one of these experiments on, and your client may even spontaneously combust. Jokes aside, your client may delete all your data or your security and privacy could be compromised in unexpected ways. Please proceed with caution.

+

These are experimental features that may break in unexpected ways. Use with caution.

{features} -
-
window.location.reload()}>Restart Vector
)