summaryrefslogtreecommitdiffstats
path: root/webapp/components/suggestion
diff options
context:
space:
mode:
authorHarrison Healey <harrisonmhealey@gmail.com>2016-12-06 07:36:40 -0500
committerenahum <nahumhbl@gmail.com>2016-12-06 09:36:40 -0300
commitb477e384d86e9233aed55448598352d2c42a1525 (patch)
tree4ccb6bf77d140700c842c8999c8fdf70de244758 /webapp/components/suggestion
parent01015dd30ef74cf4b3080cd5f9ff5c5cf9df39d2 (diff)
downloadchat-b477e384d86e9233aed55448598352d2c42a1525.tar.gz
chat-b477e384d86e9233aed55448598352d2c42a1525.tar.bz2
chat-b477e384d86e9233aed55448598352d2c42a1525.zip
Added support for autocompleting at mentions for users with non-alphanumeric names (#4717)
Diffstat (limited to 'webapp/components/suggestion')
-rw-r--r--webapp/components/suggestion/at_mention_provider.jsx3
-rw-r--r--webapp/components/suggestion/suggestion_box.jsx45
2 files changed, 31 insertions, 17 deletions
diff --git a/webapp/components/suggestion/at_mention_provider.jsx b/webapp/components/suggestion/at_mention_provider.jsx
index 6118b8d98..f1b36d697 100644
--- a/webapp/components/suggestion/at_mention_provider.jsx
+++ b/webapp/components/suggestion/at_mention_provider.jsx
@@ -15,6 +15,7 @@ import {Constants, ActionTypes} from 'utils/constants.jsx';
import React from 'react';
import {FormattedMessage} from 'react-intl';
+import XRegExp from 'xregexp';
class AtMentionSuggestion extends Suggestion {
render() {
@@ -124,7 +125,7 @@ export default class AtMentionProvider {
handlePretextChanged(suggestionId, pretext) {
const hadSuggestions = this.clearTimeout(this.timeoutId);
- const captured = (/(?:^|\W)@([a-z0-9\-._]*)$/i).exec(pretext.toLowerCase());
+ const captured = XRegExp.cache('(?:^|\\W)@([\\pL\\d\\-_.]*)$', 'i').exec(pretext.toLowerCase());
if (captured) {
const prefix = captured[1];
diff --git a/webapp/components/suggestion/suggestion_box.jsx b/webapp/components/suggestion/suggestion_box.jsx
index 514227394..a1f89efb5 100644
--- a/webapp/components/suggestion/suggestion_box.jsx
+++ b/webapp/components/suggestion/suggestion_box.jsx
@@ -22,11 +22,15 @@ export default class SuggestionBox extends React.Component {
this.handleCompleteWord = this.handleCompleteWord.bind(this);
this.handleChange = this.handleChange.bind(this);
+ this.handleCompositionUpdate = this.handleCompositionUpdate.bind(this);
this.handleKeyDown = this.handleKeyDown.bind(this);
this.handlePretextChanged = this.handlePretextChanged.bind(this);
this.suggestionId = Utils.generateId();
SuggestionStore.registerSuggestionBox(this.suggestionId);
+
+ // Keep track of whether we're composing a CJK character so we can make suggetsions for partial characters
+ this.partialCharacter = '';
}
componentDidMount() {
@@ -83,20 +87,28 @@ export default class SuggestionBox extends React.Component {
handleChange(e) {
const textbox = this.getTextbox();
const caret = Utils.getCaretPosition(textbox);
- const pretext = textbox.value.substring(0, caret);
+ const pretext = textbox.value.substring(0, caret) + this.partialCharacter;
- GlobalActions.emitSuggestionPretextChanged(this.suggestionId, pretext);
+ if (SuggestionStore.getPretext(this.suggestionId) !== pretext) {
+ GlobalActions.emitSuggestionPretextChanged(this.suggestionId, pretext);
+ }
if (this.props.onChange) {
this.props.onChange(e);
}
}
+ handleCompositionUpdate(e) {
+ // Save the currently composing character so that it can be used for autocomplete suggestions
+ // when handleChange is called immediately after this
+ this.partialCharacter = e.data;
+ }
+
handleCompleteWord(term, matchedPretext) {
const textbox = this.getTextbox();
const caret = Utils.getCaretPosition(textbox);
const text = this.props.value;
- const pretext = text.substring(0, caret);
+ const pretext = text.substring(0, caret) + this.partialCharacter;
let prefix;
if (pretext.endsWith(matchedPretext)) {
@@ -168,37 +180,38 @@ export default class SuggestionBox extends React.Component {
...props
} = this.props;
+ // Don't pass props used by SuggestionBox
+ Reflect.deleteProperty(props, 'providers');
+
+ const childProps = {
+ ref: 'textbox',
+ onInput: this.handleChange,
+ onCompositionUpdate: this.handleCompositionUpdate,
+ onKeyDown: this.handleKeyDown
+ };
+
let textbox = null;
if (type === 'input') {
textbox = (
<input
- ref='textbox'
type='text'
{...props}
- onInput={this.handleChange}
- onKeyDown={this.handleKeyDown}
+ {...childProps}
/>
);
} else if (type === 'search') {
- const newProps = {...props};
- Reflect.deleteProperty(newProps, 'providers');
textbox = (
<input
- ref='textbox'
type='search'
- {...newProps}
- onInput={this.handleChange}
- onKeyDown={this.handleKeyDown}
+ {...props}
+ {...childProps}
/>
);
} else if (type === 'textarea') {
textbox = (
<AutosizeTextarea
- id={this.suggestionId}
- ref='textbox'
{...props}
- onInput={this.handleChange}
- onKeyDown={this.handleKeyDown}
+ {...childProps}
/>
);
}