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

Decorate matrix.to anchor tags as mx_UserPill and mx_RoomPill #1227

Merged
merged 3 commits into from
Jul 19, 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
25 changes: 0 additions & 25 deletions src/RichText.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,31 +113,6 @@ let emojiDecorator = {
* Returns a composite decorator which has access to provided scope.
*/
export function getScopedRTDecorators(scope: any): CompositeDecorator {
let MemberAvatar = sdk.getComponent('avatars.MemberAvatar');

let usernameDecorator = {
strategy: (contentBlock, callback) => {
findWithRegex(USERNAME_REGEX, contentBlock, callback);
},
component: (props) => {
let member = scope.room.getMember(props.children[0].props.text);
// unused until we make these decorators immutable (autocomplete needed)
let name = member ? member.name : null;
let avatar = member ? <MemberAvatar member={member} width={16} height={16}/> : null;
return <span className="mx_UserPill">{avatar}{props.children}</span>;
}
};

let roomDecorator = {
strategy: (contentBlock, callback) => {
findWithRegex(ROOM_REGEX, contentBlock, callback);
},
component: (props) => {
return <span className="mx_RoomPill">{props.children}</span>;
}
};

// TODO Re-enable usernameDecorator and roomDecorator
return [emojiDecorator];
}

Expand Down
55 changes: 55 additions & 0 deletions src/components/views/messages/TextualBody.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ import SdkConfig from '../../../SdkConfig';
import dis from '../../../dispatcher';
import { _t } from '../../../languageHandler';
import UserSettingsStore from "../../../UserSettingsStore";
import MatrixClientPeg from '../../../MatrixClientPeg';
import {RoomMember} from 'matrix-js-sdk';

linkifyMatrix(linkify);

Expand Down Expand Up @@ -80,6 +82,10 @@ module.exports = React.createClass({
componentDidMount: function() {
this._unmounted = false;

// pillifyLinks BEFORE linkifyElement because plain room/user URLs in the composer
// are still sent as plaintext URLs. If these are ever pillified in the composer,
// we should be pillify them here by doing the linkifying BEFORE the pillifying.
this.pillifyLinks(this.refs.content.children);
linkifyElement(this.refs.content, linkifyMatrix.options);
this.calculateUrlPreview();

Expand Down Expand Up @@ -162,6 +168,55 @@ module.exports = React.createClass({
}
},

pillifyLinks: function(nodes) {
const MemberAvatar = sdk.getComponent('avatars.MemberAvatar');
const RoomAvatar = sdk.getComponent('avatars.RoomAvatar');
for (let i = 0; i < nodes.length; i++) {
const node = nodes[i];
if (node.tagName === "A" && node.getAttribute("href")) {
const href = node.getAttribute("href");
// HtmlUtils transforms `matrix.to` links to local links, so match against
// user or room app links.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, it looks like your code is right, although I'm failing to find where this happens. It probably should not, and leave the href as matrix.to but override the onclick like we do with permalinks and linkified users / rooms.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, transformTags

const match = /^#\/(user|room)\/(.*)$/.exec(href) || [];
const resourceType = match[1]; // "user" or "room"
const resourceId = match[2]; // user ID or room ID
if (match && resourceType && resourceId) {
let avatar;
let roomId;
let room;
let member;
switch (resourceType) {
case "user":
roomId = this.props.mxEvent.getRoomId();
room = MatrixClientPeg.get().getRoom(roomId);
member = room.getMember(resourceId) ||
new RoomMember(null, resourceId);
avatar = <MemberAvatar member={member} width={16} height={16} name={resourceId}/>;
break;
case "room":
room = resourceId[0] === '#' ?
MatrixClientPeg.get().getRooms().find((r) => {
return r.getCanonicalAlias() === resourceId;
}) : MatrixClientPeg.get().getRoom(resourceId);
if (room) {
avatar = <RoomAvatar room={room} width={16} height={16}/>;
}
break;
}
if (avatar) {
const avatarContainer = document.createElement('span');
node.className = "mx_MTextBody_pill " +
(resourceType === "user" ? "mx_UserPill" : "mx_RoomPill");
ReactDOM.render(avatar, avatarContainer);
node.insertBefore(avatarContainer, node.firstChild);
}
}
} else if (node.children && node.children.length) {
this.pillifyLinks(node.children);
}
}
},

findLinks: function(nodes) {
var links = [];

Expand Down