Migrate more strings to translation keys (#11651)
This commit is contained in:
parent
560449676b
commit
f4d056fd38
127 changed files with 8916 additions and 8272 deletions
|
@ -68,13 +68,13 @@ export default class AutoDiscoveryUtils {
|
|||
serverDeadError: null,
|
||||
};
|
||||
}
|
||||
let title = _t("Cannot reach homeserver");
|
||||
let body: ReactNode = _t("Ensure you have a stable internet connection, or get in touch with the server admin");
|
||||
let title = _t("cannot_reach_homeserver");
|
||||
let body: ReactNode = _t("cannot_reach_homeserver_detail");
|
||||
if (!AutoDiscoveryUtils.isLivelinessError(err)) {
|
||||
const brand = SdkConfig.get().brand;
|
||||
title = _t("Your %(brand)s is misconfigured", { brand });
|
||||
title = _t("auth|misconfigured_title", { brand });
|
||||
body = _t(
|
||||
"Ask your %(brand)s admin to check <a>your config</a> for incorrect or duplicate entries.",
|
||||
"auth|misconfigured_body",
|
||||
{
|
||||
brand,
|
||||
},
|
||||
|
@ -98,22 +98,16 @@ export default class AutoDiscoveryUtils {
|
|||
const errorMessage = err instanceof Error ? err.message : err;
|
||||
if (errorMessage === AutoDiscovery.ERROR_INVALID_IDENTITY_SERVER) {
|
||||
isFatalError = false;
|
||||
title = _t("Cannot reach identity server");
|
||||
title = _t("auth|failed_connect_identity_server");
|
||||
|
||||
// It's annoying having a ladder for the third word in the same sentence, but our translations
|
||||
// don't make this easy to avoid.
|
||||
if (pageName === "register") {
|
||||
body = _t(
|
||||
"You can register, but some features will be unavailable until the identity server is back online. If you keep seeing this warning, check your configuration or contact a server admin.",
|
||||
);
|
||||
body = _t("auth|failed_connect_identity_server_register");
|
||||
} else if (pageName === "reset_password") {
|
||||
body = _t(
|
||||
"You can reset your password, but some features will be unavailable until the identity server is back online. If you keep seeing this warning, check your configuration or contact a server admin.",
|
||||
);
|
||||
body = _t("auth|failed_connect_identity_server_reset_password");
|
||||
} else {
|
||||
body = _t(
|
||||
"You can log in, but some features will be unavailable until the identity server is back online. If you keep seeing this warning, check your configuration or contact a server admin.",
|
||||
);
|
||||
body = _t("auth|failed_connect_identity_server_other");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -143,7 +137,7 @@ export default class AutoDiscoveryUtils {
|
|||
syntaxOnly = false,
|
||||
): Promise<ValidatedServerConfig> {
|
||||
if (!homeserverUrl) {
|
||||
throw new UserFriendlyError("No homeserver URL provided");
|
||||
throw new UserFriendlyError("auth|no_hs_url_provided");
|
||||
}
|
||||
|
||||
const wellknownConfig: IClientWellKnown = {
|
||||
|
@ -195,7 +189,7 @@ export default class AutoDiscoveryUtils {
|
|||
// This shouldn't happen without major misconfiguration, so we'll log a bit of information
|
||||
// in the log so we can find this bit of code but otherwise tell the user "it broke".
|
||||
logger.error("Ended up in a state of not knowing which homeserver to connect to.");
|
||||
throw new UserFriendlyError("Unexpected error resolving homeserver configuration");
|
||||
throw new UserFriendlyError("auth|autodiscovery_unexpected_error_hs");
|
||||
}
|
||||
|
||||
const hsResult = discoveryResult["m.homeserver"];
|
||||
|
@ -220,7 +214,7 @@ export default class AutoDiscoveryUtils {
|
|||
// XXX: We mark these with _td at the top of Login.tsx - we should come up with a better solution
|
||||
throw new UserFriendlyError(String(isResult.error) as TranslationKey);
|
||||
}
|
||||
throw new UserFriendlyError("Unexpected error resolving identity server configuration");
|
||||
throw new UserFriendlyError("auth|autodiscovery_unexpected_error_is");
|
||||
} // else the error is not related to syntax - continue anyways.
|
||||
|
||||
// rewrite homeserver error since we don't care about problems
|
||||
|
@ -238,11 +232,9 @@ export default class AutoDiscoveryUtils {
|
|||
throw new UserFriendlyError(String(hsResult.error) as TranslationKey);
|
||||
}
|
||||
if (hsResult.error === AutoDiscovery.ERROR_HOMESERVER_TOO_OLD) {
|
||||
throw new UserFriendlyError(
|
||||
"Your homeserver is too old and does not support the minimum API version required. Please contact your server owner, or upgrade your server.",
|
||||
);
|
||||
throw new UserFriendlyError("auth|autodiscovery_hs_incompatible");
|
||||
}
|
||||
throw new UserFriendlyError("Unexpected error resolving homeserver configuration");
|
||||
throw new UserFriendlyError("auth|autodiscovery_unexpected_error_hs");
|
||||
} // else the error is not related to syntax - continue anyways.
|
||||
}
|
||||
|
||||
|
@ -250,7 +242,7 @@ export default class AutoDiscoveryUtils {
|
|||
|
||||
if (!preferredHomeserverUrl) {
|
||||
logger.error("No homeserver URL configured");
|
||||
throw new UserFriendlyError("Unexpected error resolving homeserver configuration");
|
||||
throw new UserFriendlyError("auth|autodiscovery_unexpected_error_hs");
|
||||
}
|
||||
|
||||
let preferredHomeserverName = serverName ?? hsResult["server_name"];
|
||||
|
@ -261,7 +253,7 @@ export default class AutoDiscoveryUtils {
|
|||
// It should have been set by now, so check it
|
||||
if (!preferredHomeserverName) {
|
||||
logger.error("Failed to parse homeserver name from homeserver URL");
|
||||
throw new UserFriendlyError("Unexpected error resolving homeserver configuration");
|
||||
throw new UserFriendlyError("auth|autodiscovery_unexpected_error_hs");
|
||||
}
|
||||
|
||||
let delegatedAuthentication: OidcClientConfig | undefined;
|
||||
|
|
|
@ -17,19 +17,19 @@ limitations under the License.
|
|||
import React, { ReactNode } from "react";
|
||||
import { MatrixError, ConnectionError } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import { _t, _td, Tags, TranslatedString, TranslationKey } from "../languageHandler";
|
||||
import { _t, _td, lookupString, Tags, TranslatedString, TranslationKey } from "../languageHandler";
|
||||
import SdkConfig from "../SdkConfig";
|
||||
import { ValidatedServerConfig } from "./ValidatedServerConfig";
|
||||
import ExternalLink from "../components/views/elements/ExternalLink";
|
||||
|
||||
export const resourceLimitStrings = {
|
||||
"monthly_active_user": _td("This homeserver has hit its Monthly Active User limit."),
|
||||
"hs_blocked": _td("This homeserver has been blocked by its administrator."),
|
||||
"": _td("This homeserver has exceeded one of its resource limits."),
|
||||
"monthly_active_user": _td("error|mau"),
|
||||
"hs_blocked": _td("error|hs_blocked"),
|
||||
"": _td("error|resource_limits"),
|
||||
};
|
||||
|
||||
export const adminContactStrings = {
|
||||
"": _td("Please <a>contact your service administrator</a> to continue using this service."),
|
||||
"": _td("error|admin_contact"),
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -67,7 +67,7 @@ export function messageForResourceLimitError(
|
|||
}
|
||||
};
|
||||
|
||||
if (errString.includes("<a>")) {
|
||||
if (lookupString(errString).includes("<a>")) {
|
||||
return _t(errString, {}, Object.assign({ a: linkSub }, extraTranslations));
|
||||
} else {
|
||||
return _t(errString, {}, extraTranslations!);
|
||||
|
@ -93,7 +93,7 @@ export function messageForSyncError(err: Error): ReactNode {
|
|||
</div>
|
||||
);
|
||||
} else {
|
||||
return <div>{_t("Unable to connect to Homeserver. Retrying…")}</div>;
|
||||
return <div>{_t("error|sync")}</div>;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -126,7 +126,7 @@ export function messageForLoginError(
|
|||
<div>
|
||||
<div>{_t("auth|incorrect_credentials")}</div>
|
||||
<div className="mx_Login_smallError">
|
||||
{_t("Please note you are logging into the %(hs)s server, not matrix.org.", {
|
||||
{_t("auth|incorrect_credentials_detail", {
|
||||
hs: serverConfig.hsName,
|
||||
})}
|
||||
</div>
|
||||
|
@ -144,7 +144,7 @@ export function messageForConnectionError(
|
|||
err: Error,
|
||||
serverConfig: Pick<ValidatedServerConfig, "hsName" | "hsUrl">,
|
||||
): ReactNode {
|
||||
let errorText = _t("There was a problem communicating with the homeserver, please try again later.");
|
||||
let errorText = _t("error|connection");
|
||||
|
||||
if (err instanceof ConnectionError) {
|
||||
if (
|
||||
|
@ -154,7 +154,7 @@ export function messageForConnectionError(
|
|||
return (
|
||||
<span>
|
||||
{_t(
|
||||
"Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or <a>enable unsafe scripts</a>.",
|
||||
"error|mixed_content",
|
||||
{},
|
||||
{
|
||||
a: (sub) => {
|
||||
|
@ -177,7 +177,7 @@ export function messageForConnectionError(
|
|||
return (
|
||||
<span>
|
||||
{_t(
|
||||
"Can't connect to homeserver - please check your connectivity, ensure your <a>homeserver's SSL certificate</a> is trusted, and that a browser extension is not blocking requests.",
|
||||
"error|tls",
|
||||
{},
|
||||
{
|
||||
a: (sub) => (
|
||||
|
|
|
@ -27,7 +27,7 @@ export function getNameForEventRoom(matrixClient: MatrixClient, userId: string,
|
|||
export function userLabelForEventRoom(matrixClient: MatrixClient, userId: string, roomId: string): string {
|
||||
const name = getNameForEventRoom(matrixClient, userId, roomId);
|
||||
if (name !== userId) {
|
||||
return _t("%(name)s (%(userId)s)", { name, userId });
|
||||
return _t("name_and_id", { name, userId });
|
||||
} else {
|
||||
return userId;
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ function friendlyError(message: string, friendlyText: string): { message: string
|
|||
}
|
||||
|
||||
function cryptoFailMsg(): string {
|
||||
return _t("Your browser does not support the required cryptography extensions");
|
||||
return _t("encryption|export_unsupported");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -53,17 +53,17 @@ export async function decryptMegolmKeyFile(data: ArrayBuffer, password: string):
|
|||
|
||||
// check we have a version byte
|
||||
if (body.length < 1) {
|
||||
throw friendlyError("Invalid file: too short", _t("Not a valid %(brand)s keyfile", { brand }));
|
||||
throw friendlyError("Invalid file: too short", _t("encryption|import_invalid_keyfile", { brand }));
|
||||
}
|
||||
|
||||
const version = body[0];
|
||||
if (version !== 1) {
|
||||
throw friendlyError("Unsupported version", _t("Not a valid %(brand)s keyfile", { brand }));
|
||||
throw friendlyError("Unsupported version", _t("encryption|import_invalid_keyfile", { brand }));
|
||||
}
|
||||
|
||||
const ciphertextLength = body.length - (1 + 16 + 16 + 4 + 32);
|
||||
if (ciphertextLength < 0) {
|
||||
throw friendlyError("Invalid file: too short", _t("Not a valid %(brand)s keyfile", { brand }));
|
||||
throw friendlyError("Invalid file: too short", _t("encryption|import_invalid_keyfile", { brand }));
|
||||
}
|
||||
|
||||
const salt = body.subarray(1, 1 + 16);
|
||||
|
@ -82,7 +82,7 @@ export async function decryptMegolmKeyFile(data: ArrayBuffer, password: string):
|
|||
throw friendlyError("subtleCrypto.verify failed: " + e, cryptoFailMsg());
|
||||
}
|
||||
if (!isValid) {
|
||||
throw friendlyError("hmac mismatch", _t("Authentication check failed: incorrect password?"));
|
||||
throw friendlyError("hmac mismatch", _t("encryption|import_invalid_passphrase"));
|
||||
}
|
||||
|
||||
let plaintext;
|
||||
|
|
|
@ -97,7 +97,7 @@ export default class MultiInviter {
|
|||
this.completionStates[addr] = InviteState.Error;
|
||||
this.errors[addr] = {
|
||||
errcode: "M_INVALID",
|
||||
errorText: _t("Unrecognised address"),
|
||||
errorText: _t("invite|invalid_address"),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -182,8 +182,8 @@ export default class MultiInviter {
|
|||
) {
|
||||
const { finished } = Modal.createDialog(ConfirmUserActionDialog, {
|
||||
member,
|
||||
action: _t("Unban"),
|
||||
title: _t("User cannot be invited until they are unbanned"),
|
||||
action: _t("action|unban"),
|
||||
title: _t("invite|unban_first_title"),
|
||||
});
|
||||
[proceed = false] = await finished;
|
||||
if (proceed) {
|
||||
|
@ -253,24 +253,24 @@ export default class MultiInviter {
|
|||
switch (err.errcode) {
|
||||
case "M_FORBIDDEN":
|
||||
if (isSpace) {
|
||||
errorText = _t("You do not have permission to invite people to this space.");
|
||||
errorText = _t("invite|error_permissions_space");
|
||||
} else {
|
||||
errorText = _t("You do not have permission to invite people to this room.");
|
||||
errorText = _t("invite|error_permissions_room");
|
||||
}
|
||||
fatal = true;
|
||||
break;
|
||||
case USER_ALREADY_INVITED:
|
||||
if (isSpace) {
|
||||
errorText = _t("User is already invited to the space");
|
||||
errorText = _t("invite|error_already_invited_space");
|
||||
} else {
|
||||
errorText = _t("User is already invited to the room");
|
||||
errorText = _t("invite|error_already_invited_room");
|
||||
}
|
||||
break;
|
||||
case USER_ALREADY_JOINED:
|
||||
if (isSpace) {
|
||||
errorText = _t("User is already in the space");
|
||||
errorText = _t("invite|error_already_joined_space");
|
||||
} else {
|
||||
errorText = _t("User is already in the room");
|
||||
errorText = _t("invite|error_already_joined_room");
|
||||
}
|
||||
break;
|
||||
case "M_LIMIT_EXCEEDED":
|
||||
|
@ -281,10 +281,10 @@ export default class MultiInviter {
|
|||
return;
|
||||
case "M_NOT_FOUND":
|
||||
case "M_USER_NOT_FOUND":
|
||||
errorText = _t("User does not exist");
|
||||
errorText = _t("invite|error_user_not_found");
|
||||
break;
|
||||
case "M_PROFILE_UNDISCLOSED":
|
||||
errorText = _t("User may or may not exist");
|
||||
errorText = _t("invite|error_profile_undisclosed");
|
||||
break;
|
||||
case "M_PROFILE_NOT_FOUND":
|
||||
if (!ignoreProfile) {
|
||||
|
@ -296,25 +296,23 @@ export default class MultiInviter {
|
|||
break;
|
||||
case "M_BAD_STATE":
|
||||
case USER_BANNED:
|
||||
errorText = _t("The user must be unbanned before they can be invited.");
|
||||
errorText = _t("invite|error_bad_state");
|
||||
break;
|
||||
case "M_UNSUPPORTED_ROOM_VERSION":
|
||||
if (isSpace) {
|
||||
errorText = _t("The user's homeserver does not support the version of the space.");
|
||||
errorText = _t("invite|error_version_unsupported_space");
|
||||
} else {
|
||||
errorText = _t("The user's homeserver does not support the version of the room.");
|
||||
errorText = _t("invite|error_version_unsupported_room");
|
||||
}
|
||||
break;
|
||||
case "ORG.MATRIX.JSSDK_MISSING_PARAM":
|
||||
if (getAddressType(address) === AddressType.Email) {
|
||||
errorText = _t(
|
||||
'Cannot invite user by email without an identity server. You can connect to one under "Settings".',
|
||||
);
|
||||
errorText = _t("cannot_invite_without_identity_server");
|
||||
}
|
||||
}
|
||||
|
||||
if (!errorText) {
|
||||
errorText = _t("Unknown server error");
|
||||
errorText = _t("invite|error_unknown");
|
||||
}
|
||||
|
||||
this.completionStates[address] = InviteState.Error;
|
||||
|
|
|
@ -99,8 +99,8 @@ export async function upgradeRoom(
|
|||
logger.error(e);
|
||||
|
||||
Modal.createDialog(ErrorDialog, {
|
||||
title: _t("Error upgrading room"),
|
||||
description: _t("Double check that your server supports the room version chosen and try again."),
|
||||
title: _t("room|upgrade_error_title"),
|
||||
description: _t("room|upgrade_error_description"),
|
||||
});
|
||||
throw e;
|
||||
}
|
||||
|
|
|
@ -527,7 +527,7 @@ export default class WidgetUtils {
|
|||
}
|
||||
|
||||
public static getWidgetName(app?: IWidget): string {
|
||||
return app?.name?.trim() || _t("Unknown App");
|
||||
return app?.name?.trim() || _t("widget|no_name");
|
||||
}
|
||||
|
||||
public static getWidgetDataTitle(app?: IWidget): string {
|
||||
|
|
|
@ -40,7 +40,7 @@ export function roomContextDetails(room: Room): RoomContextDetails | null {
|
|||
const space2Name = room.client.getRoom(secondParent)?.name;
|
||||
return {
|
||||
details: _t("%(space1Name)s and %(space2Name)s", { space1Name, space2Name }),
|
||||
ariaLabel: _t("In spaces %(space1Name)s and %(space2Name)s.", { space1Name, space2Name }),
|
||||
ariaLabel: _t("in_space1_and_space2", { space1Name, space2Name }),
|
||||
};
|
||||
} else if (parent) {
|
||||
const spaceName = room.client.getRoom(parent)?.name ?? "";
|
||||
|
@ -48,12 +48,12 @@ export function roomContextDetails(room: Room): RoomContextDetails | null {
|
|||
if (count > 0) {
|
||||
return {
|
||||
details: _t("%(spaceName)s and %(count)s others", { spaceName, count }),
|
||||
ariaLabel: _t("In %(spaceName)s and %(count)s other spaces.", { spaceName, count }),
|
||||
ariaLabel: _t("in_space_and_n_other_spaces", { spaceName, count }),
|
||||
};
|
||||
}
|
||||
return {
|
||||
details: spaceName,
|
||||
ariaLabel: _t("In %(spaceName)s.", { spaceName }),
|
||||
ariaLabel: _t("in_space", { spaceName }),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -100,7 +100,7 @@ export async function leaveRoomBehaviour(
|
|||
await matrixClient.leave(roomId);
|
||||
} catch (e) {
|
||||
if (e instanceof MatrixError) {
|
||||
const message = e.data.error || _t("Unexpected server error trying to leave the room");
|
||||
const message = e.data.error || _t("room|leave_unexpected_error");
|
||||
results[roomId] = Object.assign(new Error(message), { errcode: e.data.errcode, data: e.data });
|
||||
} else if (e instanceof Error) {
|
||||
results[roomId] = e;
|
||||
|
@ -129,14 +129,12 @@ export async function leaveRoomBehaviour(
|
|||
const messages: ReactNode[] = [];
|
||||
for (const roomErr of errors) {
|
||||
const err = roomErr[1] as MatrixError; // [0] is the roomId
|
||||
let message = _t("Unexpected server error trying to leave the room");
|
||||
let message = _t("room|leave_unexpected_error");
|
||||
if (err?.errcode && err.message) {
|
||||
if (err.errcode === "M_CANNOT_LEAVE_SERVER_NOTICE_ROOM") {
|
||||
Modal.createDialog(ErrorDialog, {
|
||||
title: _t("Can't leave Server Notices room"),
|
||||
description: _t(
|
||||
"This room is used for important messages from the Homeserver, so you cannot leave it.",
|
||||
),
|
||||
title: _t("room|leave_server_notices_title"),
|
||||
description: _t("room|leave_server_notices_description"),
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
@ -145,7 +143,7 @@ export async function leaveRoomBehaviour(
|
|||
messages.push(message, React.createElement("BR")); // createElement to avoid using a tsx file in utils
|
||||
}
|
||||
Modal.createDialog(ErrorDialog, {
|
||||
title: _t("Error leaving room"),
|
||||
title: _t("room|leave_error_title"),
|
||||
description: messages,
|
||||
});
|
||||
return;
|
||||
|
|
|
@ -47,8 +47,8 @@ export const requestMediaPermissions = async (video = true): Promise<MediaStream
|
|||
logger.log("Failed to list userMedia devices", error);
|
||||
const brand = SdkConfig.get().brand;
|
||||
Modal.createDialog(ErrorDialog, {
|
||||
title: _t("No media permissions"),
|
||||
description: _t("You may need to manually permit %(brand)s to access your microphone/webcam", { brand }),
|
||||
title: _t("voip|no_media_perms_title"),
|
||||
description: _t("voip|no_media_perms_description", { brand }),
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -92,10 +92,10 @@ export const shouldShowSpaceInvite = (space: Room): boolean =>
|
|||
export const showSpaceInvite = (space: Room, initialText = ""): void => {
|
||||
if (space.getJoinRule() === "public") {
|
||||
const modal = Modal.createDialog(InfoDialog, {
|
||||
title: _t("Invite to %(spaceName)s", { spaceName: space.name }),
|
||||
title: _t("invite|to_space", { spaceName: space.name }),
|
||||
description: (
|
||||
<React.Fragment>
|
||||
<span>{_t("Share your public space")}</span>
|
||||
<span>{_t("space|share_public")}</span>
|
||||
<SpacePublicShare space={space} onFinished={() => modal.close()} />
|
||||
</React.Fragment>
|
||||
),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue