about summary refs log tree commit diff
path: root/app
diff options
context:
space:
mode:
authorEugen Rochko <eugen@zeonfederated.com>2017-07-21 04:27:40 +0200
committerGitHub <noreply@github.com>2017-07-21 04:27:40 +0200
commita390abdefb5d741ba4375858a79fbf3eaf30f06d (patch)
treeac1d1e4f0fdd4bc39139f2732cfea182e9aa2236 /app
parentc1bc5e14ebbecd8ffc6b4188fbf608e11f64422e (diff)
Use the same emoji data on the frontend and backend (#4284)
* Use the same emoji data on the frontend and backend

* Move emoji.json to repository, add tests

This way you don't need to install node dependencies if you only
want to run Ruby code
Diffstat (limited to 'app')
-rw-r--r--app/helpers/emoji_helper.rb15
-rw-r--r--app/lib/emoji.rb40
2 files changed, 50 insertions, 5 deletions
diff --git a/app/helpers/emoji_helper.rb b/app/helpers/emoji_helper.rb
index c1595851f..848c03fce 100644
--- a/app/helpers/emoji_helper.rb
+++ b/app/helpers/emoji_helper.rb
@@ -1,19 +1,24 @@
 # frozen_string_literal: true
 
 module EmojiHelper
-  EMOJI_PATTERN = /(?<=[^[:alnum:]:]|\n|^):([\w+-]+):(?=[^[:alnum:]:]|$)/x
-
   def emojify(text)
     return text if text.blank?
 
-    text.gsub(EMOJI_PATTERN) do |match|
-      emoji = Emoji.find_by_alias($1) # rubocop:disable Rails/DynamicFindBy,Style/PerlBackrefs
+    text.gsub(emoji_pattern) do |match|
+      emoji = Emoji.instance.unicode($1) # rubocop:disable Style/PerlBackrefs
 
       if emoji
-        emoji.raw
+        emoji
       else
         match
       end
     end
   end
+
+  def emoji_pattern
+    @emoji_pattern ||=
+      /(?<=[^[:alnum:]:]|\n|^)
+      (#{Emoji.instance.names.map { |name| Regexp.escape(name) }.join('|')})
+      (?=[^[:alnum:]:]|$)/x
+  end
 end
diff --git a/app/lib/emoji.rb b/app/lib/emoji.rb
new file mode 100644
index 000000000..e444b6893
--- /dev/null
+++ b/app/lib/emoji.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+require 'singleton'
+
+class Emoji
+  include Singleton
+
+  def initialize
+    data = Oj.load(File.open(File.join(Rails.root, 'lib', 'assets', 'emoji.json')))
+
+    @map = {}
+
+    data.each do |_, emoji|
+      keys    = [emoji['shortname']] + emoji['aliases']
+      unicode = codepoint_to_unicode(emoji['unicode'])
+
+      keys.each do |key|
+        @map[key] = unicode
+      end
+    end
+  end
+
+  def unicode(shortcode)
+    @map[shortcode]
+  end
+
+  def names
+    @map.keys
+  end
+
+  private
+
+  def codepoint_to_unicode(codepoint)
+    if codepoint.include?('-')
+      codepoint.split('-').map(&:hex).pack('U')
+    else
+      [codepoint.hex].pack('U')
+    end
+  end
+end