summaryrefslogtreecommitdiffstats
path: root/webapp/components/emoji/components/emoji_list.jsx
diff options
context:
space:
mode:
Diffstat (limited to 'webapp/components/emoji/components/emoji_list.jsx')
-rw-r--r--webapp/components/emoji/components/emoji_list.jsx218
1 files changed, 218 insertions, 0 deletions
diff --git a/webapp/components/emoji/components/emoji_list.jsx b/webapp/components/emoji/components/emoji_list.jsx
new file mode 100644
index 000000000..5795a57b2
--- /dev/null
+++ b/webapp/components/emoji/components/emoji_list.jsx
@@ -0,0 +1,218 @@
+// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+import React from 'react';
+
+import * as AsyncClient from 'utils/async_client.jsx';
+import EmojiStore from 'stores/emoji_store.jsx';
+import TeamStore from 'stores/team_store.jsx';
+import * as Utils from 'utils/utils.jsx';
+
+import {FormattedMessage} from 'react-intl';
+import EmojiListItem from './emoji_list_item.jsx';
+import {Link} from 'react-router';
+import LoadingScreen from 'components/loading_screen.jsx';
+
+export default class EmojiList extends React.Component {
+ static get propTypes() {
+ return {
+ team: React.propTypes.object.isRequired,
+ user: React.propTypes.object.isRequired
+ };
+ }
+
+ constructor(props) {
+ super(props);
+
+ this.canCreateEmojis = this.canCreateEmojis.bind(this);
+
+ this.handleEmojiChange = this.handleEmojiChange.bind(this);
+
+ this.deleteEmoji = this.deleteEmoji.bind(this);
+
+ this.updateFilter = this.updateFilter.bind(this);
+
+ this.state = {
+ emojis: EmojiStore.getCustomEmojiMap(),
+ loading: !EmojiStore.hasReceivedCustomEmojis(),
+ filter: ''
+ };
+ }
+
+ componentDidMount() {
+ EmojiStore.addChangeListener(this.handleEmojiChange);
+
+ if (window.mm_config.EnableCustomEmoji === 'true') {
+ AsyncClient.listEmoji();
+ }
+ }
+
+ componentWillUnmount() {
+ EmojiStore.removeChangeListener(this.handleEmojiChange);
+ }
+
+ handleEmojiChange() {
+ this.setState({
+ emojis: EmojiStore.getCustomEmojiMap(),
+ loading: !EmojiStore.hasReceivedCustomEmojis()
+ });
+ }
+
+ updateFilter(e) {
+ this.setState({
+ filter: e.target.value
+ });
+ }
+
+ deleteEmoji(emoji) {
+ AsyncClient.deleteEmoji(emoji.id);
+ }
+
+ canCreateEmojis() {
+ if (global.window.mm_license.IsLicensed !== 'true') {
+ return true;
+ }
+
+ if (Utils.isSystemAdmin(this.props.user.roles)) {
+ return true;
+ }
+
+ if (window.mm_config.RestrictCustomEmojiCreation === 'all') {
+ return true;
+ }
+
+ if (window.mm_config.RestrictCustomEmojiCreation === 'admin') {
+ // check whether the user is an admin on any of their teams
+ for (const member of TeamStore.getTeamMembers()) {
+ if (Utils.isAdmin(member.roles)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ render() {
+ const filter = this.state.filter.toLowerCase();
+ const isSystemAdmin = Utils.isSystemAdmin(this.props.user.roles);
+
+ let emojis = [];
+ if (this.state.loading) {
+ emojis.push(
+ <LoadingScreen key='loading'/>
+ );
+ } else if (this.state.emojis.length === 0) {
+ emojis.push(
+ <tr className='backstage-list__item backstage-list__empty'>
+ <td colSpan='4'>
+ <FormattedMessage
+ id='emoji_list.empty'
+ defaultMessage='No custom emoji found'
+ />
+ </td>
+ </tr>
+ );
+ } else {
+ for (const [, emoji] of this.state.emojis) {
+ let onDelete = null;
+ if (isSystemAdmin || this.props.user.id === emoji.creator_id) {
+ onDelete = this.deleteEmoji;
+ }
+
+ emojis.push(
+ <EmojiListItem
+ key={emoji.id}
+ emoji={emoji}
+ onDelete={onDelete}
+ filter={filter}
+ />
+ );
+ }
+ }
+
+ let addLink = null;
+ if (this.canCreateEmojis()) {
+ addLink = (
+ <Link
+ className='add-link'
+ to={'/' + this.props.team.name + '/emoji/add'}
+ >
+ <button
+ type='button'
+ className='btn btn-primary'
+ >
+ <FormattedMessage
+ id='emoji_list.add'
+ defaultMessage='Add Custom Emoji'
+ />
+ </button>
+ </Link>
+ );
+ }
+
+ return (
+ <div className='backstage-content emoji-list'>
+ <div className='backstage-header'>
+ <h1>
+ <FormattedMessage
+ id='emoji_list.header'
+ defaultMessage='Custom Emoji'
+ />
+ </h1>
+ {addLink}
+ </div>
+ <div className='backstage-filters'>
+ <div className='backstage-filter__search'>
+ <i className='fa fa-search'></i>
+ <input
+ type='search'
+ className='form-control'
+ placeholder={Utils.localizeMessage('emoji_list.search', 'Search Custom Emoji')}
+ value={this.state.filter}
+ onChange={this.updateFilter}
+ style={{flexGrow: 0, flexShrink: 0}}
+ />
+ </div>
+ </div>
+ <span className='emoji-list__help'>
+ <FormattedMessage
+ id='emoji_list.help'
+ defaultMessage='Custom emoji are available to everyone on your server and will show up in the emoji autocomplete menu.'
+ />
+ </span>
+ <div className='backstage-list'>
+ <table className='emoji-list__table'>
+ <tr className='backstage-list__item emoji-list__table-header'>
+ <th className='emoji-list__name'>
+ <FormattedMessage
+ id='emoji_list.name'
+ defaultMessage='Name'
+ />
+ </th>
+ <th className='emoji-list__image'>
+ <FormattedMessage
+ id='emoji_list.image'
+ defaultMessage='Image'
+ />
+ </th>
+ <th className='emoji-list__creator'>
+ <FormattedMessage
+ id='emoji_list.creator'
+ defaultMessage='Creator'
+ />
+ </th>
+ <th className='emoji-list_actions'>
+ <FormattedMessage
+ id='emoji_list.actions'
+ defaultMessage='Actions'
+ />
+ </th>
+ </tr>
+ {emojis}
+ </table>
+ </div>
+ </div>
+ );
+ }
+}