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.
This commit is contained in:
Travis Ralston 2019-11-20 20:40:39 -07:00
parent 81c9bdd9f3
commit 94fed922cf
7 changed files with 147 additions and 22 deletions

View file

@ -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 (
<BaseDialog className='mx_IntegrationsDisabledDialog' hasCancel={true}
onFinished={this.props.onFinished}
title={_t("Integrations are disabled")}>
<div className='mx_IntegrationsDisabledDialog_content'>
<p>{_t("Enable 'Manage Integrations' in Settings to do this.")}</p>
</div>
<DialogButtons
primaryButton={_t("Settings")}
onPrimaryButtonClick={this._onOpenSettingsClick}
cancelButton={_t("OK")}
onCancel={this._onAcknowledgeClick}
/>
</BaseDialog>
);
}
}

View file

@ -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 (
<BaseDialog className='mx_IntegrationsImpossibleDialog' hasCancel={false}
onFinished={this.props.onFinished}
title={_t("Integrations not allowed")}>
<div className='mx_IntegrationsImpossibleDialog_content'>
<p>
{_t(
"Your Riot doesn't allow you to use an Integration Manager to do this. " +
"Please contact an admin.",
)}
</p>
</div>
<DialogButtons
primaryButton={_t("OK")}
onPrimaryButtonClick={this._onAcknowledgeClick}
hasCancel={false}
/>
</BaseDialog>
);
}
}

View file

@ -77,7 +77,7 @@ export default class Stickerpicker extends React.Component {
this._imError(_td("Failed to connect to integration manager"), e); this._imError(_td("Failed to connect to integration manager"), e);
}); });
} else { } 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 * @param {Event} e Event that triggered the function
*/ */
_onShowStickersClick(e) { _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 // XXX: Simplify by using a context menu that is positioned relative to the sticker picker button
const buttonRect = e.target.getBoundingClientRect(); const buttonRect = e.target.getBoundingClientRect();

View file

@ -23,9 +23,6 @@ import dis from '../../../dispatcher';
export default class IntegrationManager extends React.Component { export default class IntegrationManager extends React.Component {
static propTypes = { 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 // false to display an error saying that we couldn't connect to the integration manager
connected: PropTypes.bool.isRequired, connected: PropTypes.bool.isRequired,
@ -40,7 +37,6 @@ export default class IntegrationManager extends React.Component {
}; };
static defaultProps = { static defaultProps = {
configured: true,
connected: true, connected: true,
loading: false, loading: false,
}; };
@ -70,15 +66,6 @@ export default class IntegrationManager extends React.Component {
}; };
render() { render() {
if (!this.props.configured) {
return (
<div className='mx_IntegrationManager_error'>
<h3>{_t("No integration manager configured")}</h3>
<p>{_t("This Riot instance does not have an integration manager configured.")}</p>
</div>
);
}
if (this.props.loading) { if (this.props.loading) {
const Spinner = sdk.getComponent("elements.Spinner"); const Spinner = sdk.getComponent("elements.Spinner");
return ( return (

View file

@ -507,8 +507,6 @@
"Failed to set display name": "Failed to set display name", "Failed to set display name": "Failed to set display name",
"Disable Notifications": "Disable Notifications", "Disable Notifications": "Disable Notifications",
"Enable Notifications": "Enable 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...", "Connecting to integration manager...": "Connecting to integration manager...",
"Cannot connect to integration manager": "Cannot connect 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.", "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", "Show Text Formatting Toolbar": "Show Text Formatting Toolbar",
"Hide Text Formatting Toolbar": "Hide Text Formatting Toolbar", "Hide Text Formatting Toolbar": "Hide Text Formatting Toolbar",
"Failed to connect to integration manager": "Failed to connect to integration manager", "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", "You don't currently have any stickerpacks enabled": "You don't currently have any stickerpacks enabled",
"Add some now": "Add some now", "Add some now": "Add some now",
"Stickerpack": "Stickerpack", "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.", "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...", "Waiting for partner to confirm...": "Waiting for partner to confirm...",
"Incoming Verification Request": "Incoming Verification Request", "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.", "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.", "Your unverified device '%(displayName)s' is requesting encryption keys.": "Your unverified device '%(displayName)s' is requesting encryption keys.",
"Start verification": "Start verification", "Start verification": "Start verification",

View file

@ -20,6 +20,8 @@ import {dialogTermsInteractionCallback, TermsNotSignedError} from "../Terms";
import type {Room} from "matrix-js-sdk"; import type {Room} from "matrix-js-sdk";
import Modal from '../Modal'; import Modal from '../Modal';
import url from 'url'; import url from 'url';
import SettingsStore from "../settings/SettingsStore";
import {IntegrationManagers} from "./IntegrationManagers";
export const KIND_ACCOUNT = "account"; export const KIND_ACCOUNT = "account";
export const KIND_CONFIG = "config"; export const KIND_CONFIG = "config";
@ -57,6 +59,10 @@ export class IntegrationManagerInstance {
} }
async open(room: Room = null, screen: string = null, integrationId: string = null): void { 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 IntegrationManager = sdk.getComponent("views.settings.IntegrationManager");
const dialog = Modal.createTrackedDialog( const dialog = Modal.createTrackedDialog(
'Integration Manager', '', IntegrationManager, 'Integration Manager', '', IntegrationManager,

View file

@ -22,6 +22,10 @@ import type {MatrixClient, MatrixEvent, Room} from "matrix-js-sdk";
import WidgetUtils from "../utils/WidgetUtils"; import WidgetUtils from "../utils/WidgetUtils";
import MatrixClientPeg from "../MatrixClientPeg"; import MatrixClientPeg from "../MatrixClientPeg";
import {AutoDiscovery} from "matrix-js-sdk"; 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 HS_MANAGERS_REFRESH_INTERVAL = 8 * 60 * 60 * 1000; // 8 hours
const KIND_PREFERENCE = [ const KIND_PREFERENCE = [
@ -172,14 +176,19 @@ export class IntegrationManagers {
} }
openNoManagerDialog(): void { openNoManagerDialog(): void {
const IntegrationManager = sdk.getComponent("views.settings.IntegrationManager"); const IntegrationsImpossibleDialog = sdk.getComponent("dialogs.IntegrationsImpossibleDialog");
Modal.createTrackedDialog( Modal.createTrackedDialog('Integrations impossible', '', IntegrationsImpossibleDialog);
"Integration Manager", "None", IntegrationManager,
{configured: false}, 'mx_IntegrationManager',
);
} }
openAll(room: Room = null, screen: string = null, integrationId: string = null): void { 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"); const TabbedIntegrationManagerDialog = sdk.getComponent("views.dialogs.TabbedIntegrationManagerDialog");
Modal.createTrackedDialog( Modal.createTrackedDialog(
'Tabbed Integration Manager', '', TabbedIntegrationManagerDialog, '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) { async overwriteManagerOnAccount(manager: IntegrationManagerInstance) {
// TODO: TravisR - We should be logging out of scalar clients. // TODO: TravisR - We should be logging out of scalar clients.
await WidgetUtils.removeIntegrationManagerWidgets(); await WidgetUtils.removeIntegrationManagerWidgets();