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:
parent
d9a61c093c
commit
55336bf932
12 changed files with 446 additions and 189 deletions
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue