Fix instances of double translation and guard translation calls using typescript (#11443)
Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>
This commit is contained in:
parent
d13b6e1b41
commit
ac70f7ac9b
157 changed files with 554 additions and 780 deletions
|
@ -17,7 +17,7 @@ limitations under the License.
|
|||
import React, { PureComponent, RefCallback, RefObject } from "react";
|
||||
|
||||
import Field, { IInputProps } from "../elements/Field";
|
||||
import { _t, _td } from "../../../languageHandler";
|
||||
import { _t, _td, TranslationKey } from "../../../languageHandler";
|
||||
import withValidation, { IFieldState, IValidationResult } from "../elements/Validation";
|
||||
import * as Email from "../../../email";
|
||||
|
||||
|
@ -27,9 +27,9 @@ interface IProps extends Omit<IInputProps, "onValidate" | "element"> {
|
|||
value: string;
|
||||
autoFocus?: boolean;
|
||||
|
||||
label?: string;
|
||||
labelRequired?: string;
|
||||
labelInvalid?: string;
|
||||
label: TranslationKey;
|
||||
labelRequired: TranslationKey;
|
||||
labelInvalid: TranslationKey;
|
||||
|
||||
// When present, completely overrides the default validation rules.
|
||||
validationRules?: (fieldState: IFieldState) => Promise<IValidationResult>;
|
||||
|
@ -50,12 +50,12 @@ class EmailField extends PureComponent<IProps> {
|
|||
{
|
||||
key: "required",
|
||||
test: ({ value, allowEmpty }) => allowEmpty || !!value,
|
||||
invalid: () => _t(this.props.labelRequired!),
|
||||
invalid: () => _t(this.props.labelRequired),
|
||||
},
|
||||
{
|
||||
key: "email",
|
||||
test: ({ value }) => !value || Email.looksValid(value),
|
||||
invalid: () => _t(this.props.labelInvalid!),
|
||||
invalid: () => _t(this.props.labelInvalid),
|
||||
},
|
||||
],
|
||||
});
|
||||
|
@ -80,7 +80,7 @@ class EmailField extends PureComponent<IProps> {
|
|||
id={this.props.id}
|
||||
ref={this.props.fieldRef}
|
||||
type="text"
|
||||
label={_t(this.props.label!)}
|
||||
label={_t(this.props.label)}
|
||||
value={this.props.value}
|
||||
autoFocus={this.props.autoFocus}
|
||||
onChange={this.props.onChange}
|
||||
|
|
|
@ -220,8 +220,7 @@ export class RecaptchaAuthEntry extends React.Component<IRecaptchaAuthEntryProps
|
|||
let sitePublicKey: string | undefined;
|
||||
if (!this.props.stageParams || !this.props.stageParams.public_key) {
|
||||
errorText = _t(
|
||||
"Missing captcha public key in homeserver configuration. Please report " +
|
||||
"this to your homeserver administrator.",
|
||||
"Missing captcha public key in homeserver configuration. Please report this to your homeserver administrator.",
|
||||
);
|
||||
} else {
|
||||
sitePublicKey = this.props.stageParams.public_key;
|
||||
|
|
|
@ -18,7 +18,7 @@ import React, { PureComponent, RefCallback, RefObject } from "react";
|
|||
|
||||
import Field, { IInputProps } from "../elements/Field";
|
||||
import withValidation, { IFieldState, IValidationResult } from "../elements/Validation";
|
||||
import { _t, _td } from "../../../languageHandler";
|
||||
import { _t, _td, TranslationKey } from "../../../languageHandler";
|
||||
|
||||
interface IProps extends Omit<IInputProps, "onValidate" | "label" | "element"> {
|
||||
id?: string;
|
||||
|
@ -27,9 +27,9 @@ interface IProps extends Omit<IInputProps, "onValidate" | "label" | "element"> {
|
|||
value: string;
|
||||
password: string; // The password we're confirming
|
||||
|
||||
label: string;
|
||||
labelRequired: string;
|
||||
labelInvalid: string;
|
||||
label: TranslationKey;
|
||||
labelRequired: TranslationKey;
|
||||
labelInvalid: TranslationKey;
|
||||
|
||||
onChange(ev: React.FormEvent<HTMLElement>): void;
|
||||
onValidate?(result: IValidationResult): void;
|
||||
|
|
|
@ -20,7 +20,7 @@ import zxcvbn from "zxcvbn";
|
|||
|
||||
import SdkConfig from "../../../SdkConfig";
|
||||
import withValidation, { IFieldState, IValidationResult } from "../elements/Validation";
|
||||
import { _t, _td } from "../../../languageHandler";
|
||||
import { _t, _td, TranslationKey } from "../../../languageHandler";
|
||||
import Field, { IInputProps } from "../elements/Field";
|
||||
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
||||
|
||||
|
@ -34,10 +34,10 @@ interface IProps extends Omit<IInputProps, "onValidate" | "element"> {
|
|||
// Additional strings such as a username used to catch bad passwords
|
||||
userInputs?: string[];
|
||||
|
||||
label: string;
|
||||
labelEnterPassword: string;
|
||||
labelStrongPassword: string;
|
||||
labelAllowedButUnsafe: string;
|
||||
label: TranslationKey;
|
||||
labelEnterPassword: TranslationKey;
|
||||
labelStrongPassword: TranslationKey;
|
||||
labelAllowedButUnsafe: TranslationKey;
|
||||
|
||||
onChange(ev: React.FormEvent<HTMLElement>): void;
|
||||
onValidate?(result: IValidationResult): void;
|
||||
|
|
|
@ -19,9 +19,9 @@ import React, { useEffect, useState } from "react";
|
|||
import MediaDeviceHandler, { MediaDeviceKindEnum } from "../../../MediaDeviceHandler";
|
||||
import IconizedContextMenu, { IconizedContextMenuOptionList, IconizedContextMenuRadio } from "./IconizedContextMenu";
|
||||
import { IProps as IContextMenuProps } from "../../structures/ContextMenu";
|
||||
import { _t, _td } from "../../../languageHandler";
|
||||
import { _t, _td, TranslationKey } from "../../../languageHandler";
|
||||
|
||||
const SECTION_NAMES: Record<MediaDeviceKindEnum, string> = {
|
||||
const SECTION_NAMES: Record<MediaDeviceKindEnum, TranslationKey> = {
|
||||
[MediaDeviceKindEnum.AudioInput]: _td("Input devices"),
|
||||
[MediaDeviceKindEnum.AudioOutput]: _td("Output devices"),
|
||||
[MediaDeviceKindEnum.VideoInput]: _td("Cameras"),
|
||||
|
|
|
@ -192,8 +192,7 @@ export const WidgetContextMenu: React.FC<IProps> = ({
|
|||
Modal.createDialog(QuestionDialog, {
|
||||
title: _t("Delete Widget"),
|
||||
description: _t(
|
||||
"Deleting a widget removes it for all users in this room." +
|
||||
" Are you sure you want to delete this widget?",
|
||||
"Deleting a widget removes it for all users in this room. Are you sure you want to delete this widget?",
|
||||
),
|
||||
button: _t("Delete widget"),
|
||||
onFinished: (confirmed) => {
|
||||
|
|
|
@ -20,7 +20,7 @@ import { Room, EventType } from "matrix-js-sdk/src/matrix";
|
|||
import { sleep } from "matrix-js-sdk/src/utils";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
|
||||
import { _t, _td } from "../../../languageHandler";
|
||||
import { _t, _td, TranslationKey } from "../../../languageHandler";
|
||||
import BaseDialog from "./BaseDialog";
|
||||
import Dropdown from "../elements/Dropdown";
|
||||
import SearchBox from "../../structures/SearchBox";
|
||||
|
@ -357,7 +357,7 @@ export const AddExistingToSpace: React.FC<IAddExistingToSpaceProps> = ({
|
|||
};
|
||||
|
||||
const defaultRendererFactory =
|
||||
(title: string): Renderer =>
|
||||
(title: TranslationKey): Renderer =>
|
||||
(rooms, selectedToAdd, { scrollTop, height }, onChange) =>
|
||||
(
|
||||
<div className="mx_AddExistingToSpace_section">
|
||||
|
|
|
@ -78,9 +78,7 @@ export const AnalyticsLearnMoreDialog: React.FC<IProps> = ({
|
|||
<div className="mx_AnalyticsLearnMore_image_holder" />
|
||||
<div className="mx_AnalyticsLearnMore_copy">
|
||||
{_t(
|
||||
"Help us identify issues and improve %(analyticsOwner)s by sharing anonymous usage data. " +
|
||||
"To understand how people use multiple devices, we'll generate a random identifier, " +
|
||||
"shared by your devices.",
|
||||
"Help us identify issues and improve %(analyticsOwner)s by sharing anonymous usage data. To understand how people use multiple devices, we'll generate a random identifier, shared by your devices.",
|
||||
{ analyticsOwner },
|
||||
)}
|
||||
</div>
|
||||
|
|
|
@ -224,10 +224,7 @@ export default class BugReportDialog extends React.Component<IProps, IState> {
|
|||
{warning}
|
||||
<p>
|
||||
{_t(
|
||||
"Debug logs contain application usage data including your " +
|
||||
"username, the IDs or aliases of the rooms you " +
|
||||
"have visited, which UI elements you last interacted with, " +
|
||||
"and the usernames of other users. They do not contain messages.",
|
||||
"Debug logs contain application usage data including your username, the IDs or aliases of the rooms you have visited, which UI elements you last interacted with, and the usernames of other users. They do not contain messages.",
|
||||
)}
|
||||
</p>
|
||||
<p>
|
||||
|
@ -273,10 +270,7 @@ export default class BugReportDialog extends React.Component<IProps, IState> {
|
|||
onChange={this.onTextChange}
|
||||
value={this.state.text}
|
||||
placeholder={_t(
|
||||
"If there is additional context that would help in " +
|
||||
"analysing the issue, such as what you were doing at " +
|
||||
"the time, room IDs, user IDs, etc., " +
|
||||
"please include those things here.",
|
||||
"If there is additional context that would help in analysing the issue, such as what you were doing at the time, room IDs, user IDs, etc., please include those things here.",
|
||||
)}
|
||||
/>
|
||||
{progress}
|
||||
|
|
|
@ -114,16 +114,13 @@ const BulkRedactDialog: React.FC<Props> = (props) => {
|
|||
<div className="mx_Dialog_content" id="mx_Dialog_content">
|
||||
<p>
|
||||
{_t(
|
||||
"You are about to remove %(count)s messages by %(user)s. " +
|
||||
"This will remove them permanently for everyone in the conversation. " +
|
||||
"Do you wish to continue?",
|
||||
"You are about to remove %(count)s messages by %(user)s. This will remove them permanently for everyone in the conversation. Do you wish to continue?",
|
||||
{ count, user },
|
||||
)}
|
||||
</p>
|
||||
<p>
|
||||
{_t(
|
||||
"For a large amount of messages, this might take some time. " +
|
||||
"Please don't refresh your client in the meantime.",
|
||||
"For a large amount of messages, this might take some time. Please don't refresh your client in the meantime.",
|
||||
)}
|
||||
</p>
|
||||
<StyledCheckbox checked={keepStateEvents} onChange={(e) => setKeepStateEvents(e.target.checked)}>
|
||||
|
@ -131,8 +128,7 @@ const BulkRedactDialog: React.FC<Props> = (props) => {
|
|||
</StyledCheckbox>
|
||||
<div className="mx_BulkRedactDialog_checkboxMicrocopy">
|
||||
{_t(
|
||||
"Uncheck if you also want to remove system messages on this user " +
|
||||
"(e.g. membership change, profile change…)",
|
||||
"Uncheck if you also want to remove system messages on this user (e.g. membership change, profile change…)",
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -26,8 +26,7 @@ export const createCantStartVoiceMessageBroadcastDialog = (): void => {
|
|||
description: (
|
||||
<p>
|
||||
{_t(
|
||||
"You can't start a voice message as you are currently recording a live broadcast. " +
|
||||
"Please end your live broadcast in order to start recording a voice message.",
|
||||
"You can't start a voice message as you are currently recording a live broadcast. Please end your live broadcast in order to start recording a voice message.",
|
||||
)}
|
||||
</p>
|
||||
),
|
||||
|
|
|
@ -44,8 +44,7 @@ export default class ConfirmWipeDeviceDialog extends React.Component<IProps> {
|
|||
<div className="mx_ConfirmWipeDeviceDialog_content">
|
||||
<p>
|
||||
{_t(
|
||||
"Clearing all data from this session is permanent. Encrypted messages will be lost " +
|
||||
"unless their keys have been backed up.",
|
||||
"Clearing all data from this session is permanent. Encrypted messages will be lost unless their keys have been backed up.",
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
@ -311,8 +311,7 @@ export default class CreateRoomDialog extends React.Component<IProps, IState> {
|
|||
}
|
||||
} else {
|
||||
microcopy = _t(
|
||||
"Your server admin has disabled end-to-end encryption by default " +
|
||||
"in private rooms & Direct Messages.",
|
||||
"Your server admin has disabled end-to-end encryption by default in private rooms & Direct Messages.",
|
||||
);
|
||||
}
|
||||
e2eeSection = (
|
||||
|
@ -330,15 +329,13 @@ export default class CreateRoomDialog extends React.Component<IProps, IState> {
|
|||
}
|
||||
|
||||
let federateLabel = _t(
|
||||
"You might enable this if the room will only be used for collaborating with internal " +
|
||||
"teams on your homeserver. This cannot be changed later.",
|
||||
"You might enable this if the room will only be used for collaborating with internal teams on your homeserver. This cannot be changed later.",
|
||||
);
|
||||
if (SdkConfig.get().default_federate === false) {
|
||||
// We only change the label if the default setting is different to avoid jarring text changes to the
|
||||
// user. They will have read the implications of turning this off/on, so no need to rephrase for them.
|
||||
federateLabel = _t(
|
||||
"You might disable this if the room will be used for collaborating with external " +
|
||||
"teams who have their own homeserver. This cannot be changed later.",
|
||||
"You might disable this if the room will be used for collaborating with external teams who have their own homeserver. This cannot be changed later.",
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -36,9 +36,7 @@ const CryptoStoreTooNewDialog: React.FC<IProps> = (props: IProps) => {
|
|||
Modal.createDialog(QuestionDialog, {
|
||||
title: _t("Sign out"),
|
||||
description: _t(
|
||||
"To avoid losing your chat history, you must export your room keys " +
|
||||
"before logging out. You will need to go back to the newer version of " +
|
||||
"%(brand)s to do this",
|
||||
"To avoid losing your chat history, you must export your room keys before logging out. You will need to go back to the newer version of %(brand)s to do this",
|
||||
{ brand },
|
||||
),
|
||||
button: _t("Sign out"),
|
||||
|
@ -53,9 +51,7 @@ const CryptoStoreTooNewDialog: React.FC<IProps> = (props: IProps) => {
|
|||
};
|
||||
|
||||
const description = _t(
|
||||
"You've previously used a newer version of %(brand)s with this session. " +
|
||||
"To use this version again with end to end encryption, you will " +
|
||||
"need to sign out and back in again.",
|
||||
"You've previously used a newer version of %(brand)s with this session. To use this version again with end to end encryption, you will need to sign out and back in again.",
|
||||
{ brand },
|
||||
);
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ limitations under the License.
|
|||
|
||||
import React, { useState } from "react";
|
||||
|
||||
import { _t, _td } from "../../../languageHandler";
|
||||
import { _t, _td, TranslationKey } from "../../../languageHandler";
|
||||
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
||||
import BaseDialog from "./BaseDialog";
|
||||
import { TimelineEventEditor } from "./devtools/Event";
|
||||
|
@ -40,13 +40,13 @@ enum Category {
|
|||
Other,
|
||||
}
|
||||
|
||||
const categoryLabels: Record<Category, string> = {
|
||||
const categoryLabels: Record<Category, TranslationKey> = {
|
||||
[Category.Room]: _td("Room"),
|
||||
[Category.Other]: _td("Other"),
|
||||
};
|
||||
|
||||
export type Tool = React.FC<IDevtoolsProps> | ((props: IDevtoolsProps) => JSX.Element);
|
||||
const Tools: Record<Category, [label: string, tool: Tool][]> = {
|
||||
const Tools: Record<Category, [label: TranslationKey, tool: Tool][]> = {
|
||||
[Category.Room]: [
|
||||
[_td("Send custom timeline event"), TimelineEventEditor],
|
||||
[_td("Explore room state"), RoomStateExplorer],
|
||||
|
|
|
@ -70,9 +70,7 @@ export default class EndPollDialog extends React.Component<IProps> {
|
|||
<QuestionDialog
|
||||
title={_t("End Poll")}
|
||||
description={_t(
|
||||
"Are you sure you want to end this poll? " +
|
||||
"This will show the final results of the poll and " +
|
||||
"stop people from being able to vote.",
|
||||
"Are you sure you want to end this poll? This will show the final results of the poll and stop people from being able to vote.",
|
||||
)}
|
||||
button={_t("End Poll")}
|
||||
onFinished={(endPoll: boolean) => this.onFinished(endPoll)}
|
||||
|
|
|
@ -96,8 +96,7 @@ const FeedbackDialog: React.FC<IProps> = (props: IProps) => {
|
|||
bugReports = (
|
||||
<p className="mx_FeedbackDialog_section_microcopy">
|
||||
{_t(
|
||||
"PRO TIP: If you start a bug, please submit <debugLogsLink>debug logs</debugLogsLink> " +
|
||||
"to help us track down the problem.",
|
||||
"PRO TIP: If you start a bug, please submit <debugLogsLink>debug logs</debugLogsLink> to help us track down the problem.",
|
||||
{},
|
||||
{
|
||||
debugLogsLink: (sub) => (
|
||||
|
@ -125,8 +124,7 @@ const FeedbackDialog: React.FC<IProps> = (props: IProps) => {
|
|||
<h3>{_t("Report a bug")}</h3>
|
||||
<p>
|
||||
{_t(
|
||||
"Please view <existingIssuesLink>existing bugs on Github</existingIssuesLink> first. " +
|
||||
"No match? <newIssueLink>Start a new one</newIssueLink>.",
|
||||
"Please view <existingIssuesLink>existing bugs on Github</existingIssuesLink> first. No match? <newIssueLink>Start a new one</newIssueLink>.",
|
||||
{},
|
||||
{
|
||||
existingIssuesLink: (sub) => {
|
||||
|
|
|
@ -181,17 +181,14 @@ export default class IncomingSasDialog extends React.Component<IProps, IState> {
|
|||
const userDetailText = [
|
||||
<p key="p1">
|
||||
{_t(
|
||||
"Verify this user to mark them as trusted. " +
|
||||
"Trusting users gives you extra peace of mind when using " +
|
||||
"end-to-end encrypted messages.",
|
||||
"Verify this user to mark them as trusted. Trusting users gives you extra peace of mind when using end-to-end encrypted messages.",
|
||||
)}
|
||||
</p>,
|
||||
<p key="p2">
|
||||
{_t(
|
||||
// NB. Below wording adjusted to singular 'session' until we have
|
||||
// cross-signing
|
||||
"Verifying this user will mark their session as trusted, and " +
|
||||
"also mark your session as trusted to them.",
|
||||
"Verifying this user will mark their session as trusted, and also mark your session as trusted to them.",
|
||||
)}
|
||||
</p>,
|
||||
];
|
||||
|
@ -199,15 +196,12 @@ export default class IncomingSasDialog extends React.Component<IProps, IState> {
|
|||
const selfDetailText = [
|
||||
<p key="p1">
|
||||
{_t(
|
||||
"Verify this device to mark it as trusted. " +
|
||||
"Trusting this device gives you and other users extra peace of mind when using " +
|
||||
"end-to-end encrypted messages.",
|
||||
"Verify this device to mark it as trusted. Trusting this device gives you and other users extra peace of mind when using end-to-end encrypted messages.",
|
||||
)}
|
||||
</p>,
|
||||
<p key="p2">
|
||||
{_t(
|
||||
"Verifying this device will mark it as trusted, and users who have verified with " +
|
||||
"you will trust this device.",
|
||||
"Verifying this device will mark it as trusted, and users who have verified with you will trust this device.",
|
||||
)}
|
||||
</p>,
|
||||
];
|
||||
|
|
|
@ -43,8 +43,7 @@ export default class IntegrationsImpossibleDialog extends React.Component<IProps
|
|||
<div className="mx_IntegrationsImpossibleDialog_content">
|
||||
<p>
|
||||
{_t(
|
||||
"Your %(brand)s doesn't allow you to use an integration manager to do this. " +
|
||||
"Please contact an admin.",
|
||||
"Your %(brand)s doesn't allow you to use an integration manager to do this. Please contact an admin.",
|
||||
{ brand },
|
||||
)}
|
||||
</p>
|
||||
|
|
|
@ -1133,9 +1133,7 @@ export default class InviteDialog extends React.PureComponent<Props, IInviteDial
|
|||
return (
|
||||
<div className="mx_InviteDialog_identityServer">
|
||||
{_t(
|
||||
"Use an identity server to invite by email. " +
|
||||
"<default>Use the default (%(defaultIdentityServerName)s)</default> " +
|
||||
"or manage in <settings>Settings</settings>.",
|
||||
"Use an identity server to invite by email. <default>Use the default (%(defaultIdentityServerName)s)</default> or manage in <settings>Settings</settings>.",
|
||||
{
|
||||
defaultIdentityServerName: abbreviateUrl(defaultIdentityServerUrl),
|
||||
},
|
||||
|
@ -1158,7 +1156,7 @@ export default class InviteDialog extends React.PureComponent<Props, IInviteDial
|
|||
return (
|
||||
<div className="mx_InviteDialog_identityServer">
|
||||
{_t(
|
||||
"Use an identity server to invite by email. " + "Manage in <settings>Settings</settings>.",
|
||||
"Use an identity server to invite by email. Manage in <settings>Settings</settings>.",
|
||||
{},
|
||||
{
|
||||
settings: (sub) => (
|
||||
|
@ -1349,23 +1347,21 @@ export default class InviteDialog extends React.PureComponent<Props, IInviteDial
|
|||
if (isSpace) {
|
||||
if (identityServersEnabled) {
|
||||
helpTextUntranslated = _td(
|
||||
"Invite someone using their name, email address, username " +
|
||||
"(like <userId/>) or <a>share this space</a>.",
|
||||
"Invite someone using their name, email address, username (like <userId/>) or <a>share this space</a>.",
|
||||
);
|
||||
} else {
|
||||
helpTextUntranslated = _td(
|
||||
"Invite someone using their name, username " + "(like <userId/>) or <a>share this space</a>.",
|
||||
"Invite someone using their name, username (like <userId/>) or <a>share this space</a>.",
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if (identityServersEnabled) {
|
||||
helpTextUntranslated = _td(
|
||||
"Invite someone using their name, email address, username " +
|
||||
"(like <userId/>) or <a>share this room</a>.",
|
||||
"Invite someone using their name, email address, username (like <userId/>) or <a>share this room</a>.",
|
||||
);
|
||||
} else {
|
||||
helpTextUntranslated = _td(
|
||||
"Invite someone using their name, username " + "(like <userId/>) or <a>share this room</a>.",
|
||||
"Invite someone using their name, username (like <userId/>) or <a>share this room</a>.",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,19 +29,14 @@ interface IProps {
|
|||
const LazyLoadingDisabledDialog: React.FC<IProps> = (props) => {
|
||||
const brand = SdkConfig.get().brand;
|
||||
const description1 = _t(
|
||||
"You've previously used %(brand)s on %(host)s with lazy loading of members enabled. " +
|
||||
"In this version lazy loading is disabled. " +
|
||||
"As the local cache is not compatible between these two settings, " +
|
||||
"%(brand)s needs to resync your account.",
|
||||
"You've previously used %(brand)s on %(host)s with lazy loading of members enabled. In this version lazy loading is disabled. As the local cache is not compatible between these two settings, %(brand)s needs to resync your account.",
|
||||
{
|
||||
brand,
|
||||
host: props.host,
|
||||
},
|
||||
);
|
||||
const description2 = _t(
|
||||
"If the other version of %(brand)s is still open in another tab, " +
|
||||
"please close it as using %(brand)s on the same host with both " +
|
||||
"lazy loading enabled and disabled simultaneously will cause issues.",
|
||||
"If the other version of %(brand)s is still open in another tab, please close it as using %(brand)s on the same host with both lazy loading enabled and disabled simultaneously will cause issues.",
|
||||
{
|
||||
brand,
|
||||
},
|
||||
|
|
|
@ -28,9 +28,7 @@ interface IProps {
|
|||
const LazyLoadingResyncDialog: React.FC<IProps> = (props) => {
|
||||
const brand = SdkConfig.get().brand;
|
||||
const description = _t(
|
||||
"%(brand)s now uses 3-5x less memory, by only loading information " +
|
||||
"about other users when needed. Please wait whilst we resynchronise " +
|
||||
"with the server!",
|
||||
"%(brand)s now uses 3-5x less memory, by only loading information about other users when needed. Please wait whilst we resynchronise with the server!",
|
||||
{ brand },
|
||||
);
|
||||
|
||||
|
|
|
@ -63,15 +63,12 @@ const LeaveSpaceDialog: React.FC<IProps> = ({ space, onFinished }) => {
|
|||
|
||||
let onlyAdminWarning;
|
||||
if (isOnlyAdmin(space)) {
|
||||
onlyAdminWarning = _t(
|
||||
"You're the only admin of this space. " + "Leaving it will mean no one has control over it.",
|
||||
);
|
||||
onlyAdminWarning = _t("You're the only admin of this space. Leaving it will mean no one has control over it.");
|
||||
} else {
|
||||
const numChildrenOnlyAdminIn = roomsToLeave.filter(isOnlyAdmin).length;
|
||||
if (numChildrenOnlyAdminIn > 0) {
|
||||
onlyAdminWarning = _t(
|
||||
"You're the only admin of some of the rooms or spaces you wish to leave. " +
|
||||
"Leaving them will leave them without any admins.",
|
||||
"You're the only admin of some of the rooms or spaces you wish to leave. Leaving them will leave them without any admins.",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -138,16 +138,12 @@ export default class LogoutDialog extends React.Component<IProps, IState> {
|
|||
<div>
|
||||
<p>
|
||||
{_t(
|
||||
"Encrypted messages are secured with end-to-end encryption. " +
|
||||
"Only you and the recipient(s) have the keys to read these messages.",
|
||||
"Encrypted messages are secured with end-to-end encryption. Only you and the recipient(s) have the keys to read these messages.",
|
||||
)}
|
||||
</p>
|
||||
<p>
|
||||
{_t(
|
||||
"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.",
|
||||
"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>
|
||||
|
|
|
@ -152,8 +152,7 @@ const ManageRestrictedJoinRuleDialog: React.FC<IProps> = ({ room, selected = [],
|
|||
>
|
||||
<p>
|
||||
{_t(
|
||||
"Decide which spaces can access this room. " +
|
||||
"If a space is selected, its members can find and join <RoomName/>.",
|
||||
"Decide which spaces can access this room. If a space is selected, its members can find and join <RoomName/>.",
|
||||
{},
|
||||
{
|
||||
RoomName: () => <b>{room.name}</b>,
|
||||
|
|
|
@ -59,8 +59,7 @@ const RegistrationEmailPromptDialog: React.FC<IProps> = ({ onFinished }) => {
|
|||
<div className="mx_Dialog_content" id="mx_RegistrationEmailPromptDialog">
|
||||
<p>
|
||||
{_t(
|
||||
"Just a heads up, if you don't add an email and forget your password, you could " +
|
||||
"<b>permanently lose access to your account</b>.",
|
||||
"Just a heads up, if you don't add an email and forget your password, you could <b>permanently lose access to your account</b>.",
|
||||
{},
|
||||
{
|
||||
b: (sub) => <b>{sub}</b>,
|
||||
|
|
|
@ -317,54 +317,39 @@ export default class ReportEventDialog extends React.Component<IProps, IState> {
|
|||
let subtitle: string;
|
||||
switch (this.state.nature) {
|
||||
case Nature.Disagreement:
|
||||
subtitle = _t(
|
||||
"What this user is writing is wrong.\n" + "This will be reported to the room moderators.",
|
||||
);
|
||||
subtitle = _t("What this user is writing is wrong.\nThis will be reported to the room moderators.");
|
||||
break;
|
||||
case Nature.Toxic:
|
||||
subtitle = _t(
|
||||
"This user is displaying toxic behaviour, " +
|
||||
"for instance by insulting other users or sharing " +
|
||||
"adult-only content in a family-friendly room " +
|
||||
"or otherwise violating the rules of this room.\n" +
|
||||
"This will be reported to the room moderators.",
|
||||
"This user is displaying toxic behaviour, for instance by insulting other users or sharing adult-only content in a family-friendly room or otherwise violating the rules of this room.\nThis will be reported to the room moderators.",
|
||||
);
|
||||
break;
|
||||
case Nature.Illegal:
|
||||
subtitle = _t(
|
||||
"This user is displaying illegal behaviour, " +
|
||||
"for instance by doxing people or threatening violence.\n" +
|
||||
"This will be reported to the room moderators who may escalate this to legal authorities.",
|
||||
"This user is displaying illegal behaviour, for instance by doxing people or threatening violence.\nThis will be reported to the room moderators who may escalate this to legal authorities.",
|
||||
);
|
||||
break;
|
||||
case Nature.Spam:
|
||||
subtitle = _t(
|
||||
"This user is spamming the room with ads, links to ads or to propaganda.\n" +
|
||||
"This will be reported to the room moderators.",
|
||||
"This user is spamming the room with ads, links to ads or to propaganda.\nThis will be reported to the room moderators.",
|
||||
);
|
||||
break;
|
||||
case NonStandardValue.Admin:
|
||||
if (client.isRoomEncrypted(this.props.mxEvent.getRoomId()!)) {
|
||||
subtitle = _t(
|
||||
"This room is dedicated to illegal or toxic content " +
|
||||
"or the moderators fail to moderate illegal or toxic content.\n" +
|
||||
"This will be reported to the administrators of %(homeserver)s. " +
|
||||
"The administrators will NOT be able to read the encrypted content of this room.",
|
||||
"This room is dedicated to illegal or toxic content or the moderators fail to moderate illegal or toxic content.\nThis will be reported to the administrators of %(homeserver)s. The administrators will NOT be able to read the encrypted content of this room.",
|
||||
{ homeserver: homeServerName },
|
||||
);
|
||||
} else {
|
||||
subtitle = _t(
|
||||
"This room is dedicated to illegal or toxic content " +
|
||||
"or the moderators fail to moderate illegal or toxic content.\n" +
|
||||
"This will be reported to the administrators of %(homeserver)s.",
|
||||
"This room is dedicated to illegal or toxic content or the moderators fail to moderate illegal or toxic content.\nThis will be reported to the administrators of %(homeserver)s.",
|
||||
{ homeserver: homeServerName },
|
||||
);
|
||||
}
|
||||
break;
|
||||
case Nature.Other:
|
||||
subtitle = _t(
|
||||
"Any other reason. Please describe the problem.\n" +
|
||||
"This will be reported to the room moderators.",
|
||||
"Any other reason. Please describe the problem.\nThis will be reported to the room moderators.",
|
||||
);
|
||||
break;
|
||||
default:
|
||||
|
@ -464,10 +449,7 @@ export default class ReportEventDialog extends React.Component<IProps, IState> {
|
|||
<div className="mx_ReportEventDialog" id="mx_ReportEventDialog">
|
||||
<p>
|
||||
{_t(
|
||||
"Reporting this message will send its unique 'event ID' to the administrator of " +
|
||||
"your homeserver. If messages in this room are encrypted, your homeserver " +
|
||||
"administrator will not be able to read the message text or view any files " +
|
||||
"or images.",
|
||||
"Reporting this message will send its unique 'event ID' to the administrator of your homeserver. If messages in this room are encrypted, your homeserver administrator will not be able to read the message text or view any files or images.",
|
||||
)}
|
||||
</p>
|
||||
{adminMessage}
|
||||
|
|
|
@ -94,9 +94,7 @@ export default class RoomUpgradeDialog extends React.Component<IProps, IState> {
|
|||
>
|
||||
<p>
|
||||
{_t(
|
||||
"Upgrading this room requires closing down the current " +
|
||||
"instance of the room and creating a new room in its place. " +
|
||||
"To give room members the best possible experience, we will:",
|
||||
"Upgrading this room requires closing down the current instance of the room and creating a new room in its place. To give room members the best possible experience, we will:",
|
||||
)}
|
||||
</p>
|
||||
<ol>
|
||||
|
@ -104,14 +102,12 @@ export default class RoomUpgradeDialog extends React.Component<IProps, IState> {
|
|||
<li>{_t("Update any local room aliases to point to the new room")}</li>
|
||||
<li>
|
||||
{_t(
|
||||
"Stop users from speaking in the old version of the room, " +
|
||||
"and post a message advising users to move to the new room",
|
||||
"Stop users from speaking in the old version of the room, and post a message advising users to move to the new room",
|
||||
)}
|
||||
</li>
|
||||
<li>
|
||||
{_t(
|
||||
"Put a link back to the old room at the start of the new room " +
|
||||
"so people can see old messages",
|
||||
"Put a link back to the old room at the start of the new room so people can see old messages",
|
||||
)}
|
||||
</li>
|
||||
</ol>
|
||||
|
|
|
@ -135,8 +135,7 @@ export default class RoomUpgradeWarningDialog extends React.Component<IProps, IS
|
|||
let bugReports = (
|
||||
<p>
|
||||
{_t(
|
||||
"This usually only affects how the room is processed on the server. If you're " +
|
||||
"having problems with your %(brand)s, please report a bug.",
|
||||
"This usually only affects how the room is processed on the server. If you're having problems with your %(brand)s, please report a bug.",
|
||||
{ brand },
|
||||
)}
|
||||
</p>
|
||||
|
@ -145,8 +144,7 @@ export default class RoomUpgradeWarningDialog extends React.Component<IProps, IS
|
|||
bugReports = (
|
||||
<p>
|
||||
{_t(
|
||||
"This usually only affects how the room is processed on the server. If you're " +
|
||||
"having problems with your %(brand)s, please <a>report a bug</a>.",
|
||||
"This usually only affects how the room is processed on the server. If you're having problems with your %(brand)s, please <a>report a bug</a>.",
|
||||
{
|
||||
brand,
|
||||
},
|
||||
|
@ -195,14 +193,12 @@ export default class RoomUpgradeWarningDialog extends React.Component<IProps, IS
|
|||
<p>
|
||||
{this.props.description ||
|
||||
_t(
|
||||
"Upgrading a room is an advanced action and is usually recommended when a room " +
|
||||
"is unstable due to bugs, missing features or security vulnerabilities.",
|
||||
"Upgrading a room is an advanced action and is usually recommended when a room is unstable due to bugs, missing features or security vulnerabilities.",
|
||||
)}
|
||||
</p>
|
||||
<p>
|
||||
{_t(
|
||||
"<b>Please note upgrading will make a new version of the room</b>. " +
|
||||
"All current messages will stay in this archived room.",
|
||||
"<b>Please note upgrading will make a new version of the room</b>. All current messages will stay in this archived room.",
|
||||
{},
|
||||
{
|
||||
b: (sub) => <b>{sub}</b>,
|
||||
|
|
|
@ -107,8 +107,7 @@ export default class ServerOfflineDialog extends React.PureComponent<IProps> {
|
|||
<div className="mx_ServerOfflineDialog_content">
|
||||
<p>
|
||||
{_t(
|
||||
"Your server isn't responding to some of your requests. " +
|
||||
"Below are some of the most likely reasons.",
|
||||
"Your server isn't responding to some of your requests. Below are some of the most likely reasons.",
|
||||
)}
|
||||
</p>
|
||||
<ul>
|
||||
|
|
|
@ -37,9 +37,7 @@ export default class SeshatResetDialog extends React.PureComponent<Props> {
|
|||
{_t("You most likely do not want to reset your event index store")}
|
||||
<br />
|
||||
{_t(
|
||||
"If you do, please note that none of your messages will be deleted, " +
|
||||
"but the search experience might be degraded for a few moments " +
|
||||
"whilst the index is recreated",
|
||||
"If you do, please note that none of your messages will be deleted, but the search experience might be degraded for a few moments whilst the index is recreated",
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
@ -101,17 +101,14 @@ export default class SessionRestoreErrorDialog extends React.Component<IProps> {
|
|||
|
||||
<p>
|
||||
{_t(
|
||||
"If you have previously used a more recent version of %(brand)s, your session " +
|
||||
"may be incompatible with this version. Close this window and return " +
|
||||
"to the more recent version.",
|
||||
"If you have previously used a more recent version of %(brand)s, your session may be incompatible with this version. Close this window and return to the more recent version.",
|
||||
{ brand },
|
||||
)}
|
||||
</p>
|
||||
|
||||
<p>
|
||||
{_t(
|
||||
"Clearing your browser's storage may fix the problem, but will sign you " +
|
||||
"out and cause any encrypted chat history to become unreadable.",
|
||||
"Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.",
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
@ -78,8 +78,7 @@ export default class SetEmailDialog extends React.Component<IProps, IState> {
|
|||
Modal.createDialog(QuestionDialog, {
|
||||
title: _t("Verification Pending"),
|
||||
description: _t(
|
||||
"Please check your email and click on the link it contains. Once this " +
|
||||
"is done, click continue.",
|
||||
"Please check your email and click on the link it contains. Once this is done, click continue.",
|
||||
),
|
||||
button: _t("Continue"),
|
||||
onFinished: this.onEmailDialogFinished,
|
||||
|
|
|
@ -59,8 +59,7 @@ const SpacePreferencesAppearanceTab: React.FC<Pick<IProps, "space">> = ({ space
|
|||
</StyledCheckbox>
|
||||
<SettingsSubsectionText>
|
||||
{_t(
|
||||
"This groups your chats with members of this space. " +
|
||||
"Turning this off will hide those chats from your view of %(spaceName)s.",
|
||||
"This groups your chats with members of this space. Turning this off will hide those chats from your view of %(spaceName)s.",
|
||||
{
|
||||
spaceName: space.name,
|
||||
},
|
||||
|
|
|
@ -65,9 +65,7 @@ export default class StorageEvictedDialog extends React.Component<IProps> {
|
|||
<div className="mx_Dialog_content" id="mx_Dialog_content">
|
||||
<p>
|
||||
{_t(
|
||||
"Some session data, including encrypted message keys, is " +
|
||||
"missing. Sign out and sign in to fix this, restoring keys " +
|
||||
"from backup.",
|
||||
"Some session data, including encrypted message keys, is missing. Sign out and sign in to fix this, restoring keys from backup.",
|
||||
)}
|
||||
</p>
|
||||
<p>
|
||||
|
|
|
@ -17,7 +17,7 @@ limitations under the License.
|
|||
import React, { ChangeEvent, createRef } from "react";
|
||||
|
||||
import Field from "../elements/Field";
|
||||
import { _t, _td } from "../../../languageHandler";
|
||||
import { _t, _td, TranslationKey } from "../../../languageHandler";
|
||||
import { IFieldState, IValidationResult } from "../elements/Validation";
|
||||
import BaseDialog from "./BaseDialog";
|
||||
import DialogButtons from "../elements/DialogButtons";
|
||||
|
@ -28,7 +28,7 @@ interface IProps {
|
|||
value: string;
|
||||
placeholder?: string;
|
||||
button?: string;
|
||||
busyMessage: string; // pass _td string
|
||||
busyMessage: TranslationKey;
|
||||
focus: boolean;
|
||||
hasCancel: boolean;
|
||||
validator?: (fieldState: IFieldState) => Promise<IValidationResult>; // result of withValidation
|
||||
|
|
|
@ -49,8 +49,7 @@ export default class UploadFailureDialog extends React.Component<IProps> {
|
|||
let buttons;
|
||||
if (this.props.totalFiles === 1 && this.props.badFiles.length === 1) {
|
||||
message = _t(
|
||||
"This file is <b>too large</b> to upload. " +
|
||||
"The file size limit is %(limit)s but this file is %(sizeOfThisFile)s.",
|
||||
"This file is <b>too large</b> to upload. The file size limit is %(limit)s but this file is %(sizeOfThisFile)s.",
|
||||
{
|
||||
limit: fileSize(this.props.contentMessages.getUploadLimit()),
|
||||
sizeOfThisFile: fileSize(this.props.badFiles[0].size),
|
||||
|
@ -69,7 +68,7 @@ export default class UploadFailureDialog extends React.Component<IProps> {
|
|||
);
|
||||
} else if (this.props.totalFiles === this.props.badFiles.length) {
|
||||
message = _t(
|
||||
"These files are <b>too large</b> to upload. " + "The file size limit is %(limit)s.",
|
||||
"These files are <b>too large</b> to upload. The file size limit is %(limit)s.",
|
||||
{
|
||||
limit: fileSize(this.props.contentMessages.getUploadLimit()),
|
||||
},
|
||||
|
@ -87,7 +86,7 @@ export default class UploadFailureDialog extends React.Component<IProps> {
|
|||
);
|
||||
} else {
|
||||
message = _t(
|
||||
"Some files are <b>too large</b> to be uploaded. " + "The file size limit is %(limit)s.",
|
||||
"Some files are <b>too large</b> to be uploaded. The file size limit is %(limit)s.",
|
||||
{
|
||||
limit: fileSize(this.props.contentMessages.getUploadLimit()),
|
||||
},
|
||||
|
|
|
@ -18,7 +18,7 @@ limitations under the License.
|
|||
import React, { ChangeEvent, ReactNode, useContext, useMemo, useRef, useState } from "react";
|
||||
import { IContent, MatrixEvent } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import { _t, _td } from "../../../../languageHandler";
|
||||
import { _t, _td, TranslationKey } from "../../../../languageHandler";
|
||||
import Field from "../../elements/Field";
|
||||
import BaseTool, { DevtoolsContext, IDevtoolsProps } from "./BaseTool";
|
||||
import MatrixClientContext from "../../../../contexts/MatrixClientContext";
|
||||
|
@ -37,7 +37,7 @@ interface IEventEditorProps extends Pick<IDevtoolsProps, "onBack"> {
|
|||
|
||||
interface IFieldDef {
|
||||
id: string;
|
||||
label: string; // _td
|
||||
label: TranslationKey;
|
||||
default?: string;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,12 +21,12 @@ import { VerificationPhase as Phase, VerificationRequestEvent } from "matrix-js-
|
|||
import { CryptoEvent } from "matrix-js-sdk/src/crypto";
|
||||
|
||||
import { useTypedEventEmitter, useTypedEventEmitterState } from "../../../../hooks/useEventEmitter";
|
||||
import { _t, _td } from "../../../../languageHandler";
|
||||
import { _t, _td, TranslationKey } from "../../../../languageHandler";
|
||||
import MatrixClientContext from "../../../../contexts/MatrixClientContext";
|
||||
import BaseTool, { DevtoolsContext, IDevtoolsProps } from "./BaseTool";
|
||||
import { Tool } from "../DevtoolsDialog";
|
||||
|
||||
const PHASE_MAP: Record<Phase, string> = {
|
||||
const PHASE_MAP: Record<Phase, TranslationKey> = {
|
||||
[Phase.Unsent]: _td("Unsent"),
|
||||
[Phase.Requested]: _td("Requested"),
|
||||
[Phase.Ready]: _td("Ready"),
|
||||
|
|
|
@ -305,8 +305,7 @@ export default class AccessSecretStorageDialog extends React.PureComponent<IProp
|
|||
<p>{_t("Only do this if you have no other device to complete verification with.")}</p>
|
||||
<p>
|
||||
{_t(
|
||||
"If you reset everything, you will restart with no trusted sessions, no trusted users, and " +
|
||||
"might not be able to see past messages.",
|
||||
"If you reset everything, you will restart with no trusted sessions, no trusted users, and might not be able to see past messages.",
|
||||
)}
|
||||
</p>
|
||||
<DialogButtons
|
||||
|
@ -329,8 +328,7 @@ export default class AccessSecretStorageDialog extends React.PureComponent<IProp
|
|||
<div className="mx_AccessSecretStorageDialog_keyStatus">
|
||||
{"\uD83D\uDC4E "}
|
||||
{_t(
|
||||
"Unable to access secret storage. " +
|
||||
"Please verify that you entered the correct Security Phrase.",
|
||||
"Unable to access secret storage. Please verify that you entered the correct Security Phrase.",
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -44,10 +44,7 @@ export default class ConfirmDestroyCrossSigningDialog extends React.Component<IP
|
|||
<div className="mx_ConfirmDestroyCrossSigningDialog_content">
|
||||
<p>
|
||||
{_t(
|
||||
"Deleting cross-signing keys is permanent. " +
|
||||
"Anyone you have verified with will see security alerts. " +
|
||||
"You almost certainly don't want to do this, unless " +
|
||||
"you've lost every device you can cross-sign from.",
|
||||
"Deleting cross-signing keys is permanent. Anyone you have verified with will see security alerts. You almost certainly don't want to do this, unless you've lost every device you can cross-sign from.",
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
@ -351,8 +351,7 @@ export default class RestoreKeyBackupDialog extends React.PureComponent<IProps,
|
|||
<div>
|
||||
<p>
|
||||
{_t(
|
||||
"Backup could not be decrypted with this Security Key: " +
|
||||
"please verify that you entered the correct Security Key.",
|
||||
"Backup could not be decrypted with this Security Key: please verify that you entered the correct Security Key.",
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
|
@ -363,8 +362,7 @@ export default class RestoreKeyBackupDialog extends React.PureComponent<IProps,
|
|||
<div>
|
||||
<p>
|
||||
{_t(
|
||||
"Backup could not be decrypted with this Security Phrase: " +
|
||||
"please verify that you entered the correct Security Phrase.",
|
||||
"Backup could not be decrypted with this Security Phrase: please verify that you entered the correct Security Phrase.",
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
|
@ -418,8 +416,7 @@ export default class RestoreKeyBackupDialog extends React.PureComponent<IProps,
|
|||
</p>
|
||||
<p>
|
||||
{_t(
|
||||
"Access your secure message history and set up secure " +
|
||||
"messaging by entering your Security Phrase.",
|
||||
"Access your secure message history and set up secure messaging by entering your Security Phrase.",
|
||||
)}
|
||||
</p>
|
||||
|
||||
|
@ -441,9 +438,7 @@ export default class RestoreKeyBackupDialog extends React.PureComponent<IProps,
|
|||
/>
|
||||
</form>
|
||||
{_t(
|
||||
"If you've forgotten your Security Phrase you can " +
|
||||
"<button1>use your Security Key</button1> or " +
|
||||
"<button2>set up new recovery options</button2>",
|
||||
"If you've forgotten your Security Phrase you can <button1>use your Security Key</button1> or <button2>set up new recovery options</button2>",
|
||||
{},
|
||||
{
|
||||
button1: (s) => (
|
||||
|
@ -493,8 +488,7 @@ export default class RestoreKeyBackupDialog extends React.PureComponent<IProps,
|
|||
</p>
|
||||
<p>
|
||||
{_t(
|
||||
"Access your secure message history and set up secure " +
|
||||
"messaging by entering your Security Key.",
|
||||
"Access your secure message history and set up secure messaging by entering your Security Key.",
|
||||
)}
|
||||
</p>
|
||||
|
||||
|
@ -516,8 +510,7 @@ export default class RestoreKeyBackupDialog extends React.PureComponent<IProps,
|
|||
/>
|
||||
</div>
|
||||
{_t(
|
||||
"If you've forgotten your Security Key you can " +
|
||||
"<button>set up new recovery options</button>",
|
||||
"If you've forgotten your Security Key you can <button>set up new recovery options</button>",
|
||||
{},
|
||||
{
|
||||
button: (s) => (
|
||||
|
|
|
@ -923,10 +923,7 @@ const SpotlightDialog: React.FC<IProps> = ({ initialText = "", initialFilter = n
|
|||
<div className="mx_SpotlightDialog_section mx_SpotlightDialog_hiddenResults" role="group">
|
||||
<h4>{_t("Some results may be hidden")}</h4>
|
||||
<div className="mx_SpotlightDialog_otherSearches_messageSearchText">
|
||||
{_t(
|
||||
"If you can't find the room you're looking for, " +
|
||||
"ask for an invite or create a new room.",
|
||||
)}
|
||||
{_t("If you can't find the room you're looking for, ask for an invite or create a new room.")}
|
||||
</div>
|
||||
<Option
|
||||
id="mx_SpotlightDialog_button_createNewRoom"
|
||||
|
|
|
@ -17,7 +17,7 @@ limitations under the License.
|
|||
import React from "react";
|
||||
import classNames from "classnames";
|
||||
|
||||
import { _t } from "../../../languageHandler";
|
||||
import { _t, _td, TranslationKey } from "../../../languageHandler";
|
||||
import BaseDialog from "..//dialogs/BaseDialog";
|
||||
import DialogButtons from "./DialogButtons";
|
||||
import AccessibleButton from "./AccessibleButton";
|
||||
|
@ -135,7 +135,7 @@ export default class DesktopCapturerSourcePicker extends React.Component<PickerI
|
|||
this.props.onFinished();
|
||||
};
|
||||
|
||||
private getTab(type: TabId, label: string): Tab<TabId> {
|
||||
private getTab(type: TabId, label: TranslationKey): Tab<TabId> {
|
||||
const sources = this.state.sources
|
||||
.filter((source) => source.id.startsWith(type))
|
||||
.map((source) => {
|
||||
|
@ -154,8 +154,8 @@ export default class DesktopCapturerSourcePicker extends React.Component<PickerI
|
|||
|
||||
public render(): React.ReactNode {
|
||||
const tabs: NonEmptyArray<Tab<TabId>> = [
|
||||
this.getTab("screen", _t("Share entire screen")),
|
||||
this.getTab("window", _t("Application window")),
|
||||
this.getTab("screen", _td("Share entire screen")),
|
||||
this.getTab("window", _td("Application window")),
|
||||
];
|
||||
|
||||
return (
|
||||
|
|
|
@ -85,8 +85,7 @@ export default class ErrorBoundary extends React.PureComponent<Props, IState> {
|
|||
<React.Fragment>
|
||||
<p>
|
||||
{_t(
|
||||
"Please <newIssueLink>create a new issue</newIssueLink> " +
|
||||
"on GitHub so that we can investigate this bug.",
|
||||
"Please <newIssueLink>create a new issue</newIssueLink> on GitHub so that we can investigate this bug.",
|
||||
{},
|
||||
{
|
||||
newIssueLink: (sub) => {
|
||||
|
@ -101,15 +100,10 @@ export default class ErrorBoundary extends React.PureComponent<Props, IState> {
|
|||
</p>
|
||||
<p>
|
||||
{_t(
|
||||
"If you've submitted a bug via GitHub, debug logs can help " +
|
||||
"us track down the problem. ",
|
||||
"If you've submitted a bug via GitHub, debug logs can help us track down the problem. ",
|
||||
)}
|
||||
{_t(
|
||||
"Debug logs contain application " +
|
||||
"usage data including your username, the IDs or aliases of " +
|
||||
"the rooms you have visited, which UI elements you " +
|
||||
"last interacted with, and the usernames of other users. " +
|
||||
"They do not contain messages.",
|
||||
"Debug logs contain application usage data including your username, the IDs or aliases of the rooms you have visited, which UI elements you last interacted with, and the usernames of other users. They do not contain messages.",
|
||||
)}
|
||||
</p>
|
||||
<AccessibleButton onClick={this.onBugReport} kind="primary">
|
||||
|
|
|
@ -205,8 +205,7 @@ export default class ReplyChain extends React.Component<IProps, IState> {
|
|||
header = (
|
||||
<blockquote className="mx_ReplyChain mx_ReplyChain_error">
|
||||
{_t(
|
||||
"Unable to load event that was replied to, " +
|
||||
"it either does not exist or you do not have permission to view it.",
|
||||
"Unable to load event that was replied to, it either does not exist or you do not have permission to view it.",
|
||||
)}
|
||||
</blockquote>
|
||||
);
|
||||
|
|
|
@ -47,9 +47,7 @@ const onHelpClick = (): void => {
|
|||
{
|
||||
title: _t("Server Options"),
|
||||
description: _t(
|
||||
"You can use the custom server options to sign into other Matrix servers by specifying " +
|
||||
"a different homeserver URL. This allows you to use %(brand)s with an existing Matrix account on " +
|
||||
"a different homeserver.",
|
||||
"You can use the custom server options to sign into other Matrix servers by specifying a different homeserver URL. This allows you to use %(brand)s with an existing Matrix account on a different homeserver.",
|
||||
{ brand },
|
||||
),
|
||||
button: _t("Dismiss"),
|
||||
|
|
|
@ -29,7 +29,7 @@ interface IProps {
|
|||
name: string;
|
||||
level: SettingLevel;
|
||||
roomId?: string; // for per-room settings
|
||||
label?: string; // untranslated
|
||||
label?: string;
|
||||
isExplicit?: boolean;
|
||||
// XXX: once design replaces all toggles make this the default
|
||||
useCheckbox?: boolean;
|
||||
|
@ -105,10 +105,7 @@ export default class SettingsFlag extends React.Component<IProps, IState> {
|
|||
|
||||
if (!canChange && this.props.hideIfCannotSet) return null;
|
||||
|
||||
const label =
|
||||
(this.props.label
|
||||
? _t(this.props.label)
|
||||
: SettingsStore.getDisplayName(this.props.name, this.props.level)) ?? undefined;
|
||||
const label = this.props.label ?? SettingsStore.getDisplayName(this.props.name, this.props.level);
|
||||
const description = SettingsStore.getDescription(this.props.name);
|
||||
const shouldWarn = SettingsStore.shouldHaveWarning(this.props.name);
|
||||
const disabled = this.state.disabled || !canChange;
|
||||
|
@ -146,7 +143,7 @@ export default class SettingsFlag extends React.Component<IProps, IState> {
|
|||
onChange={this.onChange}
|
||||
disabled={disabled}
|
||||
tooltip={disabled ? SettingsStore.disabledMessage(this.props.name) : undefined}
|
||||
title={label}
|
||||
title={label ?? undefined}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -36,10 +36,7 @@ export const EnableLiveShare: React.FC<Props> = ({ onSubmit }) => {
|
|||
</Heading>
|
||||
<p className="mx_EnableLiveShare_description">
|
||||
{_t(
|
||||
"Please note: this is a labs feature using a temporary implementation. " +
|
||||
"This means you will not be able to delete your location history, " +
|
||||
"and advanced users will be able to see your location history " +
|
||||
"even after you stop sharing your live location with this room.",
|
||||
"Please note: this is a labs feature using a temporary implementation. This means you will not be able to delete your location history, and advanced users will be able to see your location history even after you stop sharing your live location with this room.",
|
||||
)}
|
||||
</p>
|
||||
<LabelledToggleSwitch
|
||||
|
|
|
@ -167,16 +167,12 @@ export default class DateSeparator extends React.Component<IProps, IState> {
|
|||
let submitDebugLogsContent: JSX.Element = <></>;
|
||||
if (err instanceof ConnectionError) {
|
||||
friendlyErrorMessage = _t(
|
||||
"A network error occurred while trying to find and jump to the given date. " +
|
||||
"Your homeserver might be down or there was just a temporary problem with " +
|
||||
"your internet connection. Please try again. If this continues, please " +
|
||||
"contact your homeserver administrator.",
|
||||
"A network error occurred while trying to find and jump to the given date. Your homeserver might be down or there was just a temporary problem with your internet connection. Please try again. If this continues, please contact your homeserver administrator.",
|
||||
);
|
||||
} else if (err instanceof MatrixError) {
|
||||
if (err?.errcode === "M_NOT_FOUND") {
|
||||
friendlyErrorMessage = _t(
|
||||
"We were unable to find an event looking forwards from %(dateString)s. " +
|
||||
"Try choosing an earlier date.",
|
||||
"We were unable to find an event looking forwards from %(dateString)s. Try choosing an earlier date.",
|
||||
{ dateString: formatFullDateNoDay(new Date(unixTimestamp)) },
|
||||
);
|
||||
} else {
|
||||
|
@ -192,8 +188,7 @@ export default class DateSeparator extends React.Component<IProps, IState> {
|
|||
submitDebugLogsContent = (
|
||||
<p>
|
||||
{_t(
|
||||
"Please submit <debugLogsLink>debug logs</debugLogsLink> to help us " +
|
||||
"track down the problem.",
|
||||
"Please submit <debugLogsLink>debug logs</debugLogsLink> to help us track down the problem.",
|
||||
{},
|
||||
{
|
||||
debugLogsLink: (sub) => (
|
||||
|
|
|
@ -22,7 +22,7 @@ import { Icon as DownloadIcon } from "../../../../res/img/download.svg";
|
|||
import { MediaEventHelper } from "../../../utils/MediaEventHelper";
|
||||
import { RovingAccessibleTooltipButton } from "../../../accessibility/RovingTabIndex";
|
||||
import Spinner from "../elements/Spinner";
|
||||
import { _t, _td } from "../../../languageHandler";
|
||||
import { _t, _td, TranslationKey } from "../../../languageHandler";
|
||||
import { FileDownloader } from "../../../utils/FileDownloader";
|
||||
|
||||
interface IProps {
|
||||
|
@ -37,7 +37,7 @@ interface IProps {
|
|||
interface IState {
|
||||
loading: boolean;
|
||||
blob?: Blob;
|
||||
tooltip: string;
|
||||
tooltip: TranslationKey;
|
||||
}
|
||||
|
||||
export default class DownloadActionButton extends React.PureComponent<IProps, IState> {
|
||||
|
|
|
@ -53,16 +53,14 @@ const EncryptionEvent = forwardRef<HTMLDivElement, IProps>(({ mxEvent, timestamp
|
|||
} else if (dmPartner) {
|
||||
const displayName = room?.getMember(dmPartner)?.rawDisplayName || dmPartner;
|
||||
subtitle = _t(
|
||||
"Messages here are end-to-end encrypted. " +
|
||||
"Verify %(displayName)s in their profile - tap on their profile picture.",
|
||||
"Messages here are end-to-end encrypted. Verify %(displayName)s in their profile - tap on their profile picture.",
|
||||
{ displayName },
|
||||
);
|
||||
} else if (room && isLocalRoom(room)) {
|
||||
subtitle = _t("Messages in this chat will be end-to-end encrypted.");
|
||||
} else {
|
||||
subtitle = _t(
|
||||
"Messages in this room are end-to-end encrypted. " +
|
||||
"When people join, you can verify them in their profile, just tap on their profile picture.",
|
||||
"Messages in this room are end-to-end encrypted. When people join, you can verify them in their profile, just tap on their profile picture.",
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -106,9 +106,7 @@ export const RoomPredecessorTile: React.FC<IProps> = ({ mxEvent, timestamp }) =>
|
|||
{!!guessedLink ? (
|
||||
<>
|
||||
{_t(
|
||||
"Can't find the old version of this room (room ID: %(roomId)s), and we have not been " +
|
||||
"provided with 'via_servers' to look for it. It's possible that guessing the " +
|
||||
"server from the room ID will work. If you want to try, click this link:",
|
||||
"Can't find the old version of this room (room ID: %(roomId)s), and we have not been provided with 'via_servers' to look for it. It's possible that guessing the server from the room ID will work. If you want to try, click this link:",
|
||||
{
|
||||
roomId: predecessor.roomId,
|
||||
},
|
||||
|
@ -117,8 +115,7 @@ export const RoomPredecessorTile: React.FC<IProps> = ({ mxEvent, timestamp }) =>
|
|||
</>
|
||||
) : (
|
||||
_t(
|
||||
"Can't find the old version of this room (room ID: %(roomId)s), and we have not been " +
|
||||
"provided with 'via_servers' to look for it.",
|
||||
"Can't find the old version of this room (room ID: %(roomId)s), and we have not been provided with 'via_servers' to look for it.",
|
||||
{
|
||||
roomId: predecessor.roomId,
|
||||
},
|
||||
|
|
|
@ -494,9 +494,7 @@ export default class TextualBody extends React.Component<IBodyProps, IState> {
|
|||
description: (
|
||||
<div>
|
||||
{_t(
|
||||
"You are about to be taken to a third-party site so you can " +
|
||||
"authenticate your account for use with %(integrationsUrl)s. " +
|
||||
"Do you wish to continue?",
|
||||
"You are about to be taken to a third-party site so you can authenticate your account for use with %(integrationsUrl)s. Do you wish to continue?",
|
||||
{ integrationsUrl: integrationsUrl },
|
||||
)}
|
||||
</div>
|
||||
|
|
|
@ -81,8 +81,7 @@ const EncryptionInfo: React.FC<IProps> = ({
|
|||
<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.",
|
||||
"Your messages are secured and only you and the recipient have the unique keys to unlock them.",
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
|
@ -93,8 +92,7 @@ const EncryptionInfo: React.FC<IProps> = ({
|
|||
<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.",
|
||||
"In encrypted rooms, your messages are secured and only you and the recipient have the unique keys to unlock them.",
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
@ -181,8 +181,7 @@ const PinnedMessagesCard: React.FC<IProps> = ({ room, onClose, permalinkCreator
|
|||
{_t("Nothing pinned, yet")}
|
||||
</Heading>
|
||||
{_t(
|
||||
"If you have permissions, open the menu on any message and select " +
|
||||
"<b>Pin</b> to stick them here.",
|
||||
"If you have permissions, open the menu on any message and select <b>Pin</b> to stick them here.",
|
||||
{},
|
||||
{
|
||||
b: (sub) => <b>{sub}</b>,
|
||||
|
|
|
@ -383,8 +383,7 @@ export const UserOptionsSection: React.FC<{
|
|||
description: (
|
||||
<div>
|
||||
{_t(
|
||||
"All messages and invites from this user will be hidden. " +
|
||||
"Are you sure you want to ignore them?",
|
||||
"All messages and invites from this user will be hidden. Are you sure you want to ignore them?",
|
||||
)}
|
||||
</div>
|
||||
),
|
||||
|
@ -523,14 +522,10 @@ export const warnSelfDemote = async (isSpace: boolean): Promise<boolean> => {
|
|||
<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.",
|
||||
"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.",
|
||||
"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.",
|
||||
)}
|
||||
</div>
|
||||
),
|
||||
|
@ -1185,8 +1180,7 @@ export const PowerLevelEditor: React.FC<{
|
|||
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.",
|
||||
"You will not be able to undo this change as you are promoting the user to have the same power level as yourself.",
|
||||
)}
|
||||
<br />
|
||||
{_t("Are you sure?")}
|
||||
|
@ -1355,9 +1349,7 @@ const BasicUserInfo: React.FC<{
|
|||
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?",
|
||||
"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>
|
||||
),
|
||||
|
|
|
@ -93,9 +93,7 @@ export default class VerificationPanel extends React.PureComponent<IProps, IStat
|
|||
!showSAS && !showQR ? (
|
||||
<p>
|
||||
{_t(
|
||||
"The device you are trying to verify doesn't support scanning a " +
|
||||
"QR code or emoji verification, which is what %(brand)s supports. Try " +
|
||||
"with a different client.",
|
||||
"The device you are trying to verify doesn't support scanning a QR code or emoji verification, which is what %(brand)s supports. Try with a different client.",
|
||||
{ brand },
|
||||
)}
|
||||
</p>
|
||||
|
|
|
@ -182,8 +182,7 @@ export default class AliasSettings extends React.Component<IProps, IState> {
|
|||
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.",
|
||||
"There was an error updating the room's main address. It may not be allowed by the server or a temporary failure occurred.",
|
||||
),
|
||||
});
|
||||
this.setState({ canonicalAlias: oldAlias });
|
||||
|
@ -222,8 +221,7 @@ export default class AliasSettings extends React.Component<IProps, IState> {
|
|||
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.",
|
||||
"There was an error updating the room's alternative addresses. It may not be allowed by the server or a temporary failure occurred.",
|
||||
),
|
||||
});
|
||||
})
|
||||
|
@ -258,8 +256,7 @@ export default class AliasSettings extends React.Component<IProps, IState> {
|
|||
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.",
|
||||
"There was an error creating that address. It may not be allowed by the server or a temporary failure occurred.",
|
||||
),
|
||||
});
|
||||
});
|
||||
|
@ -286,8 +283,7 @@ export default class AliasSettings extends React.Component<IProps, IState> {
|
|||
description = _t("You don't have permission to delete the address.");
|
||||
} else {
|
||||
description = _t(
|
||||
"There was an error removing that address. It may no longer exist or a temporary " +
|
||||
"error occurred.",
|
||||
"There was an error removing that address. It may no longer exist or a temporary error occurred.",
|
||||
);
|
||||
}
|
||||
Modal.createDialog(ErrorDialog, {
|
||||
|
@ -450,13 +446,11 @@ export default class AliasSettings extends React.Component<IProps, IState> {
|
|||
description={
|
||||
isSpaceRoom
|
||||
? _t(
|
||||
"Set addresses for this space so users can find this space " +
|
||||
"through your homeserver (%(localDomain)s)",
|
||||
"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)",
|
||||
"Set addresses for this room so users can find this room through your homeserver (%(localDomain)s)",
|
||||
{ localDomain },
|
||||
)
|
||||
}
|
||||
|
|
|
@ -95,9 +95,7 @@ export default class UrlPreviewSettings extends React.Component<IProps> {
|
|||
}
|
||||
} else {
|
||||
previewsForAccount = _t(
|
||||
"In encrypted rooms, like this one, URL previews are disabled by default to ensure that your " +
|
||||
"homeserver (where the previews are generated) cannot gather information about links you see in " +
|
||||
"this room.",
|
||||
"In encrypted rooms, like this one, URL previews are disabled by default to ensure that your homeserver (where the previews are generated) cannot gather information about links you see in this room.",
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -114,8 +112,7 @@ export default class UrlPreviewSettings extends React.Component<IProps> {
|
|||
<>
|
||||
<p>
|
||||
{_t(
|
||||
"When someone puts a URL in their message, a URL preview can be shown to give more " +
|
||||
"information about that link such as the title, description, and an image from the website.",
|
||||
"When someone puts a URL in their message, a URL preview can be shown to give more information about that link such as the title, description, and an image from the website.",
|
||||
)}
|
||||
</p>
|
||||
<p>{previewsForAccount}</p>
|
||||
|
|
|
@ -18,7 +18,7 @@ limitations under the License.
|
|||
import React, { CSSProperties, useState } from "react";
|
||||
import classNames from "classnames";
|
||||
|
||||
import { _t, _td } from "../../../languageHandler";
|
||||
import { _t, _td, TranslationKey } from "../../../languageHandler";
|
||||
import AccessibleButton from "../elements/AccessibleButton";
|
||||
import Tooltip, { Alignment } from "../elements/Tooltip";
|
||||
import { E2EStatus } from "../../../utils/ShieldUtils";
|
||||
|
@ -32,12 +32,12 @@ export enum E2EState {
|
|||
Unauthenticated = "unauthenticated",
|
||||
}
|
||||
|
||||
const crossSigningUserTitles: { [key in E2EState]?: string } = {
|
||||
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."),
|
||||
};
|
||||
const crossSigningRoomTitles: { [key in E2EState]?: string } = {
|
||||
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"),
|
||||
|
@ -85,7 +85,7 @@ const E2EIcon: React.FC<XOR<UserProps, RoomProps>> = ({
|
|||
className,
|
||||
);
|
||||
|
||||
let e2eTitle: string | undefined;
|
||||
let e2eTitle: TranslationKey | undefined;
|
||||
if (isUser) {
|
||||
e2eTitle = crossSigningUserTitles[status];
|
||||
} else {
|
||||
|
|
|
@ -20,7 +20,7 @@ import React from "react";
|
|||
import classNames from "classnames";
|
||||
|
||||
import AccessibleButton from "../elements/AccessibleButton";
|
||||
import { _t, _td } from "../../../languageHandler";
|
||||
import { _t, _td, TranslationKey } from "../../../languageHandler";
|
||||
import E2EIcon, { E2EState } from "./E2EIcon";
|
||||
import BaseAvatar from "../avatars/BaseAvatar";
|
||||
import PresenceLabel from "./PresenceLabel";
|
||||
|
@ -30,7 +30,7 @@ export enum PowerStatus {
|
|||
Moderator = "moderator",
|
||||
}
|
||||
|
||||
const PowerLabel: Record<PowerStatus, string> = {
|
||||
const PowerLabel: Record<PowerStatus, TranslationKey> = {
|
||||
[PowerStatus.Admin]: _td("Admin"),
|
||||
[PowerStatus.Moderator]: _td("Mod"),
|
||||
};
|
||||
|
|
|
@ -20,7 +20,7 @@ import { EventType, Room, User, MatrixClient } from "matrix-js-sdk/src/matrix";
|
|||
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
||||
import RoomContext from "../../../contexts/RoomContext";
|
||||
import DMRoomMap from "../../../utils/DMRoomMap";
|
||||
import { _t, _td } from "../../../languageHandler";
|
||||
import { _t, _td, TranslationKey } from "../../../languageHandler";
|
||||
import AccessibleButton, { ButtonEvent } from "../elements/AccessibleButton";
|
||||
import MiniAvatarUploader, { AVATAR_SIZE } from "../elements/MiniAvatarUploader";
|
||||
import RoomAvatar from "../avatars/RoomAvatar";
|
||||
|
@ -44,7 +44,7 @@ function hasExpectedEncryptionSettings(matrixClient: MatrixClient, room: Room):
|
|||
return isPublic || !privateShouldBeEncrypted(matrixClient) || isEncrypted;
|
||||
}
|
||||
|
||||
const determineIntroMessage = (room: Room, encryptedSingle3rdPartyInvite: boolean): string => {
|
||||
const determineIntroMessage = (room: Room, encryptedSingle3rdPartyInvite: boolean): TranslationKey => {
|
||||
if (room instanceof LocalRoom) {
|
||||
return _td("Send your first message to invite <displayName/> to chat");
|
||||
}
|
||||
|
@ -270,9 +270,7 @@ const NewRoomIntro: React.FC = () => {
|
|||
}
|
||||
|
||||
const subText = _t(
|
||||
"Your private messages are normally encrypted, but this room isn't. " +
|
||||
"Usually this is due to an unsupported device or method being used, " +
|
||||
"like email invites.",
|
||||
"Your private messages are normally encrypted, but this room isn't. Usually this is due to an unsupported device or method being used, like email invites.",
|
||||
);
|
||||
|
||||
let subButton: JSX.Element | undefined;
|
||||
|
|
|
@ -26,7 +26,7 @@ import { ActionPayload } from "../../../dispatcher/payloads";
|
|||
import { ViewRoomDeltaPayload } from "../../../dispatcher/payloads/ViewRoomDeltaPayload";
|
||||
import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload";
|
||||
import { useEventEmitterState } from "../../../hooks/useEventEmitter";
|
||||
import { _t, _td } from "../../../languageHandler";
|
||||
import { _t, _td, TranslationKey } from "../../../languageHandler";
|
||||
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
||||
import PosthogTrackers from "../../../PosthogTrackers";
|
||||
import SettingsStore from "../../../settings/SettingsStore";
|
||||
|
@ -93,7 +93,7 @@ export const TAG_ORDER: TagID[] = [
|
|||
const ALWAYS_VISIBLE_TAGS: TagID[] = [DefaultTagID.DM, DefaultTagID.Untagged];
|
||||
|
||||
interface ITagAesthetics {
|
||||
sectionLabel: string;
|
||||
sectionLabel: TranslationKey;
|
||||
sectionLabelRaw?: string;
|
||||
AuxButtonComponent?: ComponentType<IAuxButtonProps>;
|
||||
isInvite: boolean;
|
||||
|
|
|
@ -421,8 +421,7 @@ export default class RoomPreviewBar extends React.Component<IProps, IState> {
|
|||
}
|
||||
const joinRule = this.joinRule();
|
||||
const errCodeMessage = _t(
|
||||
"An error (%(errcode)s) was returned while trying to validate your " +
|
||||
"invite. You could try to pass this information on to the person who invited you.",
|
||||
"An error (%(errcode)s) was returned while trying to validate your invite. You could try to pass this information on to the person who invited you.",
|
||||
{ errcode: this.state.threePidFetchError?.errcode || _t("unknown error code") },
|
||||
);
|
||||
switch (joinRule) {
|
||||
|
@ -447,8 +446,7 @@ export default class RoomPreviewBar extends React.Component<IProps, IState> {
|
|||
case MessageCase.InvitedEmailNotFoundInAccount: {
|
||||
if (roomName) {
|
||||
title = _t(
|
||||
"This invite to %(roomName)s was sent to %(email)s which is not " +
|
||||
"associated with your account",
|
||||
"This invite to %(roomName)s was sent to %(email)s which is not associated with your account",
|
||||
{
|
||||
roomName,
|
||||
email: this.props.invitedEmail,
|
||||
|
@ -585,9 +583,7 @@ export default class RoomPreviewBar extends React.Component<IProps, IState> {
|
|||
subTitle = [
|
||||
_t("Try again later, or ask a room or space admin to check if you have access."),
|
||||
_t(
|
||||
"%(errcode)s was returned while trying to access the room or space. " +
|
||||
"If you think you're seeing this message in error, please " +
|
||||
"<issueLink>submit a bug report</issueLink>.",
|
||||
"%(errcode)s was returned while trying to access the room or space. If you think you're seeing this message in error, please <issueLink>submit a bug report</issueLink>.",
|
||||
{ errcode: String(this.props.error?.errcode) },
|
||||
{
|
||||
issueLink: (label) => (
|
||||
|
|
|
@ -73,15 +73,12 @@ export default class RoomUpgradeWarningBar extends React.PureComponent<IProps, I
|
|||
<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.",
|
||||
"Upgrading this room will shut down the current instance of the room and create an upgraded room with the same name.",
|
||||
)}
|
||||
</p>
|
||||
<p>
|
||||
{_t(
|
||||
"<b>Warning</b>: upgrading a room will <i>not automatically migrate room members " +
|
||||
"to the new version of the room.</i> We'll post a link to the new room in the old " +
|
||||
"version of the room - room members will have to click this link to join the new room.",
|
||||
"<b>Warning</b>: upgrading a room will <i>not automatically migrate room members to the new version of the room.</i> We'll post a link to the new room in the old version of the room - room members will have to click this link to join the new room.",
|
||||
{},
|
||||
{
|
||||
b: (sub) => <b>{sub}</b>,
|
||||
|
@ -111,8 +108,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>.",
|
||||
"This room is running room version <roomVersion />, which this homeserver has marked as <i>unstable</i>.",
|
||||
{},
|
||||
{
|
||||
roomVersion: () => <code>{this.props.room.getVersion()}</code>,
|
||||
|
|
|
@ -496,7 +496,10 @@ export class SendMessageComposer extends React.Component<ISendMessageComposerPro
|
|||
return; // errored
|
||||
}
|
||||
|
||||
if (content && [CommandCategories.messages, CommandCategories.effects].includes(cmd.category)) {
|
||||
if (
|
||||
content &&
|
||||
[CommandCategories.messages as string, CommandCategories.effects as string].includes(cmd.category)
|
||||
) {
|
||||
// Attach any mentions which might be contained in the command content.
|
||||
attachMentions(this.props.mxClient.getSafeUserId(), content, model, replyToEvent);
|
||||
attachRelation(content, this.props.relation);
|
||||
|
|
|
@ -19,7 +19,7 @@ import { Room, ClientEvent } from "matrix-js-sdk/src/matrix";
|
|||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { IWidget } from "matrix-widget-api";
|
||||
|
||||
import { _t, _td } from "../../../languageHandler";
|
||||
import { _t, _td, TranslationKey } from "../../../languageHandler";
|
||||
import AppTile from "../elements/AppTile";
|
||||
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
||||
import dis from "../../../dispatcher/dispatcher";
|
||||
|
@ -159,7 +159,7 @@ export default class Stickerpicker extends React.PureComponent<IProps, IState> {
|
|||
this.sendVisibilityToWidget(this.props.isStickerPickerOpen);
|
||||
}
|
||||
|
||||
private imError(errorMsg: string, e: Error): void {
|
||||
private imError(errorMsg: TranslationKey, e: Error): void {
|
||||
logger.error(errorMsg, e);
|
||||
this.setState({
|
||||
imError: _t(errorMsg),
|
||||
|
|
|
@ -108,8 +108,7 @@ export default class ThirdPartyMemberInfo extends React.Component<IProps, IState
|
|||
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.",
|
||||
"Could not revoke the invite. The server may be experiencing a temporary problem or you do not have sufficient permissions to revoke the invite.",
|
||||
),
|
||||
});
|
||||
});
|
||||
|
|
|
@ -203,8 +203,7 @@ export default class CrossSigningPanel extends React.PureComponent<{}, IState> {
|
|||
summarisedStatus = (
|
||||
<SettingsSubsectionText data-testid="summarised-status">
|
||||
{_t(
|
||||
"Your account has a cross-signing identity in secret storage, " +
|
||||
"but it is not yet trusted by this session.",
|
||||
"Your account has a cross-signing identity in secret storage, but it is not yet trusted by this session.",
|
||||
)}
|
||||
</SettingsSubsectionText>
|
||||
);
|
||||
|
|
|
@ -149,8 +149,7 @@ export default class EventIndexPanel extends React.Component<{}, IState> {
|
|||
<>
|
||||
<SettingsSubsectionText>
|
||||
{_t(
|
||||
"Securely cache encrypted messages locally for them " +
|
||||
"to appear in search results, using %(size)s to store messages from %(rooms)s rooms.",
|
||||
"Securely cache encrypted messages locally for them to appear in search results, using %(size)s to store messages from %(rooms)s rooms.",
|
||||
{
|
||||
size: formatBytes(this.state.eventIndexSize, 0),
|
||||
// This drives the singular / plural string
|
||||
|
@ -188,10 +187,7 @@ export default class EventIndexPanel extends React.Component<{}, IState> {
|
|||
eventIndexingSettings = (
|
||||
<SettingsSubsectionText>
|
||||
{_t(
|
||||
"%(brand)s is missing some components required for securely " +
|
||||
"caching encrypted messages locally. If you'd like to " +
|
||||
"experiment with this feature, build a custom %(brand)s Desktop " +
|
||||
"with <nativeLink>search components added</nativeLink>.",
|
||||
"%(brand)s is missing some components required for securely caching encrypted messages locally. If you'd like to experiment with this feature, build a custom %(brand)s Desktop with <nativeLink>search components added</nativeLink>.",
|
||||
{
|
||||
brand,
|
||||
},
|
||||
|
@ -209,9 +205,7 @@ export default class EventIndexPanel extends React.Component<{}, IState> {
|
|||
eventIndexingSettings = (
|
||||
<SettingsSubsectionText>
|
||||
{_t(
|
||||
"%(brand)s can't securely cache encrypted messages locally " +
|
||||
"while running in a web browser. Use <desktopLink>%(brand)s Desktop</desktopLink> " +
|
||||
"for encrypted messages to appear in search results.",
|
||||
"%(brand)s can't securely cache encrypted messages locally while running in a web browser. Use <desktopLink>%(brand)s Desktop</desktopLink> for encrypted messages to appear in search results.",
|
||||
{
|
||||
brand,
|
||||
},
|
||||
|
|
|
@ -323,9 +323,7 @@ const JoinRuleSettings: React.FC<JoinRuleSettingsProps> = ({
|
|||
warning = (
|
||||
<b>
|
||||
{_t(
|
||||
"This room is in some spaces you're not an admin of. " +
|
||||
"In those spaces, the old room will still be shown, " +
|
||||
"but people will be prompted to join the new one.",
|
||||
"This room is in some spaces you're not an admin of. In those spaces, the old room will still be shown, but people will be prompted to join the new one.",
|
||||
)}
|
||||
</b>
|
||||
);
|
||||
|
@ -335,8 +333,7 @@ const JoinRuleSettings: React.FC<JoinRuleSettingsProps> = ({
|
|||
targetVersion,
|
||||
<>
|
||||
{_t(
|
||||
"This upgrade will allow members of selected spaces " +
|
||||
"access to this room without an invite.",
|
||||
"This upgrade will allow members of selected spaces access to this room without an invite.",
|
||||
)}
|
||||
{warning}
|
||||
</>,
|
||||
|
|
|
@ -259,17 +259,14 @@ export default class SecureBackupPanel extends React.PureComponent<{}, IState> {
|
|||
<>
|
||||
<SettingsSubsectionText>
|
||||
{_t(
|
||||
"This session is <b>not backing up your keys</b>, " +
|
||||
"but you do have an existing backup you can restore from " +
|
||||
"and add to going forward.",
|
||||
"This session is <b>not backing up your keys</b>, but you do have an existing backup you can restore from and add to going forward.",
|
||||
{},
|
||||
{ b: (sub) => <b>{sub}</b> },
|
||||
)}
|
||||
</SettingsSubsectionText>
|
||||
<SettingsSubsectionText>
|
||||
{_t(
|
||||
"Connect this session to key backup before signing out to avoid " +
|
||||
"losing any keys that may only be on this session.",
|
||||
"Connect this session to key backup before signing out to avoid losing any keys that may only be on this session.",
|
||||
)}
|
||||
</SettingsSubsectionText>
|
||||
</>
|
||||
|
@ -382,9 +379,7 @@ export default class SecureBackupPanel extends React.PureComponent<{}, IState> {
|
|||
<>
|
||||
<SettingsSubsectionText>
|
||||
{_t(
|
||||
"Back up your encryption keys with your account data in case you " +
|
||||
"lose access to your sessions. Your keys will be secured with a " +
|
||||
"unique Security Key.",
|
||||
"Back up your encryption keys with your account data in case you lose access to your sessions. Your keys will be secured with a unique Security Key.",
|
||||
)}
|
||||
</SettingsSubsectionText>
|
||||
{statusDescription}
|
||||
|
|
|
@ -296,9 +296,7 @@ export default class SetIdServer extends React.Component<IProps, IState> {
|
|||
<div>
|
||||
<p>
|
||||
{_t(
|
||||
"You should <b>remove your personal data</b> from identity server " +
|
||||
"<idserver /> before disconnecting. Unfortunately, identity server " +
|
||||
"<idserver /> is currently offline or cannot be reached.",
|
||||
"You should <b>remove your personal data</b> from identity server <idserver /> before disconnecting. Unfortunately, identity server <idserver /> is currently offline or cannot be reached.",
|
||||
{},
|
||||
messageElements,
|
||||
)}
|
||||
|
@ -307,8 +305,7 @@ export default class SetIdServer extends React.Component<IProps, IState> {
|
|||
<ul>
|
||||
<li>
|
||||
{_t(
|
||||
"check your browser plugins for anything that might block " +
|
||||
"the identity server (such as Privacy Badger)",
|
||||
"check your browser plugins for anything that might block the identity server (such as Privacy Badger)",
|
||||
)}
|
||||
</li>
|
||||
<li>
|
||||
|
@ -338,8 +335,7 @@ export default class SetIdServer extends React.Component<IProps, IState> {
|
|||
</p>
|
||||
<p>
|
||||
{_t(
|
||||
"We recommend that you remove your email addresses and phone numbers " +
|
||||
"from the identity server before disconnecting.",
|
||||
"We recommend that you remove your email addresses and phone numbers from the identity server before disconnecting.",
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
|
@ -388,15 +384,13 @@ export default class SetIdServer extends React.Component<IProps, IState> {
|
|||
if (idServerUrl) {
|
||||
sectionTitle = _t("Identity server (%(server)s)", { server: abbreviateUrl(idServerUrl) });
|
||||
bodyText = _t(
|
||||
"You are currently using <server></server> to discover and be discoverable by " +
|
||||
"existing contacts you know. You can change your identity server below.",
|
||||
"You are currently using <server></server> to discover and be discoverable by existing contacts you know. You can change your identity server below.",
|
||||
{},
|
||||
{ server: (sub) => <b>{abbreviateUrl(idServerUrl)}</b> },
|
||||
);
|
||||
if (this.props.missingTerms) {
|
||||
bodyText = _t(
|
||||
"If you don't want to use <server /> to discover and be discoverable by existing " +
|
||||
"contacts you know, enter another identity server below.",
|
||||
"If you don't want to use <server /> to discover and be discoverable by existing contacts you know, enter another identity server below.",
|
||||
{},
|
||||
{ server: (sub) => <b>{abbreviateUrl(idServerUrl)}</b> },
|
||||
);
|
||||
|
@ -404,9 +398,7 @@ export default class SetIdServer extends React.Component<IProps, IState> {
|
|||
} else {
|
||||
sectionTitle = _t("Identity server");
|
||||
bodyText = _t(
|
||||
"You are not currently using an identity server. " +
|
||||
"To discover and be discoverable by existing contacts you know, " +
|
||||
"add one below.",
|
||||
"You are not currently using an identity server. To discover and be discoverable by existing contacts you know, add one below.",
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -414,15 +406,11 @@ export default class SetIdServer extends React.Component<IProps, IState> {
|
|||
if (idServerUrl) {
|
||||
let discoButtonContent: React.ReactNode = _t("Disconnect");
|
||||
let discoBodyText = _t(
|
||||
"Disconnecting from your identity server will mean you " +
|
||||
"won't be discoverable by other users and you won't be " +
|
||||
"able to invite others by email or phone.",
|
||||
"Disconnecting from your identity server will mean you won't be discoverable by other users and you won't be able to invite others by email or phone.",
|
||||
);
|
||||
if (this.props.missingTerms) {
|
||||
discoBodyText = _t(
|
||||
"Using an identity server is optional. If you choose not to " +
|
||||
"use an identity server, you won't be discoverable by other users " +
|
||||
"and you won't be able to invite others by email or phone.",
|
||||
"Using an identity server is optional. If you choose not to use an identity server, you won't be discoverable by other users and you won't be able to invite others by email or phone.",
|
||||
);
|
||||
discoButtonContent = _t("Do not use an identity server");
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ export default class SetIntegrationManager extends React.Component<IProps, IStat
|
|||
if (currentManager) {
|
||||
managerName = `(${currentManager.name})`;
|
||||
bodyText = _t(
|
||||
"Use an integration manager <b>(%(serverName)s)</b> to manage bots, widgets, " + "and sticker packs.",
|
||||
"Use an integration manager <b>(%(serverName)s)</b> to manage bots, widgets, and sticker packs.",
|
||||
{ serverName: currentManager.name },
|
||||
{ b: (sub) => <b>{sub}</b> },
|
||||
);
|
||||
|
@ -92,8 +92,7 @@ export default class SetIntegrationManager extends React.Component<IProps, IStat
|
|||
<SettingsSubsectionText>{bodyText}</SettingsSubsectionText>
|
||||
<SettingsSubsectionText>
|
||||
{_t(
|
||||
"Integration managers receive configuration data, and can modify widgets, " +
|
||||
"send room invites, and set power levels on your behalf.",
|
||||
"Integration managers receive configuration data, and can modify widgets, send room invites, and set power levels on your behalf.",
|
||||
)}
|
||||
</SettingsSubsectionText>
|
||||
</label>
|
||||
|
|
|
@ -280,8 +280,7 @@ export default class PhoneNumbers extends React.Component<IProps, IState> {
|
|||
<div>
|
||||
<div>
|
||||
{_t(
|
||||
"A text message has been sent to +%(msisdn)s. " +
|
||||
"Please enter the verification code it contains.",
|
||||
"A text message has been sent to +%(msisdn)s. Please enter the verification code it contains.",
|
||||
{ msisdn: msisdn },
|
||||
)}
|
||||
<br />
|
||||
|
|
|
@ -84,14 +84,12 @@ const DeviceNameEditor: React.FC<Props & { stopEditing: () => void }> = ({ devic
|
|||
<>
|
||||
<p>
|
||||
{_t(
|
||||
`Other users in direct messages and rooms that you join ` +
|
||||
`are able to view a full list of your sessions.`,
|
||||
"Other users in direct messages and rooms that you join are able to view a full list of your sessions.",
|
||||
)}
|
||||
</p>
|
||||
<p>
|
||||
{_t(
|
||||
`This provides them with confidence that they are really speaking to you, ` +
|
||||
`but it also means they can see the session name you enter here.`,
|
||||
"This provides them with confidence that they are really speaking to you, but it also means they can see the session name you enter here.",
|
||||
)}
|
||||
</p>
|
||||
</>
|
||||
|
|
|
@ -42,8 +42,7 @@ const securityCardContent: Record<
|
|||
</p>
|
||||
<p>
|
||||
{_t(
|
||||
`This means that you have all the keys needed to unlock your encrypted messages ` +
|
||||
`and confirm to other users that you trust this session.`,
|
||||
"This means that you have all the keys needed to unlock your encrypted messages and confirm to other users that you trust this session.",
|
||||
)}
|
||||
</p>
|
||||
</>
|
||||
|
@ -60,8 +59,7 @@ const securityCardContent: Record<
|
|||
</p>
|
||||
<p>
|
||||
{_t(
|
||||
`You should make especially certain that you recognise these sessions ` +
|
||||
`as they could represent an unauthorised use of your account.`,
|
||||
"You should make especially certain that you recognise these sessions as they could represent an unauthorised use of your account.",
|
||||
)}
|
||||
</p>
|
||||
</>
|
||||
|
@ -98,8 +96,7 @@ const securityCardContent: Record<
|
|||
</p>
|
||||
<p>
|
||||
{_t(
|
||||
`Removing inactive sessions improves security and performance, ` +
|
||||
`and makes it easier for you to identify if a new session is suspicious.`,
|
||||
"Removing inactive sessions improves security and performance, and makes it easier for you to identify if a new session is suspicious.",
|
||||
)}
|
||||
</p>
|
||||
</>
|
||||
|
|
|
@ -88,8 +88,7 @@ const securityCardContent: Record<
|
|||
[DeviceSecurityVariation.Unverified]: {
|
||||
title: _t("Unverified sessions"),
|
||||
description: _t(
|
||||
`Verify your sessions for enhanced secure messaging or ` +
|
||||
`sign out from those you don't recognize or use anymore.`,
|
||||
"Verify your sessions for enhanced secure messaging or sign out from those you don't recognize or use anymore.",
|
||||
),
|
||||
},
|
||||
[DeviceSecurityVariation.Unverifiable]: {
|
||||
|
@ -99,7 +98,7 @@ const securityCardContent: Record<
|
|||
[DeviceSecurityVariation.Inactive]: {
|
||||
title: _t("Inactive sessions"),
|
||||
description: _t(
|
||||
`Consider signing out from old sessions ` + `(%(inactiveAgeDays)s days or older) you don't use anymore.`,
|
||||
"Consider signing out from old sessions (%(inactiveAgeDays)s days or older) you don't use anymore.",
|
||||
{ inactiveAgeDays: INACTIVE_DEVICE_AGE_DAYS },
|
||||
),
|
||||
},
|
||||
|
|
|
@ -56,8 +56,7 @@ export default class LoginWithQRSection extends React.Component<IProps> {
|
|||
<div className="mx_LoginWithQRSection">
|
||||
<p className="mx_SettingsTab_subsectionText">
|
||||
{_t(
|
||||
"You can use this device to sign in a new device with a QR code. You will need to " +
|
||||
"scan the QR code shown on this device with your device that's signed out.",
|
||||
"You can use this device to sign in a new device with a QR code. You will need to scan the QR code shown on this device with your device that's signed out.",
|
||||
)}
|
||||
</p>
|
||||
<AccessibleButton onClick={this.props.onShowQr} kind="primary">
|
||||
|
|
|
@ -63,8 +63,7 @@ const SecurityRecommendations: React.FC<Props> = ({ devices, currentDeviceId, go
|
|||
description={
|
||||
<>
|
||||
{_t(
|
||||
`Verify your sessions for enhanced secure messaging` +
|
||||
` or sign out from those you don't recognize or use anymore.`,
|
||||
"Verify your sessions for enhanced secure messaging or sign out from those you don't recognize or use anymore.",
|
||||
)}
|
||||
<DeviceSecurityLearnMore variation={DeviceSecurityVariation.Unverified} />
|
||||
</>
|
||||
|
@ -88,8 +87,7 @@ const SecurityRecommendations: React.FC<Props> = ({ devices, currentDeviceId, go
|
|||
description={
|
||||
<>
|
||||
{_t(
|
||||
`Consider signing out from old sessions ` +
|
||||
`(%(inactiveAgeDays)s days or older) you don't use anymore.`,
|
||||
"Consider signing out from old sessions (%(inactiveAgeDays)s days or older) you don't use anymore.",
|
||||
{ inactiveAgeDays },
|
||||
)}
|
||||
<DeviceSecurityLearnMore variation={DeviceSecurityVariation.Inactive} />
|
||||
|
|
|
@ -110,11 +110,7 @@ export default function NotificationSettings2(): JSX.Element {
|
|||
onAction={() => reconcile(model!)}
|
||||
>
|
||||
{_t(
|
||||
"<strong>Update:</strong>" +
|
||||
"We’ve simplified Notifications Settings to make options easier to find. " +
|
||||
"Some custom settings you’ve chosen in the past are not shown here, but they’re still active. " +
|
||||
"If you proceed, some of your settings may change. " +
|
||||
"<a>Learn more</a>",
|
||||
"<strong>Update:</strong>We’ve simplified Notifications Settings to make options easier to find. Some custom settings you’ve chosen in the past are not shown here, but they’re still active. If you proceed, some of your settings may change. <a>Learn more</a>",
|
||||
{},
|
||||
{
|
||||
strong: boldText,
|
||||
|
|
|
@ -120,9 +120,7 @@ export default class AdvancedRoomSettingsTab extends React.Component<IProps, ISt
|
|||
<div>
|
||||
<p className="mx_SettingsTab_warningText">
|
||||
{_t(
|
||||
"<b>Warning</b>: upgrading a room will <i>not automatically migrate room members " +
|
||||
"to the new version of the room.</i> We'll post a link to the new room in the old " +
|
||||
"version of the room - room members will have to click this link to join the new room.",
|
||||
"<b>Warning</b>: upgrading a room will <i>not automatically migrate room members to the new version of the room.</i> We'll post a link to the new room in the old version of the room - room members will have to click this link to join the new room.",
|
||||
{},
|
||||
{
|
||||
b: (sub) => <b>{sub}</b>,
|
||||
|
|
|
@ -63,7 +63,7 @@ export default class BridgeSettingsTab extends React.Component<IProps> {
|
|||
<div>
|
||||
<p>
|
||||
{_t(
|
||||
"This room is bridging messages to the following platforms. " + "<a>Learn more.</a>",
|
||||
"This room is bridging messages to the following platforms. <a>Learn more.</a>",
|
||||
{},
|
||||
{
|
||||
// TODO: We don't have this link yet: this will prevent the translators
|
||||
|
@ -85,7 +85,7 @@ export default class BridgeSettingsTab extends React.Component<IProps> {
|
|||
content = (
|
||||
<p>
|
||||
{_t(
|
||||
"This room isn't bridging messages to any platforms. " + "<a>Learn more.</a>",
|
||||
"This room isn't bridging messages to any platforms. <a>Learn more.</a>",
|
||||
{},
|
||||
{
|
||||
// TODO: We don't have this link yet: this will prevent the translators
|
||||
|
|
|
@ -221,8 +221,7 @@ export default class NotificationsSettingsTab extends React.Component<IProps, IS
|
|||
{_t("@mentions & keywords")}
|
||||
<div className="mx_NotificationSettingsTab_microCopy">
|
||||
{_t(
|
||||
"Get notified only with mentions and keywords " +
|
||||
"as set up in your <a>settings</a>",
|
||||
"Get notified only with mentions and keywords as set up in your <a>settings</a>",
|
||||
{},
|
||||
{
|
||||
a: (sub) => (
|
||||
|
|
|
@ -20,7 +20,7 @@ import { logger } from "matrix-js-sdk/src/logger";
|
|||
import { throttle, get } from "lodash";
|
||||
import { compare } from "matrix-js-sdk/src/utils";
|
||||
|
||||
import { _t, _td } from "../../../../../languageHandler";
|
||||
import { _t, _td, TranslationKey } from "../../../../../languageHandler";
|
||||
import AccessibleButton from "../../../elements/AccessibleButton";
|
||||
import Modal from "../../../../../Modal";
|
||||
import ErrorDialog from "../../../dialogs/ErrorDialog";
|
||||
|
@ -207,8 +207,7 @@ export default class RolesRoomSettingsTab extends React.Component<IProps> {
|
|||
Modal.createDialog(ErrorDialog, {
|
||||
title: _t("Error changing power level requirement"),
|
||||
description: _t(
|
||||
"An error occurred changing the room's power level requirements. Ensure you have sufficient " +
|
||||
"permissions and try again.",
|
||||
"An error occurred changing the room's power level requirements. Ensure you have sufficient permissions and try again.",
|
||||
),
|
||||
});
|
||||
});
|
||||
|
@ -233,8 +232,7 @@ export default class RolesRoomSettingsTab extends React.Component<IProps> {
|
|||
Modal.createDialog(ErrorDialog, {
|
||||
title: _t("Error changing power level"),
|
||||
description: _t(
|
||||
"An error occurred changing the user's power level. Ensure you have sufficient " +
|
||||
"permissions and try again.",
|
||||
"An error occurred changing the user's power level. Ensure you have sufficient permissions and try again.",
|
||||
),
|
||||
});
|
||||
});
|
||||
|
@ -249,7 +247,7 @@ export default class RolesRoomSettingsTab extends React.Component<IProps> {
|
|||
const plContent = plEvent ? plEvent.getContent() || {} : {};
|
||||
const canChangeLevels = room.currentState.mayClientSendStateEvent(EventType.RoomPowerLevels, client);
|
||||
|
||||
const plEventsToLabels: Record<EventType | string, string | null> = {
|
||||
const plEventsToLabels: Record<EventType | string, TranslationKey | null> = {
|
||||
// These will be translated for us later.
|
||||
[EventType.RoomAvatar]: isSpaceRoom ? _td("Change space avatar") : _td("Change room avatar"),
|
||||
[EventType.RoomName]: isSpaceRoom ? _td("Change space name") : _td("Change room name"),
|
||||
|
@ -458,10 +456,11 @@ export default class RolesRoomSettingsTab extends React.Component<IProps> {
|
|||
return null;
|
||||
}
|
||||
|
||||
let label = plEventsToLabels[eventType];
|
||||
if (label) {
|
||||
const translationKeyForEvent = plEventsToLabels[eventType];
|
||||
let label: string;
|
||||
if (translationKeyForEvent) {
|
||||
const brand = SdkConfig.get("element_call").brand ?? DEFAULTS.element_call.brand;
|
||||
label = _t(label, { brand });
|
||||
label = _t(translationKeyForEvent, { brand });
|
||||
} else {
|
||||
label = _t("Send %(eventType)s events", { eventType });
|
||||
}
|
||||
|
|
|
@ -122,11 +122,7 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
|
|||
<p>
|
||||
{" "}
|
||||
{_t(
|
||||
"<b>It's not recommended to add encryption to public rooms.</b> " +
|
||||
"Anyone can find and join public rooms, so anyone can read messages in them. " +
|
||||
"You'll get none of the benefits of encryption, and you won't be able to turn it " +
|
||||
"off later. Encrypting messages in a public room will make receiving and sending " +
|
||||
"messages slower.",
|
||||
"<b>It's not recommended to add encryption to public rooms.</b> Anyone can find and join public rooms, so anyone can read messages in them. You'll get none of the benefits of encryption, and you won't be able to turn it off later. Encrypting messages in a public room will make receiving and sending messages slower.",
|
||||
undefined,
|
||||
{ b: (sub) => <b>{sub}</b> },
|
||||
)}{" "}
|
||||
|
@ -134,8 +130,7 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
|
|||
<p>
|
||||
{" "}
|
||||
{_t(
|
||||
"To avoid these issues, create a <a>new encrypted room</a> for " +
|
||||
"the conversation you plan to have.",
|
||||
"To avoid these issues, create a <a>new encrypted room</a> for the conversation you plan to have.",
|
||||
undefined,
|
||||
{
|
||||
a: (sub) => (
|
||||
|
@ -165,9 +160,7 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
|
|||
Modal.createDialog(QuestionDialog, {
|
||||
title: _t("Enable encryption?"),
|
||||
description: _t(
|
||||
"Once enabled, encryption for a room cannot be disabled. Messages sent in an encrypted " +
|
||||
"room cannot be seen by the server, only by the participants of the room. Enabling encryption " +
|
||||
"may prevent many bots and bridges from working correctly. <a>Learn more about encryption.</a>",
|
||||
"Once enabled, encryption for a room cannot be disabled. Messages sent in an encrypted room cannot be seen by the server, only by the participants of the room. Enabling encryption may prevent many bots and bridges from working correctly. <a>Learn more about encryption.</a>",
|
||||
{},
|
||||
{
|
||||
a: (sub) => <ExternalLink href={SdkConfig.get("help_encryption_url")}>{sub}</ExternalLink>,
|
||||
|
@ -322,10 +315,7 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
|
|||
<p>
|
||||
{" "}
|
||||
{_t(
|
||||
"<b>It's not recommended to make encrypted rooms public.</b> " +
|
||||
"It will mean anyone can find and join the room, so anyone can read messages. " +
|
||||
"You'll get none of the benefits of encryption. Encrypting messages in a public " +
|
||||
"room will make receiving and sending messages slower.",
|
||||
"<b>It's not recommended to make encrypted rooms public.</b> It will mean anyone can find and join the room, so anyone can read messages. You'll get none of the benefits of encryption. Encrypting messages in a public room will make receiving and sending messages slower.",
|
||||
undefined,
|
||||
{ b: (sub) => <b>{sub}</b> },
|
||||
)}{" "}
|
||||
|
@ -333,8 +323,7 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
|
|||
<p>
|
||||
{" "}
|
||||
{_t(
|
||||
"To avoid these issues, create a <a>new public room</a> for the conversation " +
|
||||
"you plan to have.",
|
||||
"To avoid these issues, create a <a>new public room</a> for the conversation you plan to have.",
|
||||
undefined,
|
||||
{
|
||||
a: (sub) => (
|
||||
|
@ -398,8 +387,7 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
|
|||
}
|
||||
|
||||
const description = _t(
|
||||
"Changes to who can read history will only apply to future messages in this room. " +
|
||||
"The visibility of existing history will be unchanged.",
|
||||
"Changes to who can read history will only apply to future messages in this room. The visibility of existing history will be unchanged.",
|
||||
);
|
||||
|
||||
return (
|
||||
|
@ -435,8 +423,7 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
|
|||
/>
|
||||
<p>
|
||||
{_t(
|
||||
"People with supported clients will be able to join " +
|
||||
"the room without having a registered account.",
|
||||
"People with supported clients will be able to join the room without having a registered account.",
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
@ -82,10 +82,9 @@ const ElementCallSwitch: React.FC<ElementCallSwitchProps> = ({ room }) => {
|
|||
<LabelledToggleSwitch
|
||||
data-testid="element-call-switch"
|
||||
label={_t("Enable %(brand)s as an additional calling option in this room", { brand })}
|
||||
caption={_t(
|
||||
"%(brand)s is end-to-end encrypted, " + "but is currently limited to smaller numbers of users.",
|
||||
{ brand },
|
||||
)}
|
||||
caption={_t("%(brand)s is end-to-end encrypted, but is currently limited to smaller numbers of users.", {
|
||||
brand,
|
||||
})}
|
||||
value={elementCallEnabled}
|
||||
onChange={onChange}
|
||||
disabled={!maySend}
|
||||
|
|
|
@ -455,8 +455,7 @@ export default class GeneralUserSettingsTab extends React.Component<IProps, ISta
|
|||
const intro = (
|
||||
<SettingsSubsectionText>
|
||||
{_t(
|
||||
"Agree to the identity server (%(serverName)s) Terms of Service to " +
|
||||
"allow yourself to be discoverable by email address or phone number.",
|
||||
"Agree to the identity server (%(serverName)s) Terms of Service to allow yourself to be discoverable by email address or phone number.",
|
||||
{ serverName: this.state.idServerName },
|
||||
)}
|
||||
</SettingsSubsectionText>
|
||||
|
|
|
@ -136,8 +136,7 @@ export default class HelpUserSettingsTab extends React.Component<IProps, IState>
|
|||
<ul>
|
||||
<li>
|
||||
{_t(
|
||||
"The <photo>default cover photo</photo> is © " +
|
||||
"<author>Jesús Roncero</author> used under the terms of <terms>CC-BY-SA 4.0</terms>.",
|
||||
"The <photo>default cover photo</photo> is © <author>Jesús Roncero</author> used under the terms of <terms>CC-BY-SA 4.0</terms>.",
|
||||
{},
|
||||
{
|
||||
photo: (sub) => (
|
||||
|
@ -166,8 +165,7 @@ export default class HelpUserSettingsTab extends React.Component<IProps, IState>
|
|||
</li>
|
||||
<li>
|
||||
{_t(
|
||||
"The <colr>twemoji-colr</colr> font is © <author>Mozilla Foundation</author> " +
|
||||
"used under the terms of <terms>Apache 2.0</terms>.",
|
||||
"The <colr>twemoji-colr</colr> font is © <author>Mozilla Foundation</author> used under the terms of <terms>Apache 2.0</terms>.",
|
||||
{},
|
||||
{
|
||||
colr: (sub) => (
|
||||
|
@ -194,9 +192,7 @@ export default class HelpUserSettingsTab extends React.Component<IProps, IState>
|
|||
</li>
|
||||
<li>
|
||||
{_t(
|
||||
"The <twemoji>Twemoji</twemoji> emoji art is © " +
|
||||
"<author>Twitter, Inc and other contributors</author> used under the terms of " +
|
||||
"<terms>CC-BY 4.0</terms>.",
|
||||
"The <twemoji>Twemoji</twemoji> emoji art is © <author>Twitter, Inc and other contributors</author> used under the terms of <terms>CC-BY 4.0</terms>.",
|
||||
{},
|
||||
{
|
||||
twemoji: (sub) => (
|
||||
|
@ -244,8 +240,7 @@ export default class HelpUserSettingsTab extends React.Component<IProps, IState>
|
|||
faqText = (
|
||||
<div>
|
||||
{_t(
|
||||
"For help with using %(brand)s, click <a>here</a> or start a chat with our " +
|
||||
"bot using the button below.",
|
||||
"For help with using %(brand)s, click <a>here</a> or start a chat with our bot using the button below.",
|
||||
{
|
||||
brand,
|
||||
},
|
||||
|
@ -284,16 +279,11 @@ export default class HelpUserSettingsTab extends React.Component<IProps, IState>
|
|||
<>
|
||||
<SettingsSubsectionText>
|
||||
{_t(
|
||||
"If you've submitted a bug via GitHub, debug logs can help " +
|
||||
"us track down the problem. ",
|
||||
"If you've submitted a bug via GitHub, debug logs can help us track down the problem. ",
|
||||
)}
|
||||
</SettingsSubsectionText>
|
||||
{_t(
|
||||
"Debug logs contain application " +
|
||||
"usage data including your username, the IDs or aliases of " +
|
||||
"the rooms you have visited, which UI elements you " +
|
||||
"last interacted with, and the usernames of other users. " +
|
||||
"They do not contain messages.",
|
||||
"Debug logs contain application usage data including your username, the IDs or aliases of the rooms you have visited, which UI elements you last interacted with, and the usernames of other users. They do not contain messages.",
|
||||
)}
|
||||
</>
|
||||
}
|
||||
|
@ -303,8 +293,7 @@ export default class HelpUserSettingsTab extends React.Component<IProps, IState>
|
|||
</AccessibleButton>
|
||||
<SettingsSubsectionText>
|
||||
{_t(
|
||||
"To report a Matrix-related security issue, please read the Matrix.org " +
|
||||
"<a>Security Disclosure Policy</a>.",
|
||||
"To report a Matrix-related security issue, please read the Matrix.org <a>Security Disclosure Policy</a>.",
|
||||
{},
|
||||
{
|
||||
a: (sub) => (
|
||||
|
@ -369,8 +358,7 @@ export default class HelpUserSettingsTab extends React.Component<IProps, IState>
|
|||
<summary>{_t("Access Token")}</summary>
|
||||
<b>
|
||||
{_t(
|
||||
"Your access token gives full access to your account." +
|
||||
" Do not share it with anyone.",
|
||||
"Your access token gives full access to your account. Do not share it with anyone.",
|
||||
)}
|
||||
</b>
|
||||
<CopyableText getTextToCopy={() => this.context.getAccessToken()}>
|
||||
|
|
|
@ -113,9 +113,7 @@ export default class LabsUserSettingsTab extends React.Component<{}> {
|
|||
<SettingsSection heading={_t("Upcoming features")}>
|
||||
<SettingsSubsectionText>
|
||||
{_t(
|
||||
"What's next for %(brand)s? " +
|
||||
"Labs are the best way to get things early, " +
|
||||
"test out new features and help shape them before they actually launch.",
|
||||
"What's next for %(brand)s? Labs are the best way to get things early, test out new features and help shape them before they actually launch.",
|
||||
{ brand: SdkConfig.get("brand") },
|
||||
)}
|
||||
</SettingsSubsectionText>
|
||||
|
@ -126,11 +124,7 @@ export default class LabsUserSettingsTab extends React.Component<{}> {
|
|||
<SettingsSection heading={_t("Early previews")}>
|
||||
<SettingsSubsectionText>
|
||||
{_t(
|
||||
"Feeling experimental? " +
|
||||
"Try out our latest ideas in development. " +
|
||||
"These features are not finalised; " +
|
||||
"they may be unstable, may change, or may be dropped altogether. " +
|
||||
"<a>Learn more</a>.",
|
||||
"Feeling experimental? Try out our latest ideas in development. These features are not finalised; they may be unstable, may change, or may be dropped altogether. <a>Learn more</a>.",
|
||||
{},
|
||||
{
|
||||
a: (sub) => {
|
||||
|
|
|
@ -259,28 +259,21 @@ export default class MjolnirUserSettingsTab extends React.Component<{}, IState>
|
|||
<span className="warning">{_t("⚠ These settings are meant for advanced users.")}</span>
|
||||
<p>
|
||||
{_t(
|
||||
"Add users and servers you want to ignore here. Use asterisks " +
|
||||
"to have %(brand)s match any characters. For example, <code>@bot:*</code> " +
|
||||
"would ignore all users that have the name 'bot' on any server.",
|
||||
"Add users and servers you want to ignore here. Use asterisks to have %(brand)s match any characters. For example, <code>@bot:*</code> would ignore all users that have the name 'bot' on any server.",
|
||||
{ brand },
|
||||
{ code: (s) => <code>{s}</code> },
|
||||
)}
|
||||
</p>
|
||||
<p>
|
||||
{_t(
|
||||
"Ignoring people is done through ban lists which contain rules for " +
|
||||
"who to ban. Subscribing to a ban list means the users/servers blocked by " +
|
||||
"that list will be hidden from you.",
|
||||
"Ignoring people is done through ban lists which contain rules for who to ban. Subscribing to a ban list means the users/servers blocked by that list will be hidden from you.",
|
||||
)}
|
||||
</p>
|
||||
</SettingsSubsectionText>
|
||||
<SettingsSubsection
|
||||
heading={_t("Personal ban list")}
|
||||
description={_t(
|
||||
"Your personal ban list holds all the users/servers you personally don't " +
|
||||
"want to see messages from. After ignoring your first user/server, a new room " +
|
||||
"will show up in your room list named '%(myBanList)s' - stay in this room to keep " +
|
||||
"the ban list in effect.",
|
||||
"Your personal ban list holds all the users/servers you personally don't want to see messages from. After ignoring your first user/server, a new room will show up in your room list named '%(myBanList)s' - stay in this room to keep the ban list in effect.",
|
||||
{
|
||||
myBanList: _t("My Ban List"),
|
||||
},
|
||||
|
|
|
@ -302,8 +302,7 @@ export default class SecurityUserSettingsTab extends React.Component<IProps, ISt
|
|||
warning = (
|
||||
<div className="mx_SecurityUserSettingsTab_warning">
|
||||
{_t(
|
||||
"Your server admin has disabled end-to-end encryption by default " +
|
||||
"in private rooms & Direct Messages.",
|
||||
"Your server admin has disabled end-to-end encryption by default in private rooms & Direct Messages.",
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -303,8 +303,7 @@ const SessionManagerTab: React.FC = () => {
|
|||
/>
|
||||
}
|
||||
description={_t(
|
||||
`For best security, verify your sessions and sign out ` +
|
||||
`from any session that you don't recognize or use anymore.`,
|
||||
"For best security, verify your sessions and sign out from any session that you don't recognize or use anymore.",
|
||||
)}
|
||||
data-testid="other-sessions-section"
|
||||
stretchContent
|
||||
|
|
|
@ -68,8 +68,7 @@ const SidebarUserSettingsTab: React.FC = () => {
|
|||
<SettingsSubsection
|
||||
heading={_t("Spaces to show")}
|
||||
description={_t(
|
||||
"Spaces are ways to group rooms and people. " +
|
||||
"Alongside the spaces you're in, you can use some pre-built ones too.",
|
||||
"Spaces are ways to group rooms and people. Alongside the spaces you're in, you can use some pre-built ones too.",
|
||||
)}
|
||||
>
|
||||
<StyledCheckbox
|
||||
|
|
|
@ -287,8 +287,7 @@ const SpaceCreateMenu: React.FC<{
|
|||
<h2>{_t("Create a space")}</h2>
|
||||
<p>
|
||||
{_t(
|
||||
"Spaces are a new way to group rooms and people. What kind of Space do you want to create? " +
|
||||
"You can change this later.",
|
||||
"Spaces are a new way to group rooms and people. What kind of Space do you want to create? You can change this later.",
|
||||
)}
|
||||
</p>
|
||||
|
||||
|
|
|
@ -43,8 +43,7 @@ export function UserOnboardingHeader({ useCase }: Props): JSX.Element {
|
|||
case UseCase.PersonalMessaging:
|
||||
title = _t("Secure messaging for friends and family");
|
||||
description = _t(
|
||||
"With free end-to-end encrypted messaging, and unlimited voice and video calls, " +
|
||||
"%(brand)s is a great way to stay in touch.",
|
||||
"With free end-to-end encrypted messaging, and unlimited voice and video calls, %(brand)s is a great way to stay in touch.",
|
||||
{
|
||||
brand: SdkConfig.get("brand"),
|
||||
},
|
||||
|
@ -55,8 +54,7 @@ export function UserOnboardingHeader({ useCase }: Props): JSX.Element {
|
|||
case UseCase.WorkMessaging:
|
||||
title = _t("Secure messaging for work");
|
||||
description = _t(
|
||||
"With free end-to-end encrypted messaging, and unlimited voice and video calls," +
|
||||
" %(brand)s is a great way to stay in touch.",
|
||||
"With free end-to-end encrypted messaging, and unlimited voice and video calls, %(brand)s is a great way to stay in touch.",
|
||||
{
|
||||
brand: SdkConfig.get("brand"),
|
||||
},
|
||||
|
@ -67,8 +65,7 @@ export function UserOnboardingHeader({ useCase }: Props): JSX.Element {
|
|||
case UseCase.CommunityMessaging:
|
||||
title = _t("Community ownership");
|
||||
description = _t(
|
||||
"Keep ownership and control of community discussion.\n" +
|
||||
"Scale to support millions, with powerful moderation and interoperability.",
|
||||
"Keep ownership and control of community discussion.\nScale to support millions, with powerful moderation and interoperability.",
|
||||
);
|
||||
image = require("../../../../res/img/user-onboarding/CommunityMessaging.png");
|
||||
actionLabel = _t("Find your people");
|
||||
|
@ -78,8 +75,7 @@ export function UserOnboardingHeader({ useCase }: Props): JSX.Element {
|
|||
brand: SdkConfig.get("brand"),
|
||||
});
|
||||
description = _t(
|
||||
"With free end-to-end encrypted messaging, and unlimited voice and video calls," +
|
||||
" %(brand)s is a great way to stay in touch.",
|
||||
"With free end-to-end encrypted messaging, and unlimited voice and video calls, %(brand)s is a great way to stay in touch.",
|
||||
{
|
||||
brand: SdkConfig.get("brand"),
|
||||
},
|
||||
|
|
|
@ -31,8 +31,7 @@ export default class VerificationComplete extends React.Component<IProps> {
|
|||
<p>{_t("You've successfully verified this user.")}</p>
|
||||
<p>
|
||||
{_t(
|
||||
"Secure messages with this user are end-to-end encrypted and not able to be " +
|
||||
"read by third parties.",
|
||||
"Secure messages with this user are end-to-end encrypted and not able to be read by third parties.",
|
||||
)}
|
||||
</p>
|
||||
<DialogButtons
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue