From 998a55a5902e44c6f9ae815a64bd2cfda51826fe Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Mon, 5 Jun 2017 16:51:50 +0100 Subject: [PATCH 01/14] Add basic group view --- src/PageTypes.js | 1 + src/components/structures/GroupView.js | 130 ++++++++++++++++++++++ src/components/structures/LoggedInView.js | 7 ++ src/components/structures/MatrixChat.js | 23 ++++ src/linkify-matrix.js | 49 ++++++++ 5 files changed, 210 insertions(+) create mode 100644 src/components/structures/GroupView.js diff --git a/src/PageTypes.js b/src/PageTypes.js index d87b363a6f..b2346c62c3 100644 --- a/src/PageTypes.js +++ b/src/PageTypes.js @@ -22,4 +22,5 @@ export default { CreateRoom: "create_room", RoomDirectory: "room_directory", UserView: "user_view", + GroupView: "group_view", }; diff --git a/src/components/structures/GroupView.js b/src/components/structures/GroupView.js new file mode 100644 index 0000000000..2368c44319 --- /dev/null +++ b/src/components/structures/GroupView.js @@ -0,0 +1,130 @@ +/* +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 MatrixClientPeg from '../../MatrixClientPeg'; +import sdk from '../../index'; +import sanitizeHtml from "sanitize-html"; +import { sanitizeHtmlParams } from '../../HtmlUtils'; + + +module.exports = React.createClass({ + displayName: 'GroupView', + + propTypes: { + groupId: React.PropTypes.string.isRequired, + }, + + getInitialState: function() { + return { + phase: "GroupView.LOADING", // LOADING / DISPLAY / ERROR / NOT_FOUND + summary: null, + }; + }, + + componentWillMount: function() { + this.setState({ + phase: "GroupView.LOADING", + summary: null, + }) + this._loadGroupFromServer(this.props.groupId) + }, + + componentWillReceiveProps: function(new_props) { + if (this.props.groupId != new_props.groupId) { + this.setState({ + phase: "GroupView.LOADING", + summary: null, + }) + this._loadGroupFromServer(new_props.groupId); + } + }, + + _loadGroupFromServer: function(groupId) { + const self = this; + MatrixClientPeg.get().getGroupSummary(groupId).done(function(res) { + self.setState({ + phase: "GroupView.DISPLAY", + summary: res, + }); + }, function(err) { + self.setState({ + phase: err.errcode == 404 ? "GroupView.NOT_FOUND" :"GroupView.ERROR", + summary: null, + }); + }); + }, + + render: function() { + var BaseAvatar = sdk.getComponent("avatars.BaseAvatar"); + var Loader = sdk.getComponent("elements.Spinner"); + + if (this.state.phase == "GroupView.LOADING") { + return ( +
+ +
+ ); + } else if (this.state.phase == "GroupView.DISPLAY") { + const summary = this.state.summary; + let avatar_url = null; + if (summary.profile.avatar_url) { + avatar_url = MatrixClientPeg.get().mxcUrlToHttp(summary.profile.avatar_url); + } + let description = null; + if (summary.profile.long_description) { + description = sanitizeHtml(summary.profile.long_description); + } + return ( +
+
+
+
+ +
+
+
+ {summary.profile.name} + + ({this.props.groupId}) + +
+
+ {summary.profile.short_description} +
+
+
+
+
+
+ ); + } else if (this.state.phase == "GroupView.NOT_FOUND") { +
+ Group {this.props.groupId} not found +
+ } else { + return ( +
+ Failed to load {this.props.groupId} +
+ ); + } + }, +}); diff --git a/src/components/structures/LoggedInView.js b/src/components/structures/LoggedInView.js index e2fdeb4687..cf9a8310b1 100644 --- a/src/components/structures/LoggedInView.js +++ b/src/components/structures/LoggedInView.js @@ -179,6 +179,7 @@ export default React.createClass({ const CreateRoom = sdk.getComponent('structures.CreateRoom'); const RoomDirectory = sdk.getComponent('structures.RoomDirectory'); const HomePage = sdk.getComponent('structures.HomePage'); + const GroupView = sdk.getComponent('structures.GroupView'); const MatrixToolbar = sdk.getComponent('globals.MatrixToolbar'); const GuestWarningBar = sdk.getComponent('globals.GuestWarningBar'); const NewVersionBar = sdk.getComponent('globals.NewVersionBar'); @@ -247,6 +248,12 @@ export default React.createClass({ page_element = null; // deliberately null for now right_panel = ; break; + case PageTypes.GroupView: + // TODO + page_element = + break; } var topBar; diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index 0dedc02270..8771231e68 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -261,6 +261,9 @@ module.exports = React.createClass({ if (this.onUserClick) { linkifyMatrix.onUserClick = this.onUserClick; } + if (this.onGroupClick) { + linkifyMatrix.onGroupClick = this.onGroupClick; + } window.addEventListener('resize', this.handleResize); this.handleResize(); @@ -458,6 +461,12 @@ module.exports = React.createClass({ this._setPage(PageTypes.RoomDirectory); this.notifyNewScreen('directory'); break; + case 'view_group': + const groupId = payload.group_id; + this.setState({currentGroupId: groupId}); + this._setPage(PageTypes.GroupView); + this.notifyNewScreen('group/' + groupId); + break; case 'view_home_page': if (!this._teamToken) { dis.dispatch({action: 'view_room_directory'}); @@ -1001,6 +1010,15 @@ module.exports = React.createClass({ member: member, }); } + } else if (screen.indexOf('group/') == 0) { + const groupId = screen.substring(6); + + // TODO: Check valid group ID + + dis.dispatch({ + action: 'view_group', + group_id: groupId, + }); } else { console.info("Ignoring showScreen for '%s'", screen); } @@ -1029,6 +1047,11 @@ module.exports = React.createClass({ }); }, + onGroupClick: function(event, groupId) { + event.preventDefault(); + dis.dispatch({action: 'view_group', group_id: groupId}); + }, + onLogoutClick: function(event) { dis.dispatch({ action: 'logout', diff --git a/src/linkify-matrix.js b/src/linkify-matrix.js index d9b0b78982..b96730145a 100644 --- a/src/linkify-matrix.js +++ b/src/linkify-matrix.js @@ -108,11 +108,53 @@ function matrixLinkify(linkify) { S_AT_NAME_COLON_DOMAIN.on(TT.DOT, S_AT_NAME_COLON_DOMAIN_DOT); S_AT_NAME_COLON_DOMAIN_DOT.on(TT.DOMAIN, S_AT_NAME_COLON_DOMAIN); S_AT_NAME_COLON_DOMAIN_DOT.on(TT.TLD, S_USERID); + + + var GROUPID = function(value) { + MultiToken.call(this, value); + this.type = 'groupid'; + this.isLink = true; + }; + GROUPID.prototype = new MultiToken(); + + var S_PLUS = new linkify.parser.State(); + var S_PLUS_NAME = new linkify.parser.State(); + var S_PLUS_NAME_COLON = new linkify.parser.State(); + var S_PLUS_NAME_COLON_DOMAIN = new linkify.parser.State(); + var S_PLUS_NAME_COLON_DOMAIN_DOT = new linkify.parser.State(); + var S_GROUPID = new linkify.parser.State(GROUPID); + + var groupid_tokens = [ + TT.DOT, + TT.UNDERSCORE, + TT.PLUS, + TT.NUM, + TT.DOMAIN, + TT.TLD, + + // as in roomname_tokens + TT.LOCALHOST, + ]; + + S_START.on(TT.PLUS, S_PLUS); + + S_PLUS.on(groupid_tokens, S_PLUS_NAME); + S_PLUS_NAME.on(groupid_tokens, S_PLUS_NAME); + S_PLUS_NAME.on(TT.DOMAIN, S_PLUS_NAME); + + S_PLUS_NAME.on(TT.COLON, S_PLUS_NAME_COLON); + + S_PLUS_NAME_COLON.on(TT.DOMAIN, S_PLUS_NAME_COLON_DOMAIN); + S_PLUS_NAME_COLON.on(TT.LOCALHOST, S_GROUPID); // accept +foo:localhost + S_PLUS_NAME_COLON_DOMAIN.on(TT.DOT, S_PLUS_NAME_COLON_DOMAIN_DOT); + S_PLUS_NAME_COLON_DOMAIN_DOT.on(TT.DOMAIN, S_PLUS_NAME_COLON_DOMAIN); + S_PLUS_NAME_COLON_DOMAIN_DOT.on(TT.TLD, S_GROUPID); } // stubs, overwritten in MatrixChat's componentDidMount matrixLinkify.onUserClick = function(e, userId) { e.preventDefault(); }; matrixLinkify.onAliasClick = function(e, roomAlias) { e.preventDefault(); }; +matrixLinkify.onGroupClick = function(e, groupId) { e.preventDefault(); }; var escapeRegExp = function(string) { return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); @@ -143,6 +185,12 @@ matrixLinkify.options = { matrixLinkify.onAliasClick(e, href); } }; + case "groupid": + return { + click: function(e) { + matrixLinkify.onGroupClick(e, href); + } + }; } }, @@ -150,6 +198,7 @@ matrixLinkify.options = { switch (type) { case 'roomalias': case 'userid': + case "groupid": return matrixLinkify.MATRIXTO_BASE_URL + '/#/' + href; default: var m; From 2efa099de28ffd1217e7287e5cbee17ed87de495 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 23 Jun 2017 17:02:54 +0100 Subject: [PATCH 02/14] Use function from HTMLUtils for sanitizing Encapsulates things a little nicer --- src/HtmlUtils.js | 12 +++++++++++- src/components/structures/GroupView.js | 26 ++++++++++---------------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/HtmlUtils.js b/src/HtmlUtils.js index aec32092ed..5c1c2881e5 100644 --- a/src/HtmlUtils.js +++ b/src/HtmlUtils.js @@ -107,7 +107,17 @@ export function stripParagraphs(html: string): string { return contentHTML; } -var sanitizeHtmlParams = { +/* + * Given an untrusted HTML string, return a React node with an sanitized version + * of that HTML. + */ +export function sanitizedHtmlNode(insaneHtml) { + const saneHtml = sanitizeHtml(insaneHtml, sanitizeHtmlParams); + + return
; +} + +const sanitizeHtmlParams = { allowedTags: [ 'font', // custom to matrix for IRC-style font coloring 'del', // for markdown diff --git a/src/components/structures/GroupView.js b/src/components/structures/GroupView.js index 2368c44319..5c049b93be 100644 --- a/src/components/structures/GroupView.js +++ b/src/components/structures/GroupView.js @@ -16,8 +16,7 @@ limitations under the License. import MatrixClientPeg from '../../MatrixClientPeg'; import sdk from '../../index'; -import sanitizeHtml from "sanitize-html"; -import { sanitizeHtmlParams } from '../../HtmlUtils'; +import { sanitizedHtmlNode } from '../../HtmlUtils'; module.exports = React.createClass({ @@ -53,14 +52,13 @@ module.exports = React.createClass({ }, _loadGroupFromServer: function(groupId) { - const self = this; - MatrixClientPeg.get().getGroupSummary(groupId).done(function(res) { - self.setState({ + MatrixClientPeg.get().getGroupSummary(groupId).done((res) => { + this.setState({ phase: "GroupView.DISPLAY", summary: res, }); - }, function(err) { - self.setState({ + }, (err) => { + this.setState({ phase: err.errcode == 404 ? "GroupView.NOT_FOUND" :"GroupView.ERROR", summary: null, }); @@ -68,15 +66,11 @@ module.exports = React.createClass({ }, render: function() { - var BaseAvatar = sdk.getComponent("avatars.BaseAvatar"); - var Loader = sdk.getComponent("elements.Spinner"); + const BaseAvatar = sdk.getComponent("avatars.BaseAvatar"); + const Loader = sdk.getComponent("elements.Spinner"); if (this.state.phase == "GroupView.LOADING") { - return ( -
- -
- ); + return ; } else if (this.state.phase == "GroupView.DISPLAY") { const summary = this.state.summary; let avatar_url = null; @@ -85,7 +79,7 @@ module.exports = React.createClass({ } let description = null; if (summary.profile.long_description) { - description = sanitizeHtml(summary.profile.long_description); + description = sanitizedHtmlNode(summary.profile.long_description); } return (
@@ -112,7 +106,7 @@ module.exports = React.createClass({
-
+ {description}
); } else if (this.state.phase == "GroupView.NOT_FOUND") { From a26498bc6c17cfffb0f0bff0cfb69f6b81b785d7 Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 26 Jun 2017 17:38:10 +0100 Subject: [PATCH 03/14] Make 'group not found' work --- src/components/structures/GroupView.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/components/structures/GroupView.js b/src/components/structures/GroupView.js index 5c049b93be..94d7f1c422 100644 --- a/src/components/structures/GroupView.js +++ b/src/components/structures/GroupView.js @@ -59,7 +59,7 @@ module.exports = React.createClass({ }); }, (err) => { this.setState({ - phase: err.errcode == 404 ? "GroupView.NOT_FOUND" :"GroupView.ERROR", + phase: err.httpStatus == 404 ? "GroupView.NOT_FOUND" :"GroupView.ERROR", summary: null, }); }); @@ -110,9 +110,11 @@ module.exports = React.createClass({ ); } else if (this.state.phase == "GroupView.NOT_FOUND") { -
- Group {this.props.groupId} not found -
+ return ( +
+ Group {this.props.groupId} not found +
+ ); } else { return (
From 812b3643dee3003f698138949b2a0a563aa59612 Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 26 Jun 2017 17:47:17 +0100 Subject: [PATCH 04/14] Add message for HSes that don't support groups Also add an unrelated missed translation --- src/components/structures/GroupView.js | 8 ++++++++ src/i18n/strings/en_EN.json | 4 +++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/components/structures/GroupView.js b/src/components/structures/GroupView.js index 94d7f1c422..a212fe336f 100644 --- a/src/components/structures/GroupView.js +++ b/src/components/structures/GroupView.js @@ -17,6 +17,7 @@ limitations under the License. import MatrixClientPeg from '../../MatrixClientPeg'; import sdk from '../../index'; import { sanitizedHtmlNode } from '../../HtmlUtils'; +import { _t } from '../../languageHandler'; module.exports = React.createClass({ @@ -30,6 +31,7 @@ module.exports = React.createClass({ return { phase: "GroupView.LOADING", // LOADING / DISPLAY / ERROR / NOT_FOUND summary: null, + error: null, }; }, @@ -61,6 +63,7 @@ module.exports = React.createClass({ this.setState({ phase: err.httpStatus == 404 ? "GroupView.NOT_FOUND" :"GroupView.ERROR", summary: null, + error: err, }); }); }, @@ -116,9 +119,14 @@ module.exports = React.createClass({
); } else { + let extraText; + if (this.state.error.errcode === 'M_UNRECOGNIZED') { + extraText =
{_t('This Home server does not support groups')}
; + } return (
Failed to load {this.props.groupId} + {extraText}
); } diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index a4dcb2873f..c6bd304428 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -920,5 +920,7 @@ "Ignore request": "Ignore request", "You added a new device '%(displayName)s', which is requesting encryption keys.": "You added a new device '%(displayName)s', which is requesting encryption keys.", "Your unverified device '%(displayName)s' is requesting encryption keys.": "Your unverified device '%(displayName)s' is requesting encryption keys.", - "Encryption key request": "Encryption key request" + "Encryption key request": "Encryption key request", + "This Home server does not support groups": "This Home server does not support groups", + "Loading device info...": "Loading device info..." } From c033d5defd02aafad7ba292f6d8648fdf3065111 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 27 Jun 2017 09:58:29 +0100 Subject: [PATCH 05/14] Missing React import --- src/components/structures/GroupView.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/structures/GroupView.js b/src/components/structures/GroupView.js index a212fe336f..fcb1885261 100644 --- a/src/components/structures/GroupView.js +++ b/src/components/structures/GroupView.js @@ -14,6 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ +import React from 'react'; import MatrixClientPeg from '../../MatrixClientPeg'; import sdk from '../../index'; import { sanitizedHtmlNode } from '../../HtmlUtils'; From f0aaca0a31166379461c625e71dbca8c47722a27 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 27 Jun 2017 10:05:05 +0100 Subject: [PATCH 06/14] Fix some PR feedback --- src/components/structures/GroupView.js | 14 +++++--------- src/components/structures/LoggedInView.js | 3 +-- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/src/components/structures/GroupView.js b/src/components/structures/GroupView.js index fcb1885261..9140ee2c71 100644 --- a/src/components/structures/GroupView.js +++ b/src/components/structures/GroupView.js @@ -37,10 +37,6 @@ module.exports = React.createClass({ }, componentWillMount: function() { - this.setState({ - phase: "GroupView.LOADING", - summary: null, - }) this._loadGroupFromServer(this.props.groupId) }, @@ -62,7 +58,7 @@ module.exports = React.createClass({ }); }, (err) => { this.setState({ - phase: err.httpStatus == 404 ? "GroupView.NOT_FOUND" :"GroupView.ERROR", + phase: err.httpStatus === 404 ? "GroupView.NOT_FOUND" : "GroupView.ERROR", summary: null, error: err, }); @@ -77,9 +73,9 @@ module.exports = React.createClass({ return ; } else if (this.state.phase == "GroupView.DISPLAY") { const summary = this.state.summary; - let avatar_url = null; - if (summary.profile.avatar_url) { - avatar_url = MatrixClientPeg.get().mxcUrlToHttp(summary.profile.avatar_url); + let avatarUrl = null; + if (summary.profile.avatarUrl) { + avatarUrl = MatrixClientPeg.get().mxcUrlToHttp(summary.profile.avatarUrl); } let description = null; if (summary.profile.long_description) { @@ -90,7 +86,7 @@ module.exports = React.createClass({
-
diff --git a/src/components/structures/LoggedInView.js b/src/components/structures/LoggedInView.js index 988c0f5ccc..aef7fe9cce 100644 --- a/src/components/structures/LoggedInView.js +++ b/src/components/structures/LoggedInView.js @@ -282,10 +282,9 @@ export default React.createClass({ right_panel = ; break; case PageTypes.GroupView: - // TODO page_element = + />; break; } From 867b47f4a21ccc26ed4f51b66e0f0763222b7682 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 27 Jun 2017 10:28:46 +0100 Subject: [PATCH 07/14] PR feedback: remove phases --- src/components/structures/GroupView.js | 46 +++++++++++++------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/src/components/structures/GroupView.js b/src/components/structures/GroupView.js index 9140ee2c71..8a28a31001 100644 --- a/src/components/structures/GroupView.js +++ b/src/components/structures/GroupView.js @@ -30,21 +30,20 @@ module.exports = React.createClass({ getInitialState: function() { return { - phase: "GroupView.LOADING", // LOADING / DISPLAY / ERROR / NOT_FOUND summary: null, error: null, }; }, componentWillMount: function() { - this._loadGroupFromServer(this.props.groupId) + this._loadGroupFromServer(this.props.groupId); }, componentWillReceiveProps: function(new_props) { if (this.props.groupId != new_props.groupId) { this.setState({ - phase: "GroupView.LOADING", summary: null, + error: null, }) this._loadGroupFromServer(new_props.groupId); } @@ -53,12 +52,11 @@ module.exports = React.createClass({ _loadGroupFromServer: function(groupId) { MatrixClientPeg.get().getGroupSummary(groupId).done((res) => { this.setState({ - phase: "GroupView.DISPLAY", summary: res, + error: null, }); }, (err) => { this.setState({ - phase: err.httpStatus === 404 ? "GroupView.NOT_FOUND" : "GroupView.ERROR", summary: null, error: err, }); @@ -69,9 +67,9 @@ module.exports = React.createClass({ const BaseAvatar = sdk.getComponent("avatars.BaseAvatar"); const Loader = sdk.getComponent("elements.Spinner"); - if (this.state.phase == "GroupView.LOADING") { + if (this.state.summary === null && this.state.error === null) { return ; - } else if (this.state.phase == "GroupView.DISPLAY") { + } else if (this.state.summary) { const summary = this.state.summary; let avatarUrl = null; if (summary.profile.avatarUrl) { @@ -109,23 +107,25 @@ module.exports = React.createClass({ {description}
); - } else if (this.state.phase == "GroupView.NOT_FOUND") { - return ( -
- Group {this.props.groupId} not found -
- ); - } else { - let extraText; - if (this.state.error.errcode === 'M_UNRECOGNIZED') { - extraText =
{_t('This Home server does not support groups')}
; + } else if (this.state.error) { + if (this.state.error.httpStatus === 404) { + return ( +
+ Group {this.props.groupId} not found +
+ ); + } else { + let extraText; + if (this.state.error.errcode === 'M_UNRECOGNIZED') { + extraText =
{_t('This Home server does not support groups')}
; + } + return ( +
+ Failed to load {this.props.groupId} + {extraText} +
+ ); } - return ( -
- Failed to load {this.props.groupId} - {extraText} -
- ); } }, }); From 971f7ad0453bbdd8f33e7541339a0f43b52725a6 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 27 Jun 2017 10:32:21 +0100 Subject: [PATCH 08/14] Fix avatars --- src/components/structures/GroupView.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/structures/GroupView.js b/src/components/structures/GroupView.js index 8a28a31001..1a45c2ff3c 100644 --- a/src/components/structures/GroupView.js +++ b/src/components/structures/GroupView.js @@ -72,8 +72,8 @@ module.exports = React.createClass({ } else if (this.state.summary) { const summary = this.state.summary; let avatarUrl = null; - if (summary.profile.avatarUrl) { - avatarUrl = MatrixClientPeg.get().mxcUrlToHttp(summary.profile.avatarUrl); + if (summary.profile.avatar_url) { + avatarUrl = MatrixClientPeg.get().mxcUrlToHttp(summary.profile.avatar_url); } let description = null; if (summary.profile.long_description) { From 2aeaaf26ca5fb70e92e05d1b6fb95dbb17f5f0fc Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 27 Jun 2017 11:52:23 +0100 Subject: [PATCH 09/14] remove inline css --- src/components/structures/GroupView.js | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/components/structures/GroupView.js b/src/components/structures/GroupView.js index 1a45c2ff3c..6e873a9b59 100644 --- a/src/components/structures/GroupView.js +++ b/src/components/structures/GroupView.js @@ -80,7 +80,7 @@ module.exports = React.createClass({ description = sanitizedHtmlNode(summary.profile.long_description); } return ( -
+
@@ -90,11 +90,7 @@ module.exports = React.createClass({
{summary.profile.name} - + ({this.props.groupId})
@@ -110,7 +106,7 @@ module.exports = React.createClass({ } else if (this.state.error) { if (this.state.error.httpStatus === 404) { return ( -
+
Group {this.props.groupId} not found
); @@ -120,7 +116,7 @@ module.exports = React.createClass({ extraText =
{_t('This Home server does not support groups')}
; } return ( -
+
Failed to load {this.props.groupId} {extraText}
From 6c9716637e8be54fa8966bb41fd005cd9bc1d804 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 27 Jun 2017 13:13:00 +0100 Subject: [PATCH 10/14] Fix linting errors --- src/components/structures/GroupView.js | 8 ++++---- src/components/structures/MatrixChat.js | 10 ++++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/components/structures/GroupView.js b/src/components/structures/GroupView.js index 6e873a9b59..db0b556260 100644 --- a/src/components/structures/GroupView.js +++ b/src/components/structures/GroupView.js @@ -39,13 +39,13 @@ module.exports = React.createClass({ this._loadGroupFromServer(this.props.groupId); }, - componentWillReceiveProps: function(new_props) { - if (this.props.groupId != new_props.groupId) { + componentWillReceiveProps: function(newProps) { + if (this.props.groupId != newProps.groupId) { this.setState({ summary: null, error: null, - }) - this._loadGroupFromServer(new_props.groupId); + }); + this._loadGroupFromServer(newProps.groupId); } }, diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index f4da0e6a44..025805d921 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -487,10 +487,12 @@ module.exports = React.createClass({ this.notifyNewScreen('directory'); break; case 'view_group': - const groupId = payload.group_id; - this.setState({currentGroupId: groupId}); - this._setPage(PageTypes.GroupView); - this.notifyNewScreen('group/' + groupId); + { + const groupId = payload.group_id; + this.setState({currentGroupId: groupId}); + this._setPage(PageTypes.GroupView); + this.notifyNewScreen('group/' + groupId); + } break; case 'view_home_page': this._setPage(PageTypes.HomePage); From 87fac367ac6d0909b823072a95485bc63e81b6c0 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 27 Jun 2017 13:37:59 +0100 Subject: [PATCH 11/14] quote consistency --- src/linkify-matrix.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/linkify-matrix.js b/src/linkify-matrix.js index b96730145a..01512a771a 100644 --- a/src/linkify-matrix.js +++ b/src/linkify-matrix.js @@ -198,7 +198,7 @@ matrixLinkify.options = { switch (type) { case 'roomalias': case 'userid': - case "groupid": + case 'groupid': return matrixLinkify.MATRIXTO_BASE_URL + '/#/' + href; default: var m; From aa7a113324d1cea68cc9a611c7332088c2a19fc5 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 27 Jun 2017 13:41:43 +0100 Subject: [PATCH 12/14] More PR feedback --- src/components/structures/GroupView.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/components/structures/GroupView.js b/src/components/structures/GroupView.js index db0b556260..71deaf529b 100644 --- a/src/components/structures/GroupView.js +++ b/src/components/structures/GroupView.js @@ -72,11 +72,11 @@ module.exports = React.createClass({ } else if (this.state.summary) { const summary = this.state.summary; let avatarUrl = null; - if (summary.profile.avatar_url) { + if (summary.profile && summary.profile.avatar_url) { avatarUrl = MatrixClientPeg.get().mxcUrlToHttp(summary.profile.avatar_url); } let description = null; - if (summary.profile.long_description) { + if (summary.profile && summary.profile.long_description) { description = sanitizedHtmlNode(summary.profile.long_description); } return ( @@ -122,6 +122,9 @@ module.exports = React.createClass({
); } + } else { + console.error("Invalid state for GroupView"); + return
; } }, }); From 1deb4062946f083406fd95c35d39007c152a57d4 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 7 Jul 2017 10:08:29 +0100 Subject: [PATCH 13/14] Fix race --- src/components/structures/GroupView.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/structures/GroupView.js b/src/components/structures/GroupView.js index 71deaf529b..d3a06b915b 100644 --- a/src/components/structures/GroupView.js +++ b/src/components/structures/GroupView.js @@ -44,8 +44,9 @@ module.exports = React.createClass({ this.setState({ summary: null, error: null, + }, () => { + this._loadGroupFromServer(newProps.groupId); }); - this._loadGroupFromServer(newProps.groupId); } },