diff --git a/public/locales/en.json b/public/locales/en.json index 291fd9c5..28655db8 100644 --- a/public/locales/en.json +++ b/public/locales/en.json @@ -1,4 +1,28 @@ { + "EmojiBoard": { + "sticker": "Sticker", + "emoji": "Emoji", + "search": "Search", + "search_or_react": "Search or Text Reaction", + "react": "React", + "no_sticker_packs": "No Sticker Packs!", + "add_stickers_hint": "Add stickers from user, room or space settings.", + "recent": "Recent", + "personal_pack": "Personal Pack", + "unknown": "Unknown", + "unknown_pack": "Unknown Pack", + "search_results": "Search Results", + "no_results": "No Results found", + "aria_emoji": "{{name}} emoji", + "cat_people": "Smileys & People", + "cat_nature": "Animals & Nature", + "cat_food": "Food & Drinks", + "cat_activity": "Activity", + "cat_travel": "Travel & Places", + "cat_object": "Objects", + "cat_symbol": "Symbols", + "cat_flag": "Flags" + }, "Organisms": { "RoomCommon": { "changed_room_name": " changed room name" diff --git a/public/locales/ru.json b/public/locales/ru.json index a0822c9f..d184ad3f 100644 --- a/public/locales/ru.json +++ b/public/locales/ru.json @@ -1,4 +1,28 @@ { + "EmojiBoard": { + "sticker": "Стикеры", + "emoji": "Эмодзи", + "search": "Поиск", + "search_or_react": "Поиск или текст-реакция", + "react": "Реакция", + "no_sticker_packs": "Нет наборов стикеров", + "add_stickers_hint": "Добавьте стикеры в настройках профиля, комнаты или пространства.", + "recent": "Недавние", + "personal_pack": "Личный набор", + "unknown": "Без названия", + "unknown_pack": "Набор без названия", + "search_results": "Результаты поиска", + "no_results": "Ничего не найдено", + "aria_emoji": "{{name}}, эмодзи", + "cat_people": "Смайлы и люди", + "cat_nature": "Животные и природа", + "cat_food": "Еда и напитки", + "cat_activity": "Активности", + "cat_travel": "Путешествия и места", + "cat_object": "Предметы", + "cat_symbol": "Символы", + "cat_flag": "Флаги" + }, "Organisms": { "RoomCommon": { "changed_room_name": " изменил(а) название комнаты" diff --git a/src/app/components/emoji-board/EmojiBoard.tsx b/src/app/components/emoji-board/EmojiBoard.tsx index be10a212..db371808 100644 --- a/src/app/components/emoji-board/EmojiBoard.tsx +++ b/src/app/components/emoji-board/EmojiBoard.tsx @@ -15,6 +15,7 @@ import { isKeyHotkey } from 'is-hotkey'; import { Room } from 'matrix-js-sdk'; import { atom, PrimitiveAtom, useAtom, useSetAtom } from 'jotai'; import { useVirtualizer } from '@tanstack/react-virtual'; +import { useTranslation } from 'react-i18next'; import { IEmoji } from '../../plugins/emoji'; import { emojiGroups, emojis } from '../../plugins/emoji-data'; import { useEmojiGroupLabels } from './useEmojiGroupLabels'; @@ -76,6 +77,7 @@ const useGroups = ( const recentEmojis = useRecentEmoji(mx, 21); const labels = useEmojiGroupLabels(); + const { t } = useTranslation(); const emojiGroupItems = useMemo(() => { const g: EmojiGroupItem[] = []; @@ -83,17 +85,18 @@ const useGroups = ( g.push({ id: RECENT_GROUP_ID, - name: 'Recent', + name: t('EmojiBoard.recent'), items: recentEmojis, }); imagePacks.forEach((pack) => { let label = pack.meta.name; - if (!label) label = isUserId(pack.id) ? 'Personal Pack' : mx.getRoom(pack.id)?.name; + if (!label) + label = isUserId(pack.id) ? t('EmojiBoard.personal_pack') : mx.getRoom(pack.id)?.name; g.push({ id: pack.id, - name: label ?? 'Unknown', + name: label ?? t('EmojiBoard.unknown'), items: pack .getImages(ImageUsage.Emoticon) .sort((a, b) => a.shortcode.localeCompare(b.shortcode)), @@ -109,7 +112,7 @@ const useGroups = ( }); return g; - }, [mx, recentEmojis, labels, imagePacks, tab]); + }, [mx, recentEmojis, labels, imagePacks, tab, t]); const stickerGroupItems = useMemo(() => { const g: StickerGroupItem[] = []; @@ -117,11 +120,12 @@ const useGroups = ( imagePacks.forEach((pack) => { let label = pack.meta.name; - if (!label) label = isUserId(pack.id) ? 'Personal Pack' : mx.getRoom(pack.id)?.name; + if (!label) + label = isUserId(pack.id) ? t('EmojiBoard.personal_pack') : mx.getRoom(pack.id)?.name; g.push({ id: pack.id, - name: label ?? 'Unknown', + name: label ?? t('EmojiBoard.unknown'), items: pack .getImages(ImageUsage.Sticker) .sort((a, b) => a.shortcode.localeCompare(b.shortcode)), @@ -129,7 +133,7 @@ const useGroups = ( }); return g; - }, [mx, imagePacks, tab]); + }, [mx, imagePacks, tab, t]); return [emojiGroupItems, stickerGroupItems]; }; @@ -178,6 +182,7 @@ function EmojiSidebar({ activeGroupAtom, packs, onScrollToGroup }: EmojiSidebarP const usage = ImageUsage.Emoticon; const labels = useEmojiGroupLabels(); const icons = useEmojiGroupIcons(); + const { t } = useTranslation(); const handleScrollToGroup = (groupId: string) => { setActiveGroupId(groupId); @@ -190,7 +195,7 @@ function EmojiSidebar({ activeGroupAtom, packs, onScrollToGroup }: EmojiSidebarP @@ -200,7 +205,8 @@ function EmojiSidebar({ activeGroupAtom, packs, onScrollToGroup }: EmojiSidebarP {packs.map((pack) => { let label = pack.meta.name; - if (!label) label = isUserId(pack.id) ? 'Personal Pack' : mx.getRoom(pack.id)?.name; + if (!label) + label = isUserId(pack.id) ? t('EmojiBoard.personal_pack') : mx.getRoom(pack.id)?.name; const url = mxcUrlToHttp(mx, pack.getAvatarUrl(usage) ?? '', useAuthentication) ?? undefined; @@ -210,7 +216,7 @@ function EmojiSidebar({ activeGroupAtom, packs, onScrollToGroup }: EmojiSidebarP key={pack.id} active={activeGroupId === pack.id} id={pack.id} - label={label ?? 'Unknown Pack'} + label={label ?? t('EmojiBoard.unknown_pack')} url={url} onClick={handleScrollToGroup} /> @@ -252,6 +258,7 @@ function StickerSidebar({ activeGroupAtom, packs, onScrollToGroup }: StickerSide const [activeGroupId, setActiveGroupId] = useAtom(activeGroupAtom); const usage = ImageUsage.Sticker; + const { t } = useTranslation(); const handleScrollToGroup = (groupId: string) => { setActiveGroupId(groupId); @@ -263,7 +270,8 @@ function StickerSidebar({ activeGroupAtom, packs, onScrollToGroup }: StickerSide {packs.map((pack) => { let label = pack.meta.name; - if (!label) label = isUserId(pack.id) ? 'Personal Pack' : mx.getRoom(pack.id)?.name; + if (!label) + label = isUserId(pack.id) ? t('EmojiBoard.personal_pack') : mx.getRoom(pack.id)?.name; const url = mxcUrlToHttp(mx, pack.getAvatarUrl(usage) ?? '', useAuthentication) ?? undefined; @@ -273,7 +281,7 @@ function StickerSidebar({ activeGroupAtom, packs, onScrollToGroup }: StickerSide key={pack.id} active={activeGroupId === pack.id} id={pack.id} - label={label ?? 'Unknown Pack'} + label={label ?? t('EmojiBoard.unknown_pack')} url={url} onClick={handleScrollToGroup} /> @@ -378,6 +386,7 @@ export function EmojiBoard({ addToRecentEmoji = true, }: EmojiBoardProps) { const mx = useMatrixClient(); + const { t } = useTranslation(); const emojiTab = tab === EmojiBoardTab.Emoji; const usage = emojiTab ? ImageUsage.Emoticon : ImageUsage.Sticker; @@ -542,7 +551,9 @@ export function EmojiBoard({ {searchedItems && ( {searchedItems.map(renderItem)} diff --git a/src/app/components/emoji-board/components/Item.tsx b/src/app/components/emoji-board/components/Item.tsx index cdc0679e..19acca22 100644 --- a/src/app/components/emoji-board/components/Item.tsx +++ b/src/app/components/emoji-board/components/Item.tsx @@ -1,5 +1,6 @@ import React from 'react'; import { Box } from 'folds'; +import { useTranslation } from 'react-i18next'; import { MatrixClient } from 'matrix-js-sdk'; import { EmojiItemInfo, EmojiType } from '../types'; import * as css from './styles.css'; @@ -27,6 +28,7 @@ type EmojiItemProps = { emoji: IEmoji; }; export function EmojiItem({ emoji }: EmojiItemProps) { + const { t } = useTranslation(); return ( - No Sticker Packs! + {t('EmojiBoard.no_sticker_packs')} - Add stickers from user, room or space settings. + {t('EmojiBoard.add_stickers_hint')} diff --git a/src/app/components/emoji-board/components/SearchInput.tsx b/src/app/components/emoji-board/components/SearchInput.tsx index 6de4d977..0a4f43a7 100644 --- a/src/app/components/emoji-board/components/SearchInput.tsx +++ b/src/app/components/emoji-board/components/SearchInput.tsx @@ -1,5 +1,6 @@ import React, { ChangeEventHandler, useRef } from 'react'; import { Input, Chip, Icon, Icons, Text } from 'folds'; +import { useTranslation } from 'react-i18next'; import { mobileOrTablet } from '../../../utils/user-agent'; type SearchInputProps = { @@ -15,6 +16,7 @@ export function SearchInput({ onTextCustomEmojiSelect, }: SearchInputProps) { const inputRef = useRef(null); + const { t } = useTranslation(); const handleReact = () => { const textEmoji = inputRef.current?.value.trim(); @@ -27,7 +29,7 @@ export function SearchInput({ ref={inputRef} variant="SurfaceVariant" size="400" - placeholder={allowTextCustomEmoji ? 'Search or Text Reaction ' : 'Search'} + placeholder={allowTextCustomEmoji ? t('EmojiBoard.search_or_react') : t('EmojiBoard.search')} maxLength={50} after={ allowTextCustomEmoji && query ? ( @@ -38,7 +40,7 @@ export function SearchInput({ outlined onClick={handleReact} > - React + {t('EmojiBoard.react')} ) : ( diff --git a/src/app/components/emoji-board/components/Tabs.tsx b/src/app/components/emoji-board/components/Tabs.tsx index d433354f..1f361590 100644 --- a/src/app/components/emoji-board/components/Tabs.tsx +++ b/src/app/components/emoji-board/components/Tabs.tsx @@ -1,5 +1,6 @@ import React, { CSSProperties } from 'react'; import { Badge, Box, Text } from 'folds'; +import { useTranslation } from 'react-i18next'; import { EmojiBoardTab } from '../types'; const styles: CSSProperties = { @@ -13,6 +14,7 @@ export function EmojiBoardTabs({ tab: EmojiBoardTab; onTabChange: (tab: EmojiBoardTab) => void; }) { + const { t } = useTranslation(); return ( onTabChange(EmojiBoardTab.Sticker)} > - Sticker + {t('EmojiBoard.sticker')} onTabChange(EmojiBoardTab.Emoji)} > - Emoji + {t('EmojiBoard.emoji')} diff --git a/src/app/components/emoji-board/useEmojiGroupLabels.ts b/src/app/components/emoji-board/useEmojiGroupLabels.ts index a1e5cf2c..6dd8143b 100644 --- a/src/app/components/emoji-board/useEmojiGroupLabels.ts +++ b/src/app/components/emoji-board/useEmojiGroupLabels.ts @@ -1,19 +1,22 @@ import { useMemo } from 'react'; +import { useTranslation } from 'react-i18next'; import { EmojiGroupId } from '../../plugins/emoji'; export type IEmojiGroupLabels = Record; -export const useEmojiGroupLabels = (): IEmojiGroupLabels => - useMemo( +export const useEmojiGroupLabels = (): IEmojiGroupLabels => { + const { t } = useTranslation(); + return useMemo( () => ({ - [EmojiGroupId.People]: 'Smileys & People', - [EmojiGroupId.Nature]: 'Animals & Nature', - [EmojiGroupId.Food]: 'Food & Drinks', - [EmojiGroupId.Activity]: 'Activity', - [EmojiGroupId.Travel]: 'Travel & Places', - [EmojiGroupId.Object]: 'Objects', - [EmojiGroupId.Symbol]: 'Symbols', - [EmojiGroupId.Flag]: 'Flags', + [EmojiGroupId.People]: t('EmojiBoard.cat_people'), + [EmojiGroupId.Nature]: t('EmojiBoard.cat_nature'), + [EmojiGroupId.Food]: t('EmojiBoard.cat_food'), + [EmojiGroupId.Activity]: t('EmojiBoard.cat_activity'), + [EmojiGroupId.Travel]: t('EmojiBoard.cat_travel'), + [EmojiGroupId.Object]: t('EmojiBoard.cat_object'), + [EmojiGroupId.Symbol]: t('EmojiBoard.cat_symbol'), + [EmojiGroupId.Flag]: t('EmojiBoard.cat_flag'), }), - [] + [t] ); +};