diff options
author | Harrison Healey <harrisonmhealey@gmail.com> | 2016-07-05 11:58:18 -0400 |
---|---|---|
committer | Joram Wilander <jwawilander@gmail.com> | 2016-07-05 11:58:18 -0400 |
commit | dc2f2a800105b77e665ec2a00c6290f35b1a2ba3 (patch) | |
tree | 82f23c2e72a7c785f55c2d6c1c35c10c16994918 /webapp/stores | |
parent | a65f1fc266f15eaa8f79541d4d11440c3d356bb6 (diff) | |
download | chat-dc2f2a800105b77e665ec2a00c6290f35b1a2ba3.tar.gz chat-dc2f2a800105b77e665ec2a00c6290f35b1a2ba3.tar.bz2 chat-dc2f2a800105b77e665ec2a00c6290f35b1a2ba3.zip |
PLT-3145 Custom Emojis (#3381)
* Reorganized Backstage code to use a view controller and separated it from integrations code
* Renamed InstalledIntegrations component to BackstageList
* Added EmojiList page
* Added AddEmoji page
* Added custom emoji to autocomplete and text formatter
* Moved system emoji to EmojiStore
* Stopped trying to get emoji before logging in
* Rerender posts when emojis change
* Fixed submit handler on backstage pages to properly support enter
* Removed debugging code
* Updated javascript driver
* Fixed unit tests
* Fixed backstage routes
* Added clientside validation to prevent users from creating an emoji with the same name as a system one
* Fixed AddEmoji page to properly redirect when an emoji is created successfully
* Fixed updating emoji list when an emoji is deleted
* Added type prop to BackstageList to properly support using a table for the list
* Added help text to EmojiList
* Fixed backstage on smaller screen sizes
* Disable custom emoji by default
* Improved restrictions on creating emojis
* Fixed non-admin users seeing the option to delete each other's emojis
* Fixing gofmt
* Fixed emoji unit tests
* Fixed trying to get emoji from the server when it's disabled
Diffstat (limited to 'webapp/stores')
-rw-r--r-- | webapp/stores/emoji_store.jsx | 135 | ||||
-rw-r--r-- | webapp/stores/team_store.jsx | 7 |
2 files changed, 140 insertions, 2 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(); diff --git a/webapp/stores/team_store.jsx b/webapp/stores/team_store.jsx index f4d60ba74..d81863aba 100644 --- a/webapp/stores/team_store.jsx +++ b/webapp/stores/team_store.jsx @@ -160,13 +160,16 @@ class TeamStoreClass extends EventEmitter { } isTeamAdminForCurrentTeam() { + return this.isTeamAdmin(UserStore.getCurrentId(), this.getCurrentId()); + } + + isTeamAdmin(userId, teamId) { if (!Utils) { Utils = require('utils/utils.jsx'); //eslint-disable-line global-require } - const userId = UserStore.getCurrentId(); var teamMembers = this.getTeamMembers(); - const teamMember = teamMembers.find((m) => m.user_id === userId && m.team_id === this.getCurrentId()); + const teamMember = teamMembers.find((m) => m.user_id === userId && m.team_id === teamId); if (teamMember) { return Utils.isAdmin(teamMember.roles); |