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

Replace (IRC) with flair
This commit is contained in:
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 = {
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

View file

@ -17,20 +17,109 @@
'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) {
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,
},
contextTypes: {
matrixClient: PropTypes.instanceOf(MatrixClient),
},
getInitialState() {
return {
userGroups: null,
relatedGroups: [],
};
},
componentWillMount() {
this.unmounted = false;
this._updateRelatedGroups();
FlairStore.getPublicisedGroupsCached(
this.context.matrixClient, this.props.mxEvent.getSender(),
).then((userGroups) => {
if (this.unmounted) return;
this.setState({userGroups});
});
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();
}
},
_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 || []
: [],
});
},
_getDisplayedGroups(userGroups, relatedGroups) {
let displayedGroups = userGroups || [];
if (relatedGroups && relatedGroups.length > 0) {
displayedGroups = displayedGroups.filter((groupId) => {
return relatedGroups.includes(groupId);
});
} else {
displayedGroups = [];
}
return displayedGroups;
},
render() {
const EmojiText = sdk.getComponent('elements.EmojiText');
const {mxEvent} = props;
const name = mxEvent.sender ? mxEvent.sender.name : mxEvent.getSender();
const {mxEvent} = this.props;
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
@ -38,29 +127,18 @@ export default function SenderProfile(props) {
<span className="mx_SenderProfile_name">
{ nameElem }
</span>
{ props.enableFlair ?
<Flair key='flair'
userId={mxEvent.getSender()}
roomId={mxEvent.getRoomId()}
showRelated={true} />
: null
}
{ flair }
</span>;
const content = props.text ?
const content = this.props.text ?
<span className="mx_SenderProfile_aux">
{ _t(props.text, { senderName: () => nameElem }) }
{ _t(this.props.text, { senderName: () => nameElem }) }
</span> : nameFlair;
return (
<div className="mx_SenderProfile" dir="auto" onClick={props.onClick}>
<div className="mx_SenderProfile" dir="auto" onClick={this.props.onClick}>
{ content }
</div>
);
}
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,
};
},
});