Merge pull request #1637 from matrix-org/luke/replace-IRC-with-flair

Replace (IRC) with flair
pull/21833/head
David Baker 2017-11-28 16:00:47 +00:00 committed by GitHub
commit a5acc2cfc2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 119 additions and 68 deletions

View File

@ -72,24 +72,19 @@ export default class Flair extends React.Component {
this.state = { this.state = {
profiles: [], profiles: [],
}; };
this.onRoomStateEvents = this.onRoomStateEvents.bind(this);
} }
componentWillUnmount() { componentWillUnmount() {
this._unmounted = true; this._unmounted = true;
this.context.matrixClient.removeListener('RoomState.events', this.onRoomStateEvents);
} }
componentWillMount() { componentWillMount() {
this._unmounted = false; this._unmounted = false;
this._generateAvatars(); this._generateAvatars(this.props.groups);
this.context.matrixClient.on('RoomState.events', this.onRoomStateEvents);
} }
onRoomStateEvents(event) { componentWillReceiveProps(newProps) {
if (event.getType() === 'm.room.related_groups' && FlairStore.groupSupport()) { this._generateAvatars(newProps.groups);
this._generateAvatars();
}
} }
async _getGroupProfiles(groups) { async _getGroupProfiles(groups) {
@ -106,23 +101,7 @@ export default class Flair extends React.Component {
return profiles.filter((p) => p !== null); return profiles.filter((p) => p !== null);
} }
async _generateAvatars() { async _generateAvatars(groups) {
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 = [];
}
}
if (!groups || groups.length === 0) { if (!groups || groups.length === 0) {
return; return;
} }
@ -148,13 +127,7 @@ export default class Flair extends React.Component {
} }
Flair.propTypes = { Flair.propTypes = {
userId: PropTypes.string, groups: PropTypes.arrayOf(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,
}; };
// TODO: We've decided that all components should follow this pattern, which means removing withMatrixClient and using // TODO: We've decided that all components should follow this pattern, which means removing withMatrixClient and using

View File

@ -17,50 +17,128 @@
'use strict'; 'use strict';
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types';
import {MatrixClient} from 'matrix-js-sdk';
import sdk from '../../../index'; import sdk from '../../../index';
import Flair from '../elements/Flair.js'; import Flair from '../elements/Flair.js';
import FlairStore from '../../../stores/FlairStore';
import { _t } from '../../../languageHandler'; import { _t } from '../../../languageHandler';
export default function SenderProfile(props) { export default React.createClass({
const EmojiText = sdk.getComponent('elements.EmojiText'); displayName: 'SenderProfile',
const {mxEvent} = props; propTypes: {
const name = mxEvent.sender ? mxEvent.sender.name : mxEvent.getSender(); mxEvent: PropTypes.object.isRequired, // event whose sender we're showing
const {msgtype} = mxEvent.getContent(); text: PropTypes.string, // Text to show. Defaults to sender name
onClick: PropTypes.func,
},
if (msgtype === 'm.emote') { contextTypes: {
return <span />; // emote message must include the name so don't duplicate it matrixClient: PropTypes.instanceOf(MatrixClient),
} },
const nameElem = <EmojiText key='name'>{ name || '' }</EmojiText>; getInitialState() {
return {
userGroups: null,
relatedGroups: [],
};
},
// Name + flair componentWillMount() {
const nameFlair = <span> this.unmounted = false;
<span className="mx_SenderProfile_name"> this._updateRelatedGroups();
{ nameElem }
</span> FlairStore.getPublicisedGroupsCached(
{ props.enableFlair ? this.context.matrixClient, this.props.mxEvent.getSender(),
<Flair key='flair' ).then((userGroups) => {
userId={mxEvent.getSender()} if (this.unmounted) return;
roomId={mxEvent.getRoomId()} this.setState({userGroups});
showRelated={true} /> });
: null
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();
} }
</span>; },
const content = props.text ? _updateRelatedGroups() {
<span className="mx_SenderProfile_aux"> if (this.unmounted) return;
{ _t(props.text, { senderName: () => nameElem }) } const relatedGroupsEvent = this.context.matrixClient
</span> : nameFlair; .getRoom(this.props.mxEvent.getRoomId())
.currentState
.getStateEvents('m.room.related_groups', '');
this.setState({
relatedGroups: relatedGroupsEvent ?
relatedGroupsEvent.getContent().groups || []
: [],
});
},
return ( _getDisplayedGroups(userGroups, relatedGroups) {
<div className="mx_SenderProfile" dir="auto" onClick={props.onClick}> let displayedGroups = userGroups || [];
{ content } if (relatedGroups && relatedGroups.length > 0) {
</div> displayedGroups = displayedGroups.filter((groupId) => {
); return relatedGroups.includes(groupId);
} });
} else {
displayedGroups = [];
}
return displayedGroups;
},
SenderProfile.propTypes = { render() {
mxEvent: React.PropTypes.object.isRequired, // event whose sender we're showing const EmojiText = sdk.getComponent('elements.EmojiText');
text: React.PropTypes.string, // Text to show. Defaults to sender name const {mxEvent} = this.props;
onClick: React.PropTypes.func, let name = mxEvent.sender ? mxEvent.sender.name : mxEvent.getSender();
}; const {msgtype} = mxEvent.getContent();
if (msgtype === 'm.emote') {
return <span />; // emote message must include the name so don't duplicate it
}
let flair = <div />;
if (this.props.enableFlair) {
const displayedGroups = this._getDisplayedGroups(
this.state.userGroups, this.state.relatedGroups,
);
// Backwards-compatible replacing of "(IRC)" with AS user flair
name = displayedGroups.length > 0 ? name.replace(' (IRC)', '') : name;
flair = <Flair key='flair'
userId={mxEvent.getSender()}
groups={displayedGroups}
/>;
}
const nameElem = <EmojiText key='name'>{ name || '' }</EmojiText>;
// Name + flair
const nameFlair = <span>
<span className="mx_SenderProfile_name">
{ nameElem }
</span>
{ flair }
</span>;
const content = this.props.text ?
<span className="mx_SenderProfile_aux">
{ _t(this.props.text, { senderName: () => nameElem }) }
</span> : nameFlair;
return (
<div className="mx_SenderProfile" dir="auto" onClick={this.props.onClick}>
{ content }
</div>
);
},
});