diff --git a/src/components/views/elements/MessageEditor.js b/src/components/views/elements/MessageEditor.js index 0c249d067b..4f1e1675a5 100644 --- a/src/components/views/elements/MessageEditor.js +++ b/src/components/views/elements/MessageEditor.js @@ -40,16 +40,17 @@ export default class MessageEditor extends React.Component { constructor(props, context) { super(props, context); + const room = this.context.matrixClient.getRoom(this.props.event.getRoomId()); const partCreator = new PartCreator( () => this._autocompleteRef, query => this.setState({query}), + room, ); this.model = new EditorModel( - parseEvent(this.props.event), + parseEvent(this.props.event, room), partCreator, this._updateEditorState, ); - const room = this.context.matrixClient.getRoom(this.props.event.getRoomId()); this.state = { autoComplete: null, room, diff --git a/src/editor/autocomplete.js b/src/editor/autocomplete.js index d2f73b1dff..82d4086b45 100644 --- a/src/editor/autocomplete.js +++ b/src/editor/autocomplete.js @@ -17,11 +17,12 @@ limitations under the License. import {UserPillPart, RoomPillPart, PlainPart} from "./parts"; export default class AutocompleteWrapperModel { - constructor(updateCallback, getAutocompleterComponent, updateQuery) { + constructor(updateCallback, getAutocompleterComponent, updateQuery, room) { this._updateCallback = updateCallback; this._getAutocompleterComponent = getAutocompleterComponent; this._updateQuery = updateQuery; this._query = null; + this._room = room; } onEscape(e) { @@ -83,11 +84,12 @@ export default class AutocompleteWrapperModel { case "@": { const displayName = completion.completion; const userId = completion.completionId; - return new UserPillPart(userId, displayName); + const member = this._room.getMember(userId); + return new UserPillPart(userId, displayName, member); } case "#": { const displayAlias = completion.completionId; - return new RoomPillPart(displayAlias); + return new RoomPillPart(displayAlias, this._room); } // also used for emoji completion default: diff --git a/src/editor/deserialize.js b/src/editor/deserialize.js index a7f28badb1..0c9d090ea5 100644 --- a/src/editor/deserialize.js +++ b/src/editor/deserialize.js @@ -17,7 +17,7 @@ limitations under the License. import { MATRIXTO_URL_PATTERN } from '../linkify-matrix'; import { PlainPart, UserPillPart, RoomPillPart, NewlinePart } from "./parts"; -function parseHtmlMessage(html) { +function parseHtmlMessage(html, room) { const REGEX_MATRIXTO = new RegExp(MATRIXTO_URL_PATTERN); // no nodes from parsing here should be inserted in the document, // as scripts in event handlers, etc would be executed then. @@ -37,8 +37,8 @@ function parseHtmlMessage(html) { const resourceId = pillMatch[1]; // The room/user ID const prefix = pillMatch[2]; // The first character of prefix switch (prefix) { - case "@": return new UserPillPart(resourceId, n.textContent); - case "#": return new RoomPillPart(resourceId, n.textContent); + case "@": return new UserPillPart(resourceId, n.textContent, room.getMember(resourceId)); + case "#": return new RoomPillPart(resourceId, n.textContent, room); default: return new PlainPart(n.textContent); } } @@ -54,10 +54,10 @@ function parseHtmlMessage(html) { return parts; } -export function parseEvent(event) { +export function parseEvent(event, room) { const content = event.getContent(); if (content.format === "org.matrix.custom.html") { - return parseHtmlMessage(content.formatted_body || ""); + return parseHtmlMessage(content.formatted_body || "", room); } else { const body = content.body || ""; const lines = body.split("\n"); diff --git a/src/editor/parts.js b/src/editor/parts.js index bf792b1ab9..53d596ae2d 100644 --- a/src/editor/parts.js +++ b/src/editor/parts.js @@ -216,8 +216,9 @@ export class NewlinePart extends BasePart { } export class RoomPillPart extends PillPart { - constructor(displayAlias) { + constructor(displayAlias, room) { super(displayAlias, displayAlias); + this._room = room; } get type() { @@ -226,6 +227,11 @@ export class RoomPillPart extends PillPart { } export class UserPillPart extends PillPart { + constructor(userId, displayName, member) { + super(userId, displayName); + this._member = member; + } + get type() { return "user-pill"; } @@ -256,9 +262,14 @@ export class PillCandidatePart extends PlainPart { } export class PartCreator { - constructor(getAutocompleterComponent, updateQuery) { + constructor(getAutocompleterComponent, updateQuery, room) { this._autoCompleteCreator = (updateCallback) => { - return new AutocompleteWrapperModel(updateCallback, getAutocompleterComponent, updateQuery); + return new AutocompleteWrapperModel( + updateCallback, + getAutocompleterComponent, + updateQuery, + room, + ); }; }