diff --git a/src/components/views/context_menus/WidgetContextMenu.tsx b/src/components/views/context_menus/WidgetContextMenu.tsx index 8026942038..3c7bf0ee0e 100644 --- a/src/components/views/context_menus/WidgetContextMenu.tsx +++ b/src/components/views/context_menus/WidgetContextMenu.tsx @@ -127,7 +127,8 @@ const WidgetContextMenu: React.FC = ({ console.info("Revoking permission for widget to load: " + app.eventId); const current = SettingsStore.getValue("allowedWidgets", roomId); current[app.eventId] = false; - SettingsStore.setValue("allowedWidgets", roomId, SettingLevel.ROOM_ACCOUNT, current).catch(err => { + const level = SettingsStore.firstSupportedLevel("allowedWidgets"); + SettingsStore.setValue("allowedWidgets", roomId, level, current).catch(err => { console.error(err); // We don't really need to do anything about this - the user will just hit the button again. }); diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index 7e0ae965bb..65bc0ac6f1 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -240,7 +240,8 @@ export default class AppTile extends React.Component { console.info("Granting permission for widget to load: " + this.props.app.eventId); const current = SettingsStore.getValue("allowedWidgets", roomId); current[this.props.app.eventId] = true; - SettingsStore.setValue("allowedWidgets", roomId, SettingLevel.ROOM_ACCOUNT, current).then(() => { + const level = SettingsStore.firstSupportedLevel("allowedWidgets"); + SettingsStore.setValue("allowedWidgets", roomId, level, current).then(() => { this.setState({hasPermissionToLoad: true}); // Fetch a token for the integration manager, now that we're allowed to diff --git a/src/settings/Settings.ts b/src/settings/Settings.ts index b239b809fe..6ca009df61 100644 --- a/src/settings/Settings.ts +++ b/src/settings/Settings.ts @@ -421,7 +421,8 @@ export const SETTINGS: {[setting: string]: ISetting} = { default: true, }, "allowedWidgets": { - supportedLevels: [SettingLevel.ROOM_ACCOUNT], + supportedLevels: [SettingLevel.ROOM_ACCOUNT, SettingLevel.ROOM_DEVICE], + supportedLevelsAreOrdered: true, default: {}, // none allowed }, "analyticsOptIn": { diff --git a/src/settings/SettingsStore.ts b/src/settings/SettingsStore.ts index 82f169f498..2d024ba3f8 100644 --- a/src/settings/SettingsStore.ts +++ b/src/settings/SettingsStore.ts @@ -467,6 +467,31 @@ export default class SettingsStore { return LEVEL_HANDLERS[level].isSupported(); } + /** + * Determines the first supported level out of all the levels that can be used for a + * specific setting. + * @param {string} settingName The setting name. + * @return {SettingLevel} + */ + public static firstSupportedLevel(settingName: string): SettingLevel { + // Verify that the setting is actually a setting + const setting = SETTINGS[settingName]; + if (!setting) { + throw new Error("Setting '" + settingName + "' does not appear to be a setting."); + } + + const levelOrder = (setting.supportedLevelsAreOrdered ? setting.supportedLevels : LEVEL_ORDER); + if (!levelOrder.includes(SettingLevel.DEFAULT)) levelOrder.push(SettingLevel.DEFAULT); // always include default + + const handlers = SettingsStore.getHandlers(settingName); + + for (const level of levelOrder) { + const handler = handlers[level]; + if (!handler) continue; + return level; + } + } + /** * Debugging function for reading explicit setting values without going through the * complicated/biased functions in the SettingsStore. This will print information to