From 148120a1d454e6634ac0797093434d756b194ea9 Mon Sep 17 00:00:00 2001 From: "v.lagerev" Date: Tue, 14 Apr 2026 21:27:03 +0300 Subject: [PATCH] localize room settings --- public/locales/en.json | 223 ++++++++++++++++++ public/locales/ru.json | 223 ++++++++++++++++++ src/app/components/AccountDataEditor.tsx | 20 +- src/app/components/JoinRulesSwitcher.tsx | 24 +- .../image-pack-view/ImagePackContent.tsx | 24 +- .../image-pack-view/ImagePackView.tsx | 4 +- .../components/image-pack-view/ImageTile.tsx | 15 +- .../components/image-pack-view/PackMeta.tsx | 28 ++- .../image-pack-view/UsageSwitcher.tsx | 10 +- .../developer-tools/DevelopTools.tsx | 50 ++-- .../developer-tools/SendRoomEvent.tsx | 12 +- .../developer-tools/StateEventEditor.tsx | 18 +- .../emojis-stickers/EmojisStickers.tsx | 4 +- .../emojis-stickers/RoomPacks.tsx | 27 ++- .../common-settings/general/RoomAddress.tsx | 45 ++-- .../general/RoomEncryption.tsx | 18 +- .../general/RoomHistoryVisibility.tsx | 22 +- .../common-settings/general/RoomJoinRules.tsx | 8 +- .../common-settings/general/RoomProfile.tsx | 25 +- .../common-settings/general/RoomPublish.tsx | 8 +- .../common-settings/general/RoomUpgrade.tsx | 23 +- .../common-settings/members/Members.tsx | 14 +- .../permissions/PermissionGroups.tsx | 18 +- .../common-settings/permissions/Powers.tsx | 12 +- .../permissions/PowersEditor.tsx | 53 +++-- .../features/room-settings/RoomSettings.tsx | 19 +- .../room-settings/general/General.tsx | 10 +- .../room-settings/permissions/Permissions.tsx | 4 +- .../permissions/usePermissionItems.ts | 68 +++--- src/app/hooks/useMemberFilter.ts | 19 +- src/app/hooks/useMemberSort.ts | 19 +- src/app/hooks/usePowerLevelTags.ts | 44 ++-- src/app/hooks/useRoomCreatorsTag.ts | 16 +- 33 files changed, 836 insertions(+), 291 deletions(-) diff --git a/public/locales/en.json b/public/locales/en.json index d360962d..b8be7e7b 100644 --- a/public/locales/en.json +++ b/public/locales/en.json @@ -607,5 +607,228 @@ "existing_space": "Existing Space", "add_room": "Add Room", "existing_room": "Existing Room" + }, + + "RoomSettings": { + "general": "General", + "members": "Members", + "permissions": "Permissions", + "emojis_stickers": "Emojis & Stickers", + "developer_tools": "Developer Tools", + + "profile": "Profile", + "edit": "Edit", + "unknown": "Unknown", + "avatar": "Avatar", + "upload": "Upload", + "reset": "Reset", + "remove": "Remove", + "name": "Name", + "topic": "Topic", + "save": "Save", + "cancel": "Cancel", + + "options": "Options", + "addresses": "Addresses", + "advanced_options": "Advanced Options", + + "space_access": "Space Access", + "room_access": "Room Access", + "space_access_desc": "Change how people can join the space.", + "room_access_desc": "Change how people can join the room.", + + "join_invite_only": "Invite Only", + "join_knock_invite": "Knock & Invite", + "join_space_members_or_knock": "Space Members or Knock", + "join_space_members": "Space Members", + "join_public": "Public", + "join_unsupported": "Unsupported", + + "history_visibility": "Message History Visibility", + "history_visibility_desc": "Changes to history visibility will only apply to future messages and will not affect existing history.", + "visibility_after_invite": "After Invite", + "visibility_after_join": "After Join", + "visibility_all_messages": "All Messages", + "visibility_all_messages_guests": "All Messages (Guests)", + + "room_encryption": "Room Encryption", + "encryption_enabled_desc": "Messages in this room are protected by end-to-end encryption.", + "encryption_disabled_desc": "Once enabled, encryption cannot be disabled!", + "enabled": "Enabled", + "enable": "Enable", + "enable_encryption": "Enable Encryption", + "enable_encryption_confirm": "Are you sure? Once enabled, encryption cannot be disabled!", + "enable_e2e_encryption": "Enable E2E Encryption", + + "publish_to_directory": "Publish to Directory", + "publish_space_desc": "List the space in the public directory to make it discoverable by others.", + "publish_room_desc": "List the room in the public directory to make it discoverable by others.", + + "published_addresses": "Published Addresses", + "published_addresses_desc": "If access is Public, Published addresses will be used to join by anyone.", + "no_addresses": "No Addresses", + "no_addresses_hint": "To publish an address, it needs to be set as a local address first", + "main": "Main", + "unset_main": "Unset Main", + "set_main": "Set Main", + "address_in_use": "Address is already in use!", + "published": "Published", + "unpublish": "Unpublish", + "publish": "Publish", + "delete": "Delete", + "selected_count": "{{count}} Selected", + + "local_addresses": "Local Addresses", + "local_addresses_desc": "Set local address so users can join through your homeserver.", + "collapse": "Collapse", + "expand": "Expand", + "loading": "Loading...", + + "space_upgrade": "Space Upgrade", + "room_upgrade": "Room Upgrade", + "upgrade": "Upgrade", + "action_irreversible": "This action is irreversible!", + "upgrade_space": "Upgrade Space", + "upgrade_room": "Upgrade Room", + "space_replaced": "This space has been replaced!", + "room_replaced": "This room has been replaced!", + "current_version": "Current version: {{version}}.", + "old_space": "Old Space", + "old_room": "Old Room", + "open_new_space": "Open New Space", + "open_new_room": "Open New Room", + + "members_count": "{{count}} Members", + "search": "Search", + "no_results": "No Results", + "results_count": "{{count}} Results", + "scroll_to_top": "Scroll to Top", + "no_membership_members": "No \"{{filter}}\" Members", + + "filter_joined": "Joined", + "filter_invited": "Invited", + "filter_left": "Left", + "filter_kicked": "Kicked", + "filter_banned": "Banned", + + "sort_a_to_z": "A to Z", + "sort_z_to_a": "Z to A", + "sort_newest": "Newest", + "sort_oldest": "Oldest", + + "perm_messages": "Messages", + "perm_send_messages": "Send Messages", + "perm_send_stickers": "Send Stickers", + "perm_send_reactions": "Send Reactions", + "perm_ping_room": "Ping @room", + "perm_pin_messages": "Pin Messages", + "perm_other_message_events": "Other Message Events", + "perm_calls": "Calls", + "perm_join_call": "Join Call", + "perm_moderation": "Moderation", + "perm_invite": "Invite", + "perm_kick": "Kick", + "perm_ban": "Ban", + "perm_delete_others_messages": "Delete Others' Messages", + "perm_delete_self_messages": "Delete Self Messages", + "perm_room_overview": "Room Overview", + "perm_room_avatar": "Room Avatar", + "perm_room_name": "Room Name", + "perm_room_topic": "Room Topic", + "perm_settings": "Settings", + "perm_change_room_access": "Change Room Access", + "perm_publish_address": "Publish Address", + "perm_change_all_permission": "Change All Permissions", + "perm_edit_power_levels": "Edit Power Levels", + "perm_enable_encryption": "Enable Encryption", + "perm_history_visibility": "History Visibility", + "perm_upgrade_room": "Upgrade Room", + "perm_other_settings": "Other Settings", + "perm_other": "Other", + "perm_manage_emojis_stickers": "Manage Emojis & Stickers", + "perm_change_server_acls": "Change Server ACLs", + "perm_modify_widgets": "Modify Widgets", + + "founders": "Founders", + "founders_desc": "Founding members have all permissions and can only be changed during a room upgrade.", + "power_levels": "Power Levels", + "power_levels_desc": "Manage and customize incremental power levels for users.", + + "new_power_level": "New Power Level", + "new_power_level_desc": "Create a new power level.", + "power_level_placeholder": "Bot", + "create": "Create", + "color": "Color", + "pick": "Pick", + "power": "Power", + "icon": "Icon", + "import": "Import", + "undo": "Undo", + "used_power_level": "Used Power Level", + "used_power_level_desc": "You have to remove its use before you can delete it.", + "changes_saved": "Changes saved! Apply when ready.", + "failed_to_apply": "Failed to apply changes! Please try again.", + "apply_changes": "Apply Changes", + "and_above": "& Above", + + "users": "Users", + "default_power": "Default Power", + "default_power_desc": "Default power level for all users.", + + "packs": "Packs", + "new_pack": "New Pack", + "new_pack_desc": "Add your own emoji and sticker pack to use in room.", + "no_packs": "No Packs", + "no_packs_desc": "There are no emoji or sticker packs to display at the moment.", + "view": "View", + "failed_to_remove_packs": "Failed to remove packs! Please try again.", + "delete_selected_packs": "Delete selected packs. ({{count}} selected)", + + "enable_developer_tools": "Enable Developer Tools", + "room_id": "Room ID", + "room_id_desc": "Copy room ID to clipboard.", + "copy": "Copy", + "data": "Data", + "new_message_event": "New Message Event", + "new_message_event_desc": "Create and send a new message event within the room.", + "compose": "Compose", + "room_state": "Room State", + "room_state_desc": "State events of the room.", + "events": "Events", + "total": "Total: {{count}}", + "add_new": "Add New", + "default_key": "Default", + "account_data": "Account Data", + "account_data_desc": "Private personalization data stored within room.", + "state_event": "State Event", + "json_content": "JSON Content", + "state_event_type": "State Event Type", + "message_event_type": "Message Event Type", + "send": "Send", + "state_key_optional": "State Key (Optional)", + + "pack": "Pack", + "images_usage": "Images Usage", + "images_usage_desc": "Select how the images are being used: as emojis, as stickers, or as both.", + "images": "Images", + "upload_images": "Upload Images", + "upload_images_desc": "Select images from your storage to upload them in pack.", + "select": "Select", + "pack_avatar": "Pack Avatar", + "attribution": "Attribution", + "shortcode": "Shortcode:", + "body": "Body:", + "usage_both": "Both", + "usage_sticker": "Sticker", + "usage_emoji": "Emoji", + + "power_goku": "Goku", + "power_manager": "Manager", + "power_founder": "Founder", + "power_admin": "Admin", + "power_moderator": "Moderator", + "power_member": "Member", + "power_muted": "Muted", + "power_team": "Team" } } diff --git a/public/locales/ru.json b/public/locales/ru.json index 661e2cb1..7038ed20 100644 --- a/public/locales/ru.json +++ b/public/locales/ru.json @@ -609,5 +609,228 @@ "existing_space": "Существующее пространство", "add_room": "Добавить комнату", "existing_room": "Существующая комната" + }, + + "RoomSettings": { + "general": "Основные", + "members": "Участники", + "permissions": "Права доступа", + "emojis_stickers": "Эмодзи и стикеры", + "developer_tools": "Инструменты разработчика", + + "profile": "Профиль", + "edit": "Редактировать", + "unknown": "Неизвестно", + "avatar": "Аватар", + "upload": "Загрузить", + "reset": "Сбросить", + "remove": "Удалить", + "name": "Название", + "topic": "Тема", + "save": "Сохранить", + "cancel": "Отмена", + + "options": "Настройки", + "addresses": "Адреса", + "advanced_options": "Дополнительные настройки", + + "space_access": "Доступ к пространству", + "room_access": "Доступ к комнате", + "space_access_desc": "Изменить способ вступления в пространство.", + "room_access_desc": "Изменить способ вступления в комнату.", + + "join_invite_only": "Только по приглашению", + "join_knock_invite": "Запрос и приглашение", + "join_space_members_or_knock": "Участники пространства или запрос", + "join_space_members": "Участники пространства", + "join_public": "Публичный", + "join_unsupported": "Не поддерживается", + + "history_visibility": "Видимость истории сообщений", + "history_visibility_desc": "Изменения видимости истории применяются только к новым сообщениям и не затрагивают существующую историю.", + "visibility_after_invite": "После приглашения", + "visibility_after_join": "После вступления", + "visibility_all_messages": "Все сообщения", + "visibility_all_messages_guests": "Все сообщения (гости)", + + "room_encryption": "Шифрование комнаты", + "encryption_enabled_desc": "Сообщения в этой комнате защищены сквозным шифрованием.", + "encryption_disabled_desc": "После включения шифрование невозможно отключить!", + "enabled": "Включено", + "enable": "Включить", + "enable_encryption": "Включить шифрование", + "enable_encryption_confirm": "Вы уверены? После включения шифрование невозможно отключить!", + "enable_e2e_encryption": "Включить E2E-шифрование", + + "publish_to_directory": "Показывать в поиске", + "publish_space_desc": "Сделать пространство видимым в общем списке, чтобы другие пользователи могли его найти.", + "publish_room_desc": "Сделать комнату видимой в общем списке, чтобы другие пользователи могли её найти.", + + "published_addresses": "Опубликованные адреса", + "published_addresses_desc": "Если доступ публичный, опубликованные адреса будут использоваться для присоединения.", + "no_addresses": "Нет адресов", + "no_addresses_hint": "Чтобы опубликовать адрес, его сначала нужно задать как локальный", + "main": "Основной", + "unset_main": "Снять основной", + "set_main": "Сделать основным", + "address_in_use": "Адрес уже занят!", + "published": "Опубликован", + "unpublish": "Снять публикацию", + "publish": "Опубликовать", + "delete": "Удалить", + "selected_count": "Выбрано: {{count}}", + + "local_addresses": "Локальные адреса", + "local_addresses_desc": "Задайте локальный адрес, чтобы пользователи могли присоединиться через ваш сервер.", + "collapse": "Свернуть", + "expand": "Развернуть", + "loading": "Загрузка...", + + "space_upgrade": "Обновление пространства", + "room_upgrade": "Обновление комнаты", + "upgrade": "Обновить", + "action_irreversible": "Это действие необратимо!", + "upgrade_space": "Обновить пространство", + "upgrade_room": "Обновить комнату", + "space_replaced": "Это пространство было заменено!", + "room_replaced": "Эта комната была заменена!", + "current_version": "Текущая версия: {{version}}.", + "old_space": "Старое пространство", + "old_room": "Старая комната", + "open_new_space": "Открыть новое пространство", + "open_new_room": "Открыть новую комнату", + + "members_count": "{{count}} участников", + "search": "Поиск", + "no_results": "Ничего не найдено", + "results_count": "{{count}} результатов", + "scroll_to_top": "Наверх", + "no_membership_members": "Нет участников «{{filter}}»", + + "filter_joined": "Вступившие", + "filter_invited": "Приглашённые", + "filter_left": "Вышедшие", + "filter_kicked": "Исключённые", + "filter_banned": "Забаненные", + + "sort_a_to_z": "А — Я", + "sort_z_to_a": "Я — А", + "sort_newest": "Новые", + "sort_oldest": "Старые", + + "perm_messages": "Сообщения", + "perm_send_messages": "Отправка сообщений", + "perm_send_stickers": "Отправка стикеров", + "perm_send_reactions": "Отправка реакций", + "perm_ping_room": "Упоминание @room", + "perm_pin_messages": "Закрепление сообщений", + "perm_other_message_events": "Прочие события сообщений", + "perm_calls": "Звонки", + "perm_join_call": "Присоединиться к звонку", + "perm_moderation": "Модерация", + "perm_invite": "Приглашение", + "perm_kick": "Исключение", + "perm_ban": "Бан", + "perm_delete_others_messages": "Удаление чужих сообщений", + "perm_delete_self_messages": "Удаление своих сообщений", + "perm_room_overview": "Обзор комнаты", + "perm_room_avatar": "Аватар комнаты", + "perm_room_name": "Название комнаты", + "perm_room_topic": "Тема комнаты", + "perm_settings": "Настройки", + "perm_change_room_access": "Изменение доступа к комнате", + "perm_publish_address": "Публикация адреса", + "perm_change_all_permission": "Изменение всех прав", + "perm_edit_power_levels": "Редактирование уровней власти", + "perm_enable_encryption": "Включение шифрования", + "perm_history_visibility": "Видимость истории", + "perm_upgrade_room": "Обновление комнаты", + "perm_other_settings": "Прочие настройки", + "perm_other": "Прочее", + "perm_manage_emojis_stickers": "Управление эмодзи и стикерами", + "perm_change_server_acls": "Изменение ACL серверов", + "perm_modify_widgets": "Изменение виджетов", + + "founders": "Основатели", + "founders_desc": "Основатели имеют все права. Изменить их состав можно только при обновлении комнаты.", + "power_levels": "Уровни власти", + "power_levels_desc": "Управление и настройка уровней власти для пользователей.", + + "new_power_level": "Новый уровень власти", + "power_level_placeholder": "Бот", + "new_power_level_desc": "Создать новый уровень власти.", + "create": "Создать", + "color": "Цвет", + "pick": "Выбрать", + "power": "Уровень", + "icon": "Иконка", + "import": "Импорт", + "undo": "Отменить", + "used_power_level": "Используемый уровень власти", + "used_power_level_desc": "Необходимо убрать его использование, прежде чем удалить.", + "changes_saved": "Изменения сохранены! Примените, когда будете готовы.", + "failed_to_apply": "Не удалось применить изменения! Попробуйте ещё раз.", + "apply_changes": "Применить изменения", + "and_above": "и выше", + + "users": "Пользователи", + "default_power": "Уровень по умолчанию", + "default_power_desc": "Уровень власти по умолчанию для всех пользователей.", + + "packs": "Паки", + "new_pack": "Новый пак", + "new_pack_desc": "Добавьте свой пак эмодзи и стикеров для использования в комнате.", + "no_packs": "Нет паков", + "no_packs_desc": "На данный момент нет паков эмодзи или стикеров для отображения.", + "view": "Открыть", + "failed_to_remove_packs": "Не удалось удалить паки! Попробуйте ещё раз.", + "delete_selected_packs": "Удалить выбранные паки. (Выбрано: {{count}})", + + "enable_developer_tools": "Включить инструменты разработчика", + "room_id": "ID комнаты", + "room_id_desc": "Скопировать ID комнаты в буфер обмена.", + "copy": "Копировать", + "data": "Данные", + "new_message_event": "Новое событие сообщения", + "new_message_event_desc": "Создать и отправить новое событие сообщения в комнату.", + "compose": "Создать", + "room_state": "Состояние комнаты", + "room_state_desc": "State-события комнаты.", + "events": "События", + "total": "Всего: {{count}}", + "add_new": "Добавить", + "default_key": "По умолчанию", + "account_data": "Данные аккаунта", + "account_data_desc": "Персональные данные, хранящиеся в комнате.", + "state_event": "State-событие", + "json_content": "JSON-содержимое", + "state_event_type": "Тип state-события", + "message_event_type": "Тип события сообщения", + "send": "Отправить", + "state_key_optional": "State Key (необязательно)", + + "pack": "Пак", + "images_usage": "Использование изображений", + "images_usage_desc": "Выберите, как используются изображения: как эмодзи, как стикеры или как и то, и другое.", + "images": "Изображения", + "upload_images": "Загрузить изображения", + "upload_images_desc": "Выберите изображения из хранилища для загрузки в пак.", + "select": "Выбрать", + "pack_avatar": "Аватар пака", + "attribution": "Авторство", + "shortcode": "Шорткод:", + "body": "Описание:", + "usage_both": "Оба", + "usage_sticker": "Стикер", + "usage_emoji": "Эмодзи", + + "power_goku": "Гоку", + "power_manager": "Менеджер", + "power_founder": "Основатель", + "power_admin": "Админ", + "power_moderator": "Модератор", + "power_member": "Участник", + "power_muted": "Без голоса", + "power_team": "Команда" } } diff --git a/src/app/components/AccountDataEditor.tsx b/src/app/components/AccountDataEditor.tsx index 2dbaf1f1..d09701ca 100644 --- a/src/app/components/AccountDataEditor.tsx +++ b/src/app/components/AccountDataEditor.tsx @@ -14,6 +14,7 @@ import { Scroll, config, } from 'folds'; +import { useTranslation } from 'react-i18next'; import { MatrixError } from 'matrix-js-sdk'; import { Cursor } from '../plugins/text-area'; import { syntaxErrorPosition } from '../utils/dom'; @@ -47,6 +48,7 @@ function AccountDataEdit({ onCancel, onSave, }: AccountDataEditProps) { + const { t } = useTranslation(); const alive = useAlive(); const textAreaRef = useRef(null); @@ -121,7 +123,7 @@ function AccountDataEdit({ aria-disabled={submitting} > - Account Data + {t('RoomSettings.account_data')} } > - Save + {t('RoomSettings.save')} @@ -165,7 +167,7 @@ function AccountDataEdit({ - JSON Content + {t('RoomSettings.json_content')} void; }; function AccountDataView({ type, defaultContent, onEdit }: AccountDataViewProps) { + const { t } = useTranslation(); return ( - Account Data + {t('RoomSettings.account_data')} - JSON Content + {t('RoomSettings.json_content')} ({ type: type ?? '', content: content ?? {}, @@ -290,7 +294,7 @@ export function AccountDataEditor({ onClick={requestClose} before={} > - Developer Tools + {t('RoomSettings.developer_tools')} diff --git a/src/app/components/JoinRulesSwitcher.tsx b/src/app/components/JoinRulesSwitcher.tsx index bbc0a65d..249178b4 100644 --- a/src/app/components/JoinRulesSwitcher.tsx +++ b/src/app/components/JoinRulesSwitcher.tsx @@ -15,6 +15,7 @@ import { } from 'folds'; import { JoinRule } from 'matrix-js-sdk'; import FocusTrap from 'focus-trap-react'; +import { useTranslation } from 'react-i18next'; import { stopPropagation } from '../utils/keyboard'; import { getRoomIconSrc } from '../utils/room'; @@ -37,18 +38,20 @@ export const useJoinRuleIcons = (roomType?: string): JoinRuleIcons => ); type JoinRuleLabels = Record; -export const useRoomJoinRuleLabel = (): JoinRuleLabels => - useMemo( +export const useRoomJoinRuleLabel = (): JoinRuleLabels => { + const { t } = useTranslation(); + return useMemo( () => ({ - [JoinRule.Invite]: 'Invite Only', - [JoinRule.Knock]: 'Knock & Invite', - knock_restricted: 'Space Members or Knock', - [JoinRule.Restricted]: 'Space Members', - [JoinRule.Public]: 'Public', - [JoinRule.Private]: 'Invite Only', + [JoinRule.Invite]: t('RoomSettings.join_invite_only'), + [JoinRule.Knock]: t('RoomSettings.join_knock_invite'), + knock_restricted: t('RoomSettings.join_space_members_or_knock'), + [JoinRule.Restricted]: t('RoomSettings.join_space_members'), + [JoinRule.Public]: t('RoomSettings.join_public'), + [JoinRule.Private]: t('RoomSettings.join_invite_only'), }), - [] + [t] ); +}; type JoinRulesSwitcherProps = { icons: JoinRuleIcons; @@ -68,6 +71,7 @@ export function JoinRulesSwitcher({ disabled, changing, }: JoinRulesSwitcherProps) { + const { t } = useTranslation(); const [cords, setCords] = useState(); const handleOpenMenu: MouseEventHandler = (evt) => { @@ -138,7 +142,7 @@ export function JoinRulesSwitcher({ onClick={handleOpenMenu} disabled={disabled} > - {labels[value] ?? 'Unsupported'} + {labels[value] ?? t('RoomSettings.join_unsupported')} ); diff --git a/src/app/components/image-pack-view/ImagePackContent.tsx b/src/app/components/image-pack-view/ImagePackContent.tsx index a696ebe8..8e42fe52 100644 --- a/src/app/components/image-pack-view/ImagePackContent.tsx +++ b/src/app/components/image-pack-view/ImagePackContent.tsx @@ -1,5 +1,6 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { as, Box, Text, config, Button, Menu, Spinner } from 'folds'; +import { useTranslation } from 'react-i18next'; import { ImagePack, ImageUsage, @@ -33,6 +34,7 @@ export type ImagePackContentProps = { export const ImagePackContent = as<'div', ImagePackContentProps>( ({ imagePack, canEdit, onUpdate, ...props }, ref) => { + const { t } = useTranslation(); const useAuthentication = useMediaAuthentication(); const [metaEditing, setMetaEditing] = useState(false); @@ -256,11 +258,11 @@ export const ImagePackContent = as<'div', ImagePackContentProps>( {applyState.status === AsyncStatus.Error ? ( - Failed to apply changes! Please try again. + {t('RoomSettings.failed_to_apply')} ) : ( - Changes saved! Apply when ready. + {t('RoomSettings.changes_saved')} )} @@ -273,7 +275,7 @@ export const ImagePackContent = as<'div', ImagePackContentProps>( disabled={!canApplyChanges || applying} onClick={handleResetSavedChanges} > - Reset + {t('RoomSettings.reset')} )} - Pack + {t('RoomSettings.pack')} ( gap="400" > ( {images.length === 0 && !canEdit ? null : ( - Images + {t('RoomSettings.images')} {canEdit && ( ( gap="400" > ( outlined onClick={() => pickFiles('image/*')} > - Select + {t('RoomSettings.select')} } /> diff --git a/src/app/components/image-pack-view/ImagePackView.tsx b/src/app/components/image-pack-view/ImagePackView.tsx index ab81d503..808e30ee 100644 --- a/src/app/components/image-pack-view/ImagePackView.tsx +++ b/src/app/components/image-pack-view/ImagePackView.tsx @@ -1,5 +1,6 @@ import React from 'react'; import { Box, IconButton, Text, Icon, Icons, Scroll, Chip } from 'folds'; +import { useTranslation } from 'react-i18next'; import { PackAddress } from '../../plugins/custom-emoji'; import { Page, PageHeader, PageContent } from '../page'; import { useMatrixClient } from '../../hooks/useMatrixClient'; @@ -11,6 +12,7 @@ type ImagePackViewProps = { requestClose: () => void; }; export function ImagePackView({ address, requestClose }: ImagePackViewProps) { + const { t } = useTranslation(); const mx = useMatrixClient(); const room = address && mx.getRoom(address.roomId); @@ -25,7 +27,7 @@ export function ImagePackView({ address, requestClose }: ImagePackViewProps) { onClick={requestClose} before={} > - Emojis & Stickers + {t('RoomSettings.emojis_stickers')} diff --git a/src/app/components/image-pack-view/ImageTile.tsx b/src/app/components/image-pack-view/ImageTile.tsx index 37337ff7..b642828a 100644 --- a/src/app/components/image-pack-view/ImageTile.tsx +++ b/src/app/components/image-pack-view/ImageTile.tsx @@ -1,5 +1,6 @@ import React, { FormEventHandler, ReactNode, useMemo, useState } from 'react'; import { Badge, Box, Button, Chip, Icon, Icons, Input, Text } from 'folds'; +import { useTranslation } from 'react-i18next'; import { UsageSwitcher, useUsageStr } from './UsageSwitcher'; import { mxcUrlToHttp } from '../../utils/matrix'; import * as css from './style.css'; @@ -30,6 +31,7 @@ export function ImageTile({ onDeleteToggle, deleted, }: ImageTileProps) { + const { t } = useTranslation(); const mx = useMatrixClient(); const getUsageStr = useUsageStr(); @@ -71,7 +73,7 @@ export function ImageTile({ radii="Pill" onClick={() => onDeleteToggle?.(defaultShortcode)} > - {deleted ? Undo : } + {deleted ? {t('RoomSettings.undo')} : } {!deleted && ( onEdit?.(defaultShortcode, image)} > - Edit + {t('RoomSettings.edit')} )} @@ -120,6 +122,7 @@ export function ImageTileEdit({ onCancel, onSave, }: ImageTileEditProps) { + const { t } = useTranslation(); const mx = useMatrixClient(); const defaultUsage = image.usage ?? packUsage; @@ -171,7 +174,7 @@ export function ImageTileEdit({ Shortcode:} + before={{t('RoomSettings.shortcode')}} defaultValue={image.shortcode} name="shortcodeInput" variant="Secondary" @@ -181,7 +184,7 @@ export function ImageTileEdit({ autoFocus /> Body:} + before={{t('RoomSettings.body')}} defaultValue={image.body} name="bodyInput" variant="Secondary" @@ -195,7 +198,7 @@ export function ImageTileEdit({ diff --git a/src/app/components/image-pack-view/PackMeta.tsx b/src/app/components/image-pack-view/PackMeta.tsx index f091f30b..3717c0ba 100644 --- a/src/app/components/image-pack-view/PackMeta.tsx +++ b/src/app/components/image-pack-view/PackMeta.tsx @@ -13,6 +13,7 @@ import { Chip, } from 'folds'; import Linkify from 'linkify-react'; +import { useTranslation } from 'react-i18next'; import { mxcUrlToHttp } from '../../utils/matrix'; import { useMatrixClient } from '../../hooks/useMatrixClient'; import { nameInitials } from '../../utils/common'; @@ -31,13 +32,14 @@ type ImagePackAvatarProps = { name?: string; }; function ImagePackAvatar({ url, name }: ImagePackAvatarProps) { + const { t } = useTranslation(); return ( {url ? ( - + ) : ( - {nameInitials(name ?? 'Unknown')} + {nameInitials(name ?? t('RoomSettings.unknown'))} )} @@ -50,6 +52,7 @@ type ImagePackProfileProps = { onEdit?: () => void; }; export function ImagePackProfile({ meta, canEdit, onEdit }: ImagePackProfileProps) { + const { t } = useTranslation(); const mx = useMatrixClient(); const useAuthentication = useMediaAuthentication(); const avatarUrl = meta.avatar @@ -61,7 +64,7 @@ export function ImagePackProfile({ meta, canEdit, onEdit }: ImagePackProfileProp - {meta.name ?? 'Unknown'} + {meta.name ?? t('RoomSettings.unknown')} {meta.attribution && ( @@ -79,7 +82,7 @@ export function ImagePackProfile({ meta, canEdit, onEdit }: ImagePackProfileProp onClick={onEdit} outlined > - Edit + {t('RoomSettings.edit')} )} @@ -97,6 +100,7 @@ type ImagePackProfileEditProps = { onSave: (meta: PackMetaReader) => void; }; export function ImagePackProfileEdit({ meta, onCancel, onSave }: ImagePackProfileEditProps) { + const { t } = useTranslation(); const mx = useMatrixClient(); const useAuthentication = useMediaAuthentication(); const [avatar, setAvatar] = useState(meta.avatar); @@ -147,7 +151,7 @@ export function ImagePackProfileEdit({ meta, onCancel, onSave }: ImagePackProfil - Pack Avatar + {t('RoomSettings.pack_avatar')} {uploadAtom ? ( pickFile('image/*')} > - Upload + {t('RoomSettings.upload')} {!avatar && meta.avatar && ( )} {avatar && ( @@ -189,7 +193,7 @@ export function ImagePackProfileEdit({ meta, onCancel, onSave }: ImagePackProfil radii="300" onClick={() => setAvatar(undefined)} > - Remove + {t('RoomSettings.remove')} )} @@ -200,11 +204,11 @@ export function ImagePackProfileEdit({ meta, onCancel, onSave }: ImagePackProfil - Name + {t('RoomSettings.name')} - Attribution + {t('RoomSettings.attribution')}