diff options
| author | Henry Jameson <me@hjkos.com> | 2022-10-09 18:51:42 +0300 |
|---|---|---|
| committer | Henry Jameson <me@hjkos.com> | 2022-10-09 18:51:42 +0300 |
| commit | 5fa533fbb7b3d507c0136044fd51db033c25db05 (patch) | |
| tree | fd7d50093d2bc44884cf76244d3becc2b3413c0e /src/components/emoji_input | |
| parent | 0331e42ee8576893dab2c6319ee5c0d62895b8d8 (diff) | |
| parent | c807254d3eadbd57de292360c5200358261cbc0f (diff) | |
Merge remote-tracking branch 'origin/develop' into scrolltotop
* origin/develop: (89 commits)
Update dependency @vuelidate/validators to v2.0.0
Remove lolex package
Remove diff package
Pin dependencies
Update dependency sass to v1.55.0
Make suggestor suggest according to cldr annotations
Make chunks named
Use import() for emoji.json
Add regional indicators
Support filtering by keywords from cldr
Display localized unicode emoji names
Load unicode emoji annotations
Extract language list to its own file
using the half-shit approach since proper approach is full-shit
Make unicode emoji phrases match with _
Use console.info
Fix non-square emojis being truncated
Fix emoji picker lint
Fix emoji picker lint
Tweak efficiency when changing filter keywords in emoji picker
...
Diffstat (limited to 'src/components/emoji_input')
| -rw-r--r-- | src/components/emoji_input/emoji_input.js | 50 | ||||
| -rw-r--r-- | src/components/emoji_input/emoji_input.vue | 3 | ||||
| -rw-r--r-- | src/components/emoji_input/suggestor.js | 34 |
3 files changed, 66 insertions, 21 deletions
diff --git a/src/components/emoji_input/emoji_input.js b/src/components/emoji_input/emoji_input.js index b664d6b3..ffc0ffac 100644 --- a/src/components/emoji_input/emoji_input.js +++ b/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 @@ -207,7 +252,6 @@ const EmojiInput = { }, triggerShowPicker () { this.showPicker = true - this.$refs.picker.startEmojiLoad() this.$nextTick(() => { this.scrollIntoView() this.focusPickerInput() diff --git a/src/components/emoji_input/emoji_input.vue b/src/components/emoji_input/emoji_input.vue index 81b81913..43581dbf 100644 --- a/src/components/emoji_input/emoji_input.vue +++ b/src/components/emoji_input/emoji_input.vue @@ -19,6 +19,7 @@ v-if="enableEmojiPicker" ref="picker" :class="{ hide: !showPicker }" + :showing="showPicker" :enable-sticker-picker="enableStickerPicker" class="emoji-picker-panel" @emoji="insert" @@ -63,7 +64,7 @@ v-if="!suggestion.user" class="displayText" > - {{ suggestion.displayText }} + {{ maybeLocalizedEmojiName(suggestion) }} </span> <span class="detailText">{{ suggestion.detailText }}</span> </div> diff --git a/src/components/emoji_input/suggestor.js b/src/components/emoji_input/suggestor.js index 0ddb4d68..adaa879e 100644 --- a/src/components/emoji_input/suggestor.js +++ b/src/components/emoji_input/suggestor.js @@ -2,7 +2,7 @@ * suggest - generates a suggestor function to be used by emoji-input * data: object providing source information for specific types of suggestions: * data.emoji - optional, an array of all emoji available i.e. - * (state.instance.emoji + state.instance.customEmoji) + * (getters.standardEmojiList + state.instance.customEmoji) * data.users - optional, an array of all known users * updateUsersList - optional, a function to search and append to users * @@ -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 }) } |
