From f1c1caac624eab113e64902ad2dd0b84c21efcf2 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 23 Jan 2019 17:32:27 -0700 Subject: [PATCH] Implement labs tab in new user settings --- res/css/structures/_TabbedView.scss | 2 +- .../views/dialogs/_UserSettingsDialog.scss | 6 +- res/css/views/settings/tabs/_SettingsTab.scss | 1 + res/img/feather-icons/flag.svg | 5 ++ .../views/dialogs/UserSettingsDialog.js | 85 +++++++++++-------- .../views/settings/tabs/LabsSettingsTab.js | 69 +++++++++++++++ src/i18n/strings/en_EN.json | 2 +- 7 files changed, 130 insertions(+), 40 deletions(-) create mode 100644 res/img/feather-icons/flag.svg create mode 100644 src/components/views/settings/tabs/LabsSettingsTab.js diff --git a/res/css/structures/_TabbedView.scss b/res/css/structures/_TabbedView.scss index 0f4b67ad71..d9d66f470a 100644 --- a/res/css/structures/_TabbedView.scss +++ b/res/css/structures/_TabbedView.scss @@ -65,7 +65,7 @@ limitations under the License. mask-repeat: no-repeat; mask-size: 14px; width: 14px; - height: 14px; + height: 15px; mask-position: center; content: ''; vertical-align: middle; diff --git a/res/css/views/dialogs/_UserSettingsDialog.scss b/res/css/views/dialogs/_UserSettingsDialog.scss index c4bd8a5110..d7a31d0c99 100644 --- a/res/css/views/dialogs/_UserSettingsDialog.scss +++ b/res/css/views/dialogs/_UserSettingsDialog.scss @@ -60,4 +60,8 @@ .mx_UserSettingsDialog_helpIcon:before { mask-image: url('$(res)/img/feather-icons/help-circle.svg'); -} \ No newline at end of file +} + +.mx_UserSettingsDialog_labsIcon:before { + mask-image: url('$(res)/img/feather-icons/flag.svg'); +} diff --git a/res/css/views/settings/tabs/_SettingsTab.scss b/res/css/views/settings/tabs/_SettingsTab.scss index f03c8b8bd0..1a26c58c44 100644 --- a/res/css/views/settings/tabs/_SettingsTab.scss +++ b/res/css/views/settings/tabs/_SettingsTab.scss @@ -48,6 +48,7 @@ limitations under the License. display: inline-block; font-size: 12px; color: $primary-fg-color; + max-width: calc(100% - 48px); // Force word wrap instead of colliding with the switch } .mx_SettingsTab_section .mx_SettingsFlag .mx_ToggleSwitch { diff --git a/res/img/feather-icons/flag.svg b/res/img/feather-icons/flag.svg new file mode 100644 index 0000000000..983c02762b --- /dev/null +++ b/res/img/feather-icons/flag.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/components/views/dialogs/UserSettingsDialog.js b/src/components/views/dialogs/UserSettingsDialog.js index dd404ce280..e893f96a5f 100644 --- a/src/components/views/dialogs/UserSettingsDialog.js +++ b/src/components/views/dialogs/UserSettingsDialog.js @@ -21,6 +21,8 @@ import {_t, _td} from "../../../languageHandler"; import AccessibleButton from "../elements/AccessibleButton"; import GeneralSettingsTab from "../settings/tabs/GeneralSettingsTab"; import dis from '../../../dispatcher'; +import SettingsStore from "../../../settings/SettingsStore"; +import LabsSettingsTab from "../settings/tabs/LabsSettingsTab"; // TODO: Ditch this whole component export class TempTab extends React.Component { @@ -44,43 +46,52 @@ export default class UserSettingsDialog extends React.Component { }; _getTabs() { - return [ - new Tab( - _td("General"), - "mx_UserSettingsDialog_settingsIcon", - , - ), - new Tab( - _td("Notifications"), - "mx_UserSettingsDialog_bellIcon", -
Notifications Test
, - ), - new Tab( - _td("Preferences"), - "mx_UserSettingsDialog_preferencesIcon", -
Preferences Test
, - ), - new Tab( - _td("Voice & Video"), - "mx_UserSettingsDialog_voiceIcon", -
Voice Test
, - ), - new Tab( - _td("Security & Privacy"), - "mx_UserSettingsDialog_securityIcon", -
Security Test
, - ), - new Tab( - _td("Help & About"), - "mx_UserSettingsDialog_helpIcon", -
Help Test
, - ), - new Tab( - _td("Visit old settings"), - "mx_UserSettingsDialog_helpIcon", - , - ), - ]; + const tabs = []; + + tabs.push(new Tab( + _td("General"), + "mx_UserSettingsDialog_settingsIcon", + , + )); + tabs.push(new Tab( + _td("Notifications"), + "mx_UserSettingsDialog_bellIcon", +
Notifications Test
, + )); + tabs.push(new Tab( + _td("Preferences"), + "mx_UserSettingsDialog_preferencesIcon", +
Preferences Test
, + )); + tabs.push(new Tab( + _td("Voice & Video"), + "mx_UserSettingsDialog_voiceIcon", +
Voice Test
, + )); + tabs.push(new Tab( + _td("Security & Privacy"), + "mx_UserSettingsDialog_securityIcon", +
Security Test
, + )); + if (SettingsStore.getLabsFeatures().length > 0) { + tabs.push(new Tab( + _td("Labs"), + "mx_UserSettingsDialog_labsIcon", + , + )); + } + tabs.push(new Tab( + _td("Help & About"), + "mx_UserSettingsDialog_helpIcon", +
Help Test
, + )); + tabs.push(new Tab( + _td("Visit old settings"), + "mx_UserSettingsDialog_helpIcon", + , + )); + + return tabs; } render() { diff --git a/src/components/views/settings/tabs/LabsSettingsTab.js b/src/components/views/settings/tabs/LabsSettingsTab.js new file mode 100644 index 0000000000..5cda8f6cd6 --- /dev/null +++ b/src/components/views/settings/tabs/LabsSettingsTab.js @@ -0,0 +1,69 @@ +/* +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. +*/ + +import React from 'react'; +import {_t} from "../../../../languageHandler"; +import PropTypes from "prop-types"; +import SettingsStore from "../../../../settings/SettingsStore"; +import ToggleSwitch from "../../elements/ToggleSwitch"; + +export class LabsSettingToggle extends React.Component { + static propTypes = { + featureId: PropTypes.string.isRequired, + }; + + _onChange = async (checked) => { + if (this.props.featureId === "feature_lazyloading") { + const confirmed = await this._onLazyLoadChanging(checked); + if (!confirmed) { + return; + } + } + + await SettingsStore.setFeatureEnabled(this.props.featureId, checked); + this.forceUpdate(); + }; + + render() { + // This is a minimal version of a SettingsFlag + const label = _t(SettingsStore.getDisplayName(this.props.featureId)); + const value = SettingsStore.isFeatureEnabled(this.props.featureId); + return ( +
+ {label} + +
+ ); + } +} + +export default class LabsSettingsTab extends React.Component { + constructor() { + super(); + } + + render() { + const flags = SettingsStore.getLabsFeatures().map(f => ); + return ( +
+
{_t("Labs")}
+
+ {flags} +
+
+ ); + } +} diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index b9b4684e08..b2dbb5387b 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -439,6 +439,7 @@ "Deactivating your account is a permanent action - be careful!": "Deactivating your account is a permanent action - be careful!", "Close Account": "Close Account", "General": "General", + "Labs": "Labs", "Cannot add any more widgets": "Cannot add any more widgets", "The maximum permitted number of widgets have already been added to this room.": "The maximum permitted number of widgets have already been added to this room.", "Add a widget": "Add a widget", @@ -1281,7 +1282,6 @@ "Riot collects anonymous analytics to allow us to improve the application.": "Riot collects anonymous analytics to allow us to improve the application.", "Privacy is important to us, so we don't collect any personal or identifiable data for our analytics.": "Privacy is important to us, so we don't collect any personal or identifiable data for our analytics.", "Learn more about how we use analytics.": "Learn more about how we use analytics.", - "Labs": "Labs", "These are experimental features that may break in unexpected ways": "These are experimental features that may break in unexpected ways", "Use with caution": "Use with caution", "Lazy loading members not supported": "Lazy loading members not supported",