Merge branch 'develop' into travis/granular-settings

This commit is contained in:
Travis Ralston 2017-11-03 22:00:07 -06:00
commit 893c39bfbe
40 changed files with 954 additions and 548 deletions

View file

@ -19,6 +19,7 @@
import React from 'react';
import sdk from '../../../index';
import Flair from '../elements/Flair.js';
import { _tJsx } from '../../../languageHandler';
export default function SenderProfile(props) {
const EmojiText = sdk.getComponent('elements.EmojiText');
@ -30,23 +31,39 @@ export default function SenderProfile(props) {
return <span />; // emote message must include the name so don't duplicate it
}
// Name + flair
const nameElem = [
<EmojiText key='name' className="mx_SenderProfile_name">{ name || '' }</EmojiText>,
props.enableFlair ?
<Flair key='flair'
userId={mxEvent.getSender()}
roomId={mxEvent.getRoomId()}
showRelated={true} />
: null,
];
let content = '';
if(props.text) {
// Replace senderName, and wrap surrounding text in spans with the right class
content = _tJsx(props.text, /^(.*)\%\(senderName\)s(.*)$/m, (p1, p2) => [
p1 ? <span className='mx_SenderProfile_aux'>{ p1 }</span> : null,
nameElem,
p2 ? <span className='mx_SenderProfile_aux'>{ p2 }</span> : null,
]);
} else {
content = nameElem;
}
return (
<div className="mx_SenderProfile" dir="auto" onClick={props.onClick}>
<EmojiText className="mx_SenderProfile_name">{ name || '' }</EmojiText>
{ props.enableFlair ?
<Flair
userId={mxEvent.getSender()}
roomId={mxEvent.getRoomId()}
showRelated={true} />
: null
}
{ props.aux ? <EmojiText className="mx_SenderProfile_aux"> { props.aux }</EmojiText> : null }
{ content }
</div>
);
}
SenderProfile.propTypes = {
mxEvent: React.PropTypes.object.isRequired, // event whose sender we're showing
aux: React.PropTypes.string, // stuff to go after the sender name, if anything
text: React.PropTypes.string, // Text to show. Defaults to sender name
onClick: React.PropTypes.func,
};

View file

@ -34,6 +34,7 @@ import ContextualMenu from '../../structures/ContextualMenu';
import {RoomMember} from 'matrix-js-sdk';
import classNames from 'classnames';
import SettingsStore from "../../../settings/SettingsStore";
import PushProcessor from 'matrix-js-sdk/lib/pushprocessor';
linkifyMatrix(linkify);
@ -169,8 +170,10 @@ module.exports = React.createClass({
pillifyLinks: function(nodes) {
const shouldShowPillAvatar = !SettingsStore.getValue("Pill.shouldHidePillAvatar");
for (let i = 0; i < nodes.length; i++) {
const node = nodes[i];
let node = nodes[0];
while (node) {
let pillified = false;
if (node.tagName === "A" && node.getAttribute("href")) {
const href = node.getAttribute("href");
@ -189,10 +192,71 @@ module.exports = React.createClass({
ReactDOM.render(pill, pillContainer);
node.parentNode.replaceChild(pillContainer, node);
// Pills within pills aren't going to go well, so move on
pillified = true;
// update the current node with one that's now taken its place
node = pillContainer;
}
} else if (node.nodeType == Node.TEXT_NODE) {
const Pill = sdk.getComponent('elements.Pill');
let currentTextNode = node;
const roomNotifTextNodes = [];
// Take a textNode and break it up to make all the instances of @room their
// own textNode, adding those nodes to roomNotifTextNodes
while (currentTextNode !== null) {
const roomNotifPos = Pill.roomNotifPos(currentTextNode.textContent);
let nextTextNode = null;
if (roomNotifPos > -1) {
let roomTextNode = currentTextNode;
if (roomNotifPos > 0) roomTextNode = roomTextNode.splitText(roomNotifPos);
if (roomTextNode.textContent.length > Pill.roomNotifLen()) {
nextTextNode = roomTextNode.splitText(Pill.roomNotifLen());
}
roomNotifTextNodes.push(roomTextNode);
}
currentTextNode = nextTextNode;
}
if (roomNotifTextNodes.length > 0) {
const pushProcessor = new PushProcessor(MatrixClientPeg.get());
const atRoomRule = pushProcessor.getPushRuleById(".m.rule.roomnotif");
if (pushProcessor.ruleMatchesEvent(atRoomRule, this.props.mxEvent)) {
// Now replace all those nodes with Pills
for (const roomNotifTextNode of roomNotifTextNodes) {
const pillContainer = document.createElement('span');
const room = MatrixClientPeg.get().getRoom(this.props.mxEvent.getRoomId());
const pill = <Pill
type={Pill.TYPE_AT_ROOM_MENTION}
inMessage={true}
room={room}
shouldShowPillAvatar={true}
/>;
ReactDOM.render(pill, pillContainer);
roomNotifTextNode.parentNode.replaceChild(pillContainer, roomNotifTextNode);
// Set the next node to be processed to the one after the node
// we're adding now, since we've just inserted nodes into the structure
// we're iterating over.
// Note we've checked roomNotifTextNodes.length > 0 so we'll do this at least once
node = roomNotifTextNode.nextSibling;
}
// Nothing else to do for a text node (and we don't need to advance
// the loop pointer because we did it above)
continue;
}
}
} else if (node.children && node.children.length) {
this.pillifyLinks(node.children);
}
if (node.childNodes && node.childNodes.length && !pillified) {
this.pillifyLinks(node.childNodes);
}
node = node.nextSibling;
}
},