From 13e96ffd3be51635614034f567a812253144d49d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9gis=20Hanol?= <regis@hanol.fr>
Date: Thu, 5 Nov 2015 17:25:26 +0100
Subject: [PATCH] FEATURE: add support for custom emojis via plugins

---
 app/models/emoji.rb              | 15 ++++++++++---
 lib/discourse_plugin_registry.rb | 13 ++++++++++++
 lib/plugin/instance.rb           | 36 ++++++++++++++++++++++++++++++--
 3 files changed, 59 insertions(+), 5 deletions(-)

diff --git a/app/models/emoji.rb b/app/models/emoji.rb
index 10313e4a45b..906436e0cd8 100644
--- a/app/models/emoji.rb
+++ b/app/models/emoji.rb
@@ -104,9 +104,18 @@ class Emoji
   end
 
   def self.load_custom
-    Dir.glob(File.join(Emoji.base_directory, "*.{png,gif}"))
-       .sort
-       .map { |emoji| Emoji.create_from_path(emoji) }
+    uploaded = Dir.glob(File.join(Emoji.base_directory, "*.{png,gif}"))
+                  .sort
+                  .map { |emoji| Emoji.create_from_path(emoji) }
+
+    from_plugins = DiscoursePluginRegistry.emojis.map do |name, url|
+      Emoji.new.tap do |e|
+        e.name = name
+        e.url = url
+      end
+    end
+
+    uploaded + from_plugins
   end
 
   def self.base_directory
diff --git a/lib/discourse_plugin_registry.rb b/lib/discourse_plugin_registry.rb
index 45858362151..1f4ed770929 100644
--- a/lib/discourse_plugin_registry.rb
+++ b/lib/discourse_plugin_registry.rb
@@ -14,6 +14,7 @@ class DiscoursePluginRegistry
     attr_writer :handlebars
     attr_writer :serialized_current_user_fields
     attr_writer :seed_data
+    attr_writer :emojis
 
     attr_accessor :custom_html
 
@@ -61,6 +62,10 @@ class DiscoursePluginRegistry
     def seed_data
       @seed_data ||= HashWithIndifferentAccess.new({})
     end
+
+    def emojis
+      @emojis ||= HashWithIndifferentAccess.new({})
+    end
   end
 
   def register_js(filename, options={})
@@ -131,6 +136,10 @@ class DiscoursePluginRegistry
     self.seed_data[key] = value
   end
 
+  def self.register_emoji(name, url)
+    self.emojis[name] = url
+  end
+
   def javascripts
     self.class.javascripts
   end
@@ -159,6 +168,10 @@ class DiscoursePluginRegistry
     self.class.handlebars
   end
 
+  def emojis
+    self.class.emojis
+  end
+
   def self.clear
     self.javascripts = nil
     self.server_side_javascripts = nil
diff --git a/lib/plugin/instance.rb b/lib/plugin/instance.rb
index 2e341bf5788..05748e2c002 100644
--- a/lib/plugin/instance.rb
+++ b/lib/plugin/instance.rb
@@ -17,8 +17,13 @@ class Plugin::Instance
     }
   end
 
-  def seed_data
-    @seed_data ||= {}
+  # Memoized hash readers
+  [:seed_data, :emojis].each do |att|
+    class_eval %Q{
+      def #{att}
+        @#{att} ||= HashWithIndifferentAccess.new({})
+      end
+    }
   end
 
   def self.find_all(parent_path)
@@ -213,6 +218,10 @@ class Plugin::Instance
     seed_data[key] = value
   end
 
+  def register_emoji(name, url)
+    emojis[name] = url
+  end
+
   def automatic_assets
     css = styles.join("\n")
     js = javascripts.join("\n")
@@ -230,6 +239,25 @@ class Plugin::Instance
       end
     end
 
+    unless emojis.blank?
+      if @enabled_site_setting.present?
+        js << "Discourse.initializer({" << "\n"
+        js << "name: 'emojis'," << "\n"
+        js << "initialize: function() {" << "\n"
+        js << "if (Discourse.SiteSettings.#{@enabled_site_setting}) {" << "\n"
+      end
+
+      emojis.each do |name, url|
+        js << "Discourse.Dialect.registerEmoji('#{name}', '#{url}');" << "\n"
+      end
+
+      if @enabled_site_setting.present?
+        js << "}" << "\n"
+        js << "}" << "\n"
+        js << "});" << "\n"
+      end
+    end
+
     # Generate an IIFE for the JS
     js = "(function(){#{js}})();" if js.present?
 
@@ -272,6 +300,10 @@ class Plugin::Instance
       DiscoursePluginRegistry.register_seed_data(key, value)
     end
 
+    emojis.each do |name, url|
+      DiscoursePluginRegistry.register_emoji(name, url)
+    end
+
     # TODO: possibly amend this to a rails engine
 
     # Automatically include assets