mirror of
https://github.com/vector-im/element-web.git
synced 2024-11-15 20:54:59 +08:00
Make the Manage Integrations Button defer scalar auth to the manager
This moves the responsibility of creating a URL to open from the button (and other components) to the integrations manager dialog itself. By doing this, we also cut down on scalar API calls because we don't pick up on account information until the user opens the dialog.
This commit is contained in:
parent
6cc443cd01
commit
a5f296457f
@ -29,3 +29,16 @@ limitations under the License.
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.mx_IntegrationsManager_loading h3 {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.mx_IntegrationsManager_error {
|
||||
text-align: center;
|
||||
padding-top: 20px;
|
||||
}
|
||||
|
||||
.mx_IntegrationsManager_error h3 {
|
||||
color: $warning-color;
|
||||
}
|
@ -29,6 +29,14 @@ class ScalarAuthClient {
|
||||
this.scalarToken = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if setting up a ScalarAuthClient is even possible
|
||||
* @returns {boolean} true if possible, false otherwise.
|
||||
*/
|
||||
static isPossible() {
|
||||
return SdkConfig.get()['integrations_rest_url'] && SdkConfig.get()['integrations_ui_url'];
|
||||
}
|
||||
|
||||
connect() {
|
||||
return this.getScalarToken().then((tok) => {
|
||||
this.scalarToken = tok;
|
||||
@ -41,7 +49,8 @@ class ScalarAuthClient {
|
||||
|
||||
// Returns a scalar_token string
|
||||
getScalarToken() {
|
||||
const token = window.localStorage.getItem("mx_scalar_token");
|
||||
let token = this.scalarToken;
|
||||
if (!token) token = window.localStorage.getItem("mx_scalar_token");
|
||||
|
||||
if (!token) {
|
||||
return this.registerForToken();
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
Copyright 2017 New Vector Ltd
|
||||
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.
|
||||
@ -17,10 +18,7 @@ limitations under the License.
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import sdk from '../../../index';
|
||||
import classNames from 'classnames';
|
||||
import SdkConfig from '../../../SdkConfig';
|
||||
import ScalarAuthClient from '../../../ScalarAuthClient';
|
||||
import ScalarMessaging from '../../../ScalarMessaging';
|
||||
import Modal from "../../../Modal";
|
||||
import { _t } from '../../../languageHandler';
|
||||
import AccessibleButton from './AccessibleButton';
|
||||
@ -28,85 +26,28 @@ import AccessibleButton from './AccessibleButton';
|
||||
export default class ManageIntegsButton extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
scalarError: null,
|
||||
};
|
||||
|
||||
this.onManageIntegrations = this.onManageIntegrations.bind(this);
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
ScalarMessaging.startListening();
|
||||
this.scalarClient = null;
|
||||
|
||||
if (SdkConfig.get().integrations_ui_url && SdkConfig.get().integrations_rest_url) {
|
||||
this.scalarClient = new ScalarAuthClient();
|
||||
this.scalarClient.connect().done(() => {
|
||||
this.forceUpdate();
|
||||
}, (err) => {
|
||||
this.setState({scalarError: err});
|
||||
console.error('Error whilst initialising scalarClient for ManageIntegsButton', err);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
ScalarMessaging.stopListening();
|
||||
}
|
||||
|
||||
onManageIntegrations(ev) {
|
||||
onManageIntegrations = (ev) => {
|
||||
ev.preventDefault();
|
||||
if (this.state.scalarError && !this.scalarClient.hasCredentials()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const IntegrationsManager = sdk.getComponent("views.settings.IntegrationsManager");
|
||||
this.scalarClient.connect().done(() => {
|
||||
Modal.createDialog(IntegrationsManager, {
|
||||
src: (this.scalarClient !== null && this.scalarClient.hasCredentials()) ?
|
||||
this.scalarClient.getScalarInterfaceUrlForRoom(this.props.room) :
|
||||
null,
|
||||
}, "mx_IntegrationsManager");
|
||||
}, (err) => {
|
||||
this.setState({scalarError: err});
|
||||
console.error('Error ensuring a valid scalar_token exists', err);
|
||||
});
|
||||
}
|
||||
Modal.createDialog(IntegrationsManager, {
|
||||
room: this.props.room,
|
||||
}, "mx_IntegrationsManager");
|
||||
};
|
||||
|
||||
render() {
|
||||
let integrationsButton = <div />;
|
||||
let integrationsWarningTriangle = <div />;
|
||||
let integrationsErrorPopup = <div />;
|
||||
if (this.scalarClient !== null) {
|
||||
const integrationsButtonClasses = classNames({
|
||||
mx_RoomHeader_button: true,
|
||||
mx_RoomHeader_manageIntegsButton: true,
|
||||
mx_ManageIntegsButton_error: !!this.state.scalarError,
|
||||
});
|
||||
|
||||
if (this.state.scalarError && !this.scalarClient.hasCredentials()) {
|
||||
integrationsWarningTriangle = <img
|
||||
src={require("../../../../res/img/warning.svg")}
|
||||
title={_t('Integrations Error')}
|
||||
width="17"
|
||||
/>;
|
||||
// Popup shown when hovering over integrationsButton_error (via CSS)
|
||||
integrationsErrorPopup = (
|
||||
<span className="mx_ManageIntegsButton_errorPopup">
|
||||
{ _t('Could not connect to the integration server') }
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
if (ScalarAuthClient.isPossible()) {
|
||||
const AccessibleButton = sdk.getComponent("elements.AccessibleButton");
|
||||
integrationsButton = (
|
||||
<AccessibleButton className={integrationsButtonClasses}
|
||||
<AccessibleButton
|
||||
className='mx_RoomHeader_button mx_RoomHeader_manageIntegsButton'
|
||||
title={_t("Manage Integrations")}
|
||||
onClick={this.onManageIntegrations}
|
||||
title={_t('Manage Integrations')}
|
||||
>
|
||||
{ integrationsWarningTriangle }
|
||||
{ integrationsErrorPopup }
|
||||
</AccessibleButton>
|
||||
);
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
return integrationsButton;
|
||||
|
@ -18,20 +18,68 @@ limitations under the License.
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import sdk from '../../../index';
|
||||
import MatrixClientPeg from '../../../MatrixClientPeg';
|
||||
import { _t } from '../../../languageHandler';
|
||||
import Modal from '../../../Modal';
|
||||
import dis from '../../../dispatcher';
|
||||
import ScalarAuthClient from '../../../ScalarAuthClient';
|
||||
|
||||
export default class IntegrationsManager extends React.Component {
|
||||
static propTypes = {
|
||||
// the source of the integration manager being embedded
|
||||
src: PropTypes.string.isRequired,
|
||||
// the room object where the integrations manager should be opened in
|
||||
room: PropTypes.object.isRequired,
|
||||
|
||||
// the screen name to open
|
||||
screen: PropTypes.string,
|
||||
|
||||
// the integration ID to open
|
||||
integrationId: PropTypes.string,
|
||||
|
||||
// callback when the manager is dismissed
|
||||
onFinished: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
loading: true,
|
||||
configured: ScalarAuthClient.isPossible(),
|
||||
connected: false, // true if a `src` is set and able to be connected to
|
||||
src: null, // string for where to connect to
|
||||
};
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
if (!this.state.configured) return;
|
||||
|
||||
const scalarClient = new ScalarAuthClient();
|
||||
scalarClient.connect().then(() => {
|
||||
const hasCredentials = scalarClient.hasCredentials();
|
||||
if (!hasCredentials) {
|
||||
this.setState({
|
||||
connected: false,
|
||||
loading: false,
|
||||
});
|
||||
} else {
|
||||
const src = scalarClient.getScalarInterfaceUrlForRoom(
|
||||
this.props.room,
|
||||
this.props.screen,
|
||||
this.props.integrationId,
|
||||
);
|
||||
this.setState({
|
||||
loading: false,
|
||||
connected: true,
|
||||
src: src,
|
||||
});
|
||||
}
|
||||
}).catch(err => {
|
||||
console.error(err);
|
||||
this.setState({
|
||||
loading: false,
|
||||
connected: false,
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.dispatcherRef = dis.register(this.onAction);
|
||||
document.addEventListener("keydown", this.onKeyDown);
|
||||
@ -57,6 +105,34 @@ export default class IntegrationsManager extends React.Component {
|
||||
};
|
||||
|
||||
render() {
|
||||
return <iframe src={ this.props.src }></iframe>;
|
||||
if (!this.state.configured) {
|
||||
return (
|
||||
<div className='mx_IntegrationsManager_error'>
|
||||
<h3>{_t("No integrations server configured")}</h3>
|
||||
<p>{_t("This Riot instance does not have an integrations server configured.")}</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (this.state.loading) {
|
||||
const Spinner = sdk.getComponent("elements.Spinner");
|
||||
return (
|
||||
<div className='mx_IntegrationsManager_loading'>
|
||||
<h3>{_t("Connecting to integrations server...")}</h3>
|
||||
<Spinner />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (!this.state.connected) {
|
||||
return (
|
||||
<div className='mx_IntegrationsManager_error'>
|
||||
<h3>{_t("Cannot connect to integrations server")}</h3>
|
||||
<p>{_t("The integrations server is offline or it cannot reach your homeserver.")}</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return <iframe src={this.state.src}></iframe>;
|
||||
}
|
||||
}
|
@ -483,6 +483,11 @@
|
||||
"Email Address": "Email Address",
|
||||
"Disable Notifications": "Disable Notifications",
|
||||
"Enable Notifications": "Enable Notifications",
|
||||
"No integrations server configured": "No integrations server configured",
|
||||
"This Riot instance does not have an integrations server configured.": "This Riot instance does not have an integrations server configured.",
|
||||
"Connecting to integrations server...": "Connecting to integrations server...",
|
||||
"Cannot connect to integrations server": "Cannot connect to integrations server",
|
||||
"The integrations server is offline or it cannot reach your homeserver.": "The integrations server is offline or it cannot reach your homeserver.",
|
||||
"Delete Backup": "Delete Backup",
|
||||
"Are you sure? You will lose your encrypted messages if your keys are not backed up properly.": "Are you sure? You will lose your encrypted messages if your keys are not backed up properly.",
|
||||
"Encrypted messages are secured with end-to-end encryption. Only you and the recipient(s) have the keys to read these messages.": "Encrypted messages are secured with end-to-end encryption. Only you and the recipient(s) have the keys to read these messages.",
|
||||
@ -864,6 +869,8 @@
|
||||
"This Room": "This Room",
|
||||
"All Rooms": "All Rooms",
|
||||
"Search…": "Search…",
|
||||
"Failed to connect to integrations server": "Failed to connect to integrations server",
|
||||
"No integrations server is configured to manage stickers with": "No integrations server 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",
|
||||
@ -1017,7 +1024,6 @@
|
||||
"Rotate Right": "Rotate Right",
|
||||
"Rotate clockwise": "Rotate clockwise",
|
||||
"Download this file": "Download this file",
|
||||
"Integrations Error": "Integrations Error",
|
||||
"Manage Integrations": "Manage Integrations",
|
||||
"%(nameList)s %(transitionList)s": "%(nameList)s %(transitionList)s",
|
||||
"%(severalUsers)sjoined %(count)s times|other": "%(severalUsers)sjoined %(count)s times",
|
||||
|
Loading…
Reference in New Issue
Block a user