hedgedoc/src/components/editor/editor-pane/autocompletion/emoji.ts
Erik Michelson 5574f09ef5
Replace emoji-mart with emoji-picker-element (#620)
* Change dependencies

* Use emoji-picker-element instead of emoji-mart

* Optimize emoji-picker appeareance and data-source

* Add twemoji font to emoji-picker

* Add missing useEffect dependency

* Add emoji-shortcode map

* Include emoji-data into bundle and remove dynamic fetch

* Rename shortcode-map

* Fix emoji-picker being hidden on second attempt to open it

* Add support for skin-tone short-codes

* Remove whitespace line

* Don't reinitialize the picker on every open

* Fixed linting and test issues

* Update CHANGELOG entry
2020-10-10 23:12:17 +02:00

63 lines
2.2 KiB
TypeScript

import { Editor, Hint, Hints, Pos } from 'codemirror'
import Database from 'emoji-picker-element/database'
import { Emoji, EmojiClickEventDetail, NativeEmoji } from 'emoji-picker-element/shared'
import { customEmojis } from '../tool-bar/emoji-picker/emoji-picker'
import { getEmojiIcon, getEmojiShortCode } from '../tool-bar/utils/emojiUtils'
import { findWordAtCursor, Hinter } from './index'
const emojiIndex = new Database({
customEmoji: customEmojis,
dataSource: '/static/js/emoji-data.json'
})
const emojiWordRegex = /^:([\w-_+]*)$/
const generateEmojiHints = (editor: Editor): Promise< Hints| null > => {
return new Promise((resolve) => {
const searchTerm = findWordAtCursor(editor)
const searchResult = emojiWordRegex.exec(searchTerm.text)
if (searchResult === null) {
resolve(null)
return
}
const term = searchResult[1]
let suggestionList: Emoji[]
emojiIndex.getEmojiBySearchQuery(term)
.then(async (result) => {
suggestionList = result
if (result.length === 0) {
suggestionList = await emojiIndex.getTopFavoriteEmoji(7)
}
const cursor = editor.getCursor()
const skinTone = await emojiIndex.getPreferredSkinTone()
const emojiEventDetails: EmojiClickEventDetail[] = suggestionList.map((emoji) => {
return {
emoji,
skinTone: skinTone,
unicode: ((emoji as NativeEmoji).unicode ? (emoji as NativeEmoji).unicode : undefined),
name: emoji.name
}
})
resolve({
list: emojiEventDetails.map((emojiData): Hint => ({
text: getEmojiShortCode(emojiData),
render: (parent: HTMLLIElement) => {
const wrapper = document.createElement('div')
wrapper.innerHTML = `${getEmojiIcon(emojiData)} ${getEmojiShortCode(emojiData)}`
parent.appendChild(wrapper)
}
})),
from: Pos(cursor.line, searchTerm.start),
to: Pos(cursor.line, searchTerm.end)
})
})
.catch(error => {
console.error(error)
resolve(null)
})
})
}
export const EmojiHinter: Hinter = {
wordRegExp: emojiWordRegex,
hint: generateEmojiHints
}