Add SettingsLevel enum; Move settings to own file.

Signed-off-by: Travis Ralston <travpc@gmail.com>
This commit is contained in:
Travis Ralston 2017-11-03 23:19:45 -06:00
parent 893c39bfbe
commit 8282534f87
16 changed files with 259 additions and 213 deletions

View file

@ -15,7 +15,7 @@
*/
import * as Matrix from 'matrix-js-sdk';
import SettingsStore from "./settings/SettingsStore";
import SettingsStore, {SettingLevel} from "./settings/SettingsStore";
export default {
getDevices: function() {
@ -51,12 +51,12 @@ export default {
},
setAudioInput: function(deviceId) {
SettingsStore.setValue("webrtc_audioinput", null, "device", deviceId);
SettingsStore.setValue("webrtc_audioinput", null, SettingLevel.DEVICE, deviceId);
Matrix.setMatrixCallAudioInput(deviceId);
},
setVideoInput: function(deviceId) {
SettingsStore.setValue("webrtc_videoinput", null, "device", deviceId);
SettingsStore.setValue("webrtc_videoinput", null, SettingLevel.DEVICE, deviceId);
Matrix.setMatrixCallVideoInput(deviceId);
},
};

View file

@ -48,10 +48,12 @@ export default {
// TODO
},
// TODO: {Travis} Granular setting
getEnableNotifications: function() {
return Notifier.isEnabled();
},
// TODO: {Travis} Granular setting
setEnableNotifications: function(enable) {
if (!Notifier.supportsDesktopNotifications()) {
return;
@ -59,10 +61,12 @@ export default {
Notifier.setEnabled(enable);
},
// TODO: {Travis} Granular setting
getEnableNotificationBody: function() {
return Notifier.isBodyEnabled();
},
// TODO: {Travis} Granular setting
setEnableNotificationBody: function(enable) {
if (!Notifier.supportsDesktopNotifications()) {
return;
@ -70,10 +74,12 @@ export default {
Notifier.setBodyEnabled(enable);
},
// TODO: {Travis} Granular setting
getEnableAudioNotifications: function() {
return Notifier.isAudioEnabled();
},
// TODO: {Travis} Granular setting
setEnableAudioNotifications: function(enable) {
Notifier.setAudioEnabled(enable);
},

View file

@ -15,7 +15,7 @@ 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 SettingsStore from "../../settings/SettingsStore";
import SettingsStore, {SettingLevel} from "../../settings/SettingsStore";
const React = require('react');
const ReactDOM = require('react-dom');
@ -282,8 +282,8 @@ module.exports = React.createClass({
if (this._unmounted) return;
this.setState({
mediaDevices,
activeAudioInput: SettingsStore.getValueAt("device", 'webrtc_audioinput'),
activeVideoInput: SettingsStore.getValueAt("device", 'webrtc_videoinput'),
activeAudioInput: SettingsStore.getValueAt(SettingLevel.DEVICE, 'webrtc_audioinput'),
activeVideoInput: SettingsStore.getValueAt(SettingLevel.DEVICE, 'webrtc_videoinput'),
});
});
},
@ -616,7 +616,7 @@ module.exports = React.createClass({
onLanguageChange: function(newLang) {
if(this.state.language !== newLang) {
// We intentionally promote this to the account level at this point
SettingsStore.setValue("language", null, "account", newLang);
SettingsStore.setValue("language", null, SettingLevel.ACCOUNT, newLang);
this.setState({
language: newLang,
});
@ -639,7 +639,7 @@ module.exports = React.createClass({
// 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("autocompleteDelay", null, "device", e.target.value);
SettingsStore.setValue("autocompleteDelay", null, SettingLevel.DEVICE, e.target.value);
return (
<div>
<h3>{ _t("User Interface") }</h3>
@ -653,7 +653,7 @@ module.exports = React.createClass({
<td>
<input
type="number"
defaultValue={SettingsStore.getValueAt("device", "autocompleteDelay")}
defaultValue={SettingsStore.getValueAt(SettingLevel.DEVICE, "autocompleteDelay")}
onChange={onChange}
/>
</td>
@ -672,7 +672,7 @@ module.exports = React.createClass({
<div className="mx_UserSettings_toggle" key={setting.id}>
<SettingsFlag name={setting.id}
label={setting.label}
level="account"
level={SettingLevel.ACCOUNT}
onChange={setting.fn} />
</div>
);
@ -685,7 +685,7 @@ module.exports = React.createClass({
<div className="mx_UserSettings_toggle" key={setting.id + '_' + setting.value}>
<SettingsFlag name="theme"
label={setting.label}
level="account"
level={SettingLevel.ACCOUNT}
onChange={onChange}
group="theme"
value={setting.value} />
@ -764,7 +764,7 @@ module.exports = React.createClass({
<div className="mx_UserSettings_toggle" key={setting.id}>
<SettingsFlag name={setting.id}
label={setting.label}
level="device"
level={SettingLevel.DEVICE}
onChange={setting.fn} />
</div>
);

View file

@ -23,7 +23,7 @@ import * as languageHandler from '../../../languageHandler';
import sdk from '../../../index';
import Login from '../../../Login';
import PlatformPeg from '../../../PlatformPeg';
import SettingsStore from "../../../settings/SettingsStore";
import SettingsStore, {SettingLevel} from "../../../settings/SettingsStore";
// For validating phone numbers without country codes
const PHONE_NUMBER_REGEX = /^[0-9\(\)\-\s]*$/;
@ -312,7 +312,7 @@ module.exports = React.createClass({
_onLanguageChange: function(newLang) {
if(languageHandler.getCurrentLanguage() !== newLang) {
SettingsStore.setValue("language", null, "device", newLang);
SettingsStore.setValue("language", null, SettingLevel.DEVICE, newLang);
PlatformPeg.get().reload();
}
},

View file

@ -18,7 +18,7 @@ limitations under the License.
const React = require('react');
const sdk = require("../../../index");
import { _t, _tJsx } from '../../../languageHandler';
import SettingsStore from "../../../settings/SettingsStore";
import SettingsStore, {SettingLevel} from "../../../settings/SettingsStore";
module.exports = React.createClass({
@ -38,7 +38,7 @@ module.exports = React.createClass({
const roomId = this.props.room.roomId;
let previewsForAccount = null;
if (SettingsStore.getValueAt("account", "urlPreviewsEnabled")) {
if (SettingsStore.getValueAt(SettingLevel.ACCOUNT, "urlPreviewsEnabled")) {
previewsForAccount = (
_tJsx("You have <a>enabled</a> URL previews by default.", /<a>(.*?)<\/a>/, (sub)=><a href="#/settings">{ sub }</a>)
);
@ -54,14 +54,14 @@ module.exports = React.createClass({
previewsForRoom = (
<label>
<SettingsFlag name="urlPreviewsEnabled"
level="room"
level={SettingLevel.ROOM}
roomId={this.props.room.roomId}
isExplicit={true} />
</label>
);
} else {
let str = "URL previews are enabled by default for participants in this room.";
if (!SettingsStore.getValueAt("room", "urlPreviewsEnabled")) {
if (!SettingsStore.getValueAt(SettingLevel.ROOM, "urlPreviewsEnabled")) {
str = "URL previews are disabled by default for participants in this room.";
}
previewsForRoom = (<label>{ _t(str) }</label>);
@ -69,7 +69,7 @@ module.exports = React.createClass({
let previewsForRoomAccount = (
<SettingsFlag name="urlPreviewsEnabled"
level="room-account"
level={SettingLevel.ROOM_ACCOUNT}
roomId={this.props.room.roomId}
/>
);

View file

@ -22,7 +22,7 @@ import Modal from '../../../Modal';
import sdk from '../../../index';
import dis from '../../../dispatcher';
import Autocomplete from './Autocomplete';
import SettingsStore from "../../../settings/SettingsStore";
import SettingsStore, {SettingLevel} from "../../../settings/SettingsStore";
export default class MessageComposer extends React.Component {
@ -226,7 +226,7 @@ export default class MessageComposer extends React.Component {
}
onToggleFormattingClicked() {
SettingsStore.setValue("MessageComposer.showFormatting", null, "account", !this.state.showFormatting);
SettingsStore.setValue("MessageComposer.showFormatting", null, SettingLevel.DEVICE, !this.state.showFormatting);
this.setState({showFormatting: !this.state.showFormatting});
}

View file

@ -49,7 +49,7 @@ const REGEX_MATRIXTO = new RegExp(MATRIXTO_URL_PATTERN);
const REGEX_MATRIXTO_MARKDOWN_GLOBAL = new RegExp(MATRIXTO_MD_LINK_PATTERN, 'g');
import {asciiRegexp, shortnameToUnicode, emojioneList, asciiList, mapUnicodeToShort} from 'emojione';
import SettingsStore from "../../../settings/SettingsStore";
import SettingsStore, {SettingLevel} from "../../../settings/SettingsStore";
const EMOJI_SHORTNAMES = Object.keys(emojioneList);
const EMOJI_UNICODE_TO_SHORTNAME = mapUnicodeToShort();
const REGEX_EMOJI_WHITESPACE = new RegExp('(?:^|\\s)(' + asciiRegexp + ')\\s$');
@ -535,7 +535,7 @@ export default class MessageComposerInput extends React.Component {
editorState: this.createEditorState(enabled, contentState),
isRichtextEnabled: enabled,
});
SettingsStore.setValue("MessageComposerInput.isRichTextEnabled", null, "account", enabled);
SettingsStore.setValue("MessageComposerInput.isRichTextEnabled", null, SettingLevel.ACCOUNT, enabled);
}
handleKeyCommand = (command: string): boolean => {

View file

@ -24,7 +24,7 @@ import Modal from '../../../Modal';
import ObjectUtils from '../../../ObjectUtils';
import dis from '../../../dispatcher';
import AccessibleButton from '../elements/AccessibleButton';
import SettingsStore from "../../../settings/SettingsStore";
import SettingsStore, {SettingLevel} from "../../../settings/SettingsStore";
// parse a string as an integer; if the input is undefined, or cannot be parsed
@ -382,7 +382,7 @@ module.exports = React.createClass({
// TODO: {Travis} Use generic blacklistUnverifiedDevices
const blacklistUnverifiedDevicesPerRoom = SettingsStore.getValue("blacklistUnverifiedDevicesPerRoom");
blacklistUnverifiedDevicesPerRoom[this.props.room.roomId] = value;
SettingsStore.setValue("blacklistUnverifiedDevicesPerRoom", null, "device", blacklistUnverifiedDevicesPerRoom);
SettingsStore.setValue("blacklistUnverifiedDevicesPerRoom", null, SettingLevel.DEVICE, blacklistUnverifiedDevicesPerRoom);
this.props.room.setBlacklistUnverifiedDevices(value);
},

View file

@ -19,7 +19,7 @@ import request from 'browser-request';
import counterpart from 'counterpart';
import Promise from 'bluebird';
import React from 'react';
import SettingsStore from "./settings/SettingsStore";
import SettingsStore, {SettingLevel} from "./settings/SettingsStore";
const i18nFolder = 'i18n/';
@ -167,7 +167,7 @@ export function setLanguage(preferredLangs) {
}).then((langData) => {
counterpart.registerTranslations(langToUse, langData);
counterpart.setLocale(langToUse);
SettingsStore.setValue("language", null, "device", langToUse);
SettingsStore.setValue("language", null, SettingLevel.DEVICE, langToUse);
console.log("set language to " + langToUse);
// Set 'en' as fallback language:

View file

@ -50,7 +50,8 @@ export default class AccountSettingHandler extends SettingsHandler {
}
isSupported() {
return !!MatrixClientPeg.get();
const cli = MatrixClientPeg.get();
return cli !== undefined && cli !== null;
}
_getSettings(eventType = "im.vector.web.settings") {

View file

@ -59,7 +59,7 @@ export default class DeviceSettingsHandler extends SettingsHandler {
}
isSupported() {
return !!localStorage;
return localStorage !== undefined && localStorage !== null;
}
_getSettings() {

View file

@ -46,11 +46,14 @@ export default class RoomAccountSettingsHandler extends SettingsHandler {
canSetValue(settingName, roomId) {
const room = MatrixClientPeg.get().getRoom(roomId);
return !!room; // If they have the room, they can set their own account data
// If they have the room, they can set their own account data
return room !== undefined && room !== null;
}
isSupported() {
return !!MatrixClientPeg.get();
const cli = MatrixClientPeg.get();
return cli !== undefined && cli !== null;
}
_getSettings(roomId, eventType = "im.vector.settings") {

View file

@ -44,7 +44,7 @@ export default class RoomDeviceSettingsHandler extends SettingsHandler {
}
isSupported() {
return !!localStorage;
return localStorage !== undefined && localStorage !== null;
}
_getKey(settingName, roomId) {

View file

@ -53,7 +53,8 @@ export default class RoomSettingsHandler extends SettingsHandler {
}
isSupported() {
return !!MatrixClientPeg.get();
const cli = MatrixClientPeg.get();
return cli !== undefined && cli !== null;
}
_getSettings(roomId, eventType = "im.vector.web.settings") {

198
src/settings/Settings.js Normal file
View file

@ -0,0 +1,198 @@
/*
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 {_td} from '../languageHandler';
// These are just a bunch of helper arrays to avoid copy/pasting a bunch of times
const LEVELS_ROOM_SETTINGS = ['device', 'room-device', 'room-account', 'account', 'config'];
const LEVELS_ROOM_SETTINGS_WITH_ROOM = ['device', 'room-device', 'room-account', 'account', 'config', 'room'];
const LEVELS_ACCOUNT_SETTINGS = ['device', 'account', 'config'];
const LEVELS_FEATURE = ['device', 'config'];
const LEVELS_DEVICE_ONLY_SETTINGS = ['device'];
const LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG = ['device', 'config'];
export const SETTINGS = {
// EXAMPLE SETTING:
// "my-setting": {
// // Required by features, optional otherwise
// isFeature: false,
//
// // Recommended.
// displayName: _td("Cool Name"),
//
// // Required.
// supportedLevels: [
// // The order does not matter.
//
// "device", // Affects the current device only
// "room-device", // Affects the current room on the current device
// "room-account", // Affects the current room for the current account
// "account", // Affects the current account
// "room", // Affects the current room (controlled by room admins)
// "config", // Affects the current application
//
// // "default" is always supported and does not get listed here.
// ],
//
// // Optional. Any data type.
// default: {
// your: "value",
// },
// },
"feature_groups": {
isFeature: true,
displayName: _td("Communities"),
supportedLevels: LEVELS_FEATURE,
},
"feature_pinning": {
isFeature: true,
displayName: _td("Message Pinning"),
supportedLevels: LEVELS_FEATURE,
},
"MessageComposerInput.dontSuggestEmoji": {
supportedLevels: LEVELS_ACCOUNT_SETTINGS,
displayName: _td('Disable Emoji suggestions while typing'),
default: false,
},
"useCompactLayout": {
supportedLevels: LEVELS_ACCOUNT_SETTINGS,
displayName: _td('Use compact timeline layout'),
default: false,
},
"hideRedactions": {
supportedLevels: LEVELS_ROOM_SETTINGS_WITH_ROOM,
displayName: _td('Hide removed messages'),
default: false,
},
"hideJoinLeaves": {
supportedLevels: LEVELS_ROOM_SETTINGS_WITH_ROOM,
displayName: _td('Hide join/leave messages (invites/kicks/bans unaffected)'),
default: false,
},
"hideAvatarDisplaynameChanges": {
supportedLevels: LEVELS_ROOM_SETTINGS_WITH_ROOM,
displayName: _td('Hide avatar and display name changes'),
default: false,
},
"hideReadReceipts": {
supportedLevels: LEVELS_ROOM_SETTINGS,
displayName: _td('Hide read receipts'),
default: false,
},
"showTwelveHourTimestamps": {
supportedLevels: LEVELS_ACCOUNT_SETTINGS,
displayName: _td('Show timestamps in 12 hour format (e.g. 2:30pm)'),
default: false,
},
"alwaysShowTimestamps": {
supportedLevels: LEVELS_ACCOUNT_SETTINGS,
displayName: _td('Always show message timestamps'),
default: false,
},
"autoplayGifsAndVideos": {
supportedLevels: LEVELS_ACCOUNT_SETTINGS,
displayName: _td('Autoplay GIFs and videos'),
default: false,
},
"enableSyntaxHighlightLanguageDetection": {
supportedLevels: LEVELS_ACCOUNT_SETTINGS,
displayName: _td('Enable automatic language detection for syntax highlighting'),
default: false,
},
"Pill.shouldHidePillAvatar": {
supportedLevels: LEVELS_ACCOUNT_SETTINGS,
displayName: _td('Hide avatars in user and room mentions'),
default: false,
},
"TextualBody.disableBigEmoji": {
supportedLevels: LEVELS_ACCOUNT_SETTINGS,
displayName: _td('Disable big emoji in chat'),
default: false,
},
"MessageComposerInput.isRichTextEnabled": {
supportedLevels: LEVELS_ACCOUNT_SETTINGS,
default: false,
},
"MessageComposer.showFormatting": {
supportedLevels: LEVELS_ACCOUNT_SETTINGS,
default: false,
},
"dontSendTypingNotifications": {
supportedLevels: LEVELS_ACCOUNT_SETTINGS,
displayName: _td("Don't send typing notifications"),
default: false,
},
"MessageComposerInput.autoReplaceEmoji": {
supportedLevels: LEVELS_ACCOUNT_SETTINGS,
displayName: _td('Automatically replace plain text Emoji'),
default: false,
},
"VideoView.flipVideoHorizontally": {
supportedLevels: LEVELS_ACCOUNT_SETTINGS,
displayName: _td('Mirror local video feed'),
default: false,
},
"theme": {
supportedLevels: LEVELS_ACCOUNT_SETTINGS,
default: "light",
},
"webRtcForceTURN": {
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG,
displayName: _td('Disable Peer-to-Peer for 1:1 calls'),
default: false,
},
"webrtc_audioinput": {
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS,
},
"webrtc_videoinput": {
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS,
},
"language": {
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG,
default: "en"
},
"analyticsOptOut": {
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG,
displayName: _td('Opt out of analytics'),
default: false,
},
"autocompleteDelay": {
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG,
default: 200,
},
"blacklistUnverifiedDevicesPerRoom": {
// TODO: {Travis} Write a migration path to support blacklistUnverifiedDevices
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS,
displayName: _td('Never send encrypted messages to unverified devices from this device'),
default: {},
},
"blacklistUnverifiedDevices": {
// TODO: {Travis} Write a migration path to support blacklistUnverifiedDevices
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS,
displayName: _td('Never send encrypted messages to unverified devices from this device'),
default: false,
},
"urlPreviewsEnabled": {
supportedLevels: LEVELS_ROOM_SETTINGS_WITH_ROOM,
displayName: {
"default": _td('Enable inline URL previews by default'),
"room-account": _td("Enable URL previews for this room (only affects you)"),
"room": _td("Enable URL previews by default for participants in this room"),
},
default: true,
},
};

View file

@ -22,190 +22,27 @@ import RoomAccountSettingsHandler from "./RoomAccountSettingsHandler";
import AccountSettingsHandler from "./AccountSettingsHandler";
import RoomSettingsHandler from "./RoomSettingsHandler";
import ConfigSettingsHandler from "./ConfigSettingsHandler";
import {_t, _td} from '../languageHandler';
import {_t} from '../languageHandler';
import SdkConfig from "../SdkConfig";
import {SETTINGS} from "./Settings";
// Preset levels for room-based settings (eg: URL previews).
// Doesn't include 'room' because most settings don't need it. Use .concat('room') to add.
const LEVELS_PRESET_ROOM = ['device', 'room-device', 'room-account', 'account', 'config'];
// Preset levels for account-based settings (eg: interface language).
const LEVELS_PRESET_ACCOUNT = ['device', 'account', 'config'];
// Preset levels for features (labs) settings.
const LEVELS_PRESET_FEATURE = ['device', 'config'];
const SETTINGS = {
// EXAMPLE SETTING:
// "my-setting": {
// // Required by features, optional otherwise
// isFeature: false,
// displayName: _td("Cool Name"),
//
// // Required.
// supportedLevels: [
// // The order does not matter.
//
// "device", // Affects the current device only
// "room-device", // Affects the current room on the current device
// "room-account", // Affects the current room for the current account
// "account", // Affects the current account
// "room", // Affects the current room (controlled by room admins)
// "config", // Affects the current application
//
// // "default" is always supported and does not get listed here.
// ],
//
// // Optional. Any data type.
// default: {
// your: "value",
// },
// },
"feature_groups": {
isFeature: true,
displayName: _td("Communities"),
supportedLevels: LEVELS_PRESET_FEATURE,
},
"feature_pinning": {
isFeature: true,
displayName: _td("Message Pinning"),
supportedLevels: LEVELS_PRESET_FEATURE,
},
"MessageComposerInput.dontSuggestEmoji": {
supportedLevels: LEVELS_PRESET_ACCOUNT,
default: false,
displayName: _td('Disable Emoji suggestions while typing'),
},
"useCompactLayout": {
supportedLevels: LEVELS_PRESET_ACCOUNT,
default: false,
displayName: _td('Use compact timeline layout'),
},
"hideRedactions": {
supportedLevels: LEVELS_PRESET_ROOM.concat("room"),
default: false,
displayName: _td('Hide removed messages'),
},
"hideJoinLeaves": {
supportedLevels: LEVELS_PRESET_ROOM.concat("room"),
default: false,
displayName: _td('Hide join/leave messages (invites/kicks/bans unaffected)'),
},
"hideAvatarDisplaynameChanges": {
supportedLevels: LEVELS_PRESET_ROOM.concat("room"),
default: false,
displayName: _td('Hide avatar and display name changes'),
},
"hideReadReceipts": {
supportedLevels: LEVELS_PRESET_ROOM,
default: false,
displayName: _td('Hide read receipts'),
},
"showTwelveHourTimestamps": {
supportedLevels: LEVELS_PRESET_ACCOUNT,
default: false,
displayName: _td('Show timestamps in 12 hour format (e.g. 2:30pm)'),
},
"alwaysShowTimestamps": {
supportedLevels: LEVELS_PRESET_ACCOUNT,
default: false,
displayName: _td('Always show message timestamps'),
},
"autoplayGifsAndVideos": {
supportedLevels: LEVELS_PRESET_ACCOUNT,
default: false,
displayName: _td('Autoplay GIFs and videos'),
},
"enableSyntaxHighlightLanguageDetection": {
supportedLevels: LEVELS_PRESET_ACCOUNT,
default: false,
displayName: _td('Enable automatic language detection for syntax highlighting'),
},
"Pill.shouldHidePillAvatar": {
supportedLevels: LEVELS_PRESET_ACCOUNT,
default: false,
displayName: _td('Hide avatars in user and room mentions'),
},
"TextualBody.disableBigEmoji": {
supportedLevels: LEVELS_PRESET_ACCOUNT,
default: false,
displayName: _td('Disable big emoji in chat'),
},
"MessageComposerInput.isRichTextEnabled": {
supportedLevels: LEVELS_PRESET_ACCOUNT,
default: false,
},
"MessageComposer.showFormatting": {
supportedLevels: LEVELS_PRESET_ACCOUNT,
default: false,
},
"dontSendTypingNotifications": {
supportedLevels: LEVELS_PRESET_ACCOUNT,
default: false,
displayName: _td("Don't send typing notifications"),
},
"MessageComposerInput.autoReplaceEmoji": {
supportedLevels: LEVELS_PRESET_ACCOUNT,
default: false,
displayName: _td('Automatically replace plain text Emoji'),
},
"VideoView.flipVideoHorizontally": {
supportedLevels: LEVELS_PRESET_ACCOUNT,
default: false,
displayName: _td('Mirror local video feed'),
},
"theme": {
supportedLevels: LEVELS_PRESET_ACCOUNT,
default: "light",
},
"webRtcForceTURN": {
supportedLevels: ['device', 'config'],
default: false,
displayName: _td('Disable Peer-to-Peer for 1:1 calls'),
},
"webrtc_audioinput": {
supportedLevels: ['device'],
},
"webrtc_videoinput": {
supportedLevels: ['device'],
},
"language": {
supportedLevels: ['device', 'config'],
default: "en"
},
"analyticsOptOut": {
supportedLevels: ['device', 'config'],
default: false,
displayName: _td('Opt out of analytics'),
},
"autocompleteDelay": {
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,
displayName: _td('Never send encrypted messages to unverified devices from this device'),
},
"urlPreviewsEnabled": {
supportedLevels: LEVELS_PRESET_ROOM.concat("room"),
default: true,
displayName: {
"default": _td('Enable inline URL previews by default'),
"room-account": _td("Enable URL previews for this room (only affects you)"),
"room": _td("Enable URL previews by default for participants in this room"),
},
},
/**
* Represents the various setting levels supported by the SettingsStore.
*/
export const SettingLevel = {
// Note: This enum is not used in this class or in the Settings file
// This should always be used elsewhere in the project.
DEVICE: "device",
ROOM_DEVICE: "room-device",
ROOM_ACCOUNT: "room-account",
ACCOUNT: "account",
ROOM: "room",
CONFIG: "config",
DEFAULT: "default",
};
// Convert the above into simpler formats for the handlers
// Convert the settings to easier to manage objects for the handlers
const defaultSettings = {};
const featureNames = [];
for (const key of Object.keys(SETTINGS)) {