Use semantic heading in user settings Sidebar & Voip (#10782)

* 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

* semantic headings and cleanup in Sidebar user settings

* semantic heading in voice user settings

* sonarcloud bug and test
This commit is contained in:
Kerry 2023-05-19 12:03:39 +12:00 committed by GitHub
parent d9a61c093c
commit 55336bf932
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 446 additions and 189 deletions

View file

@ -1,5 +1,5 @@
/*
Copyright 2021 - 2022 The Matrix.org Foundation C.I.C.
Copyright 2021 - 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.
@ -16,6 +16,10 @@ limitations under the License.
import React, { ChangeEvent } from "react";
import { Icon as HomeIcon } from "../../../../../../res/img/element-icons/home.svg";
import { Icon as FavoriteIcon } from "../../../../../../res/img/element-icons/roomlist/favorite.svg";
import { Icon as MembersIcon } from "../../../../../../res/img/element-icons/room/members.svg";
import { Icon as HashCircleIcon } from "../../../../../../res/img/element-icons/roomlist/hash-circle.svg";
import { _t } from "../../../../../languageHandler";
import SettingsStore from "../../../../../settings/SettingsStore";
import { SettingLevel } from "../../../../../settings/SettingLevel";
@ -23,6 +27,9 @@ import StyledCheckbox from "../../../elements/StyledCheckbox";
import { useSettingValue } from "../../../../../hooks/useSettings";
import { MetaSpace } from "../../../../../stores/spaces";
import PosthogTrackers from "../../../../../PosthogTrackers";
import SettingsTab from "../SettingsTab";
import { SettingsSection } from "../../shared/SettingsSection";
import SettingsSubsection, { SettingsSubsectionText } from "../../shared/SettingsSubsection";
type InteractionName = "WebSettingsSidebarTabSpacesCheckbox" | "WebQuickSettingsPinToSidebarCheckbox";
@ -50,79 +57,91 @@ const SidebarUserSettingsTab: React.FC = () => {
} = useSettingValue<Record<MetaSpace, boolean>>("Spaces.enabledMetaSpaces");
const allRoomsInHome = useSettingValue<boolean>("Spaces.allRoomsInHome");
const onAllRoomsInHomeToggle = async (event: ChangeEvent<HTMLInputElement>): Promise<void> => {
await SettingsStore.setValue("Spaces.allRoomsInHome", null, SettingLevel.ACCOUNT, event.target.checked);
PosthogTrackers.trackInteraction("WebSettingsSidebarTabSpacesCheckbox", event, 1);
};
return (
<div className="mx_SettingsTab mx_SidebarUserSettingsTab">
<div className="mx_SettingsTab_heading">{_t("Sidebar")}</div>
<div className="mx_SettingsTab_section">
<div className="mx_SettingsTab_subheading">{_t("Spaces to show")}</div>
<div className="mx_SettingsTab_subsectionText">
{_t(
<SettingsTab>
<SettingsSection heading={_t("Sidebar")}>
<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.",
)}
</div>
<StyledCheckbox
checked={!!homeEnabled}
onChange={onMetaSpaceChangeFactory(MetaSpace.Home, "WebSettingsSidebarTabSpacesCheckbox")}
className="mx_SidebarUserSettingsTab_homeCheckbox"
disabled={homeEnabled}
>
{_t("Home")}
</StyledCheckbox>
<div className="mx_SidebarUserSettingsTab_checkboxMicrocopy">
{_t("Home is useful for getting an overview of everything.")}
</div>
<StyledCheckbox
checked={!!homeEnabled}
onChange={onMetaSpaceChangeFactory(MetaSpace.Home, "WebSettingsSidebarTabSpacesCheckbox")}
className="mx_SidebarUserSettingsTab_checkbox"
disabled={homeEnabled}
>
<SettingsSubsectionText>
<HomeIcon />
{_t("Home")}
</SettingsSubsectionText>
<SettingsSubsectionText>
{_t("Home is useful for getting an overview of everything.")}
</SettingsSubsectionText>
</StyledCheckbox>
<StyledCheckbox
checked={allRoomsInHome}
disabled={!homeEnabled}
onChange={(e) => {
SettingsStore.setValue("Spaces.allRoomsInHome", null, SettingLevel.ACCOUNT, e.target.checked);
PosthogTrackers.trackInteraction("WebSettingsSidebarTabSpacesCheckbox", e, 1);
}}
className="mx_SidebarUserSettingsTab_homeAllRoomsCheckbox"
>
{_t("Show all rooms")}
</StyledCheckbox>
<div className="mx_SidebarUserSettingsTab_checkboxMicrocopy">
{_t("Show all your rooms in Home, even if they're in a space.")}
</div>
<StyledCheckbox
checked={allRoomsInHome}
disabled={!homeEnabled}
onChange={onAllRoomsInHomeToggle}
className="mx_SidebarUserSettingsTab_checkbox mx_SidebarUserSettingsTab_homeAllRoomsCheckbox"
data-testid="mx_SidebarUserSettingsTab_homeAllRoomsCheckbox"
>
<SettingsSubsectionText>{_t("Show all rooms")}</SettingsSubsectionText>
<SettingsSubsectionText>
{_t("Show all your rooms in Home, even if they're in a space.")}
</SettingsSubsectionText>
</StyledCheckbox>
<StyledCheckbox
checked={!!favouritesEnabled}
onChange={onMetaSpaceChangeFactory(MetaSpace.Favourites, "WebSettingsSidebarTabSpacesCheckbox")}
className="mx_SidebarUserSettingsTab_favouritesCheckbox"
>
{_t("Favourites")}
</StyledCheckbox>
<div className="mx_SidebarUserSettingsTab_checkboxMicrocopy">
{_t("Group all your favourite rooms and people in one place.")}
</div>
<StyledCheckbox
checked={!!favouritesEnabled}
onChange={onMetaSpaceChangeFactory(MetaSpace.Favourites, "WebSettingsSidebarTabSpacesCheckbox")}
className="mx_SidebarUserSettingsTab_checkbox"
>
<SettingsSubsectionText>
<FavoriteIcon />
{_t("Favourites")}
</SettingsSubsectionText>
<SettingsSubsectionText>
{_t("Group all your favourite rooms and people in one place.")}
</SettingsSubsectionText>
</StyledCheckbox>
<StyledCheckbox
checked={!!peopleEnabled}
onChange={onMetaSpaceChangeFactory(MetaSpace.People, "WebSettingsSidebarTabSpacesCheckbox")}
className="mx_SidebarUserSettingsTab_peopleCheckbox"
>
{_t("People")}
</StyledCheckbox>
<div className="mx_SidebarUserSettingsTab_checkboxMicrocopy">
{_t("Group all your people in one place.")}
</div>
<StyledCheckbox
checked={!!peopleEnabled}
onChange={onMetaSpaceChangeFactory(MetaSpace.People, "WebSettingsSidebarTabSpacesCheckbox")}
className="mx_SidebarUserSettingsTab_checkbox"
>
<SettingsSubsectionText>
<MembersIcon />
{_t("People")}
</SettingsSubsectionText>
<SettingsSubsectionText>{_t("Group all your people in one place.")}</SettingsSubsectionText>
</StyledCheckbox>
<StyledCheckbox
checked={!!orphansEnabled}
onChange={onMetaSpaceChangeFactory(MetaSpace.Orphans, "WebSettingsSidebarTabSpacesCheckbox")}
className="mx_SidebarUserSettingsTab_orphansCheckbox"
>
{_t("Rooms outside of a space")}
</StyledCheckbox>
<div className="mx_SidebarUserSettingsTab_checkboxMicrocopy">
{_t("Group all your rooms that aren't part of a space in one place.")}
</div>
</div>
</div>
<StyledCheckbox
checked={!!orphansEnabled}
onChange={onMetaSpaceChangeFactory(MetaSpace.Orphans, "WebSettingsSidebarTabSpacesCheckbox")}
className="mx_SidebarUserSettingsTab_checkbox"
>
<SettingsSubsectionText>
<HashCircleIcon />
{_t("Rooms outside of a space")}
</SettingsSubsectionText>
<SettingsSubsectionText>
{_t("Group all your rooms that aren't part of a space in one place.")}
</SettingsSubsectionText>
</StyledCheckbox>
</SettingsSubsection>
</SettingsSection>
</SettingsTab>
);
};

View file

@ -26,6 +26,9 @@ import { SettingLevel } from "../../../../../settings/SettingLevel";
import SettingsFlag from "../../../elements/SettingsFlag";
import LabelledToggleSwitch from "../../../elements/LabelledToggleSwitch";
import { requestMediaPermissions } from "../../../../../utils/media/requestMediaPermissions";
import SettingsTab from "../SettingsTab";
import { SettingsSection } from "../../shared/SettingsSection";
import SettingsSubsection from "../../shared/SettingsSubsection";
interface IState {
mediaDevices: IMediaDevices | null;
@ -128,7 +131,7 @@ export default class VoiceUserSettingsTab extends React.Component<{}, IState> {
let webcamDropdown: ReactNode | undefined;
if (!this.state.mediaDevices) {
requestButton = (
<div className="mx_VoiceUserSettingsTab_missingMediaPermissions">
<div>
<p>{_t("Missing media permissions, click the button below to request.")}</p>
<AccessibleButton onClick={this.requestMediaPermissions} kind="primary">
{_t("Request media permissions")}
@ -148,33 +151,30 @@ export default class VoiceUserSettingsTab extends React.Component<{}, IState> {
}
return (
<div className="mx_SettingsTab mx_VoiceUserSettingsTab">
<div className="mx_SettingsTab_heading">{_t("Voice & Video")}</div>
{requestButton}
<div className="mx_SettingsTab_section">
<span className="mx_SettingsTab_subheading">{_t("Voice settings")}</span>
{speakerDropdown}
{microphoneDropdown}
<LabelledToggleSwitch
value={this.state.audioAutoGainControl}
onChange={async (v): Promise<void> => {
await MediaDeviceHandler.setAudioAutoGainControl(v);
this.setState({ audioAutoGainControl: MediaDeviceHandler.getAudioAutoGainControl() });
}}
label={_t("Automatically adjust the microphone volume")}
data-testid="voice-auto-gain"
/>
</div>
<div className="mx_SettingsTab_section">
<span className="mx_SettingsTab_subheading">{_t("Video settings")}</span>
{webcamDropdown}
<SettingsFlag name="VideoView.flipVideoHorizontally" level={SettingLevel.ACCOUNT} />
</div>
<SettingsTab>
<SettingsSection heading={_t("Voice & Video")}>
{requestButton}
<SettingsSubsection heading={_t("Voice settings")} stretchContent>
{speakerDropdown}
{microphoneDropdown}
<LabelledToggleSwitch
value={this.state.audioAutoGainControl}
onChange={async (v): Promise<void> => {
await MediaDeviceHandler.setAudioAutoGainControl(v);
this.setState({ audioAutoGainControl: MediaDeviceHandler.getAudioAutoGainControl() });
}}
label={_t("Automatically adjust the microphone volume")}
data-testid="voice-auto-gain"
/>
</SettingsSubsection>
<SettingsSubsection heading={_t("Video settings")} stretchContent>
{webcamDropdown}
<SettingsFlag name="VideoView.flipVideoHorizontally" level={SettingLevel.ACCOUNT} />
</SettingsSubsection>
</SettingsSection>
<div className="mx_SettingsTab_heading">{_t("Advanced")}</div>
<div className="mx_SettingsTab_section">
<span className="mx_SettingsTab_subheading">{_t("Voice processing")}</span>
<div className="mx_SettingsTab_section">
<SettingsSection heading={_t("Advanced")}>
<SettingsSubsection heading={_t("Voice processing")}>
<LabelledToggleSwitch
value={this.state.audioNoiseSuppression}
onChange={async (v): Promise<void> => {
@ -193,9 +193,8 @@ export default class VoiceUserSettingsTab extends React.Component<{}, IState> {
label={_t("Echo cancellation")}
data-testid="voice-echo-cancellation"
/>
</div>
<div className="mx_SettingsTab_section">
<span className="mx_SettingsTab_subheading">{_t("Connection")}</span>
</SettingsSubsection>
<SettingsSubsection heading={_t("Connection")}>
<SettingsFlag
name="webRtcAllowPeerToPeer"
level={SettingLevel.DEVICE}
@ -206,9 +205,9 @@ export default class VoiceUserSettingsTab extends React.Component<{}, IState> {
level={SettingLevel.DEVICE}
onChange={this.changeFallbackICEServerAllowed}
/>
</div>
</div>
</div>
</SettingsSubsection>
</SettingsSection>
</SettingsTab>
);
}
}