Browse Source

Merge branch 'master' into glitch-soc/merge-upstream

Thibaut Girka 3 weeks ago
parent
commit
3922b518f7

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

@@ -7,7 +7,7 @@ class Api::V1::CustomEmojisController < Api::BaseController
7 7
 
8 8
   def index
9 9
     render_cached_json('api:v1:custom_emojis', expires_in: 1.minute) do
10
-      ActiveModelSerializers::SerializableResource.new(CustomEmoji.local.where(disabled: false), each_serializer: REST::CustomEmojiSerializer)
10
+      ActiveModelSerializers::SerializableResource.new(CustomEmoji.local.where(disabled: false).includes(:category), each_serializer: REST::CustomEmojiSerializer)
11 11
     end
12 12
   end
13 13
 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';
6 6
 import classNames from 'classnames';
7 7
 import ImmutablePropTypes from 'react-immutable-proptypes';
8 8
 import detectPassiveEvents from 'detect-passive-events';
9
-import { buildCustomEmojis } from '../../emoji/emoji';
9
+import { buildCustomEmojis, categoriesFromEmojis } from '../../emoji/emoji';
10 10
 
11 11
 const messages = defineMessages({
12 12
   emoji: { id: 'emoji_button.label', defaultMessage: 'Insert emoji' },
@@ -31,19 +31,6 @@ let EmojiPicker, Emoji; // load asynchronously
31 31
 const backgroundImageFn = () => `${assetHost}/emoji/sheet_10.png`;
32 32
 const listenerOptions = detectPassiveEvents.hasSupport ? { passive: true } : false;
33 33
 
34
-const categoriesSort = [
35
-  'recent',
36
-  'custom',
37
-  'people',
38
-  'nature',
39
-  'foods',
40
-  'activity',
41
-  'places',
42
-  'objects',
43
-  'symbols',
44
-  'flags',
45
-];
46
-
47 34
 class ModifierPickerMenu extends React.PureComponent {
48 35
 
49 36
   static propTypes = {
@@ -241,8 +228,23 @@ class EmojiPickerMenu extends React.PureComponent {
241 228
     }
242 229
 
243 230
     const title = intl.formatMessage(messages.emoji);
231
+
244 232
     const { modifierOpen } = this.state;
245 233
 
234
+    const categoriesSort = [
235
+      'recent',
236
+      'people',
237
+      'nature',
238
+      'foods',
239
+      'activity',
240
+      'places',
241
+      'objects',
242
+      'symbols',
243
+      'flags',
244
+    ];
245
+
246
+    categoriesSort.splice(1, 0, ...Array.from(categoriesFromEmojis(custom_emojis)).sort());
247
+
246 248
     return (
247 249
       <div className={classNames('emoji-picker-dropdown__menu', { selecting: modifierOpen })} style={style} ref={this.setRef}>
248 250
         <EmojiPicker

+ 1
- 1
app/javascript/mastodon/features/compose/containers/search_results_container.js View File

@@ -5,7 +5,7 @@ import { fetchSuggestions, dismissSuggestion } from '../../../actions/suggestion
5 5
 const mapStateToProps = state => ({
6 6
   results: state.getIn(['search', 'results']),
7 7
   suggestions: state.getIn(['suggestions', 'items']),
8
-  searchTerm: state.getIn(['search', 'value']),
8
+  searchTerm: state.getIn(['search', 'searchTerm']),
9 9
 });
10 10
 
11 11
 const mapDispatchToProps = dispatch => ({

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

@@ -92,8 +92,11 @@ export const buildCustomEmojis = (customEmojis) => {
92 92
       keywords: [name],
93 93
       imageUrl: url,
94 94
       custom: true,
95
+      customCategory: emoji.get('category'),
95 96
     });
96 97
   });
97 98
 
98 99
   return emojis;
99 100
 };
101
+
102
+export const categoriesFromEmojis = customEmojis => customEmojis.reduce((set, emoji) => set.add(emoji.get('category') ? `custom-${emoji.get('category')}` : 'custom'), new Set());

+ 5
- 1
app/javascript/mastodon/features/ui/components/columns_area.js View File

@@ -110,6 +110,11 @@ class ColumnsArea extends ImmutablePureComponent {
110 110
     // React-router does this for us, but too late, feeling laggy.
111 111
     document.querySelector(currentLinkSelector).classList.remove('active');
112 112
     document.querySelector(nextLinkSelector).classList.add('active');
113
+
114
+    if (!this.state.shouldAnimate && typeof this.pendingIndex === 'number') {
115
+      this.context.router.history.push(getLink(this.pendingIndex));
116
+      this.pendingIndex = null;
117
+    }
113 118
   }
114 119
 
115 120
   handleAnimationEnd = () => {
@@ -160,7 +165,6 @@ class ColumnsArea extends ImmutablePureComponent {
160 165
     const { shouldAnimate } = this.state;
161 166
 
162 167
     const columnIndex = getIndex(this.context.router.history.location.pathname);
163
-    this.pendingIndex = null;
164 168
 
165 169
     if (singleColumn) {
166 170
       const floatingActionButton = shouldHideFAB(this.context.router.history.location.pathname) ? null : <Link key='floating-action-button' to='/statuses/new' className='floating-action-button' aria-label={intl.formatMessage(messages.publish)}><Icon id='pencil' /></Link>;

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

@@ -16,6 +16,7 @@
16 16
 #  uri                :string
17 17
 #  image_remote_url   :string
18 18
 #  visible_in_picker  :boolean          default(TRUE), not null
19
+#  category_id        :bigint(8)
19 20
 #
20 21
 
21 22
 class CustomEmoji < ApplicationRecord
@@ -27,6 +28,7 @@ class CustomEmoji < ApplicationRecord
27 28
     :(#{SHORTCODE_RE_FRAGMENT}):
28 29
     (?=[^[:alnum:]:]|$)/x
29 30
 
31
+  belongs_to :category, class_name: 'CustomEmojiCategory', optional: true
30 32
   has_one :local_counterpart, -> { where(domain: nil) }, class_name: 'CustomEmoji', primary_key: :shortcode, foreign_key: :shortcode
31 33
 
32 34
   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 @@
1
+# frozen_string_literal: true
2
+
3
+# == Schema Information
4
+#
5
+# Table name: custom_emoji_categories
6
+#
7
+#  id         :bigint(8)        not null, primary key
8
+#  name       :string
9
+#  created_at :datetime         not null
10
+#  updated_at :datetime         not null
11
+#
12
+
13
+class CustomEmojiCategory < ApplicationRecord
14
+  has_many :emojis, class_name: 'CustomEmoji', foreign_key: 'category_id', inverse_of: :category
15
+end

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

@@ -5,6 +5,8 @@ class REST::CustomEmojiSerializer < ActiveModel::Serializer
5 5
 
6 6
   attributes :shortcode, :url, :static_url, :visible_in_picker
7 7
 
8
+  attribute :category, if: :category_loaded?
9
+
8 10
   def url
9 11
     full_asset_url(object.image.url)
10 12
   end
@@ -12,4 +14,12 @@ class REST::CustomEmojiSerializer < ActiveModel::Serializer
12 14
   def static_url
13 15
     full_asset_url(object.image.url(:static))
14 16
   end
17
+
18
+  def category
19
+    object.category.name
20
+  end
21
+
22
+  def category_loaded?
23
+    object.association(:category).loaded? && object.category.present?
24
+  end
15 25
 end

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

@@ -0,0 +1,9 @@
1
+class CreateCustomEmojiCategories < ActiveRecord::Migration[5.2]
2
+  def change
3
+    create_table :custom_emoji_categories do |t|
4
+      t.string :name, index: { unique: true }
5
+
6
+      t.timestamps
7
+    end
8
+  end
9
+end

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

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

+ 9
- 1
db/schema.rb View File

@@ -10,7 +10,7 @@
10 10
 #
11 11
 # It's strongly recommended that you check this file into your version control system.
12 12
 
13
-ActiveRecord::Schema.define(version: 2019_05_29_143559) do
13
+ActiveRecord::Schema.define(version: 2019_06_27_222826) do
14 14
 
15 15
   # These are extensions that must be enabled in order to support this database
16 16
   enable_extension "plpgsql"
@@ -218,6 +218,13 @@ ActiveRecord::Schema.define(version: 2019_05_29_143559) do
218 218
     t.index ["uri"], name: "index_conversations_on_uri", unique: true
219 219
   end
220 220
 
221
+  create_table "custom_emoji_categories", force: :cascade do |t|
222
+    t.string "name"
223
+    t.datetime "created_at", null: false
224
+    t.datetime "updated_at", null: false
225
+    t.index ["name"], name: "index_custom_emoji_categories_on_name", unique: true
226
+  end
227
+
221 228
   create_table "custom_emojis", force: :cascade do |t|
222 229
     t.string "shortcode", default: "", null: false
223 230
     t.string "domain"
@@ -231,6 +238,7 @@ ActiveRecord::Schema.define(version: 2019_05_29_143559) do
231 238
     t.string "uri"
232 239
     t.string "image_remote_url"
233 240
     t.boolean "visible_in_picker", default: true, null: false
241
+    t.bigint "category_id"
234 242
     t.index ["shortcode", "domain"], name: "index_custom_emojis_on_shortcode_and_domain", unique: true
235 243
   end
236 244
 

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

@@ -15,6 +15,7 @@ module Mastodon
15 15
     option :suffix
16 16
     option :overwrite, type: :boolean
17 17
     option :unlisted, type: :boolean
18
+    option :category
18 19
     desc 'import PATH', 'Import emoji from a TAR GZIP archive at PATH'
19 20
     long_desc <<-LONG_DESC
20 21
       Imports custom emoji from a TAR GZIP archive specified by PATH.
@@ -22,6 +23,9 @@ module Mastodon
22 23
       Existing emoji will be skipped unless the --overwrite option
23 24
       is provided, in which case they will be overwritten.
24 25
 
26
+      You can specifiy a --category under which the emojis will be
27
+      grouped together.
28
+
25 29
       With the --prefix option, a prefix can be added to all
26 30
       generated shortcodes. Likewise, the --suffix option controls
27 31
       the suffix of all shortcodes.
@@ -33,6 +37,7 @@ module Mastodon
33 37
       imported = 0
34 38
       skipped  = 0
35 39
       failed   = 0
40
+      category = options[:category] ? CustomEmojiCategory.find_or_create_by(name: options[:category]) : nil
36 41
 
37 42
       Gem::Package::TarReader.new(Zlib::GzipReader.open(path)) do |tar|
38 43
         tar.each do |entry|
@@ -50,6 +55,7 @@ module Mastodon
50 55
           custom_emoji.image = StringIO.new(entry.read)
51 56
           custom_emoji.image_file_name = File.basename(entry.full_name)
52 57
           custom_emoji.visible_in_picker = !options[:unlisted]
58
+          custom_emoji.category = category
53 59
 
54 60
           if custom_emoji.save
55 61
             imported += 1

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

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

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

@@ -0,0 +1,5 @@
1
+require 'rails_helper'
2
+
3
+RSpec.describe CustomEmojiCategory, type: :model do
4
+  pending "add some examples to (or delete) #{__FILE__}"
5
+end

+ 2
- 2
yarn.lock View File

@@ -3388,8 +3388,8 @@ elliptic@^6.0.0:
3388 3388
     minimalistic-crypto-utils "^1.0.0"
3389 3389
 
3390 3390
 emoji-mart@Gargron/emoji-mart#build:
3391
-  version "2.6.2"
3392
-  resolved "https://codeload.github.com/Gargron/emoji-mart/tar.gz/ff00dc470b5b2d9f145a6d6e977a54de5df2b4c9"
3391
+  version "2.6.3"
3392
+  resolved "https://codeload.github.com/Gargron/emoji-mart/tar.gz/934f314fd8322276765066e8a2a6be5bac61b1cf"
3393 3393
 
3394 3394
 emoji-regex@^7.0.1, emoji-regex@^7.0.2:
3395 3395
   version "7.0.3"

Loading…
Cancel
Save