mirror of
https://github.com/element-hq/element-web
synced 2024-11-24 02:05:45 +03:00
Merge pull request #2372 from matrix-org/dbkr/electron_sandbox
React-sdk changes to support sandboxed electron
This commit is contained in:
commit
1ca91370f3
3 changed files with 25 additions and 61 deletions
|
@ -3,6 +3,7 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2016 Aviral Dasgupta
|
Copyright 2016 Aviral Dasgupta
|
||||||
Copyright 2016 OpenMarket Ltd
|
Copyright 2016 OpenMarket Ltd
|
||||||
|
Copyright 2018 New Vector Ltd
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -105,11 +106,6 @@ export default class BasePlatform {
|
||||||
return "Not implemented";
|
return "Not implemented";
|
||||||
}
|
}
|
||||||
|
|
||||||
isElectron(): boolean { return false; }
|
|
||||||
|
|
||||||
setupScreenSharingForIframe() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Restarts the application, without neccessarily reloading
|
* Restarts the application, without neccessarily reloading
|
||||||
* any application code
|
* any application code
|
||||||
|
|
|
@ -188,9 +188,11 @@ module.exports = React.createClass({
|
||||||
phase: "UserSettings.LOADING", // LOADING, DISPLAY
|
phase: "UserSettings.LOADING", // LOADING, DISPLAY
|
||||||
email_add_pending: false,
|
email_add_pending: false,
|
||||||
vectorVersion: undefined,
|
vectorVersion: undefined,
|
||||||
|
canSelfUpdate: null,
|
||||||
rejectingInvites: false,
|
rejectingInvites: false,
|
||||||
mediaDevices: null,
|
mediaDevices: null,
|
||||||
ignoredUsers: [],
|
ignoredUsers: [],
|
||||||
|
autoLaunchEnabled: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -209,6 +211,13 @@ module.exports = React.createClass({
|
||||||
}, (e) => {
|
}, (e) => {
|
||||||
console.log("Failed to fetch app version", e);
|
console.log("Failed to fetch app version", e);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
PlatformPeg.get().canSelfUpdate().then((canUpdate) => {
|
||||||
|
if (this._unmounted) return;
|
||||||
|
this.setState({
|
||||||
|
canSelfUpdate: canUpdate,
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
this._refreshMediaDevices();
|
this._refreshMediaDevices();
|
||||||
|
@ -227,11 +236,12 @@ module.exports = React.createClass({
|
||||||
});
|
});
|
||||||
this._refreshFromServer();
|
this._refreshFromServer();
|
||||||
|
|
||||||
if (PlatformPeg.get().isElectron()) {
|
if (PlatformPeg.get().supportsAutoLaunch()) {
|
||||||
const {ipcRenderer} = require('electron');
|
PlatformPeg.get().getAutoLaunchEnabled().then(enabled => {
|
||||||
|
this.setState({
|
||||||
ipcRenderer.on('settings', this._electronSettings);
|
autoLaunchEnabled: enabled,
|
||||||
ipcRenderer.send('settings_get');
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
|
@ -262,11 +272,6 @@ module.exports = React.createClass({
|
||||||
if (cli) {
|
if (cli) {
|
||||||
cli.removeListener("RoomMember.membership", this._onInviteStateChange);
|
cli.removeListener("RoomMember.membership", this._onInviteStateChange);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PlatformPeg.get().isElectron()) {
|
|
||||||
const {ipcRenderer} = require('electron');
|
|
||||||
ipcRenderer.removeListener('settings', this._electronSettings);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// `UserSettings` assumes that the client peg will not be null, so give it some
|
// `UserSettings` assumes that the client peg will not be null, so give it some
|
||||||
|
@ -285,10 +290,6 @@ module.exports = React.createClass({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
_electronSettings: function(ev, settings) {
|
|
||||||
this.setState({ electron_settings: settings });
|
|
||||||
},
|
|
||||||
|
|
||||||
_refreshMediaDevices: function(stream) {
|
_refreshMediaDevices: function(stream) {
|
||||||
if (stream) {
|
if (stream) {
|
||||||
// kill stream so that we don't leave it lingering around with webcam enabled etc
|
// kill stream so that we don't leave it lingering around with webcam enabled etc
|
||||||
|
@ -967,7 +968,7 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
_renderCheckUpdate: function() {
|
_renderCheckUpdate: function() {
|
||||||
const platform = PlatformPeg.get();
|
const platform = PlatformPeg.get();
|
||||||
if ('canSelfUpdate' in platform && platform.canSelfUpdate() && 'startUpdateCheck' in platform) {
|
if (this.state.canSelfUpdate) {
|
||||||
return <div>
|
return <div>
|
||||||
<h3>{ _t('Updates') }</h3>
|
<h3>{ _t('Updates') }</h3>
|
||||||
<div className="mx_UserSettings_section">
|
<div className="mx_UserSettings_section">
|
||||||
|
@ -1012,8 +1013,7 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
_renderElectronSettings: function() {
|
_renderElectronSettings: function() {
|
||||||
const settings = this.state.electron_settings;
|
if (!PlatformPeg.get().supportsAutoLaunch()) return;
|
||||||
if (!settings) return;
|
|
||||||
|
|
||||||
// TODO: This should probably be a granular setting, but it only applies to electron
|
// TODO: This should probably be a granular setting, but it only applies to electron
|
||||||
// and ends up being get/set outside of matrix anyways (local system setting).
|
// and ends up being get/set outside of matrix anyways (local system setting).
|
||||||
|
@ -1023,7 +1023,7 @@ module.exports = React.createClass({
|
||||||
<div className="mx_UserSettings_toggle">
|
<div className="mx_UserSettings_toggle">
|
||||||
<input type="checkbox"
|
<input type="checkbox"
|
||||||
name="auto-launch"
|
name="auto-launch"
|
||||||
defaultChecked={settings['auto-launch']}
|
defaultChecked={this.state.autoLaunchEnabled}
|
||||||
onChange={this._onAutoLaunchChanged}
|
onChange={this._onAutoLaunchChanged}
|
||||||
/>
|
/>
|
||||||
<label htmlFor="auto-launch">{ _t('Start automatically after system login') }</label>
|
<label htmlFor="auto-launch">{ _t('Start automatically after system login') }</label>
|
||||||
|
@ -1033,8 +1033,11 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
_onAutoLaunchChanged: function(e) {
|
_onAutoLaunchChanged: function(e) {
|
||||||
const {ipcRenderer} = require('electron');
|
PlatformPeg.get().setAutoLaunchEnabled(e.target.checked).then(() => {
|
||||||
ipcRenderer.send('settings_set', 'auto-launch', e.target.checked);
|
this.setState({
|
||||||
|
autoLaunchEnabled: e.target.checked,
|
||||||
|
});
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
_mapWebRtcDevicesToSpans: function(devices) {
|
_mapWebRtcDevicesToSpans: function(devices) {
|
||||||
|
@ -1393,7 +1396,7 @@ module.exports = React.createClass({
|
||||||
{ this._renderBulkOptions() }
|
{ this._renderBulkOptions() }
|
||||||
{ this._renderBugReport() }
|
{ this._renderBugReport() }
|
||||||
|
|
||||||
{ PlatformPeg.get().isElectron() && this._renderElectronSettings() }
|
{ this._renderElectronSettings() }
|
||||||
|
|
||||||
{ this._renderAnalyticsControl() }
|
{ this._renderAnalyticsControl() }
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,6 @@ import qs from 'querystring';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import MatrixClientPeg from '../../../MatrixClientPeg';
|
import MatrixClientPeg from '../../../MatrixClientPeg';
|
||||||
import PlatformPeg from '../../../PlatformPeg';
|
|
||||||
import ScalarAuthClient from '../../../ScalarAuthClient';
|
import ScalarAuthClient from '../../../ScalarAuthClient';
|
||||||
import WidgetMessaging from '../../../WidgetMessaging';
|
import WidgetMessaging from '../../../WidgetMessaging';
|
||||||
import TintableSvgButton from './TintableSvgButton';
|
import TintableSvgButton from './TintableSvgButton';
|
||||||
|
@ -49,7 +48,6 @@ export default class AppTile extends React.Component {
|
||||||
this.state = this._getNewState(props);
|
this.state = this._getNewState(props);
|
||||||
|
|
||||||
this._onAction = this._onAction.bind(this);
|
this._onAction = this._onAction.bind(this);
|
||||||
this._onMessage = this._onMessage.bind(this);
|
|
||||||
this._onLoaded = this._onLoaded.bind(this);
|
this._onLoaded = this._onLoaded.bind(this);
|
||||||
this._onEditClick = this._onEditClick.bind(this);
|
this._onEditClick = this._onEditClick.bind(this);
|
||||||
this._onDeleteClick = this._onDeleteClick.bind(this);
|
this._onDeleteClick = this._onDeleteClick.bind(this);
|
||||||
|
@ -143,10 +141,6 @@ export default class AppTile extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
// Legacy Jitsi widget messaging -- TODO replace this with standard widget
|
|
||||||
// postMessaging API
|
|
||||||
window.addEventListener('message', this._onMessage, false);
|
|
||||||
|
|
||||||
// Widget action listeners
|
// Widget action listeners
|
||||||
this.dispatcherRef = dis.register(this._onAction);
|
this.dispatcherRef = dis.register(this._onAction);
|
||||||
}
|
}
|
||||||
|
@ -155,9 +149,6 @@ export default class AppTile extends React.Component {
|
||||||
// Widget action listeners
|
// Widget action listeners
|
||||||
dis.unregister(this.dispatcherRef);
|
dis.unregister(this.dispatcherRef);
|
||||||
|
|
||||||
// Jitsi listener
|
|
||||||
window.removeEventListener('message', this._onMessage);
|
|
||||||
|
|
||||||
// if it's not remaining on screen, get rid of the PersistedElement container
|
// if it's not remaining on screen, get rid of the PersistedElement container
|
||||||
if (!ActiveWidgetStore.getWidgetPersistence(this.props.id)) {
|
if (!ActiveWidgetStore.getWidgetPersistence(this.props.id)) {
|
||||||
ActiveWidgetStore.destroyPersistentWidget();
|
ActiveWidgetStore.destroyPersistentWidget();
|
||||||
|
@ -233,32 +224,6 @@ export default class AppTile extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Legacy Jitsi widget messaging
|
|
||||||
// TODO -- This should be replaced with the new widget postMessaging API
|
|
||||||
_onMessage(event) {
|
|
||||||
if (this.props.type !== 'jitsi') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!event.origin) {
|
|
||||||
event.origin = event.originalEvent.origin;
|
|
||||||
}
|
|
||||||
|
|
||||||
const widgetUrlObj = url.parse(this.state.widgetUrl);
|
|
||||||
const eventOrigin = url.parse(event.origin);
|
|
||||||
if (
|
|
||||||
eventOrigin.protocol !== widgetUrlObj.protocol ||
|
|
||||||
eventOrigin.host !== widgetUrlObj.host
|
|
||||||
) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.data.widgetAction === 'jitsi_iframe_loaded') {
|
|
||||||
const iframe = this.refs.appFrame.contentWindow
|
|
||||||
.document.querySelector('iframe[id^="jitsiConferenceFrame"]');
|
|
||||||
PlatformPeg.get().setupScreenSharingForIframe(iframe);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_canUserModify() {
|
_canUserModify() {
|
||||||
// User widgets should always be modifiable by their creator
|
// User widgets should always be modifiable by their creator
|
||||||
if (this.props.userWidget && MatrixClientPeg.get().credentials.userId === this.props.creatorUserId) {
|
if (this.props.userWidget && MatrixClientPeg.get().credentials.userId === this.props.creatorUserId) {
|
||||||
|
|
Loading…
Reference in a new issue