Browse Source

Add categories for custom emojis (#11196)

Fix #7940
master^2
Eugen Rochko 4 years ago
committed by GitHub
parent
commit
e64e6a03dd
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 86 additions and 18 deletions
  1. +1
    -1
      app/controllers/api/v1/custom_emojis_controller.rb
  2. +16
    -14
      app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.js
  3. +3
    -0
      app/javascript/mastodon/features/emoji/emoji.js
  4. +2
    -0
      app/models/custom_emoji.rb
  5. +15
    -0
      app/models/custom_emoji_category.rb
  6. +10
    -0
      app/serializers/rest/custom_emoji_serializer.rb
  7. +9
    -0
      db/migrate/20190627222225_create_custom_emoji_categories.rb
  8. +5
    -0
      db/migrate/20190627222826_add_category_id_to_custom_emojis.rb
  9. +9
    -1
      db/schema.rb
  10. +6
    -0
      lib/mastodon/emoji_cli.rb
  11. +3
    -0
      spec/fabricators/custom_emoji_category_fabricator.rb
  12. +5
    -0
      spec/models/custom_emoji_category_spec.rb
  13. +2
    -2
      yarn.lock

+ 1
- 1
app/controllers/api/v1/custom_emojis_controller.rb View File

@@ -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

+ 16
- 14
app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.js View File

@@ -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


+ 3
- 0
app/javascript/mastodon/features/emoji/emoji.js View File

@@ -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());

+ 2
- 0
app/models/custom_emoji.rb View File

@@ -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' } }


+ 15
- 0
app/models/custom_emoji_category.rb View File

@@ -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

+ 10
- 0
app/serializers/rest/custom_emoji_serializer.rb View File

@@ -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

+ 9
- 0
db/migrate/20190627222225_create_custom_emoji_categories.rb View File

@@ -0,0 +1,9 @@
class CreateCustomEmojiCategories < ActiveRecord::Migration[5.2]
def change
create_table :custom_emoji_categories do |t|
t.string :name, index: { unique: true }

t.timestamps
end
end
end

+ 5
- 0
db/migrate/20190627222826_add_category_id_to_custom_emojis.rb View File

@@ -0,0 +1,5 @@
class AddCategoryIdToCustomEmojis < ActiveRecord::Migration[5.2]
def change
add_column :custom_emojis, :category_id, :bigint
end
end

+ 9
- 1
db/schema.rb View File

@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 2019_05_29_143559) do
ActiveRecord::Schema.define(version: 2019_06_27_222826) do

# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -208,6 +208,13 @@ ActiveRecord::Schema.define(version: 2019_05_29_143559) do
t.index ["uri"], name: "index_conversations_on_uri", unique: true
end

create_table "custom_emoji_categories", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["name"], name: "index_custom_emoji_categories_on_name", unique: true
end

create_table "custom_emojis", force: :cascade do |t|
t.string "shortcode", default: "", null: false
t.string "domain"
@@ -221,6 +228,7 @@ ActiveRecord::Schema.define(version: 2019_05_29_143559) do
t.string "uri"
t.string "image_remote_url"
t.boolean "visible_in_picker", default: true, null: false
t.bigint "category_id"
t.index ["shortcode", "domain"], name: "index_custom_emojis_on_shortcode_and_domain", unique: true
end



+ 6
- 0
lib/mastodon/emoji_cli.rb View File

@@ -15,6 +15,7 @@ module Mastodon
option :suffix
option :overwrite, type: :boolean
option :unlisted, type: :boolean
option :category
desc 'import PATH', 'Import emoji from a TAR GZIP archive at PATH'
long_desc <<-LONG_DESC
Imports custom emoji from a TAR GZIP archive specified by PATH.
@@ -22,6 +23,9 @@ module Mastodon
Existing emoji will be skipped unless the --overwrite option
is provided, in which case they will be overwritten.

You can specifiy a --category under which the emojis will be
grouped together.

With the --prefix option, a prefix can be added to all
generated shortcodes. Likewise, the --suffix option controls
the suffix of all shortcodes.
@@ -33,6 +37,7 @@ module Mastodon
imported = 0
skipped = 0
failed = 0
category = options[:category] ? CustomEmojiCategory.find_or_create_by(name: options[:category]) : nil

Gem::Package::TarReader.new(Zlib::GzipReader.open(path)) do |tar|
tar.each do |entry|
@@ -50,6 +55,7 @@ module Mastodon
custom_emoji.image = StringIO.new(entry.read)
custom_emoji.image_file_name = File.basename(entry.full_name)
custom_emoji.visible_in_picker = !options[:unlisted]
custom_emoji.category = category

if custom_emoji.save
imported += 1


+ 3
- 0
spec/fabricators/custom_emoji_category_fabricator.rb View File

@@ -0,0 +1,3 @@
Fabricator(:custom_emoji_category) do
name "MyString"
end

+ 5
- 0
spec/models/custom_emoji_category_spec.rb View File

@@ -0,0 +1,5 @@
require 'rails_helper'

RSpec.describe CustomEmojiCategory, type: :model do
pending "add some examples to (or delete) #{__FILE__}"
end

+ 2
- 2
yarn.lock View File

@@ -3384,8 +3384,8 @@ elliptic@^6.0.0:
minimalistic-crypto-utils "^1.0.0"

emoji-mart@Gargron/emoji-mart#build:
version "2.6.2"
resolved "https://codeload.github.com/Gargron/emoji-mart/tar.gz/ff00dc470b5b2d9f145a6d6e977a54de5df2b4c9"
version "2.6.3"
resolved "https://codeload.github.com/Gargron/emoji-mart/tar.gz/934f314fd8322276765066e8a2a6be5bac61b1cf"

emoji-regex@^7.0.1, emoji-regex@^7.0.2:
version "7.0.3"


Loading…
Cancel
Save