From b728b25c102d10ac9447fee27a2b667e58f78b9b Mon Sep 17 00:00:00 2001 From: Claire Date: Tue, 11 Oct 2022 12:36:24 +0200 Subject: Move flavours/glitch/utils/emoji back to flavours/glitch/features/emoji --- app/javascript/flavours/glitch/actions/compose.js | 2 +- .../flavours/glitch/actions/importer/normalizer.js | 2 +- .../glitch/components/autosuggest_emoji.js | 2 +- app/javascript/flavours/glitch/components/poll.js | 2 +- .../flavours/glitch/features/emoji/emoji.js | 116 +++++++++ .../glitch/features/emoji/emoji_compressed.js | 122 ++++++++++ .../flavours/glitch/features/emoji/emoji_map.json | 1 + .../glitch/features/emoji/emoji_mart_data_light.js | 41 ++++ .../features/emoji/emoji_mart_search_light.js | 185 +++++++++++++++ .../flavours/glitch/features/emoji/emoji_picker.js | 7 + .../features/emoji/emoji_unicode_mapping_light.js | 35 +++ .../flavours/glitch/features/emoji/emoji_utils.js | 258 +++++++++++++++++++++ .../glitch/features/emoji/unicode_to_filename.js | 26 +++ .../features/emoji/unicode_to_unified_name.js | 21 ++ .../flavours/glitch/features/emoji_picker/index.js | 2 +- .../getting_started/components/announcements.js | 2 +- .../ui/components/compare_history_modal.js | 2 +- .../glitch/features/ui/util/async-components.js | 2 +- app/javascript/flavours/glitch/packs/public.js | 2 +- .../flavours/glitch/reducers/custom_emojis.js | 4 +- .../glitch/utils/emoji/emoji_compressed.js | 122 ---------- .../flavours/glitch/utils/emoji/emoji_map.json | 1 - .../glitch/utils/emoji/emoji_mart_data_light.js | 41 ---- .../glitch/utils/emoji/emoji_mart_search_light.js | 185 --------------- .../flavours/glitch/utils/emoji/emoji_picker.js | 7 - .../utils/emoji/emoji_unicode_mapping_light.js | 35 --- .../flavours/glitch/utils/emoji/emoji_utils.js | 258 --------------------- .../flavours/glitch/utils/emoji/index.js | 116 --------- .../glitch/utils/emoji/unicode_to_filename.js | 26 --- .../glitch/utils/emoji/unicode_to_unified_name.js | 21 -- 30 files changed, 823 insertions(+), 823 deletions(-) create mode 100644 app/javascript/flavours/glitch/features/emoji/emoji.js create mode 100644 app/javascript/flavours/glitch/features/emoji/emoji_compressed.js create mode 100644 app/javascript/flavours/glitch/features/emoji/emoji_map.json create mode 100644 app/javascript/flavours/glitch/features/emoji/emoji_mart_data_light.js create mode 100644 app/javascript/flavours/glitch/features/emoji/emoji_mart_search_light.js create mode 100644 app/javascript/flavours/glitch/features/emoji/emoji_picker.js create mode 100644 app/javascript/flavours/glitch/features/emoji/emoji_unicode_mapping_light.js create mode 100644 app/javascript/flavours/glitch/features/emoji/emoji_utils.js create mode 100644 app/javascript/flavours/glitch/features/emoji/unicode_to_filename.js create mode 100644 app/javascript/flavours/glitch/features/emoji/unicode_to_unified_name.js delete mode 100644 app/javascript/flavours/glitch/utils/emoji/emoji_compressed.js delete mode 100644 app/javascript/flavours/glitch/utils/emoji/emoji_map.json delete mode 100644 app/javascript/flavours/glitch/utils/emoji/emoji_mart_data_light.js delete mode 100644 app/javascript/flavours/glitch/utils/emoji/emoji_mart_search_light.js delete mode 100644 app/javascript/flavours/glitch/utils/emoji/emoji_picker.js delete mode 100644 app/javascript/flavours/glitch/utils/emoji/emoji_unicode_mapping_light.js delete mode 100644 app/javascript/flavours/glitch/utils/emoji/emoji_utils.js delete mode 100644 app/javascript/flavours/glitch/utils/emoji/index.js delete mode 100644 app/javascript/flavours/glitch/utils/emoji/unicode_to_filename.js delete mode 100644 app/javascript/flavours/glitch/utils/emoji/unicode_to_unified_name.js (limited to 'app/javascript') diff --git a/app/javascript/flavours/glitch/actions/compose.js b/app/javascript/flavours/glitch/actions/compose.js index 0ef505363..02aa4f144 100644 --- a/app/javascript/flavours/glitch/actions/compose.js +++ b/app/javascript/flavours/glitch/actions/compose.js @@ -1,7 +1,7 @@ import api from '../api'; import { CancelToken, isCancel } from 'axios'; import { throttle } from 'lodash'; -import { search as emojiSearch } from 'flavours/glitch/utils/emoji/emoji_mart_search_light'; +import { search as emojiSearch } from 'flavours/glitch/features/emoji/emoji_mart_search_light'; import { useEmoji } from './emojis'; import { tagHistory } from '../settings'; import { recoverHashtags } from 'flavours/glitch/utils/hashtag'; diff --git a/app/javascript/flavours/glitch/actions/importer/normalizer.js b/app/javascript/flavours/glitch/actions/importer/normalizer.js index bf1e129a2..1c9f524e4 100644 --- a/app/javascript/flavours/glitch/actions/importer/normalizer.js +++ b/app/javascript/flavours/glitch/actions/importer/normalizer.js @@ -1,5 +1,5 @@ import escapeTextContentForBrowser from 'escape-html'; -import emojify from 'flavours/glitch/utils/emoji'; +import emojify from 'flavours/glitch/features/emoji/emoji'; import { unescapeHTML } from 'flavours/glitch/utils/html'; import { autoHideCW } from 'flavours/glitch/utils/content_warning'; diff --git a/app/javascript/flavours/glitch/components/autosuggest_emoji.js b/app/javascript/flavours/glitch/components/autosuggest_emoji.js index dd756544b..83fafbd10 100644 --- a/app/javascript/flavours/glitch/components/autosuggest_emoji.js +++ b/app/javascript/flavours/glitch/components/autosuggest_emoji.js @@ -1,6 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; -import unicodeMapping from 'flavours/glitch/utils/emoji/emoji_unicode_mapping_light'; +import unicodeMapping from 'flavours/glitch/features/emoji/emoji_unicode_mapping_light'; import { assetHost } from 'flavours/glitch/utils/config'; diff --git a/app/javascript/flavours/glitch/components/poll.js b/app/javascript/flavours/glitch/components/poll.js index 6dfa73f49..da65cd241 100644 --- a/app/javascript/flavours/glitch/components/poll.js +++ b/app/javascript/flavours/glitch/components/poll.js @@ -7,7 +7,7 @@ import classNames from 'classnames'; import Motion from 'flavours/glitch/features/ui/util/optional_motion'; import spring from 'react-motion/lib/spring'; import escapeTextContentForBrowser from 'escape-html'; -import emojify from 'flavours/glitch/utils/emoji'; +import emojify from 'flavours/glitch/features/emoji/emoji'; import RelativeTimestamp from './relative_timestamp'; import Icon from 'flavours/glitch/components/icon'; diff --git a/app/javascript/flavours/glitch/features/emoji/emoji.js b/app/javascript/flavours/glitch/features/emoji/emoji.js new file mode 100644 index 000000000..c4e2c26f2 --- /dev/null +++ b/app/javascript/flavours/glitch/features/emoji/emoji.js @@ -0,0 +1,116 @@ +import { autoPlayGif, useSystemEmojiFont } from 'flavours/glitch/initial_state'; +import unicodeMapping from './emoji_unicode_mapping_light'; +import { assetHost } from 'flavours/glitch/utils/config'; +import Trie from 'substring-trie'; + +const trie = new Trie(Object.keys(unicodeMapping)); + +// Convert to file names from emojis. (For different variation selector emojis) +const emojiFilenames = (emojis) => { + return emojis.map(v => unicodeMapping[v].filename); +}; + +// Emoji requiring extra borders depending on theme +const darkEmoji = emojiFilenames(['๐ŸŽฑ', '๐Ÿœ', 'โšซ', '๐Ÿ–ค', 'โฌ›', 'โ—ผ๏ธ', 'โ—พ', 'โ—ผ๏ธ', 'โœ’๏ธ', 'โ–ช๏ธ', '๐Ÿ’ฃ', '๐ŸŽณ', '๐Ÿ“ท', '๐Ÿ“ธ', 'โ™ฃ๏ธ', '๐Ÿ•ถ๏ธ', 'โœด๏ธ', '๐Ÿ”Œ', '๐Ÿ’‚โ€โ™€๏ธ', '๐Ÿ“ฝ๏ธ', '๐Ÿณ', '๐Ÿฆ', '๐Ÿ’‚', '๐Ÿ”ช', '๐Ÿ•ณ๏ธ', '๐Ÿ•น๏ธ', '๐Ÿ•‹', '๐Ÿ–Š๏ธ', '๐Ÿ–‹๏ธ', '๐Ÿ’‚โ€โ™‚๏ธ', '๐ŸŽค', '๐ŸŽ“', '๐ŸŽฅ', '๐ŸŽผ', 'โ™ ๏ธ', '๐ŸŽฉ', '๐Ÿฆƒ', '๐Ÿ“ผ', '๐Ÿ“น', '๐ŸŽฎ', '๐Ÿƒ', '๐Ÿด', '๐Ÿž', '๐Ÿ•บ', '๐Ÿ“ฑ', '๐Ÿ“ฒ', '๐Ÿšฒ']); +const lightEmoji = emojiFilenames(['๐Ÿ‘ฝ', 'โšพ', '๐Ÿ”', 'โ˜๏ธ', '๐Ÿ’จ', '๐Ÿ•Š๏ธ', '๐Ÿ‘€', '๐Ÿฅ', '๐Ÿ‘ป', '๐Ÿ', 'โ•', 'โ”', 'โ›ธ๏ธ', '๐ŸŒฉ๏ธ', '๐Ÿ”Š', '๐Ÿ”‡', '๐Ÿ“ƒ', '๐ŸŒง๏ธ', '๐Ÿ', '๐Ÿš', '๐Ÿ™', '๐Ÿ“', '๐Ÿ‘', '๐Ÿ’€', 'โ˜ ๏ธ', '๐ŸŒจ๏ธ', '๐Ÿ”‰', '๐Ÿ”ˆ', '๐Ÿ’ฌ', '๐Ÿ’ญ', '๐Ÿ', '๐Ÿณ๏ธ', 'โšช', 'โฌœ', 'โ—ฝ', 'โ—ป๏ธ', 'โ–ซ๏ธ']); + +const emojiFilename = (filename) => { + const borderedEmoji = (document.body && document.body.classList.contains('skin-mastodon-light')) ? lightEmoji : darkEmoji; + return borderedEmoji.includes(filename) ? (filename + '_border') : filename; +}; + +const emojify = (str, customEmojis = {}) => { + const tagCharsWithoutEmojis = '<&'; + const tagCharsWithEmojis = Object.keys(customEmojis).length ? '<&:' : '<&'; + let rtn = '', tagChars = tagCharsWithEmojis, invisible = 0; + for (;;) { + let match, i = 0, tag; + while (i < str.length && (tag = tagChars.indexOf(str[i])) === -1 && (invisible || useSystemEmojiFont || !(match = trie.search(str.slice(i))))) { + i += str.codePointAt(i) < 65536 ? 1 : 2; + } + let rend, replacement = ''; + if (i === str.length) { + break; + } else if (str[i] === ':') { + if (!(() => { + rend = str.indexOf(':', i + 1) + 1; + if (!rend) return false; // no pair of ':' + const lt = str.indexOf('<', i + 1); + if (!(lt === -1 || lt >= rend)) return false; // tag appeared before closing ':' + const shortname = str.slice(i, rend); + // now got a replacee as ':shortname:' + // if you want additional emoji handler, add statements below which set replacement and return true. + if (shortname in customEmojis) { + const filename = autoPlayGif ? customEmojis[shortname].url : customEmojis[shortname].static_url; + replacement = `${shortname}`; + return true; + } + return false; + })()) rend = ++i; + } else if (tag >= 0) { // <, & + rend = str.indexOf('>;'[tag], i + 1) + 1; + if (!rend) { + break; + } + if (tag === 0) { + if (invisible) { + if (str[i + 1] === '/') { // closing tag + if (!--invisible) { + tagChars = tagCharsWithEmojis; + } + } else if (str[rend - 2] !== '/') { // opening tag + invisible++; + } + } else { + if (str.startsWith('