pl-fe: allow using system emoji font

Signed-off-by: Nicole Mikołajczyk <git@mkljczk.pl>
This commit is contained in:
Nicole Mikołajczyk
2025-05-23 19:01:48 +02:00
parent e7e0e964af
commit 6d0116292e
7 changed files with 36 additions and 15 deletions

View File

@ -13,10 +13,12 @@ interface IEmoji {
}
const Emoji: React.FC<IEmoji> = ({ emoji, emojiMap, hovered }) => {
const { autoPlayGif } = useSettings();
const { autoPlayGif, systemEmojiFont } = useSettings();
// @ts-ignore
if (unicodeMapping[emoji]) {
if (systemEmojiFont) return <>{emoji}</>;
// @ts-ignore
const { filename, shortCode } = unicodeMapping[emoji];
const title = shortCode ? `:${shortCode}:` : '';

View File

@ -2,6 +2,7 @@ import React from 'react';
import { isCustomEmoji } from 'pl-fe/features/emoji';
import unicodeMapping from 'pl-fe/features/emoji/mapping';
import { useSettings } from 'pl-fe/hooks/use-settings';
import { joinPublicPath } from 'pl-fe/utils/static';
import type { Emoji } from 'pl-fe/features/emoji';
@ -11,29 +12,39 @@ interface IAutosuggestEmoji {
}
const AutosuggestEmoji: React.FC<IAutosuggestEmoji> = ({ emoji }) => {
let url, alt;
const { systemEmojiFont } = useSettings();
let emojiElement;
if (isCustomEmoji(emoji)) {
url = emoji.imageUrl;
alt = emoji.colons;
emojiElement = (
<img
className='emojione mr-2 block size-4'
src={emoji.imageUrl}
alt={emoji.colons}
/>
);
} else {
if (systemEmojiFont) emojiElement = <>{emoji.native}</>;
const mapping = unicodeMapping[emoji.native] || unicodeMapping[emoji.native.replace(/\uFE0F$/, '')];
if (!mapping) {
return null;
}
url = joinPublicPath(`packs/emoji/${mapping.unified}.svg`);
alt = emoji.native;
emojiElement = (
<img
className='emojione mr-2 block size-4'
src={joinPublicPath(`packs/emoji/${mapping.unified}.svg`)}
alt={emoji.native}
/>
);
}
return (
<div className='flex flex-row items-center justify-start text-sm leading-[18px]' data-testid='emoji'>
<img
className='emojione mr-2 block size-4'
src={url}
alt={alt}
/>
{emojiElement}
{emoji.colons}
</div>

View File

@ -13,7 +13,7 @@ interface IEmoji extends Pick<React.ImgHTMLAttributes<HTMLImageElement>, 'alt' |
/** A single emoji image. */
const Emoji: React.FC<IEmoji> = (props): JSX.Element | null => {
const { disableUserProvidedMedia } = useSettings();
const { disableUserProvidedMedia, systemEmojiFont } = useSettings();
const { emoji, alt, src, noGroup, ...rest } = props;
let filename;
@ -39,6 +39,8 @@ const Emoji: React.FC<IEmoji> = (props): JSX.Element | null => {
);
}
if (systemEmojiFont) return <>{emoji}</>;
return (
<img
draggable='false'

View File

@ -35,7 +35,7 @@ interface IEmojify {
}
const Emojify: React.FC<IEmojify> = React.memo(({ text, emojis = {} }) => {
const { disableUserProvidedMedia } = useSettings();
const { disableUserProvidedMedia, systemEmojiFont } = useSettings();
if (Array.isArray(emojis)) emojis = makeEmojiMap(emojis);
@ -63,7 +63,7 @@ const Emojify: React.FC<IEmojify> = React.memo(({ text, emojis = {} }) => {
// unqualified emojis aren't in emoji-mart's mappings so we just add FEOF
const unqualified = c + String.fromCodePoint(65039);
if (c in unicodeMapping) {
if (!systemEmojiFont && c in unicodeMapping) {
clearStack();
const { unified, shortcode } = unicodeMapping[c];
@ -71,7 +71,7 @@ const Emojify: React.FC<IEmojify> = React.memo(({ text, emojis = {} }) => {
nodes.push(
<img key={index} draggable={false} className='emojione transition-transform hover:scale-125' alt={c} title={`:${shortcode}:`} src={`/packs/emoji/${unified}.svg`} />,
);
} else if (unqualified in unicodeMapping) {
} else if (!systemEmojiFont && unqualified in unicodeMapping) {
clearStack();
const { unified, shortcode } = unicodeMapping[unqualified];

View File

@ -331,6 +331,10 @@ const Preferences = () => {
<SettingToggle settings={settings} settingPath={['systemFont']} onChange={onToggleChange} />
</ListItem>
<ListItem label={<FormattedMessage id='preferences.fields.system_emoji_font_label' defaultMessage='Use system emoji font' />}>
<SettingToggle settings={settings} settingPath={['systemEmojiFont']} onChange={onToggleChange} />
</ListItem>
<ListItem label={<FormattedMessage id='preferences.fields.reduce_motion_label' defaultMessage='Reduce motion in animations' />}>
<SettingToggle settings={settings} settingPath={['reduceMotion']} onChange={onToggleChange} />
</ListItem>

View File

@ -1355,6 +1355,7 @@
"preferences.fields.privacy_label": "Default post privacy",
"preferences.fields.reduce_motion_label": "Reduce motion in animations",
"preferences.fields.spoilers_display_label": "Automatically expand text behind spoilers",
"preferences.fields.system_emoji_font_label": "Use system emoji font",
"preferences.fields.system_font_label": "Use system's default font",
"preferences.fields.theme": "Theme",
"preferences.fields.theme_reset": "Reset theme",

View File

@ -59,6 +59,7 @@ const settingsSchema = v.object({
})), undefined),
systemFont: v.fallback(v.boolean(), false),
systemEmojiFont: v.fallback(v.boolean(), false),
demetricator: v.fallback(v.boolean(), false),
chats: coerceObject({