summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKagami Sascha Rosylight <saschanaz@outlook.com>2024-01-07 08:02:53 +0100
committerGitHub <noreply@github.com>2024-01-07 16:02:53 +0900
commit5e71418d5caca1cea333ee1b8629987cc69c4fbc (patch)
treeac591fa298bbe9ed5e5a2dcf311df3eec922e0a2
parentrefactor (diff)
downloadmisskey-5e71418d5caca1cea333ee1b8629987cc69c4fbc.tar.gz
misskey-5e71418d5caca1cea333ee1b8629987cc69c4fbc.tar.bz2
misskey-5e71418d5caca1cea333ee1b8629987cc69c4fbc.zip
fix(frontend/emoji) restore U+FE0F for simple emojis (#12866)
* fix(frontend/emoji) restore U+FE0F for simple emojis * Update CHANGELOG.md --------- Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
-rw-r--r--CHANGELOG.md1
-rw-r--r--packages/frontend/src/components/global/MkEmoji.vue10
-rw-r--r--packages/frontend/src/scripts/emojilist.ts7
-rw-r--r--packages/frontend/test/emoji.test.ts41
-rw-r--r--packages/frontend/test/init.ts24
5 files changed, 65 insertions, 18 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0d2fb4ccd5..474fcad674 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -21,6 +21,7 @@
### Client
- Feat: 新しいゲームを追加
- Enhance: ハッシュタグ入力時に、本文の末尾の行に何も書かれていない場合は新たにスペースを追加しないように
+- Fix: ネイティブモードの絵文字がモノクロにならないように
- Fix: v2023.12.0で追加された「モデレーターがユーザーのアイコンもしくはバナー画像を未設定状態にできる機能」が管理画面上で正しく表示されていない問題を修正
- Enhance: チャンネルノートのピン留めをノートのメニューからできるよ
diff --git a/packages/frontend/src/components/global/MkEmoji.vue b/packages/frontend/src/components/global/MkEmoji.vue
index 76ca8688d1..f6b21343b6 100644
--- a/packages/frontend/src/components/global/MkEmoji.vue
+++ b/packages/frontend/src/components/global/MkEmoji.vue
@@ -5,15 +5,14 @@ SPDX-License-Identifier: AGPL-3.0-only
<template>
<img v-if="!useOsNativeEmojis" :class="$style.root" :src="url" :alt="props.emoji" decoding="async" @pointerenter="computeTitle" @click="onClick"/>
-<span v-else-if="useOsNativeEmojis" :alt="props.emoji" @pointerenter="computeTitle" @click="onClick">{{ props.emoji }}</span>
-<span v-else>{{ emoji }}</span>
+<span v-else :alt="props.emoji" @pointerenter="computeTitle" @click="onClick">{{ colorizedNativeEmoji }}</span>
</template>
<script lang="ts" setup>
import { computed, inject } from 'vue';
import { char2twemojiFilePath, char2fluentEmojiFilePath } from '@/scripts/emoji-base.js';
import { defaultStore } from '@/store.js';
-import { getEmojiName } from '@/scripts/emojilist.js';
+import { colorizeEmoji, getEmojiName } from '@/scripts/emojilist.js';
import * as os from '@/os.js';
import copyToClipboard from '@/scripts/copy-to-clipboard.js';
import * as sound from '@/scripts/sound.js';
@@ -30,9 +29,8 @@ const react = inject<((name: string) => void) | null>('react', null);
const char2path = defaultStore.state.emojiStyle === 'twemoji' ? char2twemojiFilePath : char2fluentEmojiFilePath;
const useOsNativeEmojis = computed(() => defaultStore.state.emojiStyle === 'native');
-const url = computed(() => {
- return char2path(props.emoji);
-});
+const url = computed(() => char2path(props.emoji));
+const colorizedNativeEmoji = computed(() => colorizeEmoji(props.emoji));
// Searching from an array with 2000 items for every emoji felt like too energy-consuming, so I decided to do it lazily on pointerenter
function computeTitle(event: PointerEvent): void {
diff --git a/packages/frontend/src/scripts/emojilist.ts b/packages/frontend/src/scripts/emojilist.ts
index 8885bf4b7f..4bd8bf94be 100644
--- a/packages/frontend/src/scripts/emojilist.ts
+++ b/packages/frontend/src/scripts/emojilist.ts
@@ -36,7 +36,8 @@ for (let i = 0; i < emojilist.length; i++) {
export const emojiCharByCategory = _charGroupByCategory;
export function getEmojiName(char: string): string | null {
- const idx = _indexByChar.get(char);
+ // Colorize it because emojilist.json assumes that
+ const idx = _indexByChar.get(colorizeEmoji(char));
if (idx == null) {
return null;
} else {
@@ -44,6 +45,10 @@ export function getEmojiName(char: string): string | null {
}
}
+export function colorizeEmoji(char: string) {
+ return char.length === 1 ? `${char}\uFE0F` : char;
+}
+
export interface CustomEmojiFolderTree {
value: string;
category: string;
diff --git a/packages/frontend/test/emoji.test.ts b/packages/frontend/test/emoji.test.ts
new file mode 100644
index 0000000000..a1782a4913
--- /dev/null
+++ b/packages/frontend/test/emoji.test.ts
@@ -0,0 +1,41 @@
+/*
+ * SPDX-FileCopyrightText: syuilo and other misskey contributors
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+import { describe, test, assert, afterEach } from 'vitest';
+import { render, cleanup, type RenderResult } from '@testing-library/vue';
+import { defaultStoreState } from './init.js';
+import { getEmojiName } from '@/scripts/emojilist.js';
+import { components } from '@/components/index.js';
+import { directives } from '@/directives/index.js';
+import MkEmoji from '@/components/global/MkEmoji.vue';
+
+describe('Emoji', () => {
+ const renderEmoji = (emoji: string): RenderResult => {
+ return render(MkEmoji, {
+ props: { emoji },
+ global: { directives, components },
+ });
+ };
+
+ afterEach(() => {
+ cleanup();
+ defaultStoreState.emojiStyle = '';
+ });
+
+ describe('MkEmoji', () => {
+ test('Should render selector-less heart with color in native mode', async () => {
+ defaultStoreState.emojiStyle = 'native';
+ const mkEmoji = await renderEmoji('\u2764'); // monochrome heart
+ assert.ok(mkEmoji.queryByText('\u2764\uFE0F')); // colored heart
+ assert.ok(!mkEmoji.queryByText('\u2764'));
+ });
+ });
+
+ describe('Emoji list', () => {
+ test('Should get the name of the heart', () => {
+ assert.strictEqual(getEmojiName('\u2764'), 'heart');
+ });
+ });
+});
diff --git a/packages/frontend/test/init.ts b/packages/frontend/test/init.ts
index 6d93ff8cb0..f21248cfee 100644
--- a/packages/frontend/test/init.ts
+++ b/packages/frontend/test/init.ts
@@ -17,21 +17,23 @@ updateI18n(locales['en-US']);
// XXX: misskey-js panics if WebSocket is not defined
vi.stubGlobal('WebSocket', class WebSocket extends EventTarget { static CLOSING = 2; });
+export const defaultStoreState: Record<string, unknown> = {
+
+ // なんかtestがうまいこと動かないのでここに書く
+ dataSaver: {
+ media: false,
+ avatar: false,
+ urlPreview: false,
+ code: false,
+ },
+
+};
+
// XXX: defaultStore somehow becomes undefined in vitest?
vi.mock('@/store.js', () => {
return {
defaultStore: {
- state: {
-
- // なんかtestがうまいこと動かないのでここに書く
- dataSaver: {
- media: false,
- avatar: false,
- urlPreview: false,
- code: false,
- },
-
- },
+ state: defaultStoreState,
},
};
});