From 560dfe74af153cc69e098f4873fe2d32930358d6 Mon Sep 17 00:00:00 2001
From: Joffrey JAFFEUX <j.jaffeux@gmail.com>
Date: Wed, 28 Jun 2017 15:07:05 +0200
Subject: [PATCH] Adds support for skin tones in emoji picker

---
 .../discourse/lib/emoji/toolbar.js.es6        | 29 ++++++-
 .../discourse/templates/emoji-toolbar.raw.hbs | 42 ++++++----
 app/assets/stylesheets/common/base/emoji.scss | 79 +++++++++++++------
 3 files changed, 110 insertions(+), 40 deletions(-)

diff --git a/app/assets/javascripts/discourse/lib/emoji/toolbar.js.es6 b/app/assets/javascripts/discourse/lib/emoji/toolbar.js.es6
index 3666df1b580..6c990548e3a 100644
--- a/app/assets/javascripts/discourse/lib/emoji/toolbar.js.es6
+++ b/app/assets/javascripts/discourse/lib/emoji/toolbar.js.es6
@@ -1,6 +1,6 @@
 import groups from 'discourse/lib/emoji/groups';
 import KeyValueStore from "discourse/lib/key-value-store";
-import { emojiList } from 'pretty-text/emoji';
+import { emojiList, isSkinTonableEmoji } from 'pretty-text/emoji';
 import { emojiUrlFor } from 'discourse/lib/text';
 import { findRawTemplate } from 'discourse/lib/raw-templates';
 
@@ -11,6 +11,7 @@ let PER_ROW = 12;
 const PER_PAGE = 60;
 
 let ungroupedIcons, recentlyUsedIcons;
+let selectedSkinTone = keyValueStore.getObject('selectedSkinTone') || 1;
 
 if (!keyValueStore.getObject(EMOJI_USAGE)) {
   keyValueStore.setObject({key: EMOJI_USAGE, value: {}});
@@ -121,6 +122,13 @@ function bindEvents(page, offset, options) {
     render(p, 0, options);
     return false;
   });
+
+  $('.emoji-modal .tones-button').click(function(){
+    selectedSkinTone = parseInt($(this).data('skin-tone'));
+    keyValueStore.setObject({key: 'selectedSkinTone', value: selectedSkinTone});
+    render(page, offset, options);
+    return false;
+  });
 }
 
 function render(page, offset, options) {
@@ -139,12 +147,29 @@ function render(page, offset, options) {
       rows.push(row);
       row = [];
     }
-    row.push({src: emojiUrlFor(icons[i]), title: icons[i]});
+
+    let code = icons[i];
+    if(selectedSkinTone !== 1 && isSkinTonableEmoji(code)) {
+      code = `${code}:t${selectedSkinTone}`;
+    }
+
+    row.push({src: emojiUrlFor(code), title: code});
   }
   rows.push(row);
 
+  const skinTones = [];
+  const skinToneNames = ['default', 'light', 'medium-light', 'medium', 'medium-dark', 'dark'];
+  for(let i=1; i<skinToneNames.length+1; i++){
+    skinTones.push({
+      selected: selectedSkinTone === i,
+      level: i,
+      className: skinToneNames[i-1]
+    });
+  }
+
   const model = {
     toolbarItems: toolbarItems,
+    skinTones: skinTones,
     rows: rows,
     prevDisabled: offset === 0,
     nextDisabled: (max + 1) > icons.length,
diff --git a/app/assets/javascripts/discourse/templates/emoji-toolbar.raw.hbs b/app/assets/javascripts/discourse/templates/emoji-toolbar.raw.hbs
index b7e39bb37ba..972ec3729af 100644
--- a/app/assets/javascripts/discourse/templates/emoji-toolbar.raw.hbs
+++ b/app/assets/javascripts/discourse/templates/emoji-toolbar.raw.hbs
@@ -14,22 +14,32 @@
   </table>
   </div>
 
-  <div class='info'></div>
-  <div class='nav'>
-    <span class='prev'>
-      {{#if prevDisabled}}
-        {{fa-icon "fast-backward"}}
-      {{else}}
-        <a>{{fa-icon "fast-backward"}}</a>
-      {{/if}}
-    </span>
-    <span class='next'>
-      {{#if nextDisabled}}
-        {{fa-icon "fast-forward"}}
-      {{else}}
-        <a>{{fa-icon "fast-forward"}}</a>
-      {{/if}}
-    </span>
+  <div class='footer'>
+    <div class='info'></div>
+    <div class='tones'>
+      {{#each skinTones as |skinTone|}}
+        <button class='tones-button {{skinTone.className}}' data-skin-tone="{{skinTone.level}}">
+          {{#if skinTone.selected}}{{fa-icon "check"}}{{/if}}
+        </button>
+      {{/each}}
+    </div>
+    <div class='nav'>
+      <span class='prev'>
+        {{#if prevDisabled}}
+          {{fa-icon "fast-backward"}}
+        {{else}}
+          <a>{{fa-icon "fast-backward"}}</a>
+        {{/if}}
+      </span>
+      <span class='next'>
+        {{#if nextDisabled}}
+          {{fa-icon "fast-forward"}}
+        {{else}}
+          <a>{{fa-icon "fast-forward"}}</a>
+        {{/if}}
+      </span>
+    </div>
   </div>
+
   <div class='clearfix'></div>
 </div>
diff --git a/app/assets/stylesheets/common/base/emoji.scss b/app/assets/stylesheets/common/base/emoji.scss
index e97a2d186a6..7517044c898 100644
--- a/app/assets/stylesheets/common/base/emoji.scss
+++ b/app/assets/stylesheets/common/base/emoji.scss
@@ -18,6 +18,8 @@ body img.emoji {
   margin-top: -132px;
   margin-left: -222px;
   background-color: dark-light-choose(#dadada, blend-primary-secondary(5%));
+  display: flex;
+  flex-direction: column;
 }
 
 table.emoji-page td {
@@ -71,30 +73,12 @@ table.emoji-page td {
   background-color: $secondary;
 }
 
-.emoji-modal .info {
-  height: 30px;
-  margin-left: 8px;
-  margin-top: 15px;
-  margin-bottom: 0px;
-}
-
-.emoji-modal .info span {
-  margin-left: 5px;
-  font-weight: bold;
-  color: $primary;
-}
-
-.emoji-modal .info {
-  float: left;
-}
-.emoji-modal .nav {
-  float: right;
-  margin-top: 15px;
-}
-
 .emoji-modal .nav span {
   color: dark-light-choose(#aaa, #555);
-  margin-right: 10px;
+}
+
+.emoji-modal .nav span.next {
+  margin-left: 10px;
 }
 
 .emoji-modal .nav a {
@@ -108,3 +92,54 @@ table.emoji-page td {
   overflow: hidden;
   vertical-align: middle;
 }
+
+.emoji-modal .footer {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  flex-direction: row;
+  flex-grow: 2;
+  padding: 8px;
+}
+
+.emoji-modal .info {
+  flex: 10;
+}
+
+.emoji-modal .info span {
+  margin-left: 5px;
+  font-weight: bold;
+  color: $primary;
+}
+
+.emoji-modal .nav {
+  margin-left: 10px;
+}
+
+.emoji-modal .tones {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+}
+
+.emoji-modal .tones-button {
+  width: 20px;
+  height: 20px;
+  margin-left: 5px;
+  border: 0;
+  border-radius: 3px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+.emoji-modal .tones-button.default { background: #ffcc4d; }
+.emoji-modal .tones-button.light { background: #f7dece; }
+.emoji-modal .tones-button.medium-light { background: #f3d2a2; }
+.emoji-modal .tones-button.medium { background: #d5ab88; }
+.emoji-modal .tones-button.medium-dark { background: #af7e57; }
+.emoji-modal .tones-button.dark { background: #7c533e; }
+
+.emoji-modal .tones-button i.fa {
+  color: #fff;
+  text-shadow: 0.5px 1.5px 0 rgba(0,0,0,0.3);
+}