Use semantic headings in user settings Security (#10774)
* split SettingsSection out of SettingsTab, replace usage * correct copyright * use semantic headings in GeneralRoomSettingsTab * use SettingsTab and SettingsSubsection in room settings * fix VoipRoomSettingsTab * use SettingsSection components in space settings * settingssubsection text component * use semantic headings in HelpUserSetttings tab * use ExternalLink components for external links * test * strict * lint * semantic heading in labs settings * semantic headings in keyboard settings tab * semantic heading in preferencesusersettingstab * tidying * use new settings components in eventindexpanel * findByTestId * prettier * semantic headings and style refresh for crypto settings * e2e panel * test cross signing panel * strict * more strict * tweak * test eventindexpanel * strict fixes
This commit is contained in:
parent
6c262fff6b
commit
d9a61c093c
16 changed files with 721 additions and 303 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2019 - 2022 The Matrix.org Foundation C.I.C.
|
||||
Copyright 2019 - 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -41,6 +41,9 @@ import { privateShouldBeEncrypted } from "../../../../../utils/rooms";
|
|||
import LoginWithQR, { Mode } from "../../../auth/LoginWithQR";
|
||||
import LoginWithQRSection from "../../devices/LoginWithQRSection";
|
||||
import type { IServerVersions } from "matrix-js-sdk/src/matrix";
|
||||
import SettingsTab from "../SettingsTab";
|
||||
import { SettingsSection } from "../../shared/SettingsSection";
|
||||
import SettingsSubsection, { SettingsSubsectionText } from "../../shared/SettingsSubsection";
|
||||
|
||||
interface IIgnoredUserProps {
|
||||
userId: string;
|
||||
|
@ -245,10 +248,9 @@ export default class SecurityUserSettingsTab extends React.Component<IProps, ISt
|
|||
});
|
||||
|
||||
return (
|
||||
<div className="mx_SettingsTab_section">
|
||||
<span className="mx_SettingsTab_subheading">{_t("Ignored users")}</span>
|
||||
<div className="mx_SettingsTab_subsectionText">{userIds}</div>
|
||||
</div>
|
||||
<SettingsSubsection heading={_t("Ignored users")}>
|
||||
<SettingsSubsectionText>{userIds}</SettingsSubsectionText>
|
||||
</SettingsSubsection>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -260,24 +262,25 @@ export default class SecurityUserSettingsTab extends React.Component<IProps, ISt
|
|||
}
|
||||
|
||||
return (
|
||||
<div className="mx_SettingsTab_section mx_SecurityUserSettingsTab_bulkOptions">
|
||||
<span className="mx_SettingsTab_subheading">{_t("Bulk options")}</span>
|
||||
<AccessibleButton
|
||||
onClick={this.onAcceptAllInvitesClicked}
|
||||
kind="primary"
|
||||
disabled={this.state.managingInvites}
|
||||
>
|
||||
{_t("Accept all %(invitedRooms)s invites", { invitedRooms: invitedRoomIds.size })}
|
||||
</AccessibleButton>
|
||||
<AccessibleButton
|
||||
onClick={this.onRejectAllInvitesClicked}
|
||||
kind="danger"
|
||||
disabled={this.state.managingInvites}
|
||||
>
|
||||
{_t("Reject all %(invitedRooms)s invites", { invitedRooms: invitedRoomIds.size })}
|
||||
</AccessibleButton>
|
||||
{this.state.managingInvites ? <InlineSpinner /> : <div />}
|
||||
</div>
|
||||
<SettingsSubsection heading={_t("Bulk options")}>
|
||||
<div className="mx_SecurityUserSettingsTab_bulkOptions">
|
||||
<AccessibleButton
|
||||
onClick={this.onAcceptAllInvitesClicked}
|
||||
kind="primary"
|
||||
disabled={this.state.managingInvites}
|
||||
>
|
||||
{_t("Accept all %(invitedRooms)s invites", { invitedRooms: invitedRoomIds.size })}
|
||||
</AccessibleButton>
|
||||
<AccessibleButton
|
||||
onClick={this.onRejectAllInvitesClicked}
|
||||
kind="danger"
|
||||
disabled={this.state.managingInvites}
|
||||
>
|
||||
{_t("Reject all %(invitedRooms)s invites", { invitedRooms: invitedRoomIds.size })}
|
||||
</AccessibleButton>
|
||||
{this.state.managingInvites ? <InlineSpinner /> : <div />}
|
||||
</div>
|
||||
</SettingsSubsection>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -291,19 +294,15 @@ export default class SecurityUserSettingsTab extends React.Component<IProps, ISt
|
|||
|
||||
public render(): React.ReactNode {
|
||||
const secureBackup = (
|
||||
<div className="mx_SettingsTab_section">
|
||||
<span className="mx_SettingsTab_subheading">{_t("Secure Backup")}</span>
|
||||
<div className="mx_SettingsTab_subsectionText">
|
||||
<SecureBackupPanel />
|
||||
</div>
|
||||
</div>
|
||||
<SettingsSubsection heading={_t("Secure Backup")}>
|
||||
<SecureBackupPanel />
|
||||
</SettingsSubsection>
|
||||
);
|
||||
|
||||
const eventIndex = (
|
||||
<div className="mx_SettingsTab_section">
|
||||
<span className="mx_SettingsTab_subheading">{_t("Message search")}</span>
|
||||
<SettingsSubsection heading={_t("Message search")}>
|
||||
<EventIndexPanel />
|
||||
</div>
|
||||
</SettingsSubsection>
|
||||
);
|
||||
|
||||
// XXX: There's no such panel in the current cross-signing designs, but
|
||||
|
@ -311,12 +310,9 @@ export default class SecurityUserSettingsTab extends React.Component<IProps, ISt
|
|||
// in having advanced details here once all flows are implemented, we
|
||||
// can remove this.
|
||||
const crossSigning = (
|
||||
<div className="mx_SettingsTab_section">
|
||||
<span className="mx_SettingsTab_subheading">{_t("Cross-signing")}</span>
|
||||
<div className="mx_SettingsTab_subsectionText">
|
||||
<CrossSigningPanel />
|
||||
</div>
|
||||
</div>
|
||||
<SettingsSubsection heading={_t("Cross-signing")}>
|
||||
<CrossSigningPanel />
|
||||
</SettingsSubsection>
|
||||
);
|
||||
|
||||
let warning;
|
||||
|
@ -340,28 +336,24 @@ export default class SecurityUserSettingsTab extends React.Component<IProps, ISt
|
|||
});
|
||||
};
|
||||
privacySection = (
|
||||
<React.Fragment>
|
||||
<div className="mx_SettingsTab_heading">{_t("Privacy")}</div>
|
||||
<div className="mx_SettingsTab_section">
|
||||
<span className="mx_SettingsTab_subheading">{_t("Analytics")}</span>
|
||||
<div className="mx_SettingsTab_subsectionText">
|
||||
<p>
|
||||
{_t(
|
||||
"Share anonymous data to help us identify issues. Nothing personal. " +
|
||||
"No third parties.",
|
||||
)}
|
||||
</p>
|
||||
<AccessibleButton kind="link" onClick={onClickAnalyticsLearnMore}>
|
||||
{_t("Learn more")}
|
||||
</AccessibleButton>
|
||||
</div>
|
||||
<SettingsSection heading={_t("Privacy")}>
|
||||
<SettingsSubsection
|
||||
heading={_t("Analytics")}
|
||||
description={_t(
|
||||
"Share anonymous data to help us identify issues. Nothing personal. No third parties.",
|
||||
)}
|
||||
>
|
||||
<AccessibleButton kind="link" onClick={onClickAnalyticsLearnMore}>
|
||||
{_t("Learn more")}
|
||||
</AccessibleButton>
|
||||
{PosthogAnalytics.instance.isEnabled() && (
|
||||
<SettingsFlag name="pseudonymousAnalyticsOptIn" level={SettingLevel.ACCOUNT} />
|
||||
)}
|
||||
<span className="mx_SettingsTab_subheading">{_t("Sessions")}</span>
|
||||
</SettingsSubsection>
|
||||
<SettingsSubsection heading={_t("Sessions")}>
|
||||
<SettingsFlag name="deviceClientInformationOptIn" level={SettingLevel.ACCOUNT} />
|
||||
</div>
|
||||
</React.Fragment>
|
||||
</SettingsSubsection>
|
||||
</SettingsSection>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -373,67 +365,60 @@ export default class SecurityUserSettingsTab extends React.Component<IProps, ISt
|
|||
// only show the section if there's something to show
|
||||
if (ignoreUsersPanel || invitesPanel || e2ePanel) {
|
||||
advancedSection = (
|
||||
<>
|
||||
<div className="mx_SettingsTab_heading">{_t("Advanced")}</div>
|
||||
<div className="mx_SettingsTab_section">
|
||||
{ignoreUsersPanel}
|
||||
{invitesPanel}
|
||||
{e2ePanel}
|
||||
</div>
|
||||
</>
|
||||
<SettingsSection heading={_t("Advanced")}>
|
||||
{ignoreUsersPanel}
|
||||
{invitesPanel}
|
||||
{e2ePanel}
|
||||
</SettingsSection>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const useNewSessionManager = SettingsStore.getValue("feature_new_device_manager");
|
||||
const devicesSection = useNewSessionManager ? null : (
|
||||
<>
|
||||
<div className="mx_SettingsTab_heading">{_t("Where you're signed in")}</div>
|
||||
<div className="mx_SettingsTab_section" data-testid="devices-section">
|
||||
<span className="mx_SettingsTab_subsectionText">
|
||||
{_t(
|
||||
"Manage your signed-in devices below. " +
|
||||
"A device's name is visible to people you communicate with.",
|
||||
)}
|
||||
</span>
|
||||
<DevicesPanel />
|
||||
</div>
|
||||
<SettingsSection heading={_t("Where you're signed in")} data-testid="devices-section">
|
||||
<SettingsSubsectionText>
|
||||
{_t(
|
||||
"Manage your signed-in devices below. " +
|
||||
"A device's name is visible to people you communicate with.",
|
||||
)}
|
||||
</SettingsSubsectionText>
|
||||
<DevicesPanel />
|
||||
<LoginWithQRSection
|
||||
onShowQr={this.onShowQRClicked}
|
||||
versions={this.state.versions}
|
||||
capabilities={this.state.capabilities}
|
||||
/>
|
||||
</>
|
||||
</SettingsSection>
|
||||
);
|
||||
|
||||
const client = MatrixClientPeg.get();
|
||||
|
||||
if (this.state.showLoginWithQR) {
|
||||
return (
|
||||
<div className="mx_SettingsTab mx_SecurityUserSettingsTab">
|
||||
<SettingsTab>
|
||||
<LoginWithQR
|
||||
onFinished={this.onLoginWithQRFinished}
|
||||
mode={this.state.showLoginWithQR}
|
||||
client={client}
|
||||
/>
|
||||
</div>
|
||||
</SettingsTab>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="mx_SettingsTab mx_SecurityUserSettingsTab">
|
||||
<SettingsTab>
|
||||
{warning}
|
||||
{devicesSection}
|
||||
<div className="mx_SettingsTab_heading">{_t("Encryption")}</div>
|
||||
<div className="mx_SettingsTab_section">
|
||||
<SettingsSection heading={_t("Encryption")}>
|
||||
{secureBackup}
|
||||
{eventIndex}
|
||||
{crossSigning}
|
||||
<CryptographyPanel />
|
||||
</div>
|
||||
</SettingsSection>
|
||||
{privacySection}
|
||||
{advancedSection}
|
||||
</div>
|
||||
</SettingsTab>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue