diff --git a/src/app/organisms/emoji-board/EmojiBoard.jsx b/src/app/organisms/emoji-board/EmojiBoard.jsx index 03dcf4f..3f473e4 100644 --- a/src/app/organisms/emoji-board/EmojiBoard.jsx +++ b/src/app/organisms/emoji-board/EmojiBoard.jsx @@ -4,11 +4,10 @@ import React, { useState, useEffect, useRef } from 'react'; import PropTypes from 'prop-types'; import './EmojiBoard.scss'; -import EventEmitter from 'events'; - import parse from 'html-react-parser'; import twemoji from 'twemoji'; -import { emojiGroups, searchEmoji } from './emoji'; +import { emojiGroups, emojis } from './emoji'; +import AsyncSearch from '../../../util/AsyncSearch'; import Text from '../../atoms/text/Text'; import RawIcon from '../../atoms/system-icons/RawIcon'; @@ -26,20 +25,18 @@ import BulbIC from '../../../../public/res/ic/outlined/bulb.svg'; import PeaceIC from '../../../../public/res/ic/outlined/peace.svg'; import FlagIC from '../../../../public/res/ic/outlined/flag.svg'; -const viewEvent = new EventEmitter(); - -function EmojiGroup({ name, emojis }) { +function EmojiGroup({ name, groupEmojis }) { function getEmojiBoard() { const emojiBoard = []; const ROW_EMOJIS_COUNT = 7; - const totalEmojis = emojis.length; + const totalEmojis = groupEmojis.length; for (let r = 0; r < totalEmojis; r += ROW_EMOJIS_COUNT) { const emojiRow = []; for (let c = r; c < r + ROW_EMOJIS_COUNT; c += 1) { const emojiIndex = c; if (emojiIndex >= totalEmojis) break; - const emoji = emojis[emojiIndex]; + const emoji = groupEmojis[emojiIndex]; emojiRow.push( { @@ -65,13 +62,13 @@ function EmojiGroup({ name, emojis }) { return (
{name} -
{getEmojiBoard()}
+ {groupEmojis.length !== 0 &&
{getEmojiBoard()}
}
); } EmojiGroup.propTypes = { name: PropTypes.string.isRequired, - emojis: PropTypes.arrayOf(PropTypes.shape({ + groupEmojis: PropTypes.arrayOf(PropTypes.shape({ length: PropTypes.number, unicode: PropTypes.string, hexcode: PropTypes.string, @@ -82,25 +79,30 @@ EmojiGroup.propTypes = { })).isRequired, }; +const asyncSearch = new AsyncSearch(); +asyncSearch.setup(emojis, { keys: ['shortcode'], limit: 30 }); function SearchedEmoji() { - const [searchedEmojis, setSearchedEmojis] = useState([]); + const [searchedEmojis, setSearchedEmojis] = useState(null); - function handleSearchEmoji(term) { - if (term.trim() === '') { - setSearchedEmojis([]); + function handleSearchEmoji(resultEmojis, term) { + if (term === '' || resultEmojis.length === 0) { + if (term === '') setSearchedEmojis(null); + else setSearchedEmojis([]); return; } - setSearchedEmojis(searchEmoji(term).map((finding) => finding.item)); + setSearchedEmojis(resultEmojis); } useEffect(() => { - viewEvent.on('search-emoji', handleSearchEmoji); + asyncSearch.on(asyncSearch.RESULT_SENT, handleSearchEmoji); return () => { - viewEvent.removeListener('search-emoji', handleSearchEmoji); + asyncSearch.removeListener(asyncSearch.RESULT_SENT, handleSearchEmoji); }; }, []); - return searchedEmojis.length !== 0 && ; + if (searchedEmojis === null) return false; + + return ; } function EmojiBoard({ onSelect }) { @@ -148,17 +150,14 @@ function EmojiBoard({ onSelect }) { return; } if (searchRef.current.placeholder === shortcodes[0]) return; - searchRef.current.setAttribute('placeholder', `:${shortcodes[0]}:`); + searchRef.current.setAttribute('placeholder', shortcodes[0]); setEmojiInfo({ hexcode, shortcode: shortcodes[0] }); } function handleSearchChange(e) { const term = e.target.value; - setTimeout(() => { - if (e.target.value !== term) return; - viewEvent.emit('search-emoji', term); - scrollEmojisRef.current.scrollTop = 0; - }, 500); + asyncSearch.search(term); + scrollEmojisRef.current.scrollTop = 0; } function openGroup(groupOrder) { @@ -182,7 +181,7 @@ function EmojiBoard({ onSelect }) { { emojiGroups.map((group) => ( - + )) } diff --git a/src/app/organisms/emoji-board/emoji.js b/src/app/organisms/emoji-board/emoji.js index 315b139..878a019 100644 --- a/src/app/organisms/emoji-board/emoji.js +++ b/src/app/organisms/emoji-board/emoji.js @@ -1,6 +1,5 @@ import emojisData from 'emojibase-data/en/compact.json'; import shortcodes from 'emojibase-data/en/shortcodes/joypixels.json'; -import Fuse from 'fuse.js'; const emojiGroups = [{ name: 'Smileys & people', @@ -62,18 +61,7 @@ emojisData.forEach((emoji) => { addToGroup(em); emojis.push(em); }); -function searchEmoji(term) { - const options = { - includeScore: true, - keys: ['shortcodes', 'annotation', 'tags'], - threshold: '0.3', - }; - const fuse = new Fuse(emojis, options); - let result = fuse.search(term); - if (result.length > 20) result = result.slice(0, 20); - return result; -} export { - emojis, emojiGroups, searchEmoji, + emojis, emojiGroups, }; diff --git a/src/util/AsyncSearch.js b/src/util/AsyncSearch.js index f2ac04c..b90ae15 100644 --- a/src/util/AsyncSearch.js +++ b/src/util/AsyncSearch.js @@ -57,6 +57,10 @@ class AsyncSearch extends EventEmitter { this.term = (this.isCaseSensitive) ? term : term.toLocaleLowerCase(); if (this.ignoreWhitespace) this.term = this.term.replace(' ', ''); + if (this.term === '') { + this._sendFindings(); + return; + } this._find(this.sessionStartTimestamp, 0); } @@ -117,7 +121,7 @@ class AsyncSearch extends EventEmitter { } _sendFindings() { - this.emit(this.RESULT_SENT, this.findingList); + this.emit(this.RESULT_SENT, this.findingList, this.term); } }