Merge branch 'refactor-emoji-input' into shigusegubu

* refactor-emoji-input:
  Some comments, added sorting for emojis
  fixed several bugs
This commit is contained in:
Henry Jameson 2019-06-09 20:41:35 +03:00
commit 15722295b7
3 changed files with 38 additions and 20 deletions

View file

@ -64,6 +64,7 @@ const EmojiInput = {
if (!input) return if (!input) return
this.input = input this.input = input
this.resize() this.resize()
input.elm.addEventListener('transitionend', this.onTransition)
input.elm.addEventListener('blur', this.onBlur) input.elm.addEventListener('blur', this.onBlur)
input.elm.addEventListener('focus', this.onFocus) input.elm.addEventListener('focus', this.onFocus)
input.elm.addEventListener('paste', this.onPaste) input.elm.addEventListener('paste', this.onPaste)
@ -73,6 +74,7 @@ const EmojiInput = {
unmounted () { unmounted () {
const { input } = this const { input } = this
if (input) { if (input) {
input.elm.removeEventListener('transitionend', this.onTransition)
input.elm.removeEventListener('blur', this.onBlur) input.elm.removeEventListener('blur', this.onBlur)
input.elm.removeEventListener('focus', this.onFocus) input.elm.removeEventListener('focus', this.onFocus)
input.elm.removeEventListener('paste', this.onPaste) input.elm.removeEventListener('paste', this.onPaste)
@ -86,8 +88,8 @@ const EmojiInput = {
this.$emit('input', newValue) this.$emit('input', newValue)
this.caret = 0 this.caret = 0
}, },
replaceText () { replaceText (e) {
const len = this.suggestions.length || 0 const len = (this.suggestions && this.suggestions.length) || 0
if (this.textAtCaret.length === 1) { return } if (this.textAtCaret.length === 1) { return }
if (len > 0) { if (len > 0) {
const suggestion = this.suggestions[this.highlighted] const suggestion = this.suggestions[this.highlighted]
@ -96,9 +98,10 @@ const EmojiInput = {
this.$emit('input', newValue) this.$emit('input', newValue)
this.caret = 0 this.caret = 0
this.highlighted = 0 this.highlighted = 0
e.preventDefault()
} }
}, },
cycleBackward () { cycleBackward (e) {
const len = this.suggestions.length || 0 const len = this.suggestions.length || 0
if (len > 0) { if (len > 0) {
this.highlighted -= 1 this.highlighted -= 1
@ -109,7 +112,7 @@ const EmojiInput = {
this.highlighted = 0 this.highlighted = 0
} }
}, },
cycleForward () { cycleForward (e) {
const len = this.suggestions.length || 0 const len = this.suggestions.length || 0
if (len > 0) { if (len > 0) {
this.highlighted += 1 this.highlighted += 1
@ -120,6 +123,9 @@ const EmojiInput = {
this.highlighted = 0 this.highlighted = 0
} }
}, },
onTransition (e) {
this.resize(e)
},
onBlur (e) { onBlur (e) {
this.focused = false this.focused = false
this.setCaret(e) this.setCaret(e)
@ -145,24 +151,20 @@ const EmojiInput = {
const { ctrlKey, shiftKey, key } = e const { ctrlKey, shiftKey, key } = e
if (key === 'Tab') { if (key === 'Tab') {
if (shiftKey) { if (shiftKey) {
this.cycleBackward() this.cycleBackward(e)
e.preventDefault()
} else { } else {
this.cycleForward() this.cycleForward(e)
e.preventDefault()
} }
} }
if (key === 'ArrowUp') { if (key === 'ArrowUp') {
this.cycleBackward() this.cycleBackward(e)
e.preventDefault() e.preventDefault()
} else if (key === 'ArrowDown') { } else if (key === 'ArrowDown') {
this.cycleForward() this.cycleForward(e)
e.preventDefault()
} }
if (key === 'Enter') { if (key === 'Enter') {
if (!ctrlKey) { if (!ctrlKey) {
this.replaceText() this.replaceText(e)
e.preventDefault()
} }
} }
}, },

View file

@ -1,13 +1,11 @@
export default function suggest (data) { export default function suggest (data) {
return input => { return input => {
const trimmed = input.trim() const firstChar = input[0]
const firstChar = trimmed[0]
console.log(`'${trimmed}'`, firstChar, firstChar === ':')
if (firstChar === ':' && data.emoji) { if (firstChar === ':' && data.emoji) {
return suggestEmoji(data.emoji)(trimmed) return suggestEmoji(data.emoji)(input)
} }
if (firstChar === '@' && data.users) { if (firstChar === '@' && data.users) {
return suggestUsers(data.users)(trimmed) return suggestUsers(data.users)(input)
} }
return [] return []
} }
@ -18,6 +16,19 @@ function suggestEmoji (emojis) {
const noPrefix = input.toLowerCase().substr(1) const noPrefix = input.toLowerCase().substr(1)
return emojis return emojis
.filter(({ displayText }) => displayText.toLowerCase().startsWith(noPrefix)) .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
// Sort alphabetically
const alphabetically = a.displayText > b.displayText ? 1 : -1
return bScore - aScore + alphabetically
})
} }
} }
@ -33,12 +44,17 @@ function suggestUsers (users) {
let aScore = 0 let aScore = 0
let bScore = 0 let bScore = 0
// Matches on screen name (i.e. user@instance) makes a priority
aScore += a.screen_name.toLowerCase().startsWith(noPrefix) * 2 aScore += a.screen_name.toLowerCase().startsWith(noPrefix) * 2
aScore += a.name.toLowerCase().startsWith(noPrefix)
bScore += b.screen_name.toLowerCase().startsWith(noPrefix) * 2 bScore += b.screen_name.toLowerCase().startsWith(noPrefix) * 2
// Matches on name takes second priority
aScore += a.name.toLowerCase().startsWith(noPrefix)
bScore += b.name.toLowerCase().startsWith(noPrefix) bScore += b.name.toLowerCase().startsWith(noPrefix)
const diff = bScore * 10 - aScore * 10 const diff = bScore * 10 - aScore * 10
// Then sort alphabetically
const nameAlphabetically = a.name > b.name ? 1 : -1 const nameAlphabetically = a.name > b.name ? 1 : -1
const screenNameAlphabetically = a.screen_name > b.screen_name ? 1 : -1 const screenNameAlphabetically = a.screen_name > b.screen_name ? 1 : -1

View file

@ -105,7 +105,7 @@ const PostStatusForm = {
}) })
}, },
emojiSuggestor () { emojiSuggestor () {
suggestor({ emoji: [ return suggestor({ emoji: [
...this.$store.state.instance.emoji, ...this.$store.state.instance.emoji,
...this.$store.state.instance.customEmoji ...this.$store.state.instance.customEmoji
]}) ]})