From 3addb924b1caa60d96886596d9245421d2b01f0a Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Tue, 28 Nov 2017 10:04:34 +0000 Subject: [PATCH] Replace (IRC) with flair If a user has public groups that are honoured in their flair, remove the (IRC) to give the appearance that the flair replaces it. --- src/components/views/elements/Flair.js | 37 +---- .../views/messages/SenderProfile.js | 140 +++++++++++++----- 2 files changed, 109 insertions(+), 68 deletions(-) diff --git a/src/components/views/elements/Flair.js b/src/components/views/elements/Flair.js index 4a34dac0de..25a8d538e1 100644 --- a/src/components/views/elements/Flair.js +++ b/src/components/views/elements/Flair.js @@ -72,24 +72,19 @@ export default class Flair extends React.Component { this.state = { profiles: [], }; - this.onRoomStateEvents = this.onRoomStateEvents.bind(this); } componentWillUnmount() { this._unmounted = true; - this.context.matrixClient.removeListener('RoomState.events', this.onRoomStateEvents); } componentWillMount() { this._unmounted = false; - this._generateAvatars(); - this.context.matrixClient.on('RoomState.events', this.onRoomStateEvents); + this._generateAvatars(this.props.groups); } - onRoomStateEvents(event) { - if (event.getType() === 'm.room.related_groups' && FlairStore.groupSupport()) { - this._generateAvatars(); - } + componentWillReceiveProps(newProps) { + this._generateAvatars(newProps.groups); } async _getGroupProfiles(groups) { @@ -106,23 +101,7 @@ export default class Flair extends React.Component { return profiles.filter((p) => p !== null); } - async _generateAvatars() { - let groups = await FlairStore.getPublicisedGroupsCached(this.context.matrixClient, this.props.userId); - if (this.props.roomId && this.props.showRelated) { - const relatedGroupsEvent = this.context.matrixClient - .getRoom(this.props.roomId) - .currentState - .getStateEvents('m.room.related_groups', ''); - const relatedGroups = relatedGroupsEvent ? - relatedGroupsEvent.getContent().groups || [] : []; - if (relatedGroups && relatedGroups.length > 0) { - groups = groups.filter((groupId) => { - return relatedGroups.includes(groupId); - }); - } else { - groups = []; - } - } + async _generateAvatars(groups) { if (!groups || groups.length === 0) { return; } @@ -148,13 +127,7 @@ export default class Flair extends React.Component { } Flair.propTypes = { - userId: PropTypes.string, - - // Whether to show only the flair associated with related groups of the given room, - // or all flair associated with a user. - showRelated: PropTypes.bool, - // The room that this flair will be displayed in. Optional. Only applies when showRelated = true. - roomId: PropTypes.string, + groups: PropTypes.arrayOf(PropTypes.string), }; // TODO: We've decided that all components should follow this pattern, which means removing withMatrixClient and using diff --git a/src/components/views/messages/SenderProfile.js b/src/components/views/messages/SenderProfile.js index 28064070cb..e2f2eb3cea 100644 --- a/src/components/views/messages/SenderProfile.js +++ b/src/components/views/messages/SenderProfile.js @@ -17,50 +17,118 @@ 'use strict'; import React from 'react'; +import PropTypes from 'prop-types'; +import {MatrixClient} from 'matrix-js-sdk'; import sdk from '../../../index'; import Flair from '../elements/Flair.js'; +import FlairStore from '../../../stores/FlairStore'; import { _t } from '../../../languageHandler'; -export default function SenderProfile(props) { - const EmojiText = sdk.getComponent('elements.EmojiText'); - const {mxEvent} = props; - const name = mxEvent.sender ? mxEvent.sender.name : mxEvent.getSender(); - const {msgtype} = mxEvent.getContent(); +export default React.createClass({ + displayName: 'SenderProfile', + propTypes: { + mxEvent: PropTypes.object.isRequired, // event whose sender we're showing + text: PropTypes.string, // Text to show. Defaults to sender name + onClick: PropTypes.func, + }, - if (msgtype === 'm.emote') { - return ; // emote message must include the name so don't duplicate it - } + contextTypes: { + matrixClient: PropTypes.instanceOf(MatrixClient), + }, - const nameElem = { name || '' }; + getInitialState() { + return { + groups: null, + relatedGroups: [], + }; + }, - // Name + flair - const nameFlair = - - { nameElem } - - { props.enableFlair ? - - : null + componentWillMount() { + this.unmounted = false; + this._updateRelatedGroups(); + + FlairStore.getPublicisedGroupsCached( + this.context.matrixClient, this.props.mxEvent.getSender(), + ).then((groups) => { + if (this.unmounted) return; + this.setState({groups}); + }); + + this.context.matrixClient.on('RoomState.events', this.onRoomStateEvents); + }, + + componentWillUnmount() { + this.unmounted = true; + this.context.matrixClient.removeListener('RoomState.events', this.onRoomStateEvents); + }, + + onRoomStateEvents(event) { + if (event.getType() === 'm.room.related_groups' && + event.getRoomId() === this.props.mxEvent.getRoomId() + ) { + this._updateRelatedGroups(); } - ; + }, - const content = props.text ? - - { _t(props.text, { senderName: () => nameElem }) } - : nameFlair; + _updateRelatedGroups() { + if (this.unmounted) return; + const relatedGroupsEvent = this.context.matrixClient + .getRoom(this.props.mxEvent.getRoomId()) + .currentState + .getStateEvents('m.room.related_groups', ''); + this.setState({ + relatedGroups: relatedGroupsEvent ? + relatedGroupsEvent.getContent().groups || [] + : [], + }); + }, - return ( -
- { content } -
- ); -} + render() { + const EmojiText = sdk.getComponent('elements.EmojiText'); + const {mxEvent} = this.props; + let name = mxEvent.sender ? mxEvent.sender.name : mxEvent.getSender(); + const {msgtype} = mxEvent.getContent(); -SenderProfile.propTypes = { - mxEvent: React.PropTypes.object.isRequired, // event whose sender we're showing - text: React.PropTypes.string, // Text to show. Defaults to sender name - onClick: React.PropTypes.func, -}; + if (msgtype === 'm.emote') { + return ; // emote message must include the name so don't duplicate it + } + + let groups = this.state.groups || []; + if (this.state.relatedGroups && this.state.relatedGroups.length > 0) { + groups = groups.filter((groupId) => { + return this.state.relatedGroups.includes(groupId); + }); + } else { + groups = []; + } + + name = groups.length > 0 ? name.replace(' (IRC)', '') : name; + + const nameElem = { name || '' }; + + // Name + flair + const nameFlair = + + { nameElem } + + { this.props.enableFlair ? + + : null + } + ; + + const content = this.props.text ? + + { _t(this.props.text, { senderName: () => nameElem }) } + : nameFlair; + + return ( +
+ { content } +
+ ); + }, +});