diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..8f9bfed
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "twemoji"]
+ path = twemoji
+ url = https://github.com/jdecked/twemoji
diff --git a/package-lock.json b/package-lock.json
index 3dc4e73..afbbd9b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -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",
@@ -4189,18 +4189,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"
diff --git a/package.json b/package.json
index 4ae4f9c..eb1a062 100644
--- a/package.json
+++ b/package.json
@@ -34,8 +34,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",
diff --git a/public/font/Twemoji.Mozilla.v0.7.0+sup39.240115.ttf b/public/font/Twemoji.Mozilla.v0.7.0+sup39.240115.ttf
deleted file mode 100644
index e76d894..0000000
Binary files a/public/font/Twemoji.Mozilla.v0.7.0+sup39.240115.ttf and /dev/null differ
diff --git a/public/font/Twemoji.Mozilla.v0.7.0+sup39.240115.woff2 b/public/font/Twemoji.Mozilla.v0.7.0+sup39.240115.woff2
deleted file mode 100644
index 9099020..0000000
Binary files a/public/font/Twemoji.Mozilla.v0.7.0+sup39.240115.woff2 and /dev/null differ
diff --git a/src/app/components/editor/Elements.tsx b/src/app/components/editor/Elements.tsx
index c4767ab..3f4fd49 100644
--- a/src/app/components/editor/Elements.tsx
+++ b/src/app/components/editor/Elements.tsx
@@ -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() ? : element.key
)}
{children}
diff --git a/src/app/components/emoji-board/EmojiBoard.css.tsx b/src/app/components/emoji-board/EmojiBoard.css.tsx
index ba4ca4e..58e8431 100644
--- a/src/app/components/emoji-board/EmojiBoard.css.tsx
+++ b/src/app/components/emoji-board/EmojiBoard.css.tsx
@@ -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,
{
diff --git a/src/app/components/emoji-board/EmojiBoard.tsx b/src/app/components/emoji-board/EmojiBoard.tsx
index 5452722..56d0fad 100644
--- a/src/app/components/emoji-board/EmojiBoard.tsx
+++ b/src/app/components/emoji-board/EmojiBoard.tsx
@@ -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';
@@ -270,6 +278,13 @@ export const EmojiGroup = as<
));
+const NativeEmoji = (emoji: IEmoji) =>
+ isUsingTwemoji() ? : emoji.unicode;
+
export function EmojiItem({
label,
type,
@@ -440,7 +455,7 @@ export function RecentEmojiGroup({
data={emoji.unicode}
shortcode={emoji.shortcode}
>
- {emoji.unicode}
+ {NativeEmoji(emoji)}
))}
@@ -472,7 +487,7 @@ export function SearchEmojiGroup({
data={emoji.unicode}
shortcode={emoji.shortcode}
>
- {emoji.unicode}
+ {NativeEmoji(emoji)}
) : (
- {emoji.unicode}
+ {NativeEmoji(emoji)}
))}
diff --git a/src/app/plugins/emoji.ts b/src/app/plugins/emoji.ts
index 2462b7f..24217cc 100644
--- a/src/app/plugins/emoji.ts
+++ b/src/app/plugins/emoji.ts
@@ -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`;
+}
diff --git a/src/app/plugins/react-custom-html-parser.tsx b/src/app/plugins/react-custom-html-parser.tsx
index ee41687..2924961 100644
--- a/src/app/plugins/react-custom-html-parser.tsx
+++ b/src/app/plugins/react-custom-html-parser.tsx
@@ -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) => (
-
-
- {match[0]}
-
-
- ),
+ (match, pushIndex) => {
+ const char = match[0];
+ const className = css.Emoticon();
+ const title = getShortcodeFor(getHexcodeForEmoji(char));
+ return {
+ isUsingTwemoji() ? : {match[0]}
+ };
+ },
(txt) => txt
);
diff --git a/src/index.scss b/src/index.scss
index f7f286e..c3cd13c 100644
--- a/src/index.scss
+++ b/src/index.scss
@@ -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;
diff --git a/twemoji b/twemoji
new file mode 160000
index 0000000..310184b
--- /dev/null
+++ b/twemoji
@@ -0,0 +1 @@
+Subproject commit 310184baaae6f797e9ef2650bea35187242ffafb
diff --git a/vite.config.js b/vite.config.js
index 8357339..294bcfe 100644
--- a/vite.config.js
+++ b/vite.config.js
@@ -33,6 +33,10 @@ const copyFiles = {
src: 'public/res/android',
dest: 'public/',
},
+ {
+ src: 'twemoji/assets/svg/*',
+ dest: 'twemoji/',
+ },
],
}