diff options
Diffstat (limited to 'webapp/stores/emoji_store.jsx')
-rw-r--r-- | webapp/stores/emoji_store.jsx | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/webapp/stores/emoji_store.jsx b/webapp/stores/emoji_store.jsx new file mode 100644 index 000000000..5e1d81dd3 --- /dev/null +++ b/webapp/stores/emoji_store.jsx @@ -0,0 +1,135 @@ +// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +import AppDispatcher from '../dispatcher/app_dispatcher.jsx'; +import Constants from 'utils/constants.jsx'; +import EventEmitter from 'events'; + +import EmojiJson from 'utils/emoji.json'; + +const ActionTypes = Constants.ActionTypes; + +const CHANGE_EVENT = 'changed'; + +class EmojiStore extends EventEmitter { + constructor() { + super(); + + this.dispatchToken = AppDispatcher.register(this.handleEventPayload.bind(this)); + + this.emojis = new Map(EmojiJson); + this.systemEmojis = new Map(EmojiJson); + + this.unicodeEmojis = new Map(); + for (const [, emoji] of this.systemEmojis) { + if (emoji.unicode) { + this.unicodeEmojis.set(emoji.unicode, emoji); + } + } + + this.receivedCustomEmojis = false; + this.customEmojis = new Map(); + } + + addChangeListener(callback) { + this.on(CHANGE_EVENT, callback); + } + + removeChangeListener(callback) { + this.removeListener(CHANGE_EVENT, callback); + } + + emitChange() { + this.emit(CHANGE_EVENT); + } + + hasReceivedCustomEmojis() { + return this.receivedCustomEmojis; + } + + setCustomEmojis(customEmojis) { + this.customEmojis = new Map(); + + for (const emoji of customEmojis) { + this.addCustomEmoji(emoji); + } + + // add custom emojis to the map first so that they can't override system ones + this.emojis = new Map([...this.customEmojis, ...this.systemEmojis]); + } + + addCustomEmoji(emoji) { + this.customEmojis.set(emoji.name, emoji); + } + + removeCustomEmoji(id) { + for (const [name, emoji] of this.customEmojis) { + if (emoji.id === id) { + this.customEmojis.delete(name); + break; + } + } + } + + getSystemEmojis() { + return this.systemEmojis; + } + + getCustomEmojiMap() { + return this.customEmojis; + } + + getEmojis() { + return this.emojis; + } + + has(name) { + return this.emojis.has(name); + } + + get(name) { + // prioritize system emojis so that custom ones can't override them + return this.emojis.get(name); + } + + hasUnicode(codepoint) { + return this.unicodeEmojis.has(codepoint); + } + + getUnicode(codepoint) { + return this.unicodeEmojis.get(codepoint); + } + + getEmojiImageUrl(emoji) { + if (emoji.id) { + // must match Client.getCustomEmojiImageUrl + return `/api/v3/emoji/${emoji.id}`; + } + + const filename = emoji.unicode || emoji.filename || emoji.name; + + return Constants.EMOJI_PATH + '/' + filename + '.png'; + } + + handleEventPayload(payload) { + const action = payload.action; + + switch (action.type) { + case ActionTypes.RECEIVED_CUSTOM_EMOJIS: + this.setCustomEmojis(action.emojis); + this.receivedCustomEmojis = true; + this.emitChange(); + break; + case ActionTypes.RECEIVED_CUSTOM_EMOJI: + this.addCustomEmoji(action.emoji); + this.emitChange(); + break; + case ActionTypes.REMOVED_CUSTOM_EMOJI: + this.removeCustomEmoji(action.id); + this.emitChange(); + break; + } + } +} + +export default new EmojiStore(); |