From 036e1f982bc781e8853c59e62d29571e583a7e90 Mon Sep 17 00:00:00 2001 From: Kerry Archibald Date: Fri, 28 Apr 2023 14:37:17 +1200 Subject: [PATCH 01/24] split SettingsSection out of SettingsTab, replace usage --- res/css/_components.pcss | 1 + res/css/views/settings/_SettingsFieldset.pcss | 6 +- .../views/settings/tabs/_SettingsSection.pcss | 36 ++++++ .../views/settings/shared/SettingsSection.tsx | 48 ++++++++ .../views/settings/tabs/SettingsTab.tsx | 24 +++- .../settings/tabs/user/SessionManagerTab.tsx | 113 +++++++++--------- .../views/settings/tabs/SettingsTab-test.tsx | 2 +- .../__snapshots__/SettingsTab-test.tsx.snap | 5 - 8 files changed, 167 insertions(+), 68 deletions(-) create mode 100644 res/css/views/settings/tabs/_SettingsSection.pcss create mode 100644 src/components/views/settings/shared/SettingsSection.tsx diff --git a/res/css/_components.pcss b/res/css/_components.pcss index 2b0cf70b9c2..f200429ced3 100644 --- a/res/css/_components.pcss +++ b/res/css/_components.pcss @@ -339,6 +339,7 @@ @import "./views/settings/_SpellCheckLanguages.pcss"; @import "./views/settings/_ThemeChoicePanel.pcss"; @import "./views/settings/_UpdateCheckButton.pcss"; +@import "./views/settings/tabs/_SettingsSection.pcss"; @import "./views/settings/tabs/_SettingsTab.pcss"; @import "./views/settings/tabs/room/_GeneralRoomSettingsTab.pcss"; @import "./views/settings/tabs/room/_NotificationSettingsTab.pcss"; diff --git a/res/css/views/settings/_SettingsFieldset.pcss b/res/css/views/settings/_SettingsFieldset.pcss index 5e2d466568d..556fcdf8eb9 100644 --- a/res/css/views/settings/_SettingsFieldset.pcss +++ b/res/css/views/settings/_SettingsFieldset.pcss @@ -20,9 +20,11 @@ limitations under the License. } .mx_SettingsFieldset_legend { - font-size: $font-16px; - display: block; + // matches h3 + font-size: $font-18px; font-weight: var(--font-semi-bold); + line-height: $font-22px; + display: block; color: $primary-content; margin-bottom: 10px; margin-top: 12px; diff --git a/res/css/views/settings/tabs/_SettingsSection.pcss b/res/css/views/settings/tabs/_SettingsSection.pcss new file mode 100644 index 00000000000..19ef46f79f2 --- /dev/null +++ b/res/css/views/settings/tabs/_SettingsSection.pcss @@ -0,0 +1,36 @@ +/* +Copyright 2019, 2020 New Vector Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_SettingsSection { + --SettingsTab_section-margin-bottom-preferences-labs: 30px; + --SettingsTab_heading_nth_child-margin-top: 30px; /* TODO: Use a spacing variable */ + --SettingsTab_fullWidthField-margin-inline-end: 100px; + --SettingsTab_tooltip-max-width: 120px; /* So it fits in the space provided by the page */ + + color: $primary-content; + + a { + color: $links; + } +} + +.mx_SettingsSection_subSections { + display: grid; + grid-template-columns: 1fr; + grid-gap: $spacing-32; + + padding: $spacing-16 0; +} diff --git a/src/components/views/settings/shared/SettingsSection.tsx b/src/components/views/settings/shared/SettingsSection.tsx new file mode 100644 index 00000000000..1fc00905653 --- /dev/null +++ b/src/components/views/settings/shared/SettingsSection.tsx @@ -0,0 +1,48 @@ +/* +Copyright 2022 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. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import React, { HTMLAttributes } from "react"; + +import Heading from "../../typography/Heading"; + +export interface SettingsSectionProps extends HTMLAttributes { + heading: string | React.ReactNode; + children?: React.ReactNode; +} + +/** + * A section of settings content + * A SettingsTab may contain one or more SettingsSections + * Eg: + * ``` + * + * + * + * // profile settings form + * + * + * // account settings + * + * + * + * ``` + */ +export const SettingsSection: React.FC = ({ heading, children, ...rest }) => ( +
+ {typeof heading === "string" ? {heading} : <>{heading}} +
{children}
+
+); diff --git a/src/components/views/settings/tabs/SettingsTab.tsx b/src/components/views/settings/tabs/SettingsTab.tsx index 57b29f49c4f..e9f25ec7406 100644 --- a/src/components/views/settings/tabs/SettingsTab.tsx +++ b/src/components/views/settings/tabs/SettingsTab.tsx @@ -15,16 +15,30 @@ limitations under the License. */ import React from "react"; -import Heading from "../../typography/Heading"; - export interface SettingsTabProps { - heading: string; children?: React.ReactNode; } -const SettingsTab: React.FC = ({ heading, children }) => ( +/** + * Container for a tab of settings panel content + * Should contain one or more SettingsSection + * Settings width, padding and spacing between sections + * Eg: + * ``` + * + * + * + * // profile settings form + * + * + * // account settings + * + * + * + * ``` + */ +const SettingsTab: React.FC = ({ children }) => (
- {heading}
{children}
); diff --git a/src/components/views/settings/tabs/user/SessionManagerTab.tsx b/src/components/views/settings/tabs/user/SessionManagerTab.tsx index 7305975be1a..176767ad07e 100644 --- a/src/components/views/settings/tabs/user/SessionManagerTab.tsx +++ b/src/components/views/settings/tabs/user/SessionManagerTab.tsx @@ -38,6 +38,7 @@ import { useAsyncMemo } from "../../../../../hooks/useAsyncMemo"; import QuestionDialog from "../../../dialogs/QuestionDialog"; import { FilterVariation } from "../../devices/filter"; import { OtherSessionsSectionHeading } from "../../devices/OtherSessionsSectionHeading"; +import { SettingsSection } from "../../shared/SettingsSection"; const confirmSignOut = async (sessionsToSignOutCount: number): Promise => { const { finished } = Modal.createDialog(QuestionDialog, { @@ -225,62 +226,64 @@ const SessionManagerTab: React.FC = () => { } return ( - - - saveDeviceName(currentDeviceId, deviceName)} - onVerifyCurrentDevice={onVerifyCurrentDevice} - onSignOutCurrentDevice={onSignOutCurrentDevice} - signOutAllOtherSessions={signOutAllOtherSessions} - otherSessionsCount={otherSessionsCount} - /> - {shouldShowOtherSessions && ( - - } - description={_t( - `For best security, verify your sessions and sign out ` + - `from any session that you don't recognize or use anymore.`, - )} - data-testid="other-sessions-section" - > - + + + saveDeviceName(currentDeviceId, deviceName)} + onVerifyCurrentDevice={onVerifyCurrentDevice} + onSignOutCurrentDevice={onSignOutCurrentDevice} + signOutAllOtherSessions={signOutAllOtherSessions} + otherSessionsCount={otherSessionsCount} + /> + {shouldShowOtherSessions && ( + } - onSignOutDevices={onSignOutOtherDevices} - saveDeviceName={saveDeviceName} - setPushNotifications={setPushNotifications} - ref={filteredDeviceListRef} - supportsMSC3881={supportsMSC3881} - /> - - )} - + description={_t( + `For best security, verify your sessions and sign out ` + + `from any session that you don't recognize or use anymore.`, + )} + data-testid="other-sessions-section" + > + + + )} + + ); }; diff --git a/test/components/views/settings/tabs/SettingsTab-test.tsx b/test/components/views/settings/tabs/SettingsTab-test.tsx index 2cd678c6729..9b1f8190f88 100644 --- a/test/components/views/settings/tabs/SettingsTab-test.tsx +++ b/test/components/views/settings/tabs/SettingsTab-test.tsx @@ -22,7 +22,7 @@ import SettingsTab, { SettingsTabProps } from "../../../../../src/components/vie describe("", () => { const getComponent = (props: SettingsTabProps): ReactElement => ; it("renders tab", () => { - const { container } = render(getComponent({ heading: "Test Tab", children:
test
})); + const { container } = render(getComponent({ children:
test
})); expect(container).toMatchSnapshot(); }); diff --git a/test/components/views/settings/tabs/__snapshots__/SettingsTab-test.tsx.snap b/test/components/views/settings/tabs/__snapshots__/SettingsTab-test.tsx.snap index 704189fb1f2..cbebf4d8db1 100644 --- a/test/components/views/settings/tabs/__snapshots__/SettingsTab-test.tsx.snap +++ b/test/components/views/settings/tabs/__snapshots__/SettingsTab-test.tsx.snap @@ -5,11 +5,6 @@ exports[` renders tab 1`] = `
-

- Test Tab -

From 8e4f061dd15fe360293099109f95803334df912a Mon Sep 17 00:00:00 2001 From: Kerry Archibald Date: Fri, 28 Apr 2023 15:17:46 +1200 Subject: [PATCH 02/24] correct copyright --- res/css/views/settings/tabs/_SettingsSection.pcss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/css/views/settings/tabs/_SettingsSection.pcss b/res/css/views/settings/tabs/_SettingsSection.pcss index 19ef46f79f2..b0388a1d7a9 100644 --- a/res/css/views/settings/tabs/_SettingsSection.pcss +++ b/res/css/views/settings/tabs/_SettingsSection.pcss @@ -1,5 +1,5 @@ /* -Copyright 2019, 2020 New Vector Ltd +Copyright 2023 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. From 77f046e6039eea882a24c855c98412ca003f64a0 Mon Sep 17 00:00:00 2001 From: Kerry Archibald Date: Fri, 28 Apr 2023 14:39:29 +1200 Subject: [PATCH 03/24] use semantic headings in GeneralRoomSettingsTab --- .../tabs/room/GeneralRoomSettingsTab.tsx | 54 ++++++++++--------- .../tabs/room/VoipRoomSettingsTab.tsx | 11 ++-- 2 files changed, 36 insertions(+), 29 deletions(-) diff --git a/src/components/views/settings/tabs/room/GeneralRoomSettingsTab.tsx b/src/components/views/settings/tabs/room/GeneralRoomSettingsTab.tsx index a915aa42e38..cc8db528a12 100644 --- a/src/components/views/settings/tabs/room/GeneralRoomSettingsTab.tsx +++ b/src/components/views/settings/tabs/room/GeneralRoomSettingsTab.tsx @@ -27,6 +27,9 @@ import { UIFeature } from "../../../../../settings/UIFeature"; import UrlPreviewSettings from "../../../room_settings/UrlPreviewSettings"; import AliasSettings from "../../../room_settings/AliasSettings"; import PosthogTrackers from "../../../../../PosthogTrackers"; +import SettingsSubsection from "../../shared/SettingsSubsection"; +import SettingsTab from "../SettingsTab"; +import { SettingsSection } from "../../shared/SettingsSection"; interface IProps { room: Room; @@ -72,35 +75,36 @@ export default class GeneralRoomSettingsTab extends React.Component - {_t("Leave room")} -
- - {_t("Leave room")} - -
- + + + {_t("Leave room")} + + ); } return ( -
-
{_t("General")}
-
- -
- -
{_t("Room Addresses")}
- -
{_t("Other")}
- {urlPreviewSettings} - {leaveSection} -
+ + +
+ +
+
+ + + + + + + {urlPreviewSettings} + {leaveSection} + +
); } } diff --git a/src/components/views/settings/tabs/room/VoipRoomSettingsTab.tsx b/src/components/views/settings/tabs/room/VoipRoomSettingsTab.tsx index f2749d8131d..94f89be331c 100644 --- a/src/components/views/settings/tabs/room/VoipRoomSettingsTab.tsx +++ b/src/components/views/settings/tabs/room/VoipRoomSettingsTab.tsx @@ -28,6 +28,7 @@ import SettingsTab from "../SettingsTab"; import { ElementCall } from "../../../../../models/Call"; import { useRoomState } from "../../../../../hooks/useRoomState"; import SdkConfig, { DEFAULTS } from "../../../../../SdkConfig"; +import { SettingsSection } from "../../shared/SettingsSection"; interface ElementCallSwitchProps { room: Room; @@ -100,10 +101,12 @@ interface Props { export const VoipRoomSettingsTab: React.FC = ({ room }) => { return ( - - - - + + + + + + ); }; From 2b251b4f5eadfe094c07de9ad61053d519992240 Mon Sep 17 00:00:00 2001 From: Kerry Archibald Date: Fri, 28 Apr 2023 15:14:21 +1200 Subject: [PATCH 04/24] use SettingsTab and SettingsSubsection in room settings --- res/css/views/settings/tabs/_SettingsTab.pcss | 2 +- .../tabs/room/_RolesRoomSettingsTab.pcss | 2 +- .../tabs/room/_SecurityRoomSettingsTab.pcss | 16 +- .../tabs/room/AdvancedRoomSettingsTab.tsx | 48 +-- .../settings/tabs/room/BridgeSettingsTab.tsx | 9 +- .../tabs/room/NotificationSettingsTab.tsx | 282 +++++++++--------- .../tabs/room/RolesRoomSettingsTab.tsx | 41 +-- .../tabs/room/SecurityRoomSettingsTab.tsx | 85 +++--- .../AdvancedRoomSettingsTab-test.tsx.snap | 100 ++++--- .../BridgeSettingsTab-test.tsx.snap | 178 ++++++----- .../RolesRoomSettingsTab-test.tsx.snap | 4 +- 11 files changed, 411 insertions(+), 356 deletions(-) diff --git a/res/css/views/settings/tabs/_SettingsTab.pcss b/res/css/views/settings/tabs/_SettingsTab.pcss index 4f240109c18..fac189e8587 100644 --- a/res/css/views/settings/tabs/_SettingsTab.pcss +++ b/res/css/views/settings/tabs/_SettingsTab.pcss @@ -103,5 +103,5 @@ limitations under the License. grid-template-columns: 1fr; grid-gap: $spacing-32; - padding: $spacing-16 0; + padding-bottom: $spacing-16; } diff --git a/res/css/views/settings/tabs/room/_RolesRoomSettingsTab.pcss b/res/css/views/settings/tabs/room/_RolesRoomSettingsTab.pcss index 5d0a8ed1423..ce8dff9f0c2 100644 --- a/res/css/views/settings/tabs/room/_RolesRoomSettingsTab.pcss +++ b/res/css/views/settings/tabs/room/_RolesRoomSettingsTab.pcss @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -.mx_RolesRoomSettingsTab ul { +.mx_RolesRoomSettingsTab_bannedList { margin-bottom: 0; } diff --git a/res/css/views/settings/tabs/room/_SecurityRoomSettingsTab.pcss b/res/css/views/settings/tabs/room/_SecurityRoomSettingsTab.pcss index cf3e16bc044..339b5d2590e 100644 --- a/res/css/views/settings/tabs/room/_SecurityRoomSettingsTab.pcss +++ b/res/css/views/settings/tabs/room/_SecurityRoomSettingsTab.pcss @@ -14,14 +14,12 @@ See the License for the specific language governing permissions and limitations under the License. */ -.mx_SecurityRoomSettingsTab { - .mx_SettingsTab_showAdvanced { - margin-bottom: $spacing-16; - } +.mx_SecurityRoomSettingsTab_advancedSection { + margin-top: $spacing-16; +} - .mx_SecurityRoomSettingsTab_warning { - display: flex; - align-items: center; - column-gap: $spacing-4; - } +.mx_SecurityRoomSettingsTab_warning { + display: flex; + align-items: center; + column-gap: $spacing-4; } diff --git a/src/components/views/settings/tabs/room/AdvancedRoomSettingsTab.tsx b/src/components/views/settings/tabs/room/AdvancedRoomSettingsTab.tsx index e8ce957c3b5..a7068ea1cfa 100644 --- a/src/components/views/settings/tabs/room/AdvancedRoomSettingsTab.tsx +++ b/src/components/views/settings/tabs/room/AdvancedRoomSettingsTab.tsx @@ -27,6 +27,9 @@ import { Action } from "../../../../../dispatcher/actions"; import CopyableText from "../../../elements/CopyableText"; import { ViewRoomPayload } from "../../../../../dispatcher/payloads/ViewRoomPayload"; import SettingsStore from "../../../../../settings/SettingsStore"; +import SettingsTab from "../SettingsTab"; +import { SettingsSection } from "../../shared/SettingsSection"; +import SettingsSubsection from "../../shared/SettingsSubsection"; interface IProps { room: Room; @@ -154,30 +157,27 @@ export default class AdvancedRoomSettingsTab extends React.Component -
{_t("Advanced")}
-
- - {room.isSpaceRoom() ? _t("Space information") : _t("Room information")} - -
- {_t("Internal room ID")} - this.props.room.roomId}> - {this.props.room.roomId} - -
- {unfederatableSection} -
-
- {_t("Room version")} -
- {_t("Room version:")}  - {room.getVersion()} -
- {oldRoomLink} - {roomUpgradeButton} -
-
+ + + +
+ {_t("Internal room ID")} + this.props.room.roomId}> + {this.props.room.roomId} + +
+ {unfederatableSection} +
+ +
+ {_t("Room version:")}  + {room.getVersion()} +
+ {oldRoomLink} + {roomUpgradeButton} +
+
+
); } } diff --git a/src/components/views/settings/tabs/room/BridgeSettingsTab.tsx b/src/components/views/settings/tabs/room/BridgeSettingsTab.tsx index 8731cee0a6a..04b75cb4cc6 100644 --- a/src/components/views/settings/tabs/room/BridgeSettingsTab.tsx +++ b/src/components/views/settings/tabs/room/BridgeSettingsTab.tsx @@ -21,6 +21,8 @@ import { MatrixEvent } from "matrix-js-sdk/src/models/event"; import { _t } from "../../../../../languageHandler"; import { MatrixClientPeg } from "../../../../../MatrixClientPeg"; import BridgeTile from "../../BridgeTile"; +import SettingsTab from "../SettingsTab"; +import { SettingsSection } from "../../shared/SettingsSection"; const BRIDGE_EVENT_TYPES = [ "uk.half-shot.bridge", @@ -99,10 +101,9 @@ export default class BridgeSettingsTab extends React.Component { } return ( -
-
{_t("Bridges")}
-
{content}
-
+ + {content} + ); } } diff --git a/src/components/views/settings/tabs/room/NotificationSettingsTab.tsx b/src/components/views/settings/tabs/room/NotificationSettingsTab.tsx index d8232210fa8..f1304d44ed7 100644 --- a/src/components/views/settings/tabs/room/NotificationSettingsTab.tsx +++ b/src/components/views/settings/tabs/room/NotificationSettingsTab.tsx @@ -32,6 +32,9 @@ import defaultDispatcher from "../../../../../dispatcher/dispatcher"; import { Action } from "../../../../../dispatcher/actions"; import { UserTab } from "../../../dialogs/UserTab"; import { chromeFileInputFix } from "../../../../../utils/BrowserWorkarounds"; +import SettingsTab from "../SettingsTab"; +import { SettingsSection } from "../../shared/SettingsSection"; +import SettingsSubsection from "../../shared/SettingsSubsection"; interface IProps { roomId: string; @@ -168,149 +171,148 @@ export default class NotificationsSettingsTab extends React.Component -
{_t("Notifications")}
- -
- - {_t("Default")} -
- {_t( - "Get notifications as set up in your settings", - {}, - { - a: (sub) => ( - - {sub} - - ), - }, - )} -
- - ), - }, - { - value: RoomNotifState.AllMessagesLoud, - className: "mx_NotificationSettingsTab_allMessagesEntry", - label: ( - <> - {_t("All messages")} -
- {_t("Get notified for every message")} -
- - ), - }, - { - value: RoomNotifState.MentionsOnly, - className: "mx_NotificationSettingsTab_mentionsKeywordsEntry", - label: ( - <> - {_t("@mentions & keywords")} -
- {_t( - "Get notified only with mentions and keywords " + - "as set up in your settings", - {}, - { - a: (sub) => ( - - {sub} - - ), - }, - )} -
- - ), - }, - { - value: RoomNotifState.Mute, - className: "mx_NotificationSettingsTab_noneEntry", - label: ( - <> - {_t("Off")} -
- {_t("You won't get any notifications")} -
- - ), - }, - ]} - onChange={this.onRoomNotificationChange} - value={this.roomProps.notificationVolume} - /> -
+ + +
+ + {_t("Default")} +
+ {_t( + "Get notifications as set up in your settings", + {}, + { + a: (sub) => ( + + {sub} + + ), + }, + )} +
+ + ), + }, + { + value: RoomNotifState.AllMessagesLoud, + className: "mx_NotificationSettingsTab_allMessagesEntry", + label: ( + <> + {_t("All messages")} +
+ {_t("Get notified for every message")} +
+ + ), + }, + { + value: RoomNotifState.MentionsOnly, + className: "mx_NotificationSettingsTab_mentionsKeywordsEntry", + label: ( + <> + {_t("@mentions & keywords")} +
+ {_t( + "Get notified only with mentions and keywords " + + "as set up in your settings", + {}, + { + a: (sub) => ( + + {sub} + + ), + }, + )} +
+ + ), + }, + { + value: RoomNotifState.Mute, + className: "mx_NotificationSettingsTab_noneEntry", + label: ( + <> + {_t("Off")} +
+ {_t("You won't get any notifications")} +
+ + ), + }, + ]} + onChange={this.onRoomNotificationChange} + value={this.roomProps.notificationVolume} + /> +
-
- {_t("Sounds")} -
-
- - {_t("Notification sound")}: {this.state.currentSound} - + +
+
+ + {_t("Notification sound")}: {this.state.currentSound} + +
+ + {_t("Reset")} +
- - {_t("Reset")} - -
-
-

{_t("Set a new custom sound")}

-
-
- -
- - {currentUploadedFile} +
+

{_t("Set a new custom sound")}

+
+
+ +
+ + {currentUploadedFile} +
+ + + {_t("Browse")} + + + + {_t("Save")} + +
- - - {_t("Browse")} - - - - {_t("Save")} - -
-
-
-
+ + + ); } } diff --git a/src/components/views/settings/tabs/room/RolesRoomSettingsTab.tsx b/src/components/views/settings/tabs/room/RolesRoomSettingsTab.tsx index 3f2c6d65fe0..0ed44cf173c 100644 --- a/src/components/views/settings/tabs/room/RolesRoomSettingsTab.tsx +++ b/src/components/views/settings/tabs/room/RolesRoomSettingsTab.tsx @@ -36,6 +36,8 @@ import { VoiceBroadcastInfoEventType } from "../../../../../voice-broadcast"; import { ElementCall } from "../../../../../models/Call"; import SdkConfig, { DEFAULTS } from "../../../../../SdkConfig"; import { AddPrivilegedUsers } from "../../AddPrivilegedUsers"; +import SettingsTab from "../SettingsTab"; +import { SettingsSection } from "../../shared/SettingsSection"; interface IEventShowOpts { isState?: boolean; @@ -399,7 +401,7 @@ export default class RolesRoomSettingsTab extends React.Component { const canBanUsers = currentUserLevel >= banLevel; bannedUsersSection = ( -
    +
      {banned.map((member) => { const banEvent = member.events.member?.getContent(); const bannedById = member.events.member?.getSender(); @@ -479,24 +481,25 @@ export default class RolesRoomSettingsTab extends React.Component { .filter(Boolean); return ( -
      -
      {_t("Roles & Permissions")}
      - {privilegedUsersSection} - {canChangeLevels && } - {mutedUsersSection} - {bannedUsersSection} - - {powerSelectors} - {eventPowerSelectors} - -
      + + + {privilegedUsersSection} + {canChangeLevels && } + {mutedUsersSection} + {bannedUsersSection} + + {powerSelectors} + {eventPowerSelectors} + + + ); } } diff --git a/src/components/views/settings/tabs/room/SecurityRoomSettingsTab.tsx b/src/components/views/settings/tabs/room/SecurityRoomSettingsTab.tsx index aad1535505a..71afe65d98b 100644 --- a/src/components/views/settings/tabs/room/SecurityRoomSettingsTab.tsx +++ b/src/components/views/settings/tabs/room/SecurityRoomSettingsTab.tsx @@ -41,6 +41,8 @@ import SettingsFieldset from "../../SettingsFieldset"; import ExternalLink from "../../../elements/ExternalLink"; import PosthogTrackers from "../../../../../PosthogTrackers"; import MatrixClientContext from "../../../../../contexts/MatrixClientContext"; +import { SettingsSection } from "../../shared/SettingsSection"; +import SettingsTab from "../SettingsTab"; interface IProps { room: Room; @@ -265,6 +267,23 @@ export default class SecurityRoomSettingsTab extends React.Component + + {this.state.showAdvancedSection ? _t("Hide advanced") : _t("Show advanced")} + + {this.state.showAdvancedSection && this.renderAdvanced()} +
+ ); + } + return ( + {advanced} ); } @@ -399,7 +419,7 @@ export default class SecurityRoomSettingsTab extends React.Component +
- +
); } @@ -437,45 +457,30 @@ export default class SecurityRoomSettingsTab extends React.Component - - {this.state.showAdvancedSection ? _t("Hide advanced") : _t("Show advanced")} - - {this.state.showAdvancedSection && this.renderAdvanced()} -
- ); - } - return ( -
-
{_t("Security & Privacy")}
- - - - {encryptionSettings} - - - {this.renderJoinRule()} - - {advanced} - {historySection} -
+ + + + + {encryptionSettings} + + + {this.renderJoinRule()} + {historySection} + + + //
+ //
{_t("Security & Privacy")}
+ + //
); } } diff --git a/test/components/views/settings/tabs/room/__snapshots__/AdvancedRoomSettingsTab-test.tsx.snap b/test/components/views/settings/tabs/room/__snapshots__/AdvancedRoomSettingsTab-test.tsx.snap index fa0aa0338e9..f8ec32b7f3a 100644 --- a/test/components/views/settings/tabs/room/__snapshots__/AdvancedRoomSettingsTab-test.tsx.snap +++ b/test/components/views/settings/tabs/room/__snapshots__/AdvancedRoomSettingsTab-test.tsx.snap @@ -6,50 +6,78 @@ exports[`AdvancedRoomSettingsTab should render as expected 1`] = ` class="mx_SettingsTab" >
- Advanced -
-
- - Room information - -
- - Internal room ID - +

