diff --git a/.eslintrc.json b/.eslintrc.json index 2858e326e..da6314749 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -37,6 +37,12 @@ } ], "func-names": ["warn", "as-needed"], + "no-param-reassign": [ + "error", + { + "props": false + } + ], "jsx-a11y/label-has-for": 0, "import/prefer-default-export": 0, "no-return-assign": 0, @@ -52,6 +58,7 @@ "no-restricted-syntax": 0, "no-empty": 0, "react/prefer-stateless-function": 0, - "react/sort-comp": 0 + "react/sort-comp": 0, + "jsx-a11y/media-has-caption": 0 } } diff --git a/package.json b/package.json index 2bce15580..0553b341c 100644 --- a/package.json +++ b/package.json @@ -61,6 +61,7 @@ "mixpanel-browser": "^2.17.1", "moment": "^2.22.0", "node-fetch": "^2.3.0", + "preprocess-loader": "^0.3.0", "qrcode.react": "^0.8.0", "rc-progress": "^2.0.6", "react": "^16.8.2", @@ -87,6 +88,7 @@ "stream-to-blob-url": "^2.1.1", "three": "^0.93.0", "tree-kill": "^1.1.0", + "video.js": "^7.2.2", "y18n": "^4.0.0" }, "devDependencies": { @@ -121,12 +123,14 @@ "json-loader": "^0.5.4", "lint-staged": "^7.0.2", "make-runnable": "^1.3.6", + "node-libs-browser": "^2.1.0", "node-loader": "^0.6.0", "node-sass": "^4.11.0", "prettier": "^1.11.1", "sass-loader": "^6.0.7", "webpack": "^3.10.0", "webpack-build-notifier": "^0.1.23", + "webpack-cli": "^2.0.0", "yarnhook": "^0.2.0" }, "engines": { diff --git a/src/main/index.js b/src/main/index.js index 3a3681e52..e31642e6c 100644 --- a/src/main/index.js +++ b/src/main/index.js @@ -1,5 +1,6 @@ /* eslint-disable no-console */ // Module imports +// @if TARGET='app' import keytar from 'keytar'; import SemVer from 'semver'; import url from 'url'; @@ -99,10 +100,12 @@ app.on('ready', async () => { if (isDev) { await installExtensions(); } + rendererWindow = createWindow(appState); rendererWindow.webContents.on('devtools-opened', () => { rendererWindow.webContents.send('devtools-is-opened'); }); + tray = createTray(rendererWindow); // HACK: patch webrequest to fix devtools incompatibility with electron 2.x. // See https://github.com/electron/electron/issues/13008#issuecomment-400261941 @@ -324,3 +327,4 @@ const isSecondInstance = app.makeSingleInstance(argv => { if (isSecondInstance) { app.exit(); } +// @endif diff --git a/src/renderer/app.js b/src/renderer/app.js index 6d93deb25..4f8512f85 100644 --- a/src/renderer/app.js +++ b/src/renderer/app.js @@ -1,15 +1,30 @@ +/* eslint-disable no-redeclare */ import store from 'store'; -import { remote } from 'electron'; import Path from 'path'; +// @if TARGET='app' import y18n from 'y18n'; +import { remote } from 'electron'; import isDev from 'electron-is-dev'; +// @endif +// @if TARGET='web' +import { y18n } from 'web/stubs'; +// @endif +// @if TARGET='app' const env = process.env.NODE_ENV || 'production'; const i18n = y18n({ directory: Path.join(remote.app.getAppPath(), '/../static/locales').replace(/\\/g, '\\\\'), updateFiles: false, locale: 'en', }); +// @endif +// @if TARGET='web' +const env = process.env.NODE_ENV || 'development'; +const i18n = y18n({ + updateFiles: false, + locale: 'en', +}); +// @endif const logs = []; const app = { @@ -22,6 +37,7 @@ const app = { }, }; +// @if TARGET='app' // Workaround for https://github.com/electron-userland/electron-webpack/issues/52 if (!isDev) { window.staticResourcesPath = Path.join(remote.app.getAppPath(), '../static').replace( @@ -31,6 +47,7 @@ if (!isDev) { } else { window.staticResourcesPath = ''; } +// @endif // eslint-disable-next-line no-underscore-dangle global.__ = i18n.__; @@ -42,3 +59,4 @@ global.app = app; global.store = app.store; export default app; +/* eslint-enable no-redeclare */ diff --git a/src/renderer/component/common/file-exporter.jsx b/src/renderer/component/common/file-exporter.jsx index 67542048d..a3ec156c1 100644 --- a/src/renderer/component/common/file-exporter.jsx +++ b/src/renderer/component/common/file-exporter.jsx @@ -5,7 +5,16 @@ import path from 'path'; import React from 'react'; import Button from 'component/button'; import parseData from 'util/parse-data'; +/* eslint-disable no-redeclare */ +// @if TARGET='app' +// $FlowFixMe import { remote } from 'electron'; +// @endif +// @if TARGET='web' +// $FlowFixMe +import { remote } from 'web/stubs'; +// @endif +/* eslint-enable no-redeclare */ type Props = { data: Array, diff --git a/src/renderer/component/common/file-selector.jsx b/src/renderer/component/common/file-selector.jsx index 390d3203b..dd2be0ca1 100644 --- a/src/renderer/component/common/file-selector.jsx +++ b/src/renderer/component/common/file-selector.jsx @@ -1,6 +1,15 @@ // @flow -import React from 'react'; +import * as React from 'react'; +/* eslint-disable no-redeclare */ +// @if TARGET='app' +// $FlowFixMe import { remote } from 'electron'; +// @endif +// @if TARGET='web' +// $FlowFixMe +import { remote } from 'web/stubs'; +// @endif +/* eslint-enable no-redeclare */ import Button from 'component/button'; import { FormField } from 'component/common/form'; import path from 'path'; @@ -24,9 +33,14 @@ class FileSelector extends React.PureComponent { type: 'file', }; + fileInput: { current: React.ElementRef }; + constructor() { super(); this.input = null; + // @if TARGET='web' + this.fileInput = React.createRef(); + // @endif } handleButtonClick() { @@ -54,6 +68,20 @@ class FileSelector extends React.PureComponent { ); } + handleFileInputSelection() { + const { files } = this.fileInput.current; + if (!files) { + return; + } + + const filePath = files[0]; + const fileName = filePath.name; + + if (this.props.onFileChosen) { + this.props.onFileChosen(filePath, fileName); + } + } + input: ?HTMLInputElement; render() { @@ -63,22 +91,29 @@ class FileSelector extends React.PureComponent { type === 'file' ? fileLabel || __('Choose File') : directoryLabel || __('Choose Directory'); return ( - { - if (this.input) this.input = input; - }} - onFocus={() => { - if (this.input) this.input.select(); - }} - readOnly="readonly" - value={currentPath || __('No File Chosen')} - inputButton={ -