Migrate more strings to translation keys (#11680)

This commit is contained in:
Michael Telatynski 2023-09-29 08:49:26 +01:00 committed by GitHub
parent 8014cebb20
commit 6af4335db1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
101 changed files with 6739 additions and 5973 deletions

View file

@ -240,7 +240,7 @@ const Tile: React.FC<ITileProps> = ({
let joinedSection: ReactElement | undefined;
if (joinedRoom) {
joinedSection = <div className="mx_SpaceHierarchy_roomTile_joined">{_t("Joined")}</div>;
joinedSection = <div className="mx_SpaceHierarchy_roomTile_joined">{_t("common|joined")}</div>;
}
let suggestedSection: ReactElement | undefined;

View file

@ -77,7 +77,7 @@ export default class CompleteSecurity extends React.Component<IProps, IState> {
title = _t("Device verified");
} else if (phase === Phase.ConfirmSkip) {
icon = <span className="mx_CompleteSecurity_headerIcon mx_E2EIcon_warning" />;
title = _t("Are you sure?");
title = _t("common|are_you_sure");
} else if (phase === Phase.Busy) {
icon = <span className="mx_CompleteSecurity_headerIcon mx_E2EIcon_warning" />;
title = _t("Verify this device");

View file

@ -346,7 +346,7 @@ export default class ForgotPassword extends React.Component<Props, State> {
public async renderConfirmLogoutDevicesDialog(): Promise<boolean> {
const { finished } = Modal.createDialog(QuestionDialog, {
title: _t("Warning!"),
title: _t("common|warning"),
description: (
<div>
<p>

View file

@ -676,7 +676,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
viewInRoomButton = (
<IconizedContextMenuOption
iconClassName="mx_MessageContextMenu_iconViewInRoom"
label={_t("View in room")}
label={_t("timeline|mab|view_in_room")}
onClick={this.viewInRoom}
/>
);

View file

@ -265,7 +265,7 @@ const RoomContextMenu: React.FC<IProps> = ({ room, onFinished, ...props }) => {
RightPanelStore.instance.pushCard({ phase: RightPanelPhases.FilePanel }, false);
onFinished();
}}
label={_t("Files")}
label={_t("right_panel|files_button")}
iconClassName="mx_RoomTile_iconFiles"
/>
);
@ -286,7 +286,7 @@ const RoomContextMenu: React.FC<IProps> = ({ room, onFinished, ...props }) => {
RightPanelStore.instance.pushCard({ phase: RightPanelPhases.PinnedMessages }, false);
onFinished();
}}
label={_t("Pinned")}
label={_t("right_panel|pinned_messages_button")}
iconClassName="mx_RoomTile_iconPins"
>
{pinCount > 0 && <span className="mx_IconizedContextMenu_sublabel">{pinCount}</span>}
@ -306,7 +306,7 @@ const RoomContextMenu: React.FC<IProps> = ({ room, onFinished, ...props }) => {
RightPanelStore.instance.setCard({ phase: RightPanelPhases.RoomSummary }, false);
onFinished();
}}
label={_t("Widgets")}
label={_t("right_panel|widgets_section")}
iconClassName="mx_RoomTile_iconWidgets"
/>
);
@ -323,7 +323,7 @@ const RoomContextMenu: React.FC<IProps> = ({ room, onFinished, ...props }) => {
Modal.createDialog(ExportDialog, { room });
onFinished();
}}
label={_t("Export chat")}
label={_t("right_panel|export_chat_button")}
iconClassName="mx_RoomTile_iconExport"
/>
);

View file

@ -109,7 +109,7 @@ const ThreadListContextMenu: React.FC<ThreadListContextMenuProps> = ({
{isMainSplitTimelineShown && (
<IconizedContextMenuOption
onClick={(e) => viewInRoom(e)}
label={_t("View in room")}
label={_t("timeline|mab|view_in_room")}
iconClassName="mx_ThreadPanel_viewInRoom"
/>
)}
@ -117,7 +117,7 @@ const ThreadListContextMenu: React.FC<ThreadListContextMenuProps> = ({
<IconizedContextMenuOption
data-testid="copy-thread-link"
onClick={(e) => copyLinkToThread(e)}
label={_t("Copy link to thread")}
label={_t("timeline|mab|copy_link_thread")}
iconClassName="mx_ThreadPanel_copyLinkToThread"
/>
)}

View file

@ -130,7 +130,7 @@ const Entry: React.FC<IEntryProps> = ({ room, type, content, matrixClient: cli,
} else {
className = "mx_ForwardList_sendFailed";
disabled = true;
title = _t("Failed to send");
title = _t("timeline|send_state_failed");
icon = <NotificationBadge notification={StaticNotificationState.RED_EXCLAMATION} />;
}

View file

@ -1062,7 +1062,7 @@ export default class InviteDialog extends React.PureComponent<Props, IInviteDial
showMore = (
<div className="mx_InviteDialog_section_showMore">
<AccessibleButton onClick={showMoreFn} kind="link">
{_t("Show more")}
{_t("common|show_more")}
</AccessibleButton>
</div>
);

View file

@ -176,7 +176,7 @@ export default class LogoutDialog extends React.Component<IProps, IState> {
"When you sign out, these keys will be deleted from this device, which means you won't be able to read encrypted messages unless you have the keys for them on your other devices, or backed them up to the server.",
)}
</p>
<p>{_t("Back up your keys before signing out to avoid losing them.")}</p>
<p>{_t("encryption|setup_secure_backup|explainer")}</p>
</div>
);

View file

@ -208,7 +208,7 @@ class RoomSettingsDialog extends React.Component<IProps, IState> {
tabs.push(
new Tab(
RoomSettingsTab.PollHistory,
_td("Poll history"),
_td("right_panel|polls_button"),
"mx_RoomSettingsDialog_pollsIcon",
<PollHistoryTab room={this.state.room} onFinished={() => this.props.onFinished(true)} />,
),

View file

@ -61,7 +61,7 @@ export class EditableItem extends React.Component<IItemProps, IItemState> {
if (this.state.verifyRemove) {
return (
<div className="mx_EditableItem">
<span className="mx_EditableItem_promptText">{_t("Are you sure?")}</span>
<span className="mx_EditableItem_promptText">{_t("common|are_you_sure")}</span>
<AccessibleButton
onClick={this.onActuallyRemove}
kind="primary_sm"

View file

@ -58,7 +58,7 @@ export default class InviteReason extends React.PureComponent<IProps, IState> {
{this.props.htmlReason ? sanitizedHtmlNode(this.props.htmlReason) : this.props.reason}
</div>
<AccessibleButton kind="link_inline" className="mx_InviteReason_view" onClick={this.onViewClick}>
{_t("View message")}
{_t("common|view_message")}
</AccessibleButton>
</div>
);

View file

@ -23,7 +23,7 @@ import { IBodyProps } from "./IBodyProps";
function getErrorMessage(mxEvent?: MatrixEvent): string {
return mxEvent?.isEncryptedDisabledForUnverifiedDevices
? _t("The sender has blocked you from receiving this message")
: _t("Unable to decrypt message");
: _t("threads|unable_to_decrypt");
}
// A placeholder element for messages that could not be decrypted

View file

@ -155,7 +155,7 @@ export default class MKeyVerificationRequest extends React.Component<IProps> {
} else if (request.phase === VerificationPhase.Cancelled) {
stateLabel = this.cancelledLabel(request.cancellingUserId!);
} else if (request.accepting) {
stateLabel = _t("Accepting…");
stateLabel = _t("encryption|verification|accepting");
} else if (request.declining) {
stateLabel = _t("Declining…");
}

View file

@ -549,7 +549,7 @@ export default class MessageActionBar extends React.PureComponent<IMessageAction
// aria-live=off to not have this read out automatically as navigating around timeline, gets repetitive.
return (
<Toolbar className="mx_MessageActionBar" aria-label={_t("Message Actions")} aria-live="off">
<Toolbar className="mx_MessageActionBar" aria-label={_t("timeline|mab|label")} aria-live="off">
{toolbarOpts}
</Toolbar>
);

View file

@ -62,7 +62,7 @@ export const PollHistory: React.FC<PollHistoryProps> = ({ room, matrixClient, pe
const title = focusedPoll ? (
<PollDetailHeader filter={filter} onNavigateBack={() => setFocusedPollId(null)} />
) : (
_t("Poll history")
_t("right_panel|polls_button")
);
return (

View file

@ -51,15 +51,15 @@ const EncryptionInfo: React.FC<IProps> = ({
}: IProps) => {
let content: JSX.Element;
if (waitingForOtherParty && isSelfVerification) {
content = <div>{_t("To proceed, please accept the verification request on your other device.")}</div>;
content = <div>{_t("encryption|verification|self_verification_hint")}</div>;
} else if (waitingForOtherParty || waitingForNetwork) {
let text: string;
if (waitingForOtherParty) {
text = _t("Waiting for %(displayName)s to accept…", {
text = _t("encryption|verification|waiting_for_user_accept", {
displayName: (member as User).displayName || (member as RoomMember).name || member.userId,
});
} else {
text = _t("Accepting…");
text = _t("encryption|verification|accepting");
}
content = <PendingActionSpinner text={text} />;
} else {
@ -69,7 +69,7 @@ const EncryptionInfo: React.FC<IProps> = ({
className="mx_UserInfo_wideButton mx_UserInfo_startVerification"
onClick={onStartVerification}
>
{_t("Start Verification")}
{_t("encryption|verification|start_button")}
</AccessibleButton>
);
}
@ -78,23 +78,15 @@ const EncryptionInfo: React.FC<IProps> = ({
if (isRoomEncrypted) {
description = (
<div>
<p>{_t("Messages in this room are end-to-end encrypted.")}</p>
<p>
{_t(
"Your messages are secured and only you and the recipient have the unique keys to unlock them.",
)}
</p>
<p>{_t("user_info|room_encrypted")}</p>
<p>{_t("user_info|room_encrypted_detail")}</p>
</div>
);
} else {
description = (
<div>
<p>{_t("Messages in this room are not end-to-end encrypted.")}</p>
<p>
{_t(
"In encrypted rooms, your messages are secured and only you and the recipient have the unique keys to unlock them.",
)}
</p>
<p>{_t("user_info|room_unencrypted")}</p>
<p>{_t("user_info|room_unencrypted_detail")}</p>
</div>
);
}
@ -110,13 +102,9 @@ const EncryptionInfo: React.FC<IProps> = ({
{description}
</div>
<div className="mx_UserInfo_container">
<h3>{_t("Verify User")}</h3>
<h3>{_t("user_info|verify_button")}</h3>
<div>
<p>
{_t(
"For extra security, verify this user by checking a one-time code on both of your devices.",
)}
</p>
<p>{_t("user_info|verify_explainer")}</p>
<p>{_t("encryption|verification|in_person")}</p>
{content}
</div>

View file

@ -78,15 +78,15 @@ const EncryptionPanel: React.FC<IProps> = (props: IProps) => {
) {
Modal.createDialog(ErrorDialog, {
headerImage: require("../../../../res/img/e2e/warning-deprecated.svg").default,
title: _t("Your messages are not secure"),
title: _t("encryption|messages_not_secure|title"),
description: (
<div>
{_t("One of the following may be compromised:")}
{_t("encryption|messages_not_secure|heading")}
<ul>
<li>{_t("Your homeserver")}</li>
<li>{_t("The homeserver the user you're verifying is connected to")}</li>
<li>{_t("Yours, or the other users' internet connection")}</li>
<li>{_t("Yours, or the other users' session")}</li>
<li>{_t("encryption|messages_not_secure|cause_1")}</li>
<li>{_t("encryption|messages_not_secure|cause_2")}</li>
<li>{_t("encryption|messages_not_secure|cause_3")}</li>
<li>{_t("encryption|messages_not_secure|cause_4")}</li>
</ul>
</div>
),
@ -117,8 +117,8 @@ const EncryptionPanel: React.FC<IProps> = (props: IProps) => {
Modal.createDialog(ErrorDialog, {
headerImage: require("../../../../res/img/e2e/warning.svg").default,
title: _t("Error starting verification"),
description: _t("We were unable to start a chat with the other user."),
title: _t("encryption|verification|error_starting_title"),
description: _t("encryption|verification|error_starting_description"),
});
return;
}

View file

@ -94,7 +94,7 @@ const PinnedMessagesHeaderButton: React.FC<IHeaderButtonProps> = ({ room, isHigh
return (
<HeaderButton
name="pinnedMessagesButton"
title={_t("Pinned messages")}
title={_t("right_panel|pinned_messages|title")}
isHighlighted={isHighlighted}
isUnread={!!unreadIndicator}
onClick={onClick}
@ -114,7 +114,12 @@ const TimelineCardHeaderButton: React.FC<IHeaderButtonProps> = ({ room, isHighli
unreadIndicator = <UnreadIndicator color={color} />;
}
return (
<HeaderButton name="timelineCardButton" title={_t("Chat")} isHighlighted={isHighlighted} onClick={onClick}>
<HeaderButton
name="timelineCardButton"
title={_t("right_panel|video_room_chat|title")}
isHighlighted={isHighlighted}
onClick={onClick}
>
{unreadIndicator}
</HeaderButton>
);
@ -304,7 +309,7 @@ export default class LegacyRoomHeaderButtons extends HeaderButtons<IProps> {
<HeaderButton
key="roomSummaryButton"
name="roomSummaryButton"
title={_t("Room info")}
title={_t("right_panel|room_summary_card|title")}
isHighlighted={this.isPhase(ROOM_INFO_PHASES)}
onClick={this.onRoomSummaryClicked}
/>,

View file

@ -178,10 +178,10 @@ const PinnedMessagesCard: React.FC<IProps> = ({ room, onClose, permalinkCreator
</div>
<Heading size="4" className="mx_PinnedMessagesCard_empty_header">
{_t("Nothing pinned, yet")}
{_t("right_panel|pinned_messages|empty")}
</Heading>
{_t(
"If you have permissions, open the menu on any message and select <b>Pin</b> to stick them here.",
"right_panel|pinned_messages|explainer",
{},
{
b: (sub) => <b>{sub}</b>,
@ -223,7 +223,7 @@ const PinnedMessagesCard: React.FC<IProps> = ({ room, onClose, permalinkCreator
header={
<div className="mx_BaseCard_header_title">
<Heading size="4" className="mx_BaseCard_header_title_heading">
{_t("Pinned messages")}
{_t("right_panel|pinned_messages|title")}
</Heading>
</div>
}

View file

@ -149,7 +149,7 @@ const AppRow: React.FC<IAppRowProps> = ({ app, room }) => {
let pinTitle: string;
if (cannotPin) {
pinTitle = _t("You can only pin up to %(count)s widgets", { count: MAX_PINNED });
pinTitle = _t("right_panel|pinned_messages|limits", { count: MAX_PINNED });
} else {
pinTitle = isPinned ? _t("action|unpin") : _t("action|pin");
}
@ -167,9 +167,9 @@ const AppRow: React.FC<IAppRowProps> = ({ app, room }) => {
let openTitle = "";
if (isPinned) {
openTitle = _t("Unpin this widget to view it in this panel");
openTitle = _t("widget|unpin_to_view_right_panel");
} else if (isMaximised) {
openTitle = _t("Close this widget to view it in this panel");
openTitle = _t("widget|close_to_view_right_panel");
}
const classes = classNames("mx_BaseCard_Button mx_RoomSummaryCard_Button", {
@ -237,19 +237,19 @@ const AppsSection: React.FC<IAppsSectionProps> = ({ room }) => {
if (realApps.length > 0 && WidgetLayoutStore.instance.canCopyLayoutToRoom(room)) {
copyLayoutBtn = (
<AccessibleButton kind="link" onClick={() => WidgetLayoutStore.instance.copyLayoutToRoom(room)}>
{_t("Set my room layout for everyone")}
{_t("widget|set_room_layout")}
</AccessibleButton>
);
}
return (
<Group className="mx_RoomSummaryCard_appsGroup" title={_t("Widgets")}>
<Group className="mx_RoomSummaryCard_appsGroup" title={_t("right_panel|widgets_section")}>
{realApps.map((app) => (
<AppRow key={app.id} app={app} room={room} />
))}
{copyLayoutBtn}
<AccessibleButton kind="link" onClick={onManageIntegrations}>
{realApps.length > 0 ? _t("Edit widgets, bridges & bots") : _t("Add widgets, bridges & bots")}
{realApps.length > 0 ? _t("right_panel|edit_integrations") : _t("right_panel|add_integrations")}
</AccessibleButton>
</Group>
);
@ -310,7 +310,7 @@ const RoomSummaryCard: React.FC<IProps> = ({ room, permalinkCreator, onClose, on
<div className="mx_RoomSummaryCard_avatar" role="presentation">
<RoomAvatar room={room} size="54px" viewAvatarOnClick />
<TextWithTooltip
tooltip={isRoomEncrypted ? _t("common|encrypted") : _t("Not encrypted")}
tooltip={isRoomEncrypted ? _t("common|encrypted") : _t("common|unencrypted")}
class={classNames("mx_RoomSummaryCard_e2ee", {
mx_RoomSummaryCard_e2ee_normal: isRoomEncrypted,
mx_RoomSummaryCard_e2ee_warning: isRoomEncrypted && e2eStatus === E2EStatus.Warning,
@ -350,28 +350,28 @@ const RoomSummaryCard: React.FC<IProps> = ({ room, permalinkCreator, onClose, on
onSearchClick?.();
}}
>
{_t("Search")}
{_t("right_panel|search_button")}
</Button>
)}
{!isVideoRoom && (
<Button className="mx_RoomSummaryCard_icon_files" onClick={onRoomFilesClick}>
{_t("Files")}
{_t("right_panel|files_button")}
</Button>
)}
{!isVideoRoom && (
<Button className="mx_RoomSummaryCard_icon_poll" onClick={onRoomPollHistoryClick}>
{_t("Poll history")}
{_t("right_panel|polls_button")}
</Button>
)}
{pinningEnabled && !isVideoRoom && (
<Button className="mx_RoomSummaryCard_icon_pins" onClick={onRoomPinsClick}>
{_t("Pinned")}
{_t("right_panel|pinned_messages_button")}
{pinCount > 0 && <span className="mx_BaseCard_Button_sublabel">{pinCount}</span>}
</Button>
)}
{!isVideoRoom && (
<Button className="mx_RoomSummaryCard_icon_export" onClick={onRoomExportClick}>
{_t("Export chat")}
{_t("right_panel|export_chat_button")}
</Button>
)}
<Button
@ -379,10 +379,10 @@ const RoomSummaryCard: React.FC<IProps> = ({ room, permalinkCreator, onClose, on
className="mx_RoomSummaryCard_icon_share"
onClick={onShareRoomClick}
>
{_t("Share room")}
{_t("right_panel|share_button")}
</Button>
<Button className="mx_RoomSummaryCard_icon_settings" onClick={onRoomSettingsClick}>
{_t("Room settings")}
{_t("right_panel|settings_button")}
</Button>
</Group>

View file

@ -195,7 +195,7 @@ export default class TimelineCard extends React.Component<IProps, IState> {
return (
<div className="mx_BaseCard_header_title">
<Heading size="4" className="mx_BaseCard_header_title_heading">
{_t("Chat")}
{_t("right_panel|video_room_chat|title")}
</Heading>
</div>
);

View file

@ -283,12 +283,12 @@ function DevicesSection({
}
}
expandCountCaption = _t("%(count)s verified sessions", { count: expandSectionDevices.length });
expandHideCaption = _t("Hide verified sessions");
expandHideCaption = _t("user_info|hide_verified_sessions");
expandIconClasses += " mx_E2EIcon_verified";
} else {
expandSectionDevices = devices;
expandCountCaption = _t("%(count)s sessions", { count: devices.length });
expandHideCaption = _t("Hide sessions");
expandHideCaption = _t("user_info|hide_sessions");
expandIconClasses += " mx_E2EIcon_normal";
}
@ -381,14 +381,8 @@ export const UserOptionsSection: React.FC<{
const ignore = useCallback(async () => {
const name = (member instanceof User ? member.displayName : member.name) || member.userId;
const { finished } = Modal.createDialog(QuestionDialog, {
title: _t("Ignore %(user)s", { user: name }),
description: (
<div>
{_t(
"All messages and invites from this user will be hidden. Are you sure you want to ignore them?",
)}
</div>
),
title: _t("user_info|ignore_confirm_title", { user: name }),
description: <div>{_t("user_info|ignore_confirm_description")}</div>,
button: _t("action|ignore"),
});
const [confirmed] = await finished;
@ -438,7 +432,7 @@ export const UserOptionsSection: React.FC<{
if (room?.getEventReadUpTo(member.userId)) {
readReceiptButton = (
<AccessibleButton kind="link" onClick={onReadReceiptButton} className="mx_UserInfo_field">
{_t("Jump to read receipt")}
{_t("user_info|jump_to_rr_button")}
</AccessibleButton>
);
}
@ -497,7 +491,7 @@ export const UserOptionsSection: React.FC<{
const shareUserButton = (
<AccessibleButton kind="link" onClick={onShareUserClick} className="mx_UserInfo_field">
{_t("Share Link to User")}
{_t("user_info|share_button")}
</AccessibleButton>
);
@ -520,19 +514,15 @@ export const UserOptionsSection: React.FC<{
export const warnSelfDemote = async (isSpace: boolean): Promise<boolean> => {
const { finished } = Modal.createDialog(QuestionDialog, {
title: _t("Demote yourself?"),
title: _t("user_info|demote_self_confirm_title"),
description: (
<div>
{isSpace
? _t(
"You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the space it will be impossible to regain privileges.",
)
: _t(
"You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the room it will be impossible to regain privileges.",
)}
? _t("user_info|demote_self_confirm_description_space")
: _t("user_info|demote_self_confirm_room")}
</div>
),
button: _t("Demote"),
button: _t("user_info|demote_button"),
});
const [confirmed] = await finished;
@ -544,7 +534,7 @@ const GenericAdminToolsContainer: React.FC<{
}> = ({ children }) => {
return (
<div className="mx_UserInfo_container">
<h3>{_t("Admin Tools")}</h3>
<h3>{_t("user_info|admin_tools_section")}</h3>
<div className="mx_UserInfo_buttons">{children}</div>
</div>
);
@ -631,15 +621,15 @@ export const RoomKickButton = ({
member,
action: room.isSpaceRoom()
? member.membership === "invite"
? _t("Disinvite from space")
: _t("Remove from space")
? _t("user_info|disinvite_button_space")
: _t("user_info|kick_button_space")
: member.membership === "invite"
? _t("Disinvite from room")
: _t("Remove from room"),
? _t("user_info|disinvite_button_room")
: _t("user_info|kick_button_room"),
title:
member.membership === "invite"
? _t("Disinvite from %(roomName)s", { roomName: room.name })
: _t("Remove from %(roomName)s", { roomName: room.name }),
? _t("user_info|disinvite_button_room_name", { roomName: room.name })
: _t("user_info|kick_button_room_name", { roomName: room.name }),
askReason: member.membership === "join",
danger: true,
};
@ -664,9 +654,9 @@ export const RoomKickButton = ({
child.currentState.hasSufficientPowerLevelFor("kick", myMember.powerLevel)
);
},
allLabel: _t("Remove them from everything I'm able to"),
specificLabel: _t("Remove them from specific things I'm able to"),
warningMessage: _t("They'll still be able to access whatever you're not an admin of."),
allLabel: _t("user_info|kick_button_space_everything"),
specificLabel: _t("user_info|kick_space_specific"),
warningMessage: _t("user_info|kick_space_warning"),
},
"mx_ConfirmSpaceUserActionDialog_wrapper",
));
@ -690,7 +680,7 @@ export const RoomKickButton = ({
function (err) {
logger.error("Kick error: " + err);
Modal.createDialog(ErrorDialog, {
title: _t("Failed to remove user"),
title: _t("user_info|error_kicking_user"),
description: err && err.message ? err.message : "Operation failed",
});
},
@ -702,11 +692,11 @@ export const RoomKickButton = ({
const kickLabel = room.isSpaceRoom()
? member.membership === "invite"
? _t("Disinvite from space")
: _t("Remove from space")
? _t("user_info|disinvite_button_space")
: _t("user_info|kick_button_space")
: member.membership === "invite"
? _t("Disinvite from room")
: _t("Remove from room");
? _t("user_info|disinvite_button_room")
: _t("user_info|kick_button_room");
return (
<AccessibleButton
@ -740,7 +730,7 @@ const RedactMessagesButton: React.FC<IBaseProps> = ({ member }) => {
className="mx_UserInfo_field mx_UserInfo_destructive"
onClick={onRedactAllMessages}
>
{_t("Remove recent messages")}
{_t("user_info|redact_button")}
</AccessibleButton>
);
};
@ -763,14 +753,14 @@ export const BanToggleButton = ({
member,
action: room.isSpaceRoom()
? isBanned
? _t("Unban from space")
: _t("Ban from space")
? _t("user_info|unban_button_space")
: _t("user_info|ban_button_space")
: isBanned
? _t("Unban from room")
: _t("Ban from room"),
? _t("user_info|unban_button_room")
: _t("user_info|ban_button_room"),
title: isBanned
? _t("Unban from %(roomName)s", { roomName: room.name })
: _t("Ban from %(roomName)s", { roomName: room.name }),
? _t("user_info|unban_room_confirm_title", { roomName: room.name })
: _t("user_info|ban_room_confirm_title", { roomName: room.name }),
askReason: !isBanned,
danger: !isBanned,
};
@ -808,15 +798,9 @@ export const BanToggleButton = ({
child.currentState.hasSufficientPowerLevelFor("ban", myMember.powerLevel)
);
},
allLabel: isBanned
? _t("Unban them from everything I'm able to")
: _t("Ban them from everything I'm able to"),
specificLabel: isBanned
? _t("Unban them from specific things I'm able to")
: _t("Ban them from specific things I'm able to"),
warningMessage: isBanned
? _t("They won't be able to access whatever you're not an admin of.")
: _t("They'll still be able to access whatever you're not an admin of."),
allLabel: isBanned ? _t("user_info|unban_space_everything") : _t("user_info|ban_space_everything"),
specificLabel: isBanned ? _t("user_info|unban_space_specific") : _t("user_info|ban_space_specific"),
warningMessage: isBanned ? _t("user_info|unban_space_warning") : _t("user_info|kick_space_warning"),
},
"mx_ConfirmSpaceUserActionDialog_wrapper",
));
@ -849,7 +833,7 @@ export const BanToggleButton = ({
logger.error("Ban error: " + err);
Modal.createDialog(ErrorDialog, {
title: _t("common|error"),
description: _t("Failed to ban user"),
description: _t("user_info|error_ban_user"),
});
},
)
@ -858,9 +842,9 @@ export const BanToggleButton = ({
});
};
let label = room.isSpaceRoom() ? _t("Ban from space") : _t("Ban from room");
let label = room.isSpaceRoom() ? _t("user_info|ban_button_space") : _t("user_info|ban_button_room");
if (isBanned) {
label = room.isSpaceRoom() ? _t("Unban from space") : _t("Unban from room");
label = room.isSpaceRoom() ? _t("user_info|unban_button_space") : _t("user_info|unban_button_room");
}
const classes = classNames("mx_UserInfo_field", {
@ -931,7 +915,7 @@ const MuteToggleButton: React.FC<IBaseRoomProps> = ({
logger.error("Mute error: " + err);
Modal.createDialog(ErrorDialog, {
title: _t("common|error"),
description: _t("Failed to mute user"),
description: _t("user_info|error_mute_user"),
});
},
)
@ -1179,14 +1163,12 @@ export const PowerLevelEditor: React.FC<{
const myPower = powerLevelEvent.getContent().users[myUserId || ""];
if (myPower && parseInt(myPower) <= powerLevel && myUserId !== target) {
const { finished } = Modal.createDialog(QuestionDialog, {
title: _t("Warning!"),
title: _t("common|warning"),
description: (
<div>
{_t(
"You will not be able to undo this change as you are promoting the user to have the same power level as yourself.",
)}
{_t("user_info|promote_warning")}
<br />
{_t("Are you sure?")}
{_t("common|are_you_sure")}
</div>
),
button: _t("action|continue"),
@ -1348,15 +1330,9 @@ const BasicUserInfo: React.FC<{
const onSynapseDeactivate = useCallback(async () => {
const { finished } = Modal.createDialog(QuestionDialog, {
title: _t("Deactivate user?"),
description: (
<div>
{_t(
"Deactivating this user will log them out and prevent them from logging back in. Additionally, they will leave all the rooms they are in. This action cannot be reversed. Are you sure you want to deactivate this user?",
)}
</div>
),
button: _t("Deactivate user"),
title: _t("user_info|deactivate_confirm_title"),
description: <div>{_t("user_info|deactivate_confirm_description")}</div>,
button: _t("user_info|deactivate_confirm_action"),
danger: true,
});
@ -1371,7 +1347,7 @@ const BasicUserInfo: React.FC<{
const description = err instanceof Error ? err.message : _t("invite|failed_generic");
Modal.createDialog(ErrorDialog, {
title: _t("Failed to deactivate user"),
title: _t("user_info|error_deactivate"),
description,
});
}
@ -1390,7 +1366,7 @@ const BasicUserInfo: React.FC<{
className="mx_UserInfo_field mx_UserInfo_destructive"
onClick={onSynapseDeactivate}
>
{_t("Deactivate user")}
{_t("user_info|deactivate_confirm_action")}
</AccessibleButton>
);
}
@ -1404,7 +1380,7 @@ const BasicUserInfo: React.FC<{
<div className="mx_UserInfo_container">
<h3>
{_t(
"Role in <RoomName/>",
"user_info|role_label",
{},
{
RoomName: () => <b>{room.name}</b>,
@ -1449,10 +1425,10 @@ const BasicUserInfo: React.FC<{
if (!cryptoEnabled) {
text = _t("This client does not support end-to-end encryption.");
} else if (room && !room.isSpaceRoom()) {
text = _t("Messages in this room are not end-to-end encrypted.");
text = _t("user_info|room_unencrypted");
}
} else if (!room.isSpaceRoom()) {
text = _t("Messages in this room are end-to-end encrypted.");
text = _t("user_info|room_encrypted");
}
let verifyButton;

View file

@ -180,10 +180,8 @@ export default class AliasSettings extends React.Component<IProps, IState> {
.catch((err) => {
logger.error(err);
Modal.createDialog(ErrorDialog, {
title: _t("Error updating main address"),
description: _t(
"There was an error updating the room's main address. It may not be allowed by the server or a temporary failure occurred.",
),
title: _t("room_settings|general|error_updating_canonical_alias_title"),
description: _t("room_settings|general|error_updating_canonical_alias_description"),
});
this.setState({ canonicalAlias: oldAlias });
})
@ -219,10 +217,8 @@ export default class AliasSettings extends React.Component<IProps, IState> {
// TODO: Add error handling based upon server validation
logger.error(err);
Modal.createDialog(ErrorDialog, {
title: _t("Error updating main address"),
description: _t(
"There was an error updating the room's alternative addresses. It may not be allowed by the server or a temporary failure occurred.",
),
title: _t("room_settings|general|error_updating_canonical_alias_title"),
description: _t("room_settings|general|error_updating_alias_description"),
});
})
.finally(() => {
@ -254,10 +250,8 @@ export default class AliasSettings extends React.Component<IProps, IState> {
.catch((err) => {
logger.error(err);
Modal.createDialog(ErrorDialog, {
title: _t("Error creating address"),
description: _t(
"There was an error creating that address. It may not be allowed by the server or a temporary failure occurred.",
),
title: _t("room_settings|general|error_creating_alias_title"),
description: _t("room_settings|general|error_creating_alias_description"),
});
});
};
@ -280,14 +274,12 @@ export default class AliasSettings extends React.Component<IProps, IState> {
logger.error(err);
let description;
if (err.errcode === "M_FORBIDDEN") {
description = _t("You don't have permission to delete the address.");
description = _t("room_settings|general|error_deleting_alias_description_forbidden");
} else {
description = _t(
"There was an error removing that address. It may no longer exist or a temporary error occurred.",
);
description = _t("room_settings|general|error_deleting_alias_description");
}
Modal.createDialog(ErrorDialog, {
title: _t("Error removing address"),
title: _t("room_settings|general|error_deleting_alias_title"),
description,
});
});
@ -350,7 +342,7 @@ export default class AliasSettings extends React.Component<IProps, IState> {
disabled={this.state.updatingCanonicalAlias || !this.props.canSetCanonicalAlias}
element="select"
id="canonicalAlias"
label={_t("Main address")}
label={_t("room_settings|general|canonical_alias_field_label")}
>
<option value="" key="unset">
{_t("not specified")}
@ -388,9 +380,11 @@ export default class AliasSettings extends React.Component<IProps, IState> {
onItemAdded={this.onLocalAliasAdded}
onItemRemoved={this.onLocalAliasDeleted}
noItemsLabel={
isSpaceRoom ? _t("This space has no local addresses") : _t("This room has no local addresses")
isSpaceRoom
? _t("room_settings|general|no_aliases_space")
: _t("room_settings|general|no_aliases_room")
}
placeholder={_t("Local address")}
placeholder={_t("room_settings|general|local_alias_field_label")}
domain={localDomain}
/>
);
@ -400,14 +394,14 @@ export default class AliasSettings extends React.Component<IProps, IState> {
<>
<SettingsFieldset
data-testid="published-address-fieldset"
legend={_t("Published Addresses")}
legend={_t("room_settings|general|published_aliases_section")}
description={
<>
{isSpaceRoom
? _t("Published addresses can be used by anyone on any server to join your space.")
: _t("Published addresses can be used by anyone on any server to join your room.")}
? _t("room_settings|general|published_aliases_explainer_space")
: _t("room_settings|general|published_aliases_explainer_room")}
&nbsp;
{_t("To publish an address, it needs to be set as a local address first.")}
{_t("room_settings|general|published_aliases_description")}
</>
}
>
@ -434,30 +428,24 @@ export default class AliasSettings extends React.Component<IProps, IState> {
onItemAdded={this.onAltAliasAdded}
onItemRemoved={this.onAltAliasDeleted}
suggestionsListId="mx_AliasSettings_altRecommendations"
itemsLabel={_t("Other published addresses:")}
noItemsLabel={_t("No other published addresses yet, add one below")}
placeholder={_t("New published address (e.g. #alias:server)")}
itemsLabel={_t("room_settings|general|aliases_items_label")}
noItemsLabel={_t("room_settings|general|aliases_no_items_label")}
placeholder={_t("room_settings|general|new_alias_placeholder")}
roomId={this.props.roomId}
/>
</SettingsFieldset>
<SettingsFieldset
data-testid="local-address-fieldset"
legend={_t("Local Addresses")}
legend={_t("room_settings|general|local_aliases_section")}
description={
isSpaceRoom
? _t(
"Set addresses for this space so users can find this space through your homeserver (%(localDomain)s)",
{ localDomain },
)
: _t(
"Set addresses for this room so users can find this room through your homeserver (%(localDomain)s)",
{ localDomain },
)
? _t("room_settings|general|local_aliases_explainer_space", { localDomain })
: _t("room_settings|general|local_aliases_explainer_room", { localDomain })
}
>
<details onToggle={this.onLocalAliasesToggled} open={this.state.detailsOpen}>
<summary className="mx_AliasSettings_localAddresses">
{this.state.detailsOpen ? _t("room_list|show_less") : _t("Show more")}
{this.state.detailsOpen ? _t("room_list|show_less") : _t("common|show_more")}
</summary>
{localAliasesList}
</details>

View file

@ -248,7 +248,7 @@ export default class RoomProfileSettings extends React.Component<IProps, IState>
<div className="mx_ProfileSettings_profile">
<div className="mx_ProfileSettings_profile_controls">
<Field
label={_t("Room Name")}
label={_t("room_settings|general|name_field_label")}
type="text"
value={this.state.displayName}
autoComplete="off"
@ -261,7 +261,7 @@ export default class RoomProfileSettings extends React.Component<IProps, IState>
"mx_ProfileSettings_profile_controls_topic--room",
)}
id="profileTopic" // See: NewRoomIntro.tsx
label={_t("Room Topic")}
label={_t("room_settings|general|topic_field_label")}
disabled={!this.state.canSetTopic}
type="text"
value={this.state.topic}
@ -273,7 +273,7 @@ export default class RoomProfileSettings extends React.Component<IProps, IState>
<AvatarSetting
avatarUrl={this.state.avatarUrl ?? undefined}
avatarName={this.state.displayName || this.props.roomId}
avatarAltText={_t("Room avatar")}
avatarAltText={_t("room_settings|general|avatar_field_label")}
uploadAvatar={this.state.canSetAvatar ? this.uploadAvatar : undefined}
removeAvatar={this.state.canSetAvatar ? this.removeAvatar : undefined}
/>

View file

@ -33,14 +33,14 @@ export enum E2EState {
}
const crossSigningUserTitles: { [key in E2EState]?: TranslationKey } = {
[E2EState.Warning]: _td("This user has not verified all of their sessions."),
[E2EState.Normal]: _td("You have not verified this user."),
[E2EState.Verified]: _td("You have verified this user. This user has verified all of their sessions."),
[E2EState.Warning]: _td("encryption|cross_signing_user_warning"),
[E2EState.Normal]: _td("encryption|cross_signing_user_normal"),
[E2EState.Verified]: _td("encryption|cross_signing_user_verified"),
};
const crossSigningRoomTitles: { [key in E2EState]?: TranslationKey } = {
[E2EState.Warning]: _td("Someone is using an unknown session"),
[E2EState.Normal]: _td("This room is end-to-end encrypted"),
[E2EState.Verified]: _td("Everyone in this room is verified"),
[E2EState.Warning]: _td("encryption|cross_signing_room_warning"),
[E2EState.Normal]: _td("encryption|cross_signing_room_normal"),
[E2EState.Verified]: _td("encryption|cross_signing_room_verified"),
};
interface Props {

View file

@ -482,7 +482,7 @@ class EditMessageComposer extends React.Component<IEditMessageComposerProps, ISt
room={room}
threadId={this.props.editState?.getEvent()?.getThread()?.id}
initialCaret={this.props.editState.getCaret() ?? undefined}
label={_t("Edit message")}
label={_t("composer|edit_composer_label")}
onChange={this.onChange}
/>
<div className="mx_EditMessageComposer_buttons">

View file

@ -512,12 +512,12 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
if (this.props.highlightLink) {
return (
<a className="mx_ThreadSummary_icon" href={this.props.highlightLink}>
{_t("From a thread")}
{_t("timeline|thread_info_basic")}
</a>
);
}
return <p className="mx_ThreadSummary_icon">{_t("From a thread")}</p>;
return <p className="mx_ThreadSummary_icon">{_t("timeline|thread_info_basic")}</p>;
}
}
@ -741,25 +741,23 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
break;
case EventShieldReason.UNVERIFIED_IDENTITY:
shieldReasonMessage = _t("Encrypted by an unverified user.");
shieldReasonMessage = _t("encryption|event_shield_reason_unverified_identity");
break;
case EventShieldReason.UNSIGNED_DEVICE:
shieldReasonMessage = _t("Encrypted by a device not verified by its owner.");
shieldReasonMessage = _t("encryption|event_shield_reason_unsigned_device");
break;
case EventShieldReason.UNKNOWN_DEVICE:
shieldReasonMessage = _t("Encrypted by an unknown or deleted device.");
shieldReasonMessage = _t("encryption|event_shield_reason_unknown_device");
break;
case EventShieldReason.AUTHENTICITY_NOT_GUARANTEED:
shieldReasonMessage = _t(
"The authenticity of this encrypted message can't be guaranteed on this device.",
);
shieldReasonMessage = _t("encryption|event_shield_reason_authenticity_not_guaranteed");
break;
case EventShieldReason.MISMATCHED_SENDER_KEY:
shieldReasonMessage = _t("Encrypted by an unverified session");
shieldReasonMessage = _t("encryption|event_shield_reason_mismatched_sender_key");
break;
}
@ -936,7 +934,7 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
logger.warn(`Event type not supported: type:${eventType} isState:${mxEvent.isState()}`);
return (
<div className="mx_EventTile mx_EventTile_info mx_MNoticeBody">
<div className="mx_EventTile_line">{_t("This event could not be displayed")}</div>
<div className="mx_EventTile_line">{_t("timeline|error_no_renderer")}</div>
</div>
);
}
@ -1468,16 +1466,12 @@ const SafeEventTile = forwardRef<UnwrappedEventTile, EventTileProps>((props, ref
export default SafeEventTile;
function E2ePadlockUnencrypted(props: Omit<IE2ePadlockProps, "title" | "icon">): JSX.Element {
return <E2ePadlock title={_t("Unencrypted")} icon={E2ePadlockIcon.Warning} {...props} />;
return <E2ePadlock title={_t("common|unencrypted")} icon={E2ePadlockIcon.Warning} {...props} />;
}
function E2ePadlockDecryptionFailure(props: Omit<IE2ePadlockProps, "title" | "icon">): JSX.Element {
return (
<E2ePadlock
title={_t("This message could not be decrypted")}
icon={E2ePadlockIcon.DecryptionFailure}
{...props}
/>
<E2ePadlock title={_t("timeline|undecryptable_tooltip")} icon={E2ePadlockIcon.DecryptionFailure} {...props} />
);
}
@ -1556,13 +1550,13 @@ function SentReceipt({ messageState }: ISentReceiptProps): JSX.Element {
nonCssBadge = <NotificationBadge notification={StaticNotificationState.RED_EXCLAMATION} />;
}
let label = _t("Sending your message…");
let label = _t("timeline|send_state_sending");
if (messageState === "encrypting") {
label = _t("Encrypting your message…");
label = _t("timeline|send_state_encrypting");
} else if (isSent) {
label = _t("Your message was sent");
label = _t("timeline|send_state_sent");
} else if (isFailed) {
label = _t("Failed to send");
label = _t("timeline|send_state_failed");
}
const [{ showTooltip, hideTooltip }, tooltip] = useTooltip({
id: tooltipId,

View file

@ -31,11 +31,11 @@ export function EventTileThreadToolbar({
copyLinkToThread: (evt: ButtonEvent) => void;
}): JSX.Element {
return (
<Toolbar className="mx_MessageActionBar" aria-label={_t("Message Actions")} aria-live="off">
<Toolbar className="mx_MessageActionBar" aria-label={_t("timeline|mab|label")} aria-live="off">
<RovingAccessibleTooltipButton
className="mx_MessageActionBar_iconButton"
onClick={viewInRoom}
title={_t("View in room")}
title={_t("timeline|mab|view_in_room")}
key="view_in_room"
>
<ViewInRoomIcon />
@ -43,7 +43,7 @@ export function EventTileThreadToolbar({
<RovingAccessibleTooltipButton
className="mx_MessageActionBar_iconButton"
onClick={copyLinkToThread}
title={_t("Copy link to thread")}
title={_t("timeline|mab|copy_link_thread")}
key="copy_link_to_thread"
>
<LinkIcon />

View file

@ -39,7 +39,7 @@ const JumpToBottomButton: React.FC<IProps> = (props) => {
<div className={className}>
<AccessibleButton
className="mx_JumpToBottomButton_scrollDown"
title={_t("Scroll to most recent messages")}
title={_t("room|jump_to_bottom_button")}
onClick={props.onScrollToBottomClick}
/>
{badge}

View file

@ -118,7 +118,7 @@ export default class PinnedEventTile extends React.Component<IProps> {
</span>
<AccessibleButton onClick={this.onTileClicked} kind="link">
{_t("View message")}
{_t("common|view_message")}
</AccessibleButton>
</div>
</div>

View file

@ -120,9 +120,7 @@ export default class ReplyTile extends React.PureComponent<IProps> {
const { mxEvent } = this.props;
logger.warn(`Event type not supported: type:${mxEvent.getType()} isState:${mxEvent.isState()}`);
return (
<div className="mx_ReplyTile mx_ReplyTile_info mx_MNoticeBody">
{_t("This event could not be displayed")}
</div>
<div className="mx_ReplyTile mx_ReplyTile_info mx_MNoticeBody">{_t("timeline|error_no_renderer")}</div>
);
}

View file

@ -184,7 +184,7 @@ const RoomPreviewCard: FC<IProps> = ({ room, onJoinButtonClicked, onRejectButton
joinButtons = (
<AccessibleButton kind="primary" onClick={viewLabs}>
{_t("Show Labs settings")}
{_t("room|show_labs_settings")}
</AccessibleButton>
);
}

View file

@ -41,7 +41,7 @@ export const RoomTileCallSummary: FC<Props> = ({ call }) => {
break;
case ConnectionState.Connected:
case ConnectionState.Disconnecting:
text = _t("Joined");
text = _t("common|joined");
active = true;
break;
}

View file

@ -71,11 +71,7 @@ export default class RoomUpgradeWarningBar extends React.PureComponent<IProps, I
let doUpgradeWarnings = (
<div>
<div className="mx_RoomUpgradeWarningBar_body">
<p>
{_t(
"Upgrading this room will shut down the current instance of the room and create an upgraded room with the same name.",
)}
</p>
<p>{_t("room|upgrade_warning_bar")}</p>
<p>
{_t(
"room_settings|advanced|room_upgrade_warning",
@ -98,7 +94,7 @@ export default class RoomUpgradeWarningBar extends React.PureComponent<IProps, I
if (this.state.upgraded) {
doUpgradeWarnings = (
<div className="mx_RoomUpgradeWarningBar_body">
<p>{_t("This room has already been upgraded.")}</p>
<p>{_t("room|upgrade_warning_bar_upgraded")}</p>
</div>
);
}
@ -108,7 +104,7 @@ export default class RoomUpgradeWarningBar extends React.PureComponent<IProps, I
<div className="mx_RoomUpgradeWarningBar_wrapped">
<div className="mx_RoomUpgradeWarningBar_header">
{_t(
"This room is running room version <roomVersion />, which this homeserver has marked as <i>unstable</i>.",
"room|upgrade_warning_bar_unstable",
{},
{
roomVersion: () => <code>{this.props.room.getVersion()}</code>,
@ -117,9 +113,7 @@ export default class RoomUpgradeWarningBar extends React.PureComponent<IProps, I
)}
</div>
{doUpgradeWarnings}
<div className="mx_RoomUpgradeWarningBar_small">
{_t("Only room administrators will see this warning")}
</div>
<div className="mx_RoomUpgradeWarningBar_small">{_t("room|upgrade_warning_bar_admins")}</div>
</div>
</div>
);

View file

@ -104,7 +104,7 @@ export default class SearchBar extends React.Component<IProps, IState> {
aria-checked={this.state.scope === SearchScope.Room}
role="radio"
>
{_t("This Room")}
{_t("room|search|this_room")}
</AccessibleButton>
<AccessibleButton
className={allRoomsClasses}
@ -112,7 +112,7 @@ export default class SearchBar extends React.Component<IProps, IState> {
aria-checked={this.state.scope === SearchScope.All}
role="radio"
>
{_t("All Rooms")}
{_t("room|search|all_rooms")}
</AccessibleButton>
</div>
<div className="mx_SearchBar_input mx_textinput">
@ -120,9 +120,11 @@ export default class SearchBar extends React.Component<IProps, IState> {
ref={this.searchTerm}
type="text"
autoFocus={true}
placeholder={_t("Search…")}
placeholder={_t("room|search|field_placeholder")}
aria-label={
this.state.scope === SearchScope.Room ? _t("Search this room") : _t("Search all rooms")
this.state.scope === SearchScope.Room
? _t("room|search|this_room_button")
: _t("room|search|all_rooms_button")
}
onKeyDown={this.onSearchChange}
/>

View file

@ -94,7 +94,7 @@ export default class Stickerpicker extends React.PureComponent<IProps, IState> {
return this.scalarClient;
})
.catch((e) => {
this.imError(_td("Failed to connect to integration manager"), e);
this.imError(_td("integration_manager|error_connecting_heading"), e);
});
} else {
IntegrationManagers.sharedInstance().openNoManagerDialog();
@ -213,8 +213,8 @@ export default class Stickerpicker extends React.PureComponent<IProps, IState> {
private defaultStickerpickerContent(): JSX.Element {
return (
<AccessibleButton onClick={this.launchManageIntegrations} className="mx_Stickers_contentPlaceholder">
<p>{_t("You don't currently have any stickerpacks enabled")}</p>
<p className="mx_Stickers_addLink">{_t("Add some now")}</p>
<p>{_t("stickers|empty")}</p>
<p className="mx_Stickers_addLink">{_t("stickers|empty_add_prompt")}</p>
<img src={require("../../../../res/img/stickerpack-placeholder.png")} alt="" />
</AccessibleButton>
);

View file

@ -106,10 +106,8 @@ export default class ThirdPartyMemberInfo extends React.Component<IProps, IState
this.setState({ invited: true });
Modal.createDialog(ErrorDialog, {
title: _t("Failed to revoke invite"),
description: _t(
"Could not revoke the invite. The server may be experiencing a temporary problem or you do not have sufficient permissions to revoke the invite.",
),
title: _t("user_info|error_revoke_3pid_invite_title"),
description: _t("user_info|error_revoke_3pid_invite_description"),
});
});
@ -122,9 +120,9 @@ export default class ThirdPartyMemberInfo extends React.Component<IProps, IState
if (this.state.canKick && this.state.invited) {
adminTools = (
<div className="mx_MemberInfo_container">
<h3>{_t("Admin Tools")}</h3>
<h3>{_t("user_info|admin_tools_section")}</h3>
<AccessibleButton className="mx_MemberInfo_field" onClick={this.onKickClick}>
{_t("Revoke invite")}
{_t("user_info|revoke_invite")}
</AccessibleButton>
</div>
);
@ -153,7 +151,7 @@ export default class ThirdPartyMemberInfo extends React.Component<IProps, IState
<h2>{this.state.displayName}</h2>
</div>
<div className="mx_MemberInfo_container mx_MemberInfo_container--profile">
{_t("Invited by %(sender)s", { sender: this.state.senderName })}
{_t("user_info|invited_by", { sender: this.state.senderName })}
</div>
{adminTools}
</div>

View file

@ -59,7 +59,7 @@ const ThreadSummary: React.FC<IProps> = ({ mxEvent, thread, ...props }) => {
});
PosthogTrackers.trackInteraction("WebRoomTimelineThreadSummaryButton", ev);
}}
aria-label={_t("Open thread")}
aria-label={_t("threads|open_thread")}
>
<span className="mx_ThreadSummary_replies_amount">{countSection}</span>
<ThreadMessagePreview thread={thread} showDisplayname={!roomContext.narrow} />
@ -111,9 +111,9 @@ export const ThreadMessagePreview: React.FC<IPreviewProps> = ({ thread, showDisp
{lastReply.isDecryptionFailure() ? (
<div
className="mx_ThreadSummary_content mx_DecryptionFailureBody"
title={_t("Unable to decrypt message")}
title={_t("threads|unable_to_decrypt")}
>
<span className="mx_ThreadSummary_message-preview">{_t("Unable to decrypt message")}</span>
<span className="mx_ThreadSummary_message-preview">{_t("threads|unable_to_decrypt")}</span>
</div>
) : (
<div className="mx_ThreadSummary_content" title={preview}>

View file

@ -30,7 +30,7 @@ export default class TopUnreadMessagesBar extends React.PureComponent<IProps> {
<div className="mx_TopUnreadMessagesBar">
<AccessibleButton
className="mx_TopUnreadMessagesBar_scrollUp"
title={_t("Jump to first unread message.")}
title={_t("room|jump_read_marker")}
onClick={this.props.onScrollUpClick}
/>
<AccessibleButton

View file

@ -180,14 +180,10 @@ export default class VoiceRecordComposerTile extends React.PureComponent<IProps,
// The "microphone access error" dialogs are used a lot, so let's functionify them
const accessError = (): void => {
Modal.createDialog(ErrorDialog, {
title: _t("Unable to access your microphone"),
title: _t("voip|unable_to_access_audio_input_title"),
description: (
<>
<p>
{_t(
"We were unable to access your microphone. Please check your browser settings and try again.",
)}
</p>
<p>{_t("voip|unable_to_access_audio_input_description")}</p>
</>
),
});
@ -199,14 +195,10 @@ export default class VoiceRecordComposerTile extends React.PureComponent<IProps,
const devices = await MediaDeviceHandler.getDevices();
if (!devices?.[MediaDeviceKindEnum.AudioInput]?.length) {
Modal.createDialog(ErrorDialog, {
title: _t("No microphone found"),
title: _t("voip|no_audio_input_title"),
description: (
<>
<p>
{_t(
"We didn't find a microphone on your device. Please check your settings and try again.",
)}
</p>
<p>{_t("voip|no_audio_input_description")}</p>
</>
),
});
@ -273,9 +265,9 @@ export default class VoiceRecordComposerTile extends React.PureComponent<IProps,
let stopBtn;
let deleteButton;
if (this.state.recordingPhase === RecordingState.Started) {
let tooltip = _t("Send voice message");
let tooltip = _t("composer|send_voice_message");
if (!!this.state.recorder) {
tooltip = _t("Stop recording");
tooltip = _t("composer|stop_voice_message");
}
stopBtn = (
@ -316,7 +308,7 @@ export default class VoiceRecordComposerTile extends React.PureComponent<IProps,
notification={StaticNotificationState.forSymbol("!", NotificationColor.Red)}
/>
</span>
<span className="text-warning">{_t("Failed to send")}</span>
<span className="text-warning">{_t("timeline|send_state_failed")}</span>
</span>
);
}

View file

@ -71,7 +71,7 @@ export const LinkModal: React.FC<LinkModalProps> = ({
return (
<BaseDialog
className="mx_LinkModal"
title={isEditing ? _t("Edit link") : _t("Create a link")}
title={isEditing ? _t("composer|link_modal|title_edit") : _t("composer|link_modal|title_create")}
hasCancel={true}
onFinished={onFinished}
>
@ -96,7 +96,7 @@ export const LinkModal: React.FC<LinkModalProps> = ({
<Field
required={true}
autoFocus={true}
label={_t("Text")}
label={_t("composer|link_modal|text_field_label")}
value={fields.text}
className="mx_LinkModal_Field"
placeholder=""
@ -108,7 +108,7 @@ export const LinkModal: React.FC<LinkModalProps> = ({
<Field
required={true}
autoFocus={!hasText}
label={_t("Link")}
label={_t("composer|link_modal|link_field_label")}
value={fields.link}
className="mx_LinkModal_Field"
placeholder=""

View file

@ -346,14 +346,12 @@ export default class SecureBackupPanel extends React.PureComponent<{}, IState> {
<SettingsSubsectionText>
{_t("settings|security|key_backup_inactive_warning", {}, { b: (sub) => <b>{sub}</b> })}
</SettingsSubsectionText>
<SettingsSubsectionText>
{_t("Back up your keys before signing out to avoid losing them.")}
</SettingsSubsectionText>
<SettingsSubsectionText>{_t("encryption|setup_secure_backup|explainer")}</SettingsSubsectionText>
</>
);
actions.push(
<AccessibleButton key="setup" kind="primary" onClick={this.startNewBackup}>
{_t("Set up")}
{_t("encryption|setup_secure_backup|title")}
</AccessibleButton>,
);
}