pl-fe: Support custom emoji categories
Signed-off-by: mkljczk <git@mkljczk.pl>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useState, useLayoutEffect, Suspense, useMemo } from 'react';
|
||||
import React, { useEffect, useLayoutEffect, useMemo, useState, Suspense } from 'react';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
|
||||
import { changeSetting, saveSettings } from 'pl-fe/actions/settings';
|
||||
@@ -8,7 +8,7 @@ import { useTheme } from 'pl-fe/hooks/use-theme';
|
||||
import { useCustomEmojis } from 'pl-fe/queries/instance/use-custom-emojis';
|
||||
import { useSettingsStore } from 'pl-fe/stores/settings';
|
||||
|
||||
import { buildCustomEmojis } from '../../emoji';
|
||||
import { buildCustomEmojiCategories } from '../../emoji';
|
||||
import { EmojiPicker } from '../../ui/util/async-components';
|
||||
|
||||
import type { CustomEmoji as BaseCustomEmoji } from 'pl-api';
|
||||
@@ -209,12 +209,16 @@ const EmojiPickerDropdown: React.FC<IEmojiPickerDropdown> = ({
|
||||
document.body.style.overflow = '';
|
||||
}, []);
|
||||
|
||||
const customEmojiCategories = useMemo(() => {
|
||||
return withCustom ? buildCustomEmojiCategories(customEmojis || [], intl) : undefined;
|
||||
}, [withCustom, customEmojis]);
|
||||
|
||||
return (
|
||||
visible ? (
|
||||
<RenderAfter update={update}>
|
||||
<Suspense>
|
||||
<EmojiPicker
|
||||
custom={withCustom ? [{ emojis: buildCustomEmojis(customEmojis || []) }] : undefined}
|
||||
custom={customEmojiCategories}
|
||||
title={title}
|
||||
onEmojiSelect={handlePick}
|
||||
recent={frequentlyUsedEmojis}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { IntlShape } from 'react-intl';
|
||||
|
||||
import type { Emoji as EmojiMart, CustomEmoji as EmojiMartCustom } from './data';
|
||||
import type { CustomEmoji as BaseCustomEmoji } from 'pl-api';
|
||||
|
||||
@@ -56,7 +58,7 @@ const validEmojiChar = (c: string) =>
|
||||
const buildCustomEmojis = (customEmojis: Array<BaseCustomEmoji>) => {
|
||||
const emojis: EmojiMart<EmojiMartCustom>[] = [];
|
||||
|
||||
customEmojis.forEach((emoji: any) => {
|
||||
customEmojis.forEach((emoji) => {
|
||||
const shortcode = emoji.shortcode;
|
||||
const url = emoji.static_url;
|
||||
const name = shortcode.replace(':', '');
|
||||
@@ -72,6 +74,39 @@ const buildCustomEmojis = (customEmojis: Array<BaseCustomEmoji>) => {
|
||||
return emojis;
|
||||
};
|
||||
|
||||
const buildCustomEmojiCategories = (customEmojis: Array<BaseCustomEmoji>, intl?: IntlShape) => {
|
||||
const emojiCategories: Record<string, EmojiMart<EmojiMartCustom>[]> = {};
|
||||
|
||||
for (const emoji of customEmojis) {
|
||||
const categoryName = emoji.category || 'uncategorized';
|
||||
if (!emojiCategories[categoryName]) {
|
||||
emojiCategories[categoryName] = [];
|
||||
}
|
||||
const category = emojiCategories[categoryName];
|
||||
|
||||
const shortcode = emoji.shortcode;
|
||||
const url = emoji.static_url;
|
||||
const name = shortcode.replace(':', '');
|
||||
|
||||
category.push({
|
||||
id: name,
|
||||
name,
|
||||
keywords: [name],
|
||||
skins: [{ src: url }],
|
||||
});
|
||||
}
|
||||
|
||||
return Object.entries(emojiCategories)
|
||||
.toSorted((a, b) => a[0].localeCompare(b[0]))
|
||||
.map(([categoryName, emojis]) => ({
|
||||
id: categoryName,
|
||||
name: categoryName === 'uncategorized' && intl
|
||||
? intl.formatMessage({ id: 'emoji_button.uncategorized', defaultMessage: 'Uncategorized' })
|
||||
: categoryName.replace(/^pack:/, ''),
|
||||
emojis,
|
||||
}));
|
||||
};
|
||||
|
||||
export {
|
||||
type CustomEmoji,
|
||||
type NativeEmoji,
|
||||
@@ -79,5 +114,6 @@ export {
|
||||
isCustomEmoji,
|
||||
isNativeEmoji,
|
||||
buildCustomEmojis,
|
||||
buildCustomEmojiCategories,
|
||||
validEmojiChar,
|
||||
};
|
||||
|
||||
@@ -691,6 +691,7 @@
|
||||
"emoji_button.skins_choose": "Choose default skin tone",
|
||||
"emoji_button.symbols": "Symbols",
|
||||
"emoji_button.travel": "Travel & Places",
|
||||
"emoji_button.uncategorized": "Uncategorized",
|
||||
"empty_column.account_blocked": "You are blocked by @{accountUsername}.",
|
||||
"empty_column.account_favourited_statuses": "This user doesn't have any liked posts yet.",
|
||||
"empty_column.account_timeline": "No posts here!",
|
||||
|
||||
Reference in New Issue
Block a user