From 94fed922cfe3c61ca3fd6169efdb1c4e54405778 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 20 Nov 2019 20:40:39 -0700 Subject: [PATCH] Intercept cases of disabled/no integration managers We already intercepted most of the cases where no integration manager was present, though there was a bug in many components where openAll() would be called regardless of an integration manager being available. The integration manager being disabled by the user is handled in the IntegrationManager classes rather than on click because we have quite a few calls to these functions. The StickerPicker is an exception because it does slightly different behaviour. This also removes the old "no integration manager configured" state from the IntegrationManager component as it is now replaced by a dialog. --- .../dialogs/IntegrationsDisabledDialog.js | 57 +++++++++++++++++++ .../dialogs/IntegrationsImpossibleDialog.js | 55 ++++++++++++++++++ src/components/views/rooms/Stickerpicker.js | 7 ++- .../views/settings/IntegrationManager.js | 13 ----- src/i18n/strings/en_EN.json | 7 ++- .../IntegrationManagerInstance.js | 6 ++ src/integrations/IntegrationManagers.js | 24 ++++++-- 7 files changed, 147 insertions(+), 22 deletions(-) create mode 100644 src/components/views/dialogs/IntegrationsDisabledDialog.js create mode 100644 src/components/views/dialogs/IntegrationsImpossibleDialog.js diff --git a/src/components/views/dialogs/IntegrationsDisabledDialog.js b/src/components/views/dialogs/IntegrationsDisabledDialog.js new file mode 100644 index 0000000000..3ab1123f8b --- /dev/null +++ b/src/components/views/dialogs/IntegrationsDisabledDialog.js @@ -0,0 +1,57 @@ +/* +Copyright 2019 The Matrix.org Foundation C.I.C. + +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 PropTypes from 'prop-types'; +import {_t} from "../../../languageHandler"; +import sdk from "../../../index"; +import dis from '../../../dispatcher'; + +export default class IntegrationsDisabledDialog extends React.Component { + static propTypes = { + onFinished: PropTypes.func.isRequired, + }; + + _onAcknowledgeClick = () => { + this.props.onFinished(); + }; + + _onOpenSettingsClick = () => { + this.props.onFinished(); + dis.dispatch({action: "view_user_settings"}); + }; + + render() { + const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); + const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); + + return ( + +
+

{_t("Enable 'Manage Integrations' in Settings to do this.")}

+
+ +
+ ); + } +} diff --git a/src/components/views/dialogs/IntegrationsImpossibleDialog.js b/src/components/views/dialogs/IntegrationsImpossibleDialog.js new file mode 100644 index 0000000000..9927f627f1 --- /dev/null +++ b/src/components/views/dialogs/IntegrationsImpossibleDialog.js @@ -0,0 +1,55 @@ +/* +Copyright 2019 The Matrix.org Foundation C.I.C. + +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 PropTypes from 'prop-types'; +import {_t} from "../../../languageHandler"; +import sdk from "../../../index"; + +export default class IntegrationsImpossibleDialog extends React.Component { + static propTypes = { + onFinished: PropTypes.func.isRequired, + }; + + _onAcknowledgeClick = () => { + this.props.onFinished(); + }; + + render() { + const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); + const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); + + return ( + +
+

+ {_t( + "Your Riot doesn't allow you to use an Integration Manager to do this. " + + "Please contact an admin.", + )} +

+
+ +
+ ); + } +} diff --git a/src/components/views/rooms/Stickerpicker.js b/src/components/views/rooms/Stickerpicker.js index 47239cf33f..d35285463a 100644 --- a/src/components/views/rooms/Stickerpicker.js +++ b/src/components/views/rooms/Stickerpicker.js @@ -77,7 +77,7 @@ export default class Stickerpicker extends React.Component { this._imError(_td("Failed to connect to integration manager"), e); }); } else { - this._imError(_td("No integration manager is configured to manage stickers with")); + IntegrationManagers.sharedInstance().openNoManagerDialog(); } } @@ -293,6 +293,11 @@ export default class Stickerpicker extends React.Component { * @param {Event} e Event that triggered the function */ _onShowStickersClick(e) { + if (!SettingsStore.getValue("integrationProvisioning")) { + // Intercept this case and spawn a warning. + return IntegrationManagers.sharedInstance().showDisabledDialog(); + } + // XXX: Simplify by using a context menu that is positioned relative to the sticker picker button const buttonRect = e.target.getBoundingClientRect(); diff --git a/src/components/views/settings/IntegrationManager.js b/src/components/views/settings/IntegrationManager.js index 97c469e9aa..1ab17ca8a0 100644 --- a/src/components/views/settings/IntegrationManager.js +++ b/src/components/views/settings/IntegrationManager.js @@ -23,9 +23,6 @@ import dis from '../../../dispatcher'; export default class IntegrationManager extends React.Component { static propTypes = { - // false to display an error saying that there is no integration manager configured - configured: PropTypes.bool.isRequired, - // false to display an error saying that we couldn't connect to the integration manager connected: PropTypes.bool.isRequired, @@ -40,7 +37,6 @@ export default class IntegrationManager extends React.Component { }; static defaultProps = { - configured: true, connected: true, loading: false, }; @@ -70,15 +66,6 @@ export default class IntegrationManager extends React.Component { }; render() { - if (!this.props.configured) { - return ( -
-

{_t("No integration manager configured")}

-

{_t("This Riot instance does not have an integration manager configured.")}

-
- ); - } - if (this.props.loading) { const Spinner = sdk.getComponent("elements.Spinner"); return ( diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 0735a8e4b3..375124b4dc 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -507,8 +507,6 @@ "Failed to set display name": "Failed to set display name", "Disable Notifications": "Disable Notifications", "Enable Notifications": "Enable Notifications", - "No integration manager configured": "No integration manager configured", - "This Riot instance does not have an integration manager configured.": "This Riot instance does not have an integration manager configured.", "Connecting to integration manager...": "Connecting to integration manager...", "Cannot connect to integration manager": "Cannot connect to integration manager", "The integration manager is offline or it cannot reach your homeserver.": "The integration manager is offline or it cannot reach your homeserver.", @@ -1020,7 +1018,6 @@ "Show Text Formatting Toolbar": "Show Text Formatting Toolbar", "Hide Text Formatting Toolbar": "Hide Text Formatting Toolbar", "Failed to connect to integration manager": "Failed to connect to integration manager", - "No integration manager is configured to manage stickers with": "No integration manager is configured to manage stickers with", "You don't currently have any stickerpacks enabled": "You don't currently have any stickerpacks enabled", "Add some now": "Add some now", "Stickerpack": "Stickerpack", @@ -1393,6 +1390,10 @@ "Verifying this user will mark their device as trusted, and also mark your device as trusted to them.": "Verifying this user will mark their device as trusted, and also mark your device as trusted to them.", "Waiting for partner to confirm...": "Waiting for partner to confirm...", "Incoming Verification Request": "Incoming Verification Request", + "Integrations are disabled": "Integrations are disabled", + "Enable 'Manage Integrations' in Settings to do this.": "Enable 'Manage Integrations' in Settings to do this.", + "Integrations not allowed": "Integrations not allowed", + "Your Riot doesn't allow you to use an Integration Manager to do this. Please contact an admin.": "Your Riot doesn't allow you to use an Integration Manager to do this. Please contact an admin.", "You added a new device '%(displayName)s', which is requesting encryption keys.": "You added a new device '%(displayName)s', which is requesting encryption keys.", "Your unverified device '%(displayName)s' is requesting encryption keys.": "Your unverified device '%(displayName)s' is requesting encryption keys.", "Start verification": "Start verification", diff --git a/src/integrations/IntegrationManagerInstance.js b/src/integrations/IntegrationManagerInstance.js index 2b616c9fed..4958209351 100644 --- a/src/integrations/IntegrationManagerInstance.js +++ b/src/integrations/IntegrationManagerInstance.js @@ -20,6 +20,8 @@ import {dialogTermsInteractionCallback, TermsNotSignedError} from "../Terms"; import type {Room} from "matrix-js-sdk"; import Modal from '../Modal'; import url from 'url'; +import SettingsStore from "../settings/SettingsStore"; +import {IntegrationManagers} from "./IntegrationManagers"; export const KIND_ACCOUNT = "account"; export const KIND_CONFIG = "config"; @@ -57,6 +59,10 @@ export class IntegrationManagerInstance { } async open(room: Room = null, screen: string = null, integrationId: string = null): void { + if (!SettingsStore.getValue("integrationProvisioning")) { + return IntegrationManagers.sharedInstance().showDisabledDialog(); + } + const IntegrationManager = sdk.getComponent("views.settings.IntegrationManager"); const dialog = Modal.createTrackedDialog( 'Integration Manager', '', IntegrationManager, diff --git a/src/integrations/IntegrationManagers.js b/src/integrations/IntegrationManagers.js index 96fd18b5b8..60ceb49dc0 100644 --- a/src/integrations/IntegrationManagers.js +++ b/src/integrations/IntegrationManagers.js @@ -22,6 +22,10 @@ import type {MatrixClient, MatrixEvent, Room} from "matrix-js-sdk"; import WidgetUtils from "../utils/WidgetUtils"; import MatrixClientPeg from "../MatrixClientPeg"; import {AutoDiscovery} from "matrix-js-sdk"; +import {_t} from "../languageHandler"; +import dis from "../dispatcher"; +import React from 'react'; +import SettingsStore from "../settings/SettingsStore"; const HS_MANAGERS_REFRESH_INTERVAL = 8 * 60 * 60 * 1000; // 8 hours const KIND_PREFERENCE = [ @@ -172,14 +176,19 @@ export class IntegrationManagers { } openNoManagerDialog(): void { - const IntegrationManager = sdk.getComponent("views.settings.IntegrationManager"); - Modal.createTrackedDialog( - "Integration Manager", "None", IntegrationManager, - {configured: false}, 'mx_IntegrationManager', - ); + const IntegrationsImpossibleDialog = sdk.getComponent("dialogs.IntegrationsImpossibleDialog"); + Modal.createTrackedDialog('Integrations impossible', '', IntegrationsImpossibleDialog); } openAll(room: Room = null, screen: string = null, integrationId: string = null): void { + if (!SettingsStore.getValue("integrationProvisioning")) { + return this.showDisabledDialog(); + } + + if (this._managers.length === 0) { + return this.openNoManagerDialog(); + } + const TabbedIntegrationManagerDialog = sdk.getComponent("views.dialogs.TabbedIntegrationManagerDialog"); Modal.createTrackedDialog( 'Tabbed Integration Manager', '', TabbedIntegrationManagerDialog, @@ -187,6 +196,11 @@ export class IntegrationManagers { ); } + showDisabledDialog(): void { + const IntegrationsDisabledDialog = sdk.getComponent("dialogs.IntegrationsDisabledDialog"); + Modal.createTrackedDialog('Integrations disabled', '', IntegrationsDisabledDialog); + } + async overwriteManagerOnAccount(manager: IntegrationManagerInstance) { // TODO: TravisR - We should be logging out of scalar clients. await WidgetUtils.removeIntegrationManagerWidgets();