about summary refs log tree commit diff
path: root/app
diff options
context:
space:
mode:
authorEugen Rochko <eugen@zeonfederated.com>2019-06-28 15:54:10 +0200
committerGitHub <noreply@github.com>2019-06-28 15:54:10 +0200
commite64e6a03dd1e0978fee48f0596dcfbc7fd29958f (patch)
treed3a3da3ebed0fc4b942993bab88240f360903686 /app
parent072158ee973f8e09a0abd34a825d9bce038a5d68 (diff)
Add categories for custom emojis (#11196)
Fix #7940
Diffstat (limited to 'app')
-rw-r--r--app/controllers/api/v1/custom_emojis_controller.rb2
-rw-r--r--app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.js30
-rw-r--r--app/javascript/mastodon/features/emoji/emoji.js3
-rw-r--r--app/models/custom_emoji.rb2
-rw-r--r--app/models/custom_emoji_category.rb15
-rw-r--r--app/serializers/rest/custom_emoji_serializer.rb10
6 files changed, 47 insertions, 15 deletions
diff --git a/app/controllers/api/v1/custom_emojis_controller.rb b/app/controllers/api/v1/custom_emojis_controller.rb
index 1bb19a09d..b6877fb3c 100644
--- a/app/controllers/api/v1/custom_emojis_controller.rb
+++ b/app/controllers/api/v1/custom_emojis_controller.rb
@@ -7,7 +7,7 @@ class Api::V1::CustomEmojisController < Api::BaseController
 
   def index
     render_cached_json('api:v1:custom_emojis', expires_in: 1.minute) do
-      ActiveModelSerializers::SerializableResource.new(CustomEmoji.local.where(disabled: false), each_serializer: REST::CustomEmojiSerializer)
+      ActiveModelSerializers::SerializableResource.new(CustomEmoji.local.where(disabled: false).includes(:category), each_serializer: REST::CustomEmojiSerializer)
     end
   end
 end
diff --git a/app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.js b/app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.js
index c1429c756..e57c3c20c 100644
--- a/app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.js
+++ b/app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.js
@@ -6,7 +6,7 @@ import Overlay from 'react-overlays/lib/Overlay';
 import classNames from 'classnames';
 import ImmutablePropTypes from 'react-immutable-proptypes';
 import detectPassiveEvents from 'detect-passive-events';
-import { buildCustomEmojis } from '../../emoji/emoji';
+import { buildCustomEmojis, categoriesFromEmojis } from '../../emoji/emoji';
 
 const messages = defineMessages({
   emoji: { id: 'emoji_button.label', defaultMessage: 'Insert emoji' },
@@ -31,19 +31,6 @@ let EmojiPicker, Emoji; // load asynchronously
 const backgroundImageFn = () => `${assetHost}/emoji/sheet_10.png`;
 const listenerOptions = detectPassiveEvents.hasSupport ? { passive: true } : false;
 
-const categoriesSort = [
-  'recent',
-  'custom',
-  'people',
-  'nature',
-  'foods',
-  'activity',
-  'places',
-  'objects',
-  'symbols',
-  'flags',
-];
-
 class ModifierPickerMenu extends React.PureComponent {
 
   static propTypes = {
@@ -241,8 +228,23 @@ class EmojiPickerMenu extends React.PureComponent {
     }
 
     const title = intl.formatMessage(messages.emoji);
+
     const { modifierOpen } = this.state;
 
+    const categoriesSort = [
+      'recent',
+      'people',
+      'nature',
+      'foods',
+      'activity',
+      'places',
+      'objects',
+      'symbols',
+      'flags',
+    ];
+
+    categoriesSort.splice(1, 0, ...Array.from(categoriesFromEmojis(custom_emojis)).sort());
+
     return (
       <div className={classNames('emoji-picker-dropdown__menu', { selecting: modifierOpen })} style={style} ref={this.setRef}>
         <EmojiPicker
diff --git a/app/javascript/mastodon/features/emoji/emoji.js b/app/javascript/mastodon/features/emoji/emoji.js
index 988cea253..01b5a6664 100644
--- a/app/javascript/mastodon/features/emoji/emoji.js
+++ b/app/javascript/mastodon/features/emoji/emoji.js
@@ -92,8 +92,11 @@ export const buildCustomEmojis = (customEmojis) => {
       keywords: [name],
       imageUrl: url,
       custom: true,
+      customCategory: emoji.get('category'),
     });
   });
 
   return emojis;
 };
+
+export const categoriesFromEmojis = customEmojis => customEmojis.reduce((set, emoji) => set.add(emoji.get('category') ? `custom-${emoji.get('category')}` : 'custom'), new Set());
diff --git a/app/models/custom_emoji.rb b/app/models/custom_emoji.rb
index e73cd9bd2..514cf4845 100644
--- a/app/models/custom_emoji.rb
+++ b/app/models/custom_emoji.rb
@@ -16,6 +16,7 @@
 #  uri                :string
 #  image_remote_url   :string
 #  visible_in_picker  :boolean          default(TRUE), not null
+#  category_id        :bigint(8)
 #
 
 class CustomEmoji < ApplicationRecord
@@ -27,6 +28,7 @@ class CustomEmoji < ApplicationRecord
     :(#{SHORTCODE_RE_FRAGMENT}):
     (?=[^[:alnum:]:]|$)/x
 
+  belongs_to :category, class_name: 'CustomEmojiCategory', optional: true
   has_one :local_counterpart, -> { where(domain: nil) }, class_name: 'CustomEmoji', primary_key: :shortcode, foreign_key: :shortcode
 
   has_attached_file :image, styles: { static: { format: 'png', convert_options: '-coalesce -strip' } }
diff --git a/app/models/custom_emoji_category.rb b/app/models/custom_emoji_category.rb
new file mode 100644
index 000000000..7d8c0ee2d
--- /dev/null
+++ b/app/models/custom_emoji_category.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+# == Schema Information
+#
+# Table name: custom_emoji_categories
+#
+#  id         :bigint(8)        not null, primary key
+#  name       :string
+#  created_at :datetime         not null
+#  updated_at :datetime         not null
+#
+
+class CustomEmojiCategory < ApplicationRecord
+  has_many :emojis, class_name: 'CustomEmoji', foreign_key: 'category_id', inverse_of: :category
+end
diff --git a/app/serializers/rest/custom_emoji_serializer.rb b/app/serializers/rest/custom_emoji_serializer.rb
index 65686a866..aff58e4d9 100644
--- a/app/serializers/rest/custom_emoji_serializer.rb
+++ b/app/serializers/rest/custom_emoji_serializer.rb
@@ -5,6 +5,8 @@ class REST::CustomEmojiSerializer < ActiveModel::Serializer
 
   attributes :shortcode, :url, :static_url, :visible_in_picker
 
+  attribute :category, if: :category_loaded?
+
   def url
     full_asset_url(object.image.url)
   end
@@ -12,4 +14,12 @@ class REST::CustomEmojiSerializer < ActiveModel::Serializer
   def static_url
     full_asset_url(object.image.url(:static))
   end
+
+  def category
+    object.category.name
+  end
+
+  def category_loaded?
+    object.association(:category).loaded? && object.category.present?
+  end
 end