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
This commit is contained in:
parent
c1bc5e14eb
commit
a390abdefb
5 changed files with 66 additions and 6 deletions
1
Gemfile
1
Gemfile
|
@ -28,7 +28,6 @@ gem 'devise', '~> 4.2'
|
||||||
gem 'devise-two-factor', '~> 3.0'
|
gem 'devise-two-factor', '~> 3.0'
|
||||||
gem 'doorkeeper', '~> 4.2'
|
gem 'doorkeeper', '~> 4.2'
|
||||||
gem 'fast_blank', '~> 1.0'
|
gem 'fast_blank', '~> 1.0'
|
||||||
gem 'gemoji', '~> 3.0'
|
|
||||||
gem 'goldfinger', '~> 1.2'
|
gem 'goldfinger', '~> 1.2'
|
||||||
gem 'hiredis', '~> 0.6'
|
gem 'hiredis', '~> 0.6'
|
||||||
gem 'redis-namespace', '~> 1.5'
|
gem 'redis-namespace', '~> 1.5'
|
||||||
|
|
|
@ -1,19 +1,24 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module EmojiHelper
|
module EmojiHelper
|
||||||
EMOJI_PATTERN = /(?<=[^[:alnum:]:]|\n|^):([\w+-]+):(?=[^[:alnum:]:]|$)/x
|
|
||||||
|
|
||||||
def emojify(text)
|
def emojify(text)
|
||||||
return text if text.blank?
|
return text if text.blank?
|
||||||
|
|
||||||
text.gsub(EMOJI_PATTERN) do |match|
|
text.gsub(emoji_pattern) do |match|
|
||||||
emoji = Emoji.find_by_alias($1) # rubocop:disable Rails/DynamicFindBy,Style/PerlBackrefs
|
emoji = Emoji.instance.unicode($1) # rubocop:disable Style/PerlBackrefs
|
||||||
|
|
||||||
if emoji
|
if emoji
|
||||||
emoji.raw
|
emoji
|
||||||
else
|
else
|
||||||
match
|
match
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def emoji_pattern
|
||||||
|
@emoji_pattern ||=
|
||||||
|
/(?<=[^[:alnum:]:]|\n|^)
|
||||||
|
(#{Emoji.instance.names.map { |name| Regexp.escape(name) }.join('|')})
|
||||||
|
(?=[^[:alnum:]:]|$)/x
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
40
app/lib/emoji.rb
Normal file
40
app/lib/emoji.rb
Normal file
|
@ -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
|
1
lib/assets/emoji.json
Normal file
1
lib/assets/emoji.json
Normal file
File diff suppressed because one or more lines are too long
15
spec/lib/emoji_spec.rb
Normal file
15
spec/lib/emoji_spec.rb
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe Emoji do
|
||||||
|
describe '#unicode' do
|
||||||
|
it 'returns a unicode for a shortcode' do
|
||||||
|
expect(Emoji.instance.unicode(':joy:')).to eq '😂'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#names' do
|
||||||
|
it 'returns an array' do
|
||||||
|
expect(Emoji.instance.names).to be_an Array
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue