2019-08-23 17:54:08 +02:00
|
|
|
import { WEBPACK_ELECTRON_PORT } from 'config';
|
2018-08-01 22:44:01 +02:00
|
|
|
import { app, BrowserWindow, dialog, shell, screen } from 'electron';
|
2018-03-08 00:03:45 +01:00
|
|
|
import isDev from 'electron-is-dev';
|
2018-03-21 14:29:51 +01:00
|
|
|
import windowStateKeeper from 'electron-window-state';
|
2019-11-05 19:54:58 +01:00
|
|
|
import SUPPORTED_LANGUAGES from 'constants/supported_languages';
|
2020-06-10 19:03:15 +02:00
|
|
|
import { SUPPORTED_SUB_LANGUAGE_CODES, SUB_LANG_CODE_LEN } from 'constants/supported_sub_languages';
|
2018-03-21 14:29:51 +01:00
|
|
|
|
2018-01-18 03:13:08 +01:00
|
|
|
import setupBarMenu from './menu/setupBarMenu';
|
2019-11-12 23:03:11 +01:00
|
|
|
import * as PAGES from 'constants/pages';
|
2018-01-18 03:13:08 +01:00
|
|
|
|
2020-06-10 19:03:15 +02:00
|
|
|
function GetAppLangCode() {
|
|
|
|
// 1. Gets the user locale.
|
|
|
|
// 2. Converts unsupported sub-languages to its primary (e.g. "en-GB" -> "en").
|
|
|
|
// Note that the primary itself may or may not be a supported language
|
|
|
|
// (up to clients to verify against SUPPORTED_LANGUAGES).
|
|
|
|
const langCode = app.getLocale();
|
|
|
|
if (langCode.length === SUB_LANG_CODE_LEN && !SUPPORTED_SUB_LANGUAGE_CODES.includes(langCode)) {
|
|
|
|
return langCode.slice(0, 2);
|
|
|
|
}
|
|
|
|
return langCode;
|
|
|
|
}
|
|
|
|
|
2018-02-24 00:20:12 +01:00
|
|
|
export default appState => {
|
2018-03-21 14:29:51 +01:00
|
|
|
// Get primary display dimensions from Electron.
|
|
|
|
const { width, height } = screen.getPrimaryDisplay().workAreaSize;
|
|
|
|
|
|
|
|
// Load the previous state with fallback to defaults.
|
|
|
|
const windowState = windowStateKeeper({
|
|
|
|
defaultWidth: width,
|
|
|
|
defaultHeight: height,
|
|
|
|
});
|
|
|
|
|
2019-11-18 19:30:15 +01:00
|
|
|
const startMinimized = (process.argv || []).includes('--hidden');
|
|
|
|
|
2018-07-05 04:49:12 +02:00
|
|
|
const windowConfiguration = {
|
2019-09-26 18:07:11 +02:00
|
|
|
backgroundColor: '#270f34', // Located in src/scss/init/_vars.scss `--color-background--splash`
|
2018-03-26 23:32:43 +02:00
|
|
|
minWidth: 950,
|
2018-01-18 03:13:08 +01:00
|
|
|
minHeight: 600,
|
|
|
|
autoHideMenuBar: true,
|
2019-10-09 18:34:18 +02:00
|
|
|
titleBarStyle: 'hiddenInset',
|
2018-01-18 03:13:08 +01:00
|
|
|
show: false,
|
2018-03-21 14:29:51 +01:00
|
|
|
// Create the window using the state information.
|
|
|
|
x: windowState.x,
|
|
|
|
y: windowState.y,
|
|
|
|
// If state is undefined, create window as maximized.
|
|
|
|
width: windowState.width === undefined ? width : windowState.width,
|
|
|
|
height: windowState.height === undefined ? height : windowState.height,
|
2019-12-20 17:26:55 +01:00
|
|
|
icon: 'static/img/tray/default/tray.png',
|
2018-07-05 04:49:12 +02:00
|
|
|
webPreferences: {
|
|
|
|
// Disable renderer process's webSecurity on development to enable CORS.
|
|
|
|
webSecurity: !isDev,
|
|
|
|
plugins: true,
|
|
|
|
},
|
|
|
|
};
|
2019-05-01 16:18:26 +02:00
|
|
|
const lbryProto = 'lbry://';
|
|
|
|
const lbryProtoQ = 'lbry://?';
|
2019-09-03 05:01:04 +02:00
|
|
|
const rendererURL = isDev ? `http://localhost:${WEBPACK_ELECTRON_PORT}` : `file://${__dirname}/index.html`;
|
2018-01-18 03:13:08 +01:00
|
|
|
|
|
|
|
let window = new BrowserWindow(windowConfiguration);
|
|
|
|
|
2018-03-21 14:29:51 +01:00
|
|
|
// Let us register listeners on the window, so we can update the state
|
|
|
|
// automatically (the listeners will be removed when the window is closed)
|
|
|
|
// and restore the maximized or full screen state.
|
|
|
|
windowState.manage(window);
|
2018-01-18 03:13:08 +01:00
|
|
|
|
|
|
|
let deepLinkingURI;
|
2019-05-01 16:18:26 +02:00
|
|
|
|
2019-05-07 23:38:29 +02:00
|
|
|
if ((process.platform === 'win32' || process.platform === 'linux') && String(process.argv[1]).startsWith('lbry')) {
|
2019-05-01 16:18:26 +02:00
|
|
|
[, deepLinkingURI] = process.argv || '';
|
2018-01-18 03:13:08 +01:00
|
|
|
// Keep only command line / deep linked arguments
|
|
|
|
// Windows normalizes URIs when they're passed in from other apps. On Windows, this tries to
|
|
|
|
// restore the original URI that was typed.
|
|
|
|
// - If the URI has no path, Windows adds a trailing slash. LBRY URIs can't have a slash with no
|
|
|
|
// path, so we just strip it off.
|
|
|
|
// - In a URI with a claim ID, like lbry://channel#claimid, Windows interprets the hash mark as
|
|
|
|
// an anchor and converts it to lbry://channel/#claimid. We remove the slash here as well.
|
2018-06-05 17:22:15 +02:00
|
|
|
// - ? also interpreted as an anchor, remove slash also.
|
2018-03-20 00:03:14 +01:00
|
|
|
if (process.platform === 'win32') {
|
2018-06-05 17:22:15 +02:00
|
|
|
deepLinkingURI = deepLinkingURI
|
|
|
|
.replace(/\/$/, '')
|
|
|
|
.replace('/#', '#')
|
|
|
|
.replace('/?', '?');
|
2018-03-20 00:03:14 +01:00
|
|
|
}
|
|
|
|
} else {
|
2019-05-01 16:18:26 +02:00
|
|
|
deepLinkingURI = appState.macDeepLinkingURI || '';
|
|
|
|
}
|
|
|
|
|
|
|
|
// is it a lbry://? pointing to an app page
|
|
|
|
if (deepLinkingURI.includes(lbryProtoQ)) {
|
2019-08-29 01:53:48 +02:00
|
|
|
let path = deepLinkingURI.substr(lbryProtoQ.length);
|
|
|
|
let page = path.indexOf('?') >= 0 ? path.substring(0, path.indexOf('?')) : path;
|
|
|
|
if (Object.values(PAGES).includes(page)) {
|
2019-05-01 16:18:26 +02:00
|
|
|
deepLinkingURI = deepLinkingURI.replace(lbryProtoQ, '#/$/');
|
|
|
|
} else {
|
|
|
|
deepLinkingURI = '';
|
|
|
|
}
|
|
|
|
// else is it a claim
|
|
|
|
} else if (deepLinkingURI.includes(lbryProto)) {
|
|
|
|
deepLinkingURI = deepLinkingURI.replace(lbryProto, '#');
|
|
|
|
} else {
|
|
|
|
deepLinkingURI = '';
|
2018-01-18 03:13:08 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
setupBarMenu();
|
2019-01-31 14:32:44 +01:00
|
|
|
|
2019-11-05 19:54:58 +01:00
|
|
|
window.loadURL(rendererURL + deepLinkingURI);
|
2019-10-11 16:02:24 +02:00
|
|
|
|
2018-02-24 00:20:12 +01:00
|
|
|
window.on('close', event => {
|
2018-03-17 21:44:46 +01:00
|
|
|
if (!appState.isQuitting && !appState.autoUpdateAccepted) {
|
2018-02-24 00:20:12 +01:00
|
|
|
event.preventDefault();
|
2018-04-02 22:19:47 +02:00
|
|
|
if (window.isFullScreen()) {
|
|
|
|
window.once('leave-full-screen', () => {
|
|
|
|
window.hide();
|
|
|
|
});
|
|
|
|
window.setFullScreen(false);
|
|
|
|
} else {
|
|
|
|
window.hide();
|
|
|
|
}
|
2018-02-24 00:20:12 +01:00
|
|
|
}
|
2018-01-18 03:13:08 +01:00
|
|
|
});
|
|
|
|
|
|
|
|
window.on('focus', () => {
|
|
|
|
window.webContents.send('window-is-focused', null);
|
|
|
|
});
|
|
|
|
|
|
|
|
window.on('unresponsive', () => {
|
|
|
|
dialog.showMessageBox(
|
|
|
|
window,
|
|
|
|
{
|
|
|
|
type: 'warning',
|
|
|
|
buttons: ['Wait', 'Quit'],
|
|
|
|
title: 'LBRY Unresponsive',
|
|
|
|
defaultId: 1,
|
|
|
|
message: 'LBRY is not responding. Would you like to quit?',
|
|
|
|
cancelId: 0,
|
|
|
|
},
|
|
|
|
buttonIndex => {
|
|
|
|
if (buttonIndex === 1) app.quit();
|
|
|
|
}
|
|
|
|
);
|
|
|
|
});
|
2019-11-05 19:54:58 +01:00
|
|
|
|
2018-01-18 03:13:08 +01:00
|
|
|
window.once('ready-to-show', () => {
|
2019-11-18 19:30:15 +01:00
|
|
|
startMinimized ? window.hide() : window.show();
|
2018-01-18 03:13:08 +01:00
|
|
|
});
|
|
|
|
|
2019-11-18 20:42:29 +01:00
|
|
|
// A backup incase https://github.com/electron/electron/issues/7779 happens
|
2019-11-18 19:30:15 +01:00
|
|
|
window.webContents.once('dom-ready', () => {
|
2019-12-20 17:26:55 +01:00
|
|
|
startMinimized && window.hide();
|
|
|
|
});
|
2019-11-18 19:30:15 +01:00
|
|
|
|
2018-01-18 03:13:08 +01:00
|
|
|
window.webContents.on('did-finish-load', () => {
|
|
|
|
window.webContents.session.setUserAgent(`LBRY/${app.getVersion()}`);
|
2019-11-05 19:54:58 +01:00
|
|
|
|
|
|
|
// restore the user's previous language - we have to do this from here because only electron process can access app.getLocale()
|
|
|
|
window.webContents.executeJavaScript("localStorage.getItem('language')").then(storedLanguage => {
|
|
|
|
const language =
|
|
|
|
storedLanguage && storedLanguage !== 'undefined' && storedLanguage !== 'null'
|
|
|
|
? storedLanguage
|
2020-06-10 19:03:15 +02:00
|
|
|
: GetAppLangCode();
|
2019-11-05 19:54:58 +01:00
|
|
|
if (language !== 'en' && SUPPORTED_LANGUAGES[language]) {
|
|
|
|
window.webContents.send('language-set', language);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2018-03-08 00:03:45 +01:00
|
|
|
if (isDev) {
|
2018-01-18 03:13:08 +01:00
|
|
|
window.webContents.openDevTools();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
window.webContents.on('crashed', () => {
|
|
|
|
window = null;
|
|
|
|
});
|
2018-10-22 03:01:06 +02:00
|
|
|
|
2018-08-01 22:44:01 +02:00
|
|
|
window.webContents.on('new-window', (event, url) => {
|
|
|
|
event.preventDefault();
|
|
|
|
shell.openExternal(url);
|
|
|
|
});
|
2018-01-18 03:13:08 +01:00
|
|
|
|
2020-05-28 11:47:18 +02:00
|
|
|
window.webContents.on('update-target-url', (event, url) => {
|
|
|
|
// Change internal links to the lbry protocol. External (https) links should remain unchanged.
|
2020-06-09 06:10:20 +02:00
|
|
|
let hoverUrlBase = `http://localhost:${WEBPACK_ELECTRON_PORT}/`;
|
|
|
|
if (!isDev) {
|
|
|
|
// Return format of 'update-target-url':
|
|
|
|
// Linux: file:///@claim
|
|
|
|
// Windows: file:///C:/@claim
|
|
|
|
// Use '__dirname' in case installation is not in C:
|
|
|
|
const path = require('path');
|
|
|
|
const exeRoot = path.parse(__dirname).root;
|
|
|
|
|
|
|
|
if (process.platform === 'win32') {
|
|
|
|
// Add extra "/" prefix. Convert "C:\" to "C:/"
|
|
|
|
hoverUrlBase = `file:///` + exeRoot.replace(/\\/g, '/');
|
|
|
|
} else {
|
|
|
|
hoverUrlBase = `file://` + exeRoot;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let dispUrl = url.replace(hoverUrlBase, lbryProto);
|
2020-05-28 11:47:18 +02:00
|
|
|
// Non-claims don't need the lbry protocol:
|
2020-06-10 19:03:15 +02:00
|
|
|
if (dispUrl === lbryProto) {
|
2020-05-28 11:47:18 +02:00
|
|
|
dispUrl = 'Home';
|
|
|
|
} else if (dispUrl.startsWith(lbryProto + '$/')) {
|
|
|
|
dispUrl = dispUrl.replace(lbryProto, '/');
|
|
|
|
}
|
|
|
|
window.webContents.send('update-target-url', dispUrl);
|
|
|
|
});
|
|
|
|
|
2018-01-18 03:13:08 +01:00
|
|
|
return window;
|
|
|
|
};
|