diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index 37005b0d69d..05ed9c95edb 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -891,7 +891,7 @@ module.exports = React.createClass({ */ _onSetTheme: function(theme) { if (!theme) { - theme = this.props.config.default_theme || 'light'; + theme = SettingsStore.getValueAt(SettingLevel.DEFAULT, "theme"); } // look for the stylesheet elements. diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index 692dd4e01d0..794c0d5d4d9 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -613,8 +613,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, SettingLevel.ACCOUNT, newLang); + SettingsStore.setValue("language", null, SettingLevel.DEVICE, newLang); this.setState({ language: newLang, }); diff --git a/src/components/views/room_settings/UrlPreviewSettings.js b/src/components/views/room_settings/UrlPreviewSettings.js index ec690f76e81..6491bb0e09c 100644 --- a/src/components/views/room_settings/UrlPreviewSettings.js +++ b/src/components/views/room_settings/UrlPreviewSettings.js @@ -17,7 +17,7 @@ limitations under the License. const React = require('react'); const sdk = require("../../../index"); -import { _t } from '../../../languageHandler'; +import { _t, _td } from '../../../languageHandler'; import SettingsStore, {SettingLevel} from "../../../settings/SettingsStore"; @@ -63,9 +63,9 @@ module.exports = React.createClass({ ); } else { - let str = "URL previews are enabled by default for participants in this room."; + let str = _td("URL previews are enabled by default for participants in this room."); if (!SettingsStore.getValueAt(SettingLevel.ROOM, "urlPreviewsEnabled")) { - str = "URL previews are disabled by default for participants in this room."; + str = _td("URL previews are disabled by default for participants in this room."); } previewsForRoom = (); } diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 7624a60c948..128a07bc15e 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -227,6 +227,8 @@ "Delete": "Delete", "Disable Notifications": "Disable Notifications", "Enable Notifications": "Enable Notifications", + "URL previews are enabled by default for participants in this room.": "URL previews are enabled by default for participants in this room.", + "URL previews are disabled by default for participants in this room.": "URL previews are disabled by default for participants in this room.", "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", diff --git a/src/settings/SettingsStore.js b/src/settings/SettingsStore.js index b6343c4a963..d93a48005df 100644 --- a/src/settings/SettingsStore.js +++ b/src/settings/SettingsStore.js @@ -176,13 +176,21 @@ export default class SettingsStore { * @return {*} The value, or null if not found */ static getValue(settingName, roomId = null, excludeDefault = false) { - return SettingsStore.getValueAt(LEVEL_ORDER[0], settingName, roomId, false, excludeDefault); + // Verify that the setting is actually a setting + if (!SETTINGS[settingName]) { + throw new Error("Setting '" + settingName + "' does not appear to be a setting."); + } + + const setting = SETTINGS[settingName]; + const levelOrder = (setting.supportedLevelsAreOrdered ? setting.supportedLevels : LEVEL_ORDER); + + return SettingsStore.getValueAt(levelOrder[0], settingName, roomId, false, excludeDefault); } /** * Gets a setting's value at a particular level, ignoring all levels that are more specific. - * @param {"device"|"room-device"|"room-account"|"account"|"room"} level The level to - * look at. + * @param {"device"|"room-device"|"room-account"|"account"|"room"|"config"|"default"} level The + * level to look at. * @param {string} settingName The name of the setting to read. * @param {String} roomId The room ID to read the setting value in, may be null. * @param {boolean} explicit If true, this method will not consider other levels, just the one diff --git a/src/settings/controllers/NotificationControllers.js b/src/settings/controllers/NotificationControllers.js index 261e194d743..9dcf78e26b9 100644 --- a/src/settings/controllers/NotificationControllers.js +++ b/src/settings/controllers/NotificationControllers.js @@ -15,12 +15,35 @@ limitations under the License. */ import SettingController from "./SettingController"; +import MatrixClientPeg from '../../MatrixClientPeg'; + +// XXX: This feels wrong. +import PushProcessor from "matrix-js-sdk/lib/pushprocessor"; + +function isMasterRuleEnabled() { + // Return the value of the master push rule as a default + const processor = new PushProcessor(MatrixClientPeg.get()); + const masterRule = processor.getPushRuleById(".m.rule.master"); + + if (!masterRule) { + console.warn("No master push rule! Notifications are disabled for this user."); + return false; + } + + // Why enabled == false means "enabled" is beyond me. + return !masterRule.enabled; +} export class NotificationsEnabledController extends SettingController { getValueOverride(level, roomId, calculatedValue) { const Notifier = require('../../Notifier'); // avoids cyclical references + if (!Notifier.isPossible()) return false; + + if (calculatedValue === null) { + return isMasterRuleEnabled(); + } - return calculatedValue && Notifier.isPossible(); + return calculatedValue; } onChange(level, roomId, newValue) { @@ -35,15 +58,22 @@ export class NotificationsEnabledController extends SettingController { export class NotificationBodyEnabledController extends SettingController { getValueOverride(level, roomId, calculatedValue) { const Notifier = require('../../Notifier'); // avoids cyclical references + if (!Notifier.isPossible()) return false; + + if (calculatedValue === null) { + return isMasterRuleEnabled(); + } - return calculatedValue && Notifier.isEnabled(); + return calculatedValue; } } export class AudioNotificationsEnabledController extends SettingController { getValueOverride(level, roomId, calculatedValue) { const Notifier = require('../../Notifier'); // avoids cyclical references + if (!Notifier.isPossible()) return false; - return calculatedValue && Notifier.isEnabled(); + // Note: Audio notifications are *not* enabled by default. + return calculatedValue; } } diff --git a/src/settings/handlers/AccountSettingsHandler.js b/src/settings/handlers/AccountSettingsHandler.js index fe0ad2a5004..e50358a728b 100644 --- a/src/settings/handlers/AccountSettingsHandler.js +++ b/src/settings/handlers/AccountSettingsHandler.js @@ -26,6 +26,9 @@ export default class AccountSettingHandler extends SettingsHandler { // Special case URL previews if (settingName === "urlPreviewsEnabled") { const content = this._getSettings("org.matrix.preview_urls"); + + // Check to make sure that we actually got a boolean + if (typeof(content['disable']) !== "boolean") return null; return !content['disable']; } diff --git a/src/settings/handlers/DeviceSettingsHandler.js b/src/settings/handlers/DeviceSettingsHandler.js index 7b5ec6a5dd6..22f6140a800 100644 --- a/src/settings/handlers/DeviceSettingsHandler.js +++ b/src/settings/handlers/DeviceSettingsHandler.js @@ -40,11 +40,17 @@ export default class DeviceSettingsHandler extends SettingsHandler { // Special case notifications if (settingName === "notificationsEnabled") { - return localStorage.getItem("notifications_enabled") === "true"; + const value = localStorage.getItem("notifications_enabled"); + if (typeof(value) === "string") return value === "true"; + return null; // wrong type or otherwise not set } else if (settingName === "notificationBodyEnabled") { - return localStorage.getItem("notifications_body_enabled") === "true"; + const value = localStorage.getItem("notifications_body_enabled"); + if (typeof(value) === "string") return value === "true"; + return null; // wrong type or otherwise not set } else if (settingName === "audioNotificationsEnabled") { - return localStorage.getItem("audio_notifications_enabled") === "true"; + const value = localStorage.getItem("audio_notifications_enabled"); + if (typeof(value) === "string") return value === "true"; + return null; // wrong type or otherwise not set } return this._getSettings()[settingName]; diff --git a/src/settings/handlers/RoomAccountSettingsHandler.js b/src/settings/handlers/RoomAccountSettingsHandler.js index 503d5de6c40..e9465818071 100644 --- a/src/settings/handlers/RoomAccountSettingsHandler.js +++ b/src/settings/handlers/RoomAccountSettingsHandler.js @@ -25,6 +25,9 @@ export default class RoomAccountSettingsHandler extends SettingsHandler { // Special case URL previews if (settingName === "urlPreviewsEnabled") { const content = this._getSettings(roomId, "org.matrix.room.preview_urls"); + + // Check to make sure that we actually got a boolean + if (typeof(content['disable']) !== "boolean") return null; return !content['disable']; } diff --git a/src/settings/handlers/RoomSettingsHandler.js b/src/settings/handlers/RoomSettingsHandler.js index 3aee0dd6ebd..cb3e836c7f1 100644 --- a/src/settings/handlers/RoomSettingsHandler.js +++ b/src/settings/handlers/RoomSettingsHandler.js @@ -25,6 +25,9 @@ export default class RoomSettingsHandler extends SettingsHandler { // Special case URL previews if (settingName === "urlPreviewsEnabled") { const content = this._getSettings(roomId, "org.matrix.room.preview_urls"); + + // Check to make sure that we actually got a boolean + if (typeof(content['disable']) !== "boolean") return null; return !content['disable']; }