From 6f896098e380c5817fa88e6fc1dfa8e7932270c8 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Fri, 15 Dec 2017 17:14:56 +0000 Subject: [PATCH 1/7] Get Group profile from TagTile instead of TagPanel So that instead of getting all group profiles everytime the tags change order, get them when the TagTile mounts for a group tag. --- src/components/structures/TagPanel.js | 32 +++++---------------- src/components/views/elements/DNDTagTile.js | 6 ++-- src/components/views/elements/TagTile.js | 27 ++++++++++++++--- 3 files changed, 33 insertions(+), 32 deletions(-) diff --git a/src/components/structures/TagPanel.js b/src/components/structures/TagPanel.js index 49d22d8e52..aa35101197 100644 --- a/src/components/structures/TagPanel.js +++ b/src/components/structures/TagPanel.js @@ -18,7 +18,6 @@ import React from 'react'; import PropTypes from 'prop-types'; import { MatrixClient } from 'matrix-js-sdk'; import FilterStore from '../../stores/FilterStore'; -import FlairStore from '../../stores/FlairStore'; import TagOrderStore from '../../stores/TagOrderStore'; import GroupActions from '../../actions/GroupActions'; @@ -36,17 +35,7 @@ const TagPanel = React.createClass({ getInitialState() { return { - // A list of group profiles for tags that are group IDs. The intention in future - // is to allow arbitrary tags to be selected in the TagPanel, not just groups. - // For now, it suffices to maintain a list of ordered group profiles. - orderedGroupTagProfiles: [ - // { - // groupId: '+awesome:foo.bar',{ - // name: 'My Awesome Community', - // avatarUrl: 'mxc://...', - // shortDescription: 'Some description...', - // }, - ], + orderedTags: [], selectedTags: [], }; }, @@ -67,15 +56,8 @@ const TagPanel = React.createClass({ if (this.unmounted) { return; } - - const orderedTags = TagOrderStore.getOrderedTags() || []; - const orderedGroupTags = orderedTags.filter((t) => t[0] === '+'); - // XXX: One profile lookup failing will bring the whole lot down - Promise.all(orderedGroupTags.map( - (groupId) => FlairStore.getGroupProfileCached(this.context.matrixClient, groupId), - )).then((orderedGroupTagProfiles) => { - if (this.unmounted) return; - this.setState({orderedGroupTagProfiles}); + this.setState({ + orderedTags: TagOrderStore.getOrderedTags() || [], }); }); // This could be done by anything with a matrix client @@ -113,11 +95,11 @@ const TagPanel = React.createClass({ const TintableSvg = sdk.getComponent('elements.TintableSvg'); const DNDTagTile = sdk.getComponent('elements.DNDTagTile'); - const tags = this.state.orderedGroupTagProfiles.map((groupProfile, index) => { + const tags = this.state.orderedTags.map((tag, index) => { return ; }); diff --git a/src/components/views/elements/DNDTagTile.js b/src/components/views/elements/DNDTagTile.js index 4d03534980..539163d0dc 100644 --- a/src/components/views/elements/DNDTagTile.js +++ b/src/components/views/elements/DNDTagTile.js @@ -29,7 +29,7 @@ const tagTileSource = { beginDrag: function(props) { // Return the data describing the dragged item return { - tag: props.groupProfile.groupId, + tag: props.tag, }; }, @@ -55,7 +55,7 @@ const tagTileTarget = { dis.dispatch({ action: 'order_tag', tag: monitor.getItem().tag, - targetTag: props.groupProfile.groupId, + targetTag: props.tag, // Note: we indicate that the tag should be after the target when // it's being dragged over the top half of the target. after: draggedY < targetY, @@ -65,7 +65,7 @@ const tagTileTarget = { drop(props) { // Return the data to be returned by getDropResult return { - tag: props.groupProfile.groupId, + tag: props.tag, }; }, }; diff --git a/src/components/views/elements/TagTile.js b/src/components/views/elements/TagTile.js index 124559a838..9bad02e37d 100644 --- a/src/components/views/elements/TagTile.js +++ b/src/components/views/elements/TagTile.js @@ -22,17 +22,36 @@ import sdk from '../../../index'; import dis from '../../../dispatcher'; import { isOnlyCtrlOrCmdKeyEvent } from '../../../Keyboard'; +import FlairStore from '../../../stores/FlairStore'; + export default React.createClass({ displayName: 'TagTile', propTypes: { - groupProfile: PropTypes.object, + tag: PropTypes.string, }, contextTypes: { matrixClient: React.PropTypes.instanceOf(MatrixClient).isRequired, }, + componentWillMount() { + this.unmounted = false; + if (this.props.tag[0] === '+') { + FlairStore.getGroupProfileCached( + this.context.matrixClient, + this.props.tag, + ).then((profile) => { + if (this.unmounted) return; + this.setState({profile}); + }); + } + }, + + componentWillUnmount() { + this.unmounted = true; + }, + getInitialState() { return { hover: false, @@ -44,7 +63,7 @@ export default React.createClass({ e.stopPropagation(); dis.dispatch({ action: 'select_tag', - tag: this.props.groupProfile.groupId, + tag: this.props.tag, ctrlOrCmdKey: isOnlyCtrlOrCmdKeyEvent(e), shiftKey: e.shiftKey, }); @@ -62,8 +81,8 @@ export default React.createClass({ const BaseAvatar = sdk.getComponent('avatars.BaseAvatar'); const AccessibleButton = sdk.getComponent('elements.AccessibleButton'); const RoomTooltip = sdk.getComponent('rooms.RoomTooltip'); - const profile = this.props.groupProfile || {}; - const name = profile.name || profile.groupId; + const profile = this.state.profile || {}; + const name = profile.name || this.props.tag; const avatarHeight = 35; const httpUrl = profile.avatarUrl ? this.context.matrixClient.mxcUrlToHttp( From 80f11e5c77f91c676ca7b3ef1e29910d0db1519b Mon Sep 17 00:00:00 2001 From: lukebarnard Date: Tue, 2 Jan 2018 13:34:47 +0000 Subject: [PATCH 2/7] Comment tag PropType --- src/components/views/elements/TagTile.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/views/elements/TagTile.js b/src/components/views/elements/TagTile.js index 9bad02e37d..b5dfce72c0 100644 --- a/src/components/views/elements/TagTile.js +++ b/src/components/views/elements/TagTile.js @@ -28,6 +28,7 @@ export default React.createClass({ displayName: 'TagTile', propTypes: { + // A string tag such as "m.favourite" or a group ID such as "+groupid:domain.bla" tag: PropTypes.string, }, From 3cb128094d42703cfea68656fc5021d022a2ab49 Mon Sep 17 00:00:00 2001 From: lukebarnard Date: Tue, 2 Jan 2018 13:44:22 +0000 Subject: [PATCH 3/7] Add more comments to TagTile to explain what it is --- src/components/views/elements/TagTile.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/components/views/elements/TagTile.js b/src/components/views/elements/TagTile.js index b5dfce72c0..a8d4e514ae 100644 --- a/src/components/views/elements/TagTile.js +++ b/src/components/views/elements/TagTile.js @@ -24,11 +24,17 @@ import { isOnlyCtrlOrCmdKeyEvent } from '../../../Keyboard'; import FlairStore from '../../../stores/FlairStore'; +// A class for a child of TagPanel (possibly wrapped in a DNDTagTile) that represents +// a thing to click on for the user to filter the visible rooms in the RoomList to: +// - Rooms that are part of the group +// - Direct messages with members of the group +// with the intention that this could be expanded to arbitrary tags in future. export default React.createClass({ displayName: 'TagTile', propTypes: { // A string tag such as "m.favourite" or a group ID such as "+groupid:domain.bla" + // For now, only group IDs are handled. tag: PropTypes.string, }, From 2cb4c897ce55a7e113b58ec803b022e093158a2e Mon Sep 17 00:00:00 2001 From: lukebarnard Date: Tue, 2 Jan 2018 13:45:19 +0000 Subject: [PATCH 4/7] Move `getInitialState` before `componentWillMount` --- src/components/views/elements/TagTile.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/views/elements/TagTile.js b/src/components/views/elements/TagTile.js index a8d4e514ae..7bb047504e 100644 --- a/src/components/views/elements/TagTile.js +++ b/src/components/views/elements/TagTile.js @@ -42,6 +42,12 @@ export default React.createClass({ matrixClient: React.PropTypes.instanceOf(MatrixClient).isRequired, }, + getInitialState() { + return { + hover: false, + }; + }, + componentWillMount() { this.unmounted = false; if (this.props.tag[0] === '+') { @@ -59,12 +65,6 @@ export default React.createClass({ this.unmounted = true; }, - getInitialState() { - return { - hover: false, - }; - }, - onClick: function(e) { e.preventDefault(); e.stopPropagation(); From 31855f18f8c2ee380052ac23e8a486987f767455 Mon Sep 17 00:00:00 2001 From: lukebarnard Date: Tue, 2 Jan 2018 15:56:32 +0000 Subject: [PATCH 5/7] Initialise profile state --- src/components/views/elements/TagTile.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/views/elements/TagTile.js b/src/components/views/elements/TagTile.js index 7bb047504e..057ec4921b 100644 --- a/src/components/views/elements/TagTile.js +++ b/src/components/views/elements/TagTile.js @@ -45,6 +45,7 @@ export default React.createClass({ getInitialState() { return { hover: false, + profile: null, }; }, From 833cd321f3d3519f73b4c7b23a1bee006fd532bf Mon Sep 17 00:00:00 2001 From: lukebarnard Date: Tue, 2 Jan 2018 15:58:24 +0000 Subject: [PATCH 6/7] Log warning in case of failed group profile fetch --- src/components/views/elements/TagTile.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/components/views/elements/TagTile.js b/src/components/views/elements/TagTile.js index 057ec4921b..00aea1efd3 100644 --- a/src/components/views/elements/TagTile.js +++ b/src/components/views/elements/TagTile.js @@ -58,6 +58,8 @@ export default React.createClass({ ).then((profile) => { if (this.unmounted) return; this.setState({profile}); + }).catch((err) => { + console.warn('Could not fetch group profile for ' + this.props.tag, err); }); } }, From 133837cdbed146b0b2adec13f739aed2f67adbe9 Mon Sep 17 00:00:00 2001 From: lukebarnard Date: Tue, 2 Jan 2018 15:59:10 +0000 Subject: [PATCH 7/7] Document initial state --- src/components/views/elements/TagTile.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/components/views/elements/TagTile.js b/src/components/views/elements/TagTile.js index 00aea1efd3..eb9a5cbdd9 100644 --- a/src/components/views/elements/TagTile.js +++ b/src/components/views/elements/TagTile.js @@ -44,7 +44,9 @@ export default React.createClass({ getInitialState() { return { + // Whether the mouse is over the tile hover: false, + // The profile data of the group if this.props.tag is a group ID profile: null, }; },