Explorar el Código

Make suggestor suggest according to cldr annotations

Tusooa Zhu hace 2 años
padre
commit
a7f836a64e

+ 47 - 2
src/components/emoji_input/emoji_input.js

@@ -3,7 +3,7 @@ import EmojiPicker from '../emoji_picker/emoji_picker.vue'
 import UnicodeDomainIndicator from '../unicode_domain_indicator/unicode_domain_indicator.vue'
 import { take } from 'lodash'
 import { findOffset } from '../../services/offset_finder/offset_finder.service.js'
-
+import { ensureFinalFallback } from '../../i18n/languages.js'
 import { library } from '@fortawesome/fontawesome-svg-core'
 import {
   faSmileBeam
@@ -143,6 +143,51 @@ const EmojiInput = {
         const word = Completion.wordAtPosition(this.modelValue, this.caret - 1) || {}
         return word
       }
+    },
+    languages () {
+      return ensureFinalFallback(this.$store.getters.mergedConfig.interfaceLanguage)
+    },
+    maybeLocalizedEmojiNamesAndKeywords () {
+      return emoji => {
+        const names = [emoji.displayText]
+        const keywords = []
+
+        if (emoji.displayTextI18n) {
+          names.push(this.$t(emoji.displayTextI18n.key, emoji.displayTextI18n.args))
+        }
+
+        if (emoji.annotations) {
+          this.languages.forEach(lang => {
+            names.push(emoji.annotations[lang]?.name)
+
+            keywords.push(...(emoji.annotations[lang]?.keywords || []))
+          })
+        }
+
+        return {
+          names: names.filter(k => k),
+          keywords: keywords.filter(k => k)
+        }
+      }
+    },
+    maybeLocalizedEmojiName () {
+      return emoji => {
+        if (!emoji.annotations) {
+          return emoji.displayText
+        }
+
+        if (emoji.displayTextI18n) {
+          return this.$t(emoji.displayTextI18n.key, emoji.displayTextI18n.args)
+        }
+
+        for (const lang of this.languages) {
+          if (emoji.annotations[lang]?.name) {
+            return emoji.annotations[lang].name
+          }
+        }
+
+        return emoji.displayText
+      }
     }
   },
   mounted () {
@@ -181,7 +226,7 @@ const EmojiInput = {
       const firstchar = newWord.charAt(0)
       this.suggestions = []
       if (newWord === firstchar) return
-      const matchedSuggestions = await this.suggest(newWord)
+      const matchedSuggestions = await this.suggest(newWord, this.maybeLocalizedEmojiNamesAndKeywords)
       // Async: cancel if textAtCaret has changed during wait
       if (this.textAtCaret !== newWord) return
       if (matchedSuggestions.length <= 0) return

+ 1 - 1
src/components/emoji_input/emoji_input.vue

@@ -64,7 +64,7 @@
               v-if="!suggestion.user"
               class="displayText"
             >
-              {{ suggestion.displayText }}
+              {{ maybeLocalizedEmojiName(suggestion) }}
             </span>
             <span class="detailText">{{ suggestion.detailText }}</span>
           </div>

+ 16 - 16
src/components/emoji_input/suggestor.js

@@ -13,10 +13,10 @@
 export default data => {
   const emojiCurry = suggestEmoji(data.emoji)
   const usersCurry = data.store && suggestUsers(data.store)
-  return input => {
+  return (input, nameKeywordLocalizer) => {
     const firstChar = input[0]
     if (firstChar === ':' && data.emoji) {
-      return emojiCurry(input)
+      return emojiCurry(input, nameKeywordLocalizer)
     }
     if (firstChar === '@' && usersCurry) {
       return usersCurry(input)
@@ -25,34 +25,34 @@ export default data => {
   }
 }
 
-export const suggestEmoji = emojis => input => {
+export const suggestEmoji = emojis => (input, nameKeywordLocalizer) => {
   const noPrefix = input.toLowerCase().substr(1)
   return emojis
-    .filter(({ displayText }) => displayText.toLowerCase().match(noPrefix))
-    .sort((a, b) => {
-      let aScore = 0
-      let bScore = 0
+    .map(emoji => ({ ...emoji, ...nameKeywordLocalizer(emoji) }))
+    .filter((emoji) => (emoji.names.concat(emoji.keywords)).filter(kw => kw.toLowerCase().match(noPrefix)).length)
+    .map(k => {
+      let score = 0
 
       // An exact match always wins
-      aScore += a.displayText.toLowerCase() === noPrefix ? 200 : 0
-      bScore += b.displayText.toLowerCase() === noPrefix ? 200 : 0
+      score += Math.max(...k.names.map(name => name.toLowerCase() === noPrefix ? 200 : 0), 0)
 
       // Prioritize custom emoji a lot
-      aScore += a.imageUrl ? 100 : 0
-      bScore += b.imageUrl ? 100 : 0
+      score += k.imageUrl ? 100 : 0
 
       // Prioritize prefix matches somewhat
-      aScore += a.displayText.toLowerCase().startsWith(noPrefix) ? 10 : 0
-      bScore += b.displayText.toLowerCase().startsWith(noPrefix) ? 10 : 0
+      score += Math.max(...k.names.map(kw => kw.toLowerCase().startsWith(noPrefix) ? 10 : 0), 0)
 
       // Sort by length
-      aScore -= a.displayText.length
-      bScore -= b.displayText.length
+      score -= k.displayText.length
 
+      k.score = score
+      return k
+    })
+    .sort((a, b) => {
       // Break ties alphabetically
       const alphabetically = a.displayText > b.displayText ? 0.5 : -0.5
 
-      return bScore - aScore + alphabetically
+      return b.score - a.score + alphabetically
     })
 }