From b5d5c81f32897b54fc14979869c626405b35c09e Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sun, 29 Oct 2017 19:46:48 -0600 Subject: [PATCH] Add a new component to back various settings Signed-off-by: Travis Ralston --- src/components/structures/UserSettings.js | 94 ++++++------------- .../views/elements/SettingsCheckbox.js | 80 ++++++++++++++++ src/settings/SettingsStore.js | 11 ++- 3 files changed, 116 insertions(+), 69 deletions(-) create mode 100644 src/components/views/elements/SettingsCheckbox.js diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index 2320d7edb9..52fd48a6be 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -78,8 +78,6 @@ const SIMPLE_SETTINGS = [ { id: "VideoView.flipVideoHorizontally" }, ]; -// TODO: {Travis} Consider making generic setting handler to support `label` and `fn` optionally (backed by SettingsStore) - const ANALYTICS_SETTINGS_LABELS = [ { id: 'analyticsOptOut', @@ -682,54 +680,31 @@ module.exports = React.createClass({ UserSettingsStore.setUrlPreviewsDisabled(e.target.checked); }, - // TODO: {Travis} Make this a component () _renderSyncedSetting: function(setting) { - // TODO: this ought to be a separate component so that we don't need - // to rebind the onChange each time we render - - const onChange = (e) => { - SettingsStore.setValue(setting.id, null, "account", e.target.checked); - if (setting.fn) setting.fn(e.target.checked); - }; - - return
- - -
; + const SettingsCheckbox = sdk.getComponent("elements.SettingsCheckbox"); + return ( +
+ +
+ ); }, - // TODO: {Travis} Make this a component () - // {Travis} Maybe make that part of CheckboxSetting somehow? _renderThemeSelector: function(setting) { - // TODO: this ought to be a separate component so that we don't need - // to rebind the onChange each time we render - const onChange = (e) => { - if (e.target.checked) { - SettingsStore.setValue("theme", null, "account", setting.value); - } - dis.dispatch({ - action: 'set_theme', - value: setting.value, - }); - }; - return
- - -
; + const SettingsCheckbox = sdk.getComponent("elements.SettingsCheckbox"); + const onChange = (v) => dis.dispatch({action: 'set_theme', value: setting.value}); + return ( +
+ +
+ ); }, _renderCryptoInfo: function() { @@ -797,25 +772,16 @@ module.exports = React.createClass({ } else return (
); }, - // TODO: {Travis} Make this a component () _renderLocalSetting: function(setting) { - // TODO: this ought to be a separate component so that we don't need - // to rebind the onChange each time we render - const onChange = (e) => { - SettingsStore.setValue(setting.id, null, "device", e.target.checked); - if (setting.fn) setting.fn(e.target.checked); - }; - - return
- - -
; + const SettingsCheckbox = sdk.getComponent("elements.SettingsCheckbox"); + return ( +
+ +
+ ); }, _renderDevicesPanel: function() { diff --git a/src/components/views/elements/SettingsCheckbox.js b/src/components/views/elements/SettingsCheckbox.js new file mode 100644 index 0000000000..12f23de046 --- /dev/null +++ b/src/components/views/elements/SettingsCheckbox.js @@ -0,0 +1,80 @@ +/* +Copyright 2017 Travis Ralston + +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 SettingsStore from "../../../settings/SettingsStore"; +import { _t } from '../../../languageHandler'; + +module.exports = React.createClass({ + displayName: 'SettingsCheckbox', + propTypes: { + name: React.PropTypes.string.isRequired, + level: React.PropTypes.string.isRequired, + roomId: React.PropTypes.string, // for per-room settings + label: React.PropTypes.string, // untranslated + onChange: React.PropTypes.func, + + // If group is supplied, then this will create a radio button instead. + group: React.PropTypes.string, + value: React.PropTypes.any, // the value for the radio button + }, + + onChange: function(e) { + if (this.props.group && !e.target.checked) return; + + const newState = this.props.group ? this.props.value : e.target.checked; + SettingsStore.setValue(this.props.name, this.props.roomId, this.props.level, newState); + if (this.props.onChange) this.props.onChange(newState); + }, + + render: function() { + let val = SettingsStore.getValueAt(this.props.level, this.props.name, this.props.roomId); + + let label = this.props.label; + if (!label) label = SettingsStore.getDisplayName(this.props.name); + else label = _t(label); + + let id = this.props.name; + let checkbox = ( + + ); + if (this.props.group) { + id = this.props.group + '_' + this.props.name; + checkbox = ( + + ); + } + + return ( +
+ { checkbox } + +
+ ); + }, +}); diff --git a/src/settings/SettingsStore.js b/src/settings/SettingsStore.js index cae3a557fc..ae7049e7c9 100644 --- a/src/settings/SettingsStore.js +++ b/src/settings/SettingsStore.js @@ -159,7 +159,7 @@ const SETTINGS = { default: "light", }, "webRtcForceTURN": { - supportedLevels: ['device'], + supportedLevels: ['device', 'config'], default: false, displayName: _td('Disable Peer-to-Peer for 1:1 calls'), }, @@ -170,28 +170,29 @@ const SETTINGS = { supportedLevels: ['device'], }, "language": { - supportedLevels: ['device'], + supportedLevels: ['device', 'config'], default: "en" }, "analyticsOptOut": { - supportedLevels: ['device'], + supportedLevels: ['device', 'config'], default: false, displayName: _td('Opt out of analytics'), }, "autocompleteDelay": { - supportedLevels: ['device'], + supportedLevels: ['device', 'config'], default: 200, }, "blacklistUnverifiedDevicesPerRoom": { // TODO: {Travis} Write a migration path to support blacklistUnverifiedDevices supportedLevels: ['device'], default: {}, + displayName: _td('Never send encrypted messages to unverified devices from this device'), }, "blacklistUnverifiedDevices": { // TODO: {Travis} Write a migration path to support blacklistUnverifiedDevices supportedLevels: ['device'], default: false, - label: _td('Never send encrypted messages to unverified devices from this device'), + displayName: _td('Never send encrypted messages to unverified devices from this device'), }, };