summaryrefslogtreecommitdiffstats
path: root/web/react
diff options
context:
space:
mode:
authorFlorian Orben <florian.orben@gmail.com>2015-12-01 00:37:00 +0100
committerFlorian Orben <florian.orben@gmail.com>2015-12-01 22:41:06 +0100
commitc111777f85fc93ab18c6e28473e70c9ed2810683 (patch)
tree90b86627f7679529395b496a7b76c84f9f7bbea1 /web/react
parent2b2ee62a1df0504fff3f3e0e59966db1cd297531 (diff)
downloadchat-c111777f85fc93ab18c6e28473e70c9ed2810683.tar.gz
chat-c111777f85fc93ab18c6e28473e70c9ed2810683.tar.bz2
chat-c111777f85fc93ab18c6e28473e70c9ed2810683.zip
Allow to switch between default and emoji-one emoji style
Diffstat (limited to 'web/react')
-rw-r--r--web/react/components/post_body.jsx17
-rw-r--r--web/react/components/rhs_root_post.jsx7
-rw-r--r--web/react/components/user_settings/user_settings_display.jsx85
-rw-r--r--web/react/stores/preference_store.jsx1
-rw-r--r--web/react/utils/emoticons.jsx7
-rw-r--r--web/react/utils/utils.jsx9
6 files changed, 117 insertions, 9 deletions
diff --git a/web/react/components/post_body.jsx b/web/react/components/post_body.jsx
index de8195f91..75e4d735e 100644
--- a/web/react/components/post_body.jsx
+++ b/web/react/components/post_body.jsx
@@ -3,6 +3,7 @@
import FileAttachmentList from './file_attachment_list.jsx';
import UserStore from '../stores/user_store.jsx';
+import PreferenceStore from '../stores/preference_store.jsx';
import * as Utils from '../utils/utils.jsx';
import Constants from '../utils/constants.jsx';
import * as TextFormatting from '../utils/text_formatting.jsx';
@@ -19,6 +20,7 @@ export default class PostBody extends React.Component {
this.isImgLoading = false;
this.handleUserChange = this.handleUserChange.bind(this);
+ this.handlePreferenceChange = this.handlePreferenceChange.bind(this);
this.parseEmojis = this.parseEmojis.bind(this);
this.createEmbed = this.createEmbed.bind(this);
this.createImageEmbed = this.createImageEmbed.bind(this);
@@ -52,7 +54,11 @@ export default class PostBody extends React.Component {
}
parseEmojis() {
- twemoji.parse(ReactDOM.findDOMNode(this), {size: Constants.EMOJI_SIZE});
+ twemoji.parse(ReactDOM.findDOMNode(this), {
+ className: 'emoji twemoji',
+ base: '',
+ folder: Utils.getImagePathForEmoticon()
+ });
}
componentWillMount() {
@@ -65,6 +71,7 @@ export default class PostBody extends React.Component {
this.parseEmojis();
UserStore.addChangeListener(this.handleUserChange);
+ PreferenceStore.addChangeListener(this.handlePreferenceChange);
}
componentDidUpdate() {
@@ -73,6 +80,7 @@ export default class PostBody extends React.Component {
componentWillUnmount() {
UserStore.removeChangeListener(this.handleUserChange);
+ PreferenceStore.removeChangeListener(this.handlePreferenceChange);
}
handleUserChange() {
@@ -83,6 +91,13 @@ export default class PostBody extends React.Component {
}
}
+ handlePreferenceChange() {
+ $('.twemoji').each((idx, elem) => {
+ elem.src = Utils.getImagePathForEmoticon(twemoji.convert.toCodePoint(elem.alt));
+ });
+ this.forceUpdate();
+ }
+
componentWillReceiveProps(nextProps) {
const linkData = Utils.extractLinks(nextProps.post.message);
if (this.props.post.filenames.length === 0 && this.state.links && this.state.links.length > 0) {
diff --git a/web/react/components/rhs_root_post.jsx b/web/react/components/rhs_root_post.jsx
index 3d3d9e13f..8a9ca2009 100644
--- a/web/react/components/rhs_root_post.jsx
+++ b/web/react/components/rhs_root_post.jsx
@@ -8,7 +8,6 @@ import * as TextFormatting from '../utils/text_formatting.jsx';
import * as utils from '../utils/utils.jsx';
import FileAttachmentList from './file_attachment_list.jsx';
import twemoji from 'twemoji';
-import Constants from '../utils/constants.jsx';
import PostBodyAdditionalContent from './post_body_additional_content.jsx';
import * as EventHelpers from '../dispatcher/event_helpers.jsx';
@@ -21,7 +20,11 @@ export default class RhsRootPost extends React.Component {
this.state = {};
}
parseEmojis() {
- twemoji.parse(ReactDOM.findDOMNode(this), {size: Constants.EMOJI_SIZE});
+ twemoji.parse(ReactDOM.findDOMNode(this), {
+ className: 'emoji twemoji',
+ base: '',
+ folder: utils.getImagePathForEmoticon()
+ });
}
componentDidMount() {
this.parseEmojis();
diff --git a/web/react/components/user_settings/user_settings_display.jsx b/web/react/components/user_settings/user_settings_display.jsx
index 43c8d33d1..c83b74e62 100644
--- a/web/react/components/user_settings/user_settings_display.jsx
+++ b/web/react/components/user_settings/user_settings_display.jsx
@@ -6,14 +6,17 @@ import SettingItemMin from '../setting_item_min.jsx';
import SettingItemMax from '../setting_item_max.jsx';
import Constants from '../../utils/constants.jsx';
import PreferenceStore from '../../stores/preference_store.jsx';
+import * as Utils from '../../utils/utils.jsx';
function getDisplayStateFromStores() {
const militaryTime = PreferenceStore.getPreference(Constants.Preferences.CATEGORY_DISPLAY_SETTINGS, 'use_military_time', {value: 'false'});
const nameFormat = PreferenceStore.getPreference(Constants.Preferences.CATEGORY_DISPLAY_SETTINGS, 'name_format', {value: 'username'});
+ const emojiStyle = PreferenceStore.getPreference(Constants.Preferences.CATEGORY_DISPLAY_SETTINGS, 'emoji_style', {value: 'default'});
return {
militaryTime: militaryTime.value,
- nameFormat: nameFormat.value
+ nameFormat: nameFormat.value,
+ emojiStyle: emojiStyle.value
};
}
@@ -31,8 +34,9 @@ export default class UserSettingsDisplay extends React.Component {
handleSubmit() {
const timePreference = PreferenceStore.setPreference(Constants.Preferences.CATEGORY_DISPLAY_SETTINGS, 'use_military_time', this.state.militaryTime);
const namePreference = PreferenceStore.setPreference(Constants.Preferences.CATEGORY_DISPLAY_SETTINGS, 'name_format', this.state.nameFormat);
+ const emojiStyle = PreferenceStore.setPreference(Constants.Preferences.CATEGORY_DISPLAY_SETTINGS, 'emoji_style', this.state.emojiStyle);
- savePreferences([timePreference, namePreference],
+ savePreferences([timePreference, namePreference, emojiStyle],
() => {
PreferenceStore.emitChange();
this.updateSection('');
@@ -48,6 +52,9 @@ export default class UserSettingsDisplay extends React.Component {
handleNameRadio(nameFormat) {
this.setState({nameFormat});
}
+ handleEmojiRadio(emojiStyle) {
+ this.setState({emojiStyle});
+ }
updateSection(section) {
this.setState(getDisplayStateFromStores());
this.props.updateSection(section);
@@ -56,6 +63,7 @@ export default class UserSettingsDisplay extends React.Component {
const serverError = this.state.serverError || null;
let clockSection;
let nameFormatSection;
+ let emojiSection;
if (this.props.activeSection === 'clock') {
const clockFormat = [false, false];
if (this.state.militaryTime === 'true') {
@@ -209,6 +217,77 @@ export default class UserSettingsDisplay extends React.Component {
);
}
+ if (this.props.activeSection === 'emoji') {
+ const inputs = [
+ <div key='userDisplayClockOptions'>
+ <div className='radio'>
+ <label>
+ <input
+ type='radio'
+ checked={this.state.emojiStyle === 'default'}
+ onChange={this.handleEmojiRadio.bind(this, 'default')}
+ />
+ {'Default Style'}
+ <img
+ className='emoji'
+ src={Utils.getImagePathForEmoticon('smile', 'default')}
+ />
+ </label>
+ <br/>
+ </div>
+ <div className='radio'>
+ <label>
+ <input
+ type='radio'
+ checked={this.state.emojiStyle === 'emojione'}
+ onChange={this.handleEmojiRadio.bind(this, 'emojione')}
+ />
+ {'Emoji One Style'}
+ <img
+ className='emoji'
+ src={Utils.getImagePathForEmoticon('smile', 'emojione')}
+ />
+ <span className='emojiAffiliation'>
+ {'Emoji provided free by '}
+ <a
+ href='http://emojione.com/'
+ target='blank'
+ >
+ {'Emoji One'}
+ </a>
+ </span>
+ </label>
+ <br/>
+ </div>
+ <div><br/>{'Select how you prefer time displayed.'}</div>
+ </div>
+ ];
+
+ emojiSection = (
+ <SettingItemMax
+ title='Emoji Style'
+ inputs={inputs}
+ submit={this.handleSubmit}
+ server_error={serverError}
+ updateSection={(e) => {
+ this.updateSection('');
+ e.preventDefault();
+ }}
+ />
+ );
+ } else {
+ const describe = this.state.emojiStyle === 'default' ? 'Default Style' : 'Emoji One Style';
+ emojiSection = (
+ <SettingItemMin
+ title='Emoji Style'
+ describe={describe}
+ updateSection={() => {
+ this.props.updateSection('emoji');
+ }}
+ />
+ );
+ }
+
return (
<div>
<div className='modal-header'>
@@ -239,6 +318,8 @@ export default class UserSettingsDisplay extends React.Component {
<div className='divider-dark'/>
{nameFormatSection}
<div className='divider-dark'/>
+ {emojiSection}
+ <div className='divider-dark'/>
</div>
</div>
);
diff --git a/web/react/stores/preference_store.jsx b/web/react/stores/preference_store.jsx
index 068bc29c2..69a4c166b 100644
--- a/web/react/stores/preference_store.jsx
+++ b/web/react/stores/preference_store.jsx
@@ -122,5 +122,6 @@ class PreferenceStoreClass extends EventEmitter {
}
const PreferenceStore = new PreferenceStoreClass();
+PreferenceStore.setMaxListeners(0);
export default PreferenceStore;
window.PreferenceStore = PreferenceStore;
diff --git a/web/react/utils/emoticons.jsx b/web/react/utils/emoticons.jsx
index bb948b6dc..6a8ba6984 100644
--- a/web/react/utils/emoticons.jsx
+++ b/web/react/utils/emoticons.jsx
@@ -1,6 +1,8 @@
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
+import * as Utils from './utils.jsx';
+
const emoticonPatterns = {
smile: /(^|\s)(:-?\))(?=$|\s)/g, // :)
wink: /(^|\s)(;-?\))(?=$|\s)/g, // ;)
@@ -133,7 +135,7 @@ export function handleEmoticons(text, tokens) {
const alias = `MM_EMOTICON${index}`;
tokens.set(alias, {
- value: `<img align="absmiddle" alt="${matchText}" class="emoji" src="${getImagePathForEmoticon(name)}" title="${matchText}" />`,
+ value: `<img align="absmiddle" alt="${matchText}" class="emoji" src="${Utils.getImagePathForEmoticon(name)}" title="${matchText}" />`,
originalText: fullMatch
});
@@ -154,6 +156,3 @@ export function handleEmoticons(text, tokens) {
return output;
}
-function getImagePathForEmoticon(name) {
- return `/static/images/emoji/${name}.png`;
-}
diff --git a/web/react/utils/utils.jsx b/web/react/utils/utils.jsx
index aa9146183..df323eb0f 100644
--- a/web/react/utils/utils.jsx
+++ b/web/react/utils/utils.jsx
@@ -1227,3 +1227,12 @@ export function getPostTerm(post) {
export function isFeatureEnabled(feature) {
return PreferenceStore.getPreference(Constants.Preferences.CATEGORY_ADVANCED_SETTINGS, Constants.FeatureTogglePrefix + feature.label, {value: 'false'}).value === 'true';
}
+
+export function getImagePathForEmoticon(name, style) {
+ const emojiStyle = style || PreferenceStore.getPreference(Constants.Preferences.CATEGORY_DISPLAY_SETTINGS, 'emoji_style', {value: 'default'}).value;
+
+ if (name) {
+ return `/static/images/emoji/${emojiStyle}/${name}.png`;
+ }
+ return `/static/images/emoji/${emojiStyle}`;
+} \ No newline at end of file