diff --git a/src/autocomplete/Autocompleter.js b/src/autocomplete/Autocompleter.js index 6fadf53a61..7a64fb154c 100644 --- a/src/autocomplete/Autocompleter.js +++ b/src/autocomplete/Autocompleter.js @@ -34,12 +34,9 @@ export type Completion = { component: ?Component, range: SelectionRange, command: ?string, - // An entity applied during the replacement (using draftjs@0.8.1 Entity.create) - entity: ? { - type: string, - mutability: string, - data: ?Object, - }, + // If provided, apply a LINK entity to the completion with the + // data = { url: href }. + href: ?string, }; const PROVIDERS = [ diff --git a/src/components/views/messages/TextualBody.js b/src/components/views/messages/TextualBody.js index 85cc85be49..b901f98f19 100644 --- a/src/components/views/messages/TextualBody.js +++ b/src/components/views/messages/TextualBody.js @@ -297,10 +297,9 @@ module.exports = React.createClass({ onEmoteSenderClick: function(event) { const mxEvent = this.props.mxEvent; - const name = mxEvent.sender ? mxEvent.sender.name : mxEvent.getSender(); dis.dispatch({ - action: 'insert_displayname', - displayname: name.replace(' (IRC)', ''), + action: 'insert_mention', + user_id: mxEvent.getSender(), }); }, diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index 68ef3a1f44..b3831a7d0d 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -357,10 +357,10 @@ module.exports = withMatrixClient(React.createClass({ }, onSenderProfileClick: function(event) { - var mxEvent = this.props.mxEvent; + const mxEvent = this.props.mxEvent; dis.dispatch({ - action: 'insert_displayname', - displayname: (mxEvent.sender ? mxEvent.sender.name : mxEvent.getSender()).replace(' (IRC)', ''), + action: 'insert_mention', + user_id: mxEvent.getSender(), }); }, diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index 3165765167..2c011f3770 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -285,22 +285,20 @@ export default class MessageComposerInput extends React.Component { case 'focus_composer': editor.focus(); break; - - // TODO change this so we insert a complete user alias - - case 'insert_displayname': { - contentState = Modifier.replaceText( - contentState, - this.state.editorState.getSelection(), - `${payload.displayname}: `, - ); - let editorState = EditorState.push(this.state.editorState, contentState, 'insert-characters'); - editorState = EditorState.forceSelection(editorState, contentState.getSelectionAfter()); - this.onEditorContentChanged(editorState); - editor.focus(); + case 'insert_mention': { + // Pretend that we've autocompleted this user because keeping two code + // paths for inserting a user pill is not fun + const selection = this.state.editorState.getSelection(); + const member = this.props.room.getMember(payload.user_id); + const completion = member ? member.name.replace(' (IRC)', '') : payload.user_id; + this.setDisplayedCompletion({ + completion, + selection, + href: `https://matrix.to/#/${payload.user_id}`, + suffix: selection.getStartOffset() === 0 ? ': ' : ' ', + }); } break; - case 'quote': { let {body, formatted_body} = payload.event.getContent(); formatted_body = formatted_body || escape(body); @@ -938,7 +936,8 @@ export default class MessageComposerInput extends React.Component { return false; } - const {range = {}, completion = '', href = null, suffix = ''} = displayedCompletion; + const {range = null, completion = '', href = null, suffix = ''} = displayedCompletion; + let entityKey; let mdCompletion; if (href) { @@ -948,11 +947,18 @@ export default class MessageComposerInput extends React.Component { } } + let selection; + if (range) { + selection = RichText.textOffsetsToSelectionState( + range, activeEditorState.getCurrentContent().getBlocksAsArray(), + ); + } else { + selection = activeEditorState.getSelection(); + } + let contentState = Modifier.replaceText( activeEditorState.getCurrentContent(), - RichText.textOffsetsToSelectionState( - range, activeEditorState.getCurrentContent().getBlocksAsArray(), - ), + selection, mdCompletion || completion, null, entityKey,