+ Advanced +

- !room:example.com
+ class="mx_SettingsSubsection" + > +
+

+ Room information +

+
+
+
+ + Internal room ID + +
+ !room:example.com +
+
+
+
+
+
+
+

+ Room version +

+
+
+
+ + Room version: + +  1 +
+
+
-
- - Room version - -
- - Room version: - -  1 -
-
`; diff --git a/test/components/views/settings/tabs/room/__snapshots__/BridgeSettingsTab-test.tsx.snap b/test/components/views/settings/tabs/room/__snapshots__/BridgeSettingsTab-test.tsx.snap index c38e07d15f8..ed78d3834cb 100644 --- a/test/components/views/settings/tabs/room/__snapshots__/BridgeSettingsTab-test.tsx.snap +++ b/test/components/views/settings/tabs/room/__snapshots__/BridgeSettingsTab-test.tsx.snap @@ -6,75 +6,83 @@ exports[` renders when room is bridging messages 1`] = ` class="mx_SettingsTab" >
- Bridges -
-
-
-

- - This room is bridging messages to the following platforms. - - Learn more. - - -

-
    +

    -
  • -
    -
    -
    -
    +
    +
    +

    + + This room is bridging messages to the following platforms. + + Learn more. + + +

    +
      -

      - protocol-test -

      -

      - +

      +
      +
      - - Channel: - - channel-test +

      + protocol-test +

      +

      + + + Channel: + + channel-test + + - - -

      - -
      - -
    +

    + +
    +
  • +

+
+
@@ -87,25 +95,33 @@ exports[` renders when room is not bridging messages to any class="mx_SettingsTab" >
- Bridges -
-
-

- - This room isn't bridging messages to any platforms. - - Learn more. - - -

+
+

+ Bridges +

+
+

+ + This room isn't bridging messages to any platforms. + + Learn more. + + +

+
+
diff --git a/test/components/views/settings/tabs/room/__snapshots__/RolesRoomSettingsTab-test.tsx.snap b/test/components/views/settings/tabs/room/__snapshots__/RolesRoomSettingsTab-test.tsx.snap index d771a152d2a..aea48398946 100644 --- a/test/components/views/settings/tabs/room/__snapshots__/RolesRoomSettingsTab-test.tsx.snap +++ b/test/components/views/settings/tabs/room/__snapshots__/RolesRoomSettingsTab-test.tsx.snap @@ -9,7 +9,9 @@ exports[`RolesRoomSettingsTab Banned users renders banned users 1`] = ` > Banned users -
    +
    • Date: Fri, 28 Apr 2023 17:05:16 +1200 Subject: [PATCH 05/24] fix VoipRoomSettingsTab --- .../views/settings/tabs/room/VoipRoomSettingsTab.tsx | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/components/views/settings/tabs/room/VoipRoomSettingsTab.tsx b/src/components/views/settings/tabs/room/VoipRoomSettingsTab.tsx index f2749d8131d..94f89be331c 100644 --- a/src/components/views/settings/tabs/room/VoipRoomSettingsTab.tsx +++ b/src/components/views/settings/tabs/room/VoipRoomSettingsTab.tsx @@ -28,6 +28,7 @@ import SettingsTab from "../SettingsTab"; import { ElementCall } from "../../../../../models/Call"; import { useRoomState } from "../../../../../hooks/useRoomState"; import SdkConfig, { DEFAULTS } from "../../../../../SdkConfig"; +import { SettingsSection } from "../../shared/SettingsSection"; interface ElementCallSwitchProps { room: Room; @@ -100,10 +101,12 @@ interface Props { export const VoipRoomSettingsTab: React.FC = ({ room }) => { return ( - - - - + + + + + + ); }; From 7354c05aa937598519e02991d32308e290c77279 Mon Sep 17 00:00:00 2001 From: Kerry Archibald Date: Mon, 1 May 2023 14:27:30 +1200 Subject: [PATCH 06/24] use SettingsSection components in space settings --- res/css/_components.pcss | 1 - .../views/room_settings/_AliasSettings.pcss | 24 +- .../tabs/room/_GeneralRoomSettingsTab.pcss | 19 -- .../views/room_settings/AliasSettings.tsx | 19 +- .../tabs/room/GeneralRoomSettingsTab.tsx | 4 +- .../views/spaces/SpaceSettingsGeneralTab.tsx | 90 ++++---- .../spaces/SpaceSettingsVisibilityTab.tsx | 87 ++++---- .../SpaceSettingsVisibilityTab-test.tsx.snap | 210 +++++++++--------- 8 files changed, 218 insertions(+), 236 deletions(-) delete mode 100644 res/css/views/settings/tabs/room/_GeneralRoomSettingsTab.pcss diff --git a/res/css/_components.pcss b/res/css/_components.pcss index f200429ced3..94153b2e894 100644 --- a/res/css/_components.pcss +++ b/res/css/_components.pcss @@ -341,7 +341,6 @@ @import "./views/settings/_UpdateCheckButton.pcss"; @import "./views/settings/tabs/_SettingsSection.pcss"; @import "./views/settings/tabs/_SettingsTab.pcss"; -@import "./views/settings/tabs/room/_GeneralRoomSettingsTab.pcss"; @import "./views/settings/tabs/room/_NotificationSettingsTab.pcss"; @import "./views/settings/tabs/room/_RolesRoomSettingsTab.pcss"; @import "./views/settings/tabs/room/_SecurityRoomSettingsTab.pcss"; diff --git a/res/css/views/room_settings/_AliasSettings.pcss b/res/css/views/room_settings/_AliasSettings.pcss index 66ac17d8422..15a7b8a8708 100644 --- a/res/css/views/room_settings/_AliasSettings.pcss +++ b/res/css/views/room_settings/_AliasSettings.pcss @@ -27,20 +27,14 @@ limitations under the License. box-shadow: none; } -.mx_AliasSettings { - summary { - cursor: pointer; - color: $accent; - font-weight: var(--font-semi-bold); - list-style: none; - - /* list-style doesn't do it for webkit */ - &::-webkit-details-marker { - display: none; - } - } - - .mx_AliasSettings_localAliasHeader { - margin-top: 35px; +.mx_AliasSettings_localAddresses { + cursor: pointer; + color: $accent; + font-weight: var(--font-semi-bold); + list-style: none; + + /* list-style doesn't do it for webkit */ + &::-webkit-details-marker { + display: none; } } diff --git a/res/css/views/settings/tabs/room/_GeneralRoomSettingsTab.pcss b/res/css/views/settings/tabs/room/_GeneralRoomSettingsTab.pcss deleted file mode 100644 index af55820d665..00000000000 --- a/res/css/views/settings/tabs/room/_GeneralRoomSettingsTab.pcss +++ /dev/null @@ -1,19 +0,0 @@ -/* -Copyright 2019 New Vector Ltd - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -.mx_GeneralRoomSettingsTab_profileSection { - margin-top: 10px; -} diff --git a/src/components/views/room_settings/AliasSettings.tsx b/src/components/views/room_settings/AliasSettings.tsx index 16388953afd..f6a6f32e4fb 100644 --- a/src/components/views/room_settings/AliasSettings.tsx +++ b/src/components/views/room_settings/AliasSettings.tsx @@ -1,5 +1,5 @@ /* -Copyright 2016 - 2021 The Matrix.org Foundation C.I.C. +Copyright 2016 - 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. @@ -402,7 +402,7 @@ export default class AliasSettings extends React.Component { } return ( -
      + <> { } > - {/* - { _t("Published Addresses") } -

      - { isSpaceRoom - ? _t("Published addresses can be used by anyone on any server to join your space.") - : _t("Published addresses can be used by anyone on any server to join your room.") } -   - { _t("To publish an address, it needs to be set as a local address first.") } -

      */} {canonicalAliasSection} {this.props.hidePublishSetting ? null : ( { } >
      - {this.state.detailsOpen ? _t("Show less") : _t("Show more")} + + {this.state.detailsOpen ? _t("Show less") : _t("Show more")} + {localAliasesList}
      -
      + ); } } diff --git a/src/components/views/settings/tabs/room/GeneralRoomSettingsTab.tsx b/src/components/views/settings/tabs/room/GeneralRoomSettingsTab.tsx index cc8db528a12..631af29fa22 100644 --- a/src/components/views/settings/tabs/room/GeneralRoomSettingsTab.tsx +++ b/src/components/views/settings/tabs/room/GeneralRoomSettingsTab.tsx @@ -86,9 +86,7 @@ export default class GeneralRoomSettingsTab extends React.Component -
      - -
      +
      diff --git a/src/components/views/spaces/SpaceSettingsGeneralTab.tsx b/src/components/views/spaces/SpaceSettingsGeneralTab.tsx index 329a580b798..78803490644 100644 --- a/src/components/views/spaces/SpaceSettingsGeneralTab.tsx +++ b/src/components/views/spaces/SpaceSettingsGeneralTab.tsx @@ -27,6 +27,9 @@ import { avatarUrlForRoom } from "../../../Avatar"; import { htmlSerializeFromMdIfNeeded } from "../../../editor/serialize"; import { leaveSpace } from "../../../utils/leave-behaviour"; import { getTopic } from "../../../hooks/room/useTopic"; +import SettingsTab from "../settings/tabs/SettingsTab"; +import { SettingsSection } from "../settings/shared/SettingsSection"; +import SettingsSubsection from "../settings/shared/SettingsSubsection"; interface IProps { matrixClient: MatrixClient; @@ -94,50 +97,49 @@ const SpaceSettingsGeneralTab: React.FC = ({ matrixClient: cli, space }) }; return ( -
      -
      {_t("General")}
      - -
      {_t("Edit settings relating to your space.")}
      - - {error &&
      {error}
      } - -
      - - - - {_t("Cancel")} - - - {busy ? _t("Saving…") : _t("Save Changes")} - -
      - - {_t("Leave Space")} -
      - { - leaveSpace(space); - }} - > - {_t("Leave Space")} - -
      -
      + + +
      +
      {_t("Edit settings relating to your space.")}
      + + {error &&
      {error}
      } + + + + + {_t("Cancel")} + + + {busy ? _t("Saving…") : _t("Save Changes")} + +
      + + + { + leaveSpace(space); + }} + > + {_t("Leave Space")} + + +
      +
      ); }; diff --git a/src/components/views/spaces/SpaceSettingsVisibilityTab.tsx b/src/components/views/spaces/SpaceSettingsVisibilityTab.tsx index 368d6c96fc0..d94bc52ee53 100644 --- a/src/components/views/spaces/SpaceSettingsVisibilityTab.tsx +++ b/src/components/views/spaces/SpaceSettingsVisibilityTab.tsx @@ -1,5 +1,5 @@ /* -Copyright 2021 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. @@ -30,6 +30,8 @@ import JoinRuleSettings from "../settings/JoinRuleSettings"; import { useRoomState } from "../../../hooks/useRoomState"; import SettingsFieldset from "../settings/SettingsFieldset"; import { useAsyncMemo } from "../../../hooks/useAsyncMemo"; +import { SettingsSection } from "../settings/shared/SettingsSection"; +import SettingsTab from "../settings/tabs/SettingsTab"; interface IProps { matrixClient: MatrixClient; @@ -124,8 +126,7 @@ const SpaceSettingsVisibilityTab: React.FC = ({ matrixClient: cli, space let addressesSection: JSX.Element | undefined; if (space.getJoinRule() === JoinRule.Public) { addressesSection = ( - <> - {_t("Address")} + = ({ matrixClient: cli, space canonicalAliasEvent={canonicalAliasEv ?? undefined} hidePublishSetting={!serverSupportsExploringSpaces} /> - + ); } return ( -
      -
      {_t("Visibility")}
      - - {error && ( -
      - {error} -
      - )} - - - setError(_t("Failed to update the visibility of this space"))} - closeSettingsFn={closeSettingsFn} - /> - {advancedSection} -
      - { - setHistoryVisibility(checked ? HistoryVisibility.WorldReadable : HistoryVisibility.Shared); - }} - disabled={!canSetHistoryVisibility} - label={_t("Preview Space")} + + + {error && ( +
      + {error} +
      + )} + + + setError(_t("Failed to update the visibility of this space"))} + closeSettingsFn={closeSettingsFn} /> -

      - {_t("Allow people to preview your space before they join.")} -
      - {_t("Recommended for public spaces.")} -

      -
      -
      - - {addressesSection} -
      + {advancedSection} +
      + { + setHistoryVisibility( + checked ? HistoryVisibility.WorldReadable : HistoryVisibility.Shared, + ); + }} + disabled={!canSetHistoryVisibility} + label={_t("Preview Space")} + /> +

      + {_t("Allow people to preview your space before they join.")} +
      + {_t("Recommended for public spaces.")} +

      +
      + + + {addressesSection} +
      +
      ); }; diff --git a/test/components/views/spaces/__snapshots__/SpaceSettingsVisibilityTab-test.tsx.snap b/test/components/views/spaces/__snapshots__/SpaceSettingsVisibilityTab-test.tsx.snap index a93fda9d6a5..34d9f5c9313 100644 --- a/test/components/views/spaces/__snapshots__/SpaceSettingsVisibilityTab-test.tsx.snap +++ b/test/components/views/spaces/__snapshots__/SpaceSettingsVisibilityTab-test.tsx.snap @@ -21,118 +21,130 @@ exports[` renders container 1`] = ` class="mx_SettingsTab" >
      - Visibility -
      -
      - - Access -
      - Decide who can view and join mock-space. -
      -
      -

      - Allow people to preview your space before they join. -
      - - Recommended for public spaces. - -

      - + `; From 0d0aed5a710ed5026038818ee175313d0a760d8f Mon Sep 17 00:00:00 2001 From: Kerry Archibald Date: Mon, 1 May 2023 16:07:37 +1200 Subject: [PATCH 07/24] settingssubsection text component --- .../views/settings/shared/_SettingsSubsection.pcss | 2 +- .../views/settings/shared/SettingsSubsection.tsx | 8 ++++++-- .../__snapshots__/SecurityRecommendations-test.tsx.snap | 6 +++--- .../shared/__snapshots__/SettingsSubsection-test.tsx.snap | 4 ++-- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/res/css/components/views/settings/shared/_SettingsSubsection.pcss b/res/css/components/views/settings/shared/_SettingsSubsection.pcss index a2b3cd35bfa..2481452bf1a 100644 --- a/res/css/components/views/settings/shared/_SettingsSubsection.pcss +++ b/res/css/components/views/settings/shared/_SettingsSubsection.pcss @@ -19,7 +19,7 @@ limitations under the License. box-sizing: border-box; } -.mx_SettingsSubsection_description { +.mx_SettingsSubsection_text { width: 100%; box-sizing: inherit; line-height: $font-24px; diff --git a/src/components/views/settings/shared/SettingsSubsection.tsx b/src/components/views/settings/shared/SettingsSubsection.tsx index 0e78bf47505..64384d7e392 100644 --- a/src/components/views/settings/shared/SettingsSubsection.tsx +++ b/src/components/views/settings/shared/SettingsSubsection.tsx @@ -24,10 +24,14 @@ export interface SettingsSubsectionProps extends HTMLAttributes children?: React.ReactNode; } -const SettingsSubsection: React.FC = ({ heading, description, children, ...rest }) => ( +export const SettingsSubsectionText: React.FC> = ({ children, ...rest }) => ( +
      {children}
      +) + +export const SettingsSubsection: React.FC = ({ heading, description, children, ...rest }) => (
      {typeof heading === "string" ? : <>{heading}} - {!!description &&
      {description}
      } + {!!description && {description}}
      {children}
      ); diff --git a/test/components/views/settings/devices/__snapshots__/SecurityRecommendations-test.tsx.snap b/test/components/views/settings/devices/__snapshots__/SecurityRecommendations-test.tsx.snap index 011d926b1dd..6cefc1c2df0 100644 --- a/test/components/views/settings/devices/__snapshots__/SecurityRecommendations-test.tsx.snap +++ b/test/components/views/settings/devices/__snapshots__/SecurityRecommendations-test.tsx.snap @@ -16,7 +16,7 @@ exports[` renders both cards when user has both unver
      Improve your account security by following these recommendations.
      @@ -137,7 +137,7 @@ exports[` renders inactive devices section when user
      Improve your account security by following these recommendations.
      @@ -258,7 +258,7 @@ exports[` renders unverified devices section when use
      Improve your account security by following these recommendations.
      diff --git a/test/components/views/settings/shared/__snapshots__/SettingsSubsection-test.tsx.snap b/test/components/views/settings/shared/__snapshots__/SettingsSubsection-test.tsx.snap index 130b825d65f..f5394ec2b6a 100644 --- a/test/components/views/settings/shared/__snapshots__/SettingsSubsection-test.tsx.snap +++ b/test/components/views/settings/shared/__snapshots__/SettingsSubsection-test.tsx.snap @@ -15,7 +15,7 @@ exports[` renders with plain text description 1`] = `
      This describes the subsection
      @@ -70,7 +70,7 @@ exports[` renders with react element description 1`] = `

      This describes the section From 8086361d72fb6605147a0f61e6cf406b2169be3b Mon Sep 17 00:00:00 2001 From: Kerry Archibald Date: Mon, 1 May 2023 17:00:50 +1200 Subject: [PATCH 08/24] use semantic headings in HelpUserSetttings tab --- .../settings/shared/_SettingsSubsection.pcss | 21 +- .../shared/_SettingsSubsectionHeading.pcss | 1 - .../settings/shared/SettingsSubsection.tsx | 12 +- .../tabs/user/HelpUserSettingsTab.tsx | 357 +++++++++--------- .../views/dialogs/UserSettingsDialog-test.tsx | 6 +- .../SecurityRecommendations-test.tsx.snap | 24 +- .../SettingsSubsection-test.tsx.snap | 30 +- 7 files changed, 239 insertions(+), 212 deletions(-) diff --git a/res/css/components/views/settings/shared/_SettingsSubsection.pcss b/res/css/components/views/settings/shared/_SettingsSubsection.pcss index 2481452bf1a..e90585122b5 100644 --- a/res/css/components/views/settings/shared/_SettingsSubsection.pcss +++ b/res/css/components/views/settings/shared/_SettingsSubsection.pcss @@ -19,14 +19,31 @@ limitations under the License. box-sizing: border-box; } +.mx_SettingsSubsection_description { + margin-top: $spacing-8; +} + .mx_SettingsSubsection_text { width: 100%; box-sizing: inherit; - line-height: $font-24px; - margin-bottom: $spacing-24; + font-size: $font-15px; color: $secondary-content; } .mx_SettingsSubsection_content { width: 100%; + display: grid; + grid-gap: $spacing-8; + grid-template-columns: 1fr; + justify-items: flex-start; + margin-top: $spacing-24; + + summary { + color: $accent; + } + details[open] { + summary { + margin-bottom: $spacing-8; + } + } } diff --git a/res/css/components/views/settings/shared/_SettingsSubsectionHeading.pcss b/res/css/components/views/settings/shared/_SettingsSubsectionHeading.pcss index e6d4bf4be7c..00bcb4abc21 100644 --- a/res/css/components/views/settings/shared/_SettingsSubsectionHeading.pcss +++ b/res/css/components/views/settings/shared/_SettingsSubsectionHeading.pcss @@ -17,7 +17,6 @@ limitations under the License. .mx_SettingsSubsectionHeading { display: flex; flex-direction: row; - padding-bottom: $spacing-8; gap: $spacing-8; } diff --git a/src/components/views/settings/shared/SettingsSubsection.tsx b/src/components/views/settings/shared/SettingsSubsection.tsx index 64384d7e392..8fcdf327a9a 100644 --- a/src/components/views/settings/shared/SettingsSubsection.tsx +++ b/src/components/views/settings/shared/SettingsSubsection.tsx @@ -25,13 +25,19 @@ export interface SettingsSubsectionProps extends HTMLAttributes } export const SettingsSubsectionText: React.FC> = ({ children, ...rest }) => ( -

      {children}
      -) +
      + {children} +
      +); export const SettingsSubsection: React.FC = ({ heading, description, children, ...rest }) => (
      {typeof heading === "string" ? : <>{heading}} - {!!description && {description}} + {!!description && ( +
      + {description} +
      + )}
      {children}
      ); diff --git a/src/components/views/settings/tabs/user/HelpUserSettingsTab.tsx b/src/components/views/settings/tabs/user/HelpUserSettingsTab.tsx index f939cba64cc..b29ee4033a3 100644 --- a/src/components/views/settings/tabs/user/HelpUserSettingsTab.tsx +++ b/src/components/views/settings/tabs/user/HelpUserSettingsTab.tsx @@ -31,6 +31,10 @@ import { Action } from "../../../../../dispatcher/actions"; import { UserTab } from "../../../dialogs/UserTab"; import dis from "../../../../../dispatcher/dispatcher"; import CopyableText from "../../../elements/CopyableText"; +import SettingsTab from "../SettingsTab"; +import { SettingsSection } from "../../shared/SettingsSection"; +import SettingsSubsection, { SettingsSubsectionText } from "../../shared/SettingsSubsection"; +import ExternalLink from "../../../elements/ExternalLink"; interface IProps { closeSettingsFn: () => void; @@ -114,18 +118,15 @@ export default class HelpUserSettingsTab extends React.Component for (const tocEntry of tocLinks) { legalLinks.push(
      - - {tocEntry.text} - + {tocEntry.text}
      , ); } return ( -
      - {_t("Legal")} -
      {legalLinks}
      -
      + + {legalLinks} + ); } @@ -133,104 +134,95 @@ export default class HelpUserSettingsTab extends React.Component // Note: This is not translated because it is legal text. // Also,   is ugly but necessary. return ( -
      - {_t("Credits")} -
        -
      • - {_t( - "The default cover photo is © " + - "Jesús Roncero used under the terms of CC-BY-SA 4.0.", - {}, - { - photo: (sub) => ( - - {sub} - - ), - author: (sub) => ( - - {sub} - - ), - terms: (sub) => ( - - {sub} - - ), - }, - )} -
      • -
      • - {_t( - "The twemoji-colr font is © Mozilla Foundation " + - "used under the terms of Apache 2.0.", - {}, - { - colr: (sub) => ( - - {sub} - - ), - author: (sub) => ( - - {sub} - - ), - terms: (sub) => ( - - {sub} - - ), - }, - )} -
      • -
      • - {_t( - "The Twemoji emoji art is © " + - "Twitter, Inc and other contributors used under the terms of " + - "CC-BY 4.0.", - {}, - { - twemoji: (sub) => ( - - {sub} - - ), - author: (sub) => ( - - {sub} - - ), - terms: (sub) => ( - - {sub} - - ), - }, - )} -
      • -
      -
      + + +
        +
      • + {_t( + "The default cover photo is © " + + "Jesús Roncero used under the terms of CC-BY-SA 4.0.", + {}, + { + photo: (sub) => ( + + {sub} + + ), + author: (sub) => ( + {sub} + ), + terms: (sub) => ( + + {sub} + + ), + }, + )} +
      • +
      • + {_t( + "The twemoji-colr font is © Mozilla Foundation " + + "used under the terms of Apache 2.0.", + {}, + { + colr: (sub) => ( + + {sub} + + ), + author: (sub) => {sub}, + terms: (sub) => ( + + {sub} + + ), + }, + )} +
      • +
      • + {_t( + "The Twemoji emoji art is © " + + "Twitter, Inc and other contributors used under the terms of " + + "CC-BY 4.0.", + {}, + { + twemoji: (sub) => ( + {sub} + ), + author: (sub) => ( + {sub} + ), + terms: (sub) => ( + + {sub} + + ), + }, + )} +
      • +
      +
      +
      ); } @@ -255,11 +247,7 @@ export default class HelpUserSettingsTab extends React.Component brand, }, { - a: (sub) => ( - - {sub} - - ), + a: (sub) => {sub}, }, ); if (SdkConfig.get("welcome_user_id") && getCurrentLanguage().startsWith("en")) { @@ -272,11 +260,7 @@ export default class HelpUserSettingsTab extends React.Component brand, }, { - a: (sub) => ( - - {sub} - - ), + a: (sub) => {sub}, }, )}
      @@ -296,77 +280,73 @@ export default class HelpUserSettingsTab extends React.Component let bugReportingSection; if (SdkConfig.get().bug_report_endpoint_url) { bugReportingSection = ( -
      - {_t("Bug reporting")} -
      - {_t( - "If you've submitted a bug via GitHub, debug logs can help " + - "us track down the problem. ", - )} - {_t( - "Debug logs contain application " + - "usage data including your username, the IDs or aliases of " + - "the rooms you have visited, which UI elements you " + - "last interacted with, and the usernames of other users. " + - "They do not contain messages.", - )} -
      + + + {_t( + "If you've submitted a bug via GitHub, debug logs can help " + + "us track down the problem. ", + )} + + {_t( + "Debug logs contain application " + + "usage data including your username, the IDs or aliases of " + + "the rooms you have visited, which UI elements you " + + "last interacted with, and the usernames of other users. " + + "They do not contain messages.", + )} + + } + > {_t("Submit debug logs")} -
      + {_t( "To report a Matrix-related security issue, please read the Matrix.org " + "Security Disclosure Policy.", {}, { a: (sub) => ( - + {sub} - + ), }, )} -
      -
      + + ); } const { appVersion, olmVersion } = this.getVersionInfo(); return ( -
      -
      {_t("Help & About")}
      - {bugReportingSection} -
      - {_t("FAQ")} -
      {faqText}
      - - {_t("Keyboard Shortcuts")} - -
      -
      - {_t("Versions")} -
      - - {appVersion} -
      - {olmVersion} -
      -
      - {updateButton} -
      -
      - {this.renderLegal()} - {this.renderCredits()} -
      - {_t("Advanced")} -
      -
      + + + {bugReportingSection} + + + {_t("Keyboard Shortcuts")} + + + + + + {appVersion} +
      + {olmVersion} +
      +
      + {updateButton} +
      +
      + {this.renderLegal()} + {this.renderCredits()} + + {_t( "Homeserver is %(homeserverUrl)s", { @@ -376,10 +356,10 @@ export default class HelpUserSettingsTab extends React.Component code: (sub) => {sub}, }, )} -
      -
      - {MatrixClientPeg.get().getIdentityServerUrl() && - _t( + + {MatrixClientPeg.get().getIdentityServerUrl() && ( + + {_t( "Identity server is %(identityServerUrl)s", { identityServerUrl: MatrixClientPeg.get().getIdentityServerUrl(), @@ -388,25 +368,28 @@ export default class HelpUserSettingsTab extends React.Component code: (sub) => {sub}, }, )} -
      -
      - {_t("Access Token")} - - {_t( - "Your access token gives full access to your account." + - " Do not share it with anyone.", - )} - - MatrixClientPeg.get().getAccessToken()}> - {MatrixClientPeg.get().getAccessToken()} - -
      + + )} + +
      + {_t("Access Token")} + + {_t( + "Your access token gives full access to your account." + + " Do not share it with anyone.", + )} + + MatrixClientPeg.get().getAccessToken()}> + {MatrixClientPeg.get().getAccessToken()} + +
      +
      {_t("Clear cache and reload")} -
      -
      -
      + + + ); } } diff --git a/test/components/views/dialogs/UserSettingsDialog-test.tsx b/test/components/views/dialogs/UserSettingsDialog-test.tsx index b5f04c7b787..c5e831c3947 100644 --- a/test/components/views/dialogs/UserSettingsDialog-test.tsx +++ b/test/components/views/dialogs/UserSettingsDialog-test.tsx @@ -15,7 +15,7 @@ limitations under the License. */ import React, { ReactElement } from "react"; -import { render } from "@testing-library/react"; +import { render, screen } from "@testing-library/react"; import { mocked } from "jest-mock"; import SettingsStore, { CallbackFn } from "../../../../src/settings/SettingsStore"; @@ -74,7 +74,9 @@ describe("", () => { const getActiveTabLabel = (container: Element) => container.querySelector(".mx_TabbedView_tabLabel_active")?.textContent; - const getActiveTabHeading = (container: Element) => container.querySelector(".mx_SettingsTab_heading")?.textContent; + const getActiveTabHeading = (container: Element) => + container.querySelector(".mx_SettingsTab_heading")?.textContent || + container.querySelector(".mx_SettingsSection .mx_Heading_h2")?.textContent; it("should render general settings tab when no initialTabId", () => { const { container } = render(getComponent()); diff --git a/test/components/views/settings/devices/__snapshots__/SecurityRecommendations-test.tsx.snap b/test/components/views/settings/devices/__snapshots__/SecurityRecommendations-test.tsx.snap index 6cefc1c2df0..190fc3d2d05 100644 --- a/test/components/views/settings/devices/__snapshots__/SecurityRecommendations-test.tsx.snap +++ b/test/components/views/settings/devices/__snapshots__/SecurityRecommendations-test.tsx.snap @@ -16,9 +16,13 @@ exports[` renders both cards when user has both unver
      - Improve your account security by following these recommendations. +
      + Improve your account security by following these recommendations. +
      renders inactive devices section when user
      - Improve your account security by following these recommendations. +
      + Improve your account security by following these recommendations. +
      renders unverified devices section when use
      - Improve your account security by following these recommendations. +
      + Improve your account security by following these recommendations. +
      renders with plain text description 1`] = `
      - This describes the subsection +
      + This describes the subsection +
      renders with react element description 1`] = `
      -

      - This describes the section - - link - -

      +
      +

      + This describes the section + + link + +

      +
      Date: Tue, 2 May 2023 16:02:00 +1200 Subject: [PATCH 09/24] use ExternalLink components for external links --- src/components/structures/RoomStatusBar.tsx | 5 +- src/components/structures/SpaceRoomView.tsx | 5 +- .../dialogs/AnalyticsLearnMoreDialog.tsx | 5 +- .../views/dialogs/FeedbackDialog.tsx | 13 ++-- .../views/dialogs/ServerPickerDialog.tsx | 9 ++- src/components/views/dialogs/TermsDialog.tsx | 5 +- .../views/settings/EventIndexPanel.tsx | 13 ++-- .../tabs/user/HelpUserSettingsTab.tsx | 65 +++++++++++-------- src/utils/ErrorUtils.tsx | 5 +- .../FeedbackDialog-test.tsx.snap | 8 +++ .../__snapshots__/ErrorUtils-test.ts.snap | 4 ++ 11 files changed, 91 insertions(+), 46 deletions(-) diff --git a/src/components/structures/RoomStatusBar.tsx b/src/components/structures/RoomStatusBar.tsx index 24530d4cc51..7afc9025e29 100644 --- a/src/components/structures/RoomStatusBar.tsx +++ b/src/components/structures/RoomStatusBar.tsx @@ -30,6 +30,7 @@ import AccessibleButton from "../views/elements/AccessibleButton"; import InlineSpinner from "../views/elements/InlineSpinner"; import MatrixClientContext from "../../contexts/MatrixClientContext"; import { RoomStatusBarUnsentMessages } from "./RoomStatusBarUnsentMessages"; +import ExternalLink from "../views/elements/ExternalLink"; const STATUS_BAR_HIDDEN = 0; const STATUS_BAR_EXPANDED = 1; @@ -213,9 +214,9 @@ export default class RoomStatusBar extends React.PureComponent { {}, { consentLink: (sub) => ( - + {sub} - + ), }, ); diff --git a/src/components/structures/SpaceRoomView.tsx b/src/components/structures/SpaceRoomView.tsx index 85806913110..c1614b4e0ec 100644 --- a/src/components/structures/SpaceRoomView.tsx +++ b/src/components/structures/SpaceRoomView.tsx @@ -77,6 +77,7 @@ import MainSplit from "./MainSplit"; import RightPanel from "./RightPanel"; import SpaceHierarchy, { showRoom } from "./SpaceHierarchy"; import { RoomPermalinkCreator } from "../../utils/permalinks/Permalinks"; +import ExternalLink from "../views/elements/ExternalLink"; interface IProps { space: Room; @@ -593,9 +594,9 @@ const SpaceSetupPrivateInvite: React.FC<{ { b: (sub) => {sub}, link: () => ( - + app.element.io - + ), }, )} diff --git a/src/components/views/dialogs/AnalyticsLearnMoreDialog.tsx b/src/components/views/dialogs/AnalyticsLearnMoreDialog.tsx index f4cf78681b2..5ced239e9a9 100644 --- a/src/components/views/dialogs/AnalyticsLearnMoreDialog.tsx +++ b/src/components/views/dialogs/AnalyticsLearnMoreDialog.tsx @@ -22,6 +22,7 @@ import DialogButtons from "../elements/DialogButtons"; import Modal, { ComponentProps } from "../../../Modal"; import SdkConfig from "../../../SdkConfig"; import { getPolicyUrl } from "../../../toasts/AnalyticsToast"; +import ExternalLink from "../elements/ExternalLink"; export enum ButtonClicked { Primary, @@ -55,10 +56,10 @@ export const AnalyticsLearnMoreDialog: React.FC = ({ { PrivacyPolicyUrl: (sub) => { return ( - + {sub} - + ); }, }, diff --git a/src/components/views/dialogs/FeedbackDialog.tsx b/src/components/views/dialogs/FeedbackDialog.tsx index 5c8d1e4acf3..2ed1d967c28 100644 --- a/src/components/views/dialogs/FeedbackDialog.tsx +++ b/src/components/views/dialogs/FeedbackDialog.tsx @@ -27,6 +27,7 @@ import InfoDialog from "./InfoDialog"; import { submitFeedback } from "../../../rageshake/submit-rageshake"; import { useStateToggle } from "../../../hooks/useStateToggle"; import StyledCheckbox from "../elements/StyledCheckbox"; +import ExternalLink from "../elements/ExternalLink"; interface IProps { feature?: string; @@ -130,16 +131,20 @@ const FeedbackDialog: React.FC = (props: IProps) => { { existingIssuesLink: (sub) => { return ( - + {sub} - + ); }, newIssueLink: (sub) => { return ( - + {sub} - + ); }, }, diff --git a/src/components/views/dialogs/ServerPickerDialog.tsx b/src/components/views/dialogs/ServerPickerDialog.tsx index aca963e422b..8627e8b3d28 100644 --- a/src/components/views/dialogs/ServerPickerDialog.tsx +++ b/src/components/views/dialogs/ServerPickerDialog.tsx @@ -28,6 +28,7 @@ import StyledRadioButton from "../elements/StyledRadioButton"; import TextWithTooltip from "../elements/TextWithTooltip"; import withValidation, { IFieldState, IValidationResult } from "../elements/Validation"; import { ValidatedServerConfig } from "../../../utils/ValidatedServerConfig"; +import ExternalLink from "../elements/ExternalLink"; interface IProps { title?: string; @@ -236,9 +237,13 @@ export default class ServerPickerDialog extends React.PureComponent

      {_t("Learn more")}

      - + {_t("About homeservers")} - + ); diff --git a/src/components/views/dialogs/TermsDialog.tsx b/src/components/views/dialogs/TermsDialog.tsx index b0835c3afc5..ce697f1f1e2 100644 --- a/src/components/views/dialogs/TermsDialog.tsx +++ b/src/components/views/dialogs/TermsDialog.tsx @@ -22,6 +22,7 @@ import { _t, pickBestLanguage } from "../../../languageHandler"; import DialogButtons from "../elements/DialogButtons"; import BaseDialog from "./BaseDialog"; import { ServicePolicyPair } from "../../../Terms"; +import ExternalLink from "../elements/ExternalLink"; interface ITermsCheckboxProps { onChange: (url: string, checked: boolean) => void; @@ -148,9 +149,9 @@ export default class TermsDialog extends React.PureComponent{summary} {termDoc[termsLang].name} - + - + { }, { nativeLink: (sub) => ( - + {sub} - + ), }, )} @@ -217,9 +218,13 @@ export default class EventIndexPanel extends React.Component<{}, IState> { }, { desktopLink: (sub) => ( - + {sub} - + ), }, )} diff --git a/src/components/views/settings/tabs/user/HelpUserSettingsTab.tsx b/src/components/views/settings/tabs/user/HelpUserSettingsTab.tsx index f939cba64cc..af0525d6c55 100644 --- a/src/components/views/settings/tabs/user/HelpUserSettingsTab.tsx +++ b/src/components/views/settings/tabs/user/HelpUserSettingsTab.tsx @@ -31,6 +31,7 @@ import { Action } from "../../../../../dispatcher/actions"; import { UserTab } from "../../../dialogs/UserTab"; import dis from "../../../../../dispatcher/dispatcher"; import CopyableText from "../../../elements/CopyableText"; +import ExternalLink from "../../../elements/ExternalLink"; interface IProps { closeSettingsFn: () => void; @@ -114,9 +115,9 @@ export default class HelpUserSettingsTab extends React.Component for (const tocEntry of tocLinks) { legalLinks.push( , ); } @@ -143,27 +144,31 @@ export default class HelpUserSettingsTab extends React.Component {}, { photo: (sub) => ( - {sub} - + ), author: (sub) => ( - + {sub} - + ), terms: (sub) => ( - {sub} - + ), }, )} @@ -175,27 +180,27 @@ export default class HelpUserSettingsTab extends React.Component {}, { colr: (sub) => ( - {sub} - + ), author: (sub) => ( - + {sub} - + ), terms: (sub) => ( - {sub} - + ), }, )} @@ -208,23 +213,31 @@ export default class HelpUserSettingsTab extends React.Component {}, { twemoji: (sub) => ( - + {sub} - + ), author: (sub) => ( - + {sub} - + ), terms: (sub) => ( - {sub} - + ), }, )} @@ -256,9 +269,9 @@ export default class HelpUserSettingsTab extends React.Component }, { a: (sub) => ( - + {sub} - + ), }, ); @@ -273,9 +286,9 @@ export default class HelpUserSettingsTab extends React.Component }, { a: (sub) => ( - + {sub} - + ), }, )} @@ -321,13 +334,13 @@ export default class HelpUserSettingsTab extends React.Component {}, { a: (sub) => ( - {sub} - + ), }, )} diff --git a/src/utils/ErrorUtils.tsx b/src/utils/ErrorUtils.tsx index 365bd916c5d..bd37ed44271 100644 --- a/src/utils/ErrorUtils.tsx +++ b/src/utils/ErrorUtils.tsx @@ -20,6 +20,7 @@ import { MatrixError, ConnectionError } from "matrix-js-sdk/src/http-api"; import { _t, _td, Tags, TranslatedString } from "../languageHandler"; import SdkConfig from "../SdkConfig"; import { ValidatedServerConfig } from "./ValidatedServerConfig"; +import ExternalLink from "../components/views/elements/ExternalLink"; export const resourceLimitStrings = { "monthly_active_user": _td("This homeserver has hit its Monthly Active User limit."), @@ -183,9 +184,9 @@ export function messageForConnectionError( {}, { a: (sub) => ( - + {sub} - + ), }, )} diff --git a/test/components/views/dialogs/__snapshots__/FeedbackDialog-test.tsx.snap b/test/components/views/dialogs/__snapshots__/FeedbackDialog-test.tsx.snap index 2682f5234cc..2c02b622479 100644 --- a/test/components/views/dialogs/__snapshots__/FeedbackDialog-test.tsx.snap +++ b/test/components/views/dialogs/__snapshots__/FeedbackDialog-test.tsx.snap @@ -38,19 +38,27 @@ exports[`FeedbackDialog should respect feedback config 1`] = ` Please view existing bugs on Github + first. No match? Start a new one + . diff --git a/test/utils/__snapshots__/ErrorUtils-test.ts.snap b/test/utils/__snapshots__/ErrorUtils-test.ts.snap index bad4e0a1447..572c14f91cd 100644 --- a/test/utils/__snapshots__/ErrorUtils-test.ts.snap +++ b/test/utils/__snapshots__/ErrorUtils-test.ts.snap @@ -6,11 +6,15 @@ exports[`messageForConnectionError should match snapshot for ConnectionError 1`] Can't connect to homeserver - please check your connectivity, ensure your homeserver's SSL certificate + is trusted, and that a browser extension is not blocking requests. From 8e74b741f7d77a2e605b068b60616879c5c9232c Mon Sep 17 00:00:00 2001 From: Kerry Archibald Date: Tue, 2 May 2023 18:19:28 +1200 Subject: [PATCH 10/24] test --- src/components/structures/RoomStatusBar.tsx | 2 +- .../structures/RoomStatusBar-test.tsx | 65 ++++++++- .../__snapshots__/RoomStatusBar-test.tsx.snap | 126 ++++++++++++++++++ 3 files changed, 191 insertions(+), 2 deletions(-) create mode 100644 test/components/structures/__snapshots__/RoomStatusBar-test.tsx.snap diff --git a/src/components/structures/RoomStatusBar.tsx b/src/components/structures/RoomStatusBar.tsx index 7afc9025e29..3be594fcebd 100644 --- a/src/components/structures/RoomStatusBar.tsx +++ b/src/components/structures/RoomStatusBar.tsx @@ -214,7 +214,7 @@ export default class RoomStatusBar extends React.PureComponent { {}, { consentLink: (sub) => ( - + {sub} ), diff --git a/test/components/structures/RoomStatusBar-test.tsx b/test/components/structures/RoomStatusBar-test.tsx index a11bd899d39..de8260b26c3 100644 --- a/test/components/structures/RoomStatusBar-test.tsx +++ b/test/components/structures/RoomStatusBar-test.tsx @@ -14,11 +14,15 @@ See the License for the specific language governing permissions and limitations under the License. */ +import React from "react"; +import { render } from "@testing-library/react"; import { MatrixClient, PendingEventOrdering } from "matrix-js-sdk/src/client"; import { EventStatus, MatrixEvent } from "matrix-js-sdk/src/models/event"; import { Room } from "matrix-js-sdk/src/models/room"; +import { MatrixError } from "matrix-js-sdk/src/http-api"; -import { getUnsentMessages } from "../../../src/components/structures/RoomStatusBar"; +import RoomStatusBar, { getUnsentMessages } from "../../../src/components/structures/RoomStatusBar"; +import MatrixClientContext from "../../../src/contexts/MatrixClientContext"; import { MatrixClientPeg } from "../../../src/MatrixClientPeg"; import { mkEvent, stubClient } from "../../test-utils/test-utils"; import { mkThread } from "../../test-utils/threads"; @@ -34,6 +38,7 @@ describe("RoomStatusBar", () => { stubClient(); client = MatrixClientPeg.get(); + client.getSyncStateData = jest.fn().mockReturnValue({}); room = new Room(ROOM_ID, client, client.getUserId()!, { pendingEventOrdering: PendingEventOrdering.Detached, }); @@ -47,6 +52,13 @@ describe("RoomStatusBar", () => { event.status = EventStatus.NOT_SENT; }); + const getComponent = () => + render(, { + wrapper: ({ children }) => ( + {children} + ), + }); + describe("getUnsentMessages", () => { it("returns no unsent messages", () => { expect(getUnsentMessages(room)).toHaveLength(0); @@ -88,4 +100,55 @@ describe("RoomStatusBar", () => { expect(pendingEvents.every((ev) => ev.getId() !== event.getId())).toBe(true); }); }); + + describe("", () => { + it("should render nothing when room has no error or unsent messages", () => { + const { container } = getComponent(); + expect(container.firstChild).toBe(null); + }); + + describe("unsent messages", () => { + it("should render warning when messages are unsent due to consent", () => { + const unsentMessage = mkEvent({ + event: true, + type: "m.room.message", + user: "@user1:server", + room: "!room1:server", + content: {}, + }); + unsentMessage.status = EventStatus.NOT_SENT; + unsentMessage.error = new MatrixError({ + errcode: "M_CONSENT_NOT_GIVEN", + data: { consent_uri: "terms.com" }, + }); + + room.addPendingEvent(unsentMessage, "123"); + + const { container } = getComponent(); + + expect(container).toMatchSnapshot(); + }); + + it("should render warning when messages are unsent due to resource limit", () => { + const unsentMessage = mkEvent({ + event: true, + type: "m.room.message", + user: "@user1:server", + room: "!room1:server", + content: {}, + }); + unsentMessage.status = EventStatus.NOT_SENT; + unsentMessage.error = new MatrixError({ + errcode: "M_RESOURCE_LIMIT_EXCEEDED", + data: { limit_type: "monthly_active_user" }, + }); + + room.addPendingEvent(unsentMessage, "123"); + + const { container } = getComponent(); + + expect(container).toMatchSnapshot(); + }); + }); + }); }); diff --git a/test/components/structures/__snapshots__/RoomStatusBar-test.tsx.snap b/test/components/structures/__snapshots__/RoomStatusBar-test.tsx.snap new file mode 100644 index 00000000000..ed969114ec4 --- /dev/null +++ b/test/components/structures/__snapshots__/RoomStatusBar-test.tsx.snap @@ -0,0 +1,126 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`RoomStatusBar unsent messages should render warning when messages are unsent due to consent 1`] = ` +
      +
      +
      +
      +
      + + ! + +
      +
      +
      +
      + + You can't send any messages until you review and agree to + + our terms and conditions + + + . + +
      +
      + You can select all or individual messages to retry or delete +
      +
      +
      +
      + Delete all +
      +
      + Retry all +
      +
      +
      +
      +
      +`; + +exports[`RoomStatusBar unsent messages should render warning when messages are unsent due to resource limit 1`] = ` +
      +
      +
      +
      +
      + + ! + +
      +
      +
      +
      + Your message wasn't sent because this homeserver has exceeded a resource limit. Please contact your service administrator to continue using the service. +
      +
      + You can select all or individual messages to retry or delete +
      +
      +
      +
      + Delete all +
      +
      + Retry all +
      +
      +
      +
      +
      +`; From 4519726b9cfec5443806b471737ecd46df5b8b23 Mon Sep 17 00:00:00 2001 From: Kerry Archibald Date: Wed, 3 May 2023 09:03:18 +1200 Subject: [PATCH 11/24] strict --- src/components/structures/RoomStatusBar.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/structures/RoomStatusBar.tsx b/src/components/structures/RoomStatusBar.tsx index 3be594fcebd..7afc9025e29 100644 --- a/src/components/structures/RoomStatusBar.tsx +++ b/src/components/structures/RoomStatusBar.tsx @@ -214,7 +214,7 @@ export default class RoomStatusBar extends React.PureComponent { {}, { consentLink: (sub) => ( - + {sub} ), From 5ff32668a8a2922f678b27636a533d45c983c2d0 Mon Sep 17 00:00:00 2001 From: Kerry Archibald Date: Wed, 3 May 2023 14:56:07 +1200 Subject: [PATCH 12/24] lint --- test/components/views/dialogs/UserSettingsDialog-test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/components/views/dialogs/UserSettingsDialog-test.tsx b/test/components/views/dialogs/UserSettingsDialog-test.tsx index c5e831c3947..5e610b87ba7 100644 --- a/test/components/views/dialogs/UserSettingsDialog-test.tsx +++ b/test/components/views/dialogs/UserSettingsDialog-test.tsx @@ -15,7 +15,7 @@ limitations under the License. */ import React, { ReactElement } from "react"; -import { render, screen } from "@testing-library/react"; +import { render } from "@testing-library/react"; import { mocked } from "jest-mock"; import SettingsStore, { CallbackFn } from "../../../../src/settings/SettingsStore"; From fb1ace55aa8a9c4c7f68cfb5b08c615fd5480c36 Mon Sep 17 00:00:00 2001 From: Kerry Archibald Date: Wed, 3 May 2023 15:27:18 +1200 Subject: [PATCH 13/24] semantic heading in labs settings --- res/css/_components.pcss | 1 - res/css/views/beta/_BetaCard.pcss | 5 - .../tabs/user/_LabsUserSettingsTab.pcss | 27 --- .../tabs/user/LabsUserSettingsTab.tsx | 51 ++--- .../tabs/user/LabsUserSettingsTab-test.tsx | 17 +- .../LabsUserSettingsTab-test.tsx.snap | 187 ++++++++++-------- 6 files changed, 138 insertions(+), 150 deletions(-) delete mode 100644 res/css/views/settings/tabs/user/_LabsUserSettingsTab.pcss diff --git a/res/css/_components.pcss b/res/css/_components.pcss index 94153b2e894..e03e3e209e3 100644 --- a/res/css/_components.pcss +++ b/res/css/_components.pcss @@ -348,7 +348,6 @@ @import "./views/settings/tabs/user/_GeneralUserSettingsTab.pcss"; @import "./views/settings/tabs/user/_HelpUserSettingsTab.pcss"; @import "./views/settings/tabs/user/_KeyboardUserSettingsTab.pcss"; -@import "./views/settings/tabs/user/_LabsUserSettingsTab.pcss"; @import "./views/settings/tabs/user/_MjolnirUserSettingsTab.pcss"; @import "./views/settings/tabs/user/_PreferencesUserSettingsTab.pcss"; @import "./views/settings/tabs/user/_SecurityUserSettingsTab.pcss"; diff --git a/res/css/views/beta/_BetaCard.pcss b/res/css/views/beta/_BetaCard.pcss index 591fff2d954..62f7d7b93a7 100644 --- a/res/css/views/beta/_BetaCard.pcss +++ b/res/css/views/beta/_BetaCard.pcss @@ -15,7 +15,6 @@ limitations under the License. */ .mx_BetaCard { - margin-bottom: $spacing-20; padding: $spacing-24; background-color: $system; border-radius: 8px; @@ -114,10 +113,6 @@ limitations under the License. } } } - - &:last-child { - margin-bottom: 0; - } } .mx_BetaCard_betaPill { diff --git a/res/css/views/settings/tabs/user/_LabsUserSettingsTab.pcss b/res/css/views/settings/tabs/user/_LabsUserSettingsTab.pcss deleted file mode 100644 index f10b681668c..00000000000 --- a/res/css/views/settings/tabs/user/_LabsUserSettingsTab.pcss +++ /dev/null @@ -1,27 +0,0 @@ -/* -Copyright 2021 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. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -.mx_LabsUserSettingsTab { - .mx_SettingsTab_subsectionText, - .mx_SettingsTab_section { - margin-bottom: var(--SettingsTab_section-margin-bottom-preferences-labs); - } - - .mx_SettingsFlag { - margin-right: 0; /* remove right margin to align with beta cards */ - align-items: center; - } -} diff --git a/src/components/views/settings/tabs/user/LabsUserSettingsTab.tsx b/src/components/views/settings/tabs/user/LabsUserSettingsTab.tsx index f505ebb76f9..641eef0acbe 100644 --- a/src/components/views/settings/tabs/user/LabsUserSettingsTab.tsx +++ b/src/components/views/settings/tabs/user/LabsUserSettingsTab.tsx @@ -25,6 +25,9 @@ import BetaCard from "../../../beta/BetaCard"; import SettingsFlag from "../../../elements/SettingsFlag"; import { LabGroup, labGroupNames } from "../../../../../settings/Settings"; import { EnhancedMap } from "../../../../../utils/maps"; +import SettingsTab from "../SettingsTab"; +import { SettingsSection } from "../../shared/SettingsSection"; +import SettingsSubsection, { SettingsSubsectionText } from "../../shared/SettingsSubsection"; export default class LabsUserSettingsTab extends React.Component<{}> { private readonly labs: string[]; @@ -54,11 +57,11 @@ export default class LabsUserSettingsTab extends React.Component<{}> { let betaSection: JSX.Element | undefined; if (this.betas.length) { betaSection = ( -
      + <> {this.betas.map((f) => ( ))} -
      + ); } @@ -93,31 +96,35 @@ export default class LabsUserSettingsTab extends React.Component<{}> { labsSections = ( <> {sortBy(Array.from(groups.entries()), "0").map(([group, flags]) => ( -
      - {_t(labGroupNames[group])} + {flags} -
      + ))} ); } return ( -
      -
      {_t("Upcoming features")}
      -
      - {_t( - "What's next for %(brand)s? " + - "Labs are the best way to get things early, " + - "test out new features and help shape them before they actually launch.", - { brand: SdkConfig.get("brand") }, - )} -
      - {betaSection} + + + + {_t( + "What's next for %(brand)s? " + + "Labs are the best way to get things early, " + + "test out new features and help shape them before they actually launch.", + { brand: SdkConfig.get("brand") }, + )} + + {betaSection} + + {labsSections && ( - <> -
      {_t("Early previews")}
      -
      + + {_t( "Feeling experimental? " + "Try out our latest ideas in development. " + @@ -139,11 +146,11 @@ export default class LabsUserSettingsTab extends React.Component<{}> { }, }, )} -
      + {labsSections} - + )} -
      + ); } } diff --git a/test/components/views/settings/tabs/user/LabsUserSettingsTab-test.tsx b/test/components/views/settings/tabs/user/LabsUserSettingsTab-test.tsx index ddf6105274c..4933deda6d2 100644 --- a/test/components/views/settings/tabs/user/LabsUserSettingsTab-test.tsx +++ b/test/components/views/settings/tabs/user/LabsUserSettingsTab-test.tsx @@ -15,7 +15,7 @@ limitations under the License. */ import React from "react"; -import { render, waitFor } from "@testing-library/react"; +import { render, screen, waitFor } from "@testing-library/react"; import { defer } from "matrix-js-sdk/src/utils"; import LabsUserSettingsTab from "../../../../../../src/components/views/settings/tabs/user/LabsUserSettingsTab"; @@ -51,17 +51,16 @@ describe("", () => { }); it("renders settings marked as beta as beta cards", () => { - const { getByTestId } = render(getComponent()); - expect(getByTestId("labs-beta-section")).toMatchSnapshot(); + render(getComponent()); + expect(screen.getByText("Upcoming features").parentElement!).toMatchSnapshot(); }); it("does not render non-beta labs settings when disabled in config", () => { - const { container } = render(getComponent()); + render(getComponent()); expect(sdkConfigSpy).toHaveBeenCalledWith("show_labs_settings"); - const labsSections = container.getElementsByClassName("mx_SettingsTab_section"); // only section is beta section - expect(labsSections.length).toEqual(1); + expect(screen.queryByText("Early previews")).not.toBeInTheDocument(); }); it("renders non-beta labs settings when enabled in config", () => { @@ -69,8 +68,10 @@ describe("", () => { sdkConfigSpy.mockImplementation((configName) => configName === "show_labs_settings"); const { container } = render(getComponent()); - const labsSections = container.getElementsByClassName("mx_SettingsTab_section"); - expect(labsSections).toHaveLength(12); + // non-beta labs section + expect(screen.getByText("Early previews")).toBeInTheDocument(); + const labsSections = container.getElementsByClassName("mx_SettingsSubsection"); + expect(labsSections).toHaveLength(11); }); it("allow setting a labs flag which requires unstable support once support is confirmed", async () => { diff --git a/test/components/views/settings/tabs/user/__snapshots__/LabsUserSettingsTab-test.tsx.snap b/test/components/views/settings/tabs/user/__snapshots__/LabsUserSettingsTab-test.tsx.snap index 2d562b8c32f..8d7d5628095 100644 --- a/test/components/views/settings/tabs/user/__snapshots__/LabsUserSettingsTab-test.tsx.snap +++ b/test/components/views/settings/tabs/user/__snapshots__/LabsUserSettingsTab-test.tsx.snap @@ -2,121 +2,134 @@ exports[` renders settings marked as beta as beta cards 1`] = `
      +

      + Upcoming features +

      + What's next for false? Labs are the best way to get things early, test out new features and help shape them before they actually launch. +
      +
      -

      - - Video rooms - - - Beta - -

      -

      - A new way to chat over voice and video in . -

      -

      - Video rooms are always-on VoIP channels embedded within a room in . -

      -
      -
      +

      + + Video rooms + + + Beta + +

      - Join the beta +

      + A new way to chat over voice and video in . +

      +

      + Video rooms are always-on VoIP channels embedded within a room in . +

      +
      +
      + Join the beta +
      +
      +
      + Joining the beta will reload . +
      +
      - Joining the beta will reload . +
      -
      -
      -
      -
      -
      -
      -

      - - New session manager - - - Beta - -

      -

      - Have greater visibility and control over all your sessions. -

      -

      - Our new sessions manager provides better visibility of all your sessions, and greater control over them including the ability to remotely toggle push notifications. -

      -
      -
      +

      + + New session manager + + + Beta + +

      - Join the beta +

      + Have greater visibility and control over all your sessions. +

      +

      + Our new sessions manager provides better visibility of all your sessions, and greater control over them including the ability to remotely toggle push notifications. +

      +
      +
      +
      + Join the beta +
      -
      -
      - +
      + +
      From ea5edebaae8d4469c37aeca6fff5ca6918082f1c Mon Sep 17 00:00:00 2001 From: Kerry Archibald Date: Wed, 3 May 2023 15:27:36 +1200 Subject: [PATCH 14/24] semantic headings in keyboard settings tab --- res/css/views/elements/_SettingsFlag.pcss | 1 + .../tabs/user/_KeyboardUserSettingsTab.pcss | 43 +- .../tabs/user/KeyboardUserSettingsTab.tsx | 33 +- .../tabs/user/PreferencesUserSettingsTab.tsx | 2 +- .../KeyboardUserSettingsTab-test.tsx.snap | 2044 +++++++++-------- 5 files changed, 1098 insertions(+), 1025 deletions(-) diff --git a/res/css/views/elements/_SettingsFlag.pcss b/res/css/views/elements/_SettingsFlag.pcss index b3908a158ad..16be54ef3c9 100644 --- a/res/css/views/elements/_SettingsFlag.pcss +++ b/res/css/views/elements/_SettingsFlag.pcss @@ -20,6 +20,7 @@ limitations under the License. align-items: flex-start; justify-content: space-between; margin-bottom: 4px; + width: 100%; .mx_ToggleSwitch { flex: 0 0 auto; diff --git a/res/css/views/settings/tabs/user/_KeyboardUserSettingsTab.pcss b/res/css/views/settings/tabs/user/_KeyboardUserSettingsTab.pcss index 6f387380f24..c4e5b5c0aa0 100644 --- a/res/css/views/settings/tabs/user/_KeyboardUserSettingsTab.pcss +++ b/res/css/views/settings/tabs/user/_KeyboardUserSettingsTab.pcss @@ -15,31 +15,26 @@ See the License for the specific language governing permissions and limitations under the License. */ -.mx_KeyboardUserSettingsTab .mx_SettingsTab_section { - ul { - margin: 0; - padding: 0; - } - - .mx_KeyboardShortcut_shortcutRow, - .mx_KeyboardShortcut { - display: flex; - justify-content: space-between; - align-items: center; - } +.mx_KeyboardShortcut_shortcutList { + margin: 0; + padding: 0; + width: 100%; + display: grid; + grid-gap: $spacing-4; +} - .mx_KeyboardShortcut_shortcutRow { - column-gap: $spacing-8; - margin-bottom: $spacing-4; +.mx_KeyboardShortcut_shortcutRow, +.mx_KeyboardShortcut { + display: flex; + justify-content: space-between; + align-items: center; +} - /* TODO: Use flexbox */ - &:last-of-type { - margin-bottom: 0; - } +.mx_KeyboardShortcut_shortcutRow { + column-gap: $spacing-8; +} - .mx_KeyboardShortcut { - flex-wrap: nowrap; - column-gap: 5px; /* TODO: Use a spacing variable */ - } - } +.mx_KeyboardShortcut { + flex-wrap: nowrap; + column-gap: $spacing-4; } diff --git a/src/components/views/settings/tabs/user/KeyboardUserSettingsTab.tsx b/src/components/views/settings/tabs/user/KeyboardUserSettingsTab.tsx index ef79b98d483..c6cb4f1f0ab 100644 --- a/src/components/views/settings/tabs/user/KeyboardUserSettingsTab.tsx +++ b/src/components/views/settings/tabs/user/KeyboardUserSettingsTab.tsx @@ -25,6 +25,9 @@ import { getKeyboardShortcutValue, } from "../../../../../accessibility/KeyboardShortcutUtils"; import { KeyboardShortcut } from "../../KeyboardShortcut"; +import SettingsTab from "../SettingsTab"; +import { SettingsSection } from "../../shared/SettingsSection"; +import SettingsSubsection from "../../shared/SettingsSubsection"; interface IKeyboardShortcutRowProps { name: KeyBindingAction; @@ -57,26 +60,32 @@ const KeyboardShortcutSection: React.FC = ({ cate if (!category.categoryLabel) return null; return ( -
      -
      {_t(category.categoryLabel)}
      -
        - {" "} + +
          + {/* {" "} */} {category.settingNames.map((shortcutName) => { return ; - })}{" "} + })} + {/* {" "} */}
        -
      + ); }; const KeyboardUserSettingsTab: React.FC = () => { return ( -
      -
      {_t("Keyboard")}
      - {visibleCategories.map(([categoryName, category]: [CategoryName, ICategory]) => { - return ; - })} -
      + + + {visibleCategories.map(([categoryName, category]: [CategoryName, ICategory]) => { + return ( + + ); + })} + + + //
      + //
      {_t("Keyboard")}
      + //
      ); }; diff --git a/src/components/views/settings/tabs/user/PreferencesUserSettingsTab.tsx b/src/components/views/settings/tabs/user/PreferencesUserSettingsTab.tsx index 4fbb174516a..a3637ad4a81 100644 --- a/src/components/views/settings/tabs/user/PreferencesUserSettingsTab.tsx +++ b/src/components/views/settings/tabs/user/PreferencesUserSettingsTab.tsx @@ -1,5 +1,5 @@ /* -Copyright 2019-2021 The Matrix.org Foundation C.I.C. +Copyright 2019-2023 The Matrix.org Foundation C.I.C. Copyright 2019 Michael Telatynski <7t3chguy@gmail.com> Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/components/views/settings/tabs/user/__snapshots__/KeyboardUserSettingsTab-test.tsx.snap b/test/components/views/settings/tabs/user/__snapshots__/KeyboardUserSettingsTab-test.tsx.snap index 112497f7bfe..9d0badffdad 100644 --- a/test/components/views/settings/tabs/user/__snapshots__/KeyboardUserSettingsTab-test.tsx.snap +++ b/test/components/views/settings/tabs/user/__snapshots__/KeyboardUserSettingsTab-test.tsx.snap @@ -3,1023 +3,1091 @@ exports[`KeyboardUserSettingsTab renders list of keyboard shortcuts 1`] = `
      - Keyboard -
      -
      -
      - Composer -
      -
        - -
      • - Send message -
        - - - Enter - - -
        -
      • -
      • - New line -
        - - - Shift - - - + - - - Enter - - -
        -
      • -
      • - Toggle Bold -
        - - - Ctrl - - - + - - - b - - -
        -
      • -
      • - Toggle Italics -
        - - - Ctrl - - - + - - - i - - -
        -
      • -
      • - Toggle Quote -
        - - - Ctrl - - - + - - - Shift - - - + - - - > - - -
        -
      • -
      • - Toggle Link -
        - - - Ctrl - - - + - - - Shift - - - + - - - l - - -
        -
      • -
      • - Toggle Code Block -
        - - - Ctrl - - - + - - - e - - -
        -
      • -
      • - Undo edit -
        - - - Ctrl - - - + - - - z - - -
        -
      • -
      • - Redo edit -
        - - - Ctrl - - - + - - - y - - -
        -
      • -
      • - Jump to start of the composer -
        - - - Ctrl - - - + - - - Home - - -
        -
      • -
      • - Jump to end of the composer -
        - - - Ctrl - - - + - - - End - - -
        -
      • -
      • - Cancel replying to a message -
        - - - Esc - - -
        -
      • -
      • - Navigate to next message to edit -
        - - - ↓ - - -
        -
      • -
      • - Navigate to previous message to edit -
        - - - ↑ - - -
        -
      • -
      • - Navigate to next message in composer history -
        - - - Ctrl - - - + - - - Alt - - - + - - - ↓ - - -
        -
      • -
      • - Navigate to previous message in composer history -
        - - - Ctrl - - - + - - - Alt - - - + - - - ↑ - - -
        -
      • -
      • - Send a sticker -
        - - - Ctrl - - - + - - - ; - - -
        -
      • - -
      -
      -
      -
      - Calls -
      -
        - -
      • - Toggle microphone mute -
        - - - Ctrl - - - + - - - d - - -
        -
      • -
      • - Toggle webcam on/off -
        - - - Ctrl - - - + - - - e - - -
        -
      • - -
      -
      -
      -
      - Room -
      -
        - -
      • - Search (must be enabled) -
        - - - Ctrl - - - + - - - f - - -
        -
      • -
      • - Upload a file -
        - - - Ctrl - - - + - - - Shift - - - + - - - u - - -
        -
      • -
      • - Dismiss read marker and jump to bottom -
        - - - Esc - - -
        -
      • -
      • - Jump to oldest unread message -
        - - - Shift - - - + - - - Page Up - - -
        -
      • -
      • - Scroll up in the timeline -
        - - - Page Up - - -
        -
      • -
      • - Scroll down in the timeline -
        - - - Page Down - - -
        -
      • -
      • - Jump to first message -
        - - - Ctrl - - - + - - - Home - - -
        -
      • -
      • - Jump to last message -
        - - - Ctrl - - - + - - - End - - -
        -
      • - -
      -
      -
      -
      - Room List -
      -
        - -
      • - Select room from the room list -
        - - - Enter - - -
        -
      • -
      • - Collapse room list section -
        - - - ← - - -
        -
      • -
      • - Expand room list section -
        - - - → - - -
        -
      • -
      • - Navigate down in the room list -
        - - - ↓ - - -
        -
      • -
      • - Navigate up in the room list -
        - - - ↑ - - -
        -
      • - -
      -
      -
      -
      - Accessibility -
      -
        - -
      • - Close dialog or context menu -
        - - - Esc - - -
        -
      • -
      • - Activate selected button -
        - - - Enter - - -
        -
      • - -
      -
      -
      - Navigation -
      -
        - -
      • - Toggle the top left menu -
        - - - Ctrl - - - + - - - \` - - -
        -
      • -
      • +
        - Toggle right panel
        - - - Ctrl - - - + - - - . - - +
        +

        + Composer +

        +
        +
        +
          +
        • + Send message +
          + + + Enter + + +
          +
        • +
        • + New line +
          + + + Shift + + + + + + + Enter + + +
          +
        • +
        • + Toggle Bold +
          + + + Ctrl + + + + + + + b + + +
          +
        • +
        • + Toggle Italics +
          + + + Ctrl + + + + + + + i + + +
          +
        • +
        • + Toggle Quote +
          + + + Ctrl + + + + + + + Shift + + + + + + + > + + +
          +
        • +
        • + Toggle Link +
          + + + Ctrl + + + + + + + Shift + + + + + + + l + + +
          +
        • +
        • + Toggle Code Block +
          + + + Ctrl + + + + + + + e + + +
          +
        • +
        • + Undo edit +
          + + + Ctrl + + + + + + + z + + +
          +
        • +
        • + Redo edit +
          + + + Ctrl + + + + + + + y + + +
          +
        • +
        • + Jump to start of the composer +
          + + + Ctrl + + + + + + + Home + + +
          +
        • +
        • + Jump to end of the composer +
          + + + Ctrl + + + + + + + End + + +
          +
        • +
        • + Cancel replying to a message +
          + + + Esc + + +
          +
        • +
        • + Navigate to next message to edit +
          + + + ↓ + + +
          +
        • +
        • + Navigate to previous message to edit +
          + + + ↑ + + +
          +
        • +
        • + Navigate to next message in composer history +
          + + + Ctrl + + + + + + + Alt + + + + + + + ↓ + + +
          +
        • +
        • + Navigate to previous message in composer history +
          + + + Ctrl + + + + + + + Alt + + + + + + + ↑ + + +
          +
        • +
        • + Send a sticker +
          + + + Ctrl + + + + + + + ; + + +
          +
        • +
        +
        -
      • -
      • - Toggle space panel
        - - - Ctrl - - - + - - - Shift - - - + - - - d - - +
        +

        + Calls +

        +
        +
        +
          +
        • + Toggle microphone mute +
          + + + Ctrl + + + + + + + d + + +
          +
        • +
        • + Toggle webcam on/off +
          + + + Ctrl + + + + + + + e + + +
          +
        • +
        +
        -
      • -
      • - Open this settings tab
        - - - Ctrl - - - + - - - / - - +
        +

        + Room +

        +
        +
        +
          +
        • + Search (must be enabled) +
          + + + Ctrl + + + + + + + f + + +
          +
        • +
        • + Upload a file +
          + + + Ctrl + + + + + + + Shift + + + + + + + u + + +
          +
        • +
        • + Dismiss read marker and jump to bottom +
          + + + Esc + + +
          +
        • +
        • + Jump to oldest unread message +
          + + + Shift + + + + + + + Page Up + + +
          +
        • +
        • + Scroll up in the timeline +
          + + + Page Up + + +
          +
        • +
        • + Scroll down in the timeline +
          + + + Page Down + + +
          +
        • +
        • + Jump to first message +
          + + + Ctrl + + + + + + + Home + + +
          +
        • +
        • + Jump to last message +
          + + + Ctrl + + + + + + + End + + +
          +
        • +
        +
        -
      • -
      • - Go to Home View
        - - - Ctrl - - - + - - - Alt - - - + - - - h - - +
        +

        + Room List +

        +
        +
        +
          +
        • + Select room from the room list +
          + + + Enter + + +
          +
        • +
        • + Collapse room list section +
          + + + ← + + +
          +
        • +
        • + Expand room list section +
          + + + → + + +
          +
        • +
        • + Navigate down in the room list +
          + + + ↓ + + +
          +
        • +
        • + Navigate up in the room list +
          + + + ↑ + + +
          +
        • +
        +
        -
      • -
      • - Jump to room search
        - - - Ctrl - - - + - - - k - - +
        +

        + Accessibility +

        +
        +
        +
          +
        • + Close dialog or context menu +
          + + + Esc + + +
          +
        • +
        • + Activate selected button +
          + + + Enter + + +
          +
        • +
        +
        -
      • -
      • - Next unread room or DM
        - - - Alt - - - + - - - Shift - - - + - - - ↓ - - +
        +

        + Navigation +

        +
        +
        +
          +
        • + Toggle the top left menu +
          + + + Ctrl + + + + + + + \` + + +
          +
        • +
        • + Toggle right panel +
          + + + Ctrl + + + + + + + . + + +
          +
        • +
        • + Toggle space panel +
          + + + Ctrl + + + + + + + Shift + + + + + + + d + + +
          +
        • +
        • + Open this settings tab +
          + + + Ctrl + + + + + + + / + + +
          +
        • +
        • + Go to Home View +
          + + + Ctrl + + + + + + + Alt + + + + + + + h + + +
          +
        • +
        • + Jump to room search +
          + + + Ctrl + + + + + + + k + + +
          +
        • +
        • + Next unread room or DM +
          + + + Alt + + + + + + + Shift + + + + + + + ↓ + + +
          +
        • +
        • + Previous unread room or DM +
          + + + Alt + + + + + + + Shift + + + + + + + ↑ + + +
          +
        • +
        • + Next room or DM +
          + + + Alt + + + + + + + ↓ + + +
          +
        • +
        • + Previous room or DM +
          + + + Alt + + + + + + + ↑ + + +
          +
        • +
        +
        -
      • -
      • - Previous unread room or DM
        - - - Alt - - - + - - - Shift - - - + - - - ↑ - - +
        +

        + Autocomplete +

        +
        +
        +
          +
        • + Cancel autocomplete +
          + + + Esc + + +
          +
        • +
        • + Next autocomplete suggestion +
          + + + ↓ + + +
          +
        • +
        • + Previous autocomplete suggestion +
          + + + ↑ + + +
          +
        • +
        • + Complete +
          + + + Enter + + +
          +
        • +
        • + Force complete +
          + + + Tab + + +
          +
        • +
        +
        -
      • -
      • - Next room or DM -
        - - - Alt - - - + - - - ↓ - - -
        -
      • -
      • - Previous room or DM -
        - - - Alt - - - + - - - ↑ - - -
        -
      • - -
      -
      -
      -
      - Autocomplete +
      -
        - -
      • - Cancel autocomplete -
        - - - Esc - - -
        -
      • -
      • - Next autocomplete suggestion -
        - - - ↓ - - -
        -
      • -
      • - Previous autocomplete suggestion -
        - - - ↑ - - -
        -
      • -
      • - Complete -
        - - - Enter - - -
        -
      • -
      • - Force complete -
        - - - Tab - - -
        -
      • - -
      From 3a2881681cad45042c3e4e06e1d56e9c367acce5 Mon Sep 17 00:00:00 2001 From: Kerry Archibald Date: Wed, 3 May 2023 15:47:25 +1200 Subject: [PATCH 15/24] semantic heading in preferencesusersettingstab --- .../preferences-user-settings-tab.spec.ts | 6 +- res/css/_components.pcss | 1 - .../settings/shared/_SettingsSubsection.pcss | 4 + res/css/views/settings/tabs/_SettingsTab.pcss | 1 - .../user/_PreferencesUserSettingsTab.pcss | 25 - .../settings/shared/SettingsSubsection.tsx | 19 +- .../views/settings/tabs/SettingsTab.tsx | 8 +- .../tabs/user/PreferencesUserSettingsTab.tsx | 190 +- .../PreferencesUserSettingsTab-test.tsx.snap | 2118 +++++++++-------- 9 files changed, 1231 insertions(+), 1141 deletions(-) delete mode 100644 res/css/views/settings/tabs/user/_PreferencesUserSettingsTab.pcss diff --git a/cypress/e2e/settings/preferences-user-settings-tab.spec.ts b/cypress/e2e/settings/preferences-user-settings-tab.spec.ts index ad16f0a1c59..397a00a9ef8 100644 --- a/cypress/e2e/settings/preferences-user-settings-tab.spec.ts +++ b/cypress/e2e/settings/preferences-user-settings-tab.spec.ts @@ -35,12 +35,12 @@ describe("Preferences user settings tab", () => { it("should be rendered properly", () => { cy.openUserSettings("Preferences"); - cy.get(".mx_SettingsTab.mx_PreferencesUserSettingsTab").within(() => { + cy.get("[data-testid='mx_PreferencesUserSettingsTab']").within(() => { // Assert that the top heading is rendered - cy.findByTestId("preferences").should("have.text", "Preferences").should("be.visible"); + cy.contains("Preferences").should("be.visible"); }); - cy.get(".mx_SettingsTab.mx_PreferencesUserSettingsTab").percySnapshotElement( + cy.get("[data-testid='mx_PreferencesUserSettingsTab']").percySnapshotElement( "User settings tab - Preferences", { // Emulate TabbedView's actual min and max widths diff --git a/res/css/_components.pcss b/res/css/_components.pcss index e03e3e209e3..7e75fab535a 100644 --- a/res/css/_components.pcss +++ b/res/css/_components.pcss @@ -349,7 +349,6 @@ @import "./views/settings/tabs/user/_HelpUserSettingsTab.pcss"; @import "./views/settings/tabs/user/_KeyboardUserSettingsTab.pcss"; @import "./views/settings/tabs/user/_MjolnirUserSettingsTab.pcss"; -@import "./views/settings/tabs/user/_PreferencesUserSettingsTab.pcss"; @import "./views/settings/tabs/user/_SecurityUserSettingsTab.pcss"; @import "./views/settings/tabs/user/_SidebarUserSettingsTab.pcss"; @import "./views/settings/tabs/user/_VoiceUserSettingsTab.pcss"; diff --git a/res/css/components/views/settings/shared/_SettingsSubsection.pcss b/res/css/components/views/settings/shared/_SettingsSubsection.pcss index e90585122b5..9ab33c93536 100644 --- a/res/css/components/views/settings/shared/_SettingsSubsection.pcss +++ b/res/css/components/views/settings/shared/_SettingsSubsection.pcss @@ -46,4 +46,8 @@ limitations under the License. margin-bottom: $spacing-8; } } + + &.mx_SettingsSubsection_contentStretch { + justify-items: stretch; + } } diff --git a/res/css/views/settings/tabs/_SettingsTab.pcss b/res/css/views/settings/tabs/_SettingsTab.pcss index fac189e8587..b060a025418 100644 --- a/res/css/views/settings/tabs/_SettingsTab.pcss +++ b/res/css/views/settings/tabs/_SettingsTab.pcss @@ -15,7 +15,6 @@ limitations under the License. */ .mx_SettingsTab { - --SettingsTab_section-margin-bottom-preferences-labs: 30px; --SettingsTab_heading_nth_child-margin-top: 30px; /* TODO: Use a spacing variable */ --SettingsTab_fullWidthField-margin-inline-end: 100px; --SettingsTab_tooltip-max-width: 120px; /* So it fits in the space provided by the page */ diff --git a/res/css/views/settings/tabs/user/_PreferencesUserSettingsTab.pcss b/res/css/views/settings/tabs/user/_PreferencesUserSettingsTab.pcss deleted file mode 100644 index c7eb699d4c9..00000000000 --- a/res/css/views/settings/tabs/user/_PreferencesUserSettingsTab.pcss +++ /dev/null @@ -1,25 +0,0 @@ -/* -Copyright 2019 New Vector Ltd - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -.mx_PreferencesUserSettingsTab { - .mx_Field { - margin-inline-end: var(--SettingsTab_fullWidthField-margin-inline-end); - } - - .mx_SettingsTab_section { - margin-bottom: var(--SettingsTab_section-margin-bottom-preferences-labs); - } -} diff --git a/src/components/views/settings/shared/SettingsSubsection.tsx b/src/components/views/settings/shared/SettingsSubsection.tsx index 8fcdf327a9a..6c60de1296f 100644 --- a/src/components/views/settings/shared/SettingsSubsection.tsx +++ b/src/components/views/settings/shared/SettingsSubsection.tsx @@ -14,6 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ +import classNames from "classnames"; import React, { HTMLAttributes } from "react"; import { SettingsSubsectionHeading } from "./SettingsSubsectionHeading"; @@ -22,6 +23,8 @@ export interface SettingsSubsectionProps extends HTMLAttributes heading: string | React.ReactNode; description?: string | React.ReactNode; children?: React.ReactNode; + // when true content will be justify-items: stretch + stretchContent?: boolean; } export const SettingsSubsectionText: React.FC> = ({ children, ...rest }) => ( @@ -30,7 +33,13 @@ export const SettingsSubsectionText: React.FC> =
      ); -export const SettingsSubsection: React.FC = ({ heading, description, children, ...rest }) => ( +export const SettingsSubsection: React.FC = ({ + heading, + description, + children, + stretchContent, + ...rest +}) => (
      {typeof heading === "string" ? : <>{heading}} {!!description && ( @@ -38,7 +47,13 @@ export const SettingsSubsection: React.FC = ({ heading, {description}
      )} -
      {children}
      +
      + {children} +
      ); diff --git a/src/components/views/settings/tabs/SettingsTab.tsx b/src/components/views/settings/tabs/SettingsTab.tsx index e9f25ec7406..16764e9460d 100644 --- a/src/components/views/settings/tabs/SettingsTab.tsx +++ b/src/components/views/settings/tabs/SettingsTab.tsx @@ -13,9 +13,9 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -import React from "react"; +import React, { HTMLAttributes } from "react"; -export interface SettingsTabProps { +export interface SettingsTabProps extends Omit, "className"> { children?: React.ReactNode; } @@ -37,8 +37,8 @@ export interface SettingsTabProps { * * ``` */ -const SettingsTab: React.FC = ({ children }) => ( -
      +const SettingsTab: React.FC = ({ children, ...rest }) => ( +
      {children}
      ); diff --git a/src/components/views/settings/tabs/user/PreferencesUserSettingsTab.tsx b/src/components/views/settings/tabs/user/PreferencesUserSettingsTab.tsx index a3637ad4a81..cc485dca45c 100644 --- a/src/components/views/settings/tabs/user/PreferencesUserSettingsTab.tsx +++ b/src/components/views/settings/tabs/user/PreferencesUserSettingsTab.tsx @@ -30,6 +30,9 @@ import { OpenToTabPayload } from "../../../../../dispatcher/payloads/OpenToTabPa import { Action } from "../../../../../dispatcher/actions"; import SdkConfig from "../../../../../SdkConfig"; import { showUserOnboardingPage } from "../../../user-onboarding/UserOnboardingPage"; +import SettingsSubsection from "../../shared/SettingsSubsection"; +import SettingsTab from "../SettingsTab"; +import { SettingsSection } from "../../shared/SettingsSection"; interface IProps { closeSettingsFn(success: boolean): void; @@ -143,27 +146,21 @@ export default class PreferencesUserSettingsTab extends React.Component it !== "FTUE.userOnboardingButton" || showUserOnboardingPage(useCase)); return ( -
      -
      - {_t("Preferences")} -
      - - {roomListSettings.length > 0 && ( -
      - {_t("Room list")} - {this.renderGroup(roomListSettings)} -
      - )} - -
      - {_t("Spaces")} - {this.renderGroup(PreferencesUserSettingsTab.SPACES_SETTINGS, SettingLevel.ACCOUNT)} -
      - -
      - {_t("Keyboard shortcuts")} -
      - {_t( + + + {roomListSettings.length > 0 && ( + + {this.renderGroup(roomListSettings)} + + )} + + + {this.renderGroup(PreferencesUserSettingsTab.SPACES_SETTINGS, SettingLevel.ACCOUNT)} + + + click here.", {}, { @@ -174,85 +171,78 @@ export default class PreferencesUserSettingsTab extends React.Component - {this.renderGroup(PreferencesUserSettingsTab.KEYBINDINGS_SETTINGS)} -
      - -
      - {_t("Displaying time")} - {this.renderGroup(PreferencesUserSettingsTab.TIME_SETTINGS)} -
      - -
      - {_t("Presence")} - - {_t("Share your activity and status with others.")} - - {this.renderGroup(PreferencesUserSettingsTab.PRESENCE_SETTINGS)} -
      - -
      - {_t("Composer")} - {this.renderGroup(PreferencesUserSettingsTab.COMPOSER_SETTINGS)} -
      - -
      - {_t("Code blocks")} - {this.renderGroup(PreferencesUserSettingsTab.CODE_BLOCKS_SETTINGS)} -
      - -
      - {_t("Images, GIFs and videos")} - {this.renderGroup(PreferencesUserSettingsTab.IMAGES_AND_VIDEOS_SETTINGS)} -
      - -
      - {_t("Timeline")} - {this.renderGroup(PreferencesUserSettingsTab.TIMELINE_SETTINGS)} -
      - -
      - {_t("Room directory")} - {this.renderGroup(PreferencesUserSettingsTab.ROOM_DIRECTORY_SETTINGS)} -
      - -
      - {_t("General")} - {this.renderGroup(PreferencesUserSettingsTab.GENERAL_SETTINGS)} - - - - - - - - - - -
      -
      + > + {this.renderGroup(PreferencesUserSettingsTab.KEYBINDINGS_SETTINGS)} + + + + {this.renderGroup(PreferencesUserSettingsTab.TIME_SETTINGS)} + + + + {this.renderGroup(PreferencesUserSettingsTab.PRESENCE_SETTINGS)} + + + + {this.renderGroup(PreferencesUserSettingsTab.COMPOSER_SETTINGS)} + + + + {this.renderGroup(PreferencesUserSettingsTab.CODE_BLOCKS_SETTINGS)} + + + + {this.renderGroup(PreferencesUserSettingsTab.IMAGES_AND_VIDEOS_SETTINGS)} + + + + {this.renderGroup(PreferencesUserSettingsTab.TIMELINE_SETTINGS)} + + + + {this.renderGroup(PreferencesUserSettingsTab.ROOM_DIRECTORY_SETTINGS)} + + + + {this.renderGroup(PreferencesUserSettingsTab.GENERAL_SETTINGS)} + + + + + + + + + + + + + ); } } diff --git a/test/components/views/settings/tabs/user/__snapshots__/PreferencesUserSettingsTab-test.tsx.snap b/test/components/views/settings/tabs/user/__snapshots__/PreferencesUserSettingsTab-test.tsx.snap index 45340dac369..2426d97f3a7 100644 --- a/test/components/views/settings/tabs/user/__snapshots__/PreferencesUserSettingsTab-test.tsx.snap +++ b/test/components/views/settings/tabs/user/__snapshots__/PreferencesUserSettingsTab-test.tsx.snap @@ -3,1046 +3,1154 @@ exports[`PreferencesUserSettingsTab should render 1`] = `
      - Preferences -
      -
      - - Room list -
      - + Preferences +
      -
      -
      -
      -
      -
      - - Spaces - -
      -