151 строка
3.7 KiB
JavaScript
151 строка
3.7 KiB
JavaScript
// 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.setMaxListeners(600);
|
|
|
|
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);
|
|
}
|
|
|
|
this.sortCustomEmojis();
|
|
this.updateEmojiMap();
|
|
}
|
|
|
|
addCustomEmoji(emoji) {
|
|
this.customEmojis.set(emoji.name, emoji);
|
|
|
|
// this doesn't update this.emojis, but it's only called by setCustomEmojis which does that afterwards
|
|
}
|
|
|
|
removeCustomEmoji(id) {
|
|
for (const [name, emoji] of this.customEmojis) {
|
|
if (emoji.id === id) {
|
|
this.customEmojis.delete(name);
|
|
break;
|
|
}
|
|
}
|
|
|
|
this.updateEmojiMap();
|
|
}
|
|
|
|
sortCustomEmojis() {
|
|
this.customEmojis = new Map([...this.customEmojis.entries()].sort((a, b) => a[0].localeCompare(b[0])));
|
|
}
|
|
|
|
updateEmojiMap() {
|
|
// add custom emojis to the map first so that they can't override system ones
|
|
this.emojis = new Map([...this.customEmojis, ...this.systemEmojis]);
|
|
}
|
|
|
|
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();
|