Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/controllers/api/v1/custom_emojis_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -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' },
Expand All @@ -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 = {
Expand Down Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions app/javascript/mastodon/features/emoji/emoji.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 changes: 2 additions & 0 deletions app/models/custom_emoji.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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' } }
Expand Down
15 changes: 15 additions & 0 deletions app/models/custom_emoji_category.rb
Original file line number Diff line number Diff line change
@@ -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 changes: 10 additions & 0 deletions app/serializers/rest/custom_emoji_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,21 @@ 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

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 changes: 9 additions & 0 deletions db/migrate/20190627222225_create_custom_emoji_categories.rb
Original file line number Diff line number Diff line change
@@ -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 changes: 5 additions & 0 deletions db/migrate/20190627222826_add_category_id_to_custom_emojis.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddCategoryIdToCustomEmojis < ActiveRecord::Migration[5.2]
def change
add_column :custom_emojis, :category_id, :bigint
end
end
10 changes: 9 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -208,6 +208,13 @@
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"
Expand All @@ -221,6 +228,7 @@
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

Expand Down
6 changes: 6 additions & 0 deletions lib/mastodon/emoji_cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,17 @@ def self.exit_on_failure?
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.

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.
Expand All @@ -33,6 +37,7 @@ def import(path)
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|
Expand All @@ -50,6 +55,7 @@ def import(path)
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
Expand Down
3 changes: 3 additions & 0 deletions spec/fabricators/custom_emoji_category_fabricator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Fabricator(:custom_emoji_category) do
name "MyString"
end
5 changes: 5 additions & 0 deletions spec/models/custom_emoji_category_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
require 'rails_helper'

RSpec.describe CustomEmojiCategory, type: :model do
pending "add some examples to (or delete) #{__FILE__}"
end
4 changes: 2 additions & 2 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down