Migrate more strings to translation keys (#11683)
This commit is contained in:
parent
632d8f4bc7
commit
41a2325a2a
86 changed files with 4744 additions and 4051 deletions
|
@ -172,7 +172,7 @@ export const CallEvent = forwardRef<any, CallEventProps>(({ mxEvent }, ref) => {
|
|||
<div className="mx_CallEvent_wrapper" ref={ref}>
|
||||
<div className="mx_CallEvent mx_CallEvent_inactive">
|
||||
<div className="mx_CallEvent_columns">
|
||||
<span className="mx_CallEvent_title">{_t("Video call ended")}</span>
|
||||
<span className="mx_CallEvent_title">{_t("timeline|m.call|video_call_ended")}</span>
|
||||
<CallDuration delta={latestEvent.getTs() - mxEvent.getTs()} />
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -170,17 +170,14 @@ export default class DateSeparator extends React.Component<IProps, IState> {
|
|||
let friendlyErrorMessage = "An error occured while trying to find and jump to the given date.";
|
||||
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.",
|
||||
);
|
||||
friendlyErrorMessage = _t("room|error_jump_to_date_connection");
|
||||
} 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.",
|
||||
{ dateString: formatFullDateNoDay(new Date(unixTimestamp)) },
|
||||
);
|
||||
friendlyErrorMessage = _t("room|error_jump_to_date_not_found", {
|
||||
dateString: formatFullDateNoDay(new Date(unixTimestamp)),
|
||||
});
|
||||
} else {
|
||||
friendlyErrorMessage = _t("Server returned %(statusCode)s with error code %(errorCode)s", {
|
||||
friendlyErrorMessage = _t("room|error_jump_to_date", {
|
||||
statusCode: err?.httpStatus || _t("unknown status code"),
|
||||
errorCode: err?.errcode || _t("unavailable"),
|
||||
});
|
||||
|
@ -192,7 +189,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.",
|
||||
"room|error_jump_to_date_send_logs_prompt",
|
||||
{},
|
||||
{
|
||||
debugLogsLink: (sub) => (
|
||||
|
@ -215,13 +212,13 @@ export default class DateSeparator extends React.Component<IProps, IState> {
|
|||
}
|
||||
|
||||
Modal.createDialog(ErrorDialog, {
|
||||
title: _t("Unable to find event at that date"),
|
||||
title: _t("room|error_jump_to_date_title"),
|
||||
description: (
|
||||
<div data-testid="jump-to-date-error-content">
|
||||
<p>{friendlyErrorMessage}</p>
|
||||
{submitDebugLogsContent}
|
||||
<details>
|
||||
<summary>{_t("Error details")}</summary>
|
||||
<summary>{_t("room|error_jump_to_date_details")}</summary>
|
||||
<p>{String(err)}</p>
|
||||
</details>
|
||||
</div>
|
||||
|
@ -285,7 +282,7 @@ export default class DateSeparator extends React.Component<IProps, IState> {
|
|||
data-testid="jump-to-date-last-month"
|
||||
/>
|
||||
<IconizedContextMenuOption
|
||||
label={_t("The beginning of the room")}
|
||||
label={_t("room|jump_to_date_beginning")}
|
||||
onClick={this.onTheBeginningClicked}
|
||||
data-testid="jump-to-date-beginning"
|
||||
/>
|
||||
|
@ -304,7 +301,7 @@ export default class DateSeparator extends React.Component<IProps, IState> {
|
|||
data-testid="jump-to-date-separator-button"
|
||||
onClick={this.onContextMenuOpenClick}
|
||||
isExpanded={!!this.state.contextMenuPosition}
|
||||
title={_t("Jump to date")}
|
||||
title={_t("room|jump_to_date")}
|
||||
>
|
||||
<h2 className="mx_DateSeparator_dateHeading" aria-hidden="true">
|
||||
{this.getLabel()}
|
||||
|
|
|
@ -22,7 +22,7 @@ import { IBodyProps } from "./IBodyProps";
|
|||
|
||||
function getErrorMessage(mxEvent?: MatrixEvent): string {
|
||||
return mxEvent?.isEncryptedDisabledForUnverifiedDevices
|
||||
? _t("The sender has blocked you from receiving this message")
|
||||
? _t("timeline|decryption_failure_blocked")
|
||||
: _t("threads|unable_to_decrypt");
|
||||
}
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ export default class DisambiguatedProfile extends React.Component<IProps> {
|
|||
if (member?.disambiguate) {
|
||||
mxidElement = <span className="mx_DisambiguatedProfile_mxid">{identifier}</span>;
|
||||
}
|
||||
title = _t("%(displayName)s (%(matrixId)s)", {
|
||||
title = _t("timeline|disambiguated_profile", {
|
||||
displayName: rawDisplayName,
|
||||
matrixId: identifier,
|
||||
});
|
||||
|
|
|
@ -48,7 +48,7 @@ export default class DownloadActionButton extends React.PureComponent<IProps, IS
|
|||
|
||||
this.state = {
|
||||
loading: false,
|
||||
tooltip: _td("Downloading"),
|
||||
tooltip: _td("timeline|download_action_downloading"),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -57,7 +57,7 @@ export default class DownloadActionButton extends React.PureComponent<IProps, IS
|
|||
if (this.state.loading || !mediaEventHelper) return;
|
||||
|
||||
if (mediaEventHelper.media.isEncrypted) {
|
||||
this.setState({ tooltip: _td("Decrypting") });
|
||||
this.setState({ tooltip: _td("timeline|download_action_decrypting") });
|
||||
}
|
||||
|
||||
this.setState({ loading: true });
|
||||
|
|
|
@ -49,19 +49,14 @@ const EncryptionEvent = forwardRef<HTMLDivElement, IProps>(({ mxEvent, timestamp
|
|||
const dmPartner = DMRoomMap.shared().getUserIdForRoomId(roomId);
|
||||
const room = cli?.getRoom(roomId);
|
||||
if (prevContent.algorithm === ALGORITHM) {
|
||||
subtitle = _t("Some encryption parameters have been changed.");
|
||||
subtitle = _t("timeline|m.room.encryption|parameters_changed");
|
||||
} 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.",
|
||||
{ displayName },
|
||||
);
|
||||
subtitle = _t("timeline|m.room.encryption|enabled_dm", { displayName });
|
||||
} else if (room && isLocalRoom(room)) {
|
||||
subtitle = _t("Messages in this chat will be end-to-end encrypted.");
|
||||
subtitle = _t("timeline|m.room.encryption|enabled_local");
|
||||
} 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.",
|
||||
);
|
||||
subtitle = _t("timeline|m.room.encryption|enabled");
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -79,7 +74,7 @@ const EncryptionEvent = forwardRef<HTMLDivElement, IProps>(({ mxEvent, timestamp
|
|||
<EventTileBubble
|
||||
className="mx_cryptoEvent mx_cryptoEvent_icon"
|
||||
title={_t("common|encryption_enabled")}
|
||||
subtitle={_t("Ignored attempt to disable encryption")}
|
||||
subtitle={_t("timeline|m.room.encryption|disable_attempt")}
|
||||
timestamp={timestamp}
|
||||
/>
|
||||
);
|
||||
|
@ -88,8 +83,8 @@ const EncryptionEvent = forwardRef<HTMLDivElement, IProps>(({ mxEvent, timestamp
|
|||
return (
|
||||
<EventTileBubble
|
||||
className="mx_cryptoEvent mx_cryptoEvent_icon mx_cryptoEvent_icon_warning"
|
||||
title={_t("Encryption not enabled")}
|
||||
subtitle={_t("The encryption used by this room isn't supported.")}
|
||||
title={_t("timeline|m.room.encryption|disabled")}
|
||||
subtitle={_t("timeline|m.room.encryption|unsupported")}
|
||||
ref={ref}
|
||||
timestamp={timestamp}
|
||||
/>
|
||||
|
|
|
@ -38,9 +38,9 @@ const HiddenBody = React.forwardRef<any, IProps | IBodyProps>(({ mxEvent }, ref)
|
|||
throw new Error("HiddenBody should only be applied to hidden messages");
|
||||
case false:
|
||||
if (visibility.reason) {
|
||||
text = _t("Message pending moderation: %(reason)s", { reason: visibility.reason });
|
||||
text = _t("timeline|pending_moderation_reason", { reason: visibility.reason });
|
||||
} else {
|
||||
text = _t("Message pending moderation");
|
||||
text = _t("timeline|pending_moderation");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ const JumpToDatePicker: React.FC<IProps> = ({ ts, onDatePicked }: IProps) => {
|
|||
|
||||
return (
|
||||
<form className="mx_JumpToDatePicker_form" onSubmit={onJumpToDateSubmit}>
|
||||
<span className="mx_JumpToDatePicker_label">{_t("Jump to date")}</span>
|
||||
<span className="mx_JumpToDatePicker_label">{_t("room|jump_to_date")}</span>
|
||||
<Field
|
||||
element="input"
|
||||
type="date"
|
||||
|
@ -51,7 +51,7 @@ const JumpToDatePicker: React.FC<IProps> = ({ ts, onDatePicked }: IProps) => {
|
|||
// events there anyway).
|
||||
max={formatDateForInput(new Date())}
|
||||
className="mx_JumpToDatePicker_datePicker"
|
||||
label={_t("Pick a date to jump to")}
|
||||
label={_t("room|jump_to_date_prompt")}
|
||||
onFocus={onFocus}
|
||||
inputRef={ref}
|
||||
tabIndex={isActive ? 0 : -1}
|
||||
|
|
|
@ -157,23 +157,23 @@ export default class LegacyCallEvent extends React.PureComponent<IProps, IState>
|
|||
if (gotRejected) {
|
||||
return (
|
||||
<div className="mx_LegacyCallEvent_content">
|
||||
{_t("Call declined")}
|
||||
{this.renderCallBackButton(_t("Call back"))}
|
||||
{_t("timeline|m.call.invite|declined")}
|
||||
{this.renderCallBackButton(_t("timeline|m.call.invite|call_back_prompt"))}
|
||||
{this.props.timestamp}
|
||||
</div>
|
||||
);
|
||||
} else if (hangupReason === CallErrorCode.AnsweredElsewhere) {
|
||||
return (
|
||||
<div className="mx_LegacyCallEvent_content">
|
||||
{_t("Answered elsewhere")}
|
||||
{_t("timeline|m.call.invite|answered_elsewhere")}
|
||||
{this.props.timestamp}
|
||||
</div>
|
||||
);
|
||||
} else if (this.props.callEventGrouper.callWasMissed) {
|
||||
return (
|
||||
<div className="mx_LegacyCallEvent_content">
|
||||
{_t("Missed call")}
|
||||
{this.renderCallBackButton(_t("Call back"))}
|
||||
{_t("timeline|m.call.invite|missed_call")}
|
||||
{this.renderCallBackButton(_t("timeline|m.call.invite|call_back_prompt"))}
|
||||
{this.props.timestamp}
|
||||
</div>
|
||||
);
|
||||
|
@ -198,8 +198,8 @@ export default class LegacyCallEvent extends React.PureComponent<IProps, IState>
|
|||
} else if (hangupReason === CallErrorCode.InviteTimeout) {
|
||||
return (
|
||||
<div className="mx_LegacyCallEvent_content">
|
||||
{_t("No answer")}
|
||||
{this.renderCallBackButton(_t("Call back"))}
|
||||
{_t("timeline|m.call.invite|no_answer")}
|
||||
{this.renderCallBackButton(_t("timeline|m.call.invite|call_back_prompt"))}
|
||||
{this.props.timestamp}
|
||||
</div>
|
||||
);
|
||||
|
@ -208,22 +208,22 @@ export default class LegacyCallEvent extends React.PureComponent<IProps, IState>
|
|||
let reason;
|
||||
if (hangupReason === CallErrorCode.IceFailed) {
|
||||
// We couldn't establish a connection at all
|
||||
reason = _t("Could not connect media");
|
||||
reason = _t("timeline|m.call.invite|failed_connect_media");
|
||||
} else if (hangupReason === "ice_timeout") {
|
||||
// We established a connection but it died
|
||||
reason = _t("Connection failed");
|
||||
reason = _t("timeline|m.call.invite|failed_connection");
|
||||
} else if (hangupReason === CallErrorCode.NoUserMedia) {
|
||||
// The other side couldn't open capture devices
|
||||
reason = _t("Their device couldn't start the camera or microphone");
|
||||
reason = _t("timeline|m.call.invite|failed_opponent_media");
|
||||
} else if (hangupReason === "unknown_error") {
|
||||
// An error code the other side doesn't have a way to express
|
||||
// (as opposed to an error code they gave but we don't know about,
|
||||
// in which case we show the error code)
|
||||
reason = _t("An unknown error occurred");
|
||||
reason = _t("timeline|m.call.invite|unknown_error");
|
||||
} else if (hangupReason === CallErrorCode.UserBusy) {
|
||||
reason = _t("voip|user_busy_description");
|
||||
} else {
|
||||
reason = _t("Unknown failure: %(reason)s", { reason: hangupReason });
|
||||
reason = _t("timeline|m.call.invite|unknown_failure", { reason: hangupReason });
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -233,7 +233,7 @@ export default class LegacyCallEvent extends React.PureComponent<IProps, IState>
|
|||
className="mx_LegacyCallEvent_content_tooltip"
|
||||
kind={InfoTooltipKind.Warning}
|
||||
/>
|
||||
{_t("Connection failed")}
|
||||
{_t("timeline|m.call.invite|failed_connection")}
|
||||
{this.renderCallBackButton(_t("action|retry"))}
|
||||
{this.props.timestamp}
|
||||
</div>
|
||||
|
@ -258,7 +258,7 @@ export default class LegacyCallEvent extends React.PureComponent<IProps, IState>
|
|||
|
||||
return (
|
||||
<div className="mx_LegacyCallEvent_content">
|
||||
{_t("The call is in an unknown state!")}
|
||||
{_t("timeline|m.call.invite|unknown_state")}
|
||||
{this.props.timestamp}
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -98,7 +98,7 @@ export default class MAudioBody extends React.PureComponent<IBodyProps, IState>
|
|||
if (this.state.error) {
|
||||
return (
|
||||
<MediaProcessingError className="mx_MAudioBody">
|
||||
{_t("Error processing audio message")}
|
||||
{_t("timeline|m.audio|error_processing_audio")}
|
||||
</MediaProcessingError>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -228,7 +228,7 @@ const MBeaconBody = React.forwardRef<HTMLDivElement, IBodyProps>(({ mxEvent, get
|
|||
className="mx_MBeaconBody_chin"
|
||||
beacon={beacon}
|
||||
displayStatus={displayStatus}
|
||||
label={_t("View live location")}
|
||||
label={_t("timeline|m.beacon_info|view_live_location")}
|
||||
withIcon
|
||||
/>
|
||||
)}
|
||||
|
|
|
@ -150,7 +150,7 @@ export default class MFileBody extends React.Component<IProps, IState> {
|
|||
imgSrc: DOWNLOAD_ICON_URL,
|
||||
imgStyle: null,
|
||||
style: computedStyle(this.dummyLink.current),
|
||||
textContent: _t("Download %(text)s", { text }),
|
||||
textContent: _t("timeline|m.file|download_label", { text }),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
@ -174,7 +174,7 @@ export default class MFileBody extends React.Component<IProps, IState> {
|
|||
logger.warn("Unable to decrypt attachment: ", err);
|
||||
Modal.createDialog(ErrorDialog, {
|
||||
title: _t("common|error"),
|
||||
description: _t("Error decrypting attachment"),
|
||||
description: _t("timeline|m.file|error_decrypting"),
|
||||
});
|
||||
}
|
||||
};
|
||||
|
@ -248,7 +248,7 @@ export default class MFileBody extends React.Component<IProps, IState> {
|
|||
{showDownloadLink && (
|
||||
<div className="mx_MFileBody_download">
|
||||
<AccessibleButton onClick={this.decryptFile}>
|
||||
{_t("Decrypt %(text)s", { text: this.linkText })}
|
||||
{_t("timeline|m.file|decrypt_label", { text: this.linkText })}
|
||||
</AccessibleButton>
|
||||
</div>
|
||||
)}
|
||||
|
@ -346,7 +346,7 @@ export default class MFileBody extends React.Component<IProps, IState> {
|
|||
<div className="mx_MFileBody_download">
|
||||
<a {...downloadProps}>
|
||||
<span className="mx_MFileBody_download_icon" />
|
||||
{_t("Download %(text)s", { text: this.linkText })}
|
||||
{_t("timeline|m.file|download_label", { text: this.linkText })}
|
||||
</a>
|
||||
{this.context.timelineRenderingType === TimelineRenderingType.File && (
|
||||
<div className="mx_MImageBody_size">
|
||||
|
@ -362,7 +362,7 @@ export default class MFileBody extends React.Component<IProps, IState> {
|
|||
return (
|
||||
<span className="mx_MFileBody">
|
||||
{placeholder}
|
||||
{_t("Invalid file%(extra)s", { extra: extra })}
|
||||
{_t("timeline|m.file|error_invalid", { extra: extra })}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -604,11 +604,11 @@ export default class MImageBody extends React.Component<IBodyProps, IState> {
|
|||
const content = this.props.mxEvent.getContent<ImageContent>();
|
||||
|
||||
if (this.state.error) {
|
||||
let errorText = _t("Unable to show image due to error");
|
||||
let errorText = _t("timeline|m.image|error");
|
||||
if (this.state.error instanceof DecryptError) {
|
||||
errorText = _t("Error decrypting image");
|
||||
errorText = _t("timeline|m.image|error_decrypting");
|
||||
} else if (this.state.error instanceof DownloadError) {
|
||||
errorText = _t("Error downloading image");
|
||||
errorText = _t("timeline|m.image|error_downloading");
|
||||
}
|
||||
|
||||
return <MediaProcessingError className="mx_MImageBody">{errorText}</MediaProcessingError>;
|
||||
|
@ -651,7 +651,7 @@ export class HiddenImagePlaceholder extends React.PureComponent<PlaceholderIProp
|
|||
<div className={className} style={{ maxWidth: `min(100%, ${maxWidth}px)` }}>
|
||||
<div className="mx_HiddenImagePlaceholder_button">
|
||||
<span className="mx_HiddenImagePlaceholder_eye" />
|
||||
<span>{_t("Show image")}</span>
|
||||
<span>{_t("timeline|m.image|show_image")}</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -42,9 +42,9 @@ export default class MJitsiWidgetEvent extends React.PureComponent<IProps> {
|
|||
const widgetId = this.props.mxEvent.getStateKey();
|
||||
const widget = WidgetStore.instance.getRoom(room.roomId, true).widgets.find((w) => w.id === widgetId);
|
||||
|
||||
let joinCopy: string | null = _t("Join the conference at the top of this room");
|
||||
let joinCopy: string | null = _t("timeline|m.widget|jitsi_join_top_prompt");
|
||||
if (widget && WidgetLayoutStore.instance.isInContainer(room, widget, Container.Right)) {
|
||||
joinCopy = _t("Join the conference from the room information card on the right");
|
||||
joinCopy = _t("timeline|m.widget|jitsi_join_right_prompt");
|
||||
} else if (!widget) {
|
||||
joinCopy = null;
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ export default class MJitsiWidgetEvent extends React.PureComponent<IProps> {
|
|||
return (
|
||||
<EventTileBubble
|
||||
className="mx_MJitsiWidgetEvent"
|
||||
title={_t("Video conference ended by %(senderName)s", { senderName })}
|
||||
title={_t("timeline|m.widget|jitsi_ended", { senderName })}
|
||||
timestamp={this.props.timestamp}
|
||||
/>
|
||||
);
|
||||
|
@ -63,7 +63,7 @@ export default class MJitsiWidgetEvent extends React.PureComponent<IProps> {
|
|||
return (
|
||||
<EventTileBubble
|
||||
className="mx_MJitsiWidgetEvent"
|
||||
title={_t("Video conference updated by %(senderName)s", { senderName })}
|
||||
title={_t("timeline|m.widget|jitsi_updated", { senderName })}
|
||||
subtitle={joinCopy}
|
||||
timestamp={this.props.timestamp}
|
||||
/>
|
||||
|
@ -73,7 +73,7 @@ export default class MJitsiWidgetEvent extends React.PureComponent<IProps> {
|
|||
return (
|
||||
<EventTileBubble
|
||||
className="mx_MJitsiWidgetEvent"
|
||||
title={_t("Video conference started by %(senderName)s", { senderName })}
|
||||
title={_t("timeline|m.widget|jitsi_started", { senderName })}
|
||||
subtitle={joinCopy}
|
||||
timestamp={this.props.timestamp}
|
||||
/>
|
||||
|
|
|
@ -109,17 +109,17 @@ export default class MKeyVerificationConclusion extends React.Component<IProps>
|
|||
let title: string | undefined;
|
||||
|
||||
if (request.phase === VerificationPhase.Done) {
|
||||
title = _t("You verified %(name)s", {
|
||||
title = _t("timeline|m.key.verification.done", {
|
||||
name: getNameForEventRoom(client, request.otherUserId, mxEvent.getRoomId()!),
|
||||
});
|
||||
} else if (request.phase === VerificationPhase.Cancelled) {
|
||||
const userId = request.cancellingUserId;
|
||||
if (userId === myUserId) {
|
||||
title = _t("You cancelled verifying %(name)s", {
|
||||
title = _t("timeline|m.key.verification.cancel|you_cancelled", {
|
||||
name: getNameForEventRoom(client, request.otherUserId, mxEvent.getRoomId()!),
|
||||
});
|
||||
} else if (userId) {
|
||||
title = _t("%(name)s cancelled verifying", {
|
||||
title = _t("timeline|m.key.verification.cancel|user_cancelled", {
|
||||
name: getNameForEventRoom(client, userId, mxEvent.getRoomId()!),
|
||||
});
|
||||
}
|
||||
|
|
|
@ -95,7 +95,7 @@ export default class MKeyVerificationRequest extends React.Component<IProps> {
|
|||
const client = MatrixClientPeg.safeGet();
|
||||
const myUserId = client.getUserId();
|
||||
if (userId === myUserId) {
|
||||
return _t("You accepted");
|
||||
return _t("timeline|m.key.verification.request|you_accepted");
|
||||
} else {
|
||||
return _t("%(name)s accepted", {
|
||||
name: getNameForEventRoom(client, userId, this.props.mxEvent.getRoomId()!),
|
||||
|
@ -110,9 +110,9 @@ export default class MKeyVerificationRequest extends React.Component<IProps> {
|
|||
const declined = cancellationCode === "m.user";
|
||||
if (userId === myUserId) {
|
||||
if (declined) {
|
||||
return _t("You declined");
|
||||
return _t("timeline|m.key.verification.request|you_declined");
|
||||
} else {
|
||||
return _t("You cancelled");
|
||||
return _t("timeline|m.key.verification.request|you_cancelled");
|
||||
}
|
||||
} else {
|
||||
if (declined) {
|
||||
|
@ -157,7 +157,7 @@ export default class MKeyVerificationRequest extends React.Component<IProps> {
|
|||
} else if (request.accepting) {
|
||||
stateLabel = _t("encryption|verification|accepting");
|
||||
} else if (request.declining) {
|
||||
stateLabel = _t("Declining…");
|
||||
stateLabel = _t("timeline|m.key.verification.request|declining");
|
||||
}
|
||||
stateNode = <div className="mx_cryptoEvent_state">{stateLabel}</div>;
|
||||
}
|
||||
|
@ -180,7 +180,7 @@ export default class MKeyVerificationRequest extends React.Component<IProps> {
|
|||
}
|
||||
} else {
|
||||
// request sent by us
|
||||
title = _t("You sent a verification request");
|
||||
title = _t("timeline|m.key.verification.request|you_started");
|
||||
subtitle = userLabelForEventRoom(client, request.otherUserId, mxEvent.getRoomId()!);
|
||||
}
|
||||
|
||||
|
|
|
@ -126,8 +126,8 @@ export function launchPollEditor(mxEvent: MatrixEvent, getRelationsForEvent?: Ge
|
|||
const room = MatrixClientPeg.safeGet().getRoom(mxEvent.getRoomId());
|
||||
if (pollAlreadyHasVotes(mxEvent, getRelationsForEvent)) {
|
||||
Modal.createDialog(ErrorDialog, {
|
||||
title: _t("Can't edit poll"),
|
||||
description: _t("Sorry, you can't edit a poll after votes have been cast."),
|
||||
title: _t("poll|unable_edit_title"),
|
||||
description: _t("poll|unable_edit_description"),
|
||||
});
|
||||
} else if (room) {
|
||||
Modal.createDialog(
|
||||
|
@ -229,8 +229,8 @@ export default class MPollBody extends React.Component<IBodyProps, IState> {
|
|||
console.error("Failed to submit poll response event:", e);
|
||||
|
||||
Modal.createDialog(ErrorDialog, {
|
||||
title: _t("Vote not registered"),
|
||||
description: _t("Sorry, your vote was not registered. Please try again."),
|
||||
title: _t("poll|error_voting_title"),
|
||||
description: _t("poll|error_voting_description"),
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -306,19 +306,19 @@ export default class MPollBody extends React.Component<IBodyProps, IState> {
|
|||
|
||||
let totalText: string;
|
||||
if (showResults && poll.undecryptableRelationsCount) {
|
||||
totalText = _t("Due to decryption errors, some votes may not be counted");
|
||||
totalText = _t("poll|total_decryption_errors");
|
||||
} else if (poll.isEnded) {
|
||||
totalText = _t("Final result based on %(count)s votes", { count: totalVotes });
|
||||
totalText = _t("right_panel|poll|final_result", { count: totalVotes });
|
||||
} else if (!disclosed) {
|
||||
totalText = _t("Results will be visible when the poll is ended");
|
||||
totalText = _t("poll|total_not_ended");
|
||||
} else if (myVote === undefined) {
|
||||
if (totalVotes === 0) {
|
||||
totalText = _t("No votes cast");
|
||||
totalText = _t("poll|total_no_votes");
|
||||
} else {
|
||||
totalText = _t("%(count)s votes cast. Vote to see the results", { count: totalVotes });
|
||||
totalText = _t("poll|total_n_votes", { count: totalVotes });
|
||||
}
|
||||
} else {
|
||||
totalText = _t("Based on %(count)s votes", { count: totalVotes });
|
||||
totalText = _t("poll|total_n_votes_voted", { count: totalVotes });
|
||||
}
|
||||
|
||||
const editedSpan = this.props.mxEvent.replacingEvent() ? (
|
||||
|
|
|
@ -109,7 +109,7 @@ export const MPollEndBody = React.forwardRef<any, IBodyProps>(({ mxEvent, ...pro
|
|||
|
||||
return (
|
||||
<div ref={ref}>
|
||||
<Caption>{_t("Ended a poll")}</Caption>
|
||||
<Caption>{_t("timeline|m.poll.end|ended")}</Caption>
|
||||
<MPollBody mxEvent={pollStartEvent} {...props} />
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -250,7 +250,9 @@ export default class MVideoBody extends React.PureComponent<IBodyProps, IState>
|
|||
|
||||
if (this.state.error !== null) {
|
||||
return (
|
||||
<MediaProcessingError className="mx_MVideoBody">{_t("Error decrypting video")}</MediaProcessingError>
|
||||
<MediaProcessingError className="mx_MVideoBody">
|
||||
{_t("timeline|m.video|error_decrypting")}
|
||||
</MediaProcessingError>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ export default class MVoiceMessageBody extends MAudioBody {
|
|||
if (this.state.error) {
|
||||
return (
|
||||
<MediaProcessingError className="mx_MVoiceMessageBody">
|
||||
{_t("Error processing voice message")}
|
||||
{_t("timeline|m.audio|error_processing_voice_message")}
|
||||
</MediaProcessingError>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -237,16 +237,12 @@ const ReplyInThreadButton: React.FC<IReplyInThreadButton> = ({ mxEvent }) => {
|
|||
<>
|
||||
<div className="mx_Tooltip_title">
|
||||
{!hasARelation
|
||||
? _t("Reply in thread")
|
||||
: _t("Can't create a thread from an event with an existing relation")}
|
||||
? _t("action|reply_in_thread")
|
||||
: _t("threads|error_start_thread_existing_relation")}
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
title={
|
||||
!hasARelation
|
||||
? _t("Reply in thread")
|
||||
: _t("Can't create a thread from an event with an existing relation")
|
||||
}
|
||||
title={!hasARelation ? _t("action|reply_in_thread") : _t("threads|error_start_thread_existing_relation")}
|
||||
onClick={onClick}
|
||||
onContextMenu={onClick}
|
||||
>
|
||||
|
@ -515,15 +511,23 @@ export default class MessageActionBar extends React.PureComponent<IMessageAction
|
|||
const tooltip = (
|
||||
<>
|
||||
<div className="mx_Tooltip_title">
|
||||
{this.props.isQuoteExpanded ? _t("Collapse quotes") : _t("Expand quotes")}
|
||||
{this.props.isQuoteExpanded
|
||||
? _t("timeline|mab|collapse_reply_chain")
|
||||
: _t("timeline|mab|expand_reply_chain")}
|
||||
</div>
|
||||
<div className="mx_Tooltip_sub">
|
||||
{_t(ALTERNATE_KEY_NAME[Key.SHIFT]) + " + " + _t("action|click")}
|
||||
</div>
|
||||
<div className="mx_Tooltip_sub">{_t(ALTERNATE_KEY_NAME[Key.SHIFT]) + " + " + _t("Click")}</div>
|
||||
</>
|
||||
);
|
||||
toolbarOpts.push(
|
||||
<RovingAccessibleTooltipButton
|
||||
className={expandClassName}
|
||||
title={this.props.isQuoteExpanded ? _t("Collapse quotes") : _t("Expand quotes")}
|
||||
title={
|
||||
this.props.isQuoteExpanded
|
||||
? _t("timeline|mab|collapse_reply_chain")
|
||||
: _t("timeline|mab|expand_reply_chain")
|
||||
}
|
||||
tooltip={tooltip}
|
||||
onClick={this.props.toggleThreadExpanded}
|
||||
key="expand"
|
||||
|
|
|
@ -35,7 +35,7 @@ export default class MjolnirBody extends React.Component<IBodyProps> {
|
|||
<div className="mx_MjolnirBody">
|
||||
<i>
|
||||
{_t(
|
||||
"You have ignored this user, so their message is hidden. <a>Show anyways.</a>",
|
||||
"timeline|mjolnir|message_hidden",
|
||||
{},
|
||||
{
|
||||
a: (sub) => (
|
||||
|
|
|
@ -555,9 +555,9 @@ export default class TextualBody extends React.Component<IBodyProps, IState> {
|
|||
throw new Error("renderPendingModerationMarker should only be applied to hidden messages");
|
||||
case false:
|
||||
if (visibility.reason) {
|
||||
text = _t("Message pending moderation: %(reason)s", { reason: visibility.reason });
|
||||
text = _t("timeline|pending_moderation_reason", { reason: visibility.reason });
|
||||
} else {
|
||||
text = _t("Message pending moderation");
|
||||
text = _t("timeline|pending_moderation");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue