replaced fusejs in Emojiboard
This commit is contained in:
parent
c06a92e0ae
commit
633d59c13b
3 changed files with 30 additions and 39 deletions
|
@ -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>
|
||||||
|
|
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue