Merge branch 'develop' of github.com:matrix-org/matrix-react-sdk into t3chguy/cr/72

# Conflicts:
#	test/components/views/rooms/__snapshots__/RoomHeader-test.tsx.snap
This commit is contained in:
Michael Telatynski 2023-09-14 11:33:22 +01:00
commit e301fe474b
No known key found for this signature in database
GPG key ID: A2B008A5F49F5D0D
104 changed files with 7047 additions and 6250 deletions

View file

@ -74,8 +74,8 @@ const UserWelcomeTop: React.FC = () => {
<div>
<MiniAvatarUploader
hasAvatar={!!ownProfile.avatarUrl}
hasAvatarLabel={_tDom("Great, that'll help people know it's you")}
noAvatarLabel={_tDom("Add a photo so people know it's you.")}
hasAvatarLabel={_tDom("onboarding|has_avatar_label")}
noAvatarLabel={_tDom("onboarding|no_avatar_label")}
setAvatarUrl={(url) => cli.setAvatarUrl(url)}
isUserAvatar
onClick={(ev) => PosthogTrackers.trackInteraction("WebHomeMiniAvatarUploadButton", ev)}
@ -88,8 +88,8 @@ const UserWelcomeTop: React.FC = () => {
/>
</MiniAvatarUploader>
<h1>{_tDom("Welcome %(name)s", { name: ownProfile.displayName })}</h1>
<h2>{_tDom("Now, let's help you get started")}</h2>
<h1>{_tDom("onboarding|welcome_user", { name: ownProfile.displayName })}</h1>
<h2>{_tDom("onboarding|welcome_detail")}</h2>
</div>
);
};
@ -113,8 +113,8 @@ const HomePage: React.FC<IProps> = ({ justRegistered = false }) => {
introSection = (
<React.Fragment>
<img src={logoUrl} alt={config.brand} />
<h1>{_tDom("Welcome to %(appName)s", { appName: config.brand })}</h1>
<h2>{_tDom("Own your conversations.")}</h2>
<h1>{_tDom("onboarding|intro_welcome", { appName: config.brand })}</h1>
<h2>{_tDom("onboarding|intro_byline")}</h2>
</React.Fragment>
);
}
@ -125,13 +125,13 @@ const HomePage: React.FC<IProps> = ({ justRegistered = false }) => {
{introSection}
<div className="mx_HomePage_default_buttons">
<AccessibleButton onClick={onClickSendDm} className="mx_HomePage_button_sendDm">
{_tDom("Send a Direct Message")}
{_tDom("onboarding|send_dm")}
</AccessibleButton>
<AccessibleButton onClick={onClickExplore} className="mx_HomePage_button_explore">
{_tDom("Explore Public Rooms")}
{_tDom("onboarding|explore_rooms")}
</AccessibleButton>
<AccessibleButton onClick={onClickNewRoom} className="mx_HomePage_button_createGroup">
{_tDom("Create a Group Chat")}
{_tDom("onboarding|create_room")}
</AccessibleButton>
</div>
</div>

View file

@ -245,7 +245,6 @@ export interface IRoomState {
canAskToJoin: boolean;
promptAskToJoin: boolean;
knocked: boolean;
}
interface LocalRoomViewProps {
@ -458,7 +457,6 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
msc3946ProcessDynamicPredecessor: SettingsStore.getValue("feature_dynamic_room_predecessors"),
canAskToJoin: this.askToJoinEnabled,
promptAskToJoin: false,
knocked: false,
};
this.dispatcherRef = dis.register(this.onAction);
@ -664,7 +662,6 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
: false,
activeCall: roomId ? CallStore.instance.getActiveCall(roomId) : null,
promptAskToJoin: this.context.roomViewStore.promptAskToJoin(),
knocked: this.context.roomViewStore.knocked(),
};
if (
@ -1787,12 +1784,13 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
};
private onSearchClick = (): void => {
this.setState({
timelineRenderingType:
this.state.timelineRenderingType === TimelineRenderingType.Search
? TimelineRenderingType.Room
: TimelineRenderingType.Search,
});
if (this.state.timelineRenderingType === TimelineRenderingType.Search) {
this.onCancelSearchClick();
} else {
this.setState({
timelineRenderingType: TimelineRenderingType.Search,
});
}
};
private onCancelSearchClick = (): Promise<void> => {
@ -2118,7 +2116,6 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
signUrl={this.props.threepidInvite?.signUrl}
roomId={this.state.roomId}
promptAskToJoin={this.state.promptAskToJoin}
knocked={this.state.knocked}
onSubmitAskToJoin={this.onSubmitAskToJoin}
onCancelAskToJoin={this.onCancelAskToJoin}
/>
@ -2202,7 +2199,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
<RoomPreviewBar
room={this.state.room}
promptAskToJoin={myMembership === "leave" || this.state.promptAskToJoin}
knocked={myMembership === "knock" || this.state.knocked}
knocked={myMembership === "knock"}
onSubmitAskToJoin={this.onSubmitAskToJoin}
onCancelAskToJoin={this.onCancelAskToJoin}
onForgetClick={this.onForgetClick}

View file

@ -384,12 +384,12 @@ export default class ForgotPassword extends React.Component<Props, State> {
public renderSetPassword(): JSX.Element {
const submitButtonChild =
this.state.phase === Phase.ResettingPassword ? <Spinner w={16} h={16} /> : _t("Reset password");
this.state.phase === Phase.ResettingPassword ? <Spinner w={16} h={16} /> : _t("auth|reset_password_action");
return (
<>
<LockIcon className="mx_AuthBody_lockIcon" />
<h1>{_t("Reset your password")}</h1>
<h1>{_t("auth|reset_password_title")}</h1>
<form onSubmit={this.onSubmitForm}>
<fieldset disabled={this.state.phase === Phase.ResettingPassword}>
<div className="mx_AuthBody_fieldRow">

View file

@ -523,7 +523,7 @@ export default class Registration extends React.Component<IProps, IState> {
// i18n: ssoButtons is a placeholder to help translators understand context
continueWithSection = (
<h2 className="mx_AuthBody_centered">
{_t("Continue with %(ssoButtons)s", { ssoButtons: "" }).trim()}
{_t("auth|continue_with_sso", { ssoButtons: "" }).trim()}
</h2>
);
}
@ -540,7 +540,7 @@ export default class Registration extends React.Component<IProps, IState> {
action={SSOAction.REGISTER}
/>
<h2 className="mx_AuthBody_centered">
{_t("%(ssoButtons)s Or %(usernamePassword)s", {
{_t("auth|sso_or_username_password", {
ssoButtons: "",
usernamePassword: "",
}).trim()}
@ -591,7 +591,7 @@ export default class Registration extends React.Component<IProps, IState> {
const signIn = (
<span className="mx_AuthBody_changeFlow">
{_t(
"Already have an account? <a>Sign in here</a>",
"auth|sign_in_instead",
{},
{
a: (sub) => (
@ -621,13 +621,10 @@ export default class Registration extends React.Component<IProps, IState> {
regDoneText = (
<div>
<p>
{_t(
"Your new account (%(newAccountId)s) is registered, but you're already logged into a different account (%(loggedInUserId)s).",
{
newAccountId: this.state.registeredUsername,
loggedInUserId: this.state.differentLoggedInUserId,
},
)}
{_t("auth|account_clash", {
newAccountId: this.state.registeredUsername,
loggedInUserId: this.state.differentLoggedInUserId,
})}
</p>
<p>
<AccessibleButton
@ -639,7 +636,7 @@ export default class Registration extends React.Component<IProps, IState> {
}
}}
>
{_t("Continue with previous account")}
{_t("auth|account_clash_previous_account")}
</AccessibleButton>
</p>
</div>
@ -650,7 +647,7 @@ export default class Registration extends React.Component<IProps, IState> {
regDoneText = (
<h2>
{_t(
"<a>Log in</a> to your new account.",
"auth|log_in_new_account",
{},
{
a: (sub) => (
@ -673,7 +670,7 @@ export default class Registration extends React.Component<IProps, IState> {
}
body = (
<div>
<h1>{_t("Registration Successful")}</h1>
<h1>{_t("auth|registration_successful")}</h1>
{regDoneText}
</div>
);
@ -685,8 +682,8 @@ export default class Registration extends React.Component<IProps, IState> {
title={_t("Create account")}
serverPicker={
<ServerPicker
title={_t("Host account on")}
dialogTitle={_t("Decide where your account is hosted")}
title={_t("auth|server_picker_title")}
dialogTitle={_t("auth|server_picker_dialog_title")}
serverConfig={this.props.serverConfig}
onServerConfigChange={
this.state.doingUIAuth ? undefined : this.props.onServerConfigChange

View file

@ -287,7 +287,7 @@ export default class SoftLogout extends React.Component<IProps, IState> {
<p>{_t("Sign in and regain access to your account.")}</p>
{this.renderSsoForm(null)}
<h2 className="mx_AuthBody_centered">
{_t("%(ssoButtons)s Or %(usernamePassword)s", {
{_t("auth|sso_or_username_password", {
ssoButtons: "",
usernamePassword: "",
}).trim()}

View file

@ -874,7 +874,7 @@ export class SSOAuthEntry extends React.Component<ISSOAuthEntryProps, ISSOAuthEn
if (this.state.phase === SSOAuthEntry.PHASE_PREAUTH) {
continueButton = (
<AccessibleButton onClick={this.onStartAuthClick} kind={this.props.continueKind || "primary"}>
{this.props.continueText || _t("Single Sign On")}
{this.props.continueText || _t("auth|sso")}
</AccessibleButton>
);
} else {

View file

@ -45,8 +45,8 @@ interface IBetaPillProps {
export const BetaPill: React.FC<IBetaPillProps> = ({
onClick,
tooltipTitle = _t("This is a beta feature"),
tooltipCaption = _t("Click for more info"),
tooltipTitle = _t("labs|beta_feature"),
tooltipCaption = _t("labs|click_for_info"),
}) => {
if (onClick) {
return (
@ -94,18 +94,16 @@ const BetaCard: React.FC<IProps> = ({ title: titleOverride, featureId }) => {
let refreshWarning: string | undefined;
if (requiresRefresh) {
const brand = SdkConfig.get().brand;
refreshWarning = value
? _t("Leaving the beta will reload %(brand)s.", { brand })
: _t("Joining the beta will reload %(brand)s.", { brand });
refreshWarning = value ? _t("labs|leave_beta_reload", { brand }) : _t("labs|join_beta_reload", { brand });
}
let content: ReactNode;
if (busy) {
content = <InlineSpinner />;
} else if (value) {
content = _t("Leave the beta");
content = _t("labs|leave_beta");
} else {
content = _t("Join the beta");
content = _t("labs|join_beta");
}
return (

View file

@ -47,14 +47,14 @@ export const AppDownloadDialog: FC<Props> = ({ onFinished }) => {
return (
<BaseDialog
title={_t("Download %(brand)s", { brand })}
title={_t("onboarding|download_brand", { brand })}
className="mx_AppDownloadDialog"
fixedWidth
onFinished={onFinished}
>
{desktopBuilds?.get("available") && (
<div className="mx_AppDownloadDialog_desktop">
<Heading size="3">{_t("Download %(brand)s Desktop", { brand })}</Heading>
<Heading size="3">{_t("onboarding|download_brand_desktop", { brand })}</Heading>
<AccessibleButton
kind="primary"
element="a"
@ -62,7 +62,7 @@ export const AppDownloadDialog: FC<Props> = ({ onFinished }) => {
target="_blank"
onClick={() => {}}
>
{_t("Download %(brand)s Desktop", { brand })}
{_t("onboarding|download_brand_desktop", { brand })}
</AccessibleButton>
</div>
)}
@ -71,7 +71,7 @@ export const AppDownloadDialog: FC<Props> = ({ onFinished }) => {
<Heading size="3">{_t("common|ios")}</Heading>
<QRCode data={urlAppStore} margin={0} width={172} />
<div className="mx_AppDownloadDialog_info">
{_t("%(qrCode)s or %(appLinks)s", {
{_t("onboarding|qr_or_app_links", {
appLinks: "",
qrCode: "",
})}
@ -81,7 +81,7 @@ export const AppDownloadDialog: FC<Props> = ({ onFinished }) => {
element="a"
href={urlAppStore}
target="_blank"
aria-label={_t("Download on the App Store")}
aria-label={_t("onboarding|download_app_store")}
onClick={() => {}}
>
<IOSBadge />
@ -92,7 +92,7 @@ export const AppDownloadDialog: FC<Props> = ({ onFinished }) => {
<Heading size="3">{_t("common|android")}</Heading>
<QRCode data={urlAndroid} margin={0} width={172} />
<div className="mx_AppDownloadDialog_info">
{_t("%(qrCode)s or %(appLinks)s", {
{_t("onboarding|qr_or_app_links", {
appLinks: "",
qrCode: "",
})}
@ -102,7 +102,7 @@ export const AppDownloadDialog: FC<Props> = ({ onFinished }) => {
element="a"
href={urlGooglePlay}
target="_blank"
aria-label={_t("Get it on Google Play")}
aria-label={_t("onboarding|download_google_play")}
onClick={() => {}}
>
<GooglePlayBadge />
@ -111,7 +111,7 @@ export const AppDownloadDialog: FC<Props> = ({ onFinished }) => {
element="a"
href={urlFDroid}
target="_blank"
aria-label={_t("Get it on F-Droid")}
aria-label={_t("onboarding|download_f_droid")}
onClick={() => {}}
>
<FDroidBadge />
@ -120,8 +120,8 @@ export const AppDownloadDialog: FC<Props> = ({ onFinished }) => {
</div>
</div>
<div className="mx_AppDownloadDialog_legal">
<p>{_t("App Store® and the Apple logo® are trademarks of Apple Inc.")}</p>
<p>{_t("Google Play and the Google Play logo are trademarks of Google LLC.")}</p>
<p>{_t("onboarding|apple_trademarks")}</p>
<p>{_t("onboarding|google_trademarks")}</p>
</div>
</BaseDialog>
);

View file

@ -74,7 +74,7 @@ export default class DeactivateAccountDialog extends React.Component<IProps, ISt
const dialogAesthetics = {
[SSOAuthEntry.PHASE_PREAUTH]: {
body: _t("Confirm your account deactivation by using Single Sign On to prove your identity."),
continueText: _t("Single Sign On"),
continueText: _t("auth|sso"),
continueKind: "danger",
},
[SSOAuthEntry.PHASE_POSTAUTH]: {

View file

@ -106,7 +106,7 @@ const ExportDialog: React.FC<IProps> = ({ room, onFinished }) => {
const [isExporting, setExporting] = useState(false);
const sizeLimitRef = useRef<Field>(null);
const messageCountRef = useRef<Field>(null);
const [exportProgressText, setExportProgressText] = useState(_t("Processing…"));
const [exportProgressText, setExportProgressText] = useState(_t("export_chat|processing"));
const [displayCancel, setCancelWarning] = useState(false);
const [exportCancelled, setExportCancelled] = useState(false);
const [exportSuccessful, setExportSuccessful] = useState(false);
@ -173,7 +173,7 @@ const ExportDialog: React.FC<IProps> = ({ room, onFinished }) => {
invalid: () => {
const min = 1;
const max = 2000;
return _t("Enter a number between %(min)s and %(max)s", {
return _t("export_chat|enter_number_between_min_max", {
min,
max,
});
@ -188,7 +188,7 @@ const ExportDialog: React.FC<IProps> = ({ room, onFinished }) => {
invalid: () => {
const min = 1;
const max = 2000;
return _t("Size can only be a number between %(min)s MB and %(max)s MB", { min, max });
return _t("export_chat|size_limit_min_max", { min, max });
},
},
],
@ -209,7 +209,7 @@ const ExportDialog: React.FC<IProps> = ({ room, onFinished }) => {
invalid: () => {
const min = 1;
const max = 10 ** 8;
return _t("Enter a number between %(min)s and %(max)s", {
return _t("export_chat|enter_number_between_min_max", {
min,
max,
});
@ -224,7 +224,7 @@ const ExportDialog: React.FC<IProps> = ({ room, onFinished }) => {
invalid: () => {
const min = 1;
const max = 10 ** 8;
return _t("Number of messages can only be a number between %(min)s and %(max)s", { min, max });
return _t("export_chat|num_messages_min_max", { min, max });
},
},
],
@ -270,7 +270,7 @@ const ExportDialog: React.FC<IProps> = ({ room, onFinished }) => {
value={numberOfMessages.toString()}
ref={messageCountRef}
onValidate={onValidateNumberOfMessages}
label={_t("Number of messages")}
label={_t("export_chat|num_messages")}
onChange={(e) => {
setNumberOfMessages(parseInt(e.target.value));
}}
@ -284,8 +284,8 @@ const ExportDialog: React.FC<IProps> = ({ room, onFinished }) => {
// Display successful cancellation message
return (
<InfoDialog
title={_t("Export Cancelled")}
description={_t("The export was cancelled successfully")}
title={_t("export_chat|cancelled")}
description={_t("export_chat|cancelled_detail")}
hasCloseButton={true}
onFinished={onFinished}
/>
@ -294,8 +294,8 @@ const ExportDialog: React.FC<IProps> = ({ room, onFinished }) => {
// Display successful export message
return (
<InfoDialog
title={_t("Export Successful")}
description={_t("Your export was successful. Find it in your Downloads folder.")}
title={_t("export_chat|successful")}
description={_t("export_chat|successful_detail")}
hasCloseButton={true}
onFinished={onFinished}
/>
@ -310,7 +310,7 @@ const ExportDialog: React.FC<IProps> = ({ room, onFinished }) => {
onFinished={onFinished}
fixedWidth={true}
>
<p>{_t("Are you sure you want to stop exporting your data? If you do, you'll need to start over.")}</p>
<p>{_t("export_chat|confirm_stop")}</p>
<DialogButtons
primaryButton={_t("action|stop")}
primaryButtonClass="danger"
@ -325,19 +325,19 @@ const ExportDialog: React.FC<IProps> = ({ room, onFinished }) => {
// Display export settings
return (
<BaseDialog
title={isExporting ? _t("Exporting your data") : _t("Export Chat")}
title={isExporting ? _t("export_chat|exporting_your_data") : _t("export_chat|title")}
className={`mx_ExportDialog ${isExporting && "mx_ExportDialog_Exporting"}`}
contentId="mx_Dialog_content"
hasCancel={true}
onFinished={onFinished}
fixedWidth={true}
>
{!isExporting ? <p>{_t("Select from the options below to export chats from your timeline")}</p> : null}
{!isExporting ? <p>{_t("export_chat|select_option")}</p> : null}
<div className="mx_ExportDialog_options">
{!!setExportFormat && (
<>
<span className="mx_ExportDialog_subheading">{_t("Format")}</span>
<span className="mx_ExportDialog_subheading">{_t("export_chat|format")}</span>
<StyledRadioGroup
name="exportFormat"
@ -350,7 +350,7 @@ const ExportDialog: React.FC<IProps> = ({ room, onFinished }) => {
{!!setExportType && (
<>
<span className="mx_ExportDialog_subheading">{_t("Messages")}</span>
<span className="mx_ExportDialog_subheading">{_t("export_chat|messages")}</span>
<Field
id="export-type"
@ -368,7 +368,7 @@ const ExportDialog: React.FC<IProps> = ({ room, onFinished }) => {
{setSizeLimit && (
<>
<span className="mx_ExportDialog_subheading">{_t("Size Limit")}</span>
<span className="mx_ExportDialog_subheading">{_t("export_chat|size_limit")}</span>
<Field
id="size-limit"
@ -392,7 +392,7 @@ const ExportDialog: React.FC<IProps> = ({ room, onFinished }) => {
checked={includeAttachments}
onChange={(e) => setAttachments((e.target as HTMLInputElement).checked)}
>
{_t("Include Attachments")}
{_t("export_chat|include_attachments")}
</StyledCheckbox>
</>
)}

View file

@ -99,7 +99,7 @@ export default class InteractiveAuthDialog<T> extends React.Component<Interactiv
[SSOAuthEntry.PHASE_PREAUTH]: {
title: _t("Use Single Sign On to continue"),
body: _t("To continue, use Single Sign On to prove your identity."),
continueText: _t("Single Sign On"),
continueText: _t("auth|sso"),
continueKind: "primary",
},
[SSOAuthEntry.PHASE_POSTAUTH]: {

View file

@ -216,7 +216,7 @@ export default class ReportEventDialog extends React.Component<IProps, IState> {
((this.state.nature == Nature.Other || this.state.nature == NonStandardValue.Admin) && !reason)
) {
this.setState({
err: _t("Please fill why you're reporting."),
err: _t("report_content|missing_reason"),
});
return;
}
@ -225,7 +225,7 @@ export default class ReportEventDialog extends React.Component<IProps, IState> {
// We need a `reason`.
if (!reason) {
this.setState({
err: _t("Please fill why you're reporting."),
err: _t("report_content|missing_reason"),
});
return;
}
@ -295,8 +295,8 @@ export default class ReportEventDialog extends React.Component<IProps, IState> {
const ignoreUserCheckbox = (
<LabelledCheckbox
value={this.state.ignoreUserToo}
label={_t("Ignore user")}
byline={_t("Check if you want to hide all current and future messages from this user.")}
label={_t("report_content|ignore_user")}
byline={_t("report_content|hide_messages_from_user")}
onChange={this.onIgnoreUserTooChanged}
disabled={this.state.busy}
/>
@ -317,7 +317,7 @@ 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.\nThis will be reported to the room moderators.");
subtitle = _t("report_content|nature_disagreement");
break;
case Nature.Toxic:
subtitle = _t(
@ -353,7 +353,7 @@ export default class ReportEventDialog extends React.Component<IProps, IState> {
);
break;
default:
subtitle = _t("Please pick a nature and describe what makes this message abusive.");
subtitle = _t("report_content|nature");
break;
}
@ -371,7 +371,7 @@ export default class ReportEventDialog extends React.Component<IProps, IState> {
checked={this.state.nature == Nature.Disagreement}
onChange={this.onNatureChosen}
>
{_t("Disagree")}
{_t("report_content|disagree")}
</StyledRadioButton>
<StyledRadioButton
name="nature"
@ -379,7 +379,7 @@ export default class ReportEventDialog extends React.Component<IProps, IState> {
checked={this.state.nature == Nature.Toxic}
onChange={this.onNatureChosen}
>
{_t("Toxic Behaviour")}
{_t("report_content|toxic_behaviour")}
</StyledRadioButton>
<StyledRadioButton
name="nature"
@ -387,7 +387,7 @@ export default class ReportEventDialog extends React.Component<IProps, IState> {
checked={this.state.nature == Nature.Illegal}
onChange={this.onNatureChosen}
>
{_t("Illegal Content")}
{_t("report_content|illegal_content")}
</StyledRadioButton>
<StyledRadioButton
name="nature"
@ -395,7 +395,7 @@ export default class ReportEventDialog extends React.Component<IProps, IState> {
checked={this.state.nature == Nature.Spam}
onChange={this.onNatureChosen}
>
{_t("Spam or propaganda")}
{_t("report_content|spam_or_propaganda")}
</StyledRadioButton>
<StyledRadioButton
name="nature"
@ -403,7 +403,7 @@ export default class ReportEventDialog extends React.Component<IProps, IState> {
checked={this.state.nature == NonStandardValue.Admin}
onChange={this.onNatureChosen}
>
{_t("Report the entire room")}
{_t("report_content|report_entire_room")}
</StyledRadioButton>
<StyledRadioButton
name="nature"
@ -443,7 +443,7 @@ export default class ReportEventDialog extends React.Component<IProps, IState> {
<BaseDialog
className="mx_ReportEventDialog"
onFinished={this.props.onFinished}
title={_t("Report Content to Your Homeserver Administrator")}
title={_t("report_content|report_content_to_homeserver")}
contentId="mx_ReportEventDialog"
>
<div className="mx_ReportEventDialog" id="mx_ReportEventDialog">

View file

@ -189,7 +189,7 @@ export default class UserSettingsDialog extends React.Component<IProps, IState>
tabs.push(
new Tab(
UserTab.Help,
_td("Help & About"),
_td("setting|help_about|title"),
"mx_UserSettingsDialog_helpIcon",
<HelpUserSettingsTab closeSettingsFn={() => this.props.onFinished()} />,
"UserSettingsHelpAbout",

View file

@ -114,7 +114,7 @@ export default class CreateCrossSigningDialog extends React.PureComponent<IProps
[SSOAuthEntry.PHASE_PREAUTH]: {
title: _t("Use Single Sign On to continue"),
body: _t("To continue, use Single Sign On to prove your identity."),
continueText: _t("Single Sign On"),
continueText: _t("auth|sso"),
continueKind: "primary",
},
[SSOAuthEntry.PHASE_POSTAUTH]: {

View file

@ -106,7 +106,7 @@ export function RoomResultContextMenus({ room }: Props): JSX.Element {
const target = ev.target as HTMLElement;
setNotificationMenuPosition(target.getBoundingClientRect());
}}
title={_t("Notification options")}
title={_t("room_list|notification_options")}
isExpanded={notificationMenuPosition !== null}
/>
)}

View file

@ -263,15 +263,15 @@ const findVisibleRoomMembers = (visibleRooms: Room[], cli: MatrixClient, filterD
const roomAriaUnreadLabel = (room: Room, notification: RoomNotificationState): string | undefined => {
if (notification.hasMentions) {
return _t("%(count)s unread messages including mentions.", {
return _t("a11y|n_unread_messages_mentions", {
count: notification.count,
});
} else if (notification.hasUnreadCount) {
return _t("%(count)s unread messages.", {
return _t("a11y|n_unread_messages", {
count: notification.count,
});
} else if (notification.isUnread) {
return _t("Unread messages.");
return _t("a11y|unread_messages");
} else {
return undefined;
}

View file

@ -115,7 +115,7 @@ export default class ErrorBoundary extends React.PureComponent<Props, IState> {
if (MatrixClientPeg.get()) {
clearCacheButton = (
<AccessibleButton onClick={this.onClearCacheAndReload} kind="danger">
{_t("Clear cache and reload")}
{_t("setting|help_about|clear_cache_reload")}
</AccessibleButton>
);
}

View file

@ -50,7 +50,7 @@ const QRCode: React.FC<IProps> = ({ data, className, ...options }) => {
return (
<div className={classNames("mx_QRCode", className)}>
{dataUri ? <img src={dataUri} className="mx_VerificationQRCode" alt={_t("QR Code")} /> : <Spinner />}
{dataUri ? <img src={dataUri} className="mx_VerificationQRCode" alt={_t("common|qr_code")} /> : <Spinner />}
</div>
);
};

View file

@ -92,11 +92,11 @@ const SSOButton: React.FC<ISSOButtonProps> = ({
}) => {
let label: string;
if (idp) {
label = _t("Continue with %(provider)s", { provider: idp.name });
label = _t("auth|continue_with_idp", { provider: idp.name });
} else if (DELEGATED_OIDC_COMPATIBILITY.findIn<boolean>(flow)) {
label = _t("action|continue");
} else {
label = _t("Sign in with single sign-on");
label = _t("auth|sign_in_with_sso");
}
const onClick = (): void => {

View file

@ -457,7 +457,7 @@ export default class AliasSettings extends React.Component<IProps, IState> {
>
<details onToggle={this.onLocalAliasesToggled} open={this.state.detailsOpen}>
<summary className="mx_AliasSettings_localAddresses">
{this.state.detailsOpen ? _t("Show less") : _t("Show more")}
{this.state.detailsOpen ? _t("room_list|show_less") : _t("Show more")}
</summary>
{localAliasesList}
</details>

View file

@ -157,11 +157,7 @@ const DmAuxButton: React.FC<IAuxButtonProps> = ({ tabIndex, dispatcher = default
showSpaceInvite(activeSpace);
}}
disabled={!canInvite}
tooltip={
canInvite
? undefined
: _t("You do not have permissions to invite people to this space")
}
tooltip={canInvite ? undefined : _t("spaces|error_no_permission_invite")}
/>
)}
</IconizedContextMenuOptionList>
@ -253,11 +249,7 @@ const UntaggedAuxButton: React.FC<IAuxButtonProps> = ({ tabIndex }) => {
PosthogTrackers.trackInteraction("WebRoomListRoomsSublistPlusMenuCreateRoomItem", e);
}}
disabled={!canAddRooms}
tooltip={
canAddRooms
? undefined
: _t("You do not have permissions to create new rooms in this space")
}
tooltip={canAddRooms ? undefined : _t("spaces|error_no_permission_create_room")}
/>
{videoRoomsEnabled && (
<IconizedContextMenuOption
@ -273,11 +265,7 @@ const UntaggedAuxButton: React.FC<IAuxButtonProps> = ({ tabIndex }) => {
);
}}
disabled={!canAddRooms}
tooltip={
canAddRooms
? undefined
: _t("You do not have permissions to create new rooms in this space")
}
tooltip={canAddRooms ? undefined : _t("spaces|error_no_permission_create_room")}
>
<BetaPill />
</IconizedContextMenuOption>
@ -292,9 +280,7 @@ const UntaggedAuxButton: React.FC<IAuxButtonProps> = ({ tabIndex }) => {
showAddExistingRooms(activeSpace);
}}
disabled={!canAddRooms}
tooltip={
canAddRooms ? undefined : _t("You do not have permissions to add rooms to this space")
}
tooltip={canAddRooms ? undefined : _t("spaces|error_no_permission_add_room")}
/>
</>
) : null}

View file

@ -267,9 +267,7 @@ const RoomListHeader: React.FC<IProps> = ({ onVisibilityChange }) => {
closePlusMenu();
}}
disabled={!canAddSubRooms}
tooltip={
!canAddSubRooms ? _t("You do not have permissions to add rooms to this space") : undefined
}
tooltip={!canAddSubRooms ? _t("spaces|error_no_permission_add_room") : undefined}
/>
{canCreateSpaces && (
<IconizedContextMenuOption
@ -282,11 +280,7 @@ const RoomListHeader: React.FC<IProps> = ({ onVisibilityChange }) => {
closePlusMenu();
}}
disabled={!canAddSubSpaces}
tooltip={
!canAddSubSpaces
? _t("You do not have permissions to add spaces to this space")
: undefined
}
tooltip={!canAddSubSpaces ? _t("spaces|error_no_permission_add_space") : undefined}
>
<BetaPill />
</IconizedContextMenuOption>

View file

@ -584,14 +584,14 @@ export default class RoomSublist extends React.Component<IProps, IState> {
onChange={this.onUnreadFirstChanged}
checked={isUnreadFirst}
>
{_t("Show rooms with unread messages first")}
{_t("room_list|sort_unread_first")}
</StyledMenuItemCheckbox>
<StyledMenuItemCheckbox
onClose={this.onCloseMenu}
onChange={this.onMessagePreviewChanged}
checked={this.layout.showPreviews}
>
{_t("Show previews of messages")}
{_t("room_list|show_previews")}
</StyledMenuItemCheckbox>
</fieldset>
</React.Fragment>
@ -607,14 +607,14 @@ export default class RoomSublist extends React.Component<IProps, IState> {
>
<div className="mx_RoomSublist_contextMenu">
<fieldset>
<legend className="mx_RoomSublist_contextMenu_title">{_t("Sort by")}</legend>
<legend className="mx_RoomSublist_contextMenu_title">{_t("room_list|sort_by")}</legend>
<StyledMenuItemRadio
onClose={this.onCloseMenu}
onChange={() => this.onTagSortChanged(SortAlgorithm.Recent)}
checked={!isAlphabetical}
name={`mx_${this.props.tagId}_sortBy`}
>
{_t("Activity")}
{_t("room_list|sort_by_activity")}
</StyledMenuItemRadio>
<StyledMenuItemRadio
onClose={this.onCloseMenu}
@ -622,7 +622,7 @@ export default class RoomSublist extends React.Component<IProps, IState> {
checked={isAlphabetical}
name={`mx_${this.props.tagId}_sortBy`}
>
{_t("A-Z")}
{_t("room_list|sort_by_alphabet")}
</StyledMenuItemRadio>
</fieldset>
{otherSections}
@ -636,7 +636,7 @@ export default class RoomSublist extends React.Component<IProps, IState> {
<ContextMenuTooltipButton
className="mx_RoomSublist_menuButton"
onClick={this.onOpenMenuClick}
title={_t("List options")}
title={_t("room_list|sublist_options")}
isExpanded={!!this.state.contextMenuPosition}
/>
{contextMenu}
@ -788,7 +788,7 @@ export default class RoomSublist extends React.Component<IProps, IState> {
if (this.slidingSyncMode) {
numMissing = RoomListStore.instance.getCount(this.props.tagId) - amountFullyShown;
}
const label = _t("Show %(count)s more", { count: numMissing });
const label = _t("room_list|show_n_more", { count: numMissing });
let showMoreText: ReactNode = <span className="mx_RoomSublist_showNButtonText">{label}</span>;
if (this.props.isMinimized) showMoreText = null;
showNButton = (
@ -806,7 +806,7 @@ export default class RoomSublist extends React.Component<IProps, IState> {
);
} else if (this.numTiles > this.layout.defaultVisibleTiles) {
// we have all tiles visible - add a button to show less
const label = _t("Show less");
const label = _t("room_list|show_less");
let showLessText: ReactNode = <span className="mx_RoomSublist_showNButtonText">{label}</span>;
if (this.props.isMinimized) showLessText = null;
showNButton = (

View file

@ -313,7 +313,7 @@ export class RoomTile extends React.PureComponent<ClassProps, State> {
<ContextMenuTooltipButton
className={classes}
onClick={this.onNotificationsMenuOpenClick}
title={_t("Notification options")}
title={_t("room_list|notification_options")}
isExpanded={!!this.state.notificationsMenuPosition}
tabIndex={isActive ? 0 : -1}
/>
@ -433,17 +433,17 @@ export class RoomTile extends React.PureComponent<ClassProps, State> {
} else if (this.notificationState.hasMentions) {
ariaLabel +=
" " +
_t("%(count)s unread messages including mentions.", {
_t("a11y|n_unread_messages_mentions", {
count: this.notificationState.count,
});
} else if (this.notificationState.hasUnreadCount) {
ariaLabel +=
" " +
_t("%(count)s unread messages.", {
_t("a11y|n_unread_messages", {
count: this.notificationState.count,
});
} else if (this.notificationState.isUnread) {
ariaLabel += " " + _t("Unread messages.");
ariaLabel += " " + _t("a11y|unread_messages");
}
let ariaDescribedBy: string;

View file

@ -56,7 +56,7 @@ export const deleteDevicesWithInteractiveAuth = async (
body: _t("Confirm logging out these devices by using Single Sign On to prove your identity.", {
count: numDevices,
}),
continueText: _t("Single Sign On"),
continueText: _t("auth|sso"),
continueKind: "primary",
},
[SSOAuthEntry.PHASE_POSTAUTH]: {

View file

@ -78,8 +78,8 @@ export default class HelpUserSettingsTab extends React.Component<IProps, IState>
: "<not-enabled>";
return {
appVersion: `${_t("%(brand)s version:", { brand })} ${appVersion}`,
olmVersion: `${_t("Olm version:")} ${olmVersion}`,
appVersion: `${_t("setting|help_about|brand_version", { brand })} ${appVersion}`,
olmVersion: `${_t("setting|help_about|olm_version")} ${olmVersion}`,
};
}
@ -228,7 +228,7 @@ export default class HelpUserSettingsTab extends React.Component<IProps, IState>
const brand = SdkConfig.get().brand;
let faqText = _t(
"For help with using %(brand)s, click <a>here</a>.",
"setting|help_about|help_link",
{
brand,
},
@ -240,7 +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.",
"setting|help_about|help_link_chat_bot",
{
brand,
},
@ -258,7 +258,7 @@ export default class HelpUserSettingsTab extends React.Component<IProps, IState>
)}
<div>
<AccessibleButton onClick={this.onStartBotChat} kind="primary">
{_t("Chat with %(brand)s Bot", { brand })}
{_t("setting|help_about|chat_bot", { brand })}
</AccessibleButton>
</div>
</div>
@ -306,10 +306,10 @@ export default class HelpUserSettingsTab extends React.Component<IProps, IState>
return (
<SettingsTab>
<SettingsSection heading={_t("Help & About")}>
<SettingsSection heading={_t("setting|help_about|title")}>
{bugReportingSection}
<SettingsSubsection heading={_t("common|faq")} description={faqText} />
<SettingsSubsection heading={_t("Versions")}>
<SettingsSubsection heading={_t("setting|help_about|versions")}>
<SettingsSubsectionText>
<CopyableText getTextToCopy={this.getVersionTextToCopy}>
{appVersion}
@ -325,7 +325,7 @@ export default class HelpUserSettingsTab extends React.Component<IProps, IState>
<SettingsSubsection heading={_t("Advanced")}>
<SettingsSubsectionText>
{_t(
"Homeserver is <code>%(homeserverUrl)s</code>",
"setting|help_about|homeserver",
{
homeserverUrl: this.context.getHomeserverUrl(),
},
@ -337,7 +337,7 @@ export default class HelpUserSettingsTab extends React.Component<IProps, IState>
{this.context.getIdentityServerUrl() && (
<SettingsSubsectionText>
{_t(
"Identity server is <code>%(identityServerUrl)s</code>",
"setting|help_about|identity_server",
{
identityServerUrl: this.context.getIdentityServerUrl(),
},
@ -350,18 +350,14 @@ export default class HelpUserSettingsTab extends React.Component<IProps, IState>
<SettingsSubsectionText>
<details>
<summary>{_t("common|access_token")}</summary>
<b>
{_t(
"Your access token gives full access to your account. Do not share it with anyone.",
)}
</b>
<b>{_t("setting|help_about|access_token_detail")}</b>
<CopyableText getTextToCopy={() => this.context.getAccessToken()}>
{this.context.getAccessToken()}
</CopyableText>
</details>
</SettingsSubsectionText>
<AccessibleButton onClick={this.onClearCacheAndReload} kind="danger">
{_t("Clear cache and reload")}
{_t("setting|help_about|clear_cache_reload")}
</AccessibleButton>
</SettingsSubsection>
</SettingsSection>