From 2c514720d5a035c44dbeca930ec416ad60087304 Mon Sep 17 00:00:00 2001 From: hmhealey Date: Wed, 2 Dec 2015 12:06:42 -0500 Subject: Fixed emoticon code to use an ES6 map properly --- web/react/utils/emoticons.jsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'web') diff --git a/web/react/utils/emoticons.jsx b/web/react/utils/emoticons.jsx index 8943e9544..ab04936c0 100644 --- a/web/react/utils/emoticons.jsx +++ b/web/react/utils/emoticons.jsx @@ -116,19 +116,19 @@ function initializeEmoticonMap() { const out = new Map(); for (let i = 0; i < emoticonNames.length; i++) { - out[emoticonNames[i]] = true; + out.set(emoticonNames[i], true); } return out; } -const emoticonMap = initializeEmoticonMap(); +export const emoticonMap = initializeEmoticonMap(); export function handleEmoticons(text, tokens) { let output = text; function replaceEmoticonWithToken(fullMatch, prefix, matchText, name) { - if (emoticonMap[name]) { + if (emoticonMap.has(name)) { const index = tokens.size; const alias = `MM_EMOTICON${index}`; @@ -159,4 +159,4 @@ export function getImagePathForEmoticon(name) { return `/static/images/emoji/${name}.png`; } return `/static/images/emoji`; -} \ No newline at end of file +} -- cgit v1.2.3-1-g7c22 From 027c4c88f01210a967dc1f80919eb33d8da67737 Mon Sep 17 00:00:00 2001 From: hmhealey Date: Wed, 2 Dec 2015 12:11:49 -0500 Subject: Added emoji autocomplete to post textbox --- .../components/suggestion/emoticon_provider.jsx | 74 ++++++++++++++++++++++ .../components/suggestion/suggestion_list.jsx | 1 + web/react/components/textbox.jsx | 3 +- web/sass-files/sass/partials/_suggestion_list.scss | 16 +++++ 4 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 web/react/components/suggestion/emoticon_provider.jsx (limited to 'web') diff --git a/web/react/components/suggestion/emoticon_provider.jsx b/web/react/components/suggestion/emoticon_provider.jsx new file mode 100644 index 000000000..7dcb86442 --- /dev/null +++ b/web/react/components/suggestion/emoticon_provider.jsx @@ -0,0 +1,74 @@ +// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +import SuggestionStore from '../../stores/suggestion_store.jsx'; +import * as Emoticons from '../../utils/emoticons.jsx'; + +const MAX_EMOTICON_SUGGESTIONS = 40; + +class EmoticonSuggestion extends React.Component { + render() { + const text = this.props.term; + const name = this.props.item; + + let className = 'emoticon-suggestion'; + if (this.props.isSelection) { + className += ' suggestion--selected'; + } + + return ( +
+
+ {text} +
+
+ {text} +
+
+ ); + } +} + +EmoticonSuggestion.propTypes = { + item: React.PropTypes.string.isRequired, + term: React.PropTypes.string.isRequired, + isSelection: React.PropTypes.bool, + onClick: React.PropTypes.func +}; + +export default class EmoticonProvider { + handlePretextChanged(suggestionId, pretext) { + const captured = (/(?:^|\s)(:([a-zA-Z0-9_+\-]*))$/g).exec(pretext); + if (captured) { + const text = captured[1]; + const partialName = captured[2]; + + const terms = []; + const names = []; + + for (const emoticon of Emoticons.emoticonMap.keys()) { + if (emoticon.indexOf(partialName) !== -1) { + terms.push(':' + emoticon + ':'); + names.push(emoticon); + + if (terms.length >= MAX_EMOTICON_SUGGESTIONS) { + break; + } + } + } + + if (terms.length > 0) { + SuggestionStore.setMatchedPretext(suggestionId, text); + SuggestionStore.addSuggestions(suggestionId, terms, names, EmoticonSuggestion); + } + } + } +} diff --git a/web/react/components/suggestion/suggestion_list.jsx b/web/react/components/suggestion/suggestion_list.jsx index 45843f4c8..87021fd94 100644 --- a/web/react/components/suggestion/suggestion_list.jsx +++ b/web/react/components/suggestion/suggestion_list.jsx @@ -100,6 +100,7 @@ export default class SuggestionList extends React.Component { key={term} ref={term} item={item} + term={term} isSelection={isSelection} onClick={this.handleItemClick.bind(this, term)} /> diff --git a/web/react/components/textbox.jsx b/web/react/components/textbox.jsx index 107e65f57..b29f304ab 100644 --- a/web/react/components/textbox.jsx +++ b/web/react/components/textbox.jsx @@ -3,6 +3,7 @@ import AtMentionProvider from './suggestion/at_mention_provider.jsx'; import CommandProvider from './suggestion/command_provider.jsx'; +import EmoticonProvider from './suggestion/emoticon_provider.jsx'; import SuggestionList from './suggestion/suggestion_list.jsx'; import SuggestionBox from './suggestion/suggestion_box.jsx'; import ErrorStore from '../stores/error_store.jsx'; @@ -29,7 +30,7 @@ export default class Textbox extends React.Component { connection: '' }; - this.suggestionProviders = [new AtMentionProvider()]; + this.suggestionProviders = [new AtMentionProvider(), new EmoticonProvider()]; if (props.supportsCommands) { this.suggestionProviders.push(new CommandProvider()); } diff --git a/web/sass-files/sass/partials/_suggestion_list.scss b/web/sass-files/sass/partials/_suggestion_list.scss index c3df88964..0cf3fff5f 100644 --- a/web/sass-files/sass/partials/_suggestion_list.scss +++ b/web/sass-files/sass/partials/_suggestion_list.scss @@ -45,3 +45,19 @@ .command-desc { color: #a7a8ab; } + +.emoticon-suggestion { + width: 100%; + height: 36px; + cursor: pointer; + font-size: 13px; + line-height: 36px; +} + +.emoticon-suggestion__image { + width: 32px; + height: 32px; + margin-right: 6px; + padding: 2px; + text-align: center; +} -- cgit v1.2.3-1-g7c22