mirror of
https://github.com/glitch-soc/mastodon.git
synced 2025-12-15 08:48:53 +00:00
[Glitch] Fix inversion of emoji colours based on dark/light mode
Port 591776d7ad to glitch-soc
Signed-off-by: Claire <claire.github-309c@sitedethib.com>
This commit is contained in:
@@ -1,9 +1,14 @@
|
|||||||
import type { FC } from 'react';
|
import type { FC } from 'react';
|
||||||
import { useContext, useEffect, useState } from 'react';
|
import { useContext, useEffect, useState } from 'react';
|
||||||
|
|
||||||
|
import classNames from 'classnames';
|
||||||
|
|
||||||
import { EMOJI_TYPE_CUSTOM } from '@/flavours/glitch/features/emoji/constants';
|
import { EMOJI_TYPE_CUSTOM } from '@/flavours/glitch/features/emoji/constants';
|
||||||
import { useEmojiAppState } from '@/flavours/glitch/features/emoji/mode';
|
import { useEmojiAppState } from '@/flavours/glitch/features/emoji/mode';
|
||||||
import { unicodeHexToUrl } from '@/flavours/glitch/features/emoji/normalize';
|
import {
|
||||||
|
emojiToInversionClassName,
|
||||||
|
unicodeHexToUrl,
|
||||||
|
} from '@/flavours/glitch/features/emoji/normalize';
|
||||||
import {
|
import {
|
||||||
isStateLoaded,
|
isStateLoaded,
|
||||||
loadEmojiDataToState,
|
loadEmojiDataToState,
|
||||||
@@ -41,6 +46,9 @@ export const Emoji: FC<EmojiProps> = ({
|
|||||||
}, [appState.currentLocale, state]);
|
}, [appState.currentLocale, state]);
|
||||||
|
|
||||||
const animate = useContext(AnimateEmojiContext);
|
const animate = useContext(AnimateEmojiContext);
|
||||||
|
|
||||||
|
const inversionClass = emojiToInversionClassName(code);
|
||||||
|
|
||||||
const fallback = showFallback ? code : null;
|
const fallback = showFallback ? code : null;
|
||||||
|
|
||||||
// If the code is invalid or we otherwise know it's not valid, show the fallback.
|
// If the code is invalid or we otherwise know it's not valid, show the fallback.
|
||||||
@@ -79,7 +87,7 @@ export const Emoji: FC<EmojiProps> = ({
|
|||||||
src={src}
|
src={src}
|
||||||
alt={state.data.unicode}
|
alt={state.data.unicode}
|
||||||
title={state.data.label}
|
title={state.data.label}
|
||||||
className='emojione'
|
className={classNames('emojione', inversionClass)}
|
||||||
loading='lazy'
|
loading='lazy'
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -116,3 +116,29 @@ export const EMOJIS_WITH_LIGHT_BORDER = [
|
|||||||
'🪽', // 1FAE8
|
'🪽', // 1FAE8
|
||||||
'🪿', // 1FABF
|
'🪿', // 1FABF
|
||||||
];
|
];
|
||||||
|
|
||||||
|
export const EMOJIS_REQUIRING_INVERSION_IN_LIGHT_MODE = [
|
||||||
|
'⛓️', // 26D3-FE0F
|
||||||
|
];
|
||||||
|
|
||||||
|
export const EMOJIS_REQUIRING_INVERSION_IN_DARK_MODE = [
|
||||||
|
'🔜', // 1F51C
|
||||||
|
'🔙', // 1F519
|
||||||
|
'🔛', // 1F51B
|
||||||
|
'🔝', // 1F51D
|
||||||
|
'🔚', // 1F51A
|
||||||
|
'©️', // 00A9 FE0F
|
||||||
|
'➰', // 27B0
|
||||||
|
'💱', // 1F4B1
|
||||||
|
'✔️', // 2714 FE0F
|
||||||
|
'➗', // 2797
|
||||||
|
'💲', // 1F4B2
|
||||||
|
'➖', // 2796
|
||||||
|
'✖️', // 2716 FE0F
|
||||||
|
'➕', // 2795
|
||||||
|
'®️', // 00AE FE0F
|
||||||
|
'🕷️', // 1F577 FE0F
|
||||||
|
'📞', // 1F4DE
|
||||||
|
'™️', // 2122 FE0F
|
||||||
|
'〰️', // 3030 FE0F
|
||||||
|
];
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import Trie from 'substring-trie';
|
import Trie from 'substring-trie';
|
||||||
|
|
||||||
|
import { getUserTheme, isDarkMode } from '@/flavours/glitch/utils/theme';
|
||||||
import { assetHost } from 'flavours/glitch/utils/config';
|
import { assetHost } from 'flavours/glitch/utils/config';
|
||||||
|
|
||||||
import { autoPlayGif } from '../../initial_state';
|
import { autoPlayGif } from '../../initial_state';
|
||||||
@@ -97,9 +98,9 @@ const emojifyTextNode = (node, customEmojis) => {
|
|||||||
const { filename, shortCode } = unicodeMapping[unicode_emoji];
|
const { filename, shortCode } = unicodeMapping[unicode_emoji];
|
||||||
const title = shortCode ? `:${shortCode}:` : '';
|
const title = shortCode ? `:${shortCode}:` : '';
|
||||||
|
|
||||||
const isSystemTheme = !!document.body?.classList.contains('theme-system');
|
const isSystemTheme = getUserTheme() === 'system';
|
||||||
|
|
||||||
const theme = (isSystemTheme || document.body?.classList.contains('theme-mastodon-light')) ? 'light' : 'dark';
|
const theme = (isSystemTheme || !isDarkMode()) ? 'light' : 'dark';
|
||||||
|
|
||||||
const imageFilename = emojiFilename(filename, theme);
|
const imageFilename = emojiFilename(filename, theme);
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
import { createAppSelector, useAppSelector } from '@/flavours/glitch/store';
|
import { createAppSelector, useAppSelector } from '@/flavours/glitch/store';
|
||||||
import { isDevelopment } from '@/flavours/glitch/utils/environment';
|
import { isDevelopment } from '@/flavours/glitch/utils/environment';
|
||||||
|
import { isDarkMode } from '@/flavours/glitch/utils/theme';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
EMOJI_MODE_NATIVE,
|
EMOJI_MODE_NATIVE,
|
||||||
@@ -27,7 +28,7 @@ export function useEmojiAppState(): EmojiAppState {
|
|||||||
currentLocale: locale,
|
currentLocale: locale,
|
||||||
locales: [locale],
|
locales: [locale],
|
||||||
mode,
|
mode,
|
||||||
darkTheme: document.body.classList.contains('theme-default'),
|
darkTheme: isDarkMode(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ import {
|
|||||||
SKIN_TONE_CODES,
|
SKIN_TONE_CODES,
|
||||||
EMOJIS_WITH_DARK_BORDER,
|
EMOJIS_WITH_DARK_BORDER,
|
||||||
EMOJIS_WITH_LIGHT_BORDER,
|
EMOJIS_WITH_LIGHT_BORDER,
|
||||||
|
EMOJIS_REQUIRING_INVERSION_IN_LIGHT_MODE,
|
||||||
|
EMOJIS_REQUIRING_INVERSION_IN_DARK_MODE,
|
||||||
} from './constants';
|
} from './constants';
|
||||||
import type { CustomEmojiMapArg, ExtraCustomEmojiMap } from './types';
|
import type { CustomEmojiMapArg, ExtraCustomEmojiMap } from './types';
|
||||||
|
|
||||||
@@ -150,6 +152,16 @@ export function twemojiToUnicodeInfo(
|
|||||||
return hexNumbersToString(mappedCodes);
|
return hexNumbersToString(mappedCodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function emojiToInversionClassName(emoji: string): string | null {
|
||||||
|
if (EMOJIS_REQUIRING_INVERSION_IN_DARK_MODE.includes(emoji)) {
|
||||||
|
return 'invert-on-dark';
|
||||||
|
}
|
||||||
|
if (EMOJIS_REQUIRING_INVERSION_IN_LIGHT_MODE.includes(emoji)) {
|
||||||
|
return 'invert-on-light';
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
export function cleanExtraEmojis(extraEmojis?: CustomEmojiMapArg) {
|
export function cleanExtraEmojis(extraEmojis?: CustomEmojiMapArg) {
|
||||||
if (!extraEmojis) {
|
if (!extraEmojis) {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -1,2 +1 @@
|
|||||||
@use 'mastodon/variables';
|
|
||||||
@use 'common';
|
@use 'common';
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
@use 'mastodon/variables';
|
||||||
@use 'mastodon/mixins';
|
@use 'mastodon/mixins';
|
||||||
@use '@/styles/fonts/roboto';
|
@use '@/styles/fonts/roboto';
|
||||||
@use '@/styles/fonts/roboto-mono';
|
@use '@/styles/fonts/roboto-mono';
|
||||||
|
|||||||
@@ -1,3 +1,2 @@
|
|||||||
@use 'mastodon/variables';
|
|
||||||
@use 'common';
|
@use 'common';
|
||||||
@use 'mastodon/high-contrast';
|
@use 'mastodon/high-contrast';
|
||||||
|
|||||||
@@ -1,4 +1 @@
|
|||||||
@use 'mastodon/variables' with (
|
|
||||||
$emojis-requiring-inversion: 'chains'
|
|
||||||
);
|
|
||||||
@use 'common';
|
@use 'common';
|
||||||
|
|||||||
@@ -20,8 +20,3 @@ $no-columns-breakpoint: 600px;
|
|||||||
$font-sans-serif: 'mastodon-font-sans-serif' !default;
|
$font-sans-serif: 'mastodon-font-sans-serif' !default;
|
||||||
$font-display: 'mastodon-font-display' !default;
|
$font-display: 'mastodon-font-display' !default;
|
||||||
$font-monospace: 'mastodon-font-monospace' !default;
|
$font-monospace: 'mastodon-font-monospace' !default;
|
||||||
|
|
||||||
$emojis-requiring-inversion: 'back' 'copyright' 'curly_loop' 'currency_exchange'
|
|
||||||
'end' 'heavy_check_mark' 'heavy_division_sign' 'heavy_dollar_sign'
|
|
||||||
'heavy_minus_sign' 'heavy_multiplication_x' 'heavy_plus_sign' 'on'
|
|
||||||
'registered' 'soon' 'spider' 'telephone_receiver' 'tm' 'top' 'wavy_dash' !default;
|
|
||||||
|
|||||||
@@ -1,17 +1,3 @@
|
|||||||
@use 'variables' as *;
|
|
||||||
|
|
||||||
%emoji-color-inversion {
|
|
||||||
filter: invert(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.emojione {
|
|
||||||
@each $emoji in $emojis-requiring-inversion {
|
|
||||||
&[title=':#{$emoji}:'] {
|
|
||||||
@extend %emoji-color-inversion;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// glitch-soc addition
|
// glitch-soc addition
|
||||||
.hicolor-privacy-icons {
|
.hicolor-privacy-icons {
|
||||||
.status__visibility-icon.icon-globe,
|
.status__visibility-icon.icon-globe,
|
||||||
|
|||||||
@@ -1,3 +1,15 @@
|
|||||||
@function css-alpha($base-color, $amount) {
|
@function css-alpha($base-color, $amount) {
|
||||||
@return #{rgb(from $base-color r g b / $amount)};
|
@return #{rgb(from $base-color r g b / $amount)};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@mixin invert-on-light {
|
||||||
|
.invert-on-light {
|
||||||
|
filter: invert(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin invert-on-dark {
|
||||||
|
.invert-on-dark {
|
||||||
|
filter: invert(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
@use 'base';
|
@use 'base';
|
||||||
@use 'dark';
|
@use 'dark';
|
||||||
@use 'light';
|
@use 'light';
|
||||||
|
@use 'utils';
|
||||||
|
|
||||||
html {
|
html {
|
||||||
@include base.palette;
|
@include base.palette;
|
||||||
@@ -10,6 +11,7 @@ html {
|
|||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
@include dark.tokens;
|
@include dark.tokens;
|
||||||
|
@include utils.invert-on-dark;
|
||||||
|
|
||||||
@media (prefers-contrast: more) {
|
@media (prefers-contrast: more) {
|
||||||
@include dark.contrast-overrides;
|
@include dark.contrast-overrides;
|
||||||
@@ -18,6 +20,7 @@ html {
|
|||||||
|
|
||||||
@media (prefers-color-scheme: light) {
|
@media (prefers-color-scheme: light) {
|
||||||
@include light.tokens;
|
@include light.tokens;
|
||||||
|
@include utils.invert-on-light;
|
||||||
|
|
||||||
@media (prefers-contrast: more) {
|
@media (prefers-contrast: more) {
|
||||||
@include light.contrast-overrides;
|
@include light.contrast-overrides;
|
||||||
@@ -33,6 +36,7 @@ html:where(
|
|||||||
color-scheme: dark;
|
color-scheme: dark;
|
||||||
|
|
||||||
@include dark.tokens;
|
@include dark.tokens;
|
||||||
|
@include utils.invert-on-dark;
|
||||||
}
|
}
|
||||||
|
|
||||||
html[data-user-theme='contrast'],
|
html[data-user-theme='contrast'],
|
||||||
@@ -45,4 +49,5 @@ html:where([data-user-theme='mastodon-light']) {
|
|||||||
color-scheme: light;
|
color-scheme: light;
|
||||||
|
|
||||||
@include light.tokens;
|
@include light.tokens;
|
||||||
|
@include utils.invert-on-light;
|
||||||
}
|
}
|
||||||
|
|||||||
13
app/javascript/flavours/glitch/utils/theme.ts
Normal file
13
app/javascript/flavours/glitch/utils/theme.ts
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
export function getUserTheme() {
|
||||||
|
const { userTheme } = document.documentElement.dataset;
|
||||||
|
return userTheme;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isDarkMode() {
|
||||||
|
const { userTheme } = document.documentElement.dataset;
|
||||||
|
return (
|
||||||
|
(userTheme === 'system' &&
|
||||||
|
window.matchMedia('(prefers-color-scheme: dark)').matches) ||
|
||||||
|
userTheme !== 'mastodon-light'
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user