mirror of
				https://codeberg.org/yeentown/barkey.git
				synced 2025-11-04 15:34:13 +00:00 
			
		
		
		
	Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop
This commit is contained in:
		
						commit
						0d49e94982
					
				
					 5 changed files with 65 additions and 18 deletions
				
			
		| 
						 | 
				
			
			@ -21,6 +21,7 @@
 | 
			
		|||
### Client
 | 
			
		||||
- Feat: 新しいゲームを追加
 | 
			
		||||
- Enhance: ハッシュタグ入力時に、本文の末尾の行に何も書かれていない場合は新たにスペースを追加しないように
 | 
			
		||||
- Fix: ネイティブモードの絵文字がモノクロにならないように
 | 
			
		||||
- Fix: v2023.12.0で追加された「モデレーターがユーザーのアイコンもしくはバナー画像を未設定状態にできる機能」が管理画面上で正しく表示されていない問題を修正
 | 
			
		||||
- Enhance: チャンネルノートのピン留めをノートのメニューからできるよ
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										41
									
								
								packages/frontend/test/emoji.test.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								packages/frontend/test/emoji.test.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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');
 | 
			
		||||
		});
 | 
			
		||||
	});
 | 
			
		||||
});
 | 
			
		||||
| 
						 | 
				
			
			@ -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,
 | 
			
		||||
		},
 | 
			
		||||
	};
 | 
			
		||||
});
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue