replaced fusejs in Emojiboard

This commit is contained in:
unknown 2021-08-25 15:00:40 +05:30
parent c06a92e0ae
commit 633d59c13b
3 changed files with 30 additions and 39 deletions

View file

@ -4,11 +4,10 @@ import React, { useState, useEffect, useRef } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import './EmojiBoard.scss'; import './EmojiBoard.scss';
import EventEmitter from 'events';
import parse from 'html-react-parser'; import parse from 'html-react-parser';
import twemoji from 'twemoji'; 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 Text from '../../atoms/text/Text';
import RawIcon from '../../atoms/system-icons/RawIcon'; 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 PeaceIC from '../../../../public/res/ic/outlined/peace.svg';
import FlagIC from '../../../../public/res/ic/outlined/flag.svg'; import FlagIC from '../../../../public/res/ic/outlined/flag.svg';
const viewEvent = new EventEmitter(); function EmojiGroup({ name, groupEmojis }) {
function EmojiGroup({ name, emojis }) {
function getEmojiBoard() { function getEmojiBoard() {
const emojiBoard = []; const emojiBoard = [];
const ROW_EMOJIS_COUNT = 7; const ROW_EMOJIS_COUNT = 7;
const totalEmojis = emojis.length; const totalEmojis = groupEmojis.length;
for (let r = 0; r < totalEmojis; r += ROW_EMOJIS_COUNT) { for (let r = 0; r < totalEmojis; r += ROW_EMOJIS_COUNT) {
const emojiRow = []; const emojiRow = [];
for (let c = r; c < r + ROW_EMOJIS_COUNT; c += 1) { for (let c = r; c < r + ROW_EMOJIS_COUNT; c += 1) {
const emojiIndex = c; const emojiIndex = c;
if (emojiIndex >= totalEmojis) break; if (emojiIndex >= totalEmojis) break;
const emoji = emojis[emojiIndex]; const emoji = groupEmojis[emojiIndex];
emojiRow.push( emojiRow.push(
<span key={emojiIndex}> <span key={emojiIndex}>
{ {
@ -65,13 +62,13 @@ function EmojiGroup({ name, emojis }) {
return ( return (
<div className="emoji-group"> <div className="emoji-group">
<Text className="emoji-group__header" variant="b2">{name}</Text> <Text className="emoji-group__header" variant="b2">{name}</Text>
<div className="emoji-set">{getEmojiBoard()}</div> {groupEmojis.length !== 0 && <div className="emoji-set">{getEmojiBoard()}</div>}
</div> </div>
); );
} }
EmojiGroup.propTypes = { EmojiGroup.propTypes = {
name: PropTypes.string.isRequired, name: PropTypes.string.isRequired,
emojis: PropTypes.arrayOf(PropTypes.shape({ groupEmojis: PropTypes.arrayOf(PropTypes.shape({
length: PropTypes.number, length: PropTypes.number,
unicode: PropTypes.string, unicode: PropTypes.string,
hexcode: PropTypes.string, hexcode: PropTypes.string,
@ -82,25 +79,30 @@ EmojiGroup.propTypes = {
})).isRequired, })).isRequired,
}; };
const asyncSearch = new AsyncSearch();
asyncSearch.setup(emojis, { keys: ['shortcode'], limit: 30 });
function SearchedEmoji() { function SearchedEmoji() {
const [searchedEmojis, setSearchedEmojis] = useState([]); const [searchedEmojis, setSearchedEmojis] = useState(null);
function handleSearchEmoji(term) { function handleSearchEmoji(resultEmojis, term) {
if (term.trim() === '') { if (term === '' || resultEmojis.length === 0) {
setSearchedEmojis([]); if (term === '') setSearchedEmojis(null);
else setSearchedEmojis([]);
return; return;
} }
setSearchedEmojis(searchEmoji(term).map((finding) => finding.item)); setSearchedEmojis(resultEmojis);
} }
useEffect(() => { useEffect(() => {
viewEvent.on('search-emoji', handleSearchEmoji); asyncSearch.on(asyncSearch.RESULT_SENT, handleSearchEmoji);
return () => { return () => {
viewEvent.removeListener('search-emoji', handleSearchEmoji); asyncSearch.removeListener(asyncSearch.RESULT_SENT, handleSearchEmoji);
}; };
}, []); }, []);
return searchedEmojis.length !== 0 && <EmojiGroup key="-1" name="Search results" emojis={searchedEmojis} />; if (searchedEmojis === null) return false;
return <EmojiGroup key="-1" name={searchedEmojis.length === 0 ? 'No search result found' : 'Search results'} groupEmojis={searchedEmojis} />;
} }
function EmojiBoard({ onSelect }) { function EmojiBoard({ onSelect }) {
@ -148,17 +150,14 @@ function EmojiBoard({ onSelect }) {
return; return;
} }
if (searchRef.current.placeholder === shortcodes[0]) 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] }); setEmojiInfo({ hexcode, shortcode: shortcodes[0] });
} }
function handleSearchChange(e) { function handleSearchChange(e) {
const term = e.target.value; const term = e.target.value;
setTimeout(() => { asyncSearch.search(term);
if (e.target.value !== term) return;
viewEvent.emit('search-emoji', term);
scrollEmojisRef.current.scrollTop = 0; scrollEmojisRef.current.scrollTop = 0;
}, 500);
} }
function openGroup(groupOrder) { function openGroup(groupOrder) {
@ -182,7 +181,7 @@ function EmojiBoard({ onSelect }) {
<SearchedEmoji /> <SearchedEmoji />
{ {
emojiGroups.map((group) => ( emojiGroups.map((group) => (
<EmojiGroup key={group.name} name={group.name} emojis={group.emojis} /> <EmojiGroup key={group.name} name={group.name} groupEmojis={group.emojis} />
)) ))
} }
</div> </div>

View file

@ -1,6 +1,5 @@
import emojisData from 'emojibase-data/en/compact.json'; import emojisData from 'emojibase-data/en/compact.json';
import shortcodes from 'emojibase-data/en/shortcodes/joypixels.json'; import shortcodes from 'emojibase-data/en/shortcodes/joypixels.json';
import Fuse from 'fuse.js';
const emojiGroups = [{ const emojiGroups = [{
name: 'Smileys & people', name: 'Smileys & people',
@ -62,18 +61,7 @@ emojisData.forEach((emoji) => {
addToGroup(em); addToGroup(em);
emojis.push(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 { export {
emojis, emojiGroups, searchEmoji, emojis, emojiGroups,
}; };

View file

@ -57,6 +57,10 @@ class AsyncSearch extends EventEmitter {
this.term = (this.isCaseSensitive) ? term : term.toLocaleLowerCase(); this.term = (this.isCaseSensitive) ? term : term.toLocaleLowerCase();
if (this.ignoreWhitespace) this.term = this.term.replace(' ', ''); if (this.ignoreWhitespace) this.term = this.term.replace(' ', '');
if (this.term === '') {
this._sendFindings();
return;
}
this._find(this.sessionStartTimestamp, 0); this._find(this.sessionStartTimestamp, 0);
} }
@ -117,7 +121,7 @@ class AsyncSearch extends EventEmitter {
} }
_sendFindings() { _sendFindings() {
this.emit(this.RESULT_SENT, this.findingList); this.emit(this.RESULT_SENT, this.findingList, this.term);
} }
} }