Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Replace (IRC) with flair #1637

Merged
merged 4 commits into from
Nov 28, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 5 additions & 32 deletions src/components/views/elements/Flair.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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;
}
Expand All @@ -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
Expand Down
160 changes: 119 additions & 41 deletions src/components/views/messages/SenderProfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,50 +17,128 @@
'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();

if (msgtype === 'm.emote') {
return <span />; // emote message must include the name so don't duplicate it
}

const nameElem = <EmojiText key='name'>{ name || '' }</EmojiText>;

// Name + flair
const nameFlair = <span>
<span className="mx_SenderProfile_name">
{ nameElem }
</span>
{ props.enableFlair ?
<Flair key='flair'
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} = 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()}
roomId={mxEvent.getRoomId()}
showRelated={true} />
: null
groups={displayedGroups}
/>;
}
</span>;

const content = props.text ?
<span className="mx_SenderProfile_aux">
{ _t(props.text, { senderName: () => nameElem }) }
</span> : nameFlair;

return (
<div className="mx_SenderProfile" dir="auto" onClick={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,
};

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>
);
},
});