refactor: use twemoji as img
This commit is contained in:
parent
13b9c4c0a8
commit
3e07ca4c58
13 changed files with 78 additions and 133 deletions
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
[submodule "twemoji"]
|
||||
path = twemoji
|
||||
url = https://github.com/jdecked/twemoji
|
76
package-lock.json
generated
76
package-lock.json
generated
|
@ -24,8 +24,8 @@
|
|||
"dateformat": "5.0.3",
|
||||
"dayjs": "1.11.10",
|
||||
"domhandler": "5.0.3",
|
||||
"emojibase": "15.3.0",
|
||||
"emojibase-data": "15.3.0",
|
||||
"emojibase": "15.2.0",
|
||||
"emojibase-data": "15.2.0",
|
||||
"file-saver": "2.0.5",
|
||||
"flux": "4.0.3",
|
||||
"focus-trap-react": "10.0.2",
|
||||
|
@ -61,7 +61,6 @@
|
|||
"slate-history": "0.93.0",
|
||||
"slate-react": "0.98.4",
|
||||
"tippy.js": "6.3.7",
|
||||
"twemoji": "14.0.2",
|
||||
"ua-parser-js": "1.0.35"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -4076,18 +4075,18 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/emojibase": {
|
||||
"version": "15.3.0",
|
||||
"resolved": "https://registry.npmjs.org/emojibase/-/emojibase-15.3.0.tgz",
|
||||
"integrity": "sha512-lFdQb14hoznwDh1xDoOFzkPdeeexmbuJdhUUjDaJZf/+jK+6Z3HkI5hWOemWfEdaMxtTujc1vNRx9DKtdtiOXA==",
|
||||
"version": "15.2.0",
|
||||
"resolved": "https://registry.npmjs.org/emojibase/-/emojibase-15.2.0.tgz",
|
||||
"integrity": "sha512-gB6rIVtyJPersQvAo4nOGYPeILMhlcfZdiwCWVeRAtkJ7sm0tExZETGyLhrTQcHvZQhDEYI1vlCeqUhn5gZkQA==",
|
||||
"funding": {
|
||||
"type": "ko-fi",
|
||||
"url": "https://ko-fi.com/milesjohnson"
|
||||
}
|
||||
},
|
||||
"node_modules/emojibase-data": {
|
||||
"version": "15.3.0",
|
||||
"resolved": "https://registry.npmjs.org/emojibase-data/-/emojibase-data-15.3.0.tgz",
|
||||
"integrity": "sha512-cYsGq57W8wOd1CqQCjmtP1DpmlTVvJY+Um5UobWUQuTnqb8cO2cuqrxJxSIqxLcYZ3rtialT5kivoWigszdslg==",
|
||||
"version": "15.2.0",
|
||||
"resolved": "https://registry.npmjs.org/emojibase-data/-/emojibase-data-15.2.0.tgz",
|
||||
"integrity": "sha512-hDiw4ugxnI4pcVQO+73NlKx6aZP/A+BAPfDgK/3A83RVbHZa0Ut6GHpd5r5XUV9G7BZhKejlIRuxhXialpbt6Q==",
|
||||
"funding": {
|
||||
"type": "ko-fi",
|
||||
"url": "https://ko-fi.com/milesjohnson"
|
||||
|
@ -4988,27 +4987,6 @@
|
|||
"react": ">=16.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/fs-extra": {
|
||||
"version": "8.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
|
||||
"integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^4.0.0",
|
||||
"universalify": "^0.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6 <7 || >=8"
|
||||
}
|
||||
},
|
||||
"node_modules/fs-extra/node_modules/jsonfile": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
|
||||
"integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==",
|
||||
"optionalDependencies": {
|
||||
"graceful-fs": "^4.1.6"
|
||||
}
|
||||
},
|
||||
"node_modules/fs-minipass": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
|
||||
|
@ -5227,7 +5205,8 @@
|
|||
"node_modules/graceful-fs": {
|
||||
"version": "4.2.10",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
|
||||
"integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA=="
|
||||
"integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/grapheme-splitter": {
|
||||
"version": "1.0.4",
|
||||
|
@ -5870,17 +5849,6 @@
|
|||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/jsonfile": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-5.0.0.tgz",
|
||||
"integrity": "sha512-NQRZ5CRo74MhMMC3/3r5g2k4fjodJ/wh8MxjFbCViWKFjxrnudWSY5vomh+23ZaXzAS7J3fBZIR2dV6WbmfM0w==",
|
||||
"dependencies": {
|
||||
"universalify": "^0.1.2"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"graceful-fs": "^4.1.6"
|
||||
}
|
||||
},
|
||||
"node_modules/jsx-ast-utils": {
|
||||
"version": "3.3.3",
|
||||
"resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz",
|
||||
|
@ -7686,22 +7654,6 @@
|
|||
"typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta"
|
||||
}
|
||||
},
|
||||
"node_modules/twemoji": {
|
||||
"version": "14.0.2",
|
||||
"resolved": "https://registry.npmjs.org/twemoji/-/twemoji-14.0.2.tgz",
|
||||
"integrity": "sha512-BzOoXIe1QVdmsUmZ54xbEH+8AgtOKUiG53zO5vVP2iUu6h5u9lN15NcuS6te4OY96qx0H7JK9vjjl9WQbkTRuA==",
|
||||
"dependencies": {
|
||||
"fs-extra": "^8.0.1",
|
||||
"jsonfile": "^5.0.0",
|
||||
"twemoji-parser": "14.0.0",
|
||||
"universalify": "^0.1.2"
|
||||
}
|
||||
},
|
||||
"node_modules/twemoji-parser": {
|
||||
"version": "14.0.0",
|
||||
"resolved": "https://registry.npmjs.org/twemoji-parser/-/twemoji-parser-14.0.0.tgz",
|
||||
"integrity": "sha512-9DUOTGLOWs0pFWnh1p6NF+C3CkQ96PWmEFwhOVmT3WbecRC+68AIqpsnJXygfkFcp4aXbOp8Dwbhh/HQgvoRxA=="
|
||||
},
|
||||
"node_modules/type-check": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
|
||||
|
@ -7777,14 +7729,6 @@
|
|||
"resolved": "https://registry.npmjs.org/unhomoglyph/-/unhomoglyph-1.0.6.tgz",
|
||||
"integrity": "sha512-7uvcWI3hWshSADBu4JpnyYbTVc7YlhF5GDW/oPD5AxIxl34k4wXR3WDkPnzLxkN32LiTCTKMQLtKVZiwki3zGg=="
|
||||
},
|
||||
"node_modules/universalify": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
|
||||
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
|
||||
"engines": {
|
||||
"node": ">= 4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/update-browserslist-db": {
|
||||
"version": "1.0.10",
|
||||
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz",
|
||||
|
|
50
package.json
50
package.json
|
@ -19,60 +19,16 @@
|
|||
"author": "Ajay Bura",
|
||||
"license": "AGPL-3.0-only",
|
||||
"dependencies": {
|
||||
"@fontsource/inter": "4.5.14",
|
||||
"@khanacademy/simple-markdown": "0.8.6",
|
||||
"@matrix-org/olm": "3.2.14",
|
||||
"@tanstack/react-virtual": "3.0.0-beta.54",
|
||||
"@tippyjs/react": "4.2.6",
|
||||
"@vanilla-extract/css": "1.9.3",
|
||||
"@vanilla-extract/recipes": "0.3.0",
|
||||
"@vanilla-extract/vite-plugin": "3.7.1",
|
||||
"await-to-js": "3.0.0",
|
||||
"blurhash": "2.0.4",
|
||||
"browser-encrypt-attachment": "0.3.0",
|
||||
"classnames": "2.3.2",
|
||||
"dateformat": "5.0.3",
|
||||
"dayjs": "1.11.10",
|
||||
"domhandler": "5.0.3",
|
||||
"emojibase": "15.3.0",
|
||||
"emojibase-data": "15.3.0",
|
||||
"file-saver": "2.0.5",
|
||||
"flux": "4.0.3",
|
||||
"focus-trap-react": "10.0.2",
|
||||
"folds": "1.5.0",
|
||||
"formik": "2.2.9",
|
||||
"html-dom-parser": "4.0.0",
|
||||
"html-react-parser": "4.2.0",
|
||||
"immer": "9.0.16",
|
||||
"is-hotkey": "0.2.0",
|
||||
"jotai": "1.12.0",
|
||||
"katex": "0.16.4",
|
||||
"linkify-html": "4.0.2",
|
||||
"linkify-react": "4.1.1",
|
||||
"emojibase": "15.2.0",
|
||||
"linkifyjs": "4.0.2",
|
||||
"matrix-js-sdk": "24.1.0",
|
||||
"millify": "6.1.0",
|
||||
"pdfjs-dist": "3.10.111",
|
||||
"prismjs": "1.29.0",
|
||||
"prop-types": "15.8.1",
|
||||
"react": "17.0.2",
|
||||
"react-aria": "3.29.1",
|
||||
"react-autosize-textarea": "7.1.0",
|
||||
"react-blurhash": "0.2.0",
|
||||
"react-dnd": "15.1.2",
|
||||
"react-dnd-html5-backend": "15.1.3",
|
||||
"react-dom": "17.0.2",
|
||||
"react-error-boundary": "4.0.10",
|
||||
"react-google-recaptcha": "2.1.0",
|
||||
"react-modal": "3.16.1",
|
||||
"react-range": "1.8.14",
|
||||
"sanitize-html": "2.8.0",
|
||||
"slate": "0.94.1",
|
||||
"slate-history": "0.93.0",
|
||||
"slate-react": "0.98.4",
|
||||
"tippy.js": "6.3.7",
|
||||
"twemoji": "14.0.2",
|
||||
"ua-parser-js": "1.0.35"
|
||||
"slate": "0.94.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@esbuild-plugins/node-globals-polyfill": "0.2.3",
|
||||
|
@ -103,4 +59,4 @@
|
|||
"vite": "4.3.9",
|
||||
"vite-plugin-static-copy": "0.13.0"
|
||||
}
|
||||
}
|
||||
}
|
Binary file not shown.
Binary file not shown.
|
@ -11,6 +11,7 @@ import {
|
|||
import * as css from '../../styles/CustomHtml.css';
|
||||
import { CommandElement, EmoticonElement, LinkElement, MentionElement } from './slate';
|
||||
import { useMatrixClient } from '../../hooks/useMatrixClient';
|
||||
import { getEmojiUrl, isUsingTwemoji } from '../../plugins/emoji';
|
||||
import { getBeginCommand } from './utils';
|
||||
import { BlockType } from './types';
|
||||
|
||||
|
@ -94,7 +95,11 @@ function RenderEmoticonElement({
|
|||
alt={element.shortcode}
|
||||
/>
|
||||
) : (
|
||||
element.key
|
||||
isUsingTwemoji() ? <img
|
||||
className={css.EmoticonImg}
|
||||
src={getEmojiUrl(element.key)}
|
||||
alt={element.shortcode}
|
||||
/> : element.key
|
||||
)}
|
||||
{children}
|
||||
</span>
|
||||
|
|
|
@ -126,6 +126,15 @@ export const CustomEmojiImg = style([
|
|||
},
|
||||
]);
|
||||
|
||||
export const EmoticonImg = style([
|
||||
DefaultReset,
|
||||
{
|
||||
width: toRem(32),
|
||||
height: toRem(32),
|
||||
objectFit: 'contain',
|
||||
},
|
||||
]);
|
||||
|
||||
export const StickerImg = style([
|
||||
DefaultReset,
|
||||
{
|
||||
|
|
|
@ -34,7 +34,15 @@ import { MatrixClient, Room } from 'matrix-js-sdk';
|
|||
import { atom, useAtomValue, useSetAtom } from 'jotai';
|
||||
|
||||
import * as css from './EmojiBoard.css';
|
||||
import { EmojiGroupId, IEmoji, IEmojiGroup, emojiGroups, emojis } from '../../plugins/emoji';
|
||||
import {
|
||||
EmojiGroupId,
|
||||
IEmoji,
|
||||
IEmojiGroup,
|
||||
emojiGroups,
|
||||
emojis,
|
||||
getEmojiUrl,
|
||||
isUsingTwemoji,
|
||||
} from '../../plugins/emoji';
|
||||
import { IEmojiGroupLabels, useEmojiGroupLabels } from './useEmojiGroupLabels';
|
||||
import { IEmojiGroupIcons, useEmojiGroupIcons } from './useEmojiGroupIcons';
|
||||
import { preventScrollWithArrowKey } from '../../utils/keyboard';
|
||||
|
@ -439,9 +447,13 @@ export function RecentEmojiGroup({
|
|||
type={EmojiType.Emoji}
|
||||
data={emoji.unicode}
|
||||
shortcode={emoji.shortcode}
|
||||
>
|
||||
{emoji.unicode}
|
||||
</EmojiItem>
|
||||
>{
|
||||
isUsingTwemoji() ? <img
|
||||
className={css.EmoticonImg}
|
||||
src={getEmojiUrl(emoji.unicode)}
|
||||
alt={emoji.shortcode}
|
||||
/> : emoji.unicode
|
||||
}</EmojiItem>
|
||||
))}
|
||||
</EmojiGroup>
|
||||
);
|
||||
|
|
|
@ -112,3 +112,13 @@ emojisData.forEach((emoji) => {
|
|||
emojis.push(em);
|
||||
}
|
||||
});
|
||||
|
||||
export const isUsingTwemoji = () =>
|
||||
document.documentElement.style.getPropertyValue('--font-emoji') !== 'Twemoji_DISABLED';
|
||||
|
||||
const TWEMOJI_BASE_URL = '/twemoji'; // TODO
|
||||
export function getEmojiUrl(char: string): string {
|
||||
let codes = Array.from(char).flatMap(x => x.codePointAt(0)?.toString(16) ?? []);
|
||||
if (!codes.includes('200d')) codes = codes.filter(x => x !== 'fe0f');
|
||||
return `${TWEMOJI_BASE_URL}/${codes.join('-')}.svg`;
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ import * as css from '../styles/CustomHtml.css';
|
|||
import { getMxIdLocalPart, getRoomWithCanonicalAlias } from '../utils/matrix';
|
||||
import { getMemberDisplayName } from '../utils/room';
|
||||
import { EMOJI_PATTERN, URL_NEG_LB } from '../utils/regex';
|
||||
import { getHexcodeForEmoji, getShortcodeFor } from './emoji';
|
||||
import { getHexcodeForEmoji, getShortcodeFor, getEmojiUrl, isUsingTwemoji } from './emoji';
|
||||
import { findAndReplace } from '../utils/findAndReplace';
|
||||
|
||||
const ReactPrism = lazy(() => import('./react-prism/ReactPrism'));
|
||||
|
@ -39,13 +39,21 @@ const textToEmojifyJSX = (text: string): (string | JSX.Element)[] =>
|
|||
findAndReplace(
|
||||
text,
|
||||
EMOJI_REG_G,
|
||||
(match, pushIndex) => (
|
||||
<span key={pushIndex} className={css.EmoticonBase}>
|
||||
<span className={css.Emoticon()} title={getShortcodeFor(getHexcodeForEmoji(match[0]))}>
|
||||
{match[0]}
|
||||
</span>
|
||||
</span>
|
||||
),
|
||||
(match, pushIndex) => {
|
||||
const char = match[0];
|
||||
const className = css.Emoticon();
|
||||
const title = getShortcodeFor(getHexcodeForEmoji(char));
|
||||
return <span key={pushIndex} className={css.EmoticonBase}>{
|
||||
isUsingTwemoji() ? <img
|
||||
className={className}
|
||||
title={title}
|
||||
src={getEmojiUrl(char)}
|
||||
/> : <span
|
||||
className={className}
|
||||
title={title}
|
||||
>{match[0]}</span>
|
||||
}</span>;
|
||||
},
|
||||
(txt) => txt
|
||||
);
|
||||
|
||||
|
|
|
@ -1,12 +1,5 @@
|
|||
@use './app/partials/screen';
|
||||
|
||||
@font-face {
|
||||
font-family: Twemoji;
|
||||
src: url('../public/font/Twemoji.Mozilla.v0.7.0+sup39.240115.woff2'),
|
||||
url('../public/font/Twemoji.Mozilla.v0.7.0+sup39.240115.ttf');
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
:root {
|
||||
/* background color | --bg-[background type]: value */
|
||||
--bg-surface: #ffffff;
|
||||
|
|
1
twemoji
Submodule
1
twemoji
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 310184baaae6f797e9ef2650bea35187242ffafb
|
|
@ -33,6 +33,10 @@ const copyFiles = {
|
|||
src: 'public/res/android',
|
||||
dest: 'public/',
|
||||
},
|
||||
{
|
||||
src: 'twemoji/assets/svg/*',
|
||||
dest: 'twemoji/',
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue