FEATURE: favorites emojis will also show in composer autocomplete (#8011)

FEATURE: favorites emojis will also show in composer autocomplete (#8011)

diff --git a/app/assets/javascripts/discourse/components/d-editor.js.es6 b/app/assets/javascripts/discourse/components/d-editor.js.es6
index ad5611c..8cd3c54 100644
--- a/app/assets/javascripts/discourse/components/d-editor.js.es6
+++ b/app/assets/javascripts/discourse/components/d-editor.js.es6
@@ -220,6 +220,7 @@ export default Ember.Component.extend({
   _mouseTrap: null,
   showLink: true,
   emojiPickerIsActive: false,
+  emojiStore: Ember.inject.service("emoji-store"),
 
   @computed("placeholder")
   placeholderTranslated(placeholder) {
@@ -422,6 +423,7 @@ export default Ember.Component.extend({
 
       transformComplete: v => {
         if (v.code) {
+          this.emojiStore.track(v.code);
           return `${v.code}:`;
         } else {
           $editorInput.autocomplete({ cancel: true });
@@ -458,7 +460,17 @@ export default Ember.Component.extend({
           }
 
           if (term === "") {
-            return resolve(["slight_smile", "smile", "wink", "sunny", "blush"]);
+            if (this.emojiStore.favorites.length) {
+              return resolve(this.emojiStore.favorites.slice(0, 5));
+            } else {
+              return resolve([
+                "slight_smile",
+                "smile",
+                "wink",
+                "sunny",
+                "blush"
+              ]);
+            }
           }
 
           if (translations[full]) {
diff --git a/app/assets/javascripts/discourse/components/emoji-picker.js.es6 b/app/assets/javascripts/discourse/components/emoji-picker.js.es6
index 88185d9..dfe6287 100644
--- a/app/assets/javascripts/discourse/components/emoji-picker.js.es6
+++ b/app/assets/javascripts/discourse/components/emoji-picker.js.es6
@@ -1,7 +1,7 @@
 import { on, observes } from "ember-addons/ember-computed-decorators";
 import { findRawTemplate } from "discourse/lib/raw-templates";
 import { emojiUrlFor } from "discourse/lib/text";
-import KeyValueStore from "discourse/lib/key-value-store";
+
 import {
   extendedEmojiList,
   isSkinTonableEmoji,
@@ -10,21 +10,14 @@ import {
 import { safariHacksDisabled } from "discourse/lib/utilities";
 const { run } = Ember;
 
-const keyValueStore = new KeyValueStore("discourse_emojis_");
-const EMOJI_USAGE = "emojiUsage";
-const EMOJI_SELECTED_DIVERSITY = "emojiSelectedDiversity";
 const PER_ROW = 11;
 const customEmojis = _.keys(extendedEmojiList()).map(code => {
   return { code, src: emojiUrlFor(code) };
 });
 
-export function resetCache() {
-  keyValueStore.setObject({ key: EMOJI_USAGE, value: [] });
-  keyValueStore.setObject({ key: EMOJI_SELECTED_DIVERSITY, value: 1 });
-}
-
 export default Ember.Component.extend({
   automaticPositioning: true,
+  emojiStore: Ember.inject.service("emoji-store"),
 
   close() {
     this._unbindEvents();
@@ -46,11 +39,10 @@ export default Ember.Component.extend({
     this.$results = this.$picker.find(".results");
     this.$list = this.$picker.find(".list");
 
-    this.set(
-      "selectedDiversity",
-      keyValueStore.getObject(EMOJI_SELECTED_DIVERSITY) || 1
-    );
-    this.set("recentEmojis", keyValueStore.getObject(EMOJI_USAGE) || []);
+    this.setProperties({
+      selectedDiversity: this.emojiStore.diversity,
+      recentEmojis: this.emojiStore.favorites
+    });
 
     run.scheduleOnce("afterRender", this, function() {
       this._bindEvents();
@@ -88,18 +80,7 @@ export default Ember.Component.extend({
   _setup() {
     this.$picker = $(this.element.querySelector(".emoji-picker"));
     this.$modal = $(this.element.querySelector(".emoji-picker-modal"));
-
     this.appEvents.on("emoji-picker:close", this, "_closeEmojiPicker");
-
-    if (!keyValueStore.getObject(EMOJI_USAGE)) {
-      keyValueStore.setObject({ key: EMOJI_USAGE, value: [] });
-    } else if (_.isPlainObject(keyValueStore.getObject(EMOJI_USAGE))) {
-      // handle legacy format
-      keyValueStore.setObject({
-        key: EMOJI_USAGE,
-        value: _.keys(keyValueStore.getObject(EMOJI_USAGE))
-      });
-    }
   },
 
   @on("didUpdateAttrs")
@@ -116,10 +97,7 @@ export default Ember.Component.extend({
 
   @observes("selectedDiversity")
   selectedDiversityChanged() {
-    keyValueStore.setObject({
-      key: EMOJI_SELECTED_DIVERSITY,
-      value: this.selectedDiversity
-    });
+    this.emojiStore.diversity = this.selectedDiversity;
 
     $.each(
       this.$list.find(".emoji[data-loaded='1'].diversity"),
@@ -326,7 +304,7 @@ export default Ember.Component.extend({
       ".section[data-section='recent'] .clear-recent"
     );
     $recent.on("click", () => {
-      keyValueStore.setObject({ key: EMOJI_USAGE, value: [] });
+      this.emojiStore.favorites = [];
       this.set("recentEmojis", []);
       this._scrollTo(0);
       return false;
@@ -608,12 +586,8 @@ export default Ember.Component.extend({
   },
 
   _trackEmojiUsage(code) {
-    let recent = keyValueStore.getObject(EMOJI_USAGE) || [];
-    recent = recent.filter(r => r !== code);
-    recent.unshift(code);
-    recent.length = Math.min(recent.length, PER_ROW);
-    keyValueStore.setObject({ key: EMOJI_USAGE, value: recent });
-    this.set("recentEmojis", recent);
+    this.emojiStore.track(code);
+    this.set("recentEmojis", this.emojiStore.favorites.slice(0, PER_ROW));
   },
 
   _scrollTo(y) {
diff --git a/app/assets/javascripts/discourse/services/emoji-store.js.es6 b/app/assets/javascripts/discourse/services/emoji-store.js.es6
new file mode 100644
index 0000000..7c7a5d0
--- /dev/null
+++ b/app/assets/javascripts/discourse/services/emoji-store.js.es6
@@ -0,0 +1,48 @@
+import KeyValueStore from "discourse/lib/key-value-store";
+
+const EMOJI_USAGE = "emojiUsage";
+const EMOJI_SELECTED_DIVERSITY = "emojiSelectedDiversity";
+const TRACKED_EMOJIS = 15;
+const STORE_NAMESPACE = "discourse_emojis_";
+
+export default Ember.Service.extend({
+  init() {
+    this._super(...arguments);
+
+    this.store = new KeyValueStore(STORE_NAMESPACE);
+
+    if (!this.store.getObject(EMOJI_USAGE)) {
+      this.favorites = [];
+    }
+  },
+
+  get diversity() {
+    return this.store.getObject(EMOJI_SELECTED_DIVERSITY) || 1;
+  },
+
+  set diversity(value) {
+    this.store.setObject({ key: EMOJI_SELECTED_DIVERSITY, value: value || 1 });
+  },
+
+  get favorites() {
+    return this.store.getObject(EMOJI_USAGE) || [];
+  },
+
+  set favorites(value) {
+    this.store.setObject({ key: EMOJI_USAGE, value: value || [] });
+  },
+
+  track(code) {
+    const normalizedCode = code.replace(/(^:)|(:$)/g, "");
+    const recent = this.favorites.filter(r => r !== normalizedCode);
+    recent.unshift(normalizedCode);
+    recent.length = Math.min(recent.length, TRACKED_EMOJIS);
+    this.favorites = recent;
+  },
+
+  reset() {
+    const store = new KeyValueStore(STORE_NAMESPACE);
+    store.setObject({ key: EMOJI_USAGE, value: [] });
+    store.setObject({ key: EMOJI_SELECTED_DIVERSITY, value: 1 });
+  }
+});
diff --git a/test/javascripts/acceptance/emoji-picker-test.js.es6 b/test/javascripts/acceptance/emoji-picker-test.js.es6
index 96c5baf..f6b4046 100644
--- a/test/javascripts/acceptance/emoji-picker-test.js.es6
+++ b/test/javascripts/acceptance/emoji-picker-test.js.es6
@@ -1,11 +1,11 @@
 import { acceptance } from "helpers/qunit-helpers";
 import { IMAGE_VERSION as v } from "pretty-text/emoji/version";
-import { resetCache } from "discourse/components/emoji-picker";
 
 acceptance("EmojiPicker", {
   loggedIn: true,
   beforeEach() {
-    resetCache();
+    const store = Discourse.__container__.lookup("service:emojis-store");
+    store.reset();
   }
 });
 
diff --git a/test/javascripts/lib/emoji-store-test.js.es6 b/test/javascripts/lib/emoji-store-test.js.es6
new file mode 100644
index 0000000..f0c521a
--- /dev/null
+++ b/test/javascripts/lib/emoji-store-test.js.es6
@@ -0,0 +1,33 @@
+QUnit.module("lib:emoji-store", {
+  afterEach() {
+    const store = Discourse.__container__.lookup("service:emoji-store");
+    store.reset();
+  }
+});
+
+QUnit.test("defaults", assert => {
+  const store = Discourse.__container__.lookup("service:emoji-store");

[... diff too long, it was truncated ...]

GitHub sha: 936d4ce1

1 Like