Set up Electron integration and builds

pull/2407/head
Aviral Dasgupta 2016-10-04 16:04:03 +05:30
parent 602727b7ad
commit 4f185211ce
9 changed files with 174 additions and 7 deletions

2
.gitignore vendored
View File

@ -5,8 +5,10 @@
/node_modules
/packages/
/vector/bundle.*
/vector/electron-main.*
/vector/components.css
/vector/emojione/
/vector/electron/
/vector/config.json
/vector/olm.js
.DS_Store

View File

@ -1,5 +1,7 @@
{
"name": "vector-web",
"productName": "Riot",
"main": "vector/electron-main.js",
"version": "0.8.1",
"description": "Vector webapp",
"author": "matrix.org",
@ -16,15 +18,16 @@
"build:modernizr": "modernizr -c .modernizr.json -d src/vector/modernizr.js",
"build:css": "catw \"src/skins/vector/css/**/*.css\" -o vector/components.css --no-watch",
"build:compile": "babel --source-maps -d lib src",
"build:bundle": "NODE_ENV=production webpack -p lib/vector/index.js vector/bundle.js",
"build:bundle": "NODE_ENV=production webpack",
"build:bundle:dev": "webpack --optimize-occurence-order lib/vector/index.js vector/bundle.js",
"build:staticfiles": "cpx -v node_modules/olm/olm.js vector/",
"build:electron": "build -lwm",
"build": "npm run build:staticfiles && npm run build:emojione && npm run build:css && npm run build:compile && npm run build:bundle",
"build:dev": "npm run build:staticfiles && npm run build:emojione && npm run build:css && npm run build:compile && npm run build:bundle:dev",
"package": "scripts/package.sh",
"start:emojione": "cpx \"node_modules/emojione/assets/svg/*\" vector/emojione/svg/ -w",
"start:js": "webpack -w src/vector/index.js vector/bundle.js",
"start:js:prod": "NODE_ENV=production webpack -w src/vector/index.js vector/bundle.js",
"start:js": "webpack -w",
"start:js:prod": "NODE_ENV=production webpack -w",
"start:skins:css": "catw \"src/skins/vector/css/**/*.css\" -o vector/components.css",
"start:staticfiles": "cpx -Lwv node_modules/olm/olm.js vector/",
"//cache": "Note the -c 1 below due to https://code.google.com/p/chromium/issues/detail?id=508270",
@ -41,6 +44,7 @@
"classnames": "^2.1.2",
"draft-js": "^0.8.1",
"extract-text-webpack-plugin": "^0.9.1",
"favico.js": "^0.3.10",
"filesize": "^3.1.2",
"flux": "~2.0.3",
"gemini-scrollbar": "matrix-org/gemini-scrollbar#b302279",
@ -67,6 +71,7 @@
"catw": "^1.0.1",
"cpx": "^1.3.2",
"css-raw-loader": "^0.1.1",
"electron-builder": "^7.10.2",
"emojione": "^2.2.3",
"expect": "^1.16.0",
"fs-extra": "^0.30.0",
@ -91,5 +96,22 @@
},
"optionalDependencies": {
"olm": "https://matrix.org/packages/npm/olm/olm-1.3.0.tgz"
},
"build": {
"appId": "im.riot.app",
"category": "Network",
"electronVersion": "1.4.2",
"//asar=false": "https://github.com/electron-userland/electron-builder/issues/675",
"asar": false,
"dereference": true,
"//files": "We bundle everything, so we only need to include vector/",
"files": [
"!**/*",
"vector/**",
"package.json"
]
},
"directories": {
"output": "vector/electron"
}
}

19
src/electron-main.js Normal file
View File

@ -0,0 +1,19 @@
// @flow
const {app, BrowserWindow} = require('electron');
let window = null;
app.on('ready', () => {
window = new BrowserWindow({
icon: `${__dirname}/img/logo.png`,
});
window.loadURL(`file://${__dirname}/index.html`);
window.webContents.openDevTools();
window.on('closed', () => {
window = null;
})
});
app.on('window-all-closed', () => {
app.quit();
});

View File

