lbryweb working with desktop
This commit is contained in:
parent
100291cf57
commit
5a97077c9f
24 changed files with 1905 additions and 106 deletions
|
@ -37,6 +37,12 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"func-names": ["warn", "as-needed"],
|
"func-names": ["warn", "as-needed"],
|
||||||
|
"no-param-reassign": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
"props": false
|
||||||
|
}
|
||||||
|
],
|
||||||
"jsx-a11y/label-has-for": 0,
|
"jsx-a11y/label-has-for": 0,
|
||||||
"import/prefer-default-export": 0,
|
"import/prefer-default-export": 0,
|
||||||
"no-return-assign": 0,
|
"no-return-assign": 0,
|
||||||
|
@ -52,6 +58,7 @@
|
||||||
"no-restricted-syntax": 0,
|
"no-restricted-syntax": 0,
|
||||||
"no-empty": 0,
|
"no-empty": 0,
|
||||||
"react/prefer-stateless-function": 0,
|
"react/prefer-stateless-function": 0,
|
||||||
"react/sort-comp": 0
|
"react/sort-comp": 0,
|
||||||
|
"jsx-a11y/media-has-caption": 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,6 +61,7 @@
|
||||||
"mixpanel-browser": "^2.17.1",
|
"mixpanel-browser": "^2.17.1",
|
||||||
"moment": "^2.22.0",
|
"moment": "^2.22.0",
|
||||||
"node-fetch": "^2.3.0",
|
"node-fetch": "^2.3.0",
|
||||||
|
"preprocess-loader": "^0.3.0",
|
||||||
"qrcode.react": "^0.8.0",
|
"qrcode.react": "^0.8.0",
|
||||||
"rc-progress": "^2.0.6",
|
"rc-progress": "^2.0.6",
|
||||||
"react": "^16.8.2",
|
"react": "^16.8.2",
|
||||||
|
@ -87,6 +88,7 @@
|
||||||
"stream-to-blob-url": "^2.1.1",
|
"stream-to-blob-url": "^2.1.1",
|
||||||
"three": "^0.93.0",
|
"three": "^0.93.0",
|
||||||
"tree-kill": "^1.1.0",
|
"tree-kill": "^1.1.0",
|
||||||
|
"video.js": "^7.2.2",
|
||||||
"y18n": "^4.0.0"
|
"y18n": "^4.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
@ -121,12 +123,14 @@
|
||||||
"json-loader": "^0.5.4",
|
"json-loader": "^0.5.4",
|
||||||
"lint-staged": "^7.0.2",
|
"lint-staged": "^7.0.2",
|
||||||
"make-runnable": "^1.3.6",
|
"make-runnable": "^1.3.6",
|
||||||
|
"node-libs-browser": "^2.1.0",
|
||||||
"node-loader": "^0.6.0",
|
"node-loader": "^0.6.0",
|
||||||
"node-sass": "^4.11.0",
|
"node-sass": "^4.11.0",
|
||||||
"prettier": "^1.11.1",
|
"prettier": "^1.11.1",
|
||||||
"sass-loader": "^6.0.7",
|
"sass-loader": "^6.0.7",
|
||||||
"webpack": "^3.10.0",
|
"webpack": "^3.10.0",
|
||||||
"webpack-build-notifier": "^0.1.23",
|
"webpack-build-notifier": "^0.1.23",
|
||||||
|
"webpack-cli": "^2.0.0",
|
||||||
"yarnhook": "^0.2.0"
|
"yarnhook": "^0.2.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/* eslint-disable no-console */
|
/* eslint-disable no-console */
|
||||||
// Module imports
|
// Module imports
|
||||||
|
// @if TARGET='app'
|
||||||
import keytar from 'keytar';
|
import keytar from 'keytar';
|
||||||
import SemVer from 'semver';
|
import SemVer from 'semver';
|
||||||
import url from 'url';
|
import url from 'url';
|
||||||
|
@ -99,10 +100,12 @@ app.on('ready', async () => {
|
||||||
if (isDev) {
|
if (isDev) {
|
||||||
await installExtensions();
|
await installExtensions();
|
||||||
}
|
}
|
||||||
|
|
||||||
rendererWindow = createWindow(appState);
|
rendererWindow = createWindow(appState);
|
||||||
rendererWindow.webContents.on('devtools-opened', () => {
|
rendererWindow.webContents.on('devtools-opened', () => {
|
||||||
rendererWindow.webContents.send('devtools-is-opened');
|
rendererWindow.webContents.send('devtools-is-opened');
|
||||||
});
|
});
|
||||||
|
|
||||||
tray = createTray(rendererWindow);
|
tray = createTray(rendererWindow);
|
||||||
// HACK: patch webrequest to fix devtools incompatibility with electron 2.x.
|
// HACK: patch webrequest to fix devtools incompatibility with electron 2.x.
|
||||||
// See https://github.com/electron/electron/issues/13008#issuecomment-400261941
|
// See https://github.com/electron/electron/issues/13008#issuecomment-400261941
|
||||||
|
@ -324,3 +327,4 @@ const isSecondInstance = app.makeSingleInstance(argv => {
|
||||||
if (isSecondInstance) {
|
if (isSecondInstance) {
|
||||||
app.exit();
|
app.exit();
|
||||||
}
|
}
|
||||||
|
// @endif
|
||||||
|
|
|
@ -1,15 +1,30 @@
|
||||||
|
/* eslint-disable no-redeclare */
|
||||||
import store from 'store';
|
import store from 'store';
|
||||||
import { remote } from 'electron';
|
|
||||||
import Path from 'path';
|
import Path from 'path';
|
||||||
|
// @if TARGET='app'
|
||||||
import y18n from 'y18n';
|
import y18n from 'y18n';
|
||||||
|
import { remote } from 'electron';
|
||||||
import isDev from 'electron-is-dev';
|
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 env = process.env.NODE_ENV || 'production';
|
||||||
const i18n = y18n({
|
const i18n = y18n({
|
||||||
directory: Path.join(remote.app.getAppPath(), '/../static/locales').replace(/\\/g, '\\\\'),
|
directory: Path.join(remote.app.getAppPath(), '/../static/locales').replace(/\\/g, '\\\\'),
|
||||||
updateFiles: false,
|
updateFiles: false,
|
||||||
locale: 'en',
|
locale: 'en',
|
||||||
});
|
});
|
||||||
|
// @endif
|
||||||
|
// @if TARGET='web'
|
||||||
|
const env = process.env.NODE_ENV || 'development';
|
||||||
|
const i18n = y18n({
|
||||||
|
updateFiles: false,
|
||||||
|
locale: 'en',
|
||||||
|
});
|
||||||
|
// @endif
|
||||||
|
|
||||||
const logs = [];
|
const logs = [];
|
||||||
const app = {
|
const app = {
|
||||||
|
@ -22,6 +37,7 @@ const app = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// @if TARGET='app'
|
||||||
// Workaround for https://github.com/electron-userland/electron-webpack/issues/52
|
// Workaround for https://github.com/electron-userland/electron-webpack/issues/52
|
||||||
if (!isDev) {
|
if (!isDev) {
|
||||||
window.staticResourcesPath = Path.join(remote.app.getAppPath(), '../static').replace(
|
window.staticResourcesPath = Path.join(remote.app.getAppPath(), '../static').replace(
|
||||||
|
@ -31,6 +47,7 @@ if (!isDev) {
|
||||||
} else {
|
} else {
|
||||||
window.staticResourcesPath = '';
|
window.staticResourcesPath = '';
|
||||||
}
|
}
|
||||||
|
// @endif
|
||||||
|
|
||||||
// eslint-disable-next-line no-underscore-dangle
|
// eslint-disable-next-line no-underscore-dangle
|
||||||
global.__ = i18n.__;
|
global.__ = i18n.__;
|
||||||
|
@ -42,3 +59,4 @@ global.app = app;
|
||||||
global.store = app.store;
|
global.store = app.store;
|
||||||
|
|
||||||
export default app;
|
export default app;
|
||||||
|
/* eslint-enable no-redeclare */
|
||||||
|
|
|
@ -5,7 +5,16 @@ import path from 'path';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
import parseData from 'util/parse-data';
|
import parseData from 'util/parse-data';
|
||||||
|
/* eslint-disable no-redeclare */
|
||||||
|
// @if TARGET='app'
|
||||||
|
// $FlowFixMe
|
||||||
import { remote } from 'electron';
|
import { remote } from 'electron';
|
||||||
|
// @endif
|
||||||
|
// @if TARGET='web'
|
||||||
|
// $FlowFixMe
|
||||||
|
import { remote } from 'web/stubs';
|
||||||
|
// @endif
|
||||||
|
/* eslint-enable no-redeclare */
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
data: Array<any>,
|
data: Array<any>,
|
||||||
|
|
|
@ -1,6 +1,15 @@
|
||||||
// @flow
|
// @flow
|
||||||
import React from 'react';
|
import * as React from 'react';
|
||||||
|
/* eslint-disable no-redeclare */
|
||||||
|
// @if TARGET='app'
|
||||||
|
// $FlowFixMe
|
||||||
import { remote } from 'electron';
|
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 Button from 'component/button';
|
||||||
import { FormField } from 'component/common/form';
|
import { FormField } from 'component/common/form';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
@ -24,9 +33,14 @@ class FileSelector extends React.PureComponent<Props> {
|
||||||
type: 'file',
|
type: 'file',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
fileInput: { current: React.ElementRef<any> };
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.input = null;
|
this.input = null;
|
||||||
|
// @if TARGET='web'
|
||||||
|
this.fileInput = React.createRef();
|
||||||
|
// @endif
|
||||||
}
|
}
|
||||||
|
|
||||||
handleButtonClick() {
|
handleButtonClick() {
|
||||||
|
@ -54,6 +68,20 @@ class FileSelector extends React.PureComponent<Props> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
input: ?HTMLInputElement;
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
@ -63,6 +91,8 @@ class FileSelector extends React.PureComponent<Props> {
|
||||||
type === 'file' ? fileLabel || __('Choose File') : directoryLabel || __('Choose Directory');
|
type === 'file' ? fileLabel || __('Choose File') : directoryLabel || __('Choose Directory');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
{/* @if TARGET='app' */}
|
||||||
<FormField
|
<FormField
|
||||||
webkitdirectory="true"
|
webkitdirectory="true"
|
||||||
className="form-field--copyable"
|
className="form-field--copyable"
|
||||||
|
@ -79,6 +109,11 @@ class FileSelector extends React.PureComponent<Props> {
|
||||||
<Button button="primary" onClick={() => this.handleButtonClick()} label={label} />
|
<Button button="primary" onClick={() => this.handleButtonClick()} label={label} />
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
{/* @endif */}
|
||||||
|
{/* @if TARGET='web' */}
|
||||||
|
<input type="file" ref={this.fileInput} onChange={() => this.handleFileInputSelection()} />
|
||||||
|
{/* @endif */}
|
||||||
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,9 +7,11 @@ import ThreeViewer from 'component/viewers/threeViewer';
|
||||||
import DocumentViewer from 'component/viewers/documentViewer';
|
import DocumentViewer from 'component/viewers/documentViewer';
|
||||||
import DocxViewer from 'component/viewers/docxViewer';
|
import DocxViewer from 'component/viewers/docxViewer';
|
||||||
import HtmlViewer from 'component/viewers/htmlViewer';
|
import HtmlViewer from 'component/viewers/htmlViewer';
|
||||||
|
import AudioVideoViewer from 'component/viewers/audioVideoViewer';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
mediaType: string,
|
mediaType: string,
|
||||||
|
poster?: string,
|
||||||
source: {
|
source: {
|
||||||
stream: string => void,
|
stream: string => void,
|
||||||
fileName: string,
|
fileName: string,
|
||||||
|
@ -54,6 +56,7 @@ class FileRender extends React.PureComponent<Props> {
|
||||||
// Process command
|
// Process command
|
||||||
let message = {};
|
let message = {};
|
||||||
try {
|
try {
|
||||||
|
// $FlowFixMe
|
||||||
message = JSON.parse(/^\$LBRY_IPC:(.*)/.exec(e.message)[1]);
|
message = JSON.parse(/^\$LBRY_IPC:(.*)/.exec(e.message)[1]);
|
||||||
} catch (err) {}
|
} catch (err) {}
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
|
@ -88,10 +91,10 @@ class FileRender extends React.PureComponent<Props> {
|
||||||
}
|
}
|
||||||
|
|
||||||
renderViewer() {
|
renderViewer() {
|
||||||
const { source, mediaType, currentTheme } = this.props;
|
const { source, mediaType, currentTheme, poster } = this.props;
|
||||||
|
|
||||||
// Extract relevant data to render file
|
// Extract relevant data to render file
|
||||||
const { stream, fileType, contentType, downloadPath } = source;
|
const { stream, fileType, contentType, downloadPath, fileName } = source;
|
||||||
|
|
||||||
// Human-readable files (scripts and plain-text files)
|
// Human-readable files (scripts and plain-text files)
|
||||||
const readableFiles = ['text', 'document', 'script'];
|
const readableFiles = ['text', 'document', 'script'];
|
||||||
|
@ -112,6 +115,14 @@ class FileRender extends React.PureComponent<Props> {
|
||||||
webpreferences="sandbox=true,contextIsolation=true,webviewTag=false,enableRemoteModule=false,devTools=false"
|
webpreferences="sandbox=true,contextIsolation=true,webviewTag=false,enableRemoteModule=false,devTools=false"
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
|
video: (
|
||||||
|
<AudioVideoViewer
|
||||||
|
source={{ downloadPath, fileName }}
|
||||||
|
contentType={contentType}
|
||||||
|
poster={poster}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
audio: <AudioVideoViewer source={{ downloadPath, fileName }} contentType={contentType} />,
|
||||||
// Add routes to viewer...
|
// Add routes to viewer...
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,6 @@ export default class SplashScreen extends React.PureComponent<Props, State> {
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
const { checkDaemonVersion } = this.props;
|
const { checkDaemonVersion } = this.props;
|
||||||
|
|
||||||
this.adjustErrorTimeout();
|
this.adjustErrorTimeout();
|
||||||
Lbry.connect()
|
Lbry.connect()
|
||||||
.then(checkDaemonVersion)
|
.then(checkDaemonVersion)
|
||||||
|
@ -93,12 +92,21 @@ export default class SplashScreen extends React.PureComponent<Props, State> {
|
||||||
}
|
}
|
||||||
|
|
||||||
updateStatus() {
|
updateStatus() {
|
||||||
|
// @if TARGET='app'
|
||||||
Lbry.status().then(status => {
|
Lbry.status().then(status => {
|
||||||
this.updateStatusCallback(status);
|
this.updateStatusCallback(status);
|
||||||
});
|
});
|
||||||
|
// @endif
|
||||||
|
// @if TARGET='web'
|
||||||
|
Lbry.status().then(status => {
|
||||||
|
Lbry.account_list().then(accountList => {
|
||||||
|
this.updateStatusCallback(status, accountList);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
// @endif
|
||||||
}
|
}
|
||||||
|
|
||||||
updateStatusCallback(status: Status) {
|
updateStatusCallback(status: Status, accountList: any) {
|
||||||
const { notifyUnlockWallet, authenticate, modal } = this.props;
|
const { notifyUnlockWallet, authenticate, modal } = this.props;
|
||||||
const { launchedModal } = this.state;
|
const { launchedModal } = this.state;
|
||||||
|
|
||||||
|
@ -117,11 +125,21 @@ export default class SplashScreen extends React.PureComponent<Props, State> {
|
||||||
const { wallet, blockchain_headers: blockchainHeaders } = status;
|
const { wallet, blockchain_headers: blockchainHeaders } = status;
|
||||||
|
|
||||||
// If the wallet is locked, stop doing anything and make the user input their password
|
// If the wallet is locked, stop doing anything and make the user input their password
|
||||||
|
|
||||||
|
// @if TARGET='app'
|
||||||
if (wallet && wallet.is_locked) {
|
if (wallet && wallet.is_locked) {
|
||||||
// Clear the error timeout, it might sit on this step for a while until someone enters their password
|
// Clear the error timeout, it might sit on this step for a while until someone enters their password
|
||||||
if (this.timeout) {
|
if (this.timeout) {
|
||||||
clearTimeout(this.timeout);
|
clearTimeout(this.timeout);
|
||||||
}
|
}
|
||||||
|
// @endif
|
||||||
|
// @if TARGET='web'
|
||||||
|
console.log('I think web needs this', accountList);
|
||||||
|
// if (account_list && account_list.encrypted) {
|
||||||
|
// this.setState({
|
||||||
|
// isRunning: true,
|
||||||
|
// });
|
||||||
|
// @endif
|
||||||
|
|
||||||
// Make sure there isn't another active modal (like INCOMPATIBLE_DAEMON)
|
// Make sure there isn't another active modal (like INCOMPATIBLE_DAEMON)
|
||||||
if (launchedModal === false && !modal) {
|
if (launchedModal === false && !modal) {
|
||||||
|
|
67
src/renderer/component/viewers/audioVideoViewer.jsx
Normal file
67
src/renderer/component/viewers/audioVideoViewer.jsx
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
// @flow
|
||||||
|
import React from 'react';
|
||||||
|
import { stopContextMenu } from 'util/context-menu';
|
||||||
|
import videojs from 'video.js';
|
||||||
|
import 'video.js/dist/video-js.css';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
source: {
|
||||||
|
downloadPath: string,
|
||||||
|
fileName: string,
|
||||||
|
},
|
||||||
|
contentType: string,
|
||||||
|
poster?: string,
|
||||||
|
};
|
||||||
|
|
||||||
|
class AudioVideoViewer extends React.PureComponent<Props> {
|
||||||
|
videoNode: ?HTMLVideoElement;
|
||||||
|
player: ?{ dispose: () => void };
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
const { source, contentType, poster } = this.props;
|
||||||
|
const { downloadPath, fileName } = source;
|
||||||
|
|
||||||
|
const indexOfFileName = downloadPath.indexOf(fileName);
|
||||||
|
const basePath = downloadPath.slice(0, indexOfFileName);
|
||||||
|
const encodedFileName = encodeURIComponent(fileName);
|
||||||
|
|
||||||
|
// We only want to encode the fileName so forward slashes "/" are handled properly by the file system
|
||||||
|
// TODO: Determine changes needed for windows
|
||||||
|
const path = `${basePath}${encodedFileName}`;
|
||||||
|
|
||||||
|
const sources = [
|
||||||
|
{
|
||||||
|
src: path,
|
||||||
|
type: contentType,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const videoJsOptions = {
|
||||||
|
autoplay: true,
|
||||||
|
controls: true,
|
||||||
|
preload: 'auto',
|
||||||
|
poster,
|
||||||
|
sources,
|
||||||
|
};
|
||||||
|
|
||||||
|
this.player = videojs(this.videoNode, videoJsOptions, () => {});
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
if (this.player) {
|
||||||
|
this.player.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div className="file-render__viewer" onContextMenu={stopContextMenu}>
|
||||||
|
<div data-vjs-player>
|
||||||
|
<video ref={node => (this.videoNode = node)} className="video-js" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AudioVideoViewer;
|
|
@ -3,10 +3,12 @@
|
||||||
import App from 'component/app';
|
import App from 'component/app';
|
||||||
import SnackBar from 'component/snackBar';
|
import SnackBar from 'component/snackBar';
|
||||||
import SplashScreen from 'component/splash';
|
import SplashScreen from 'component/splash';
|
||||||
|
// @if TARGET='app'
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import * as ACTIONS from 'constants/action_types';
|
|
||||||
import * as MODALS from 'constants/modal_types';
|
|
||||||
import { ipcRenderer, remote, shell } from 'electron';
|
import { ipcRenderer, remote, shell } from 'electron';
|
||||||
|
import * as ACTIONS from 'constants/action_types';
|
||||||
|
// @endif
|
||||||
|
import * as MODALS from 'constants/modal_types';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import { Provider } from 'react-redux';
|
import { Provider } from 'react-redux';
|
||||||
|
@ -28,10 +30,12 @@ import app from './app';
|
||||||
import analytics from './analytics';
|
import analytics from './analytics';
|
||||||
import doLogWarningConsoleMessage from './logWarningConsoleMessage';
|
import doLogWarningConsoleMessage from './logWarningConsoleMessage';
|
||||||
|
|
||||||
const { autoUpdater } = remote.require('electron-updater');
|
|
||||||
const APPPAGEURL = 'lbry://?';
|
const APPPAGEURL = 'lbry://?';
|
||||||
|
|
||||||
|
// @if TARGET='app'
|
||||||
|
const { autoUpdater } = remote.require('electron-updater');
|
||||||
autoUpdater.logger = remote.require('electron-log');
|
autoUpdater.logger = remote.require('electron-log');
|
||||||
|
// @endif
|
||||||
|
|
||||||
if (process.env.LBRY_API_URL) {
|
if (process.env.LBRY_API_URL) {
|
||||||
Lbryio.setLocalApi(process.env.LBRY_API_URL);
|
Lbryio.setLocalApi(process.env.LBRY_API_URL);
|
||||||
|
@ -74,7 +78,9 @@ Lbryio.setOverride(
|
||||||
|
|
||||||
const newAuthToken = response.auth_token;
|
const newAuthToken = response.auth_token;
|
||||||
authToken = newAuthToken;
|
authToken = newAuthToken;
|
||||||
|
// @if TARGET='app'
|
||||||
ipcRenderer.send('set-auth-token', authToken);
|
ipcRenderer.send('set-auth-token', authToken);
|
||||||
|
// @endif
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
@ -87,12 +93,14 @@ Lbryio.setOverride(
|
||||||
if (authToken) {
|
if (authToken) {
|
||||||
resolve(authToken);
|
resolve(authToken);
|
||||||
} else {
|
} else {
|
||||||
|
// @if TARGET='app'
|
||||||
ipcRenderer.once('auth-token-response', (event, token) => {
|
ipcRenderer.once('auth-token-response', (event, token) => {
|
||||||
Lbryio.authToken = token;
|
Lbryio.authToken = token;
|
||||||
resolve(token);
|
resolve(token);
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcRenderer.send('get-auth-token');
|
ipcRenderer.send('get-auth-token');
|
||||||
|
// @endif
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
@ -109,6 +117,7 @@ rewards.setCallback('claimRewardSuccess', () => {
|
||||||
app.store.dispatch(doHideModal(MODALS.REWARD_APPROVAL_REQUIRED));
|
app.store.dispatch(doHideModal(MODALS.REWARD_APPROVAL_REQUIRED));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// @if TARGET='app'
|
||||||
ipcRenderer.on('open-uri-requested', (event, uri, newSession) => {
|
ipcRenderer.on('open-uri-requested', (event, uri, newSession) => {
|
||||||
if (uri && uri.startsWith('lbry://')) {
|
if (uri && uri.startsWith('lbry://')) {
|
||||||
if (uri.startsWith('lbry://?verify')) {
|
if (uri.startsWith('lbry://?verify')) {
|
||||||
|
@ -146,6 +155,7 @@ ipcRenderer.on('devtools-is-opened', () => {
|
||||||
const logOnDevelopment = false;
|
const logOnDevelopment = false;
|
||||||
doLogWarningConsoleMessage(logOnDevelopment);
|
doLogWarningConsoleMessage(logOnDevelopment);
|
||||||
});
|
});
|
||||||
|
// @endif
|
||||||
|
|
||||||
document.addEventListener('dragover', event => {
|
document.addEventListener('dragover', event => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
@ -178,15 +188,18 @@ document.addEventListener('click', event => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (target.matches('a[href^="http"]') || target.matches('a[href^="mailto"]')) {
|
if (target.matches('a[href^="http"]') || target.matches('a[href^="mailto"]')) {
|
||||||
|
// @if TARGET='app'
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
shell.openExternal(target.href);
|
shell.openExternal(target.href);
|
||||||
return;
|
return;
|
||||||
|
// @endif
|
||||||
}
|
}
|
||||||
target = target.parentNode;
|
target = target.parentNode;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const init = () => {
|
const init = () => {
|
||||||
|
// @if TARGET='app'
|
||||||
moment.locale(remote.app.getLocale());
|
moment.locale(remote.app.getLocale());
|
||||||
|
|
||||||
autoUpdater.on('error', error => {
|
autoUpdater.on('error', error => {
|
||||||
|
@ -210,6 +223,7 @@ const init = () => {
|
||||||
app.store.dispatch(doUpdateIsNightAsync());
|
app.store.dispatch(doUpdateIsNightAsync());
|
||||||
app.store.dispatch(doDownloadLanguages());
|
app.store.dispatch(doDownloadLanguages());
|
||||||
app.store.dispatch(doBlackListedOutpointsSubscribe());
|
app.store.dispatch(doBlackListedOutpointsSubscribe());
|
||||||
|
// @endif
|
||||||
|
|
||||||
function onDaemonReady() {
|
function onDaemonReady() {
|
||||||
window.sessionStorage.setItem('loaded', 'y'); // once we've made it here once per session, we don't need to show splash again
|
window.sessionStorage.setItem('loaded', 'y'); // once we've made it here once per session, we don't need to show splash again
|
||||||
|
@ -224,6 +238,9 @@ const init = () => {
|
||||||
</Provider>,
|
</Provider>,
|
||||||
document.getElementById('app')
|
document.getElementById('app')
|
||||||
);
|
);
|
||||||
|
// @if TARGET='web'
|
||||||
|
// window.sessionStorage.removeItem('loaded');
|
||||||
|
// @endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window.sessionStorage.getItem('loaded') === 'y') {
|
if (window.sessionStorage.getItem('loaded') === 'y') {
|
||||||
|
|
|
@ -4,12 +4,19 @@ const Native = {};
|
||||||
|
|
||||||
Native.getAppVersionInfo = () =>
|
Native.getAppVersionInfo = () =>
|
||||||
new Promise(resolve => {
|
new Promise(resolve => {
|
||||||
|
// @if TARGET='app'
|
||||||
ipcRenderer.once('version-info-received', (event, versionInfo) => {
|
ipcRenderer.once('version-info-received', (event, versionInfo) => {
|
||||||
resolve(versionInfo);
|
resolve(versionInfo);
|
||||||
});
|
});
|
||||||
ipcRenderer.send('version-info-requested');
|
ipcRenderer.send('version-info-requested');
|
||||||
|
// @endif
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// @if TARGET='app'
|
||||||
Native.imagePath = file => `${staticResourcesPath}/img/${file}`;
|
Native.imagePath = file => `${staticResourcesPath}/img/${file}`;
|
||||||
|
// @endif
|
||||||
|
// @if TARGET='web'
|
||||||
|
Native.imagePath = file => `staticResourcesPath/img/${file}`;
|
||||||
|
// @endif
|
||||||
|
|
||||||
export default Native;
|
export default Native;
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
|
// @if TARGET='app'
|
||||||
import { execSync } from 'child_process';
|
import { execSync } from 'child_process';
|
||||||
import isDev from 'electron-is-dev';
|
import isDev from 'electron-is-dev';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { ipcRenderer, remote } from 'electron';
|
import { ipcRenderer, remote } from 'electron';
|
||||||
|
// @endif
|
||||||
import * as ACTIONS from 'constants/action_types';
|
import * as ACTIONS from 'constants/action_types';
|
||||||
import * as MODALS from 'constants/modal_types';
|
import * as MODALS from 'constants/modal_types';
|
||||||
import { Lbry, doBalanceSubscribe, doFetchFileInfosAndPublishedClaims, doError } from 'lbry-redux';
|
import { Lbry, doBalanceSubscribe, doFetchFileInfosAndPublishedClaims, doError } from 'lbry-redux';
|
||||||
|
@ -23,9 +25,11 @@ import {
|
||||||
import { doAuthenticate } from 'lbryinc';
|
import { doAuthenticate } from 'lbryinc';
|
||||||
import { lbrySettings as config, version as appVersion } from 'package.json';
|
import { lbrySettings as config, version as appVersion } from 'package.json';
|
||||||
|
|
||||||
|
// @if TARGET='app'
|
||||||
const { autoUpdater } = remote.require('electron-updater');
|
const { autoUpdater } = remote.require('electron-updater');
|
||||||
const { download } = remote.require('electron-dl');
|
const { download } = remote.require('electron-dl');
|
||||||
const Fs = remote.require('fs');
|
const Fs = remote.require('fs');
|
||||||
|
// @endif
|
||||||
|
|
||||||
const CHECK_UPGRADE_INTERVAL = 10 * 60 * 1000;
|
const CHECK_UPGRADE_INTERVAL = 10 * 60 * 1000;
|
||||||
|
|
||||||
|
@ -71,6 +75,7 @@ export function doStartUpgrade() {
|
||||||
|
|
||||||
export function doDownloadUpgrade() {
|
export function doDownloadUpgrade() {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
|
// @if TARGET='app'
|
||||||
const state = getState();
|
const state = getState();
|
||||||
// Make a new directory within temp directory so the filename is guaranteed to be available
|
// Make a new directory within temp directory so the filename is guaranteed to be available
|
||||||
const dir = Fs.mkdtempSync(remote.app.getPath('temp') + path.sep);
|
const dir = Fs.mkdtempSync(remote.app.getPath('temp') + path.sep);
|
||||||
|
@ -101,6 +106,7 @@ export function doDownloadUpgrade() {
|
||||||
});
|
});
|
||||||
dispatch(doHideModal());
|
dispatch(doHideModal());
|
||||||
dispatch(doOpenModal(MODALS.DOWNLOADING));
|
dispatch(doOpenModal(MODALS.DOWNLOADING));
|
||||||
|
// @endif
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -255,6 +261,7 @@ export function doCheckUpgradeSubscribe() {
|
||||||
|
|
||||||
export function doCheckDaemonVersion() {
|
export function doCheckDaemonVersion() {
|
||||||
return dispatch => {
|
return dispatch => {
|
||||||
|
// @if TARGET='app'
|
||||||
Lbry.version().then(({ lbrynet_version: lbrynetVersion }) => {
|
Lbry.version().then(({ lbrynet_version: lbrynetVersion }) => {
|
||||||
// Avoid the incompatible daemon modal if running in dev mode
|
// Avoid the incompatible daemon modal if running in dev mode
|
||||||
// Lets you run a different daemon than the one specified in package.json
|
// Lets you run a different daemon than the one specified in package.json
|
||||||
|
@ -270,6 +277,12 @@ export function doCheckDaemonVersion() {
|
||||||
|
|
||||||
return dispatch(doOpenModal(MODALS.INCOMPATIBLE_DAEMON));
|
return dispatch(doOpenModal(MODALS.INCOMPATIBLE_DAEMON));
|
||||||
});
|
});
|
||||||
|
// @endif
|
||||||
|
// @if TARGET='web'
|
||||||
|
dispatch({
|
||||||
|
type: ACTIONS.DAEMON_VERSION_MATCH,
|
||||||
|
});
|
||||||
|
// @endif
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -305,12 +318,14 @@ export function doDaemonReady() {
|
||||||
dispatch({ type: ACTIONS.DAEMON_READY });
|
dispatch({ type: ACTIONS.DAEMON_READY });
|
||||||
dispatch(doFetchDaemonSettings());
|
dispatch(doFetchDaemonSettings());
|
||||||
dispatch(doBalanceSubscribe());
|
dispatch(doBalanceSubscribe());
|
||||||
|
// @if TARGET='app'
|
||||||
dispatch(doFetchFileInfosAndPublishedClaims());
|
dispatch(doFetchFileInfosAndPublishedClaims());
|
||||||
if (!selectIsUpgradeSkipped(state)) {
|
if (!selectIsUpgradeSkipped(state)) {
|
||||||
dispatch(doCheckUpgradeAvailable());
|
dispatch(doCheckUpgradeAvailable());
|
||||||
}
|
}
|
||||||
dispatch(doCheckUpgradeSubscribe());
|
dispatch(doCheckUpgradeSubscribe());
|
||||||
dispatch(doCheckSubscriptionsInit());
|
dispatch(doCheckSubscriptionsInit());
|
||||||
|
// @endif
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -324,14 +339,16 @@ export function doClearCache() {
|
||||||
|
|
||||||
export function doQuit() {
|
export function doQuit() {
|
||||||
return () => {
|
return () => {
|
||||||
|
// @if TARGET='app'
|
||||||
remote.app.quit();
|
remote.app.quit();
|
||||||
|
// @endif
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function doQuitAnyDaemon() {
|
export function doQuitAnyDaemon() {
|
||||||
return dispatch => {
|
return dispatch => {
|
||||||
|
// @if TARGET='app'
|
||||||
Lbry.stop()
|
Lbry.stop()
|
||||||
.then()
|
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
try {
|
try {
|
||||||
if (process.platform === 'win32') {
|
if (process.platform === 'win32') {
|
||||||
|
@ -342,8 +359,11 @@ export function doQuitAnyDaemon() {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
dispatch(doAlertError(`Quitting daemon failed due to: ${error.message}`));
|
dispatch(doAlertError(`Quitting daemon failed due to: ${error.message}`));
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
.finally(() => {
|
||||||
dispatch(doQuit());
|
dispatch(doQuit());
|
||||||
|
});
|
||||||
|
// @endif
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,11 +6,9 @@ import {
|
||||||
doAbandonClaim,
|
doAbandonClaim,
|
||||||
selectMyClaimsOutpoints,
|
selectMyClaimsOutpoints,
|
||||||
selectFileInfosByOutpoint,
|
selectFileInfosByOutpoint,
|
||||||
selectTotalDownloadProgress,
|
|
||||||
} from 'lbry-redux';
|
} from 'lbry-redux';
|
||||||
import { doHideModal } from 'redux/actions/app';
|
import { doHideModal } from 'redux/actions/app';
|
||||||
import { doHistoryBack } from 'redux/actions/navigation';
|
import { doHistoryBack } from 'redux/actions/navigation';
|
||||||
import setProgressBar from 'util/set-progress-bar';
|
|
||||||
|
|
||||||
export function doOpenFileInFolder(path) {
|
export function doOpenFileInFolder(path) {
|
||||||
return () => {
|
return () => {
|
||||||
|
@ -56,9 +54,6 @@ export function doDeleteFile(outpoint, deleteFromComputer, abandonClaim) {
|
||||||
outpoint,
|
outpoint,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const totalProgress = selectTotalDownloadProgress(getState());
|
|
||||||
setProgressBar(totalProgress);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,16 @@
|
||||||
|
|
||||||
import * as ACTIONS from 'constants/action_types';
|
import * as ACTIONS from 'constants/action_types';
|
||||||
import * as MODALS from 'constants/modal_types';
|
import * as MODALS from 'constants/modal_types';
|
||||||
|
/* eslint-disable no-redeclare */
|
||||||
|
// @if TARGET='app'
|
||||||
|
// $FlowFixMe
|
||||||
import { remote } from 'electron';
|
import { remote } from 'electron';
|
||||||
|
// @endif
|
||||||
|
// @if TARGET='web'
|
||||||
|
// $FlowFixMe
|
||||||
|
import { remote } from 'web/stubs';
|
||||||
|
// @endif
|
||||||
|
/* eslint-enable no-redeclare */
|
||||||
|
|
||||||
const win = remote.BrowserWindow.getFocusedWindow();
|
const win = remote.BrowserWindow.getFocusedWindow();
|
||||||
|
|
||||||
|
|
|
@ -27,10 +27,17 @@
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
iframe,
|
iframe,
|
||||||
webview {
|
webview,
|
||||||
|
.video-js {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Removing the play button because we have autoplay turned on
|
||||||
|
// These are classes added by video.js
|
||||||
|
// .video-js .vjs-big-play-button {
|
||||||
|
// display: none;
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
.document-viewer {
|
.document-viewer {
|
||||||
|
|
|
@ -1,5 +1,12 @@
|
||||||
|
/* eslint-disable no-redeclare */
|
||||||
|
// @if TARGET='app'
|
||||||
import { clipboard, remote } from 'electron';
|
import { clipboard, remote } from 'electron';
|
||||||
import isDev from 'electron-is-dev';
|
import isDev from 'electron-is-dev';
|
||||||
|
// @endif
|
||||||
|
// @if TARGET='web'
|
||||||
|
import { remote, isDev } from 'web/stubs';
|
||||||
|
// @endif
|
||||||
|
/* eslint-enable no-redeclare */
|
||||||
|
|
||||||
function injectDevelopmentTemplate(event, templates) {
|
function injectDevelopmentTemplate(event, templates) {
|
||||||
if (!isDev) return templates;
|
if (!isDev) return templates;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
/* eslint-disable no-redeclare */
|
||||||
|
// @if TARGET='app'
|
||||||
import { remote } from 'electron';
|
import { remote } from 'electron';
|
||||||
|
|
||||||
const application = remote.app;
|
const application = remote.app;
|
||||||
|
@ -9,5 +11,11 @@ const setBadge = text => {
|
||||||
|
|
||||||
dock.setBadge(text);
|
dock.setBadge(text);
|
||||||
};
|
};
|
||||||
|
// @endif
|
||||||
|
|
||||||
|
// @if TARGET='web'
|
||||||
|
const setBadge = () => {};
|
||||||
|
// @endif
|
||||||
|
/* eslint-enable no-redeclare */
|
||||||
|
|
||||||
export default setBadge;
|
export default setBadge;
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
import { remote } from 'electron';
|
|
||||||
|
|
||||||
const win = remote.getCurrentWindow();
|
|
||||||
|
|
||||||
const setProgressBar = progress => {
|
|
||||||
win.setProgressBar(progress);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default setProgressBar;
|
|
2
src/renderer/web/index.js
Normal file
2
src/renderer/web/index.js
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
import '../index';
|
||||||
|
import './publish';
|
67
src/renderer/web/publish.js
Normal file
67
src/renderer/web/publish.js
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
// @flow
|
||||||
|
import { Lbry } from 'lbry-redux';
|
||||||
|
|
||||||
|
function checkAndParseFix(response) {
|
||||||
|
if (response.status >= 200 && response.status < 300) {
|
||||||
|
return response.json();
|
||||||
|
}
|
||||||
|
return response.json().then(json => {
|
||||||
|
let error;
|
||||||
|
if (json.error) {
|
||||||
|
error = new Error(json.error);
|
||||||
|
} else {
|
||||||
|
error = new Error('Protocol error with unknown response signature');
|
||||||
|
}
|
||||||
|
return Promise.reject(error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// A modified version of Lbry.apiCall that allows
|
||||||
|
// to perform calling methods at arbitrary urls
|
||||||
|
// and pass form file fields
|
||||||
|
function apiCallViaWeb(
|
||||||
|
connectionString: string,
|
||||||
|
method: string,
|
||||||
|
params: { file_path: string },
|
||||||
|
resolve: Function,
|
||||||
|
reject: Function
|
||||||
|
) {
|
||||||
|
const counter = new Date().getTime();
|
||||||
|
const fileField = params.file_path;
|
||||||
|
// Putting a dummy value here, the server is going to process the POSTed file
|
||||||
|
// and set the file_path itself
|
||||||
|
params.file_path = '__POST_FILE__';
|
||||||
|
const jsonPayload = JSON.stringify({
|
||||||
|
jsonrpc: '2.0',
|
||||||
|
method,
|
||||||
|
params,
|
||||||
|
id: counter,
|
||||||
|
});
|
||||||
|
const body = new FormData();
|
||||||
|
body.append('file', fileField);
|
||||||
|
body.append('json_payload', jsonPayload);
|
||||||
|
const options = {
|
||||||
|
method: 'POST',
|
||||||
|
body,
|
||||||
|
};
|
||||||
|
|
||||||
|
return fetch(connectionString, options)
|
||||||
|
.then(checkAndParseFix)
|
||||||
|
.then(response => {
|
||||||
|
const error = response.error || (response.result && response.result.error);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
return reject(error);
|
||||||
|
}
|
||||||
|
return resolve(response.result);
|
||||||
|
})
|
||||||
|
.catch(reject);
|
||||||
|
}
|
||||||
|
|
||||||
|
Lbry.setOverride(
|
||||||
|
'publish',
|
||||||
|
params =>
|
||||||
|
new Promise((resolve, reject) => {
|
||||||
|
apiCallViaWeb('/storage/content/', 'publish', params, resolve, reject);
|
||||||
|
})
|
||||||
|
);
|
29
src/renderer/web/stubs.js
Normal file
29
src/renderer/web/stubs.js
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
const callable = () => {
|
||||||
|
throw Error('Need to fix this stub');
|
||||||
|
};
|
||||||
|
const returningCallable = value => () => value;
|
||||||
|
|
||||||
|
export const remote = {
|
||||||
|
dialog: {
|
||||||
|
showOpenDialog: callable,
|
||||||
|
},
|
||||||
|
getCurrentWindow: callable,
|
||||||
|
app: {
|
||||||
|
getAppPath: callable,
|
||||||
|
},
|
||||||
|
BrowserWindow: {
|
||||||
|
getFocusedWindow: callable,
|
||||||
|
},
|
||||||
|
Menu: {
|
||||||
|
getApplicationMenu: callable,
|
||||||
|
},
|
||||||
|
require: callable,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const y18n = () => ({
|
||||||
|
getLocale: returningCallable('en'),
|
||||||
|
__: value => value,
|
||||||
|
__n: value => value,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const isDev = false;
|
114
webpack.config.js
Normal file
114
webpack.config.js
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
const ELECTRON_RENDERER_PROCESS_ROOT = path.resolve(__dirname, 'src/renderer/');
|
||||||
|
|
||||||
|
module.exports = env => {
|
||||||
|
return {
|
||||||
|
// commented out because of webpack 3
|
||||||
|
// mode: 'development',
|
||||||
|
entry: './src/renderer/web/index.js',
|
||||||
|
output: {
|
||||||
|
path: path.resolve(__dirname, 'dist/web'),
|
||||||
|
filename: 'bundle.js',
|
||||||
|
publicPath: '/static/app/',
|
||||||
|
},
|
||||||
|
// commented out because of webpack 3
|
||||||
|
// optimization: {
|
||||||
|
// minimize: false,
|
||||||
|
// },
|
||||||
|
target: 'web',
|
||||||
|
node: {
|
||||||
|
fs: 'empty',
|
||||||
|
// electron: "empty",
|
||||||
|
'electron-is-dev': 'mock',
|
||||||
|
store: 'mock',
|
||||||
|
y18n: 'mock',
|
||||||
|
tls: 'mock',
|
||||||
|
net: 'mock',
|
||||||
|
},
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.jsx?$/,
|
||||||
|
use: [
|
||||||
|
{
|
||||||
|
loader: 'babel-loader',
|
||||||
|
options: {
|
||||||
|
presets: ['env', 'react', 'stage-2'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
loader: 'preprocess-loader',
|
||||||
|
options: {
|
||||||
|
TARGET: 'web',
|
||||||
|
LBRYNET_PROXY_URL: '/api_proxy/',
|
||||||
|
ppOptions: {
|
||||||
|
type: 'js',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
exclude: /node_modules/,
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// test: /\.jsx?$/,
|
||||||
|
// loader: 'babel-loader',
|
||||||
|
// options: {
|
||||||
|
// presets: ['env', 'react', 'stage-2'],
|
||||||
|
// },
|
||||||
|
// exclude: /node_modules/,
|
||||||
|
// },
|
||||||
|
{
|
||||||
|
test: /\.scss$/,
|
||||||
|
use: [
|
||||||
|
'style-loader', // creates style nodes from JS strings
|
||||||
|
'css-loader', // translates CSS into CommonJS
|
||||||
|
'sass-loader', // compiles Sass to CSS, using Node Sass by default
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.(png|woff|woff2|eot|ttf|svg|gif)$/,
|
||||||
|
// loader: 'url-loader?limit=100000'
|
||||||
|
use: [
|
||||||
|
{
|
||||||
|
loader: 'file-loader',
|
||||||
|
options: {
|
||||||
|
name: '[name].[ext]',
|
||||||
|
// outputPath: 'resources/'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.css$/,
|
||||||
|
loader: ['style-loader', 'css-loader'],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
resolve: {
|
||||||
|
modules: [ELECTRON_RENDERER_PROCESS_ROOT, 'node_modules', __dirname],
|
||||||
|
extensions: ['.js', '.jsx', '.scss', '.json'],
|
||||||
|
},
|
||||||
|
externals: [
|
||||||
|
(function() {
|
||||||
|
var IGNORES = [
|
||||||
|
'electron',
|
||||||
|
'breakdance',
|
||||||
|
'i18n',
|
||||||
|
// 'electron-is-dev',
|
||||||
|
// 'store',
|
||||||
|
// 'y18n',
|
||||||
|
// 'tls',
|
||||||
|
// 'net'
|
||||||
|
];
|
||||||
|
return function(context, request, callback) {
|
||||||
|
if (IGNORES.indexOf(request) >= 0) {
|
||||||
|
// return callback(null, "require('" + request + "')");
|
||||||
|
return callback(null, '{}');
|
||||||
|
}
|
||||||
|
return callback();
|
||||||
|
};
|
||||||
|
})(),
|
||||||
|
],
|
||||||
|
};
|
||||||
|
};
|
|
@ -8,20 +8,32 @@ if (PROCESS_ARGV) {
|
||||||
PROCESS_ARGV = JSON.parse(PROCESS_ARGV);
|
PROCESS_ARGV = JSON.parse(PROCESS_ARGV);
|
||||||
}
|
}
|
||||||
|
|
||||||
const isDev = PROCESS_ARGV && PROCESS_ARGV.original &&
|
const isDev = PROCESS_ARGV && PROCESS_ARGV.original && PROCESS_ARGV.original.indexOf('dev') !== -1;
|
||||||
(PROCESS_ARGV.original.indexOf('dev') !== -1);
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
// This rule is temporarily necessary until https://github.com/electron-userland/electron-webpack/issues/60 is fixed.
|
|
||||||
module: {
|
module: {
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
test: /\.jsx?$/,
|
test: /\.jsx?$/,
|
||||||
|
use: [
|
||||||
|
// This rule is temporarily necessary until https://github.com/electron-userland/electron-webpack/issues/60 is fixed.
|
||||||
|
{
|
||||||
loader: 'babel-loader',
|
loader: 'babel-loader',
|
||||||
options: {
|
options: {
|
||||||
presets: ['env', 'react', 'stage-2'],
|
presets: ['env', 'react', 'stage-2'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
loader: 'preprocess-loader',
|
||||||
|
options: {
|
||||||
|
TARGET: 'app',
|
||||||
|
ppOptions: {
|
||||||
|
type: 'js',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
// This allows imports to be made from the renderer process root (https://moduscreate.com/blog/es6-es2015-import-no-relative-path-webpack/).
|
// This allows imports to be made from the renderer process root (https://moduscreate.com/blog/es6-es2015-import-no-relative-path-webpack/).
|
||||||
|
@ -29,9 +41,11 @@ module.exports = {
|
||||||
modules: [ELECTRON_RENDERER_PROCESS_ROOT, 'node_modules', __dirname],
|
modules: [ELECTRON_RENDERER_PROCESS_ROOT, 'node_modules', __dirname],
|
||||||
extensions: ['.js', '.jsx', '.scss'],
|
extensions: ['.js', '.jsx', '.scss'],
|
||||||
},
|
},
|
||||||
plugins: isDev ? [
|
plugins: isDev
|
||||||
|
? [
|
||||||
new FilewatcherPlugin({
|
new FilewatcherPlugin({
|
||||||
watchFileRegex: [require.resolve('lbry-redux'), require.resolve('lbryinc')],
|
watchFileRegex: [require.resolve('lbry-redux'), require.resolve('lbryinc')],
|
||||||
}),
|
}),
|
||||||
] : [],
|
]
|
||||||
|
: [],
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue