From 96f31716f94d0e7691b85ca90e7ea977ca3adb4d Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Fri, 7 Jun 2019 00:17:49 +0300
Subject: slot-based emoji input/autocomplete component

---
 src/components/user_settings/user_settings.vue | 24 +++++++++++++-----------
 1 file changed, 13 insertions(+), 11 deletions(-)

(limited to 'src/components/user_settings/user_settings.vue')

diff --git a/src/components/user_settings/user_settings.vue b/src/components/user_settings/user_settings.vue
index 20b10979..d3d333bd 100644
--- a/src/components/user_settings/user_settings.vue
+++ b/src/components/user_settings/user_settings.vue
@@ -22,18 +22,20 @@
           <div class="setting-item" >
             <h2>{{$t('settings.name_bio')}}</h2>
             <p>{{$t('settings.name')}}</p>
-            <EmojiInput
-              type="text"
-              v-model="newName"
-              id="username"
-              classname="name-changer"
-            />
+            <emoji-input :suggest="emojiSuggestor" v-model="newName">
+              <input
+                v-model="newName"
+                id="username"
+                classname="name-changer"
+              />
+            </emoji-input>
             <p>{{$t('settings.bio')}}</p>
-            <EmojiInput
-              type="textarea"
-              v-model="newBio"
-              classname="bio"
-            />
+            <emoji-input :suggest="emojiUserSuggestor" v-model="newBio">
+              <textarea
+                v-model="newBio"
+                classname="bio"
+                />
+            </emoji-input>
             <p>
               <input type="checkbox" v-model="newLocked" id="account-locked">
               <label for="account-locked">{{$t('settings.lock_account_description')}}</label>
-- 
cgit v1.2.3-70-g09d2


From 0032802f0a3ef6249f56acefeb2b0e900b90d1b1 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Tue, 18 Jun 2019 21:30:35 +0300
Subject: review

---
 src/components/emoji-input/emoji-input.js          |  2 +-
 src/components/emoji-input/suggestor.js            | 96 +++++++++++-----------
 .../post_status_form/post_status_form.vue          |  8 +-
 src/components/user_settings/user_settings.vue     |  8 +-
 4 files changed, 55 insertions(+), 59 deletions(-)

(limited to 'src/components/user_settings/user_settings.vue')

diff --git a/src/components/emoji-input/emoji-input.js b/src/components/emoji-input/emoji-input.js
index 08c2f60b..d2e4a21a 100644
--- a/src/components/emoji-input/emoji-input.js
+++ b/src/components/emoji-input/emoji-input.js
@@ -8,7 +8,7 @@ import { take } from 'lodash'
  * Intended usage is:
  * <emoji-input v-model="something">
  *   <input v-model="something"/>
- * </emoji-input>
+ * </EmojiInput>
  *
  * Works only with <input> and <textarea>. Intended to use with only one nested
  * input. It will find first input or textarea and work with that, multiple
diff --git a/src/components/emoji-input/suggestor.js b/src/components/emoji-input/suggestor.js
index eb70f299..95f14633 100644
--- a/src/components/emoji-input/suggestor.js
+++ b/src/components/emoji-input/suggestor.js
@@ -21,65 +21,61 @@ export default function suggest (data) {
   }
 }
 
-function suggestEmoji (emojis) {
-  return input => {
-    const noPrefix = input.toLowerCase().substr(1)
-    return emojis
-      .filter(({ displayText }) => displayText.toLowerCase().startsWith(noPrefix))
-      .sort((a, b) => {
-        let aScore = 0
-        let bScore = 0
+export const suggestEmoji = (emojis) => input => {
+  const noPrefix = input.toLowerCase().substr(1)
+  return emojis
+    .filter(({ displayText }) => displayText.toLowerCase().startsWith(noPrefix))
+    .sort((a, b) => {
+      let aScore = 0
+      let bScore = 0
 
-        // Make custom emojis a priority
-        aScore += Number(!!a.imageUrl) * 10
-        bScore += Number(!!b.imageUrl) * 10
+      // Make custom emojis a priority
+      aScore += a.imageUrl ? 10 : 0
+      bScore += b.imageUrl ? 10 : 0
 
-        // Sort alphabetically
-        const alphabetically = a.displayText > b.displayText ? 1 : -1
+      // Sort alphabetically
+      const alphabetically = a.displayText > b.displayText ? 1 : -1
 
-        return bScore - aScore + alphabetically
-      })
-  }
+      return bScore - aScore + alphabetically
+    })
 }
 
-function suggestUsers (users) {
-  return input => {
-    const noPrefix = input.toLowerCase().substr(1)
-    return users.filter(
-      user =>
-        user.screen_name.toLowerCase().startsWith(noPrefix) ||
-        user.name.toLowerCase().startsWith(noPrefix)
+export const suggestUsers = (users) => input => {
+  const noPrefix = input.toLowerCase().substr(1)
+  return users.filter(
+    user =>
+      user.screen_name.toLowerCase().startsWith(noPrefix) ||
+      user.name.toLowerCase().startsWith(noPrefix)
 
-      /* taking only 20 results so that sorting is a bit cheaper, we display
-       * only 5 anyway. could be inaccurate, but we ideally we should query
-       * backend anyway
-       */
-    ).slice(0, 20).sort((a, b) => {
-      let aScore = 0
-      let bScore = 0
+    /* taking only 20 results so that sorting is a bit cheaper, we display
+     * only 5 anyway. could be inaccurate, but we ideally we should query
+     * backend anyway
+     */
+  ).slice(0, 20).sort((a, b) => {
+    let aScore = 0
+    let bScore = 0
 
-      // Matches on screen name (i.e. user@instance) makes a priority
-      aScore += a.screen_name.toLowerCase().startsWith(noPrefix) * 2
-      bScore += b.screen_name.toLowerCase().startsWith(noPrefix) * 2
+    // Matches on screen name (i.e. user@instance) makes a priority
+    aScore += a.screen_name.toLowerCase().startsWith(noPrefix) ? 2 : 0
+    bScore += b.screen_name.toLowerCase().startsWith(noPrefix) ? 2 : 0
 
-      // Matches on name takes second priority
-      aScore += a.name.toLowerCase().startsWith(noPrefix)
-      bScore += b.name.toLowerCase().startsWith(noPrefix)
+    // Matches on name takes second priority
+    aScore += a.name.toLowerCase().startsWith(noPrefix) ? 1 : 0
+    bScore += b.name.toLowerCase().startsWith(noPrefix) ? 1 : 0
 
-      const diff = bScore * 10 - aScore * 10
+    const diff = (bScore - aScore) * 10
 
-      // Then sort alphabetically
-      const nameAlphabetically = a.name > b.name ? 1 : -1
-      const screenNameAlphabetically = a.screen_name > b.screen_name ? 1 : -1
+    // Then sort alphabetically
+    const nameAlphabetically = a.name > b.name ? 1 : -1
+    const screenNameAlphabetically = a.screen_name > b.screen_name ? 1 : -1
 
-      return diff + nameAlphabetically + screenNameAlphabetically
-      /* eslint-disable camelcase */
-    }).map(({ screen_name, name, profile_image_url_original }) => ({
-      displayText: screen_name,
-      detailText: name,
-      imageUrl: profile_image_url_original,
-      replacement: '@' + screen_name + ' '
-    }))
-    /* eslint-enable camelcase */
-  }
+    return diff + nameAlphabetically + screenNameAlphabetically
+    /* eslint-disable camelcase */
+  }).map(({ screen_name, name, profile_image_url_original }) => ({
+    displayText: screen_name,
+    detailText: name,
+    imageUrl: profile_image_url_original,
+    replacement: '@' + screen_name + ' '
+  }))
+  /* eslint-enable camelcase */
 }
diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue
index a8a34265..faa32be7 100644
--- a/src/components/post_status_form/post_status_form.vue
+++ b/src/components/post_status_form/post_status_form.vue
@@ -31,7 +31,7 @@
         <span v-if="safeDMEnabled">{{ $t('post_status.direct_warning_to_first_only') }}</span>
         <span v-else>{{ $t('post_status.direct_warning_to_all') }}</span>
       </p>
-      <emoji-input
+      <EmojiInput
         v-if="newStatus.spoilerText || alwaysShowSubject"
         :suggest="emojiSuggestor"
         v-model="newStatus.spoilerText"
@@ -44,8 +44,8 @@
           v-model="newStatus.spoilerText"
           class="form-post-subject"
           />
-      </emoji-input>
-      <emoji-input
+      </EmojiInput>
+      <EmojiInput
         :suggest="emojiUserSuggestor"
         v-model="newStatus.status"
         class="form-control"
@@ -65,7 +65,7 @@
           class="form-post-body"
         >
         </textarea>
-      </emoji-input>
+      </EmojiInput>
       <div class="visibility-tray">
         <div class="text-format" v-if="formattingOptionsEnabled">
           <label for="post-content-type" class="select">
diff --git a/src/components/user_settings/user_settings.vue b/src/components/user_settings/user_settings.vue
index d3d333bd..5dab4eb7 100644
--- a/src/components/user_settings/user_settings.vue
+++ b/src/components/user_settings/user_settings.vue
@@ -22,20 +22,20 @@
           <div class="setting-item" >
             <h2>{{$t('settings.name_bio')}}</h2>
             <p>{{$t('settings.name')}}</p>
-            <emoji-input :suggest="emojiSuggestor" v-model="newName">
+            <EmojiInput :suggest="emojiSuggestor" v-model="newName">
               <input
                 v-model="newName"
                 id="username"
                 classname="name-changer"
               />
-            </emoji-input>
+            </EmojiInput>
             <p>{{$t('settings.bio')}}</p>
-            <emoji-input :suggest="emojiUserSuggestor" v-model="newBio">
+            <EmojiInput :suggest="emojiUserSuggestor" v-model="newBio">
               <textarea
                 v-model="newBio"
                 classname="bio"
                 />
-            </emoji-input>
+            </EmojiInput>
             <p>
               <input type="checkbox" v-model="newLocked" id="account-locked">
               <label for="account-locked">{{$t('settings.lock_account_description')}}</label>
-- 
cgit v1.2.3-70-g09d2