@ -28,7 +28,6 @@ require('gfm.css/gfm.css');
require('highlight.js/styles/github.css');
require('draft-js/dist/Draft.css');
// add React and ReactPerf to the global namespace, to make them easier to
// access via the console
global.React = require("react");
@ -49,6 +48,7 @@ import UAParser from 'ua-parser-js';
import url from 'url';
import {parseQs, parseQsFromFragment} from './url_utils';
import IntegrationManager from './integration';
var lastLocationHashSet = null;
@ -201,6 +201,7 @@ function onLoadCompleted() {
async function loadApp() {
const fragparts = parseQsFromFragment(window.location);
const params = parseQs(window.location);
const integrationManager = new IntegrationManager();
// don't try to redirect to the native apps if we're
// verifying a 3pid
@ -254,6 +255,7 @@ async function loadApp() {
enableGuest={true}
onLoadCompleted={onLoadCompleted}
defaultDeviceDisplayName={getDefaultDeviceDisplayName()}
integrationManager={integrationManager}
/>,
document.getElementById('matrixchat')
);

View File

@ -0,0 +1,16 @@
// @flow
export default class BaseIntegrationManager {
constructor() {
this.notificationCount = 0;
this.errorDidOccur = false;
}
setNotificationCount(count: number) {
this.notificationCount = count;
}
setErrorStatus(errorDidOccur: boolean) {
this.errorDidOccur = errorDidOccur;
}
}

View File

@ -0,0 +1,16 @@
// @flow
import BaseIntegrationManager from './BaseIntegrationManager';
// index.js imports us unconditionally, so we need this check here as well
let electron = null, remote = null;
if (window && window.process && window.process && window.process.type === 'renderer') {
electron = require('electron');
remote = electron.remote;
}
export default class ElectronIntegrationManager extends BaseIntegrationManager {
setNotificationCount(count: number) {
super.setNotificationCount(count);
remote.app.setBadgeCount(count);
}
}

View File

@ -0,0 +1,42 @@
// @flow
import BaseIntegrationManager from './BaseIntegrationManager';
import Favico from 'favico.js';
export default class WebIntegrationManager extends BaseIntegrationManager {
constructor() {
super();
this.favicon = new Favico({animation: 'popFade'});
this.updateFavicon();
}
updateFavicon() {
try {
// This needs to be in in a try block as it will throw
// if there are more than 100 badge count changes in
// its internal queue
let bgColor = "#d00",
notif = this.notificationCount;
if (this.errorDidOccur) {
notif = notif || "×";
bgColor = "#f00";
}
this.favicon.badge(notif, {
bgColor: bgColor
});
} catch (e) {
console.warn(`Failed to set badge count: ${e.message}`);
}
}
setNotificationCount(count: number) {
super.setNotificationCount(count);
this.updateFavicon();
}
setErrorStatus(errorDidOccur: boolean) {
super.setErrorStatus(errorDidOccur);
this.updateFavicon();
}
}

View File

@ -0,0 +1,15 @@
// @flow
import ElectronIntegrationManager from './ElectronIntegrationManager';
import WebIntegrationManager from './WebIntegrationManager';
let IntegrationManager = null;
if (window && window.process && window.process && window.process.type === 'renderer') {
// we're running inside electron
IntegrationManager = ElectronIntegrationManager;
} else {
IntegrationManager = WebIntegrationManager;
}
export default IntegrationManager;

View File

@ -2,7 +2,8 @@ var path = require('path');
var webpack = require('webpack');
var ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
module.exports = [{
entry: './src/vector/index.js',
module: {
preLoaders: [
{ test: /\.js$/, loader: "source-map-loader" }
@ -32,7 +33,9 @@ module.exports = {
// various levels of '.' and '..'
// Also, sometimes the resource path is absolute.
return path.relative(process.cwd(), info.resourcePath).replace(/^[\/\.]*/, '');
}
},
path: './vector/',
filename: 'bundle.js'
},
resolve: {
alias: {
@ -52,6 +55,7 @@ module.exports = {
// loads it into the browser global `Olm`), and reference it as an
// external here.
"olm": "Olm",
"electron": 'commonjs electron'
},
plugins: [
new webpack.DefinePlugin({
@ -65,4 +69,33 @@ module.exports = {
}),
],
devtool: 'source-map'
};
}, {
entry: './src/electron-main.js',
target: "electron",
output: {
devtoolModuleFilenameTemplate: function(info) {
// Reading input source maps gives only relative paths here for
// everything. Until I figure out how to fix this, this is a
// workaround.
// We use the relative resource path with any '../'s on the front
// removed which gives a tree with matrix-react-sdk and vector
// trees smashed together, but this fixes everything being under
// various levels of '.' and '..'
// Also, sometimes the resource path is absolute.
return path.relative(process.cwd(), info.resourcePath).replace(/^[\/\.]*/, '');
},
filename: 'vector/electron-main.js'
},
node: {
__dirname: false,
__filename: false
},
plugins: [
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify(process.env.NODE_ENV)
}
}),
],
devtool: 'source-map',
}];