fix cursor behaviour around pills

pull/21833/head
Matthew Hodgson 2018-05-13 00:40:54 +01:00
parent 9c0c806af4
commit c91dcffe82
2 changed files with 43 additions and 9 deletions

View File

@ -64,11 +64,11 @@ class PlainWithPillsSerializer {
} else if (node.type == 'pill') { } else if (node.type == 'pill') {
switch (this.pillFormat) { switch (this.pillFormat) {
case 'plain': case 'plain':
return node.text; return node.data.get('completion');
case 'md': case 'md':
return `[${ node.text }](${ node.data.get('url') })`; return `[${ node.text }](${ node.data.get('url') })`;
case 'id': case 'id':
return node.data.completionId || node.text; return node.data.get('completionId') || node.data.get('completion');
} }
} }
else if (node.nodes) { else if (node.nodes) {

View File

@ -177,6 +177,8 @@ export default class MessageComposerInput extends React.Component {
this.plainWithMdPills = new PlainWithPillsSerializer({ pillFormat: 'md' }); this.plainWithMdPills = new PlainWithPillsSerializer({ pillFormat: 'md' });
this.plainWithIdPills = new PlainWithPillsSerializer({ pillFormat: 'id' }); this.plainWithIdPills = new PlainWithPillsSerializer({ pillFormat: 'id' });
this.plainWithPlainPills = new PlainWithPillsSerializer({ pillFormat: 'plain' }); this.plainWithPlainPills = new PlainWithPillsSerializer({ pillFormat: 'plain' });
this.direction = '';
} }
/* /*
@ -358,6 +360,17 @@ export default class MessageComposerInput extends React.Component {
} }
onChange = (change: Change) => { onChange = (change: Change) => {
let editorState = change.value;
if (this.direction !== '') {
const focusedNode = editorState.focusInline || editorState.focusText;
if (focusedNode.isVoid) {
change = change[`collapseToEndOf${ this.direction }Text`]();
editorState = change.value;
}
}
/* /*
editorState = RichText.attachImmutableEntitiesToEmoji(editorState); editorState = RichText.attachImmutableEntitiesToEmoji(editorState);
@ -417,7 +430,7 @@ export default class MessageComposerInput extends React.Component {
*/ */
/* Since a modification was made, set originalEditorState to null, since newState is now our original */ /* Since a modification was made, set originalEditorState to null, since newState is now our original */
this.setState({ this.setState({
editorState: change.value, editorState,
originalEditorState: null, originalEditorState: null,
}); });
}; };
@ -521,6 +534,18 @@ export default class MessageComposerInput extends React.Component {
} }
onKeyDown = (ev: Event, change: Change, editor: Editor) => { onKeyDown = (ev: Event, change: Change, editor: Editor) => {
// skip void nodes - see
// https://github.com/ianstormtaylor/slate/issues/762#issuecomment-304855095
if (ev.keyCode === KeyCode.LEFT) {
this.direction = 'Previous';
}
else if (ev.keyCode === KeyCode.RIGHT) {
this.direction = 'Next';
} else {
this.direction = '';
}
switch (ev.keyCode) { switch (ev.keyCode) {
case KeyCode.ENTER: case KeyCode.ENTER:
return this.handleReturn(ev); return this.handleReturn(ev);
@ -1010,14 +1035,23 @@ export default class MessageComposerInput extends React.Component {
if (href) { if (href) {
inline = Inline.create({ inline = Inline.create({
type: 'pill', type: 'pill',
data: { url: href }, data: { completion, completionId, url: href },
nodes: [Text.create(completionId || completion)], // we can't put text in here otherwise the editor tries to select it
isVoid: true,
nodes: [],
}); });
} else if (completion === '@room') { } else if (completion === '@room') {
inline = Inline.create({ inline = Inline.create({
type: 'pill', type: 'pill',
data: { type: Pill.TYPE_AT_ROOM_MENTION }, data: { completion, completionId },
nodes: [Text.create(completionId || completion)], // we can't put text in here otherwise the editor tries to select it
isVoid: true,
nodes: [],
});
} else {
inline = Inline.create({
type: 'autocompletion',
nodes: [Text.create(completion)]
}); });
} }
@ -1072,12 +1106,12 @@ export default class MessageComposerInput extends React.Component {
case 'pill': { case 'pill': {
const { data, text } = node; const { data, text } = node;
const url = data.get('url'); const url = data.get('url');
const type = data.get('type'); const completion = data.get('completion');
const shouldShowPillAvatar = !SettingsStore.getValue("Pill.shouldHidePillAvatar"); const shouldShowPillAvatar = !SettingsStore.getValue("Pill.shouldHidePillAvatar");
const Pill = sdk.getComponent('elements.Pill'); const Pill = sdk.getComponent('elements.Pill');
if (type === Pill.TYPE_AT_ROOM_MENTION) { if (completion === '@room') {
return <Pill return <Pill
type={Pill.TYPE_AT_ROOM_MENTION} type={Pill.TYPE_AT_ROOM_MENTION}
room={this.props.room} room={this.props.room}