diff --git a/public/locales/en/translation.json b/public/locales/en/translation.json
index a8c0c4f5..06b886e4 100644
--- a/public/locales/en/translation.json
+++ b/public/locales/en/translation.json
@@ -740,6 +740,57 @@
"restricted_unsupported": "Restricted (Unsupported: room required upgrade)",
"public": "Public (anyone can join)"
},
+ "RoomEmojis": {
+ "header": "Create Pack",
+ "submit_button": "Create pack",
+ "name_placeholder": "Pack Name",
+ "no_packs": "No emoji or sticker packs."
+ },
+ "ImagePack": {
+ "rename_title": "Rename",
+ "rename_button": "Rename",
+ "shortcode_label": "Shortcode",
+ "shortcode_name": "shortcode",
+ "delete_item_title": "Delete",
+ "delete_item_message": "Are you sure that you want to delete {{key}}?",
+ "delete_item_button": "Delete",
+ "delete_pack_title": "Delete Pack",
+ "delete_pack_message": "Are you sure that you want to delete {{pack_name}}?",
+ "delete_pack_button": "Delete",
+ "image_title": "Image",
+ "image_shortcode": "Shortcode",
+ "image_usage": "Usage",
+ "view_more": "View {{count}} more",
+ "view_less": "View less",
+ "use_globally": "Use globally",
+ "use_globally_description": "Add this pack to your account to use in all rooms.",
+ "no_global_packs": "No global packs",
+ "default_personal_pack_name": "Personal"
+ },
+ "ImagePackItem": {
+ "rename_tooltip": "Rename",
+ "delete_tooltip": "Delete"
+ },
+ "ImagePackUsageSelector": {
+ "header": "Usage",
+ "type_emoji": "Emoji",
+ "type_sticker": "Sticker",
+ "type_both": "Both"
+ },
+ "ImagePackUpload": {
+ "remove_file_tooltip": "Remove file",
+ "import_image_button": "Import image",
+ "shortcode_placeholder": "shortcode",
+ "upload_button": "Upload",
+ "upload_button_progress": "Uploading..."
+ },
+ "ImagePackProfile": {
+ "attribution_prompt": "Attribution",
+ "name_prompt": "Name",
+ "edit_tooltip": "Edit",
+ "usage_header": "Usage",
+ "pack_usage": "Pack usage"
+ },
"SpaceAddExisting": {
"adding_items_one": "Adding one item...",
"adding_items_other": "Adding {{count}} items...",
diff --git a/src/app/molecules/image-pack/ImagePack.jsx b/src/app/molecules/image-pack/ImagePack.jsx
index 725291d1..89b23018 100644
--- a/src/app/molecules/image-pack/ImagePack.jsx
+++ b/src/app/molecules/image-pack/ImagePack.jsx
@@ -3,6 +3,7 @@ import React, {
} from 'react';
import PropTypes from 'prop-types';
import './ImagePack.scss';
+import { useTranslation } from 'react-i18next';
import initMatrix from '../../../client/initMatrix';
import { openReusableDialog } from '../../../client/action/navigation';
@@ -19,12 +20,14 @@ import { confirmDialog } from '../confirm-dialog/ConfirmDialog';
import ImagePackProfile from './ImagePackProfile';
import ImagePackItem from './ImagePackItem';
import ImagePackUpload from './ImagePackUpload';
+import '../../i18n';
const renameImagePackItem = (shortcode) => new Promise((resolve) => {
let isCompleted = false;
+ const { t } = useTranslation();
openReusableDialog(
- Rename ,
+ {t('Molecules.ImagePack.rename_title')} ,
(requestClose) => (
),
@@ -94,11 +97,12 @@ function useRoomImagePack(roomId, stateKey) {
}
function useUserImagePack() {
+ const { t } = useTranslation();
const mx = initMatrix.matrixClient;
const packEvent = mx.getAccountData('im.ponies.user_emotes');
const pack = useMemo(() => (
ImagePackBuilder.parsePack(mx.getUserId(), packEvent?.getContent() ?? {
- pack: { display_name: 'Personal' },
+ pack: { display_name: t('Molecules.ImagePack.default_personal_pack_name') },
images: {},
})
), []);
@@ -115,6 +119,7 @@ function useUserImagePack() {
function useImagePackHandles(pack, sendPackContent) {
const [, forceUpdate] = useReducer((count) => count + 1, 0);
+ const { t } = useTranslation();
const getNewKey = (key) => {
if (typeof key !== 'string') return undefined;
@@ -161,9 +166,9 @@ function useImagePackHandles(pack, sendPackContent) {
};
const handleDeleteItem = async (key) => {
const isConfirmed = await confirmDialog(
- 'Delete',
- `Are you sure that you want to delete "${key}"?`,
- 'Delete',
+ t('Molecules.ImagePack.delete_item_title'),
+ t('Molecules.ImagePack.delete_item_message', { key }),
+ t('Molecules.ImagePack.delete_item_button'),
'danger',
);
if (!isConfirmed) return;
@@ -227,6 +232,7 @@ function ImagePack({ roomId, stateKey, handlePackDelete }) {
const room = mx.getRoom(roomId);
const [viewMore, setViewMore] = useState(false);
const [isGlobal, setIsGlobal] = useState(isGlobalPack(roomId, stateKey));
+ const { t } = useTranslation();
const { pack, sendPackContent } = useRoomImagePack(roomId, stateKey);
@@ -251,9 +257,9 @@ function ImagePack({ roomId, stateKey, handlePackDelete }) {
const handleDeletePack = async () => {
const isConfirmed = await confirmDialog(
- 'Delete Pack',
- `Are you sure that you want to delete "${pack.displayName}"?`,
- 'Delete',
+ t('Molecules.ImagePack.delete_pack_title'),
+ t('Molecules.ImagePack.delete_pack_message', { pack_name: pack.displayName }),
+ t('Molecules.ImagePack.delete_pack_button'),
'danger',
);
if (!isConfirmed) return;
@@ -279,9 +285,9 @@ function ImagePack({ roomId, stateKey, handlePackDelete }) {
{ images.length === 0 ? null : (
- Image
- Shortcode
- Usage
+ {t('Molecules.ImagePack.image_title')}
+ {t('Molecules.ImagePack.image_shortcode')}
+ {t('Molecules.ImagePack.image_usage')}
{images.map(([shortcode, image]) => (
setViewMore(!viewMore)}>
{
viewMore
- ? 'View less'
- : `View ${pack.images.size - 2} more`
+ ? t('Molecules.ImagePack.view_less')
+ : t('Molecules.ImagePack.view_more', { count: pack.images.size - 2 })
}
)}
- { handlePackDelete && Delete Pack }
+ { handlePackDelete && {t('Molecules.ImagePack.delete_pack_title')} }
)}
- Use globally
- Add this pack to your account to use in all rooms.
+ {t('Molecules.ImagePack.use_globally')}
+ {t('Molecules.ImagePack.use_globally_description')}
@@ -333,6 +339,7 @@ ImagePack.propTypes = {
function ImagePackUser() {
const mx = initMatrix.matrixClient;
const [viewMore, setViewMore] = useState(false);
+ const { t } = useTranslation();
const { pack, sendPackContent } = useUserImagePack();
@@ -363,9 +370,9 @@ function ImagePackUser() {
{ images.length === 0 ? null : (
- Image
- Shortcode
- Usage
+ {t('Molecules.ImagePack.image_title')}
+ {t('Molecules.ImagePack.image_shortcode')}
+ {t('Molecules.ImagePack.image_usage')}
{images.map(([shortcode, image]) => (
setViewMore(!viewMore)}>
{
viewMore
- ? 'View less'
- : `View ${pack.images.size - 2} more`
+ ? t('Molecules.ImagePack.view_less')
+ : t('Molecules.ImagePack.view_more', { count: pack.images.size - 2 })
+
}
@@ -427,6 +435,7 @@ function useGlobalImagePack() {
function ImagePackGlobal() {
const mx = initMatrix.matrixClient;
const roomIdToStateKeys = useGlobalImagePack();
+ const { t } = useTranslation();
const handleChange = (roomId, stateKey) => {
removeGlobalImagePack(mx, roomId, stateKey);
@@ -457,7 +466,7 @@ function ImagePackGlobal() {
})
);
})
- : No global packs
+ : {t('Molecules.ImagePack.no_global_packs')}
}
diff --git a/src/app/molecules/image-pack/ImagePackItem.jsx b/src/app/molecules/image-pack/ImagePackItem.jsx
index 27436793..aaf18845 100644
--- a/src/app/molecules/image-pack/ImagePackItem.jsx
+++ b/src/app/molecules/image-pack/ImagePackItem.jsx
@@ -2,6 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types';
import './ImagePackItem.scss';
+import { useTranslation } from 'react-i18next';
import { openReusableContextMenu } from '../../../client/action/navigation';
import { getEventCords } from '../../../util/common';
@@ -16,9 +17,12 @@ import ChevronBottomIC from '../../../../public/res/ic/outlined/chevron-bottom.s
import PencilIC from '../../../../public/res/ic/outlined/pencil.svg';
import BinIC from '../../../../public/res/ic/outlined/bin.svg';
+import '../../i18n';
+
function ImagePackItem({
url, shortcode, usage, onUsageChange, onDelete, onRename,
}) {
+ const { t } = useTranslation();
const handleUsageSelect = (event) => {
openReusableContextMenu(
'bottom',
@@ -43,15 +47,15 @@ function ImagePackItem({
- {onRename && onRename(shortcode)} />}
- {onDelete && onDelete(shortcode)} />}
+ {onRename && onRename(shortcode)} />}
+ {onDelete && onDelete(shortcode)} />}
{onUsageChange && }
- {usage === 'emoticon' && 'Emoji'}
- {usage === 'sticker' && 'Sticker'}
- {usage === 'both' && 'Both'}
+ {usage === 'emoticon' && t('Molecules.ImagePackUsageSelector.type_emoji')}
+ {usage === 'sticker' && t('Molecules.ImagePackUsageSelector.type_sticker')}
+ {usage === 'both' && t('Molecules.ImagePackUsageSelector.type_both')}
diff --git a/src/app/molecules/image-pack/ImagePackProfile.jsx b/src/app/molecules/image-pack/ImagePackProfile.jsx
index b639936d..eba81dcd 100644
--- a/src/app/molecules/image-pack/ImagePackProfile.jsx
+++ b/src/app/molecules/image-pack/ImagePackProfile.jsx
@@ -2,6 +2,7 @@ import React, { useState } from 'react';
import PropTypes from 'prop-types';
import './ImagePackProfile.scss';
+import { useTranslation } from 'react-i18next';
import { openReusableContextMenu } from '../../../client/action/navigation';
import { getEventCords } from '../../../util/common';
@@ -16,11 +17,14 @@ import ImagePackUsageSelector from './ImagePackUsageSelector';
import ChevronBottomIC from '../../../../public/res/ic/outlined/chevron-bottom.svg';
import PencilIC from '../../../../public/res/ic/outlined/pencil.svg';
+import '../../i18n';
+
function ImagePackProfile({
avatarUrl, displayName, attribution, usage,
onUsageChange, onAvatarChange, onEditProfile,
}) {
const [isEdit, setIsEdit] = useState(false);
+ const { t } = useTranslation();
const handleSubmit = (e) => {
e.preventDefault();
@@ -70,18 +74,18 @@ function ImagePackProfile({
isEdit
? (
) : (
<>
{displayName}
- {onEditProfile && setIsEdit(true)} src={PencilIC} tooltip="Edit" />}
+ {onEditProfile && setIsEdit(true)} src={PencilIC} tooltip={t('Molecules.ImagePackProfile.edit_tooltip')} />}
{attribution && {attribution} }
>
@@ -89,15 +93,15 @@ function ImagePackProfile({
}
- Pack usage
+ {t('Molecules.ImagePackProfile.pack_usage')}
- {usage === 'emoticon' && 'Emoji'}
- {usage === 'sticker' && 'Sticker'}
- {usage === 'both' && 'Both'}
+ {usage === 'emoticon' && t('Molecules.ImagePackUsageSelector.type_emoji')}
+ {usage === 'sticker' && t('Molecules.ImagePackUsageSelector.type_sticker')}
+ {usage === 'both' && t('Molecules.ImagePackUsageSelector.type_both')}
diff --git a/src/app/molecules/image-pack/ImagePackUpload.jsx b/src/app/molecules/image-pack/ImagePackUpload.jsx
index 9358856d..645d5d77 100644
--- a/src/app/molecules/image-pack/ImagePackUpload.jsx
+++ b/src/app/molecules/image-pack/ImagePackUpload.jsx
@@ -2,6 +2,7 @@ import React, { useState, useRef } from 'react';
import PropTypes from 'prop-types';
import './ImagePackUpload.scss';
+import { useTranslation } from 'react-i18next';
import initMatrix from '../../../client/initMatrix';
import { scaleDownImage } from '../../../util/common';
@@ -10,6 +11,7 @@ import Button from '../../atoms/button/Button';
import Input from '../../atoms/input/Input';
import IconButton from '../../atoms/button/IconButton';
import CirclePlusIC from '../../../../public/res/ic/outlined/circle-plus.svg';
+import '../../i18n';
function ImagePackUpload({ onUpload }) {
const mx = initMatrix.matrixClient;
@@ -17,6 +19,7 @@ function ImagePackUpload({ onUpload }) {
const shortcodeRef = useRef(null);
const [imgFile, setImgFile] = useState(null);
const [progress, setProgress] = useState(false);
+ const { t } = useTranslation();
const handleSubmit = async (evt) => {
evt.preventDefault();
@@ -55,14 +58,14 @@ function ImagePackUpload({ onUpload }) {
imgFile
? (
-
+
{imgFile.name}
)
- : inputRef.current.click()}>Import image
+ : inputRef.current.click()}>{t('Molecules.ImagePackUpload.import_image_button')}
}
-
- {progress ? 'Uploading...' : 'Upload'}
+
+ {progress ? t('Molecules.ImagePackUpload.upload_button_progress') : t('Molecules.ImagePackUpload.upload_button')}
);
}
diff --git a/src/app/molecules/image-pack/ImagePackUsageSelector.jsx b/src/app/molecules/image-pack/ImagePackUsageSelector.jsx
index 279b3816..b6cc99d4 100644
--- a/src/app/molecules/image-pack/ImagePackUsageSelector.jsx
+++ b/src/app/molecules/image-pack/ImagePackUsageSelector.jsx
@@ -1,33 +1,36 @@
import React from 'react';
import PropTypes from 'prop-types';
+import { useTranslation } from 'react-i18next';
import { MenuHeader, MenuItem } from '../../atoms/context-menu/ContextMenu';
import CheckIC from '../../../../public/res/ic/outlined/check.svg';
+import '../../i18n';
function ImagePackUsageSelector({ usage, onSelect }) {
+ const { t } = useTranslation();
return (
- Usage
+ {t('Molecules.ImagePackUsageSelector.header')}
onSelect('emoticon')}
>
- Emoji
+ {t('Molecules.ImagePackUsageSelector.type_emoji')}
onSelect('sticker')}
>
- Sticker
+ {t('Molecules.ImagePackUsageSelector.type_sticker')}
onSelect('both')}
>
- Both
+ {t('Molecules.ImagePackUsageSelector.type_both')}
);
diff --git a/src/app/molecules/room-emojis/RoomEmojis.jsx b/src/app/molecules/room-emojis/RoomEmojis.jsx
index 81cee0a8..5c7c1101 100644
--- a/src/app/molecules/room-emojis/RoomEmojis.jsx
+++ b/src/app/molecules/room-emojis/RoomEmojis.jsx
@@ -1,6 +1,7 @@
import React, { useReducer, useEffect } from 'react';
import PropTypes from 'prop-types';
import './RoomEmojis.scss';
+import { useTranslation } from 'react-i18next';
import initMatrix from '../../../client/initMatrix';
import { suffixRename } from '../../../util/common';
@@ -10,6 +11,7 @@ import Text from '../../atoms/text/Text';
import Input from '../../atoms/input/Input';
import Button from '../../atoms/button/Button';
import ImagePack from '../image-pack/ImagePack';
+import '../../i18n';
function useRoomPacks(room) {
const mx = initMatrix.matrixClient;
@@ -79,6 +81,7 @@ function RoomEmojis({ roomId }) {
const room = mx.getRoom(roomId);
const { usablePacks, createPack, deletePack } = useRoomPacks(room);
+ const { t } = useTranslation();
const myPowerlevel = room.getMember(mx.getUserId())?.powerLevel || 0;
const canChange = room.currentState.hasSufficientPowerLevelFor('state_default', myPowerlevel);
@@ -97,10 +100,10 @@ function RoomEmojis({ roomId }) {
{ canChange && (
- Create Pack
+ {t('Molecules.RoomEmojis.header')}
)}
@@ -115,7 +118,7 @@ function RoomEmojis({ roomId }) {
/>
)) : (
- No emoji or sticker pack.
+ {t('Molecules.RoomEmojis.no_packs')}
)
}