import escapeStringRegexp from 'escape-string-regexp';
import flatten from 'lodash/flatten';
import find from 'lodash/find';
import trim from 'lodash/trim';
import emoticonData from '../../data/emoticon.json';
import { SEGMENT_EMOJI, SEGMENT_RAW } from '../../data/enum/SegmentType';
import { processMatches } from './index';
// Build a regex containing all the emoticons
const emoticonCollection = Object.values(emoticonData)
.reduce((prev, curr) => {
// Push the shortnames
prev.push(escapeStringRegexp(curr.shortname));
// Push the ascii combinations
curr.ascii.map(ascii => prev.push(escapeStringRegexp(ascii)));
return prev;
}, [])
.sort((a, b) => a.length - b.length)
.join('|');
const emoticonCollectionRegex = new RegExp(`(?:^|\\s)(${emoticonCollection})(?=\\s|$)`, 'g');
/**
* Detects an user tagging in each SEGMENT_RAW message segment provided to `input`. If an emoticon
* is detected, will convert it to a SEGMENT_EMOJI and attach a emoji object.
* @param input {Array<Object>} An array of message segments
* @returns {Array<Object>} The processed array of message segments
*/
const detectEmoji = () => input =>
flatten(
input.map(segment => {
const { type, data } = segment;
switch (type) {
case SEGMENT_RAW: {
const match = data.match(emoticonCollectionRegex);
if (match) {
const dataMatch = [];
let lastIndex = 0;
match.forEach(emoji => {
const index = data.indexOf(emoji, lastIndex);
lastIndex = index + emoji.length;
const { shortname, unicode } = find(
Object.values(emoticonData),
emoticon =>
emoticon.shortname === trim(emoji) || emoticon.ascii.includes(trim(emoji)),
);
return dataMatch.push({
index,
lastIndex,
unicode,
shortname,
});
});
return processMatches(dataMatch, segment, SEGMENT_EMOJI);
}
return segment;
}
default:
return segment;
}
}),
);
export default detectEmoji;