Merge pull request #8003 from vector-im/develop

Merge develop into experimental
This commit is contained in:
David Baker 2019-01-03 18:56:03 +00:00 committed by GitHub
commit 373c587ef8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 861 additions and 179 deletions

View file

@ -47,7 +47,9 @@ import * as languageHandler from 'matrix-react-sdk/lib/languageHandler';
import url from 'url';
import {parseQs, parseQsFromFragment} from './url_utils';
import Platform from './platform';
import ElectronPlatform from './platform/ElectronPlatform';
import WebPlatform from './platform/WebPlatform';
import MatrixClientPeg from 'matrix-react-sdk/lib/MatrixClientPeg';
import SettingsStore from "matrix-react-sdk/lib/settings/SettingsStore";
@ -226,8 +228,23 @@ async function loadApp() {
const fragparts = parseQsFromFragment(window.location);
const params = parseQs(window.location);
// set the platform for react sdk (our Platform object automatically picks the right one)
PlatformPeg.set(new Platform());
// set the platform for react sdk
if (window.ipcRenderer) {
console.log("Using Electron platform");
const plaf = new ElectronPlatform();
PlatformPeg.set(plaf);
// Electron only: see if we need to do a one-time data
// migration
if (window.localStorage.getItem('mx_user_id') === null) {
console.log("Migrating session from old origin...");
await plaf.migrateFromOldOrigin();
console.log("Origin migration complete");
}
} else {
console.log("Using Web platform");
PlatformPeg.set(new WebPlatform());
}
// Load the config file. First try to load up a domain-specific config of the
// form "config.$domain.json" and if that fails, fall back to config.json.

View file

@ -3,6 +3,7 @@
/*
Copyright 2016 Aviral Dasgupta
Copyright 2016 OpenMarket Ltd
Copyright 2018 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -21,44 +22,26 @@ import VectorBasePlatform, {updateCheckStatusEnum} from './VectorBasePlatform';
import dis from 'matrix-react-sdk/lib/dispatcher';
import { _t } from 'matrix-react-sdk/lib/languageHandler';
import Promise from 'bluebird';
import {remote, ipcRenderer, desktopCapturer} from 'electron';
import rageshake from 'matrix-react-sdk/lib/rageshake/rageshake';
remote.autoUpdater.on('update-downloaded', onUpdateDownloaded);
// try to flush the rageshake logs to indexeddb before quit.
ipcRenderer.on('before-quit', function() {
console.log('riot-desktop closing');
rageshake.flush();
});
function onUpdateDownloaded(ev: Event, releaseNotes: string, ver: string, date: Date, updateURL: string) {
dis.dispatch({
action: 'new_version',
currentVersion: remote.app.getVersion(),
newVersion: ver,
releaseNotes: releaseNotes,
});
}
const ipcRenderer = window.ipcRenderer;
function platformFriendlyName(): string {
console.log(window.process);
switch (window.process.platform) {
case 'darwin':
return 'macOS';
case 'freebsd':
return 'FreeBSD';
case 'openbsd':
return 'OpenBSD';
case 'sunos':
return 'SunOS';
case 'win32':
return 'Windows';
default:
// Sorry, Linux users: you get lumped into here,
// but only because Linux's capitalisation is
// normal. We do care about you.
return window.process.platform[0].toUpperCase() + window.process.platform.slice(1);
// used to use window.process but the same info is available here
if (navigator.userAgent.indexOf('Macintosh')) {
return 'macOS';
} else if (navigator.userAgent.indexOf('FreeBSD')) {
return 'FreeBSD';
} else if (navigator.userAgent.indexOf('OpenBSD')) {
return 'OpenBSD';
} else if (navigator.userAgent.indexOf('SunOS')) {
return 'SunOS';
} else if (navigator.userAgent.indexOf('Windows')) {
return 'Windows';
} else if (navigator.userAgent.indexOf('Linux')) {
return 'Linux';
} else {
return 'Unknown';
}
}
@ -85,9 +68,11 @@ function getUpdateCheckStatus(status) {
export default class ElectronPlatform extends VectorBasePlatform {
constructor() {
super();
dis.register(_onAction);
this.updatable = Boolean(remote.autoUpdater.getFeedURL());
this._pendingIpcCalls = {};
this._nextIpcCallId = 0;
dis.register(_onAction);
/*
IPC Call `check_updates` returns:
true if there is an update available
@ -103,10 +88,28 @@ export default class ElectronPlatform extends VectorBasePlatform {
this.showUpdateCheck = false;
});
// try to flush the rageshake logs to indexeddb before quit.
ipcRenderer.on('before-quit', function() {
console.log('riot-desktop closing');
rageshake.flush();
});
ipcRenderer.on('ipcReply', this._onIpcReply.bind(this));
ipcRenderer.on('update-downloaded', this.onUpdateDownloaded.bind(this));
this.startUpdateCheck = this.startUpdateCheck.bind(this);
this.stopUpdateCheck = this.stopUpdateCheck.bind(this);
}
async onUpdateDownloaded(ev, updateInfo) {
dis.dispatch({
action: 'new_version',
currentVersion: await this.getAppVersion(),
newVersion: updateInfo,
releaseNotes: updateInfo.releaseNotes,
});
}
getHumanReadableName(): string {
return 'Electron Platform'; // no translation required: only used for analytics
}
@ -133,7 +136,7 @@ export default class ElectronPlatform extends VectorBasePlatform {
// maybe we should pass basic styling (italics, bold, underline) through from MD
// we only have to strip out < and > as the spec doesn't include anything about things like &amp;
// so we shouldn't assume that all implementations will treat those properly. Very basic tag parsing is done.
if (window.process.platform === 'linux') {
if (navigator.userAgent.indexOf('Linux')) {
msg = msg.replace(/</g, '&lt;').replace(/>/g, '&gt;');
}
@ -147,17 +150,13 @@ export default class ElectronPlatform extends VectorBasePlatform {
},
);
notification.onclick = function() {
notification.onclick = () => {
dis.dispatch({
action: 'view_room',
room_id: room.roomId,
});
global.focus();
const win = remote.getCurrentWindow();
if (win.isMinimized()) win.restore();
else if (!win.isVisible()) win.show();
else win.focus();
this._ipcCall('focusWindow');
};
return notification;
@ -171,8 +170,25 @@ export default class ElectronPlatform extends VectorBasePlatform {
notif.close();
}
getAppVersion(): Promise<string> {
return Promise.resolve(remote.app.getVersion());
async getAppVersion(): Promise<string> {
return await this._ipcCall('getAppVersion');
}
supportsAutoLaunch() {
return true;
}
async getAutoLaunchEnabled() {
return await this._ipcCall('getAutoLaunchEnabled');
}
async setAutoLaunchEnabled(enabled) {
return await this._ipcCall('setAutoLaunchEnabled', enabled);
}
async canSelfUpdate(): boolean {
const feedUrl = await this._ipcCall('getUpdateFeedUrl');
return Boolean(feedUrl);
}
startUpdateCheck() {
@ -197,52 +213,47 @@ export default class ElectronPlatform extends VectorBasePlatform {
return null;
}
isElectron(): boolean { return true; }
requestNotificationPermission(): Promise<string> {
return Promise.resolve('granted');
}
reload() {
remote.getCurrentWebContents().reload();
// we used to remote to the main process to get it to
// reload the webcontents, but in practice this is unnecessary:
// the normal way works fine.
window.location.reload(false);
}
/* BEGIN copied and slightly-modified code
* setupScreenSharingForIframe function from:
* https://github.com/jitsi/jitsi-meet-electron-utils
* Copied directly here to avoid the need for a native electron module for
* 'just a bit of JavaScript'
* NOTE: Apache v2.0 licensed
*/
setupScreenSharingForIframe(iframe: Object) {
iframe.contentWindow.JitsiMeetElectron = {
/**
* Get sources available for screensharing. The callback is invoked
* with an array of DesktopCapturerSources.
*
* @param {Function} callback - The success callback.
* @param {Function} errorCallback - The callback for errors.
* @param {Object} options - Configuration for getting sources.
* @param {Array} options.types - Specify the desktop source types
* to get, with valid sources being "window" and "screen".
* @param {Object} options.thumbnailSize - Specify how big the
* preview images for the sources should be. The valid keys are
* height and width, e.g. { height: number, width: number}. By
* default electron will return images with height and width of
* 150px.
*/
obtainDesktopStreams(callback, errorCallback, options = {}) {
desktopCapturer.getSources(options,
(error, sources) => {
if (error) {
errorCallback(error);
return;
}
callback(sources);
});
},
};
async migrateFromOldOrigin() {
return this._ipcCall('origin_migrate');
}
async _ipcCall(name, ...args) {
const ipcCallId = ++this._nextIpcCallId;
return new Promise((resolve, reject) => {
this._pendingIpcCalls[ipcCallId] = {resolve, reject};
window.ipcRenderer.send('ipcCall', {id: ipcCallId, name, args});
// Maybe add a timeout to these? Probably not necessary.
});
}
_onIpcReply(ev, payload) {
if (payload.id === undefined) {
console.warn("Ignoring IPC reply with no ID");
return;
}
if (this._pendingIpcCalls[payload.id] === undefined) {
console.warn("Unknown IPC payload ID: " + payload.id);
return;
}
const callbacks = this._pendingIpcCalls[payload.id];
delete this._pendingIpcCalls[payload.id];
if (payload.error) {
callbacks.reject(payload.error);
} else {
callbacks.resolve(payload.reply);
}
}
/* END of copied and slightly-modified code */
}

View file

@ -3,6 +3,7 @@
/*
Copyright 2016 Aviral Dasgupta
Copyright 2016 OpenMarket Ltd
Copyright 2018 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -45,7 +46,6 @@ export default class VectorBasePlatform extends BasePlatform {
this.favicon = new Favico({animation: 'none'});
this.showUpdateCheck = false;
this._updateFavicon();
this.updatable = true;
this.startUpdateCheck = this.startUpdateCheck.bind(this);
this.stopUpdateCheck = this.stopUpdateCheck.bind(this);
@ -88,6 +88,19 @@ export default class VectorBasePlatform extends BasePlatform {
this._updateFavicon();
}
supportsAutoLaunch() {
return false;
}
// XXX: Surely this should be a setting like any other?
async getAutoLaunchEnabled() {
return false;
}
async setAutoLaunchEnabled(enabled) {
throw new Error("Unimplemented");
}
/**
* Begin update polling, if applicable
*/
@ -97,8 +110,8 @@ export default class VectorBasePlatform extends BasePlatform {
/**
* Whether we can call checkForUpdate on this platform build
*/
canSelfUpdate(): boolean {
return this.updatable;
async canSelfUpdate(): boolean {
return false;
}
startUpdateCheck() {
@ -136,4 +149,12 @@ export default class VectorBasePlatform extends BasePlatform {
getDefaultDeviceDisplayName(): string {
return _t("Unknown device");
}
/**
* Migrate account data from a previous origin
* Used only for the electron app
*/
async migrateFromOldOrigin() {
return false;
}
}

View file

@ -142,6 +142,10 @@ export default class WebPlatform extends VectorBasePlatform {
setInterval(this.pollForUpdate.bind(this), POKE_RATE_MS);
}
async canSelfUpdate(): boolean {
return true;
}
pollForUpdate() {
return this._getVersion().then((ver) => {
if (this.runningVersion === null) {

View file

@ -1,29 +0,0 @@
// @flow
/*
Copyright 2016 Aviral Dasgupta
Copyright 2016 OpenMarket Ltd
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.
*/
let Platform = null;
if (window && window.process && window.process && window.process.type === 'renderer') {
// we're running inside electron
Platform = require('./ElectronPlatform');
} else {
Platform = require('./WebPlatform');
}
export default Platform;

View file

@ -26,10 +26,13 @@ limitations under the License.
*/
import rageshake from "matrix-react-sdk/lib/rageshake/rageshake";
import SdkConfig from "matrix-react-sdk/src/SdkConfig";
function initRageshake() {
rageshake.init().then(() => {
console.log("Initialised rageshake: See https://bugs.chromium.org/p/chromium/issues/detail?id=583193 to fix line numbers on Chrome.");
console.log("Initialised rageshake.");
console.log("To fix line numbers in Chrome: " +
"Meatball menu → Settings → Blackboxing → Add /rageshake\\.js$");
window.addEventListener('beforeunload', (e) => {
console.log('riot-web closing');
@ -44,3 +47,18 @@ function initRageshake() {
}
initRageshake();
global.mxSendRageshake = function(text, withLogs) {
if (withLogs === undefined) withLogs = true;
require(['matrix-react-sdk/lib/rageshake/submit-rageshake'], (s) => {
s(SdkConfig.get().bug_report_endpoint_url, {
userText: text,
sendLogs: withLogs,
progressCallback: console.log.bind(console),
}).then(() => {
console.log("Bug report sent!");
}, (err) => {
console.error(err);
});
});
};