Partially update discord
|
@ -167,8 +167,8 @@ export default class V2C_PublicServers extends BDV2.reactComponent {
|
|||
};
|
||||
const server2 = {
|
||||
name: "Lightcord",
|
||||
online: "100+",
|
||||
members: "300+",
|
||||
online: "500+",
|
||||
members: "1200+",
|
||||
categories: ["community", "programming", "support"],
|
||||
description: "Official Lightcord server for support etc",
|
||||
identifier: "705908350218666117",
|
||||
|
|
|
@ -1,83 +0,0 @@
|
|||
.theme-dark {
|
||||
--header-primary: #fff;
|
||||
--header-secondary: #b9bbbe;
|
||||
--text-normal: #dcddde;
|
||||
--text-muted: #72767d;
|
||||
--text-link: #00b0f4;
|
||||
--channels-default: #8e9297;
|
||||
--interactive-normal: #b9bbbe;
|
||||
--interactive-hover: #dcddde;
|
||||
--interactive-active: #fff;
|
||||
--interactive-muted: #4f545c;
|
||||
--background-primary: #36393f;
|
||||
--background-secondary: #2f3136;
|
||||
--background-secondary-alt: #292b2f;
|
||||
--background-tertiary: #202225;
|
||||
--background-accent: #4f545c;
|
||||
--background-floating: #18191c;
|
||||
--background-mobile-primary: #36393f;
|
||||
--background-mobile-secondary: #2f3136;
|
||||
--background-modifier-hover: rgba(79,84,92,0.16);
|
||||
--background-modifier-active: rgba(79,84,92,0.24);
|
||||
--background-modifier-selected: rgba(79,84,92,0.32);
|
||||
--background-modifier-accent: hsla(0,0%,100%,0.06);
|
||||
--background-mentioned: rgba(250,166,26,0.05);
|
||||
--background-mentioned-hover: rgba(250,166,26,0.08);
|
||||
--background-message-hover: rgba(4,4,5,0.07);
|
||||
--elevation-stroke: 0 0 0 1px rgba(4,4,5,0.15);
|
||||
--elevation-low: 0 1px 0 rgba(4,4,5,0.2),0 1.5px 0 rgba(6,6,7,0.05),0 2px 0 rgba(4,4,5,0.05);
|
||||
--elevation-medium: 0 4px 4px rgba(0,0,0,0.16);
|
||||
--elevation-high: 0 8px 16px rgba(0,0,0,0.24);
|
||||
--logo-primary: #fff;
|
||||
--focus-primary: #00b0f4;
|
||||
--guild-header-text-shadow: 0 1px 1px rgba(0,0,0,0.4);
|
||||
--channeltextarea-background: #40444b;
|
||||
--activity-card-background: #202225;
|
||||
--textbox-markdown-syntax: #8e9297;
|
||||
--deprecated-card-bg: rgba(32,34,37,0.6);
|
||||
--deprecated-card-editable-bg: rgba(32,34,37,0.3);
|
||||
--deprecated-store-bg: #36393f;
|
||||
--deprecated-quickswitcher-input-background: #72767d;
|
||||
--deprecated-quickswitcher-input-placeholder: hsla(0,0%,100%,0.3);
|
||||
--deprecated-text-input-bg: rgba(0,0,0,0.1);
|
||||
--deprecated-text-input-border: rgba(0,0,0,0.3);
|
||||
--deprecated-text-input-border-hover: #040405;
|
||||
--deprecated-text-input-border-disabled: #202225;
|
||||
--deprecated-text-input-prefix: #dcddde;
|
||||
}
|
||||
|
||||
::placeholder, body, button, input, select, textarea {
|
||||
font-family: Whitney,Helvetica Neue,Helvetica,Arial,sans-serif;
|
||||
text-rendering: optimizeLegibility;
|
||||
}.appMount, body {
|
||||
background-color: var(--background-tertiary);
|
||||
text-rendering: optimizeLegibility;
|
||||
}body{
|
||||
color: var(--text-normal)
|
||||
}.center{
|
||||
text-align: center;
|
||||
}.marginBottom20{
|
||||
margin-bottom: 20px;
|
||||
}.button {
|
||||
position: absolute;
|
||||
top: 200px;
|
||||
padding-right: 12.5px;
|
||||
padding-top: 14px;
|
||||
background-color: #7289da;
|
||||
color: #fff;
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
border-radius: 3px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding-bottom: 14px;
|
||||
padding-left: 12.5px;
|
||||
display: inline;
|
||||
}.button:hover{
|
||||
background-color: #697ec4;
|
||||
cursor: pointer;
|
||||
}.button-yes{
|
||||
left: 100px;
|
||||
}.button-no{
|
||||
left: 300px;
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title></title>
|
||||
<link rel="stylesheet" href="lightcord://index.css">
|
||||
</head>
|
||||
<body class="theme-dark">
|
||||
<div class="appMount">
|
||||
<div class="marginBottom20">
|
||||
|
||||
</div>
|
||||
<h2 class="center">
|
||||
Would you like to use Lightcord's network features ?
|
||||
</h2>
|
||||
<div class="marginBottom20"></div>
|
||||
<div class="marginBottom20"></div>
|
||||
<div class="buttonContainer">
|
||||
<div class="button button-yes">Yes I do !</div>
|
||||
<div class="button button-no">No, thanks</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,63 +0,0 @@
|
|||
const electron = require("electron").remote
|
||||
const fetch = require("node-fetch").default
|
||||
|
||||
const currentWindow = electron.getCurrentWindow()
|
||||
|
||||
|
||||
currentWindow.webContents.on("dom-ready", () => {
|
||||
const customTitlebar = require('custom-electron-titlebar')
|
||||
|
||||
new customTitlebar.Titlebar({
|
||||
backgroundColor: customTitlebar.Color.fromHex('#2f3136'),
|
||||
"drag": true,
|
||||
minimizable: false,
|
||||
maximizable: false,
|
||||
closeable: true,
|
||||
menu: electron.Menu.buildFromTemplate([])
|
||||
});
|
||||
function resetAppMount(){
|
||||
document.querySelector("body > div.container-after-titlebar > div").remove()
|
||||
const appMount = document.createElement("div")
|
||||
appMount.className = "appMount"
|
||||
document.querySelector("body > div.container-after-titlebar").appendChild(appMount)
|
||||
}
|
||||
document.querySelector("body > div.container-after-titlebar > div > div.buttonContainer > div.button.button-yes").addEventListener("click", (ev) => {// should we move location ? or go trough a webview ?
|
||||
resetAppMount()
|
||||
const webview = document.createElement("webview")
|
||||
webview.id = "discordauth"
|
||||
webview.src = "https://discord.com/api/oauth2/authorize?client_id=711416957718757418&redirect_uri=http%3A%2F%2Flightcord.electron%2Flogin%2Fcallback&response_type=code&scope=identify"
|
||||
webview.style.width = "500ox"
|
||||
webview.style.height = "520px"
|
||||
webview.addEventListener('did-stop-loading', () => {
|
||||
console.log("Webview loaded")
|
||||
electron.webContents.fromId(webview.getWebContentsId()).on("will-navigate", (e, url) => {
|
||||
console.log(url)
|
||||
if(url.startsWith("http://lightcord.electron/login/callback?error=")){ // used denied / error.
|
||||
e.preventDefault()
|
||||
currentWindow.close()
|
||||
return
|
||||
}else if(url.startsWith("http://lightcord.electron/login/callback?code=")){ // yay we got the code
|
||||
const query = url.split("?")[1]
|
||||
e.preventDefault()
|
||||
webview.remove()
|
||||
resetAppMount()
|
||||
document.querySelector("body > div.container-after-titlebar > div").innerHTML = '<h2 class="center">Loading...</h2>'
|
||||
fetch("https://lightcord.org/auth/callback?"+query)
|
||||
.then(async res => {
|
||||
if(res.status !== 200){ // error
|
||||
currentWindow.close()
|
||||
return
|
||||
}
|
||||
const resp = await res.text()
|
||||
console.debug(resp)
|
||||
window.location.href = "lightcord://login/callback?auth="+resp
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
document.querySelector("body > div.container-after-titlebar > div").appendChild(webview)
|
||||
})
|
||||
document.querySelector("body > div.container-after-titlebar > div > div.buttonContainer > div.button.button-no").addEventListener("click", (ev) => {
|
||||
currentWindow.close()
|
||||
})
|
||||
})
|
|
@ -1,4 +1,4 @@
|
|||
'use strict';
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
|
@ -6,11 +6,11 @@ Object.defineProperty(exports, "__esModule", {
|
|||
exports.getEnableHardwareAcceleration = getEnableHardwareAcceleration;
|
||||
exports.setEnableHardwareAcceleration = setEnableHardwareAcceleration;
|
||||
|
||||
var _electron = require('electron');
|
||||
var _electron = require("electron");
|
||||
|
||||
var _appSettings = require('./appSettings');
|
||||
var _appSettings = require("./appSettings");
|
||||
|
||||
const settings = _appSettings.getSettings();
|
||||
const settings = (0, _appSettings.getSettings)();
|
||||
|
||||
function getEnableHardwareAcceleration() {
|
||||
// TODO: This should probably a constant
|
||||
|
@ -22,5 +22,6 @@ function setEnableHardwareAcceleration(enableHardwareAcceleration) {
|
|||
settings.save();
|
||||
|
||||
_electron.app.relaunch();
|
||||
|
||||
_electron.app.exit(0);
|
||||
}
|
|
@ -1,31 +1,29 @@
|
|||
'use strict';
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.hasInit = undefined;
|
||||
exports.init = init;
|
||||
exports.hasInit = void 0;
|
||||
|
||||
var _electron = require('electron');
|
||||
var _electron = require("electron");
|
||||
|
||||
var _utils = require('./utils');
|
||||
var _utils = require("./utils");
|
||||
|
||||
var _mainScreen = require('./mainScreen');
|
||||
var _mainScreen = require("./mainScreen");
|
||||
|
||||
var _ipcMain = require('./ipcMain');
|
||||
|
||||
var _ipcMain2 = _interopRequireDefault(_ipcMain);
|
||||
var _ipcMain = _interopRequireDefault(require("./ipcMain"));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
let hasInit = exports.hasInit = false;
|
||||
|
||||
let hasInit = false;
|
||||
exports.hasInit = hasInit;
|
||||
let lastIndex;
|
||||
let appIcons;
|
||||
|
||||
/**
|
||||
* Used on Windows to set the taskbar icon
|
||||
*/
|
||||
|
||||
function init() {
|
||||
// Only init on win32 platforms
|
||||
if (process.platform !== 'win32') return;
|
||||
|
@ -34,26 +32,27 @@ function init() {
|
|||
console.warn('appBadge: Has already init! Cancelling init.');
|
||||
return;
|
||||
}
|
||||
exports.hasInit = hasInit = true;
|
||||
|
||||
exports.hasInit = hasInit = true;
|
||||
lastIndex = null;
|
||||
appIcons = [];
|
||||
|
||||
const resourcePath = `app/images/badges`;
|
||||
|
||||
for (let i = 1; i <= 11; i++) {
|
||||
appIcons.push(_utils.exposeModuleResource(resourcePath, `badge-${i}.ico`));
|
||||
appIcons.push((0, _utils.exposeModuleResource)(resourcePath, `badge-${i}.ico`));
|
||||
}
|
||||
|
||||
_ipcMain2.default.on('APP_BADGE_SET', (_event, count) => setAppBadge(count));
|
||||
_ipcMain.default.on('APP_BADGE_SET', (_event, count) => setAppBadge(count));
|
||||
}
|
||||
|
||||
function setAppBadge(count) {
|
||||
const win = _electron.BrowserWindow.fromId((0, _mainScreen.getMainWindowId)());
|
||||
|
||||
const { index, description } = getOverlayIconData(count);
|
||||
const {
|
||||
index,
|
||||
description
|
||||
} = getOverlayIconData(count); // Prevent setting a new icon when the icon is the same
|
||||
|
||||
// Prevent setting a new icon when the icon is the same
|
||||
if (lastIndex !== index) {
|
||||
if (index == null) {
|
||||
win.setOverlayIcon(null, description);
|
||||
|
@ -64,32 +63,36 @@ function setAppBadge(count) {
|
|||
lastIndex = index;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* -1 is bullet
|
||||
* 0 is nothing
|
||||
* 1-9 is a number badge
|
||||
* 10+ is `9+`
|
||||
*/
|
||||
|
||||
|
||||
function getOverlayIconData(count) {
|
||||
// Unread message badge
|
||||
if (count === -1) {
|
||||
return {
|
||||
index: 10, // this.appIcons.length - 1
|
||||
index: 10,
|
||||
// this.appIcons.length - 1
|
||||
description: `Unread messages`
|
||||
};
|
||||
}
|
||||
} // Clear overlay icon
|
||||
|
||||
|
||||
// Clear overlay icon
|
||||
if (count === 0) {
|
||||
return {
|
||||
index: null, // null is used to clear the overlay icon
|
||||
index: null,
|
||||
// null is used to clear the overlay icon
|
||||
description: 'No Notifications'
|
||||
};
|
||||
}
|
||||
} // Notification badge
|
||||
|
||||
|
||||
// Notification badge
|
||||
const index = Math.max(1, Math.min(count, 10)) - 1; // arrays are 0 based
|
||||
|
||||
return {
|
||||
index,
|
||||
description: `${index} notifications`
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
'use strict';
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
|
@ -6,16 +6,14 @@ Object.defineProperty(exports, "__esModule", {
|
|||
exports.init = init;
|
||||
exports.getFeatures = getFeatures;
|
||||
|
||||
var _FeatureFlags = require('../common/FeatureFlags');
|
||||
|
||||
var _FeatureFlags2 = _interopRequireDefault(_FeatureFlags);
|
||||
var _FeatureFlags = _interopRequireDefault(require("../common/FeatureFlags"));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
let features;
|
||||
|
||||
function init() {
|
||||
features = new _FeatureFlags2.default();
|
||||
features = new _FeatureFlags.default();
|
||||
}
|
||||
|
||||
function getFeatures() {
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
'use strict';
|
||||
"use strict";
|
||||
|
||||
module.exports = require('./bootstrapModules').appSettings;
|
|
@ -1,44 +1,54 @@
|
|||
'use strict';
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
|
||||
var _electron = require('electron');
|
||||
var _electron = require("electron");
|
||||
|
||||
var _Constants = require('../Constants');
|
||||
var _securityUtils = require("../../common/securityUtils");
|
||||
|
||||
var Constants = _interopRequireWildcard(_Constants);
|
||||
var Constants = _interopRequireWildcard(require("../Constants"));
|
||||
|
||||
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
|
||||
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
|
||||
|
||||
const { MenuEvents } = Constants;
|
||||
const SEPARATOR = { type: 'separator' };
|
||||
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
||||
|
||||
const {
|
||||
MenuEvents
|
||||
} = Constants;
|
||||
const SEPARATOR = {
|
||||
type: 'separator'
|
||||
};
|
||||
|
||||
function getWindow() {
|
||||
let window = _electron.BrowserWindow.getFocusedWindow();
|
||||
|
||||
if (!window) {
|
||||
const windowList = _electron.BrowserWindow.getAllWindows();
|
||||
|
||||
if (windowList && windowList[0]) {
|
||||
window = windowList[0];
|
||||
window.show();
|
||||
window.focus();
|
||||
}
|
||||
}
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
exports.default = [{
|
||||
var _default = [{
|
||||
label: 'Lightcord',
|
||||
submenu: [{
|
||||
label: 'About Lightcord',
|
||||
label: 'About Discord',
|
||||
selector: 'orderFrontStandardAboutPanel:'
|
||||
}, {
|
||||
label: 'Check for Updates...',
|
||||
click: () => _electron.app.emit(MenuEvents.CHECK_FOR_UPDATES)
|
||||
}, {
|
||||
label: 'Acknowledgements',
|
||||
click: () => _electron.shell.openExternal('https://discord.com/acknowledgements')
|
||||
click: () => (0, _securityUtils.saferShellOpenExternal)('https://discord.com/acknowledgements')
|
||||
}, SEPARATOR, {
|
||||
label: 'Preferences',
|
||||
click: () => _electron.app.emit(MenuEvents.OPEN_SETTINGS),
|
||||
|
@ -89,6 +99,7 @@ exports.default = [{
|
|||
label: 'Reload',
|
||||
click: () => {
|
||||
const window = getWindow();
|
||||
|
||||
if (window) {
|
||||
window.webContents.reloadIgnoringCache();
|
||||
}
|
||||
|
@ -98,6 +109,7 @@ exports.default = [{
|
|||
label: 'Toggle Full Screen',
|
||||
click: () => {
|
||||
const window = getWindow();
|
||||
|
||||
if (window) {
|
||||
window.setFullScreen(!window.isFullScreen());
|
||||
}
|
||||
|
@ -109,6 +121,7 @@ exports.default = [{
|
|||
label: 'Toggle Developer Tools',
|
||||
click: () => {
|
||||
const window = getWindow();
|
||||
|
||||
if (window) {
|
||||
window.toggleDevTools();
|
||||
}
|
||||
|
@ -128,7 +141,14 @@ exports.default = [{
|
|||
}, {
|
||||
label: 'Close',
|
||||
accelerator: 'Command+W',
|
||||
selector: 'hide:'
|
||||
click: (_, window) => {
|
||||
// Main window
|
||||
if (window == null || window.windowKey == null) {
|
||||
_electron.Menu.sendActionToFirstResponder('hide:');
|
||||
} else {
|
||||
window.close();
|
||||
}
|
||||
}
|
||||
}, SEPARATOR, {
|
||||
label: 'Bring All to Front',
|
||||
selector: 'arrangeInFront:'
|
||||
|
@ -136,8 +156,9 @@ exports.default = [{
|
|||
}, {
|
||||
label: 'Help',
|
||||
submenu: [{
|
||||
label: 'Lightcord Help',
|
||||
label: 'Discord Help',
|
||||
click: () => _electron.app.emit(MenuEvents.OPEN_HELP)
|
||||
}]
|
||||
}];
|
||||
exports.default = _default;
|
||||
module.exports = exports.default;
|
|
@ -1,12 +1,13 @@
|
|||
'use strict';
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
|
||||
var _electron = require('electron');
|
||||
exports.default = void 0;
|
||||
|
||||
const menu = require('./' + process.platform);
|
||||
|
||||
exports.default = menu
|
||||
var _default = menu
|
||||
|
||||
exports.default = _default;
|
||||
module.exports = exports.default;
|
|
@ -1,21 +1,25 @@
|
|||
'use strict';
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
|
||||
var _electron = require('electron');
|
||||
var _electron = require("electron");
|
||||
|
||||
var _Constants = require('../Constants');
|
||||
var Constants = _interopRequireWildcard(require("../Constants"));
|
||||
|
||||
var Constants = _interopRequireWildcard(_Constants);
|
||||
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
|
||||
|
||||
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
|
||||
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
||||
|
||||
const { MenuEvents } = Constants;
|
||||
const SEPARATOR = { type: 'separator' };
|
||||
|
||||
exports.default = [{
|
||||
const {
|
||||
MenuEvents
|
||||
} = Constants;
|
||||
const SEPARATOR = {
|
||||
type: 'separator'
|
||||
};
|
||||
var _default = [{
|
||||
label: '&File',
|
||||
submenu: [{
|
||||
label: '&Options',
|
||||
|
@ -71,8 +75,9 @@ exports.default = [{
|
|||
label: 'Check for Updates',
|
||||
click: () => _electron.app.emit(MenuEvents.CHECK_FOR_UPDATES)
|
||||
}, SEPARATOR, {
|
||||
label: 'Lightcord Help',
|
||||
label: 'Discord Help',
|
||||
click: () => _electron.app.emit(MenuEvents.OPEN_HELP)
|
||||
}]
|
||||
}];
|
||||
exports.default = _default;
|
||||
module.exports = exports.default;
|
|
@ -1,21 +1,25 @@
|
|||
'use strict';
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
|
||||
var _electron = require('electron');
|
||||
var _electron = require("electron");
|
||||
|
||||
var _Constants = require('../Constants');
|
||||
var Constants = _interopRequireWildcard(require("../Constants"));
|
||||
|
||||
var Constants = _interopRequireWildcard(_Constants);
|
||||
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
|
||||
|
||||
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
|
||||
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
||||
|
||||
const { MenuEvents } = Constants;
|
||||
const SEPARATOR = { type: 'separator' };
|
||||
|
||||
exports.default = [{
|
||||
const {
|
||||
MenuEvents
|
||||
} = Constants;
|
||||
const SEPARATOR = {
|
||||
type: 'separator'
|
||||
};
|
||||
var _default = [{
|
||||
label: '&File',
|
||||
submenu: [{
|
||||
label: '&Options',
|
||||
|
@ -50,8 +54,9 @@ exports.default = [{
|
|||
label: 'Check for Updates',
|
||||
click: () => _electron.app.emit(MenuEvents.CHECK_FOR_UPDATES)
|
||||
}, SEPARATOR, {
|
||||
label: 'Lightcord Help',
|
||||
label: 'Discord Help',
|
||||
click: () => _electron.app.emit(MenuEvents.OPEN_HELP)
|
||||
}]
|
||||
}];
|
||||
exports.default = _default;
|
||||
module.exports = exports.default;
|
|
@ -1,3 +1,3 @@
|
|||
'use strict';
|
||||
"use strict";
|
||||
|
||||
module.exports = require('./bootstrapModules').autoStart;
|
|
@ -6,8 +6,10 @@ exports.init = function (bootstrapModules) {
|
|||
if (hasInit) {
|
||||
throw new Error(`bootstrapModules has already init`);
|
||||
}
|
||||
|
||||
for (const mod of Object.keys(bootstrapModules)) {
|
||||
exports[mod] = bootstrapModules[mod];
|
||||
}
|
||||
|
||||
hasInit = true;
|
||||
};
|
|
@ -1,3 +1,3 @@
|
|||
'use strict';
|
||||
"use strict";
|
||||
|
||||
module.exports = require('./bootstrapModules').buildInfo;
|
|
@ -0,0 +1,5 @@
|
|||
"use strict";
|
||||
|
||||
const bootstrapCrashReporterSetup = require('./bootstrapModules').crashReporterSetup;
|
||||
|
||||
module.exports = bootstrapCrashReporterSetup != null ? bootstrapCrashReporterSetup : require('../common/crashReporterSetup');
|
|
@ -1,17 +1,11 @@
|
|||
'use strict';
|
||||
|
||||
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
|
||||
"use strict";
|
||||
|
||||
const electron = require('electron');
|
||||
|
||||
const { ACCESSIBILITY_GET_ENABLED } = require('../common/constants').IPCEvents;
|
||||
const {
|
||||
ACCESSIBILITY_GET_ENABLED
|
||||
} = require('../common/constants').IPCEvents;
|
||||
|
||||
electron.ipcMain.handle(ACCESSIBILITY_GET_ENABLED, (() => {
|
||||
var _ref = _asyncToGenerator(function* (_) {
|
||||
electron.ipcMain.handle(ACCESSIBILITY_GET_ENABLED, async _ => {
|
||||
return electron.app.accessibilitySupportEnabled;
|
||||
});
|
||||
|
||||
return function (_x) {
|
||||
return _ref.apply(this, arguments);
|
||||
};
|
||||
})());
|
||||
});
|
|
@ -1,12 +1,11 @@
|
|||
'use strict';
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.injectBuildInfo = injectBuildInfo;
|
||||
exports.injectModuleUpdater = injectModuleUpdater;
|
||||
|
||||
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
|
||||
exports.injectUpdater = injectUpdater;
|
||||
|
||||
const electron = require('electron');
|
||||
|
||||
|
@ -25,6 +24,7 @@ const {
|
|||
|
||||
let injectedBuildInfo = null;
|
||||
let injectedModuleUpdater = null;
|
||||
let injectedUpdater = null;
|
||||
|
||||
function injectBuildInfo(buildInfo) {
|
||||
injectedBuildInfo = buildInfo;
|
||||
|
@ -34,110 +34,67 @@ function injectModuleUpdater(moduleUpdater) {
|
|||
injectedModuleUpdater = moduleUpdater;
|
||||
}
|
||||
|
||||
function injectUpdater(updater) {
|
||||
injectedUpdater = updater;
|
||||
}
|
||||
|
||||
electron.ipcMain.on(APP_GET_RELEASE_CHANNEL_SYNC, event => {
|
||||
event.returnValue = injectedBuildInfo.releaseChannel;
|
||||
});
|
||||
|
||||
electron.ipcMain.on(APP_GET_HOST_VERSION_SYNC, event => {
|
||||
// hardcode because Discord could identify Lightcord or could simply bug.
|
||||
if(process.platform === "darwin")
|
||||
event.returnValue = "0.0.259";
|
||||
else if(process.platform === "linux")
|
||||
event.returnValue = "0.0.12";
|
||||
else
|
||||
event.returnValue = "0.0.308"; //electron.app.getVersion();
|
||||
event.returnValue = electron.app.getVersion();
|
||||
});
|
||||
|
||||
electron.ipcMain.handle(APP_GET_MODULE_VERSIONS, (() => {
|
||||
var _ref = _asyncToGenerator(function* (_) {
|
||||
async function newUpdaterGetModuleVersions(updater) {
|
||||
// eslint-disable-next-line camelcase
|
||||
return (await updater.queryCurrentVersions()).current_modules;
|
||||
}
|
||||
|
||||
electron.ipcMain.handle(APP_GET_MODULE_VERSIONS, async _ => {
|
||||
var _injectedUpdater;
|
||||
|
||||
const newUpdater = (_injectedUpdater = injectedUpdater) === null || _injectedUpdater === void 0 ? void 0 : _injectedUpdater.getUpdater();
|
||||
|
||||
if (newUpdater != null) {
|
||||
return newUpdaterGetModuleVersions(newUpdater);
|
||||
}
|
||||
|
||||
const versions = {};
|
||||
const installed = injectedModuleUpdater != null ? injectedModuleUpdater.getInstalled() : {};
|
||||
|
||||
for (const name of Object.keys(installed)) {
|
||||
versions[name] = installed[name].installedVersion;
|
||||
}
|
||||
|
||||
return versions;
|
||||
});
|
||||
|
||||
return function (_x) {
|
||||
return _ref.apply(this, arguments);
|
||||
};
|
||||
})());
|
||||
|
||||
electron.ipcMain.handle(APP_GET_PATH, (() => {
|
||||
var _ref2 = _asyncToGenerator(function* (_, path) {
|
||||
});
|
||||
electron.ipcMain.handle(APP_GET_PATH, async (_, path) => {
|
||||
return electron.app.getPath(path);
|
||||
});
|
||||
|
||||
return function (_x2, _x3) {
|
||||
return _ref2.apply(this, arguments);
|
||||
};
|
||||
})());
|
||||
|
||||
electron.ipcMain.handle(APP_SET_BADGE_COUNT, (() => {
|
||||
var _ref3 = _asyncToGenerator(function* (_, count) {
|
||||
});
|
||||
electron.ipcMain.handle(APP_SET_BADGE_COUNT, async (_, count) => {
|
||||
electron.app.setBadgeCount(count);
|
||||
});
|
||||
|
||||
return function (_x4, _x5) {
|
||||
return _ref3.apply(this, arguments);
|
||||
};
|
||||
})());
|
||||
|
||||
electron.ipcMain.handle(APP_DOCK_SET_BADGE, (() => {
|
||||
var _ref4 = _asyncToGenerator(function* (_, badge) {
|
||||
});
|
||||
electron.ipcMain.handle(APP_DOCK_SET_BADGE, async (_, badge) => {
|
||||
if (electron.app.dock != null) {
|
||||
electron.app.dock.setBadge(badge);
|
||||
}
|
||||
});
|
||||
|
||||
return function (_x6, _x7) {
|
||||
return _ref4.apply(this, arguments);
|
||||
};
|
||||
})());
|
||||
|
||||
electron.ipcMain.handle(APP_DOCK_BOUNCE, (() => {
|
||||
var _ref5 = _asyncToGenerator(function* (_, type) {
|
||||
});
|
||||
electron.ipcMain.handle(APP_DOCK_BOUNCE, async (_, type) => {
|
||||
if (electron.app.dock != null) {
|
||||
return electron.app.dock.bounce(type);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
});
|
||||
|
||||
return function (_x8, _x9) {
|
||||
return _ref5.apply(this, arguments);
|
||||
};
|
||||
})());
|
||||
|
||||
electron.ipcMain.handle(APP_DOCK_CANCEL_BOUNCE, (() => {
|
||||
var _ref6 = _asyncToGenerator(function* (_, id) {
|
||||
});
|
||||
electron.ipcMain.handle(APP_DOCK_CANCEL_BOUNCE, async (_, id) => {
|
||||
if (electron.app.dock != null) {
|
||||
electron.app.dock.cancelBounce(id);
|
||||
}
|
||||
});
|
||||
|
||||
return function (_x10, _x11) {
|
||||
return _ref6.apply(this, arguments);
|
||||
};
|
||||
})());
|
||||
|
||||
electron.ipcMain.handle(APP_RELAUNCH, (() => {
|
||||
var _ref7 = _asyncToGenerator(function* (_) {
|
||||
});
|
||||
electron.ipcMain.handle(APP_RELAUNCH, async _ => {
|
||||
electron.app.relaunch();
|
||||
electron.app.exit(0);
|
||||
});
|
||||
|
||||
return function (_x12) {
|
||||
return _ref7.apply(this, arguments);
|
||||
};
|
||||
})());
|
||||
|
||||
electron.ipcMain.handle(APP_GET_DEFAULT_DOUBLE_CLICK_ACTION, (() => {
|
||||
var _ref8 = _asyncToGenerator(function* (_) {
|
||||
});
|
||||
electron.ipcMain.handle(APP_GET_DEFAULT_DOUBLE_CLICK_ACTION, async _ => {
|
||||
return electron.systemPreferences.getUserDefault('AppleActionOnDoubleClick', 'string');
|
||||
});
|
||||
|
||||
return function (_x13) {
|
||||
return _ref8.apply(this, arguments);
|
||||
};
|
||||
})());
|
||||
});
|
|
@ -1,37 +1,19 @@
|
|||
'use strict';
|
||||
|
||||
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
|
||||
"use strict";
|
||||
|
||||
const electron = require('electron');
|
||||
|
||||
const { CLIPBOARD_COPY, CLIPBOARD_CUT, CLIPBOARD_PASTE } = require('../common/constants').IPCEvents;
|
||||
const {
|
||||
CLIPBOARD_COPY,
|
||||
CLIPBOARD_CUT,
|
||||
CLIPBOARD_PASTE
|
||||
} = require('../common/constants').IPCEvents;
|
||||
|
||||
electron.ipcMain.handle(CLIPBOARD_COPY, (() => {
|
||||
var _ref = _asyncToGenerator(function* (_) {
|
||||
electron.ipcMain.handle(CLIPBOARD_COPY, async _ => {
|
||||
electron.webContents.getFocusedWebContents().copy();
|
||||
});
|
||||
|
||||
return function (_x) {
|
||||
return _ref.apply(this, arguments);
|
||||
};
|
||||
})());
|
||||
|
||||
electron.ipcMain.handle(CLIPBOARD_CUT, (() => {
|
||||
var _ref2 = _asyncToGenerator(function* (_) {
|
||||
});
|
||||
electron.ipcMain.handle(CLIPBOARD_CUT, async _ => {
|
||||
electron.webContents.getFocusedWebContents().cut();
|
||||
});
|
||||
|
||||
return function (_x2) {
|
||||
return _ref2.apply(this, arguments);
|
||||
};
|
||||
})());
|
||||
|
||||
electron.ipcMain.handle(CLIPBOARD_PASTE, (() => {
|
||||
var _ref3 = _asyncToGenerator(function* (_) {
|
||||
});
|
||||
electron.ipcMain.handle(CLIPBOARD_PASTE, async _ => {
|
||||
electron.webContents.getFocusedWebContents().paste();
|
||||
});
|
||||
|
||||
return function (_x3) {
|
||||
return _ref3.apply(this, arguments);
|
||||
};
|
||||
})());
|
||||
});
|
|
@ -0,0 +1,28 @@
|
|||
"use strict";
|
||||
|
||||
const electron = require('electron');
|
||||
|
||||
const {
|
||||
CONSTANTS_GET
|
||||
} = require('../common/constants').IPCEvents;
|
||||
|
||||
const {
|
||||
APP_NAME,
|
||||
APP_ID,
|
||||
API_ENDPOINT,
|
||||
UPDATE_ENDPOINT
|
||||
} = require('../../Constants');
|
||||
|
||||
const exposedConstants = {
|
||||
APP_NAME,
|
||||
APP_ID,
|
||||
API_ENDPOINT,
|
||||
UPDATE_ENDPOINT
|
||||
};
|
||||
electron.ipcMain.handle(CONSTANTS_GET, async (_, name) => {
|
||||
if (!exposedConstants.hasOwnProperty(name)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return exposedConstants[name];
|
||||
});
|
|
@ -1,77 +1,38 @@
|
|||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.injectBuildInfo = injectBuildInfo;
|
||||
|
||||
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
|
||||
"use strict";
|
||||
|
||||
const electron = require('electron');
|
||||
|
||||
const lodash = require('lodash');
|
||||
const childProcess = require('child_process');
|
||||
const { getElectronMajorVersion, flatten, reconcileCrashReporterMetadata } = require('../common/utility');
|
||||
|
||||
const { CRASH_REPORTER_UPDATE_METADATA } = require('../common/constants').IPCEvents;
|
||||
const {
|
||||
reconcileCrashReporterMetadata
|
||||
} = require('../../../common/crashReporterUtils');
|
||||
|
||||
const metadata = exports.metadata = {};
|
||||
const {
|
||||
getElectronMajorVersion
|
||||
} = require('../../../common/processUtils');
|
||||
|
||||
function injectBuildInfo(buildInfo) {
|
||||
metadata['channel'] = buildInfo.releaseChannel;
|
||||
const sentryMetadata = metadata['sentry'] != null ? metadata['sentry'] : {};
|
||||
sentryMetadata['environment'] = buildInfo.releaseChannel;
|
||||
sentryMetadata['release'] = buildInfo.version;
|
||||
metadata['sentry'] = sentryMetadata;
|
||||
}
|
||||
const {
|
||||
metadata
|
||||
} = require('../../crashReporterSetup');
|
||||
|
||||
if (process.platform === 'linux') {
|
||||
const XDG_CURRENT_DESKTOP = process.env.XDG_CURRENT_DESKTOP || 'unknown';
|
||||
const GDMSESSION = process.env.GDMSESSION || 'unknown';
|
||||
metadata['wm'] = `${XDG_CURRENT_DESKTOP},${GDMSESSION}`;
|
||||
try {
|
||||
metadata['distro'] = childProcess.execFileSync('lsb_release', ['-ds'], { timeout: 100, maxBuffer: 512, encoding: 'utf-8' }).trim();
|
||||
} catch (_) {} // just in case lsb_release doesn't exist
|
||||
}
|
||||
const {
|
||||
CRASH_REPORTER_UPDATE_METADATA
|
||||
} = require('../common/constants').IPCEvents;
|
||||
|
||||
function getCrashReporterArgs(metadata) {
|
||||
// NB: we need to flatten the metadata because modern electron caps metadata values at 127 bytes,
|
||||
// which our sentry subobject can easily exceed.
|
||||
let flat_metadata = flatten(metadata);
|
||||
|
||||
return {
|
||||
productName: 'Discord',
|
||||
companyName: 'Discord Inc.',
|
||||
submitURL: 'https://sentry.io/api/146342/minidump/?sentry_key=384ce4413de74fe0be270abe03b2b35a',
|
||||
uploadToServer: false,
|
||||
ignoreSystemCrashHandler: false,
|
||||
extra: flat_metadata
|
||||
};
|
||||
}
|
||||
|
||||
//electron.crashReporter.start(getCrashReporterArgs(metadata));
|
||||
|
||||
electron.ipcMain.handle(CRASH_REPORTER_UPDATE_METADATA, (() => {
|
||||
var _ref = _asyncToGenerator(function* (_, additional_metadata) {
|
||||
electron.ipcMain.handle(CRASH_REPORTER_UPDATE_METADATA, async (_, additional_metadata) => {
|
||||
const final_metadata = lodash.defaultsDeep({}, metadata, additional_metadata || {});
|
||||
const result = {
|
||||
metadata: final_metadata
|
||||
};
|
||||
|
||||
// In Electron 9 we only start the crashReporter once and let reconcileCrashReporterMetadata
|
||||
}; // In Electron 9 we only start the crashReporter once and let reconcileCrashReporterMetadata
|
||||
// do the work of keeping `extra` up-to-date. Prior to this we would simply start crashReporter
|
||||
// again to apply new metadata as well as pass the full arguments back to the renderer so it
|
||||
// could do similarly.
|
||||
|
||||
if (getElectronMajorVersion() < 9) {
|
||||
const args = getCrashReporterArgs(final_metadata);
|
||||
//electron.crashReporter.start(args);
|
||||
result.args = args;
|
||||
}
|
||||
|
||||
reconcileCrashReporterMetadata(electron.crashReporter, final_metadata);
|
||||
return result;
|
||||
});
|
||||
|
||||
return function (_x, _x2) {
|
||||
return _ref.apply(this, arguments);
|
||||
};
|
||||
})());
|
||||
});
|
|
@ -1,12 +1,15 @@
|
|||
'use strict';
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.injectFeaturesBackend = injectFeaturesBackend;
|
||||
|
||||
const electron = require('electron');
|
||||
|
||||
const { FEATURES_GET_BROWSER_FEATURES } = require('../common/constants').IPCEvents;
|
||||
const {
|
||||
FEATURES_GET_BROWSER_FEATURES
|
||||
} = require('../common/constants').IPCEvents;
|
||||
|
||||
let injectedFeatures = null;
|
||||
|
||||
|
|
|
@ -1,52 +1,27 @@
|
|||
'use strict';
|
||||
|
||||
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
|
||||
"use strict";
|
||||
|
||||
const electron = require('electron');
|
||||
|
||||
const {
|
||||
FILE_MANAGER_GET_MODULE_PATH,
|
||||
FILE_MANAGER_GET_MODULE_DATA_PATH_SYNC,
|
||||
FILE_MANAGER_SHOW_SAVE_DIALOG,
|
||||
FILE_MANAGER_SHOW_OPEN_DIALOG,
|
||||
FILE_MANAGER_SHOW_ITEM_IN_FOLDER
|
||||
} = require('../common/constants').IPCEvents;
|
||||
|
||||
electron.ipcMain.handle(FILE_MANAGER_GET_MODULE_PATH, (() => {
|
||||
var _ref = _asyncToGenerator(function* (_) {
|
||||
return global.modulePath;
|
||||
});
|
||||
|
||||
return function (_x) {
|
||||
return _ref.apply(this, arguments);
|
||||
};
|
||||
})());
|
||||
|
||||
electron.ipcMain.handle(FILE_MANAGER_SHOW_SAVE_DIALOG, (() => {
|
||||
var _ref2 = _asyncToGenerator(function* (_, dialogOptions) {
|
||||
return yield electron.dialog.showSaveDialog(dialogOptions);
|
||||
});
|
||||
|
||||
return function (_x2, _x3) {
|
||||
return _ref2.apply(this, arguments);
|
||||
};
|
||||
})());
|
||||
|
||||
electron.ipcMain.handle(FILE_MANAGER_SHOW_OPEN_DIALOG, (() => {
|
||||
var _ref3 = _asyncToGenerator(function* (_, dialogOptions) {
|
||||
return yield electron.dialog.showOpenDialog(dialogOptions);
|
||||
});
|
||||
|
||||
return function (_x4, _x5) {
|
||||
return _ref3.apply(this, arguments);
|
||||
};
|
||||
})());
|
||||
|
||||
electron.ipcMain.handle(FILE_MANAGER_SHOW_ITEM_IN_FOLDER, (() => {
|
||||
var _ref4 = _asyncToGenerator(function* (_, path) {
|
||||
electron.ipcMain.handle(FILE_MANAGER_GET_MODULE_PATH, async _ => {
|
||||
return global.moduleDataPath || global.modulePath;
|
||||
});
|
||||
electron.ipcMain.handle(FILE_MANAGER_SHOW_SAVE_DIALOG, async (_, dialogOptions) => {
|
||||
return await electron.dialog.showSaveDialog(dialogOptions);
|
||||
});
|
||||
electron.ipcMain.handle(FILE_MANAGER_SHOW_OPEN_DIALOG, async (_, dialogOptions) => {
|
||||
return await electron.dialog.showOpenDialog(dialogOptions);
|
||||
});
|
||||
electron.ipcMain.handle(FILE_MANAGER_SHOW_ITEM_IN_FOLDER, async (_, path) => {
|
||||
electron.shell.showItemInFolder(path);
|
||||
});
|
||||
|
||||
return function (_x6, _x7) {
|
||||
return _ref4.apply(this, arguments);
|
||||
};
|
||||
})());
|
||||
});
|
||||
electron.ipcMain.on(FILE_MANAGER_GET_MODULE_DATA_PATH_SYNC, event => {
|
||||
event.returnValue = global.moduleDataPath || global.modulePath;
|
||||
});
|
|
@ -1,12 +1,10 @@
|
|||
'use strict';
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.injectGpuSettingsBackend = injectGpuSettingsBackend;
|
||||
|
||||
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
|
||||
|
||||
const electron = require('electron');
|
||||
|
||||
const {
|
||||
|
@ -20,18 +18,11 @@ function injectGpuSettingsBackend(gpuSettings) {
|
|||
injectedGpuSettings = gpuSettings;
|
||||
}
|
||||
|
||||
electron.ipcMain.handle(GPU_SETTINGS_SET_ENABLE_HWACCEL, (() => {
|
||||
var _ref = _asyncToGenerator(function* (_, enable) {
|
||||
electron.ipcMain.handle(GPU_SETTINGS_SET_ENABLE_HWACCEL, async (_, enable) => {
|
||||
if (injectedGpuSettings) {
|
||||
injectedGpuSettings.setEnableHardwareAcceleration(enable);
|
||||
}
|
||||
});
|
||||
|
||||
return function (_x, _x2) {
|
||||
return _ref.apply(this, arguments);
|
||||
};
|
||||
})());
|
||||
|
||||
});
|
||||
electron.ipcMain.on(GPU_SETTINGS_GET_ENABLE_HWACCEL_SYNC, event => {
|
||||
event.returnValue = injectedGpuSettings != null ? injectedGpuSettings.getEnableHardwareAcceleration() : false;
|
||||
});
|
|
@ -1,23 +1,41 @@
|
|||
'use strict';
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.injectModuleUpdater = injectModuleUpdater;
|
||||
exports.injectUpdater = injectUpdater;
|
||||
|
||||
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
|
||||
const childProcess = require('child_process');
|
||||
|
||||
const electron = require('electron');
|
||||
const { once } = require('events');
|
||||
|
||||
const { NATIVE_MODULES_GET_PATHS, NATIVE_MODULES_INSTALL } = require('../common/constants').IPCEvents;
|
||||
const {
|
||||
once
|
||||
} = require('events');
|
||||
|
||||
const path = require('path');
|
||||
|
||||
const process = require('process');
|
||||
|
||||
const {
|
||||
NATIVE_MODULES_GET_PATHS,
|
||||
NATIVE_MODULES_INSTALL,
|
||||
NATIVE_MODULES_FINISH_UPDATER_BOOTSTRAP,
|
||||
NATIVE_MODULES_GET_HAS_NEW_UPDATER
|
||||
} = require('../common/constants').IPCEvents;
|
||||
|
||||
let injectedModuleUpdater = null;
|
||||
let injectedUpdater = null;
|
||||
|
||||
function injectModuleUpdater(moduleUpdater) {
|
||||
injectedModuleUpdater = moduleUpdater;
|
||||
}
|
||||
|
||||
function injectUpdater(updater) {
|
||||
injectedUpdater = updater;
|
||||
}
|
||||
|
||||
electron.ipcMain.on(NATIVE_MODULES_GET_PATHS, event => {
|
||||
event.returnValue = {
|
||||
mainAppDirname: global.mainAppDirname,
|
||||
|
@ -25,17 +43,35 @@ electron.ipcMain.on(NATIVE_MODULES_GET_PATHS, event => {
|
|||
};
|
||||
});
|
||||
|
||||
electron.ipcMain.handle(NATIVE_MODULES_INSTALL, (() => {
|
||||
var _ref = _asyncToGenerator(function* (_, moduleName) {
|
||||
async function newUpdaterInstall(updater, moduleName) {
|
||||
try {
|
||||
await updater.installModule(moduleName);
|
||||
await updater.commitModules();
|
||||
} catch (e) {
|
||||
throw new Error(`Failed to install ${moduleName}: ${e}`);
|
||||
}
|
||||
}
|
||||
|
||||
electron.ipcMain.handle(NATIVE_MODULES_INSTALL, async (_, moduleName) => {
|
||||
var _injectedUpdater;
|
||||
|
||||
const newUpdater = (_injectedUpdater = injectedUpdater) === null || _injectedUpdater === void 0 ? void 0 : _injectedUpdater.getUpdater();
|
||||
|
||||
if (newUpdater != null) {
|
||||
return newUpdaterInstall(newUpdater, moduleName);
|
||||
}
|
||||
|
||||
const updater = injectedModuleUpdater;
|
||||
|
||||
if (!updater) {
|
||||
throw new Error('Module updater is not available!');
|
||||
}
|
||||
|
||||
const waitForInstall = new Promise(function (resolve, reject) {
|
||||
let installedHandler = function (installedModuleEvent) {
|
||||
const waitForInstall = new Promise((resolve, reject) => {
|
||||
const installedHandler = installedModuleEvent => {
|
||||
if (installedModuleEvent.name === moduleName) {
|
||||
updater.events.removeListener(updater.INSTALLED_MODULE, installedHandler);
|
||||
|
||||
if (installedModuleEvent.succeeded) {
|
||||
resolve();
|
||||
} else {
|
||||
|
@ -46,12 +82,33 @@ electron.ipcMain.handle(NATIVE_MODULES_INSTALL, (() => {
|
|||
|
||||
updater.events.on(updater.INSTALLED_MODULE, installedHandler);
|
||||
});
|
||||
|
||||
updater.install(moduleName, false);
|
||||
yield waitForInstall;
|
||||
});
|
||||
await waitForInstall;
|
||||
});
|
||||
electron.ipcMain.on(NATIVE_MODULES_GET_HAS_NEW_UPDATER, event => {
|
||||
var _injectedUpdater2;
|
||||
|
||||
return function (_x, _x2) {
|
||||
return _ref.apply(this, arguments);
|
||||
};
|
||||
})());
|
||||
event.returnValue = ((_injectedUpdater2 = injectedUpdater) === null || _injectedUpdater2 === void 0 ? void 0 : _injectedUpdater2.getUpdater()) != null;
|
||||
}); // This endpoint is a bit special in the sense that it's exposed from
|
||||
// discord_updater_bootstrap instead of discord_desktop_core. The reason for
|
||||
// this is so that a malicious app can't pass in an arbitrary version number to
|
||||
// launch.
|
||||
|
||||
electron.ipcMain.on(NATIVE_MODULES_FINISH_UPDATER_BOOTSTRAP, async (_, [major, minor, revision]) => {
|
||||
// TODO(eiz): This code is currently duplicated between the updater and here
|
||||
// due to bootstrapping reasons. I'd like to not have it be that way.
|
||||
if (typeof major !== 'number' || typeof minor !== 'number' || typeof revision !== 'number') {
|
||||
throw new Error('You tried.');
|
||||
}
|
||||
|
||||
const hostVersionStr = `${major}.${minor}.${revision}`;
|
||||
const hostExePath = path.join(path.dirname(process.execPath), '..', `app-${hostVersionStr}`, path.basename(process.execPath));
|
||||
electron.app.once('will-quit', () => {
|
||||
childProcess.spawn(hostExePath, [], {
|
||||
detached: true,
|
||||
stdio: 'inherit'
|
||||
});
|
||||
});
|
||||
console.log(`Restarting from ${path.resolve(process.execPath)} to ${path.resolve(hostExePath)}`);
|
||||
electron.app.quit();
|
||||
});
|
|
@ -1,6 +1,4 @@
|
|||
'use strict';
|
||||
|
||||
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
|
||||
"use strict";
|
||||
|
||||
const electron = require('electron');
|
||||
|
||||
|
@ -12,19 +10,14 @@ const {
|
|||
POWER_MONITOR_GET_SYSTEM_IDLE_TIME
|
||||
} = require('../common/constants').IPCEvents;
|
||||
|
||||
electron.ipcMain.handle(POWER_MONITOR_GET_SYSTEM_IDLE_TIME, (() => {
|
||||
var _ref = _asyncToGenerator(function* (_) {
|
||||
electron.ipcMain.handle(POWER_MONITOR_GET_SYSTEM_IDLE_TIME, async _ => {
|
||||
return electron.powerMonitor.getSystemIdleTime() * 1000;
|
||||
});
|
||||
|
||||
return function (_x) {
|
||||
return _ref.apply(this, arguments);
|
||||
};
|
||||
})());
|
||||
});
|
||||
|
||||
function sendToAllWindows(channel) {
|
||||
electron.BrowserWindow.getAllWindows().forEach(win => {
|
||||
const contents = win.webContents;
|
||||
|
||||
if (contents != null) {
|
||||
contents.send(channel);
|
||||
}
|
||||
|
@ -34,15 +27,12 @@ function sendToAllWindows(channel) {
|
|||
electron.powerMonitor.on('resume', () => {
|
||||
sendToAllWindows(POWER_MONITOR_RESUME);
|
||||
});
|
||||
|
||||
electron.powerMonitor.on('suspend', () => {
|
||||
sendToAllWindows(POWER_MONITOR_SUSPEND);
|
||||
});
|
||||
|
||||
electron.powerMonitor.on('lock-screen', () => {
|
||||
sendToAllWindows(POWER_MONITOR_LOCK_SCREEN);
|
||||
});
|
||||
|
||||
electron.powerMonitor.on('unlock-screen', () => {
|
||||
sendToAllWindows(POWER_MONITOR_UNLOCK_SCREEN);
|
||||
});
|
|
@ -1,6 +1,4 @@
|
|||
'use strict';
|
||||
|
||||
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
|
||||
"use strict";
|
||||
|
||||
const electron = require('electron');
|
||||
|
||||
|
@ -11,40 +9,20 @@ const {
|
|||
} = require('../common/constants').IPCEvents;
|
||||
|
||||
const powerSaveBlockerIds = new Set();
|
||||
|
||||
electron.ipcMain.handle(POWER_SAVE_BLOCKER_BLOCK_DISPLAY_SLEEP, (() => {
|
||||
var _ref = _asyncToGenerator(function* (_) {
|
||||
electron.ipcMain.handle(POWER_SAVE_BLOCKER_BLOCK_DISPLAY_SLEEP, async _ => {
|
||||
const newId = electron.powerSaveBlocker.start('prevent-display-sleep');
|
||||
powerSaveBlockerIds.add(newId);
|
||||
return newId;
|
||||
});
|
||||
|
||||
return function (_x) {
|
||||
return _ref.apply(this, arguments);
|
||||
};
|
||||
})());
|
||||
|
||||
electron.ipcMain.handle(POWER_SAVE_BLOCKER_UNBLOCK_DISPLAY_SLEEP, (() => {
|
||||
var _ref2 = _asyncToGenerator(function* (_, id) {
|
||||
});
|
||||
electron.ipcMain.handle(POWER_SAVE_BLOCKER_UNBLOCK_DISPLAY_SLEEP, async (_, id) => {
|
||||
electron.powerSaveBlocker.stop(id);
|
||||
powerSaveBlockerIds.delete(id);
|
||||
});
|
||||
|
||||
return function (_x2, _x3) {
|
||||
return _ref2.apply(this, arguments);
|
||||
};
|
||||
})());
|
||||
|
||||
electron.ipcMain.handle(POWER_SAVE_BLOCKER_CLEANUP_DISPLAY_SLEEP, (() => {
|
||||
var _ref3 = _asyncToGenerator(function* (_) {
|
||||
});
|
||||
electron.ipcMain.handle(POWER_SAVE_BLOCKER_CLEANUP_DISPLAY_SLEEP, async _ => {
|
||||
// cleanup all previous sleeps
|
||||
for (const id of powerSaveBlockerIds) {
|
||||
electron.powerSaveBlocker.stop(id);
|
||||
}
|
||||
powerSaveBlockerIds.clear();
|
||||
});
|
||||
|
||||
return function (_x4) {
|
||||
return _ref3.apply(this, arguments);
|
||||
};
|
||||
})());
|
||||
powerSaveBlockerIds.clear();
|
||||
});
|
|
@ -1,8 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
|
||||
"use strict";
|
||||
|
||||
const electron = require('electron');
|
||||
|
||||
const process = require('process');
|
||||
|
||||
const {
|
||||
|
@ -14,62 +13,29 @@ const {
|
|||
PROCESS_UTILS_GET_MAIN_ARGV_SYNC
|
||||
} = require('../common/constants').IPCEvents;
|
||||
|
||||
electron.ipcMain.handle(PROCESS_UTILS_GET_CPU_USAGE, (() => {
|
||||
var _ref = _asyncToGenerator(function* (_) {
|
||||
electron.ipcMain.handle(PROCESS_UTILS_GET_CPU_USAGE, async _ => {
|
||||
let totalProcessorUsagePercent = 0.0;
|
||||
|
||||
for (const processMetric of electron.app.getAppMetrics()) {
|
||||
totalProcessorUsagePercent += processMetric.cpu.percentCPUUsage;
|
||||
}
|
||||
|
||||
return totalProcessorUsagePercent;
|
||||
});
|
||||
|
||||
return function (_x) {
|
||||
return _ref.apply(this, arguments);
|
||||
};
|
||||
})());
|
||||
|
||||
electron.ipcMain.handle(PROCESS_UTILS_GET_MEMORY_INFO, (() => {
|
||||
var _ref2 = _asyncToGenerator(function* (_) {
|
||||
});
|
||||
electron.ipcMain.handle(PROCESS_UTILS_GET_MEMORY_INFO, async _ => {
|
||||
return process.getProcessMemoryInfo();
|
||||
});
|
||||
|
||||
return function (_x2) {
|
||||
return _ref2.apply(this, arguments);
|
||||
};
|
||||
})());
|
||||
|
||||
electron.ipcMain.handle(PROCESS_UTILS_FLUSH_DNS_CACHE, (() => {
|
||||
var _ref3 = _asyncToGenerator(function* (_) {
|
||||
});
|
||||
electron.ipcMain.handle(PROCESS_UTILS_FLUSH_DNS_CACHE, async _ => {
|
||||
const defaultSession = electron.session.defaultSession;
|
||||
if (!defaultSession || !defaultSession.clearHostResolverCache) return;
|
||||
defaultSession.clearHostResolverCache();
|
||||
});
|
||||
|
||||
return function (_x3) {
|
||||
return _ref3.apply(this, arguments);
|
||||
};
|
||||
})());
|
||||
|
||||
electron.ipcMain.handle(PROCESS_UTILS_FLUSH_COOKIES, (() => {
|
||||
var _ref4 = _asyncToGenerator(function* (_) {
|
||||
});
|
||||
electron.ipcMain.handle(PROCESS_UTILS_FLUSH_COOKIES, async _ => {
|
||||
return electron.session.defaultSession.cookies.flushStore();
|
||||
});
|
||||
|
||||
return function (_x4) {
|
||||
return _ref4.apply(this, arguments);
|
||||
};
|
||||
})());
|
||||
|
||||
electron.ipcMain.handle(PROCESS_UTILS_FLUSH_STORAGE_DATA, (() => {
|
||||
var _ref5 = _asyncToGenerator(function* (_) {
|
||||
});
|
||||
electron.ipcMain.handle(PROCESS_UTILS_FLUSH_STORAGE_DATA, async _ => {
|
||||
electron.session.defaultSession.flushStorageData();
|
||||
});
|
||||
|
||||
return function (_x5) {
|
||||
return _ref5.apply(this, arguments);
|
||||
};
|
||||
})());
|
||||
|
||||
});
|
||||
electron.ipcMain.on(PROCESS_UTILS_GET_MAIN_ARGV_SYNC, event => {
|
||||
event.returnValue = process.argv;
|
||||
});
|
|
@ -1,12 +1,17 @@
|
|||
'use strict';
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.injectSettingsBackend = injectSettingsBackend;
|
||||
|
||||
const electron = require('electron');
|
||||
|
||||
const { SETTINGS_GET, SETTINGS_SET, SETTINGS_GET_SYNC } = require('../common/constants').IPCEvents;
|
||||
const {
|
||||
SETTINGS_GET,
|
||||
SETTINGS_SET,
|
||||
SETTINGS_GET_SYNC
|
||||
} = require('../common/constants').IPCEvents;
|
||||
|
||||
let injectedSettings = null;
|
||||
|
||||
|
@ -26,13 +31,11 @@ electron.ipcMain.handle(SETTINGS_GET, (_, name, defaultValue) => {
|
|||
const settings = getSettings();
|
||||
return settings.get(name, defaultValue);
|
||||
});
|
||||
|
||||
electron.ipcMain.handle(SETTINGS_SET, (_, name, value) => {
|
||||
const settings = getSettings();
|
||||
settings.set(name, value);
|
||||
settings.save();
|
||||
});
|
||||
|
||||
electron.ipcMain.on(SETTINGS_GET_SYNC, (event, name, defaultValue) => {
|
||||
const settings = getSettings();
|
||||
event.returnValue = settings.get(name, defaultValue);
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
'use strict';
|
||||
|
||||
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
|
||||
"use strict";
|
||||
|
||||
const electron = require('electron');
|
||||
|
||||
|
@ -12,64 +10,36 @@ const {
|
|||
} = require('../common/constants').IPCEvents;
|
||||
|
||||
let _learnedWords = new Set();
|
||||
|
||||
let _hasLoadedLearnedWords = false;
|
||||
|
||||
electron.ipcMain.handle(SPELLCHECK_REPLACE_MISSPELLING, (() => {
|
||||
var _ref = _asyncToGenerator(function* (event, correction) {
|
||||
electron.ipcMain.handle(SPELLCHECK_REPLACE_MISSPELLING, async (event, correction) => {
|
||||
event.sender.replaceMisspelling(correction);
|
||||
});
|
||||
|
||||
return function (_x, _x2) {
|
||||
return _ref.apply(this, arguments);
|
||||
};
|
||||
})());
|
||||
|
||||
electron.ipcMain.handle(SPELLCHECK_GET_AVAILABLE_DICTIONARIES, (() => {
|
||||
var _ref2 = _asyncToGenerator(function* (_) {
|
||||
});
|
||||
electron.ipcMain.handle(SPELLCHECK_GET_AVAILABLE_DICTIONARIES, async _ => {
|
||||
return electron.session.defaultSession.availableSpellCheckerLanguages;
|
||||
});
|
||||
|
||||
return function (_x3) {
|
||||
return _ref2.apply(this, arguments);
|
||||
};
|
||||
})());
|
||||
|
||||
electron.ipcMain.handle(SPELLCHECK_SET_LOCALE, (() => {
|
||||
var _ref3 = _asyncToGenerator(function* (_, locale) {
|
||||
});
|
||||
electron.ipcMain.handle(SPELLCHECK_SET_LOCALE, async (_, locale) => {
|
||||
electron.session.defaultSession.setSpellCheckerLanguages([locale]);
|
||||
});
|
||||
|
||||
return function (_x4, _x5) {
|
||||
return _ref3.apply(this, arguments);
|
||||
};
|
||||
})());
|
||||
|
||||
electron.ipcMain.handle(SPELLCHECK_SET_LEARNED_WORDS, (() => {
|
||||
var _ref4 = _asyncToGenerator(function* (_, newLearnedWords) {
|
||||
});
|
||||
electron.ipcMain.handle(SPELLCHECK_SET_LEARNED_WORDS, async (_, newLearnedWords) => {
|
||||
const session = electron.session.defaultSession;
|
||||
|
||||
if (!_hasLoadedLearnedWords) {
|
||||
const dictionaryContents = yield session.listWordsInSpellCheckerDictionary();
|
||||
const dictionaryContents = await session.listWordsInSpellCheckerDictionary();
|
||||
_learnedWords = new Set(dictionaryContents);
|
||||
_hasLoadedLearnedWords = true;
|
||||
}
|
||||
|
||||
_learnedWords.forEach(function (word) {
|
||||
_learnedWords.forEach(word => {
|
||||
if (!newLearnedWords.has(word)) {
|
||||
session.removeWordFromSpellCheckerDictionary(word);
|
||||
}
|
||||
});
|
||||
|
||||
newLearnedWords.forEach(function (word) {
|
||||
newLearnedWords.forEach(word => {
|
||||
if (!_learnedWords.has(word)) {
|
||||
session.addWordToSpellCheckerDictionary(word);
|
||||
}
|
||||
});
|
||||
|
||||
_learnedWords = new Set(newLearnedWords);
|
||||
});
|
||||
|
||||
return function (_x6, _x7) {
|
||||
return _ref4.apply(this, arguments);
|
||||
};
|
||||
})());
|
||||
});
|
|
@ -0,0 +1,76 @@
|
|||
"use strict";
|
||||
|
||||
var _electron = _interopRequireDefault(require("electron"));
|
||||
|
||||
var _fs = _interopRequireDefault(require("fs"));
|
||||
|
||||
var _path = _interopRequireDefault(require("path"));
|
||||
|
||||
var _appFeatures = require("../../appFeatures");
|
||||
|
||||
var paths = _interopRequireWildcard(require("../../paths"));
|
||||
|
||||
var _constants = require("../common/constants");
|
||||
|
||||
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
|
||||
|
||||
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
const {
|
||||
USER_DATA_CACHE_SAVE,
|
||||
USER_DATA_CACHE_GET,
|
||||
USER_DATA_CACHE_DELETE
|
||||
} = _constants.IPCEvents;
|
||||
const features = (0, _appFeatures.getFeatures)();
|
||||
|
||||
function getCachePath() {
|
||||
return _path.default.join(paths.getUserData(), 'userDataCache.json');
|
||||
}
|
||||
|
||||
function getMigratedPath() {
|
||||
return _path.default.join(paths.getUserData(), 'domainMigrated');
|
||||
}
|
||||
|
||||
function cacheUserData(userData) {
|
||||
_fs.default.writeFile(getCachePath(), userData, e => {
|
||||
if (e) {
|
||||
console.warn('Failed updating user data cache with error: ', e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getCachedUserData() {
|
||||
try {
|
||||
return JSON.parse(_fs.default.readFileSync(getCachePath()));
|
||||
} catch (_err) {}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function deleteCachedUserData() {
|
||||
try {
|
||||
_fs.default.unlinkSync(getCachePath());
|
||||
|
||||
_fs.default.writeFile(getMigratedPath(), '', e => {
|
||||
if (e) {
|
||||
console.warn('Failed to create domainMigrated file with error: ', e);
|
||||
}
|
||||
});
|
||||
} catch (_err) {}
|
||||
}
|
||||
|
||||
_electron.default.ipcMain.handle(USER_DATA_CACHE_GET, () => {
|
||||
return getCachedUserData();
|
||||
});
|
||||
|
||||
_electron.default.ipcMain.on(USER_DATA_CACHE_SAVE, (_event, userData) => {
|
||||
cacheUserData(userData);
|
||||
});
|
||||
|
||||
_electron.default.ipcMain.on(USER_DATA_CACHE_DELETE, _event => {
|
||||
deleteCachedUserData();
|
||||
});
|
||||
|
||||
features.declareSupported('user_data_cache');
|
|
@ -1,13 +1,12 @@
|
|||
'use strict';
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.injectGetWindow = injectGetWindow;
|
||||
|
||||
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
|
||||
|
||||
const electron = require('electron');
|
||||
|
||||
const process = require('process');
|
||||
|
||||
const {
|
||||
|
@ -33,132 +32,63 @@ function injectGetWindow(getWindow) {
|
|||
injectedGetWindow = getWindow;
|
||||
}
|
||||
|
||||
electron.ipcMain.handle(WINDOW_FLASH_FRAME, (() => {
|
||||
var _ref = _asyncToGenerator(function* (_, flag) {
|
||||
electron.ipcMain.handle(WINDOW_FLASH_FRAME, async (_, flag) => {
|
||||
const currentWindow = injectedGetWindow();
|
||||
if (currentWindow == null || currentWindow.flashFrame == null) return;
|
||||
currentWindow.flashFrame(!currentWindow.isFocused() && flag);
|
||||
});
|
||||
|
||||
return function (_x, _x2) {
|
||||
return _ref.apply(this, arguments);
|
||||
};
|
||||
})());
|
||||
|
||||
electron.ipcMain.handle(WINDOW_MINIMIZE, (() => {
|
||||
var _ref2 = _asyncToGenerator(function* (_, key) {
|
||||
});
|
||||
electron.ipcMain.handle(WINDOW_MINIMIZE, async (_, key) => {
|
||||
const win = injectedGetWindow(key);
|
||||
if (win == null) return;
|
||||
win.minimize();
|
||||
});
|
||||
|
||||
return function (_x3, _x4) {
|
||||
return _ref2.apply(this, arguments);
|
||||
};
|
||||
})());
|
||||
|
||||
electron.ipcMain.handle(WINDOW_RESTORE, (() => {
|
||||
var _ref3 = _asyncToGenerator(function* (_, key) {
|
||||
});
|
||||
electron.ipcMain.handle(WINDOW_RESTORE, async (_, key) => {
|
||||
const win = injectedGetWindow(key);
|
||||
if (win == null) return;
|
||||
win.restore();
|
||||
});
|
||||
|
||||
return function (_x5, _x6) {
|
||||
return _ref3.apply(this, arguments);
|
||||
};
|
||||
})());
|
||||
|
||||
electron.ipcMain.handle(WINDOW_MAXIMIZE, (() => {
|
||||
var _ref4 = _asyncToGenerator(function* (_, key) {
|
||||
});
|
||||
electron.ipcMain.handle(WINDOW_MAXIMIZE, async (_, key) => {
|
||||
const win = injectedGetWindow(key);
|
||||
if (win == null) return;
|
||||
|
||||
if (win.isMaximized()) {
|
||||
win.unmaximize();
|
||||
} else {
|
||||
win.maximize();
|
||||
}
|
||||
});
|
||||
|
||||
return function (_x7, _x8) {
|
||||
return _ref4.apply(this, arguments);
|
||||
};
|
||||
})());
|
||||
|
||||
electron.ipcMain.handle(WINDOW_FOCUS, (() => {
|
||||
var _ref5 = _asyncToGenerator(function* (_, key) {
|
||||
});
|
||||
electron.ipcMain.handle(WINDOW_FOCUS, async (_, key) => {
|
||||
const win = injectedGetWindow(key);
|
||||
if (win == null) return;
|
||||
win.show();
|
||||
});
|
||||
|
||||
return function (_x9, _x10) {
|
||||
return _ref5.apply(this, arguments);
|
||||
};
|
||||
})());
|
||||
|
||||
electron.ipcMain.handle(WINDOW_SET_ALWAYS_ON_TOP, (() => {
|
||||
var _ref6 = _asyncToGenerator(function* (_, key, enabled) {
|
||||
});
|
||||
electron.ipcMain.handle(WINDOW_SET_ALWAYS_ON_TOP, async (_, key, enabled) => {
|
||||
const win = injectedGetWindow(key);
|
||||
if (win == null) return;
|
||||
win.setAlwaysOnTop(enabled);
|
||||
});
|
||||
|
||||
return function (_x11, _x12, _x13) {
|
||||
return _ref6.apply(this, arguments);
|
||||
};
|
||||
})());
|
||||
|
||||
electron.ipcMain.handle(WINDOW_IS_ALWAYS_ON_TOP, (() => {
|
||||
var _ref7 = _asyncToGenerator(function* (_, key) {
|
||||
});
|
||||
electron.ipcMain.handle(WINDOW_IS_ALWAYS_ON_TOP, async (_, key) => {
|
||||
const win = injectedGetWindow(key);
|
||||
if (win == null) return false;
|
||||
return win.isAlwaysOnTop();
|
||||
});
|
||||
|
||||
return function (_x14, _x15) {
|
||||
return _ref7.apply(this, arguments);
|
||||
};
|
||||
})());
|
||||
|
||||
electron.ipcMain.handle(WINDOW_BLUR, (() => {
|
||||
var _ref8 = _asyncToGenerator(function* (_, key) {
|
||||
});
|
||||
electron.ipcMain.handle(WINDOW_BLUR, async (_, key) => {
|
||||
const win = injectedGetWindow(key);
|
||||
|
||||
if (win != null && !win.isDestroyed()) {
|
||||
win.blur();
|
||||
}
|
||||
});
|
||||
|
||||
return function (_x16, _x17) {
|
||||
return _ref8.apply(this, arguments);
|
||||
};
|
||||
})());
|
||||
|
||||
electron.ipcMain.handle(WINDOW_SET_PROGRESS_BAR, (() => {
|
||||
var _ref9 = _asyncToGenerator(function* (_, key, progress) {
|
||||
});
|
||||
electron.ipcMain.handle(WINDOW_SET_PROGRESS_BAR, async (_, key, progress) => {
|
||||
const win = injectedGetWindow(key);
|
||||
if (win == null) return;
|
||||
win.setProgressBar(progress);
|
||||
});
|
||||
|
||||
return function (_x18, _x19, _x20) {
|
||||
return _ref9.apply(this, arguments);
|
||||
};
|
||||
})());
|
||||
|
||||
electron.ipcMain.handle(WINDOW_TOGGLE_FULLSCREEN, (() => {
|
||||
var _ref10 = _asyncToGenerator(function* (_, key) {
|
||||
});
|
||||
electron.ipcMain.handle(WINDOW_TOGGLE_FULLSCREEN, async (_, key) => {
|
||||
const currentWindow = injectedGetWindow(key);
|
||||
currentWindow.setFullScreen(!currentWindow.isFullScreen());
|
||||
});
|
||||
|
||||
return function (_x21, _x22) {
|
||||
return _ref10.apply(this, arguments);
|
||||
};
|
||||
})());
|
||||
|
||||
electron.ipcMain.handle(WINDOW_CLOSE, (() => {
|
||||
var _ref11 = _asyncToGenerator(function* (_, key) {
|
||||
});
|
||||
electron.ipcMain.handle(WINDOW_CLOSE, async (_, key) => {
|
||||
if (key == null && process.platform === 'darwin') {
|
||||
electron.Menu.sendActionToFirstResponder('hide:');
|
||||
} else {
|
||||
|
@ -166,21 +96,9 @@ electron.ipcMain.handle(WINDOW_CLOSE, (() => {
|
|||
if (win == null) return;
|
||||
win.close();
|
||||
}
|
||||
});
|
||||
|
||||
return function (_x23, _x24) {
|
||||
return _ref11.apply(this, arguments);
|
||||
};
|
||||
})());
|
||||
|
||||
electron.ipcMain.handle(WINDOW_SET_BACKGROUND_THROTTLING, (() => {
|
||||
var _ref12 = _asyncToGenerator(function* (_, enabled) {
|
||||
});
|
||||
electron.ipcMain.handle(WINDOW_SET_BACKGROUND_THROTTLING, async (_, enabled) => {
|
||||
const win = injectedGetWindow();
|
||||
if (win == null) return;
|
||||
win.webContents.setBackgroundThrottling(enabled);
|
||||
});
|
||||
|
||||
return function (_x25, _x26) {
|
||||
return _ref12.apply(this, arguments);
|
||||
};
|
||||
})());
|
||||
});
|
|
@ -4,6 +4,8 @@ Object.defineProperty(exports, "__esModule", {
|
|||
value: true
|
||||
});
|
||||
exports.getDiscordIPCEvent = getDiscordIPCEvent;
|
||||
exports.IPCEvents = void 0;
|
||||
|
||||
function sanitizeIPCEvents(events) {
|
||||
for (const key of Object.keys(events)) {
|
||||
events[key] = getDiscordIPCEvent(key);
|
||||
|
@ -16,9 +18,9 @@ function getDiscordIPCEvent(ev) {
|
|||
return `DISCORD_${ev}`;
|
||||
}
|
||||
|
||||
const IPCEvents = exports.IPCEvents = sanitizeIPCEvents({
|
||||
const IPCEvents = sanitizeIPCEvents({
|
||||
ACCESSIBILITY_GET_ENABLED: null,
|
||||
|
||||
APP_BADGE_SET: null,
|
||||
APP_GET_RELEASE_CHANNEL_SYNC: null,
|
||||
APP_GET_HOST_VERSION_SYNC: null,
|
||||
APP_GET_MODULE_VERSIONS: null,
|
||||
|
@ -29,26 +31,28 @@ const IPCEvents = exports.IPCEvents = sanitizeIPCEvents({
|
|||
APP_DOCK_CANCEL_BOUNCE: null,
|
||||
APP_RELAUNCH: null,
|
||||
APP_GET_DEFAULT_DOUBLE_CLICK_ACTION: null,
|
||||
|
||||
CLIPBOARD_COPY: null,
|
||||
CLIPBOARD_CUT: null,
|
||||
CLIPBOARD_PASTE: null,
|
||||
|
||||
CHECK_FOR_UPDATES: null,
|
||||
CONSTANTS_GET: null,
|
||||
CRASH_REPORTER_UPDATE_METADATA: null,
|
||||
|
||||
FEATURES_GET_BROWSER_FEATURES: null,
|
||||
|
||||
FILE_MANAGER_GET_MODULE_PATH: null,
|
||||
FILE_MANAGER_GET_MODULE_DATA_PATH_SYNC: null,
|
||||
FILE_MANAGER_SHOW_SAVE_DIALOG: null,
|
||||
FILE_MANAGER_SHOW_OPEN_DIALOG: null,
|
||||
FILE_MANAGER_SHOW_ITEM_IN_FOLDER: null,
|
||||
|
||||
GPU_SETTINGS_SET_ENABLE_HWACCEL: null,
|
||||
GPU_SETTINGS_GET_ENABLE_HWACCEL_SYNC: null,
|
||||
|
||||
NATIVE_MODULES_GET_PATHS: null,
|
||||
NATIVE_MODULES_INSTALL: null,
|
||||
|
||||
NATIVE_MODULES_FINISH_UPDATER_BOOTSTRAP: null,
|
||||
NATIVE_MODULES_GET_HAS_NEW_UPDATER: null,
|
||||
NOTIFICATION_CLOSE: null,
|
||||
NOTIFICATION_SHOW: null,
|
||||
NOTIFICATIONS_CLEAR: null,
|
||||
OPEN_EXTERNAL_URL: null,
|
||||
POWER_MONITOR_RESUME: null,
|
||||
POWER_MONITOR_SUSPEND: null,
|
||||
POWER_MONITOR_LOCK_SCREEN: null,
|
||||
|
@ -57,24 +61,33 @@ const IPCEvents = exports.IPCEvents = sanitizeIPCEvents({
|
|||
POWER_SAVE_BLOCKER_BLOCK_DISPLAY_SLEEP: null,
|
||||
POWER_SAVE_BLOCKER_UNBLOCK_DISPLAY_SLEEP: null,
|
||||
POWER_SAVE_BLOCKER_CLEANUP_DISPLAY_SLEEP: null,
|
||||
|
||||
PROCESS_UTILS_GET_CPU_USAGE: null,
|
||||
PROCESS_UTILS_GET_MEMORY_INFO: null,
|
||||
PROCESS_UTILS_FLUSH_DNS_CACHE: null,
|
||||
PROCESS_UTILS_FLUSH_COOKIES: null,
|
||||
PROCESS_UTILS_FLUSH_STORAGE_DATA: null,
|
||||
PROCESS_UTILS_GET_MAIN_ARGV_SYNC: null,
|
||||
|
||||
QUIT_AND_INSTALL: null,
|
||||
SETTINGS_GET: null,
|
||||
SETTINGS_SET: null,
|
||||
SETTINGS_GET_SYNC: null,
|
||||
|
||||
SETTINGS_UPDATE_BACKGROUND_COLOR: null,
|
||||
SPELLCHECK_RESULT: null,
|
||||
SPELLCHECK_REPLACE_MISSPELLING: null,
|
||||
SPELLCHECK_GET_AVAILABLE_DICTIONARIES: null,
|
||||
SPELLCHECK_SET_LOCALE: null,
|
||||
SPELLCHECK_SET_LEARNED_WORDS: null,
|
||||
|
||||
SYSTEM_TRAY_SET_ICON: null,
|
||||
SYSTEM_TRAY_SET_APPLICATIONS: null,
|
||||
TOGGLE_MINIMIZE_TO_TRAY: null,
|
||||
TOGGLE_OPEN_ON_STARTUP: null,
|
||||
TOGGLE_START_MINIMIZED: null,
|
||||
UPDATE_OPEN_ON_STARTUP: null,
|
||||
UPDATER_HISTORY_QUERY_AND_TRUNCATE: null,
|
||||
UPDATED_QUOTES: null,
|
||||
USER_DATA_CACHE_DELETE: null,
|
||||
USER_DATA_CACHE_GET: null,
|
||||
USER_DATA_CACHE_SAVE: null,
|
||||
WINDOW_BLUR: null,
|
||||
WINDOW_CLOSE: null,
|
||||
WINDOW_FOCUS: null,
|
||||
|
@ -90,3 +103,4 @@ const IPCEvents = exports.IPCEvents = sanitizeIPCEvents({
|
|||
WINDOW_DEVTOOLS_OPENED: null,
|
||||
WINDOW_DEVTOOLS_CLOSED: null
|
||||
});
|
||||
exports.IPCEvents = IPCEvents;
|
|
@ -1,20 +1,14 @@
|
|||
'use strict';
|
||||
|
||||
let isAccessibilitySupportEnabled = (() => {
|
||||
var _ref = _asyncToGenerator(function* () {
|
||||
return electron.ipcRenderer.invoke(ACCESSIBILITY_GET_ENABLED);
|
||||
});
|
||||
|
||||
return function isAccessibilitySupportEnabled() {
|
||||
return _ref.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
|
||||
"use strict";
|
||||
|
||||
const electron = require('electron');
|
||||
|
||||
const { ACCESSIBILITY_GET_ENABLED } = require('../common/constants').IPCEvents;
|
||||
const {
|
||||
ACCESSIBILITY_GET_ENABLED
|
||||
} = require('../common/constants').IPCEvents;
|
||||
|
||||
async function isAccessibilitySupportEnabled() {
|
||||
return electron.ipcRenderer.invoke(ACCESSIBILITY_GET_ENABLED);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
isAccessibilitySupportEnabled
|
||||
|
|
|
@ -1,85 +1,9 @@
|
|||
'use strict';
|
||||
|
||||
let getPath = (() => {
|
||||
var _ref2 = _asyncToGenerator(function* (path) {
|
||||
if (!allowedAppPaths.has(path)) {
|
||||
throw new Error(`${path} is not an allowed app path`);
|
||||
}
|
||||
|
||||
return electron.ipcRenderer.invoke(APP_GET_PATH, path);
|
||||
});
|
||||
|
||||
return function getPath(_x2) {
|
||||
return _ref2.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
let setBadgeCount = (() => {
|
||||
var _ref3 = _asyncToGenerator(function* (count) {
|
||||
electron.ipcRenderer.invoke(APP_SET_BADGE_COUNT, count);
|
||||
});
|
||||
|
||||
return function setBadgeCount(_x3) {
|
||||
return _ref3.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
let dockSetBadge = (() => {
|
||||
var _ref4 = _asyncToGenerator(function* (badge) {
|
||||
electron.ipcRenderer.invoke(APP_DOCK_SET_BADGE, badge);
|
||||
});
|
||||
|
||||
return function dockSetBadge(_x4) {
|
||||
return _ref4.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
let dockBounce = (() => {
|
||||
var _ref5 = _asyncToGenerator(function* (type) {
|
||||
return electron.ipcRenderer.invoke(APP_DOCK_BOUNCE, type);
|
||||
});
|
||||
|
||||
return function dockBounce(_x5) {
|
||||
return _ref5.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
let dockCancelBounce = (() => {
|
||||
var _ref6 = _asyncToGenerator(function* (id) {
|
||||
electron.ipcRenderer.invoke(APP_DOCK_CANCEL_BOUNCE, id);
|
||||
});
|
||||
|
||||
return function dockCancelBounce(_x6) {
|
||||
return _ref6.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
let relaunch = (() => {
|
||||
var _ref7 = _asyncToGenerator(function* () {
|
||||
electron.ipcRenderer.invoke(APP_RELAUNCH);
|
||||
});
|
||||
|
||||
return function relaunch() {
|
||||
return _ref7.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
let getDefaultDoubleClickAction = (() => {
|
||||
var _ref8 = _asyncToGenerator(function* () {
|
||||
return electron.ipcRenderer.invoke(APP_GET_DEFAULT_DOUBLE_CLICK_ACTION);
|
||||
});
|
||||
|
||||
return function getDefaultDoubleClickAction() {
|
||||
return _ref8.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
|
||||
"use strict";
|
||||
|
||||
const electron = require('electron');
|
||||
const { UpdaterEvents } = require('../../Constants');
|
||||
|
||||
const allowedAppPaths = new Set(['home', 'appData', 'desktop', 'documents', 'downloads']);
|
||||
const allowedAppPaths = new Set(['home', 'appData', 'desktop', 'documents', 'downloads', 'crashDumps']);
|
||||
|
||||
const {
|
||||
APP_GET_RELEASE_CHANNEL_SYNC,
|
||||
APP_GET_HOST_VERSION_SYNC,
|
||||
|
@ -96,20 +20,12 @@ const {
|
|||
let releaseChannel = electron.ipcRenderer.sendSync(APP_GET_RELEASE_CHANNEL_SYNC);
|
||||
let hostVersion = electron.ipcRenderer.sendSync(APP_GET_HOST_VERSION_SYNC);
|
||||
let moduleVersions = {};
|
||||
|
||||
electron.ipcRenderer.invoke(APP_GET_MODULE_VERSIONS).then(versions => {
|
||||
moduleVersions = versions;
|
||||
});
|
||||
|
||||
electron.ipcRenderer.on('DISCORD_MODULE_INSTALLED', (() => {
|
||||
var _ref = _asyncToGenerator(function* (_) {
|
||||
moduleVersions = yield electron.ipcRenderer.invoke(APP_GET_MODULE_VERSIONS);
|
||||
});
|
||||
|
||||
return function (_x) {
|
||||
return _ref.apply(this, arguments);
|
||||
};
|
||||
})());
|
||||
electron.ipcRenderer.on('DISCORD_MODULE_INSTALLED', async _ => {
|
||||
moduleVersions = await electron.ipcRenderer.invoke(APP_GET_MODULE_VERSIONS);
|
||||
});
|
||||
|
||||
function getReleaseChannel() {
|
||||
return releaseChannel;
|
||||
|
@ -123,6 +39,59 @@ function getModuleVersions() {
|
|||
return moduleVersions;
|
||||
}
|
||||
|
||||
async function getPath(path) {
|
||||
if (!allowedAppPaths.has(path)) {
|
||||
throw new Error(`${path} is not an allowed app path`);
|
||||
}
|
||||
|
||||
return electron.ipcRenderer.invoke(APP_GET_PATH, path);
|
||||
}
|
||||
|
||||
async function setBadgeCount(count) {
|
||||
electron.ipcRenderer.invoke(APP_SET_BADGE_COUNT, count);
|
||||
}
|
||||
|
||||
async function dockSetBadge(badge) {
|
||||
electron.ipcRenderer.invoke(APP_DOCK_SET_BADGE, badge);
|
||||
}
|
||||
|
||||
async function dockBounce(type) {
|
||||
return electron.ipcRenderer.invoke(APP_DOCK_BOUNCE, type);
|
||||
}
|
||||
|
||||
async function dockCancelBounce(id) {
|
||||
electron.ipcRenderer.invoke(APP_DOCK_CANCEL_BOUNCE, id);
|
||||
}
|
||||
|
||||
async function relaunch() {
|
||||
electron.ipcRenderer.invoke(APP_RELAUNCH);
|
||||
}
|
||||
|
||||
async function getDefaultDoubleClickAction() {
|
||||
return electron.ipcRenderer.invoke(APP_GET_DEFAULT_DOUBLE_CLICK_ACTION);
|
||||
}
|
||||
|
||||
function registerUserInteractionHandler(elementId, eventType, callback) {
|
||||
const element = document.getElementById(elementId);
|
||||
|
||||
if (element == null) {
|
||||
throw new Error(`Element with id '${elementId}' was not found`);
|
||||
}
|
||||
|
||||
function handleUserInteraction(ev) {
|
||||
if (!ev.isTrusted) {
|
||||
return;
|
||||
}
|
||||
|
||||
callback(ev);
|
||||
}
|
||||
|
||||
element.addEventListener(eventType, handleUserInteraction);
|
||||
return () => {
|
||||
element.removeEventListener(eventType, handleUserInteraction);
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getReleaseChannel,
|
||||
getVersion,
|
||||
|
@ -135,5 +104,6 @@ module.exports = {
|
|||
cancelBounce: dockCancelBounce
|
||||
},
|
||||
relaunch,
|
||||
getDefaultDoubleClickAction
|
||||
getDefaultDoubleClickAction,
|
||||
registerUserInteractionHandler
|
||||
};
|
|
@ -1,9 +1,14 @@
|
|||
'use strict';
|
||||
"use strict";
|
||||
|
||||
const electron = require('electron');
|
||||
|
||||
const invariant = require('invariant');
|
||||
|
||||
const { CLIPBOARD_COPY, CLIPBOARD_CUT, CLIPBOARD_PASTE } = require('../common/constants').IPCEvents;
|
||||
const {
|
||||
CLIPBOARD_COPY,
|
||||
CLIPBOARD_CUT,
|
||||
CLIPBOARD_PASTE
|
||||
} = require('../common/constants').IPCEvents;
|
||||
|
||||
function copy(text) {
|
||||
if (text) {
|
||||
|
@ -15,9 +20,11 @@ function copy(text) {
|
|||
|
||||
function copyImage(imageArrayBuffer, imageSrc) {
|
||||
invariant(imageArrayBuffer != null, 'Image data is empty');
|
||||
|
||||
const nativeImg = electron.nativeImage.createFromBuffer(imageArrayBuffer);
|
||||
electron.clipboard.write({ html: `<img src="${imageSrc}">`, image: nativeImg });
|
||||
electron.clipboard.write({
|
||||
html: `<img src="${imageSrc}">`,
|
||||
image: nativeImg
|
||||
});
|
||||
}
|
||||
|
||||
function cut() {
|
||||
|
|
|
@ -1,33 +1,33 @@
|
|||
'use strict';
|
||||
|
||||
let updateCrashReporter = (() => {
|
||||
var _ref = _asyncToGenerator(function* (additional_metadata) {
|
||||
const result = yield electron.ipcRenderer.invoke(CRASH_REPORTER_UPDATE_METADATA, additional_metadata);
|
||||
// Calling crashReporter.start from a renderer process was deprecated in Electron 9.
|
||||
if (getElectronMajorVersion() < 9) {
|
||||
//electron.crashReporter.start(result.args);
|
||||
}
|
||||
metadata = result.metadata || {};
|
||||
|
||||
reconcileCrashReporterMetadata(electron.crashReporter, metadata);
|
||||
});
|
||||
|
||||
return function updateCrashReporter(_x) {
|
||||
return _ref.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
|
||||
"use strict";
|
||||
|
||||
const electron = require('electron');
|
||||
const { getElectronMajorVersion, reconcileCrashReporterMetadata } = require('../common/utility');
|
||||
|
||||
const { CRASH_REPORTER_UPDATE_METADATA } = require('../common/constants').IPCEvents;
|
||||
const {
|
||||
reconcileCrashReporterMetadata
|
||||
} = require('../../../common/crashReporterUtils');
|
||||
|
||||
const {
|
||||
getElectronMajorVersion
|
||||
} = require('../../../common/processUtils');
|
||||
|
||||
const {
|
||||
CRASH_REPORTER_UPDATE_METADATA
|
||||
} = require('../common/constants').IPCEvents;
|
||||
|
||||
let metadata = {};
|
||||
|
||||
updateCrashReporter(metadata);
|
||||
|
||||
async function updateCrashReporter(additional_metadata) {
|
||||
const result = await electron.ipcRenderer.invoke(CRASH_REPORTER_UPDATE_METADATA, additional_metadata); // Calling crashReporter.start from a renderer process was deprecated in Electron 9.
|
||||
|
||||
if (getElectronMajorVersion() < 9) {
|
||||
electron.crashReporter.start(result.args);
|
||||
}
|
||||
|
||||
metadata = result.metadata || {};
|
||||
reconcileCrashReporterMetadata(electron.crashReporter, metadata);
|
||||
}
|
||||
|
||||
function getMetadata() {
|
||||
return metadata;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
'use strict';
|
||||
"use strict";
|
||||
|
||||
const electron = require('electron');
|
||||
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
'use strict';
|
||||
"use strict";
|
||||
|
||||
const electron = require('electron');
|
||||
|
||||
const { FEATURES_GET_BROWSER_FEATURES } = require('../common/constants').IPCEvents;
|
||||
const {
|
||||
FEATURES_GET_BROWSER_FEATURES
|
||||
} = require('../common/constants').IPCEvents;
|
||||
|
||||
let supportedFeatures = new Set(electron.ipcRenderer.sendSync(FEATURES_GET_BROWSER_FEATURES));
|
||||
|
||||
|
|
|
@ -1,192 +1,167 @@
|
|||
'use strict';
|
||||
|
||||
let saveWithDialog = (() => {
|
||||
var _ref = _asyncToGenerator(function* (fileContents, fileName, filePath) {
|
||||
if (INVALID_FILENAME_CHAR_REGEX.test(fileName)) {
|
||||
throw new Error(`fileName has invalid characters`);
|
||||
}
|
||||
const defaultPath = filePath != null ? path.join(os.homedir(), filePath, fileName) : path.join(os.homedir(), fileName);
|
||||
|
||||
const writeFileToDisk = function (selectedFileName) {
|
||||
selectedFileName && fs.writeFileSync(selectedFileName, fileContents);
|
||||
};
|
||||
|
||||
const results = yield electron.ipcRenderer.invoke(FILE_MANAGER_SHOW_SAVE_DIALOG, { defaultPath });
|
||||
if (results && results.filePath) {
|
||||
fs.writeFileSync(results.filePath, fileContents);
|
||||
}
|
||||
});
|
||||
|
||||
return function saveWithDialog(_x, _x2, _x3) {
|
||||
return _ref.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
let showOpenDialog = (() => {
|
||||
var _ref2 = _asyncToGenerator(function* (dialogOptions) {
|
||||
const results = yield electron.ipcRenderer.invoke(FILE_MANAGER_SHOW_OPEN_DIALOG, dialogOptions);
|
||||
return results.filePaths;
|
||||
});
|
||||
|
||||
return function showOpenDialog(_x4) {
|
||||
return _ref2.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
let orderedFiles = (() => {
|
||||
var _ref3 = _asyncToGenerator(function* (folder) {
|
||||
try {
|
||||
const filenames = yield readdir(folder);
|
||||
const times = yield getTimes(filenames.map(function (filename) {
|
||||
return path.join(folder, filename);
|
||||
}));
|
||||
return times.filter(function (result) {
|
||||
return result.status === 'fulfilled';
|
||||
}).map(function (result) {
|
||||
return result.value;
|
||||
}).sort(function (a, b) {
|
||||
return b.mtime.getTime() - a.mtime.getTime();
|
||||
}).map(function (a) {
|
||||
return a.filename;
|
||||
});
|
||||
} catch (err) {
|
||||
return [];
|
||||
}
|
||||
});
|
||||
|
||||
return function orderedFiles(_x5) {
|
||||
return _ref3.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
let readLogFiles = (() => {
|
||||
var _ref4 = _asyncToGenerator(function* (maxSize, makeFile) {
|
||||
const modulePath = yield getModulePath();
|
||||
const webrtcLog0 = path.join(modulePath, 'discord_voice', 'discord-webrtc_0');
|
||||
const webrtcLog1 = path.join(modulePath, 'discord_voice', 'discord-webrtc_1');
|
||||
const webrtcLog2 = path.join(modulePath, 'discord_voice', 'discord-last-webrtc_0');
|
||||
const webrtcLog3 = path.join(modulePath, 'discord_voice', 'discord-last-webrtc_1');
|
||||
const hookLog = path.join(modulePath, 'discord_hook', 'hook.log');
|
||||
const audioState = path.join(modulePath, 'discord_voice', 'audio_state.json');
|
||||
const filesToUpload = [webrtcLog0, webrtcLog1, webrtcLog2, webrtcLog3, hookLog, audioState];
|
||||
|
||||
const crashFolder = process.platform === 'win32' ? path.join(os.tmpdir(), 'Discord Crashes', 'reports') : path.join(os.tmpdir(), 'Discord Crashes', 'completed');
|
||||
const crashFiles = yield orderedFiles(crashFolder);
|
||||
if (crashFiles.length > 0) {
|
||||
filesToUpload.push(crashFiles[0]);
|
||||
}
|
||||
|
||||
const files = yield readFiles(filesToUpload, maxSize, function (data, filename) {
|
||||
return makeFile(data, filename, 'application/octet-stream');
|
||||
});
|
||||
return files.filter(function (result) {
|
||||
return result.status === 'fulfilled';
|
||||
}).map(function (result) {
|
||||
return result.value;
|
||||
});
|
||||
});
|
||||
|
||||
return function readLogFiles(_x6, _x7) {
|
||||
return _ref4.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
let showItemInFolder = (() => {
|
||||
var _ref5 = _asyncToGenerator(function* (path) {
|
||||
electron.ipcRenderer.invoke(FILE_MANAGER_SHOW_ITEM_IN_FOLDER, path);
|
||||
});
|
||||
|
||||
return function showItemInFolder(_x8) {
|
||||
return _ref5.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
let openFiles = (() => {
|
||||
var _ref6 = _asyncToGenerator(function* (dialogOptions, maxSize, makeFile) {
|
||||
const filenames = yield showOpenDialog(dialogOptions);
|
||||
if (filenames == null) {
|
||||
return;
|
||||
}
|
||||
const files = yield readFiles(filenames, maxSize, makeFile);
|
||||
files.forEach(function (result) {
|
||||
if (result.status === 'rejected') {
|
||||
throw result.reason;
|
||||
}
|
||||
});
|
||||
return files.map(function (result) {
|
||||
return result.value;
|
||||
});
|
||||
});
|
||||
|
||||
return function openFiles(_x9, _x10, _x11) {
|
||||
return _ref6.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
let getModulePath = (() => {
|
||||
var _ref7 = _asyncToGenerator(function* () {
|
||||
return electron.ipcRenderer.invoke(FILE_MANAGER_GET_MODULE_PATH);
|
||||
});
|
||||
|
||||
return function getModulePath() {
|
||||
return _ref7.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
|
||||
"use strict";
|
||||
|
||||
const electron = require('electron');
|
||||
|
||||
const fs = require('fs');
|
||||
|
||||
const os = require('os');
|
||||
|
||||
const path = require('path');
|
||||
|
||||
const originalFs = require('original-fs');
|
||||
|
||||
const util = require('util');
|
||||
|
||||
const {
|
||||
getPath
|
||||
} = require('./app');
|
||||
|
||||
const {
|
||||
getElectronMajorVersion
|
||||
} = require('../../../common/processUtils');
|
||||
|
||||
const {
|
||||
FILE_MANAGER_GET_MODULE_PATH,
|
||||
FILE_MANAGER_GET_MODULE_DATA_PATH_SYNC,
|
||||
FILE_MANAGER_SHOW_SAVE_DIALOG,
|
||||
FILE_MANAGER_SHOW_OPEN_DIALOG,
|
||||
FILE_MANAGER_SHOW_ITEM_IN_FOLDER
|
||||
} = require('../common/constants').IPCEvents;
|
||||
|
||||
const INVALID_FILENAME_CHAR_REGEX = /[^a-zA-Z0-9-_.]/g;
|
||||
|
||||
const readdir = util.promisify(originalFs.readdir);
|
||||
|
||||
async function saveWithDialog(fileContents, fileName) {
|
||||
if (INVALID_FILENAME_CHAR_REGEX.test(fileName)) {
|
||||
throw new Error('fileName has invalid characters');
|
||||
}
|
||||
|
||||
const defaultPath = path.join((await getPath('downloads')), fileName);
|
||||
const results = await electron.ipcRenderer.invoke(FILE_MANAGER_SHOW_SAVE_DIALOG, {
|
||||
defaultPath
|
||||
});
|
||||
|
||||
if (results && results.filePath) {
|
||||
fs.writeFileSync(results.filePath, fileContents);
|
||||
}
|
||||
}
|
||||
|
||||
async function showOpenDialog({
|
||||
filters,
|
||||
properties
|
||||
}) {
|
||||
const results = await electron.ipcRenderer.invoke(FILE_MANAGER_SHOW_OPEN_DIALOG, {
|
||||
filters,
|
||||
properties
|
||||
});
|
||||
return results.filePaths;
|
||||
}
|
||||
|
||||
function getTimes(filenames) {
|
||||
return Promise.allSettled(filenames.map(filename => new Promise((resolve, reject) => {
|
||||
originalFs.stat(filename, (err, stats) => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
|
||||
if (!stats.isFile()) {
|
||||
return reject(new Error('Not a file'));
|
||||
}
|
||||
return resolve({ filename, mtime: stats.mtime });
|
||||
|
||||
return resolve({
|
||||
filename,
|
||||
mtime: stats.mtime
|
||||
});
|
||||
});
|
||||
})));
|
||||
}
|
||||
|
||||
function readFiles(filenames, maxSize, makeFile) {
|
||||
async function orderedFiles(folder) {
|
||||
try {
|
||||
const filenames = await readdir(folder);
|
||||
const times = await getTimes(filenames.map(filename => path.join(folder, filename)));
|
||||
return times.filter(result => result.status === 'fulfilled').map(result => result.value).sort((a, b) => b.mtime.getTime() - a.mtime.getTime()).map(a => a.filename);
|
||||
} catch (err) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
async function readLogFiles(maxSize) {
|
||||
const modulePath = await getModulePath();
|
||||
const webrtcLog0 = path.join(modulePath, 'discord_voice', 'discord-webrtc_0');
|
||||
const webrtcLog1 = path.join(modulePath, 'discord_voice', 'discord-webrtc_1');
|
||||
const webrtcLog2 = path.join(modulePath, 'discord_voice', 'discord-last-webrtc_0');
|
||||
const webrtcLog3 = path.join(modulePath, 'discord_voice', 'discord-last-webrtc_1');
|
||||
const hookLog = path.join(modulePath, 'discord_hook', 'hook.log');
|
||||
const audioState = path.join(modulePath, 'discord_voice', 'audio_state.json');
|
||||
const filesToUpload = [webrtcLog0, webrtcLog1, webrtcLog2, webrtcLog3, hookLog, audioState]; // Electron 9 changes crash folder location
|
||||
|
||||
const crashBaseFolder = getElectronMajorVersion() < 9 ? path.join(os.tmpdir(), 'Discord Crashes') : await getPath('crashDumps');
|
||||
const crashFolder = process.platform === 'win32' ? path.join(crashBaseFolder, 'reports') : path.join(crashBaseFolder, 'completed');
|
||||
const crashFiles = await orderedFiles(crashFolder);
|
||||
|
||||
if (crashFiles.length > 0) {
|
||||
filesToUpload.push(crashFiles[0]);
|
||||
}
|
||||
|
||||
const files = await readFiles(filesToUpload, maxSize);
|
||||
return files.filter(result => result.status === 'fulfilled').map(result => result.value);
|
||||
}
|
||||
|
||||
async function showItemInFolder(path) {
|
||||
electron.ipcRenderer.invoke(FILE_MANAGER_SHOW_ITEM_IN_FOLDER, path);
|
||||
}
|
||||
|
||||
async function openFiles(dialogOptions, maxSize) {
|
||||
const filenames = await showOpenDialog(dialogOptions);
|
||||
|
||||
if (filenames == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
const files = await readFiles(filenames, maxSize);
|
||||
files.forEach(result => {
|
||||
if (result.status === 'rejected') {
|
||||
throw result.reason;
|
||||
}
|
||||
});
|
||||
return files.map(result => result.value);
|
||||
}
|
||||
|
||||
function readFiles(filenames, maxSize) {
|
||||
return Promise.allSettled(filenames.map(filename => new Promise((resolve, reject) => {
|
||||
originalFs.stat(filename, (err, stats) => {
|
||||
if (err) return reject(err);
|
||||
|
||||
if (stats.size > maxSize) {
|
||||
const err = new Error('upload too large');
|
||||
// used to help determine why openFiles failed
|
||||
err.code = 'ETOOLARGE';
|
||||
return reject(err);
|
||||
// Used to help determine why openFiles failed.
|
||||
// Cannot use an error here because context bridge will remove the code field.
|
||||
// eslint-disable-next-line prefer-promise-reject-errors
|
||||
return reject({
|
||||
code: 'ETOOLARGE',
|
||||
message: 'upload too large'
|
||||
});
|
||||
}
|
||||
|
||||
originalFs.readFile(filename, (err, data) => {
|
||||
if (err) return reject(err);
|
||||
return resolve(makeFile(data.buffer, path.basename(filename)));
|
||||
return resolve({
|
||||
data: data.buffer,
|
||||
filename: path.basename(filename)
|
||||
});
|
||||
});
|
||||
});
|
||||
})));
|
||||
}
|
||||
|
||||
async function getModulePath() {
|
||||
return electron.ipcRenderer.invoke(FILE_MANAGER_GET_MODULE_PATH);
|
||||
}
|
||||
|
||||
function getModuleDataPathSync() {
|
||||
return electron.ipcRenderer.sendSync(FILE_MANAGER_GET_MODULE_DATA_PATH_SYNC);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
readLogFiles,
|
||||
saveWithDialog,
|
||||
|
@ -194,6 +169,7 @@ module.exports = {
|
|||
showOpenDialog,
|
||||
showItemInFolder,
|
||||
getModulePath,
|
||||
getModuleDataPathSync,
|
||||
extname: path.extname,
|
||||
basename: path.basename,
|
||||
dirname: path.dirname,
|
||||
|
|
|
@ -1,20 +1,11 @@
|
|||
'use strict';
|
||||
|
||||
let setEnableHardwareAcceleration = (() => {
|
||||
var _ref = _asyncToGenerator(function* (enable) {
|
||||
electron.ipcRenderer.invoke(GPU_SETTINGS_SET_ENABLE_HWACCEL, enable);
|
||||
});
|
||||
|
||||
return function setEnableHardwareAcceleration(_x) {
|
||||
return _ref.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
|
||||
"use strict";
|
||||
|
||||
const electron = require('electron');
|
||||
|
||||
const { GPU_SETTINGS_SET_ENABLE_HWACCEL, GPU_SETTINGS_GET_ENABLE_HWACCEL_SYNC } = require('../common/constants').IPCEvents;
|
||||
const {
|
||||
GPU_SETTINGS_SET_ENABLE_HWACCEL,
|
||||
GPU_SETTINGS_GET_ENABLE_HWACCEL_SYNC
|
||||
} = require('../common/constants').IPCEvents;
|
||||
|
||||
const hardwareAccelerationEnabled = electron.ipcRenderer.sendSync(GPU_SETTINGS_GET_ENABLE_HWACCEL_SYNC);
|
||||
|
||||
|
@ -22,6 +13,10 @@ function getEnableHardwareAcceleration() {
|
|||
return hardwareAccelerationEnabled;
|
||||
}
|
||||
|
||||
async function setEnableHardwareAcceleration(enable) {
|
||||
electron.ipcRenderer.invoke(GPU_SETTINGS_SET_ENABLE_HWACCEL, enable);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getEnableHardwareAcceleration,
|
||||
setEnableHardwareAcceleration
|
||||
|
|
|
@ -1,11 +1,26 @@
|
|||
'use strict';
|
||||
"use strict";
|
||||
|
||||
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
|
||||
const electron = require('electron');
|
||||
|
||||
const http = require('http');
|
||||
|
||||
const https = require('https');
|
||||
|
||||
function makeChunkedRequest(route, chunks, options, callback) {
|
||||
const {
|
||||
CONSTANTS_GET
|
||||
} = require('../common/constants').IPCEvents;
|
||||
|
||||
async function getAPIEndpoint() {
|
||||
const apiEndpoint = await electron.ipcRenderer.invoke(CONSTANTS_GET, 'API_ENDPOINT');
|
||||
|
||||
if (apiEndpoint == null || apiEndpoint === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
return apiEndpoint;
|
||||
}
|
||||
|
||||
async function makeChunkedRequest(route, chunks, options) {
|
||||
/**
|
||||
* Given an array of chunks, make a slow request, only writing chunks
|
||||
* after a specified amount of time
|
||||
|
@ -18,46 +33,67 @@ function makeChunkedRequest(route, chunks, options, callback) {
|
|||
* token: the token to make an authorized request from
|
||||
* chunks: chunked body of the request to upload
|
||||
*/
|
||||
|
||||
const { method, chunkInterval, token, contentType } = options;
|
||||
|
||||
const {
|
||||
method,
|
||||
chunkInterval,
|
||||
token,
|
||||
contentType
|
||||
} = options;
|
||||
let httpModule = http;
|
||||
|
||||
if (route.startsWith('https')) {
|
||||
httpModule = https;
|
||||
} // we will force the URL to hit only API_ENDPOINT
|
||||
|
||||
|
||||
const apiEndpoint = await getAPIEndpoint();
|
||||
|
||||
if (apiEndpoint == null) {
|
||||
throw new Error('missing api endpoint setting');
|
||||
}
|
||||
|
||||
const requestPromise = new Promise((() => {
|
||||
var _ref = _asyncToGenerator(function* (resolve, reject) {
|
||||
const apiEndpointUrl = new URL(apiEndpoint);
|
||||
const url = new URL(route, apiEndpoint);
|
||||
url.protocol = apiEndpointUrl.protocol;
|
||||
url.host = apiEndpointUrl.host;
|
||||
|
||||
if (!url.pathname.startsWith(apiEndpointUrl.pathname)) {
|
||||
url.pathname = `${apiEndpointUrl.pathname}${url.pathname}`;
|
||||
}
|
||||
|
||||
return new Promise(async (resolve, reject) => {
|
||||
let writeTimeout;
|
||||
const req = httpModule.request(route, {
|
||||
const req = httpModule.request(url.toString(), {
|
||||
method,
|
||||
headers: {
|
||||
authorization: token,
|
||||
'Content-Type': contentType,
|
||||
'Content-Length': Buffer.byteLength(chunks.join(''))
|
||||
}
|
||||
}, function (res) {
|
||||
}, res => {
|
||||
let responseData = '';
|
||||
res.setEncoding('utf8');
|
||||
res.on('data', function (chunk) {
|
||||
res.on('data', chunk => {
|
||||
responseData += chunk;
|
||||
});
|
||||
|
||||
res.on('end', function () {
|
||||
resolve({ status: res.statusCode, body: responseData });
|
||||
res.on('end', () => {
|
||||
resolve({
|
||||
status: res.statusCode,
|
||||
body: responseData
|
||||
});
|
||||
});
|
||||
|
||||
req.on('error', function (e) {
|
||||
});
|
||||
req.on('error', e => {
|
||||
if (writeTimeout != null) {
|
||||
clearTimeout(writeTimeout);
|
||||
}
|
||||
|
||||
reject(e);
|
||||
});
|
||||
|
||||
for (let i = 0; i < chunks.length; i++) {
|
||||
yield new Promise(function (resolve) {
|
||||
req.write(chunks[i], function () {
|
||||
await new Promise(resolve => {
|
||||
req.write(chunks[i], () => {
|
||||
writeTimeout = setTimeout(resolve, chunkInterval);
|
||||
});
|
||||
});
|
||||
|
@ -65,15 +101,11 @@ function makeChunkedRequest(route, chunks, options, callback) {
|
|||
|
||||
req.end();
|
||||
});
|
||||
|
||||
return function (_x, _x2) {
|
||||
return _ref.apply(this, arguments);
|
||||
};
|
||||
})());
|
||||
|
||||
requestPromise.then(body => callback(null, body)).catch(callback);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
makeChunkedRequest
|
||||
getAPIEndpoint,
|
||||
makeChunkedRequest: function (route, chunks, options, callback) {
|
||||
makeChunkedRequest(route, chunks, options).then(body => callback(null, body)).catch(err => callback(err));
|
||||
}
|
||||
};
|
|
@ -1,18 +1,29 @@
|
|||
'use strict';
|
||||
"use strict";
|
||||
|
||||
const electron = require('electron');
|
||||
const { getDiscordIPCEvent } = require('../common/constants');
|
||||
|
||||
const ipcRenderer = electron.ipcRenderer;
|
||||
const {
|
||||
getDiscordIPCEvent,
|
||||
IPCEvents
|
||||
} = require('../common/constants');
|
||||
|
||||
const ipcRenderer = electron.ipcRenderer; // Sending ipc directly from the renderer is considered deprecated.
|
||||
// App still sends a few, so we whitelist those.
|
||||
|
||||
const RENDERER_IPC_WHITELIST = [IPCEvents.APP_BADGE_SET, IPCEvents.CHECK_FOR_UPDATES, IPCEvents.NOTIFICATION_CLOSE, IPCEvents.NOTIFICATION_SHOW, IPCEvents.NOTIFICATIONS_CLEAR, IPCEvents.OPEN_EXTERNAL_URL, IPCEvents.QUIT_AND_INSTALL, IPCEvents.SETTINGS_UPDATE_BACKGROUND_COLOR, IPCEvents.SYSTEM_TRAY_SET_ICON, IPCEvents.SYSTEM_TRAY_SET_APPLICATIONS, IPCEvents.TOGGLE_MINIMIZE_TO_TRAY, IPCEvents.TOGGLE_OPEN_ON_STARTUP, IPCEvents.TOGGLE_START_MINIMIZED, IPCEvents.UPDATE_OPEN_ON_STARTUP, IPCEvents.UPDATER_HISTORY_QUERY_AND_TRUNCATE, IPCEvents.UPDATED_QUOTES];
|
||||
|
||||
function send(ev, ...args) {
|
||||
const event = getDiscordIPCEvent(ev)
|
||||
ipcRenderer.send(event, ...args);
|
||||
const prefixedEvent = getDiscordIPCEvent(ev);
|
||||
|
||||
if (!RENDERER_IPC_WHITELIST.includes(prefixedEvent)) {
|
||||
throw new Error('cannot send this event');
|
||||
}
|
||||
|
||||
ipcRenderer.send(prefixedEvent, ...args);
|
||||
}
|
||||
|
||||
function on(ev, callback) {
|
||||
const event = getDiscordIPCEvent(ev)
|
||||
ipcRenderer.on(event, callback);
|
||||
ipcRenderer.on(getDiscordIPCEvent(ev), callback);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
|
|
@ -1,69 +1,59 @@
|
|||
'use strict';
|
||||
|
||||
let ensureModule = (() => {
|
||||
var _ref = _asyncToGenerator(function* (name) {
|
||||
let modulePromise = modulePromises[name];
|
||||
if (modulePromise == null) {
|
||||
modulePromise = electron.ipcRenderer.invoke(NATIVE_MODULES_INSTALL, name);
|
||||
}
|
||||
return modulePromise;
|
||||
});
|
||||
|
||||
return function ensureModule(_x) {
|
||||
return _ref.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
// TODO: remove this sandboxing when we turn contextIsolation on
|
||||
// sandbox this function in a new context, else it's susceptible to prototype attacks
|
||||
// - RegExp.prototype.test = () => true
|
||||
|
||||
|
||||
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
|
||||
"use strict";
|
||||
|
||||
const electron = require('electron');
|
||||
const vm = require('vm');
|
||||
|
||||
const { NATIVE_MODULES_GET_PATHS, NATIVE_MODULES_INSTALL } = require('../common/constants').IPCEvents;
|
||||
const {
|
||||
NATIVE_MODULES_GET_PATHS,
|
||||
NATIVE_MODULES_INSTALL,
|
||||
NATIVE_MODULES_GET_HAS_NEW_UPDATER
|
||||
} = require('../common/constants').IPCEvents;
|
||||
|
||||
const modulePromises = {};
|
||||
|
||||
function getSanitizedModulePaths() {
|
||||
let sanitizedModulePaths = [];
|
||||
|
||||
const { mainAppDirname, browserModulePaths } = electron.ipcRenderer.sendSync(NATIVE_MODULES_GET_PATHS);
|
||||
|
||||
const {
|
||||
mainAppDirname,
|
||||
browserModulePaths
|
||||
} = electron.ipcRenderer.sendSync(NATIVE_MODULES_GET_PATHS);
|
||||
browserModulePaths.forEach(modulePath => {
|
||||
if (!modulePath.includes('app.asar')) {
|
||||
if (!modulePath.includes('electron.asar')) {
|
||||
sanitizedModulePaths.push(modulePath);
|
||||
}
|
||||
});
|
||||
|
||||
const rendererModulePaths = require('module')._nodeModulePaths(mainAppDirname);
|
||||
sanitizedModulePaths = sanitizedModulePaths.concat(rendererModulePaths.slice(0, 2));
|
||||
|
||||
sanitizedModulePaths = sanitizedModulePaths.concat(rendererModulePaths.slice(0, 2));
|
||||
return sanitizedModulePaths;
|
||||
}
|
||||
|
||||
const context = vm.createContext(Object.create(null));
|
||||
const _requireModule = vm.runInContext(`
|
||||
function requireModule(localRequire, name) {
|
||||
function getHasNewUpdater() {
|
||||
return electron.ipcRenderer.sendSync(NATIVE_MODULES_GET_HAS_NEW_UPDATER);
|
||||
}
|
||||
|
||||
async function ensureModule(name) {
|
||||
let modulePromise = modulePromises[name];
|
||||
|
||||
if (modulePromise == null) {
|
||||
modulePromise = electron.ipcRenderer.invoke(NATIVE_MODULES_INSTALL, name);
|
||||
}
|
||||
|
||||
await modulePromise;
|
||||
module.paths = getSanitizedModulePaths();
|
||||
}
|
||||
|
||||
function requireModule(name) {
|
||||
if (!/^discord_[a-z0-9_-]+$/.test(name) && name !== 'erlpack') {
|
||||
throw new Error('"' + String(name) + '" is not a whitelisted native module');
|
||||
}
|
||||
return localRequire(name);
|
||||
}
|
||||
requireModule
|
||||
`, context);
|
||||
|
||||
function requireModule(name) {
|
||||
return _requireModule((id) => {
|
||||
return require("../../../../../"+id)
|
||||
}, name);
|
||||
return require("../../../../../"+name);
|
||||
}
|
||||
|
||||
module.paths = getSanitizedModulePaths();
|
||||
module.exports = {
|
||||
ensureModule,
|
||||
requireModule
|
||||
requireModule,
|
||||
canBootstrapNewUpdater: !getHasNewUpdater()
|
||||
};
|
|
@ -1,9 +1,11 @@
|
|||
'use strict';
|
||||
"use strict";
|
||||
|
||||
const os = require('os');
|
||||
|
||||
const process = require('process');
|
||||
|
||||
let arch = os.arch();
|
||||
|
||||
if (process.platform === 'win32' && process.env['PROCESSOR_ARCHITEW6432'] != null) {
|
||||
arch = 'x64';
|
||||
}
|
||||
|
|
|
@ -1,18 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
let getSystemIdleTimeMs = (() => {
|
||||
var _ref = _asyncToGenerator(function* () {
|
||||
return electron.ipcRenderer.invoke(POWER_MONITOR_GET_SYSTEM_IDLE_TIME);
|
||||
});
|
||||
|
||||
return function getSystemIdleTimeMs() {
|
||||
return _ref.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
|
||||
"use strict";
|
||||
|
||||
const electron = require('electron');
|
||||
|
||||
const EventEmitter = require('events');
|
||||
|
||||
const {
|
||||
|
@ -24,19 +13,15 @@ const {
|
|||
} = require('../common/constants').IPCEvents;
|
||||
|
||||
const events = new EventEmitter();
|
||||
|
||||
electron.ipcRenderer.on(POWER_MONITOR_RESUME, () => {
|
||||
events.emit('resume');
|
||||
});
|
||||
|
||||
electron.ipcRenderer.on(POWER_MONITOR_SUSPEND, () => {
|
||||
events.emit('suspend');
|
||||
});
|
||||
|
||||
electron.ipcRenderer.on(POWER_MONITOR_LOCK_SCREEN, () => {
|
||||
events.emit('lock-screen');
|
||||
});
|
||||
|
||||
electron.ipcRenderer.on(POWER_MONITOR_UNLOCK_SCREEN, () => {
|
||||
events.emit('unlock-screen');
|
||||
});
|
||||
|
@ -53,6 +38,10 @@ function removeAllListeners() {
|
|||
events.removeAllListeners.apply(events, arguments);
|
||||
}
|
||||
|
||||
async function getSystemIdleTimeMs() {
|
||||
return electron.ipcRenderer.invoke(POWER_MONITOR_GET_SYSTEM_IDLE_TIME);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
on,
|
||||
removeListener,
|
||||
|
|
|
@ -1,36 +1,4 @@
|
|||
'use strict';
|
||||
|
||||
let blockDisplaySleep = (() => {
|
||||
var _ref = _asyncToGenerator(function* () {
|
||||
return electron.ipcRenderer.invoke(POWER_SAVE_BLOCKER_BLOCK_DISPLAY_SLEEP);
|
||||
});
|
||||
|
||||
return function blockDisplaySleep() {
|
||||
return _ref.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
let unblockDisplaySleep = (() => {
|
||||
var _ref2 = _asyncToGenerator(function* (id) {
|
||||
return electron.ipcRenderer.invoke(POWER_SAVE_BLOCKER_UNBLOCK_DISPLAY_SLEEP, id);
|
||||
});
|
||||
|
||||
return function unblockDisplaySleep(_x) {
|
||||
return _ref2.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
let cleanupDisplaySleep = (() => {
|
||||
var _ref3 = _asyncToGenerator(function* () {
|
||||
return electron.ipcRenderer.invoke(POWER_SAVE_BLOCKER_CLEANUP_DISPLAY_SLEEP);
|
||||
});
|
||||
|
||||
return function cleanupDisplaySleep() {
|
||||
return _ref3.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
|
||||
"use strict";
|
||||
|
||||
const electron = require('electron');
|
||||
|
||||
|
@ -40,6 +8,18 @@ const {
|
|||
POWER_SAVE_BLOCKER_CLEANUP_DISPLAY_SLEEP
|
||||
} = require('../common/constants').IPCEvents;
|
||||
|
||||
async function blockDisplaySleep() {
|
||||
return electron.ipcRenderer.invoke(POWER_SAVE_BLOCKER_BLOCK_DISPLAY_SLEEP);
|
||||
}
|
||||
|
||||
async function unblockDisplaySleep(id) {
|
||||
return electron.ipcRenderer.invoke(POWER_SAVE_BLOCKER_UNBLOCK_DISPLAY_SLEEP, id);
|
||||
}
|
||||
|
||||
async function cleanupDisplaySleep() {
|
||||
return electron.ipcRenderer.invoke(POWER_SAVE_BLOCKER_CLEANUP_DISPLAY_SLEEP);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
blockDisplaySleep,
|
||||
unblockDisplaySleep,
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
'use strict';
|
||||
"use strict";
|
||||
|
||||
const electron = require('electron');
|
||||
const process = require('process');
|
||||
const env = process.env;
|
||||
|
||||
const process = require('process');
|
||||
|
||||
const env = process.env;
|
||||
module.exports = {
|
||||
platform: process.platform,
|
||||
arch: process.arch,
|
||||
|
|
|
@ -1,58 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
let flushDNSCache = (() => {
|
||||
var _ref = _asyncToGenerator(function* () {
|
||||
electron.ipcRenderer.invoke(PROCESS_UTILS_FLUSH_DNS_CACHE);
|
||||
});
|
||||
|
||||
return function flushDNSCache() {
|
||||
return _ref.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
let flushCookies = (() => {
|
||||
var _ref2 = _asyncToGenerator(function* (callback) {
|
||||
try {
|
||||
yield electron.ipcRenderer.invoke(PROCESS_UTILS_FLUSH_COOKIES);
|
||||
callback();
|
||||
} catch (err) {
|
||||
callback(err);
|
||||
}
|
||||
});
|
||||
|
||||
return function flushCookies(_x) {
|
||||
return _ref2.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
let flushStorageData = (() => {
|
||||
var _ref3 = _asyncToGenerator(function* (callback) {
|
||||
try {
|
||||
yield electron.ipcRenderer.invoke(PROCESS_UTILS_FLUSH_STORAGE_DATA);
|
||||
callback();
|
||||
} catch (err) {
|
||||
callback(err);
|
||||
}
|
||||
});
|
||||
|
||||
return function flushStorageData(_x2) {
|
||||
return _ref3.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
let purgeMemory = (() => {
|
||||
var _ref4 = _asyncToGenerator(function* () {
|
||||
electron.webFrame.clearCache();
|
||||
});
|
||||
|
||||
return function purgeMemory() {
|
||||
return _ref4.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
|
||||
"use strict";
|
||||
|
||||
const electron = require('electron');
|
||||
|
||||
const process = require('process');
|
||||
|
||||
const {
|
||||
|
@ -63,23 +12,47 @@ const {
|
|||
PROCESS_UTILS_FLUSH_STORAGE_DATA,
|
||||
PROCESS_UTILS_GET_MAIN_ARGV_SYNC
|
||||
} = require('../common/constants').IPCEvents;
|
||||
|
||||
const CPU_USAGE_GATHER_INTERVAL = 1000;
|
||||
const MEMORY_USAGE_GATHER_INTERVAL = 5000;
|
||||
|
||||
const mainArgv = electron.ipcRenderer.sendSync(PROCESS_UTILS_GET_MAIN_ARGV_SYNC);
|
||||
let totalProcessorUsagePercent = 0;
|
||||
let totalMemoryUsageKB = 0;
|
||||
|
||||
setInterval(() => {
|
||||
electron.ipcRenderer.invoke(PROCESS_UTILS_GET_CPU_USAGE).then(usage => totalProcessorUsagePercent = usage);
|
||||
}, CPU_USAGE_GATHER_INTERVAL);
|
||||
|
||||
setInterval(() => {
|
||||
Promise.all([process.getProcessMemoryInfo(), electron.ipcRenderer.invoke(PROCESS_UTILS_GET_MEMORY_INFO)].map(x => x.catch(() => 0))).then(usages => {
|
||||
totalMemoryUsageKB = usages.reduce((total, usage) => total + usage.private, 0);
|
||||
});
|
||||
}, MEMORY_USAGE_GATHER_INTERVAL);
|
||||
|
||||
async function flushDNSCache() {
|
||||
electron.ipcRenderer.invoke(PROCESS_UTILS_FLUSH_DNS_CACHE);
|
||||
}
|
||||
|
||||
async function flushCookies(callback) {
|
||||
try {
|
||||
await electron.ipcRenderer.invoke(PROCESS_UTILS_FLUSH_COOKIES);
|
||||
callback();
|
||||
} catch (err) {
|
||||
callback(err);
|
||||
}
|
||||
}
|
||||
|
||||
async function flushStorageData(callback) {
|
||||
try {
|
||||
await electron.ipcRenderer.invoke(PROCESS_UTILS_FLUSH_STORAGE_DATA);
|
||||
callback();
|
||||
} catch (err) {
|
||||
callback(err);
|
||||
}
|
||||
}
|
||||
|
||||
async function purgeMemory() {
|
||||
electron.webFrame.clearCache();
|
||||
}
|
||||
|
||||
function getCurrentCPUUsagePercent() {
|
||||
return totalProcessorUsagePercent;
|
||||
}
|
||||
|
|
|
@ -1,30 +1,28 @@
|
|||
'use strict';
|
||||
|
||||
let get = (() => {
|
||||
var _ref = _asyncToGenerator(function* (name, defaultValue) {
|
||||
return electron.ipcRenderer.invoke(SETTINGS_GET, name, defaultValue);
|
||||
});
|
||||
|
||||
return function get(_x, _x2) {
|
||||
return _ref.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
let set = (() => {
|
||||
var _ref2 = _asyncToGenerator(function* (name, value) {
|
||||
return electron.ipcRenderer.invoke(SETTINGS_SET, name, value);
|
||||
});
|
||||
|
||||
return function set(_x3, _x4) {
|
||||
return _ref2.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
|
||||
"use strict";
|
||||
|
||||
const electron = require('electron');
|
||||
|
||||
const { SETTINGS_GET, SETTINGS_SET, SETTINGS_GET_SYNC } = require('../common/constants').IPCEvents;
|
||||
const {
|
||||
SETTINGS_GET,
|
||||
SETTINGS_SET,
|
||||
SETTINGS_GET_SYNC
|
||||
} = require('../common/constants').IPCEvents; // Updating app settings directly from the renderer is considered deprecated.
|
||||
// Voice still sets a few options, so we whitelist those.
|
||||
|
||||
|
||||
const RENDERER_SET_WHITELIST = ['audioSubsystem', 'useLegacyAudioDevice', 'debugLogging'];
|
||||
|
||||
async function get(name, defaultValue) {
|
||||
return electron.ipcRenderer.invoke(SETTINGS_GET, name, defaultValue);
|
||||
}
|
||||
|
||||
async function set(name, value) {
|
||||
if (!RENDERER_SET_WHITELIST.includes(name)) {
|
||||
throw new Error('cannot set this setting key');
|
||||
}
|
||||
|
||||
return electron.ipcRenderer.invoke(SETTINGS_SET, name, value);
|
||||
}
|
||||
|
||||
function getSync(name, defaultValue) {
|
||||
return electron.ipcRenderer.sendSync(SETTINGS_GET_SYNC, name, defaultValue);
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
'use strict';
|
||||
|
||||
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
|
||||
"use strict";
|
||||
|
||||
const electron = require('electron');
|
||||
|
||||
const EventEmitter = require('events');
|
||||
const { getElectronMajorVersion } = require('../common/utility');
|
||||
|
||||
const {
|
||||
getElectronMajorVersion
|
||||
} = require('../../../common/processUtils');
|
||||
|
||||
const {
|
||||
SPELLCHECK_RESULT,
|
||||
|
@ -15,87 +17,23 @@ const {
|
|||
} = require('../common/constants').IPCEvents;
|
||||
|
||||
if (getElectronMajorVersion() < 8) {
|
||||
let setSpellCheckProvider = (() => {
|
||||
var _ref = _asyncToGenerator(function* (locale, autoCorrectWord, provider) {
|
||||
async function setSpellCheckProvider(locale, autoCorrectWord, provider) {
|
||||
const asyncProvider = {
|
||||
spellCheck: function (words, callback) {
|
||||
return callback(words.filter(function (word) {
|
||||
return !provider.spellCheck(word);
|
||||
}));
|
||||
}
|
||||
spellCheck: (words, callback) => callback(words.filter(word => !provider.spellCheck(word)))
|
||||
};
|
||||
electron.webFrame.setSpellCheckProvider(locale, asyncProvider);
|
||||
});
|
||||
}
|
||||
|
||||
return function setSpellCheckProvider(_x, _x2, _x3) {
|
||||
return _ref.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
let replaceMisspelling = (() => {
|
||||
var _ref2 = _asyncToGenerator(function* (word) {
|
||||
async function replaceMisspelling(word) {
|
||||
electron.ipcRenderer.invoke(SPELLCHECK_REPLACE_MISSPELLING, word);
|
||||
});
|
||||
|
||||
return function replaceMisspelling(_x4) {
|
||||
return _ref2.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
setSpellCheckProvider,
|
||||
replaceMisspelling
|
||||
};
|
||||
} else {
|
||||
let getAvailableDictionaries = (() => {
|
||||
var _ref3 = _asyncToGenerator(function* () {
|
||||
return electron.ipcRenderer.invoke(SPELLCHECK_GET_AVAILABLE_DICTIONARIES);
|
||||
});
|
||||
|
||||
return function getAvailableDictionaries() {
|
||||
return _ref3.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
let setLocale = (() => {
|
||||
var _ref4 = _asyncToGenerator(function* (locale) {
|
||||
let succeeded = true;
|
||||
try {
|
||||
yield electron.ipcRenderer.invoke(SPELLCHECK_SET_LOCALE, locale);
|
||||
} catch (_) {
|
||||
succeeded = false;
|
||||
}
|
||||
|
||||
return succeeded;
|
||||
});
|
||||
|
||||
return function setLocale(_x5) {
|
||||
return _ref4.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
let setLearnedWords = (() => {
|
||||
var _ref5 = _asyncToGenerator(function* (learnedWords) {
|
||||
return electron.ipcRenderer.invoke(SPELLCHECK_SET_LEARNED_WORDS, learnedWords);
|
||||
});
|
||||
|
||||
return function setLearnedWords(_x6) {
|
||||
return _ref5.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
let replaceMisspelling = (() => {
|
||||
var _ref6 = _asyncToGenerator(function* (correction) {
|
||||
return electron.ipcRenderer.invoke(SPELLCHECK_REPLACE_MISSPELLING, correction);
|
||||
});
|
||||
|
||||
return function replaceMisspelling(_x7) {
|
||||
return _ref6.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
const events = new EventEmitter();
|
||||
|
||||
electron.ipcRenderer.on(SPELLCHECK_RESULT, handleSpellcheckData);
|
||||
|
||||
function handleSpellcheckData(_, misspelledWord, dictionarySuggestions) {
|
||||
|
@ -110,6 +48,30 @@ if (getElectronMajorVersion() < 8) {
|
|||
events.removeListener.apply(events, arguments);
|
||||
}
|
||||
|
||||
async function getAvailableDictionaries() {
|
||||
return electron.ipcRenderer.invoke(SPELLCHECK_GET_AVAILABLE_DICTIONARIES);
|
||||
}
|
||||
|
||||
async function setLocale(locale) {
|
||||
let succeeded = true;
|
||||
|
||||
try {
|
||||
await electron.ipcRenderer.invoke(SPELLCHECK_SET_LOCALE, locale);
|
||||
} catch (_) {
|
||||
succeeded = false;
|
||||
}
|
||||
|
||||
return succeeded;
|
||||
}
|
||||
|
||||
async function setLearnedWords(learnedWords) {
|
||||
return electron.ipcRenderer.invoke(SPELLCHECK_SET_LEARNED_WORDS, learnedWords);
|
||||
}
|
||||
|
||||
async function replaceMisspelling(correction) {
|
||||
return electron.ipcRenderer.invoke(SPELLCHECK_REPLACE_MISSPELLING, correction);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
on,
|
||||
removeListener,
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
"use strict";
|
||||
|
||||
const electron = require('electron');
|
||||
|
||||
const {
|
||||
USER_DATA_CACHE_SAVE,
|
||||
USER_DATA_CACHE_GET,
|
||||
USER_DATA_CACHE_DELETE
|
||||
} = require('../common/constants').IPCEvents;
|
||||
|
||||
async function getCached() {
|
||||
const cached = await electron.ipcRenderer.invoke(USER_DATA_CACHE_GET);
|
||||
return cached;
|
||||
}
|
||||
|
||||
function cacheUserData(userData) {
|
||||
electron.ipcRenderer.send(USER_DATA_CACHE_SAVE, userData);
|
||||
}
|
||||
|
||||
function deleteCache() {
|
||||
electron.ipcRenderer.send(USER_DATA_CACHE_DELETE);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getCached,
|
||||
cacheUserData,
|
||||
deleteCache
|
||||
};
|
|
@ -1,148 +1,4 @@
|
|||
'use strict';
|
||||
|
||||
let flashFrame = (() => {
|
||||
var _ref3 = _asyncToGenerator(function* (flag) {
|
||||
electron.ipcRenderer.invoke(WINDOW_FLASH_FRAME, flag);
|
||||
});
|
||||
|
||||
return function flashFrame(_x3) {
|
||||
return _ref3.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
let minimize = (() => {
|
||||
var _ref4 = _asyncToGenerator(function* (key) {
|
||||
electron.ipcRenderer.invoke(WINDOW_MINIMIZE, key);
|
||||
});
|
||||
|
||||
return function minimize(_x4) {
|
||||
return _ref4.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
let restore = (() => {
|
||||
var _ref5 = _asyncToGenerator(function* (key) {
|
||||
electron.ipcRenderer.invoke(WINDOW_RESTORE, key);
|
||||
});
|
||||
|
||||
return function restore(_x5) {
|
||||
return _ref5.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
let maximize = (() => {
|
||||
var _ref6 = _asyncToGenerator(function* (key) {
|
||||
electron.ipcRenderer.invoke(WINDOW_MAXIMIZE, key);
|
||||
});
|
||||
|
||||
return function maximize(_x6) {
|
||||
return _ref6.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
let focus = (() => {
|
||||
var _ref7 = _asyncToGenerator(function* (_hack, key) {
|
||||
electron.ipcRenderer.invoke(WINDOW_FOCUS, key);
|
||||
});
|
||||
|
||||
return function focus(_x7, _x8) {
|
||||
return _ref7.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
let setAlwaysOnTop = (() => {
|
||||
var _ref8 = _asyncToGenerator(function* (key, enabled) {
|
||||
return electron.ipcRenderer.invoke(WINDOW_SET_ALWAYS_ON_TOP, key, enabled);
|
||||
});
|
||||
|
||||
return function setAlwaysOnTop(_x9, _x10) {
|
||||
return _ref8.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
let isAlwaysOnTop = (() => {
|
||||
var _ref9 = _asyncToGenerator(function* (key) {
|
||||
return electron.ipcRenderer.invoke(WINDOW_IS_ALWAYS_ON_TOP, key);
|
||||
});
|
||||
|
||||
return function isAlwaysOnTop(_x11) {
|
||||
return _ref9.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
let blur = (() => {
|
||||
var _ref10 = _asyncToGenerator(function* (key) {
|
||||
electron.ipcRenderer.invoke(WINDOW_BLUR, key);
|
||||
});
|
||||
|
||||
return function blur(_x12) {
|
||||
return _ref10.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
let setProgressBar = (() => {
|
||||
var _ref11 = _asyncToGenerator(function* (progress, key) {
|
||||
electron.ipcRenderer.invoke(WINDOW_SET_PROGRESS_BAR, key, progress);
|
||||
});
|
||||
|
||||
return function setProgressBar(_x13, _x14) {
|
||||
return _ref11.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
let fullscreen = (() => {
|
||||
var _ref12 = _asyncToGenerator(function* (key) {
|
||||
electron.ipcRenderer.invoke(WINDOW_TOGGLE_FULLSCREEN, key);
|
||||
});
|
||||
|
||||
return function fullscreen(_x15) {
|
||||
return _ref12.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
let close = (() => {
|
||||
var _ref13 = _asyncToGenerator(function* (key) {
|
||||
electron.ipcRenderer.invoke(WINDOW_CLOSE, key);
|
||||
});
|
||||
|
||||
return function close(_x16) {
|
||||
return _ref13.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
let setZoomFactor = (() => {
|
||||
var _ref14 = _asyncToGenerator(function* (factor) {
|
||||
if (!electron.webFrame.setZoomFactor) return;
|
||||
electron.webFrame.setZoomFactor(factor / 100);
|
||||
});
|
||||
|
||||
return function setZoomFactor(_x17) {
|
||||
return _ref14.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
let setBackgroundThrottling = (() => {
|
||||
var _ref15 = _asyncToGenerator(function* (enabled) {
|
||||
electron.ipcRenderer.invoke(WINDOW_SET_BACKGROUND_THROTTLING, enabled);
|
||||
});
|
||||
|
||||
return function setBackgroundThrottling(_x18) {
|
||||
return _ref15.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
let setDevtoolsCallbacks = (() => {
|
||||
var _ref16 = _asyncToGenerator(function* (onOpened, onClosed) {
|
||||
devtoolsOpenedCallback = onOpened;
|
||||
devtoolsClosedCallback = onClosed;
|
||||
});
|
||||
|
||||
return function setDevtoolsCallbacks(_x19, _x20) {
|
||||
return _ref16.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
|
||||
"use strict";
|
||||
|
||||
const electron = require('electron');
|
||||
|
||||
|
@ -164,31 +20,77 @@ const {
|
|||
} = require('../common/constants').IPCEvents;
|
||||
|
||||
let devtoolsOpenedCallback = () => {};
|
||||
|
||||
let devtoolsClosedCallback = () => {};
|
||||
|
||||
electron.ipcRenderer.on(WINDOW_DEVTOOLS_OPENED, (() => {
|
||||
var _ref = _asyncToGenerator(function* (_) {
|
||||
electron.ipcRenderer.on(WINDOW_DEVTOOLS_OPENED, async _ => {
|
||||
if (devtoolsOpenedCallback != null) {
|
||||
devtoolsOpenedCallback();
|
||||
}
|
||||
});
|
||||
|
||||
return function (_x) {
|
||||
return _ref.apply(this, arguments);
|
||||
};
|
||||
})());
|
||||
|
||||
electron.ipcRenderer.on(WINDOW_DEVTOOLS_CLOSED, (() => {
|
||||
var _ref2 = _asyncToGenerator(function* (_) {
|
||||
});
|
||||
electron.ipcRenderer.on(WINDOW_DEVTOOLS_CLOSED, async _ => {
|
||||
if (devtoolsOpenedCallback != null) {
|
||||
devtoolsOpenedCallback();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return function (_x2) {
|
||||
return _ref2.apply(this, arguments);
|
||||
};
|
||||
})());
|
||||
async function flashFrame(flag) {
|
||||
electron.ipcRenderer.invoke(WINDOW_FLASH_FRAME, flag);
|
||||
}
|
||||
|
||||
async function minimize(key) {
|
||||
electron.ipcRenderer.invoke(WINDOW_MINIMIZE, key);
|
||||
}
|
||||
|
||||
async function restore(key) {
|
||||
electron.ipcRenderer.invoke(WINDOW_RESTORE, key);
|
||||
}
|
||||
|
||||
async function maximize(key) {
|
||||
electron.ipcRenderer.invoke(WINDOW_MAXIMIZE, key);
|
||||
}
|
||||
|
||||
async function focus(_hack, key) {
|
||||
electron.ipcRenderer.invoke(WINDOW_FOCUS, key);
|
||||
}
|
||||
|
||||
async function setAlwaysOnTop(key, enabled) {
|
||||
return electron.ipcRenderer.invoke(WINDOW_SET_ALWAYS_ON_TOP, key, enabled);
|
||||
}
|
||||
|
||||
async function isAlwaysOnTop(key) {
|
||||
return electron.ipcRenderer.invoke(WINDOW_IS_ALWAYS_ON_TOP, key);
|
||||
}
|
||||
|
||||
async function blur(key) {
|
||||
electron.ipcRenderer.invoke(WINDOW_BLUR, key);
|
||||
}
|
||||
|
||||
async function setProgressBar(progress, key) {
|
||||
electron.ipcRenderer.invoke(WINDOW_SET_PROGRESS_BAR, key, progress);
|
||||
}
|
||||
|
||||
async function fullscreen(key) {
|
||||
electron.ipcRenderer.invoke(WINDOW_TOGGLE_FULLSCREEN, key);
|
||||
}
|
||||
|
||||
async function close(key) {
|
||||
electron.ipcRenderer.invoke(WINDOW_CLOSE, key);
|
||||
}
|
||||
|
||||
async function setZoomFactor(factor) {
|
||||
if (!electron.webFrame.setZoomFactor) return;
|
||||
electron.webFrame.setZoomFactor(factor / 100);
|
||||
}
|
||||
|
||||
async function setBackgroundThrottling(enabled) {
|
||||
electron.ipcRenderer.invoke(WINDOW_SET_BACKGROUND_THROTTLING, enabled);
|
||||
}
|
||||
|
||||
async function setDevtoolsCallbacks(onOpened, onClosed) {
|
||||
devtoolsOpenedCallback = onOpened;
|
||||
devtoolsClosedCallback = onClosed;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
flashFrame,
|
||||
|
|
|
@ -1 +1,15 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="Layer_1" width="20" height="20" x="0" y="0" enable-background="new 40 40 20 20" version="1.1" viewBox="40 40 20 20" xml:space="preserve"><title>Slice 1</title><description>Created with Sketch (http://www.bohemiancoding.com/sketch)</description><g id="Page_1"><path id="Close" fill="#99aab5" d="M40.445,42.853l2.408-2.408c0.593-0.593,1.555-0.593,2.147,0l5,5l5-5 c0.593-0.593,1.554-0.593,2.147,0l2.408,2.408c0.593,0.593,0.593,1.554,0,2.147l-5,5l5,5c0.593,0.593,0.592,1.554,0,2.147 l-2.408,2.408c-0.593,0.593-1.555,0.593-2.147,0l-5-5l-5,5c-0.593,0.593-1.554,0.593-2.147,0l-2.408-2.408 c-0.593-0.593-0.593-1.554,0-2.147l5-5l-5-5C39.852,44.407,39.852,43.445,40.445,42.853z"/></g></svg>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 17.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns"
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="20px" height="20px"
|
||||
viewBox="40 40 20 20" enable-background="new 40 40 20 20" xml:space="preserve">
|
||||
<title>Slice 1</title>
|
||||
<description>Created with Sketch (http://www.bohemiancoding.com/sketch)</description>
|
||||
<g id="Page_1">
|
||||
<path id="Close" fill="#99aab5" d="M40.445,42.853l2.408-2.408c0.593-0.593,1.555-0.593,2.147,0l5,5l5-5
|
||||
c0.593-0.593,1.554-0.593,2.147,0l2.408,2.408c0.593,0.593,0.593,1.554,0,2.147l-5,5l5,5c0.593,0.593,0.592,1.554,0,2.147
|
||||
l-2.408,2.408c-0.593,0.593-1.555,0.593-2.147,0l-5-5l-5,5c-0.593,0.593-1.554,0.593-2.147,0l-2.408-2.408
|
||||
c-0.593-0.593-0.593-1.554,0-2.147l5-5l-5-5C39.852,44.407,39.852,43.445,40.445,42.853z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
|
Before Width: | Height: | Size: 767 B After Width: | Height: | Size: 1.1 KiB |
|
@ -1 +1,34 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="Layer_1" x="0" y="0" version="1.1" viewBox="0 0 168 190" xml:space="preserve" style="enable-background:new 0 0 168 190"><style type="text/css">.st0{fill:#fff}.st1{fill:url(#SVGID_1_)}.st2{fill:url(#SVGID_2_)}.st3{fill:url(#SVGID_3_)}</style><g><rect width="139.2" height="97.7" x="14.9" y="35.3" class="st0"/><g><linearGradient id="SVGID_1_" x1="66.7" x2="66.7" y1="112.3" y2="91.269" gradientTransform="matrix(1 0 0 -1 0 192)" gradientUnits="userSpaceOnUse"><stop offset="0" style="stop-color:#e30613"/><stop offset="1" style="stop-color:#731a14"/></linearGradient><path d="M66.7,79.7c-5.4,0-9.8,4.7-9.8,10.5s4.4,10.5,9.8,10.5s9.8-4.7,9.8-10.5C76.5,84.4,72.1,79.7,66.7,79.7z" class="st1"/><linearGradient id="SVGID_2_" x1="101.7" x2="101.7" y1="112.3" y2="91.269" gradientTransform="matrix(1 0 0 -1 0 192)" gradientUnits="userSpaceOnUse"><stop offset="0" style="stop-color:#e20613"/><stop offset="1" style="stop-color:#731a13"/></linearGradient><path d="M101.7,79.7c-5.4,0-9.8,4.7-9.8,10.5s4.4,10.5,9.8,10.5s9.8-4.7,9.8-10.5C111.5,84.4,107.1,79.7,101.7,79.7z" class="st2"/><linearGradient id="SVGID_3_" x1="84" x2="84" y1="192" y2="2" gradientTransform="matrix(1 0 0 -1 0 192)" gradientUnits="userSpaceOnUse"><stop offset="0" style="stop-color:#e30613"/><stop offset="1" style="stop-color:#731a13"/></linearGradient><path d="M148.4,0H19.6C8.8,0,0,8.8,0,19.6V148c0,10.8,8.8,19.6,19.6,19.6h108.9l-5.1-17.5l12.3,11.3l11.6,10.7 L168,190v-41.9v-9.5v-119C168,8.8,159.2,0,148.4,0z M111.3,124.1c0,0-3.4-4.1-6.3-7.7c12.6-3.5,17.4-11.3,17.4-11.3 c-4,2.6-7.7,4.4-11.1,5.6c-4.8,2-9.5,3.3-14,4.1c-9.2,1.7-17.6,1.3-24.9-0.1c-5.5-1-10.2-2.5-14.1-4.1c-2.2-0.8-4.6-1.9-7.1-3.3 c-0.3-0.2-0.6-0.3-0.9-0.5c-0.1-0.1-0.3-0.2-0.4-0.2c-1.7-1-2.6-1.6-2.6-1.6s4.6,7.6,16.8,11.2c-2.9,3.6-6.4,7.9-6.4,7.9 c-21.2-0.6-29.3-14.5-29.3-14.5c0-30.6,13.8-55.4,13.8-55.4c13.8-10.3,26.9-10,26.9-10l1,1.1C52.8,50.3,45,57.9,45,57.9 s2.1-1.2,5.7-2.7c10.3-4.5,18.4-5.7,21.8-6c0.5-0.1,1.1-0.2,1.6-0.2c5.9-0.7,12.5-0.9,19.4-0.2c9.1,1,18.9,3.7,28.9,9.1 c0,0-7.5-7.2-23.9-12.1l1.3-1.5c0,0,13.1-0.3,26.9,10c0,0,13.8,24.8,13.8,55.4C140.6,109.6,132.5,123.5,111.3,124.1z" class="st3"/></g></g></svg>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 168 190" enable-background="new 0 0 168 190" xml:space="preserve">
|
||||
<g>
|
||||
<rect x="14.4" y="46.1" fill="#FFFFFF" width="139.2" height="97.7"/>
|
||||
<g>
|
||||
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="66.6616" y1="79.7119" x2="66.6616" y2="100.7434">
|
||||
<stop offset="0" style="stop-color:#7491D5"/>
|
||||
<stop offset="1" style="stop-color:#4E68A0"/>
|
||||
</linearGradient>
|
||||
<path fill="url(#SVGID_1_)" d="M66.7,79.7c-5.4,0-9.8,4.7-9.8,10.5c0,5.8,4.4,10.5,9.8,10.5c5.4,0,9.8-4.7,9.8-10.5
|
||||
C76.5,84.4,72.1,79.7,66.7,79.7z"/>
|
||||
<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="101.661" y1="79.7119" x2="101.661" y2="100.7434">
|
||||
<stop offset="0" style="stop-color:#7491D5"/>
|
||||
<stop offset="1" style="stop-color:#4E68A0"/>
|
||||
</linearGradient>
|
||||
<path fill="url(#SVGID_2_)" d="M101.7,79.7c-5.4,0-9.8,4.7-9.8,10.5c0,5.8,4.4,10.5,9.8,10.5c5.4,0,9.8-4.7,9.8-10.5
|
||||
C111.5,84.4,107.1,79.7,101.7,79.7z"/>
|
||||
<linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="84" y1="-4.545736e-07" x2="84" y2="190">
|
||||
<stop offset="0" style="stop-color:#7491D5"/>
|
||||
<stop offset="1" style="stop-color:#4E68A0"/>
|
||||
</linearGradient>
|
||||
<path fill="url(#SVGID_3_)" d="M148.4,0H19.6C8.8,0,0,8.8,0,19.6v128.4c0,10.8,8.8,19.6,19.6,19.6h108.9l-5.1-17.5l12.3,11.3
|
||||
l11.6,10.7L168,190v-41.9v-9.5V19.6C168,8.8,159.2,0,148.4,0z M111.3,124.1c0,0-3.4-4.1-6.3-7.7c12.6-3.5,17.4-11.3,17.4-11.3
|
||||
c-4,2.6-7.7,4.4-11.1,5.6c-4.8,2-9.5,3.3-14,4.1c-9.2,1.7-17.6,1.3-24.9-0.1c-5.5-1-10.2-2.5-14.1-4.1c-2.2-0.8-4.6-1.9-7.1-3.3
|
||||
c-0.3-0.2-0.6-0.3-0.9-0.5c-0.1-0.1-0.3-0.2-0.4-0.2c-1.7-1-2.6-1.6-2.6-1.6s4.6,7.6,16.8,11.2c-2.9,3.6-6.4,7.9-6.4,7.9
|
||||
c-21.2-0.6-29.3-14.5-29.3-14.5c0-30.6,13.8-55.4,13.8-55.4c13.8-10.3,26.9-10,26.9-10l1,1.1C52.8,50.3,45,57.9,45,57.9
|
||||
s2.1-1.2,5.7-2.7c10.3-4.5,18.4-5.7,21.8-6c0.5-0.1,1.1-0.2,1.6-0.2c5.9-0.7,12.5-0.9,19.4-0.2c9.1,1,18.9,3.7,28.9,9.1
|
||||
c0,0-7.5-7.2-23.9-12.1l1.3-1.5c0,0,13.1-0.3,26.9,10c0,0,13.8,24.8,13.8,55.4C140.6,109.6,132.5,123.5,111.3,124.1z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 762 B After Width: | Height: | Size: 906 B |
Before Width: | Height: | Size: 936 B After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 1015 B After Width: | Height: | Size: 1.1 KiB |
|
@ -1,15 +1,20 @@
|
|||
'use strict';
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.startup = startup;
|
||||
exports.handleSingleInstance = handleSingleInstance;
|
||||
exports.handleOpenUrl = handleOpenUrl;
|
||||
exports.setMainWindowVisible = setMainWindowVisible;
|
||||
const { Menu, BrowserWindow } = require('electron');
|
||||
|
||||
const {
|
||||
Menu,
|
||||
BrowserWindow
|
||||
} = require('electron');
|
||||
const fetch = require("node-fetch").default
|
||||
|
||||
let mainScreen;
|
||||
|
||||
function startup(bootstrapModules) {
|
||||
// below modules are required and initted
|
||||
// in this order to prevent dependency conflicts
|
||||
|
@ -17,58 +22,94 @@ function startup(bootstrapModules) {
|
|||
require('./bootstrapModules').init(bootstrapModules);
|
||||
|
||||
require('./paths');
|
||||
|
||||
require('./splashScreen');
|
||||
|
||||
const moduleUpdater = require('./moduleUpdater');
|
||||
|
||||
const updater = require('./updater');
|
||||
|
||||
require('./autoStart');
|
||||
|
||||
const buildInfo = require('./buildInfo');
|
||||
|
||||
const appSettings = require('./appSettings');
|
||||
|
||||
const Constants = require('./Constants');
|
||||
|
||||
Constants.init(bootstrapModules.Constants);
|
||||
|
||||
const appFeatures = require('./appFeatures');
|
||||
|
||||
appFeatures.init();
|
||||
|
||||
const GPUSettings = require('./GPUSettings');
|
||||
|
||||
bootstrapModules.GPUSettings.replace(GPUSettings);
|
||||
|
||||
const rootCertificates = require('./rootCertificates');
|
||||
|
||||
rootCertificates.init();
|
||||
|
||||
require('./discord_native/browser/accessibility');
|
||||
|
||||
const app = require('./discord_native/browser/app');
|
||||
|
||||
app.injectBuildInfo(buildInfo);
|
||||
app.injectModuleUpdater(moduleUpdater);
|
||||
app.injectUpdater(updater);
|
||||
|
||||
require('./discord_native/browser/clipboard');
|
||||
const crashReporter = require('./discord_native/browser/crashReporter');
|
||||
crashReporter.injectBuildInfo(buildInfo);
|
||||
|
||||
require('./discord_native/browser/constants');
|
||||
|
||||
require('./discord_native/browser/crashReporter');
|
||||
|
||||
const features = require('./discord_native/browser/features');
|
||||
|
||||
features.injectFeaturesBackend(appFeatures.getFeatures());
|
||||
|
||||
require('./discord_native/browser/fileManager');
|
||||
|
||||
require('./discord_native/browser/userDataCache');
|
||||
|
||||
const gpuSettings = require('./discord_native/browser/gpuSettings');
|
||||
|
||||
gpuSettings.injectGpuSettingsBackend(GPUSettings);
|
||||
|
||||
const nativeModules = require('./discord_native/browser/nativeModules');
|
||||
|
||||
nativeModules.injectModuleUpdater(moduleUpdater);
|
||||
nativeModules.injectUpdater(updater);
|
||||
|
||||
require('./discord_native/browser/powerMonitor');
|
||||
|
||||
require('./discord_native/browser/powerSaveBlocker');
|
||||
|
||||
require('./discord_native/browser/processUtils');
|
||||
|
||||
const settings = require('./discord_native/browser/settings');
|
||||
|
||||
settings.injectSettingsBackend(appSettings.getSettings());
|
||||
|
||||
require('./discord_native/browser/spellCheck');
|
||||
const windowNative = require('./discord_native/browser/window');
|
||||
require("./lightcordMainProcess")
|
||||
|
||||
// expose globals that will be imported by the webapp
|
||||
const windowNative = require('./discord_native/browser/window'); // expose globals that will be imported by the webapp
|
||||
// global.releaseChannel is set in bootstrap
|
||||
global.crashReporterMetadata = crashReporter.metadata;
|
||||
|
||||
|
||||
const crashReporterSetup = require('./crashReporterSetup');
|
||||
|
||||
global.crashReporterMetadata = crashReporterSetup.metadata;
|
||||
global.mainAppDirname = Constants.MAIN_APP_DIRNAME;
|
||||
global.features = appFeatures.getFeatures();
|
||||
global.appSettings = appSettings();
|
||||
// this gets updated when launching a new main app window
|
||||
global.appSettings = appSettings.getSettings(); // this gets updated when launching a new main app window
|
||||
|
||||
global.mainWindowId = Constants.DEFAULT_MAIN_WINDOW_ID;
|
||||
global.moduleUpdater = moduleUpdater;
|
||||
|
||||
let applicationMenu = require('./applicationMenu');
|
||||
const applicationMenu = require('./applicationMenu');
|
||||
|
||||
if(appSettings().get("isTabs", false)){
|
||||
applicationMenu = applicationMenu.map(e => {
|
||||
|
@ -104,16 +145,14 @@ function startup(bootstrapModules) {
|
|||
})
|
||||
return e
|
||||
})
|
||||
Menu.setApplicationMenu(Menu.buildFromTemplate(applicationMenu));
|
||||
}else{
|
||||
Menu.setApplicationMenu(Menu.buildFromTemplate(applicationMenu));
|
||||
}
|
||||
|
||||
const ipc = require("./ipcMain") // TODO: Fix NEW_TAB
|
||||
const ipc = require("./ipcMain")
|
||||
ipc.on("NEW_TAB", () => {
|
||||
mainScreen.webContentsSend("NEW_TAB")
|
||||
})
|
||||
|
||||
Menu.setApplicationMenu(Menu.buildFromTemplate(applicationMenu));
|
||||
mainScreen = require('./mainScreen');
|
||||
|
||||
let version = bootstrapModules.Constants.version
|
||||
|
@ -181,10 +220,18 @@ function startup(bootstrapModules) {
|
|||
})
|
||||
})
|
||||
}
|
||||
|
||||
const {
|
||||
getWindow: getPopoutWindowByKey
|
||||
} = require('./popoutWindows');
|
||||
|
||||
windowNative.injectGetWindow(key => {
|
||||
return getPopoutWindowByKey(key) || BrowserWindow.fromId(mainScreen.getMainWindowId());
|
||||
});
|
||||
}
|
||||
|
||||
function handleSingleInstance(args) {
|
||||
mainScreen.handleSingleInstance(args);
|
||||
function handleOpenUrl(url) {
|
||||
mainScreen.handleOpenUrl(url);
|
||||
}
|
||||
|
||||
function setMainWindowVisible(visible) {
|
||||
|
|
|
@ -1,20 +1,16 @@
|
|||
'use strict';
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
|
||||
var _electron = require('electron');
|
||||
var _electron = require("electron");
|
||||
|
||||
exports.default = {
|
||||
on: (event, callback) => {
|
||||
_electron.ipcMain.on(`DISCORD_${event}`, callback)
|
||||
},
|
||||
removeListener: (event, callback) => {
|
||||
_electron.ipcMain.removeListener(`DISCORD_${event}`, callback)
|
||||
},
|
||||
reply: (event, channel, ...args) => {
|
||||
event.sender.send(`DISCORD_${channel}`, ...args)
|
||||
}
|
||||
var _default = {
|
||||
on: (event, callback) => _electron.ipcMain.on(`DISCORD_${event}`, callback),
|
||||
removeListener: (event, callback) => _electron.ipcMain.removeListener(`DISCORD_${event}`, callback),
|
||||
reply: (event, channel, ...args) => event.sender.send(`DISCORD_${channel}`, ...args)
|
||||
};
|
||||
exports.default = _default;
|
||||
module.exports = exports.default;
|
|
@ -1,4 +1,4 @@
|
|||
'use strict';
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
|
@ -6,10 +6,11 @@ Object.defineProperty(exports, "__esModule", {
|
|||
exports.getMainWindowId = getMainWindowId;
|
||||
exports.webContentsSend = webContentsSend;
|
||||
exports.init = init;
|
||||
exports.handleSingleInstance = handleSingleInstance;
|
||||
exports.handleOpenUrl = handleOpenUrl;
|
||||
exports.setMainWindowVisible = setMainWindowVisible;
|
||||
exports.setBlurType = setBlurType
|
||||
exports.setVibrancy = setVibrancy
|
||||
const events = exports.events = new (require("events").EventEmitter)()
|
||||
|
||||
const VIBRANCY_TYPES = [
|
||||
"titlebar",
|
||||
|
@ -33,127 +34,137 @@ const BLUR_TYPES = ["blurbehind", "acrylic", "transparent"]
|
|||
|
||||
var glasstron = require("glasstron")
|
||||
|
||||
var electron = require('electron');
|
||||
var _electron = require("electron");
|
||||
|
||||
var _path = require('path');
|
||||
var _fs = _interopRequireDefault(require("fs"));
|
||||
|
||||
var _url = require('url');
|
||||
var _path = _interopRequireDefault(require("path"));
|
||||
|
||||
var _Backoff = require('../common/Backoff');
|
||||
var _url = _interopRequireDefault(require("url"));
|
||||
|
||||
var _Backoff2 = _interopRequireDefault(_Backoff);
|
||||
var _Backoff = _interopRequireDefault(require("../common/Backoff"));
|
||||
|
||||
var _appBadge = require('./appBadge');
|
||||
var _securityUtils = require("../common/securityUtils");
|
||||
|
||||
var appBadge = _interopRequireWildcard(_appBadge);
|
||||
var appBadge = _interopRequireWildcard(require("./appBadge"));
|
||||
|
||||
var _appConfig = require('./appConfig');
|
||||
var appConfig = _interopRequireWildcard(require("./appConfig"));
|
||||
|
||||
var appConfig = _interopRequireWildcard(_appConfig);
|
||||
var _appSettings = require("./appSettings");
|
||||
|
||||
var _appSettings = require('./appSettings');
|
||||
var _buildInfo = _interopRequireDefault(require("./buildInfo"));
|
||||
|
||||
var _buildInfo = require('./buildInfo');
|
||||
var _ipcMain = _interopRequireDefault(require("./ipcMain"));
|
||||
|
||||
var _buildInfo2 = _interopRequireDefault(_buildInfo);
|
||||
var legacyModuleUpdater = _interopRequireWildcard(require("./moduleUpdater"));
|
||||
|
||||
var _ipcMain = require('./ipcMain');
|
||||
var _updater = _interopRequireDefault(require("./updater"));
|
||||
|
||||
var _ipcMain2 = _interopRequireDefault(_ipcMain);
|
||||
var notificationScreen = _interopRequireWildcard(require("./notificationScreen"));
|
||||
|
||||
var _moduleUpdater = require('./moduleUpdater');
|
||||
var paths = _interopRequireWildcard(require("./paths"));
|
||||
|
||||
var moduleUpdater = _interopRequireWildcard(_moduleUpdater);
|
||||
var popoutWindows = _interopRequireWildcard(require("./popoutWindows"));
|
||||
|
||||
var _notificationScreen = require('./notificationScreen');
|
||||
var splashScreen = _interopRequireWildcard(require("./splashScreen"));
|
||||
|
||||
var notificationScreen = _interopRequireWildcard(_notificationScreen);
|
||||
var systemTray = _interopRequireWildcard(require("./systemTray"));
|
||||
|
||||
var _popoutWindows = require('./popoutWindows');
|
||||
var _Constants = require("./Constants");
|
||||
|
||||
var popoutWindows = _interopRequireWildcard(_popoutWindows);
|
||||
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
|
||||
|
||||
var _systemTray = require('./systemTray');
|
||||
|
||||
var systemTray = _interopRequireWildcard(_systemTray);
|
||||
|
||||
var _Constants = require('./Constants');
|
||||
|
||||
const EventEmitter = require("events").EventEmitter
|
||||
|
||||
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
|
||||
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
const settings = _appSettings();
|
||||
const connectionBackoff = new _Backoff2.default(1000, 20000);
|
||||
const events = exports.events = new EventEmitter()
|
||||
const settings = (0, _appSettings.getSettings)();
|
||||
const connectionBackoff = new _Backoff.default(1000, 20000);
|
||||
const DISCORD_NAMESPACE = 'DISCORD_';
|
||||
|
||||
let isTabs = false
|
||||
function checkCanMigrate() {
|
||||
return _fs.default.existsSync(_path.default.join(paths.getUserData(), 'userDataCache.json'));
|
||||
}
|
||||
|
||||
function checkAlreadyMigrated() {
|
||||
return _fs.default.existsSync(_path.default.join(paths.getUserData(), 'domainMigrated'));
|
||||
}
|
||||
|
||||
const getWebappEndpoint = () => {
|
||||
isTabs = settings.get("isTabs", false)
|
||||
if(!isTabs){
|
||||
let endpoint = settings.get('WEBAPP_ENDPOINT');
|
||||
if (!endpoint) {
|
||||
if (_buildInfo2.default.releaseChannel === 'stable') {
|
||||
if (_buildInfo.default.releaseChannel === 'stable') {
|
||||
endpoint = 'https://discord.com';
|
||||
} else if (_buildInfo.default.releaseChannel === 'development') {
|
||||
endpoint = 'https://canary.discord.com';
|
||||
} else {
|
||||
endpoint = `https://${_buildInfo2.default.releaseChannel}.discord.com`;
|
||||
endpoint = `https://${_buildInfo.default.releaseChannel}.discord.com`;
|
||||
}
|
||||
}
|
||||
return endpoint;
|
||||
}else{
|
||||
return "file://"+_path.join(__dirname, "tabs", "index.html")
|
||||
return "file://"+_path.default.join(__dirname, "tabs", "index.html")
|
||||
}
|
||||
};
|
||||
|
||||
const WEBAPP_ENDPOINT = getWebappEndpoint();
|
||||
|
||||
function checkUrlOriginMatches(urlA, urlB) {
|
||||
let parsedUrlA;
|
||||
let parsedUrlB;
|
||||
|
||||
try {
|
||||
parsedUrlA = _url.default.parse(urlA);
|
||||
parsedUrlB = _url.default.parse(urlB);
|
||||
} catch (_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return parsedUrlA.protocol === parsedUrlB.protocol && parsedUrlA.slashes === parsedUrlB.slashes && parsedUrlA.host === parsedUrlB.host;
|
||||
}
|
||||
|
||||
function getSanitizedPath(path) {
|
||||
// using the whatwg URL api, get a sanitized pathname from given path
|
||||
// this is because url.parse's `path` may not always have a slash
|
||||
// in front of it
|
||||
return new _url.URL(path, WEBAPP_ENDPOINT).pathname;
|
||||
return new _url.default.URL(path, WEBAPP_ENDPOINT).pathname;
|
||||
}
|
||||
|
||||
function extractPathFromArgs(args, fallbackPath) {
|
||||
if (args.length === 3 && args[0] === '--url' && args[1] === '--') {
|
||||
function getSanitizedProtocolPath(url_) {
|
||||
try {
|
||||
const parsedURL = _url.parse(args[2]);
|
||||
const parsedURL = _url.default.parse(url_);
|
||||
|
||||
if (parsedURL.protocol === 'discord:') {
|
||||
return getSanitizedPath(parsedURL.path);
|
||||
}
|
||||
} catch (_) {} // protect against URIError: URI malformed
|
||||
}
|
||||
return fallbackPath;
|
||||
}
|
||||
|
||||
// TODO: These should probably be thrown in constants.
|
||||
const INITIAL_PATH = extractPathFromArgs(process.argv.slice(1), '/app');
|
||||
const WEBAPP_PATH = settings.get('WEBAPP_PATH', `${INITIAL_PATH}?_=${Date.now()}`);
|
||||
const URL_TO_LOAD = isTabs ? WEBAPP_ENDPOINT : `${WEBAPP_ENDPOINT}${WEBAPP_PATH}`;
|
||||
|
||||
return null;
|
||||
} // TODO: These should probably be thrown in constants.
|
||||
|
||||
|
||||
const WEBAPP_PATH = settings.get('WEBAPP_PATH', `/app?_=${Date.now()}`);
|
||||
const URL_TO_LOAD = `${WEBAPP_ENDPOINT}${WEBAPP_PATH}`;
|
||||
const MIN_WIDTH = settings.get('MIN_WIDTH', 940);
|
||||
const MIN_HEIGHT = settings.get('MIN_HEIGHT', 500);
|
||||
const DEFAULT_WIDTH = 1280;
|
||||
const DEFAULT_HEIGHT = 720;
|
||||
// TODO: document this var's purpose
|
||||
const MIN_VISIBLE_ON_SCREEN = 32;
|
||||
const DEFAULT_HEIGHT = 720; // TODO: document this var's purpose
|
||||
|
||||
/**
|
||||
* @type {electron.BrowserWindow}
|
||||
*/
|
||||
const MIN_VISIBLE_ON_SCREEN = 32;
|
||||
let mainWindow = null;
|
||||
let mainWindowId = _Constants.DEFAULT_MAIN_WINDOW_ID;
|
||||
let mainWindowInitialPath = null;
|
||||
let mainWindowDidFinishLoad = false; // whether we are in an intermediate auth process outside of our normal login screen (for e.g. internal builds)
|
||||
|
||||
// whether we are in an intermediate auth process outside of our normal login screen (for e.g. internal builds)
|
||||
let insideAuthFlow = false;
|
||||
let insideAuthFlow = false; // last time the main app renderer has crashed ('crashed' event)
|
||||
|
||||
// last time the main app renderer has crashed ('crashed' event)
|
||||
let lastCrashed = 0;
|
||||
|
||||
// whether we failed to load a page outside of the intermediate auth flow
|
||||
let lastCrashed = 0; // whether we failed to load a page outside of the intermediate auth flow
|
||||
// used to reload the page after a delay
|
||||
|
||||
let lastPageLoadFailed = false;
|
||||
|
||||
function getMainWindowId() {
|
||||
|
@ -177,6 +188,7 @@ function saveWindowConfig(browserWindow) {
|
|||
|
||||
settings.set('IS_MAXIMIZED', browserWindow.isMaximized());
|
||||
settings.set('IS_MINIMIZED', browserWindow.isMinimized());
|
||||
|
||||
if (!settings.get('IS_MAXIMIZED') && !settings.get('IS_MINIMIZED')) {
|
||||
settings.set('WINDOW_BOUNDS', browserWindow.getBounds());
|
||||
}
|
||||
|
@ -240,6 +252,7 @@ function setWindowVisible(isVisible, andUnminimize) {
|
|||
} else {
|
||||
webContentsSend('MAIN_WINDOW_BLUR');
|
||||
mainWindow.hide();
|
||||
|
||||
if (systemTray.hasInit) {
|
||||
systemTray.displayHowToCloseHint();
|
||||
}
|
||||
|
@ -252,36 +265,41 @@ function doAABBsOverlap(a, b) {
|
|||
const ax1 = a.x + a.width;
|
||||
const bx1 = b.x + b.width;
|
||||
const ay1 = a.y + a.height;
|
||||
const by1 = b.y + b.height;
|
||||
// clamp a to b, see if it is non-empty
|
||||
const by1 = b.y + b.height; // clamp a to b, see if it is non-empty
|
||||
|
||||
const cx0 = a.x < b.x ? b.x : a.x;
|
||||
const cx1 = ax1 < bx1 ? ax1 : bx1;
|
||||
|
||||
if (cx1 - cx0 > 0) {
|
||||
const cy0 = a.y < b.y ? b.y : a.y;
|
||||
const cy1 = ay1 < by1 ? ay1 : by1;
|
||||
|
||||
if (cy1 - cy0 > 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function applyWindowBoundsToConfig(mainWindowOptions) {
|
||||
const bounds = settings.get('WINDOW_BOUNDS')
|
||||
if (!bounds) {
|
||||
if (!settings.get('WINDOW_BOUNDS')) {
|
||||
mainWindowOptions.center = true;
|
||||
return;
|
||||
}
|
||||
|
||||
bounds.width = typeof bounds.width === "number" ? Math.max(MIN_WIDTH, bounds.width) : mainWindowOptions.width;
|
||||
bounds.height = typeof bounds.height === "number" ? Math.max(MIN_HEIGHT, bounds.height) : mainWindowOptions.height;
|
||||
|
||||
const bounds = settings.get('WINDOW_BOUNDS');
|
||||
bounds.width = Math.max(MIN_WIDTH, bounds.width);
|
||||
bounds.height = Math.max(MIN_HEIGHT, bounds.height);
|
||||
let isVisibleOnAnyScreen = false;
|
||||
const displays = electron.screen.getAllDisplays();
|
||||
|
||||
const displays = _electron.screen.getAllDisplays();
|
||||
|
||||
displays.forEach(display => {
|
||||
if (isVisibleOnAnyScreen) {
|
||||
return;
|
||||
}
|
||||
|
||||
const displayBound = display.workArea;
|
||||
displayBound.x += MIN_VISIBLE_ON_SCREEN;
|
||||
displayBound.y += MIN_VISIBLE_ON_SCREEN;
|
||||
|
@ -298,10 +316,10 @@ function applyWindowBoundsToConfig(mainWindowOptions) {
|
|||
} else {
|
||||
mainWindowOptions.center = true;
|
||||
}
|
||||
}
|
||||
|
||||
// this can be called multiple times (due to recreating the main app window),
|
||||
} // this can be called multiple times (due to recreating the main app window),
|
||||
// so we only want to update existing if we already initialized it
|
||||
|
||||
|
||||
function setupNotificationScreen(mainWindow) {
|
||||
if (!notificationScreen.hasInit) {
|
||||
notificationScreen.init({
|
||||
|
@ -310,21 +328,28 @@ function setupNotificationScreen(mainWindow) {
|
|||
maxVisible: 5,
|
||||
screenPosition: 'bottom'
|
||||
});
|
||||
|
||||
notificationScreen.events.on(notificationScreen.NOTIFICATION_CLICK, () => {
|
||||
setWindowVisible(true, true);
|
||||
});
|
||||
} else {
|
||||
notificationScreen.setMainWindow(mainWindow);
|
||||
}
|
||||
}
|
||||
|
||||
// this can be called multiple times (due to recreating the main app window),
|
||||
} // this can be called multiple times (due to recreating the main app window),
|
||||
// so we only want to update existing if we already initialized it
|
||||
|
||||
|
||||
function setupSystemTray() {
|
||||
if (!systemTray.hasInit) {
|
||||
systemTray.init({
|
||||
onCheckForUpdates: () => moduleUpdater.checkForUpdates(),
|
||||
onCheckForUpdates: () => {
|
||||
const updater = _updater.default === null || _updater.default === void 0 ? void 0 : _updater.default.getUpdater();
|
||||
|
||||
if (updater != null) {
|
||||
checkForUpdatesWithUpdater(updater);
|
||||
} else {
|
||||
legacyModuleUpdater.checkForUpdates();
|
||||
}
|
||||
},
|
||||
onTrayClicked: () => setWindowVisible(true, true),
|
||||
onOpenVoiceSettings: openVoiceSettings,
|
||||
onToggleMute: toggleMute,
|
||||
|
@ -332,26 +357,26 @@ function setupSystemTray() {
|
|||
onLaunchApplication: launchApplication
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// this can be called multiple times (due to recreating the main app window),
|
||||
} // this can be called multiple times (due to recreating the main app window),
|
||||
// so we only want to update existing if we already initialized it
|
||||
|
||||
|
||||
function setupAppBadge() {
|
||||
if (!appBadge.hasInit) {
|
||||
appBadge.init();
|
||||
}
|
||||
}
|
||||
|
||||
// this can be called multiple times (due to recreating the main app window),
|
||||
} // this can be called multiple times (due to recreating the main app window),
|
||||
// so we only want to update existing if we already initialized it
|
||||
|
||||
|
||||
function setupAppConfig() {
|
||||
if (!appConfig.hasInit) {
|
||||
appConfig.init();
|
||||
}
|
||||
}
|
||||
|
||||
// this can be called multiple times (due to recreating the main app window),
|
||||
} // this can be called multiple times (due to recreating the main app window),
|
||||
// so we only want to update existing if we already initialized it
|
||||
|
||||
|
||||
function setupPopouts() {
|
||||
if (!popoutWindows.hasInit) {
|
||||
popoutWindows.init();
|
||||
|
@ -391,13 +416,12 @@ function setBackgroundColor(color) {
|
|||
settings.set(BACKGROUND_COLOR_KEY, color);
|
||||
//mainWindow.setBackgroundColor(color);
|
||||
settings.save();
|
||||
}
|
||||
} // launch main app window; could be called multiple times for various reasons
|
||||
|
||||
|
||||
// launch main app window; could be called multiple times for various reasons
|
||||
function launchMainAppWindow(isVisible) {
|
||||
if (mainWindow) {
|
||||
// TODO: message here?
|
||||
console.log("[MainScreen] Destroying window "+mainWindow.id)
|
||||
mainWindow.destroy();
|
||||
}
|
||||
|
||||
|
@ -416,16 +440,22 @@ function launchMainAppWindow(isVisible) {
|
|||
nativeWindowOpen: true,
|
||||
enableRemoteModule: true,
|
||||
spellcheck: true,
|
||||
contextIsolation: false,
|
||||
...(isTabs ? {
|
||||
nodeIntegration: true,
|
||||
webviewTag: true
|
||||
} : {
|
||||
nodeIntegration: false,
|
||||
webviewTag: false,
|
||||
preload: _path.join(__dirname, 'mainScreenPreload.js')
|
||||
})
|
||||
contextIsolation: true,
|
||||
preload: _path.default.join(__dirname, 'mainScreenPreload.js')
|
||||
}),
|
||||
// NB: this is required in order to give popouts (or any child window opened via window.open w/ nativeWindowOpen)
|
||||
// a chance at a node environment (i.e. they run the preload, have an isolated context, etc.) when
|
||||
// `app.allowRendererProcessReuse === false` (default in Electron 7).
|
||||
additionalArguments: ['--enable-node-leakage-in-renderers']
|
||||
},
|
||||
icon: _path.join(__dirname, "images", 'discord.png')
|
||||
icon: _path.default.join(__dirname, "images", 'discord.png')
|
||||
};
|
||||
|
||||
if (process.platform === 'linux') {
|
||||
|
@ -435,7 +465,7 @@ function launchMainAppWindow(isVisible) {
|
|||
if(!settings.get("NO_WINDOWS_BOUND", false))applyWindowBoundsToConfig(mainWindowOptions);
|
||||
|
||||
const useGlasstron = settings.get("GLASSTRON", true)
|
||||
const BrowserWindow = useGlasstron ? glasstron.BrowserWindow : electron.BrowserWindow
|
||||
const BrowserWindow = useGlasstron ? glasstron.BrowserWindow : _electron.BrowserWindow
|
||||
mainWindow = new BrowserWindow(mainWindowOptions);
|
||||
mainWindowId = mainWindow.id;
|
||||
global.mainWindowId = mainWindowId;
|
||||
|
@ -463,13 +493,14 @@ function launchMainAppWindow(isVisible) {
|
|||
|
||||
mainWindow.webContents.on('new-window', (e, windowURL, frameName, disposition, options) => {
|
||||
e.preventDefault();
|
||||
if (frameName.startsWith(DISCORD_NAMESPACE) && windowURL.startsWith(WEBAPP_ENDPOINT)) {
|
||||
popoutWindows.openOrFocusWindow(e, windowURL, frameName, options);
|
||||
} else {
|
||||
electron.shell.openExternal(windowURL);
|
||||
}
|
||||
});
|
||||
|
||||
if (frameNames.tartsWith(DISCORD_NAMESPACE) && checkUrlOriginMatches(windowURL, WEBAPP_ENDPOINT) && getSanitizedPath(windowURL) === '/popout') {
|
||||
popoutWindows.openOrFocusWindow(e, windowURL, frameName, options);
|
||||
return;
|
||||
}
|
||||
|
||||
(0, _securityUtils.saferShellOpenExternal)(windowURL);
|
||||
});
|
||||
mainWindow.webContents.on('did-fail-load', (e, errCode, errDesc, validatedUrl) => {
|
||||
if (insideAuthFlow) {
|
||||
return;
|
||||
|
@ -477,12 +508,11 @@ function launchMainAppWindow(isVisible) {
|
|||
|
||||
if (validatedUrl !== URL_TO_LOAD) {
|
||||
return;
|
||||
}
|
||||
|
||||
// -3 (ABORTED) means we are reloading the page before it has finished loading
|
||||
} // -3 (ABORTED) means we are reloading the page before it has finished loading
|
||||
// 0 (???) seems to also mean the same thing
|
||||
if (errCode === -3 || errCode === 0) return;
|
||||
|
||||
|
||||
if (errCode === -3 || errCode === 0) return;
|
||||
lastPageLoadFailed = true;
|
||||
console.error('[WebContents] did-fail-load', errCode, errDesc, `retry in ${connectionBackoff.current} ms`);
|
||||
connectionBackoff.fail(() => {
|
||||
|
@ -490,12 +520,18 @@ function launchMainAppWindow(isVisible) {
|
|||
loadMainPage();
|
||||
});
|
||||
});
|
||||
|
||||
mainWindow.webContents.on('did-finish-load', () => {
|
||||
if (insideAuthFlow && mainWindow.webContents && mainWindow.webContents.getURL().startsWith(WEBAPP_ENDPOINT)) {
|
||||
if (insideAuthFlow && mainWindow.webContents && checkUrlOriginMatches(mainWindow.webContents.getURL(), WEBAPP_ENDPOINT)) {
|
||||
insideAuthFlow = false;
|
||||
}
|
||||
|
||||
mainWindowDidFinishLoad = true; // if this is a first open and there's an initial path, direct user to that path
|
||||
|
||||
if (mainWindowInitialPath != null) {
|
||||
webContentsSend('MAIN_WINDOW_PATH', mainWindowInitialPath);
|
||||
mainWindowInitialPath = null;
|
||||
}
|
||||
|
||||
webContentsSend(mainWindow != null && mainWindow.isFocused() ? 'MAIN_WINDOW_FOCUS' : 'MAIN_WINDOW_BLUR');
|
||||
|
||||
if (!lastPageLoadFailed) {
|
||||
|
@ -503,75 +539,114 @@ function launchMainAppWindow(isVisible) {
|
|||
}
|
||||
events.emit("ready")
|
||||
});
|
||||
|
||||
mainWindow.webContents.on('crashed', (e, killed) => {
|
||||
if (killed) {
|
||||
electron.app.quit();
|
||||
_electron.app.quit();
|
||||
|
||||
return;
|
||||
} // if we just crashed under 5 seconds ago, we are probably in a loop, so just die.
|
||||
|
||||
|
||||
const crashTime = Date.now();
|
||||
|
||||
if (crashTime - lastCrashed < 5 * 1000) {
|
||||
console.error('[WebContents] double crashed... RIP =(');
|
||||
|
||||
_electron.app.quit();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// if we just crashed under 5 seconds ago, we are probably in a loop, so just die.
|
||||
const crashTime = Date.now();
|
||||
if (crashTime - lastCrashed < 5 * 1000) {
|
||||
console.error('[WebContents] double crashed... RIP =(');
|
||||
electron.app.quit();
|
||||
return;
|
||||
}
|
||||
lastCrashed = crashTime;
|
||||
console.error('[WebContents] crashed... reloading');
|
||||
launchMainAppWindow(true);
|
||||
});
|
||||
|
||||
// Prevent navigation when links or files are dropping into the app, turning it into a browser.
|
||||
}); // Prevent navigation when links or files are dropping into the app, turning it into a browser.
|
||||
// https://github.com/discord/discord/pull/278
|
||||
|
||||
mainWindow.webContents.on('will-navigate', (evt, url) => {
|
||||
if (!insideAuthFlow && !url.startsWith(WEBAPP_ENDPOINT)) {
|
||||
if (!insideAuthFlow && !checkUrlOriginMatches(url, WEBAPP_ENDPOINT)) {
|
||||
evt.preventDefault();
|
||||
}
|
||||
});
|
||||
}); // track intermediate auth flow
|
||||
|
||||
// track intermediate auth flow
|
||||
mainWindow.webContents.on('did-get-redirect-request', (event, oldUrl, newUrl) => {
|
||||
if (oldUrl.startsWith(WEBAPP_ENDPOINT) && newUrl.startsWith('https://accounts.google.com/')) {
|
||||
if (checkUrlOriginMatches(oldUrl, WEBAPP_ENDPOINT) && checkUrlOriginMatches(newUrl, 'https://accounts.google.com/')) {
|
||||
insideAuthFlow = true;
|
||||
}
|
||||
});
|
||||
|
||||
mainWindow.webContents.on('context-menu', (_, params) => {
|
||||
webContentsSend('SPELLCHECK_RESULT', params.misspelledWord, params.dictionarySuggestions);
|
||||
});
|
||||
|
||||
mainWindow.webContents.on('devtools-opened', () => {
|
||||
webContentsSend('WINDOW_DEVTOOLS_OPENED');
|
||||
});
|
||||
|
||||
mainWindow.webContents.on('devtools-closed', () => {
|
||||
webContentsSend('WINDOW_DEVTOOLS_CLOSED');
|
||||
});
|
||||
|
||||
mainWindow.on('focus', () => {
|
||||
webContentsSend('MAIN_WINDOW_FOCUS');
|
||||
});
|
||||
|
||||
mainWindow.on('blur', () => {
|
||||
webContentsSend('MAIN_WINDOW_BLUR');
|
||||
});
|
||||
|
||||
mainWindow.on('page-title-updated', (e, title) => {
|
||||
if (mainWindow === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
if (!title.endsWith('Lightcord')) {
|
||||
title += ' - Lightcord';
|
||||
}
|
||||
|
||||
mainWindow.setTitle(title);
|
||||
});
|
||||
|
||||
mainWindow.on('leave-html-full-screen', () => {
|
||||
// fixes a bug wherein embedded videos returning from full screen cause our menu to be visible.
|
||||
mainWindow.setMenuBarVisibility(false);
|
||||
});
|
||||
mainWindow.webContents.on('did-navigate-in-page', (_, eventUrl) => {
|
||||
let parsedUrl;
|
||||
|
||||
try {
|
||||
parsedUrl = _url.default.parse(eventUrl);
|
||||
} catch (_) {
|
||||
return;
|
||||
} // Prevent back navigation from revisting the login page after logging in,
|
||||
// or being able to navigate back after signing out.
|
||||
|
||||
|
||||
if (parsedUrl && parsedUrl.pathname === '/login') {
|
||||
mainWindow.webContents.clearHistory();
|
||||
}
|
||||
}); // 'swipe' only works if the classic 3 finger swipe style is enabled in
|
||||
// 'System Preferences > Trackpad > More Gestures.' The more modern 2 finger
|
||||
// gesture should be added when Electron adds support.
|
||||
|
||||
mainWindow.on('swipe', (_, direction) => {
|
||||
switch (direction) {
|
||||
case 'left':
|
||||
webContentsSend('NAVIGATE_BACK', 'SWIPE');
|
||||
break;
|
||||
|
||||
case 'right':
|
||||
webContentsSend('NAVIGATE_FORWARD', 'SWIPE');
|
||||
break;
|
||||
}
|
||||
}); // Windows/Linux media keys and 4th/5th mouse buttons.
|
||||
|
||||
mainWindow.on('app-command', (_, cmd) => {
|
||||
switch (cmd) {
|
||||
case 'browser-backward':
|
||||
webContentsSend('NAVIGATE_BACK', 'BROWSER');
|
||||
break;
|
||||
|
||||
case 'browser-forward':
|
||||
webContentsSend('NAVIGATE_FORWARD', 'BROWSER');
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
if (process.platform === 'win32') {
|
||||
setupNotificationScreen(mainWindow);
|
||||
|
@ -584,25 +659,24 @@ function launchMainAppWindow(isVisible) {
|
|||
|
||||
if (process.platform === 'linux' || process.platform === 'win32') {
|
||||
systemTray.show();
|
||||
|
||||
mainWindow.on('close', e => {
|
||||
if (mainWindow === null) {
|
||||
// this means we're quitting
|
||||
popoutWindows.closePopouts();
|
||||
return;
|
||||
}
|
||||
webContentsSend('MAIN_WINDOW_BLUR');
|
||||
|
||||
// Save our app settings
|
||||
saveWindowConfig(mainWindow);
|
||||
webContentsSend('MAIN_WINDOW_BLUR'); // Save our app settings
|
||||
|
||||
saveWindowConfig(mainWindow); // Quit app if that's the setting
|
||||
|
||||
// Quit app if that's the setting
|
||||
if (!settings.get('MINIMIZE_TO_TRAY', true)) {
|
||||
electron.app.quit();
|
||||
return;
|
||||
}
|
||||
_electron.app.quit();
|
||||
|
||||
return;
|
||||
} // Else, minimize to tray
|
||||
|
||||
|
||||
// Else, minimize to tray
|
||||
setWindowVisible(false);
|
||||
e.preventDefault();
|
||||
});
|
||||
|
@ -627,6 +701,7 @@ function handleModuleUpdateCheckFinished(succeeded, updateCount, manualRequired)
|
|||
} else {
|
||||
updaterState = _Constants.UpdaterEvents.UPDATE_AVAILABLE;
|
||||
}
|
||||
|
||||
webContentsSend(updaterState);
|
||||
}
|
||||
|
||||
|
@ -634,6 +709,7 @@ function handleModuleUpdateDownloadProgress(name, progress) {
|
|||
if (mainWindow) {
|
||||
mainWindow.setProgressBar(progress);
|
||||
}
|
||||
|
||||
webContentsSend(_Constants.UpdaterEvents.MODULE_INSTALL_PROGRESS, name, progress);
|
||||
}
|
||||
|
||||
|
@ -657,93 +733,171 @@ function handleModuleUpdateInstalledModule(name, current, total, succeeded) {
|
|||
if (mainWindow) {
|
||||
mainWindow.setProgressBar(-1);
|
||||
}
|
||||
|
||||
webContentsSend(_Constants.UpdaterEvents.MODULE_INSTALLED, name, succeeded);
|
||||
}
|
||||
|
||||
// sets up event listeners between the browser window and the app to send
|
||||
// and listen to update-related events
|
||||
function setupUpdaterIPC() {
|
||||
moduleUpdater.events.on(moduleUpdater.CHECKING_FOR_UPDATES, () => {
|
||||
updaterState = _Constants.UpdaterEvents.CHECKING_FOR_UPDATES;
|
||||
function setUpdaterState(newUpdaterState) {
|
||||
updaterState = newUpdaterState;
|
||||
webContentsSend(updaterState);
|
||||
}
|
||||
|
||||
async function checkForUpdatesWithUpdater(updater) {
|
||||
if (updaterState === _Constants.UpdaterEvents.UPDATE_NOT_AVAILABLE) {
|
||||
setUpdaterState(_Constants.UpdaterEvents.CHECKING_FOR_UPDATES);
|
||||
|
||||
try {
|
||||
let installedAnything = false;
|
||||
await updater.updateToLatest(progress => {
|
||||
const task = progress.task.HostInstall || progress.task.ModuleInstall;
|
||||
|
||||
if (task != null && progress.state === 'Complete') {
|
||||
if (!installedAnything) {
|
||||
installedAnything = true;
|
||||
setUpdaterState(_Constants.UpdaterEvents.UPDATE_AVAILABLE);
|
||||
}
|
||||
}
|
||||
});
|
||||
setUpdaterState(installedAnything ? _Constants.UpdaterEvents.UPDATE_DOWNLOADED : _Constants.UpdaterEvents.UPDATE_NOT_AVAILABLE);
|
||||
} catch (e) {
|
||||
console.error('Update to latest failed: ', e);
|
||||
updaterState = _Constants.UpdaterEvents.UPDATE_NOT_AVAILABLE;
|
||||
webContentsSend(_Constants.UpdaterEvents.UPDATE_FAILED);
|
||||
}
|
||||
} else {
|
||||
webContentsSend(updaterState);
|
||||
}
|
||||
} // Setup handling of events related to updates using the new updater.
|
||||
|
||||
|
||||
function setupUpdaterEventsWithUpdater(updater) {
|
||||
_electron.app.on(_Constants.MenuEvents.CHECK_FOR_UPDATES, () => checkForUpdatesWithUpdater());
|
||||
|
||||
_ipcMain.default.on(_Constants.UpdaterEvents.CHECK_FOR_UPDATES, () => {
|
||||
return checkForUpdatesWithUpdater(updater);
|
||||
});
|
||||
|
||||
// TODO(eiz): We currently still need to handle the old style non-object-based
|
||||
_ipcMain.default.on(_Constants.UpdaterEvents.QUIT_AND_INSTALL, () => {
|
||||
saveWindowConfig(mainWindow);
|
||||
mainWindow = null; // TODO(eiz): This is a workaround for old Linux host versions whose host
|
||||
// updater did not have a quitAndInstall() method, which causes the module
|
||||
// updater to crash if a host update is available and we try to restart to
|
||||
// install modules. Remove when all hosts are updated.
|
||||
|
||||
try {
|
||||
legacyModuleUpdater.quitAndInstallUpdates();
|
||||
} catch (e) {
|
||||
_electron.app.relaunch();
|
||||
|
||||
_electron.app.quit();
|
||||
}
|
||||
});
|
||||
|
||||
_ipcMain.default.on(_Constants.UpdaterEvents.UPDATER_HISTORY_QUERY_AND_TRUNCATE, () => {
|
||||
if (updater.queryAndTruncateHistory != null) {
|
||||
webContentsSend(_Constants.UpdaterEvents.UPDATER_HISTORY_RESPONSE, updater.queryAndTruncateHistory());
|
||||
} else {
|
||||
webContentsSend(_Constants.UpdaterEvents.UPDATER_HISTORY_RESPONSE, []);
|
||||
}
|
||||
});
|
||||
} // Setup events related to updates using the old module updater.
|
||||
//
|
||||
// sets up event listeners between the browser window and the app to send
|
||||
// and listen to update-related events
|
||||
|
||||
|
||||
function setupLegacyUpdaterEvents() {
|
||||
_electron.app.on(_Constants.MenuEvents.CHECK_FOR_UPDATES, () => legacyModuleUpdater.checkForUpdates());
|
||||
|
||||
legacyModuleUpdater.events.on(legacyModuleUpdater.CHECKING_FOR_UPDATES, () => {
|
||||
updaterState = _Constants.UpdaterEvents.CHECKING_FOR_UPDATES;
|
||||
webContentsSend(updaterState);
|
||||
}); // TODO(eiz): We currently still need to handle the old style non-object-based
|
||||
// updater events to allow discord_desktop_core to be newer than the host asar,
|
||||
// which contains the updater itself.
|
||||
//
|
||||
// Once all clients have updated to a sufficiently new host, we can delete this.
|
||||
if (moduleUpdater.supportsEventObjects) {
|
||||
moduleUpdater.events.on(moduleUpdater.UPDATE_CHECK_FINISHED, ({ succeeded, updateCount, manualRequired }) => {
|
||||
|
||||
if (legacyModuleUpdater.supportsEventObjects) {
|
||||
legacyModuleUpdater.events.on(legacyModuleUpdater.UPDATE_CHECK_FINISHED, ({
|
||||
succeeded,
|
||||
updateCount,
|
||||
manualRequired
|
||||
}) => {
|
||||
handleModuleUpdateCheckFinished(succeeded, updateCount, manualRequired);
|
||||
});
|
||||
|
||||
moduleUpdater.events.on(moduleUpdater.DOWNLOADING_MODULE_PROGRESS, ({ name, progress }) => {
|
||||
legacyModuleUpdater.events.on(legacyModuleUpdater.DOWNLOADING_MODULE_PROGRESS, ({
|
||||
name,
|
||||
progress
|
||||
}) => {
|
||||
handleModuleUpdateDownloadProgress(name, progress);
|
||||
});
|
||||
|
||||
moduleUpdater.events.on(moduleUpdater.DOWNLOADING_MODULES_FINISHED, ({ succeeded, failed }) => {
|
||||
legacyModuleUpdater.events.on(legacyModuleUpdater.DOWNLOADING_MODULES_FINISHED, ({
|
||||
succeeded,
|
||||
failed
|
||||
}) => {
|
||||
handleModuleUpdateDownloadsFinished(succeeded, failed);
|
||||
});
|
||||
|
||||
moduleUpdater.events.on(moduleUpdater.INSTALLED_MODULE, ({ name, current, total, succeeded }) => {
|
||||
legacyModuleUpdater.events.on(legacyModuleUpdater.INSTALLED_MODULE, ({
|
||||
name,
|
||||
current,
|
||||
total,
|
||||
succeeded
|
||||
}) => {
|
||||
handleModuleUpdateInstalledModule(name, current, total, succeeded);
|
||||
});
|
||||
} else {
|
||||
moduleUpdater.events.on(moduleUpdater.UPDATE_CHECK_FINISHED, (succeeded, updateCount, manualRequired) => {
|
||||
legacyModuleUpdater.events.on(legacyModuleUpdater.UPDATE_CHECK_FINISHED, (succeeded, updateCount, manualRequired) => {
|
||||
handleModuleUpdateCheckFinished(succeeded, updateCount, manualRequired);
|
||||
});
|
||||
|
||||
moduleUpdater.events.on(moduleUpdater.DOWNLOADING_MODULE_PROGRESS, (name, progress) => {
|
||||
legacyModuleUpdater.events.on(legacyModuleUpdater.DOWNLOADING_MODULE_PROGRESS, (name, progress) => {
|
||||
handleModuleUpdateDownloadProgress(name, progress);
|
||||
});
|
||||
|
||||
moduleUpdater.events.on(moduleUpdater.DOWNLOADING_MODULES_FINISHED, (succeeded, failed) => {
|
||||
legacyModuleUpdater.events.on(legacyModuleUpdater.DOWNLOADING_MODULES_FINISHED, (succeeded, failed) => {
|
||||
handleModuleUpdateDownloadsFinished(succeeded, failed);
|
||||
});
|
||||
|
||||
moduleUpdater.events.on(moduleUpdater.INSTALLED_MODULE, (name, current, total, succeeded) => {
|
||||
legacyModuleUpdater.events.on(legacyModuleUpdater.INSTALLED_MODULE, (name, current, total, succeeded) => {
|
||||
handleModuleUpdateInstalledModule(name, current, total, succeeded);
|
||||
});
|
||||
}
|
||||
|
||||
_ipcMain2.default.on(_Constants.UpdaterEvents.CHECK_FOR_UPDATES, () => {
|
||||
_ipcMain.default.on(_Constants.UpdaterEvents.CHECK_FOR_UPDATES, () => {
|
||||
if (updaterState === _Constants.UpdaterEvents.UPDATE_NOT_AVAILABLE) {
|
||||
moduleUpdater.checkForUpdates();
|
||||
legacyModuleUpdater.checkForUpdates();
|
||||
} else {
|
||||
webContentsSend(updaterState);
|
||||
}
|
||||
});
|
||||
|
||||
_ipcMain2.default.on(_Constants.UpdaterEvents.QUIT_AND_INSTALL, () => {
|
||||
_ipcMain.default.on(_Constants.UpdaterEvents.QUIT_AND_INSTALL, () => {
|
||||
saveWindowConfig(mainWindow);
|
||||
mainWindow = null;
|
||||
|
||||
// TODO(eiz): This is a workaround for old Linux host versions whose host
|
||||
mainWindow = null; // TODO(eiz): This is a workaround for old Linux host versions whose host
|
||||
// updater did not have a quitAndInstall() method, which causes the module
|
||||
// updater to crash if a host update is available and we try to restart to
|
||||
// install modules. Remove when all hosts are updated.
|
||||
|
||||
try {
|
||||
moduleUpdater.quitAndInstallUpdates();
|
||||
legacyModuleUpdater.quitAndInstallUpdates();
|
||||
} catch (e) {
|
||||
electron.app.relaunch();
|
||||
electron.app.quit();
|
||||
_electron.app.relaunch();
|
||||
|
||||
_electron.app.quit();
|
||||
}
|
||||
});
|
||||
|
||||
_ipcMain2.default.on(_Constants.UpdaterEvents.MODULE_INSTALL, (_event, name) => {
|
||||
_ipcMain.default.on(_Constants.UpdaterEvents.MODULE_INSTALL, (_event, name) => {
|
||||
// NOTE: do NOT allow options to be passed in, as this enables a client to downgrade its modules to potentially
|
||||
// insecure versions.
|
||||
moduleUpdater.install(name, false);
|
||||
legacyModuleUpdater.install(name, false);
|
||||
});
|
||||
|
||||
_ipcMain2.default.on(_Constants.UpdaterEvents.MODULE_QUERY, (_event, name) => {
|
||||
webContentsSend(_Constants.UpdaterEvents.MODULE_INSTALLED, name, moduleUpdater.isInstalled(name));
|
||||
_ipcMain.default.on(_Constants.UpdaterEvents.MODULE_QUERY, (_event, name) => {
|
||||
webContentsSend(_Constants.UpdaterEvents.MODULE_INSTALLED, name, legacyModuleUpdater.isInstalled(name));
|
||||
});
|
||||
|
||||
_ipcMain2.default.on(_Constants.UpdaterEvents.UPDATER_HISTORY_QUERY_AND_TRUNCATE, () => {
|
||||
webContentsSend(_Constants.UpdaterEvents.UPDATER_HISTORY_RESPONSE, moduleUpdater.events.history);
|
||||
moduleUpdater.events.history = [];
|
||||
_ipcMain.default.on(_Constants.UpdaterEvents.UPDATER_HISTORY_QUERY_AND_TRUNCATE, () => {
|
||||
webContentsSend(_Constants.UpdaterEvents.UPDATER_HISTORY_RESPONSE, legacyModuleUpdater.events.history);
|
||||
legacyModuleUpdater.events.history = [];
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -751,46 +905,82 @@ function init() {
|
|||
// electron default behavior is to app.quit here, so long as there are no other listeners. we handle quitting
|
||||
// or minimizing to system tray ourselves via mainWindow.on('closed') so this is simply to disable the electron
|
||||
// default behavior.
|
||||
electron.app.on('window-all-closed', () => {});
|
||||
_electron.app.on('window-all-closed', () => {});
|
||||
|
||||
electron.app.on('before-quit', () => {
|
||||
_electron.app.on('before-quit', () => {
|
||||
saveWindowConfig(mainWindow);
|
||||
mainWindow = null;
|
||||
notificationScreen.close();
|
||||
});
|
||||
}); // TODO: move this to main startup
|
||||
|
||||
// TODO: move this to main startup
|
||||
electron.app.on('gpu-process-crashed', (e, killed) => {
|
||||
|
||||
_electron.app.on('gpu-process-crashed', (e, killed) => {
|
||||
if (killed) {
|
||||
electron.app.quit();
|
||||
_electron.app.quit();
|
||||
}
|
||||
});
|
||||
|
||||
electron.app.on('accessibility-support-changed', (_event, accessibilitySupportEnabled) => webContentsSend('ACCESSIBILITY_SUPPORT_CHANGED', accessibilitySupportEnabled));
|
||||
_electron.app.on('accessibility-support-changed', (_event, accessibilitySupportEnabled) => webContentsSend('ACCESSIBILITY_SUPPORT_CHANGED', accessibilitySupportEnabled));
|
||||
|
||||
electron.app.on(_Constants.MenuEvents.OPEN_HELP, () => webContentsSend('HELP_OPEN'));
|
||||
electron.app.on(_Constants.MenuEvents.OPEN_SETTINGS, () => webContentsSend('USER_SETTINGS_OPEN'));
|
||||
electron.app.on(_Constants.MenuEvents.CHECK_FOR_UPDATES, () => moduleUpdater.checkForUpdates());
|
||||
_electron.app.on(_Constants.MenuEvents.OPEN_HELP, () => webContentsSend('HELP_OPEN'));
|
||||
|
||||
_ipcMain2.default.on('SETTINGS_UPDATE_BACKGROUND_COLOR', (_event, backgroundColor) => {
|
||||
_electron.app.on(_Constants.MenuEvents.OPEN_SETTINGS, () => webContentsSend('USER_SETTINGS_OPEN')); // TODO: this hotpatches an issue with focusing the app from background.
|
||||
// delete this after next stable electron release.
|
||||
|
||||
|
||||
_electron.app.on('second-instance', (_event, args) => {
|
||||
// if the second instance is the uninstaller, the bootstrap listener will quit the running app
|
||||
if (args != null && args.indexOf('--squirrel-uninstall') > -1) {
|
||||
return;
|
||||
} // if the current instance is multi instance, we want to leave the window alone
|
||||
|
||||
|
||||
if (process.argv != null && process.argv.slice(1).includes('--multi-instance')) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mainWindow == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
setWindowVisible(true, false);
|
||||
mainWindow.focus();
|
||||
});
|
||||
|
||||
_ipcMain.default.on('SETTINGS_UPDATE_BACKGROUND_COLOR', (_event, backgroundColor) => {
|
||||
if (getBackgroundColor() !== backgroundColor) {
|
||||
setBackgroundColor(backgroundColor);
|
||||
}
|
||||
});
|
||||
|
||||
setupUpdaterIPC();
|
||||
const updater = _updater.default === null || _updater.default === void 0 ? void 0 : _updater.default.getUpdater();
|
||||
|
||||
if (updater != null) {
|
||||
setupUpdaterEventsWithUpdater(updater);
|
||||
} else {
|
||||
setupLegacyUpdaterEvents();
|
||||
}
|
||||
|
||||
launchMainAppWindow(false);
|
||||
}
|
||||
|
||||
function handleSingleInstance(args) {
|
||||
if (mainWindow != null) {
|
||||
const appPath = extractPathFromArgs(args);
|
||||
if (appPath != null) {
|
||||
webContentsSend('MAIN_WINDOW_PATH', appPath);
|
||||
function handleOpenUrl(url) {
|
||||
const path = getSanitizedProtocolPath(url);
|
||||
|
||||
if (path != null) {
|
||||
if (!mainWindowDidFinishLoad) {
|
||||
mainWindowInitialPath = path;
|
||||
}
|
||||
|
||||
webContentsSend('MAIN_WINDOW_PATH', path);
|
||||
}
|
||||
|
||||
if (mainWindow == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
setWindowVisible(true, false);
|
||||
mainWindow.focus();
|
||||
}
|
||||
}
|
||||
|
||||
function setMainWindowVisible(visible) {
|
||||
|
|
|
@ -1,7 +1,15 @@
|
|||
'use strict';
|
||||
"use strict";
|
||||
|
||||
if (!process.isMainFrame) {
|
||||
throw new Error('Preload scripts should not be running in a subframe');
|
||||
}
|
||||
|
||||
if (window.opener === null) {
|
||||
// App preload script, used to provide a replacement native API now that
|
||||
// we turned off node integration.
|
||||
const {
|
||||
contextBridge
|
||||
} = require("electron")
|
||||
|
||||
process.on("uncaughtException", console.error)
|
||||
|
||||
|
@ -9,28 +17,14 @@ const ipcRenderer = require('./discord_native/renderer/ipc');
|
|||
const electron = require("electron")
|
||||
const moduleAlias = require("./BetterDiscord/loaders/module-alias")
|
||||
const path = require("path")
|
||||
const Buffer = require("safe-buffer").Buffer
|
||||
|
||||
moduleAlias.setMain(module)
|
||||
moduleAlias.addAlias("@lightcord/api", path.join(__dirname, "../../../../LightcordApi"))
|
||||
moduleAlias.addAlias("lightcordapi", path.join(__dirname, "../../../../LightcordApi"))
|
||||
moduleAlias.addPath(path.join(__dirname, "BetterDiscord", "modules"))
|
||||
|
||||
const TRACK_ANALYTICS_EVENT = 'TRACK_ANALYTICS_EVENT';
|
||||
const TRACK_ANALYTICS_EVENT_COMMIT = 'TRACK_ANALYTICS_EVENT_COMMIT';
|
||||
|
||||
// We don't care about logging these anymore.
|
||||
// just commit so that they don't back up on disk.
|
||||
ipcRenderer.on(TRACK_ANALYTICS_EVENT, e => {
|
||||
e.sender.send(TRACK_ANALYTICS_EVENT_COMMIT);
|
||||
});
|
||||
|
||||
global.isTab = !!global.isTab
|
||||
|
||||
|
||||
const DiscordNative = {
|
||||
isRenderer: process.type === 'renderer',
|
||||
|
||||
nativeModules: require('./discord_native/renderer/nativeModules'),
|
||||
process: require('./discord_native/renderer/process'),
|
||||
os: require('./discord_native/renderer/os'),
|
||||
|
@ -49,48 +43,32 @@ const DiscordNative = {
|
|||
http: require('./discord_native/renderer/http'),
|
||||
accessibility: require('./discord_native/renderer/accessibility'),
|
||||
features: require('./discord_native/renderer/features'),
|
||||
settings: require('./discord_native/renderer/settings')
|
||||
};
|
||||
settings: require('./discord_native/renderer/settings'),
|
||||
userDataCache: require('./discord_native/renderer/userDataCache')
|
||||
}; // TODO: remove these once web no longer uses them
|
||||
|
||||
// TODO: remove these once web no longer uses them
|
||||
DiscordNative.remoteApp = DiscordNative.app;
|
||||
DiscordNative.remotePowerMonitor = DiscordNative.powerMonitor;
|
||||
contextBridge.exposeInMainWorld('DiscordNative', DiscordNative);
|
||||
|
||||
const BetterDiscord = require("./BetterDiscord")
|
||||
|
||||
const _setImmediate = setImmediate;
|
||||
const _clearImmediate = clearImmediate;
|
||||
process.once('loaded', () => {
|
||||
// Implementing DiscordNative
|
||||
// ensures native module `require` context has access to DiscordNative
|
||||
global.DiscordNative = DiscordNative;
|
||||
|
||||
// We keep these two functions in global because electron doesn't put these
|
||||
// nodejs APIs in the module scope, and these two functions
|
||||
// aren't harmful at all.
|
||||
global.setImmediate = _setImmediate;
|
||||
global.clearImmediate = _clearImmediate;
|
||||
|
||||
// Since nodeIntegration has been disable
|
||||
// We're adding node propertys on window so it's easier
|
||||
// to write code / debug
|
||||
window.global = window
|
||||
global.Buffer = Buffer
|
||||
|
||||
global.setImmediate = function(callback, ...args){
|
||||
return setTimeout(callback, 0, ...args);
|
||||
};
|
||||
global.clearImmediate = clearTimeout;
|
||||
|
||||
const buildInfo = electron.ipcRenderer.sendSync("LIGHTCORD_GET_BUILD_INFOS")
|
||||
console.log("%c%s", "color: #3767ad;font-size:25px", 'Lightcord Client\nhttps://github.com/Lightcord/Lightcord');
|
||||
console.log("%c%s", "font-size:15px", `Version: ${buildInfo.version}\nCommit: ${buildInfo.commit || "Unknown"}`)
|
||||
|
||||
|
||||
let ftime = Date.now()
|
||||
BetterDiscord.init()
|
||||
let startTime = Date.now()
|
||||
BetterDiscord.init({
|
||||
// Detect if tabPreload was used.
|
||||
isTab: require.main !== module
|
||||
})
|
||||
BetterDiscord.events.on("debug", BetterDiscord.logger.log.bind(BetterDiscord.logger))
|
||||
BetterDiscord.events.on("ready", () => {
|
||||
BetterDiscord.logger.log("BetterDiscord Loaded. took: "+(Date.now() - ftime)+"ms.")
|
||||
BetterDiscord.logger.log("BetterDiscord Loaded. took: "+(Date.now() - startTime)+"ms.")
|
||||
|
||||
try{
|
||||
// better disabling Discord's tracking request, no error in console.
|
||||
|
@ -99,4 +77,13 @@ process.once('loaded', () => {
|
|||
}
|
||||
}catch(e){}
|
||||
})
|
||||
})
|
||||
});
|
||||
window.popouts = new Map();
|
||||
} else {
|
||||
window.addEventListener('load', _ => {
|
||||
window.opener.popouts.set(window.name, window);
|
||||
});
|
||||
window.addEventListener('beforeunload', _ => {
|
||||
window.opener.popouts.delete(window.name);
|
||||
});
|
||||
}
|
|
@ -1,3 +1,3 @@
|
|||
'use strict';
|
||||
"use strict";
|
||||
|
||||
module.exports = require('./bootstrapModules').moduleUpdater;
|
|
@ -1,51 +1,44 @@
|
|||
'use strict';
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.hasInit = exports.NOTIFICATION_CLICK = exports.events = undefined;
|
||||
exports.init = init;
|
||||
exports.close = close;
|
||||
exports.setMainWindow = setMainWindow;
|
||||
exports.hasInit = exports.NOTIFICATION_CLICK = exports.events = void 0;
|
||||
|
||||
var _electron = require('electron');
|
||||
var _electron = require("electron");
|
||||
|
||||
var _fs = require('fs');
|
||||
var _fs = _interopRequireDefault(require("fs"));
|
||||
|
||||
var _fs2 = _interopRequireDefault(_fs);
|
||||
var _path = _interopRequireDefault(require("path"));
|
||||
|
||||
var _path = require('path');
|
||||
var _events = require("events");
|
||||
|
||||
var _path2 = _interopRequireDefault(_path);
|
||||
var _url = _interopRequireDefault(require("url"));
|
||||
|
||||
var _events = require('events');
|
||||
|
||||
var _url = require('url');
|
||||
|
||||
var _url2 = _interopRequireDefault(_url);
|
||||
|
||||
var _ipcMain = require('./ipcMain');
|
||||
|
||||
var _ipcMain2 = _interopRequireDefault(_ipcMain);
|
||||
var _ipcMain = _interopRequireDefault(require("./ipcMain"));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
// ipcMain events
|
||||
// TODO: transparency detection?
|
||||
// TODO: SHQueryUserNotificationState
|
||||
|
||||
// ipcMain events
|
||||
const IPC_NOTIFICATIONS_CLEAR = 'NOTIFICATIONS_CLEAR';
|
||||
const IPC_NOTIFICATION_SHOW = 'NOTIFICATION_SHOW';
|
||||
const IPC_NOTIFICATION_CLICK = 'NOTIFICATION_CLICK';
|
||||
const IPC_NOTIFICATION_CLOSE = 'NOTIFICATION_CLOSE';
|
||||
const IPC_THEME_UPDATE = "UPDATE_THEME"
|
||||
const IPC_THEME_UPDATE = "UPDATE_THEME" // events
|
||||
|
||||
// events
|
||||
const events = exports.events = new _events.EventEmitter();
|
||||
const NOTIFICATION_CLICK = exports.NOTIFICATION_CLICK = 'notification-click';
|
||||
const events = new _events.EventEmitter();
|
||||
exports.events = events;
|
||||
const NOTIFICATION_CLICK = 'notification-click';
|
||||
exports.NOTIFICATION_CLICK = NOTIFICATION_CLICK;
|
||||
let hasInit = false;
|
||||
exports.hasInit = hasInit;
|
||||
|
||||
let hasInit = exports.hasInit = false;
|
||||
const variablesFilePath = _path2.default.join(__dirname, 'notifications', 'variables.json');
|
||||
const variablesFilePath = _path.default.join(__dirname, 'notifications', 'variables.json');
|
||||
|
||||
let mainWindow;
|
||||
let title;
|
||||
|
@ -72,28 +65,29 @@ function init({
|
|||
console.warn('notificationScreen: Has already init! Cancelling init.');
|
||||
return;
|
||||
}
|
||||
|
||||
exports.hasInit = hasInit = true;
|
||||
|
||||
VARIABLES = JSON.parse(_fs2.default.readFileSync(variablesFilePath));
|
||||
|
||||
VARIABLES = JSON.parse(_fs.default.readFileSync(variablesFilePath));
|
||||
mainWindow = _mainWindow;
|
||||
|
||||
title = _title;
|
||||
maxVisible = _maxVisible;
|
||||
screenPosition = _screenPosition;
|
||||
notifications = [];
|
||||
hideTimeout = null;
|
||||
|
||||
_ipcMain2.default.on(IPC_NOTIFICATIONS_CLEAR, handleNotificationsClear);
|
||||
_ipcMain2.default.on(IPC_NOTIFICATION_SHOW, handleNotificationShow);
|
||||
_ipcMain2.default.on(IPC_NOTIFICATION_CLICK, handleNotificationClick);
|
||||
_ipcMain2.default.on(IPC_NOTIFICATION_CLOSE, handleNotificationClose);
|
||||
_ipcMain2.default.on(IPC_THEME_UPDATE, handleThemeUpdate)
|
||||
_ipcMain.default.on(IPC_NOTIFICATIONS_CLEAR, handleNotificationsClear);
|
||||
|
||||
_ipcMain.default.on(IPC_NOTIFICATION_SHOW, handleNotificationShow);
|
||||
|
||||
_ipcMain.default.on(IPC_NOTIFICATION_CLICK, handleNotificationClick);
|
||||
|
||||
_ipcMain.default.on(IPC_NOTIFICATION_CLOSE, handleNotificationClose);
|
||||
|
||||
_ipcMain.default.on(IPC_THEME_UPDATE, handleThemeUpdate)
|
||||
}
|
||||
|
||||
function destroyWindow() {
|
||||
if (notificationWindow == null) return;
|
||||
|
||||
notificationWindow.hide();
|
||||
notificationWindow.close();
|
||||
notificationWindow = null;
|
||||
|
@ -101,14 +95,17 @@ function destroyWindow() {
|
|||
|
||||
function close() {
|
||||
mainWindow = null;
|
||||
|
||||
destroyWindow();
|
||||
|
||||
_ipcMain2.default.removeListener(IPC_NOTIFICATIONS_CLEAR, handleNotificationsClear);
|
||||
_ipcMain2.default.removeListener(IPC_NOTIFICATION_SHOW, handleNotificationShow);
|
||||
_ipcMain2.default.removeListener(IPC_NOTIFICATION_CLICK, handleNotificationClick);
|
||||
_ipcMain2.default.removeListener(IPC_NOTIFICATION_CLOSE, handleNotificationClose);
|
||||
_ipcMain2.default.removeListener(IPC_THEME_UPDATE, handleThemeUpdate)
|
||||
_ipcMain.default.removeListener(IPC_NOTIFICATIONS_CLEAR, handleNotificationsClear);
|
||||
|
||||
_ipcMain.default.removeListener(IPC_NOTIFICATION_SHOW, handleNotificationShow);
|
||||
|
||||
_ipcMain.default.removeListener(IPC_NOTIFICATION_CLICK, handleNotificationClick);
|
||||
|
||||
_ipcMain.default.removeListener(IPC_NOTIFICATION_CLOSE, handleNotificationClose);
|
||||
|
||||
_ipcMain.default.removeListener(IPC_THEME_UPDATE, handleThemeUpdate)
|
||||
}
|
||||
|
||||
function setMainWindow(_mainWindow) {
|
||||
|
@ -145,6 +142,7 @@ function handleNotificationClose(e, notificationId) {
|
|||
if (notificationWindow) {
|
||||
webContentsSend(notificationWindow, 'FADE_OUT', notificationId);
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
notifications = notifications.filter(notification => notification.id !== notificationId);
|
||||
isClosing = isClosing.filter(e => e!== notificationId)
|
||||
|
@ -162,10 +160,15 @@ function updateNotifications() {
|
|||
hideTimeout = null;
|
||||
|
||||
if (notificationWindow != null) {
|
||||
const { width, height, x, y } = calculateBoundingBox();
|
||||
// [adill] this order is important. if you setPosition before you setSize electron
|
||||
const {
|
||||
width,
|
||||
height,
|
||||
x,
|
||||
y
|
||||
} = calculateBoundingBox(); // [adill] this order is important. if you setPosition before you setSize electron
|
||||
// incorrectly computes the window size. i haven't investigated the root cause
|
||||
// further than this observation.
|
||||
|
||||
notificationWindow.setSize(width, height);
|
||||
notificationWindow.setPosition(x, y);
|
||||
notificationWindow.showInactive();
|
||||
|
@ -199,23 +202,29 @@ function calculateBoundingBox() {
|
|||
};
|
||||
|
||||
const activeDisplay = _electron.screen.getDisplayNearestPoint(centerPoint) || _electron.screen.getPrimaryDisplay();
|
||||
const workArea = activeDisplay.workArea;
|
||||
|
||||
const workArea = activeDisplay.workArea;
|
||||
const width = VARIABLES.width;
|
||||
const height = maxVisible * VARIABLES.height;
|
||||
|
||||
const x = workArea.x + workArea.width - width;
|
||||
let y;
|
||||
|
||||
switch (screenPosition) {
|
||||
case 'top':
|
||||
y = workArea.y;
|
||||
break;
|
||||
|
||||
case 'bottom':
|
||||
y = workArea.y + workArea.height - height;
|
||||
break;
|
||||
}
|
||||
|
||||
return { x, y, width, height };
|
||||
return {
|
||||
x,
|
||||
y,
|
||||
width,
|
||||
height
|
||||
};
|
||||
}
|
||||
|
||||
function createWindow() {
|
||||
|
@ -236,11 +245,13 @@ function createWindow() {
|
|||
nodeIntegration: true
|
||||
}
|
||||
});
|
||||
const notificationUrl = _url2.default.format({
|
||||
|
||||
const notificationUrl = _url.default.format({
|
||||
protocol: 'file',
|
||||
slashes: true,
|
||||
pathname: _path2.default.join(__dirname, 'notifications', 'index.html')
|
||||
pathname: _path.default.join(__dirname, 'notifications', 'index.html')
|
||||
});
|
||||
|
||||
notificationWindow.loadURL(notificationUrl);
|
||||
notificationWindow.webContents.on('did-finish-load', () => {
|
||||
updateTheme(lastUsedTheme)
|
||||
|
|
|
@ -1 +1,15 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="Layer_1" width="20" height="20" x="0" y="0" enable-background="new 40 40 20 20" version="1.1" viewBox="40 40 20 20" xml:space="preserve"><title>Slice 1</title><description>Created with Sketch (http://www.bohemiancoding.com/sketch)</description><g id="Page_1"><path id="Close" fill="#99aab5" d="M40.445,42.853l2.408-2.408c0.593-0.593,1.555-0.593,2.147,0l5,5l5-5 c0.593-0.593,1.554-0.593,2.147,0l2.408,2.408c0.593,0.593,0.593,1.554,0,2.147l-5,5l5,5c0.593,0.593,0.592,1.554,0,2.147 l-2.408,2.408c-0.593,0.593-1.555,0.593-2.147,0l-5-5l-5,5c-0.593,0.593-1.554,0.593-2.147,0l-2.408-2.408 c-0.593-0.593-0.593-1.554,0-2.147l5-5l-5-5C39.852,44.407,39.852,43.445,40.445,42.853z"/></g></svg>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 17.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns"
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="20px" height="20px"
|
||||
viewBox="40 40 20 20" enable-background="new 40 40 20 20" xml:space="preserve">
|
||||
<title>Slice 1</title>
|
||||
<description>Created with Sketch (http://www.bohemiancoding.com/sketch)</description>
|
||||
<g id="Page_1">
|
||||
<path id="Close" fill="#99aab5" d="M40.445,42.853l2.408-2.408c0.593-0.593,1.555-0.593,2.147,0l5,5l5-5
|
||||
c0.593-0.593,1.554-0.593,2.147,0l2.408,2.408c0.593,0.593,0.593,1.554,0,2.147l-5,5l5,5c0.593,0.593,0.592,1.554,0,2.147
|
||||
l-2.408,2.408c-0.593,0.593-1.555,0.593-2.147,0l-5-5l-5,5c-0.593,0.593-1.554,0.593-2.147,0l-2.408-2.408
|
||||
c-0.593-0.593-0.593-1.554,0-2.147l5-5l-5-5C39.852,44.407,39.852,43.445,40.445,42.853z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
|
Before Width: | Height: | Size: 767 B After Width: | Height: | Size: 1.1 KiB |
|
@ -1 +1,34 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="Layer_1" x="0" y="0" version="1.1" viewBox="0 0 168 190" xml:space="preserve" style="enable-background:new 0 0 168 190"><style type="text/css">.st0{fill:#fff}.st1{fill:url(#SVGID_1_)}.st2{fill:url(#SVGID_2_)}.st3{fill:url(#SVGID_3_)}</style><g><rect width="139.2" height="97.7" x="14.9" y="35.3" class="st0"/><g><linearGradient id="SVGID_1_" x1="66.7" x2="66.7" y1="112.3" y2="91.269" gradientTransform="matrix(1 0 0 -1 0 192)" gradientUnits="userSpaceOnUse"><stop offset="0" style="stop-color:#e30613"/><stop offset="1" style="stop-color:#731a14"/></linearGradient><path d="M66.7,79.7c-5.4,0-9.8,4.7-9.8,10.5s4.4,10.5,9.8,10.5s9.8-4.7,9.8-10.5C76.5,84.4,72.1,79.7,66.7,79.7z" class="st1"/><linearGradient id="SVGID_2_" x1="101.7" x2="101.7" y1="112.3" y2="91.269" gradientTransform="matrix(1 0 0 -1 0 192)" gradientUnits="userSpaceOnUse"><stop offset="0" style="stop-color:#e20613"/><stop offset="1" style="stop-color:#731a13"/></linearGradient><path d="M101.7,79.7c-5.4,0-9.8,4.7-9.8,10.5s4.4,10.5,9.8,10.5s9.8-4.7,9.8-10.5C111.5,84.4,107.1,79.7,101.7,79.7z" class="st2"/><linearGradient id="SVGID_3_" x1="84" x2="84" y1="192" y2="2" gradientTransform="matrix(1 0 0 -1 0 192)" gradientUnits="userSpaceOnUse"><stop offset="0" style="stop-color:#e30613"/><stop offset="1" style="stop-color:#731a13"/></linearGradient><path d="M148.4,0H19.6C8.8,0,0,8.8,0,19.6V148c0,10.8,8.8,19.6,19.6,19.6h108.9l-5.1-17.5l12.3,11.3l11.6,10.7 L168,190v-41.9v-9.5v-119C168,8.8,159.2,0,148.4,0z M111.3,124.1c0,0-3.4-4.1-6.3-7.7c12.6-3.5,17.4-11.3,17.4-11.3 c-4,2.6-7.7,4.4-11.1,5.6c-4.8,2-9.5,3.3-14,4.1c-9.2,1.7-17.6,1.3-24.9-0.1c-5.5-1-10.2-2.5-14.1-4.1c-2.2-0.8-4.6-1.9-7.1-3.3 c-0.3-0.2-0.6-0.3-0.9-0.5c-0.1-0.1-0.3-0.2-0.4-0.2c-1.7-1-2.6-1.6-2.6-1.6s4.6,7.6,16.8,11.2c-2.9,3.6-6.4,7.9-6.4,7.9 c-21.2-0.6-29.3-14.5-29.3-14.5c0-30.6,13.8-55.4,13.8-55.4c13.8-10.3,26.9-10,26.9-10l1,1.1C52.8,50.3,45,57.9,45,57.9 s2.1-1.2,5.7-2.7c10.3-4.5,18.4-5.7,21.8-6c0.5-0.1,1.1-0.2,1.6-0.2c5.9-0.7,12.5-0.9,19.4-0.2c9.1,1,18.9,3.7,28.9,9.1 c0,0-7.5-7.2-23.9-12.1l1.3-1.5c0,0,13.1-0.3,26.9,10c0,0,13.8,24.8,13.8,55.4C140.6,109.6,132.5,123.5,111.3,124.1z" class="st3"/></g></g></svg>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 168 190" enable-background="new 0 0 168 190" xml:space="preserve">
|
||||
<g>
|
||||
<rect x="14.4" y="46.1" fill="#FFFFFF" width="139.2" height="97.7"/>
|
||||
<g>
|
||||
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="66.6616" y1="79.7119" x2="66.6616" y2="100.7434">
|
||||
<stop offset="0" style="stop-color:#7491D5"/>
|
||||
<stop offset="1" style="stop-color:#4E68A0"/>
|
||||
</linearGradient>
|
||||
<path fill="url(#SVGID_1_)" d="M66.7,79.7c-5.4,0-9.8,4.7-9.8,10.5c0,5.8,4.4,10.5,9.8,10.5c5.4,0,9.8-4.7,9.8-10.5
|
||||
C76.5,84.4,72.1,79.7,66.7,79.7z"/>
|
||||
<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="101.661" y1="79.7119" x2="101.661" y2="100.7434">
|
||||
<stop offset="0" style="stop-color:#7491D5"/>
|
||||
<stop offset="1" style="stop-color:#4E68A0"/>
|
||||
</linearGradient>
|
||||
<path fill="url(#SVGID_2_)" d="M101.7,79.7c-5.4,0-9.8,4.7-9.8,10.5c0,5.8,4.4,10.5,9.8,10.5c5.4,0,9.8-4.7,9.8-10.5
|
||||
C111.5,84.4,107.1,79.7,101.7,79.7z"/>
|
||||
<linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="84" y1="-4.545736e-07" x2="84" y2="190">
|
||||
<stop offset="0" style="stop-color:#7491D5"/>
|
||||
<stop offset="1" style="stop-color:#4E68A0"/>
|
||||
</linearGradient>
|
||||
<path fill="url(#SVGID_3_)" d="M148.4,0H19.6C8.8,0,0,8.8,0,19.6v128.4c0,10.8,8.8,19.6,19.6,19.6h108.9l-5.1-17.5l12.3,11.3
|
||||
l11.6,10.7L168,190v-41.9v-9.5V19.6C168,8.8,159.2,0,148.4,0z M111.3,124.1c0,0-3.4-4.1-6.3-7.7c12.6-3.5,17.4-11.3,17.4-11.3
|
||||
c-4,2.6-7.7,4.4-11.1,5.6c-4.8,2-9.5,3.3-14,4.1c-9.2,1.7-17.6,1.3-24.9-0.1c-5.5-1-10.2-2.5-14.1-4.1c-2.2-0.8-4.6-1.9-7.1-3.3
|
||||
c-0.3-0.2-0.6-0.3-0.9-0.5c-0.1-0.1-0.3-0.2-0.4-0.2c-1.7-1-2.6-1.6-2.6-1.6s4.6,7.6,16.8,11.2c-2.9,3.6-6.4,7.9-6.4,7.9
|
||||
c-21.2-0.6-29.3-14.5-29.3-14.5c0-30.6,13.8-55.4,13.8-55.4c13.8-10.3,26.9-10,26.9-10l1,1.1C52.8,50.3,45,57.9,45,57.9
|
||||
s2.1-1.2,5.7-2.7c10.3-4.5,18.4-5.7,21.8-6c0.5-0.1,1.1-0.2,1.6-0.2c5.9-0.7,12.5-0.9,19.4-0.2c9.1,1,18.9,3.7,28.9,9.1
|
||||
c0,0-7.5-7.2-23.9-12.1l1.3-1.5c0,0,13.1-0.3,26.9,10c0,0,13.8,24.8,13.8,55.4C140.6,109.6,132.5,123.5,111.3,124.1z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.3 KiB |
|
@ -9,7 +9,22 @@
|
|||
.notification-icon {
|
||||
border-radius: 10px
|
||||
}
|
||||
</style>
|
||||
.notification.theme-dark {
|
||||
background-color: #202225
|
||||
}
|
||||
|
||||
notif-text.theme-dark {
|
||||
color: #dcddde !important
|
||||
}
|
||||
|
||||
.notif-text.theme-light {
|
||||
background-color: #fff
|
||||
}
|
||||
|
||||
.notification.notification-contents.notification-body.theme-light {
|
||||
color: #2e3338 !important
|
||||
}
|
||||
</style
|
||||
</head>
|
||||
<body>
|
||||
<div id="notifications-mount"></div>
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
'use strict';
|
||||
"use strict";
|
||||
|
||||
module.exports = require('./bootstrapModules').paths;
|
|
@ -1,20 +1,19 @@
|
|||
'use strict';
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.hasInit = undefined;
|
||||
exports.init = init;
|
||||
exports.getWindow = getWindow;
|
||||
exports.openOrFocusWindow = openOrFocusWindow;
|
||||
exports.closePopouts = closePopouts;
|
||||
exports.hasInit = void 0;
|
||||
|
||||
var _electron = require('electron');
|
||||
var _electron = require("electron");
|
||||
|
||||
var _appFeatures = require('./appFeatures');
|
||||
var _appFeatures = require("./appFeatures");
|
||||
|
||||
var _mainScreen = require('./mainScreen');
|
||||
const { join } = require('path');
|
||||
var _mainScreen = require("./mainScreen");
|
||||
|
||||
const MIN_POPOUT_WIDTH = 320;
|
||||
const MIN_POPOUT_HEIGHT = 180;
|
||||
|
@ -30,14 +29,14 @@ const DEFAULT_POPOUT_OPTIONS = {
|
|||
show: true,
|
||||
webPreferences: {
|
||||
nodeIntegration: false,
|
||||
nativeWindowOpen: true
|
||||
},
|
||||
icon: join(__dirname, "images", 'discord.png')
|
||||
nativeWindowOpen: true,
|
||||
enableRemoteModule: false,
|
||||
contextIsolation: true
|
||||
}
|
||||
};
|
||||
const features = (0, _appFeatures.getFeatures)();
|
||||
|
||||
let hasInit = exports.hasInit = false;
|
||||
|
||||
let hasInit = false;
|
||||
exports.hasInit = hasInit;
|
||||
let popoutWindows = {};
|
||||
|
||||
function init() {
|
||||
|
@ -45,15 +44,15 @@ function init() {
|
|||
console.warn('popoutWindows: Has already init! Cancelling init.');
|
||||
return;
|
||||
}
|
||||
exports.hasInit = hasInit = true;
|
||||
|
||||
exports.hasInit = hasInit = true;
|
||||
features.declareSupported('popout_windows');
|
||||
}
|
||||
|
||||
function focusWindow(window) {
|
||||
if (window == null) return;
|
||||
// The focus call is not always respected.
|
||||
if (window == null) return; // The focus call is not always respected.
|
||||
// This uses a hack defined in https://github.com/electron/electron/issues/2867
|
||||
|
||||
window.setAlwaysOnTop(true);
|
||||
window.focus();
|
||||
window.setAlwaysOnTop(false);
|
||||
|
@ -62,7 +61,6 @@ function focusWindow(window) {
|
|||
function getWindow(key) {
|
||||
return popoutWindows[key];
|
||||
}
|
||||
|
||||
/**
|
||||
* Open a popout window with the specified key, or focus it if it's already open.
|
||||
*
|
||||
|
@ -75,11 +73,19 @@ function getWindow(key) {
|
|||
* @param {number} options.x the x position of the window
|
||||
* @param {number} options.y the y position of the window
|
||||
*/
|
||||
|
||||
|
||||
function openOrFocusWindow(e, windowURL, key, options) {
|
||||
// Without webContents, window will not properly signal parent
|
||||
const { width, height, x, y, webContents } = options;
|
||||
|
||||
const {
|
||||
width,
|
||||
height,
|
||||
x,
|
||||
y,
|
||||
webContents
|
||||
} = options;
|
||||
const existingWindow = popoutWindows[key];
|
||||
|
||||
if (existingWindow != null) {
|
||||
e.newGuest = existingWindow;
|
||||
focusWindow(existingWindow);
|
||||
|
@ -93,20 +99,21 @@ function openOrFocusWindow(e, windowURL, key, options) {
|
|||
y,
|
||||
webContents
|
||||
});
|
||||
|
||||
const newWindow = e.newGuest = new _electron.BrowserWindow(newOptions);
|
||||
newWindow.windowKey = key;
|
||||
popoutWindows[key] = newWindow;
|
||||
|
||||
if (windowURL) {
|
||||
newWindow.loadURL(windowURL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle events for our new window
|
||||
*
|
||||
* NOTE: Wanted to handle 'always-on-top-changed' and send to client but currently
|
||||
* the event seems to not fire.
|
||||
* */
|
||||
|
||||
|
||||
newWindow.once('closed', () => {
|
||||
newWindow.removeAllListeners();
|
||||
delete popoutWindows[key];
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
'use strict';
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
|
@ -6,13 +6,9 @@ Object.defineProperty(exports, "__esModule", {
|
|||
exports.init = init;
|
||||
exports.getRequestCA = getRequestCA;
|
||||
|
||||
var _fs = require('fs');
|
||||
var _fs = _interopRequireDefault(require("fs"));
|
||||
|
||||
var _fs2 = _interopRequireDefault(_fs);
|
||||
|
||||
var _path = require('path');
|
||||
|
||||
var _path2 = _interopRequireDefault(_path);
|
||||
var _path = _interopRequireDefault(require("path"));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
|
@ -20,17 +16,20 @@ let requestCA;
|
|||
|
||||
function init() {
|
||||
let rootCertificateAuthorities;
|
||||
|
||||
try {
|
||||
rootCertificateAuthorities = _fs2.default.readFileSync(_path2.default.join(__dirname, 'data', 'cacert.pem'));
|
||||
rootCertificateAuthorities = _fs.default.readFileSync(_path.default.join(__dirname, 'data', 'cacert.pem'));
|
||||
} catch (err) {
|
||||
console.error('Unable to load root certificate authorities.');
|
||||
console.error(err);
|
||||
}
|
||||
|
||||
requestCA = rootCertificateAuthorities ? { ca: rootCertificateAuthorities } : {};
|
||||
}
|
||||
requestCA = rootCertificateAuthorities ? {
|
||||
ca: rootCertificateAuthorities
|
||||
} : {};
|
||||
} // TODO: do we use this export?
|
||||
|
||||
|
||||
// TODO: do we use this export?
|
||||
function getRequestCA() {
|
||||
return requestCA;
|
||||
}
|
|
@ -1,3 +1,3 @@
|
|||
'use strict';
|
||||
"use strict";
|
||||
|
||||
module.exports = require('./bootstrapModules').splashScreen;
|
|
@ -1,30 +1,29 @@
|
|||
'use strict';
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.hasInit = undefined;
|
||||
exports.init = init;
|
||||
exports.show = show;
|
||||
exports.displayHowToCloseHint = displayHowToCloseHint;
|
||||
exports.hasInit = void 0;
|
||||
|
||||
var _electron = require('electron');
|
||||
var _electron = require("electron");
|
||||
|
||||
var _utils = require('./utils');
|
||||
var _securityUtils = require("../common/securityUtils");
|
||||
|
||||
var _appSettings = require('./appSettings');
|
||||
var _appSettings = require("./appSettings");
|
||||
|
||||
var _ipcMain = require('./ipcMain');
|
||||
var _ipcMain = _interopRequireDefault(require("./ipcMain"));
|
||||
|
||||
var _ipcMain2 = _interopRequireDefault(_ipcMain);
|
||||
var _utils = require("./utils");
|
||||
|
||||
var _Constants = require('./Constants');
|
||||
var _Constants = require("./Constants");
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
const settings = _appSettings();
|
||||
const settings = (0, _appSettings.getSettings)(); // These are lazy loaded into temp files
|
||||
|
||||
// These are lazy loaded into temp files
|
||||
const TrayIconNames = {
|
||||
DEFAULT: 'tray',
|
||||
UNREAD: 'tray-unread',
|
||||
|
@ -33,7 +32,6 @@ const TrayIconNames = {
|
|||
MUTED: 'tray-muted',
|
||||
DEAFENED: 'tray-deafened'
|
||||
};
|
||||
|
||||
const MenuItems = {
|
||||
SECRET: 'SECRET',
|
||||
MUTE: 'MUTE',
|
||||
|
@ -44,8 +42,8 @@ const MenuItems = {
|
|||
QUIT: 'QUIT',
|
||||
ACKNOWLEDGEMENTS: 'ACKNOWLEDGEMENTS'
|
||||
};
|
||||
|
||||
let hasInit = exports.hasInit = false;
|
||||
let hasInit = false;
|
||||
exports.hasInit = hasInit;
|
||||
let currentIcon;
|
||||
let options;
|
||||
let menuItems;
|
||||
|
@ -62,19 +60,18 @@ function init(_options) {
|
|||
|
||||
trayIcons = {};
|
||||
generateTrayIconPaths();
|
||||
|
||||
exports.hasInit = hasInit = true;
|
||||
options = _options;
|
||||
currentIcon = trayIcons.DEFAULT;
|
||||
menuItems = {};
|
||||
applications = [];
|
||||
contextMenu = [];
|
||||
|
||||
initializeMenuItems();
|
||||
buildContextMenu();
|
||||
|
||||
_ipcMain2.default.on('SYSTEM_TRAY_SET_ICON', (evt, icon) => setTrayIcon(icon));
|
||||
_ipcMain2.default.on('SYSTEM_TRAY_SET_APPLICATIONS', (evt, newApplications) => setApplications(newApplications));
|
||||
_ipcMain.default.on('SYSTEM_TRAY_SET_ICON', (evt, icon) => setTrayIcon(icon));
|
||||
|
||||
_ipcMain.default.on('SYSTEM_TRAY_SET_APPLICATIONS', (evt, newApplications) => setApplications(newApplications));
|
||||
}
|
||||
|
||||
function generateTrayIconPaths() {
|
||||
|
@ -83,14 +80,19 @@ function generateTrayIconPaths() {
|
|||
const suffix = process.platform === 'darwin' ? 'Template' : '';
|
||||
|
||||
for (const key of Object.keys(TrayIconNames)) {
|
||||
trayIcons[key] = _utils.exposeModuleResource(resourcePath, `${TrayIconNames[key]}${suffix}.png`);
|
||||
trayIcons[key] = (0, _utils.exposeModuleResource)(resourcePath, `${TrayIconNames[key]}${suffix}.png`);
|
||||
}
|
||||
}
|
||||
|
||||
function initializeMenuItems() {
|
||||
const { onToggleMute, onToggleDeafen, onTrayClicked, onOpenVoiceSettings, onCheckForUpdates } = options;
|
||||
const {
|
||||
onToggleMute,
|
||||
onToggleDeafen,
|
||||
onTrayClicked,
|
||||
onOpenVoiceSettings,
|
||||
onCheckForUpdates
|
||||
} = options;
|
||||
const voiceConnected = currentIcon !== trayIcons.DEFAULT && currentIcon !== trayIcons.UNREAD;
|
||||
|
||||
menuItems[MenuItems.SECRET] = {
|
||||
label: `Lightcord`,
|
||||
icon: trayIcons.DEFAULT,
|
||||
|
@ -122,14 +124,12 @@ function initializeMenuItems() {
|
|||
visible: voiceConnected,
|
||||
click: onOpenVoiceSettings
|
||||
};
|
||||
/*
|
||||
menuItems[MenuItems.CHECK_UPDATE] = {
|
||||
label: 'Check for Updates...',
|
||||
type: 'normal',
|
||||
visible: process.platform !== 'darwin',
|
||||
click: onCheckForUpdates
|
||||
};
|
||||
*/
|
||||
menuItems[MenuItems.QUIT] = {
|
||||
label: `Quit ${_Constants.APP_NAME}`,
|
||||
role: 'quit'
|
||||
|
@ -138,14 +138,15 @@ function initializeMenuItems() {
|
|||
label: 'Acknowledgements',
|
||||
type: 'normal',
|
||||
visible: process.platform !== 'darwin',
|
||||
click: () => _electron.shell.openExternal('https://discord.com/acknowledgements')
|
||||
click: () => (0, _securityUtils.saferShellOpenExternal)('https://discord.com/acknowledgements')
|
||||
};
|
||||
}
|
||||
|
||||
function buildContextMenu() {
|
||||
const separator = { type: 'separator' };
|
||||
const separator = {
|
||||
type: 'separator'
|
||||
};
|
||||
const hasApplications = applications != null && applications.length > 0;
|
||||
|
||||
contextMenu = [
|
||||
menuItems[MenuItems.SECRET],
|
||||
separator, ...(hasApplications ? [...applications, separator] : []),
|
||||
|
@ -153,26 +154,26 @@ function buildContextMenu() {
|
|||
menuItems[MenuItems.MUTE],
|
||||
menuItems[MenuItems.DEAFEN],
|
||||
menuItems[MenuItems.VOICE_SETTINGS],
|
||||
/*menuItems[MenuItems.CHECK_UPDATE], */
|
||||
// menuItems[MenuItems.CHECK_UPDATE],
|
||||
menuItems[MenuItems.ACKNOWLEDGEMENTS],
|
||||
separator, menuItems[MenuItems.QUIT]
|
||||
separator,
|
||||
menuItems[MenuItems.QUIT]
|
||||
];
|
||||
}
|
||||
|
||||
function setTrayIcon(icon) {
|
||||
// Keep track of last set icon
|
||||
currentIcon = trayIcons[icon];
|
||||
|
||||
// If icon is null, hide the tray icon. Otherwise show
|
||||
currentIcon = trayIcons[icon]; // If icon is null, hide the tray icon. Otherwise show
|
||||
// These calls also check for tray existence, so minimal cost.
|
||||
|
||||
if (icon == null) {
|
||||
hide();
|
||||
return;
|
||||
} else {
|
||||
show();
|
||||
}
|
||||
} // Keep mute/deafen menu items in sync with client, based on icon states
|
||||
|
||||
|
||||
// Keep mute/deafen menu items in sync with client, based on icon states
|
||||
const muteIndex = contextMenu.indexOf(menuItems[MenuItems.MUTE]);
|
||||
const deafenIndex = contextMenu.indexOf(menuItems[MenuItems.DEAFEN]);
|
||||
const voiceConnected = contextMenu[muteIndex].visible;
|
||||
|
@ -229,14 +230,12 @@ function setContextMenu() {
|
|||
|
||||
function show() {
|
||||
if (atomTray != null) return;
|
||||
|
||||
atomTray = new _electron.Tray(_electron.nativeImage.createFromPath(currentIcon)); // Initialize with last set icon
|
||||
atomTray.setToolTip(_Constants.APP_NAME);
|
||||
|
||||
// Set tray context menu
|
||||
setContextMenu();
|
||||
atomTray.setToolTip(_Constants.APP_NAME); // Set tray context menu
|
||||
|
||||
setContextMenu(); // Set Tray click behavior
|
||||
|
||||
// Set Tray click behavior
|
||||
atomTray.on('click', options.onTrayClicked);
|
||||
}
|
||||
|
||||
|
@ -252,9 +251,9 @@ function hide() {
|
|||
function displayHowToCloseHint() {
|
||||
if (settings.get('trayBalloonShown') != null || atomTray == null) {
|
||||
return;
|
||||
}
|
||||
} // TODO: localize
|
||||
|
||||
|
||||
// TODO: localize
|
||||
const balloonMessage = 'Hi! Lightcord will run in the background to keep you in touch with your friends.' + ' You can right-click here to quit.';
|
||||
settings.set('trayBalloonShown', true);
|
||||
settings.save();
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
global.isTab = true
|
||||
require("./mainScreenPreload")
|
|
@ -1,174 +0,0 @@
|
|||
const fs = require("fs")
|
||||
const { join } = require("path")
|
||||
const { pathToFileURL } = require("url")
|
||||
const ipc = require("../discord_native/renderer/ipc")
|
||||
|
||||
let webviews = new Map()
|
||||
window.webviews = webviews
|
||||
|
||||
function forwardToCurrentWebview(event){
|
||||
return [event, async (...args) => {
|
||||
let webview = webviews.get(document.querySelector(".chrome-tab[active]"))
|
||||
if(!webview)return
|
||||
await webview.ready
|
||||
webview.send(event, ...args.slice(1))
|
||||
}]
|
||||
}
|
||||
|
||||
/** discord_desktop_core Stable */
|
||||
ipc.on(...forwardToCurrentWebview("MAIN_WINDOW_FOCUS"))
|
||||
ipc.on(...forwardToCurrentWebview("MAIN_WINDOW_BLUR"))
|
||||
ipc.on(...forwardToCurrentWebview("SYSTEM_TRAY_OPEN_VOICE_SETTINGS"))
|
||||
ipc.on(...forwardToCurrentWebview("SYSTEM_TRAY_TOGGLE_MUTE"))
|
||||
ipc.on(...forwardToCurrentWebview("SYSTEM_TRAY_TOGGLE_DEAFEN"))
|
||||
ipc.on(...forwardToCurrentWebview("LAUNCH_APPLICATION"))
|
||||
ipc.on(...forwardToCurrentWebview("SPELLCHECK_RESULT"))
|
||||
ipc.on(...forwardToCurrentWebview("WINDOW_DEVTOOLS_OPENED"))
|
||||
ipc.on(...forwardToCurrentWebview("WINDOW_DEVTOOLS_CLOSED"))
|
||||
ipc.on(...forwardToCurrentWebview("UPDATE_ERROR"))
|
||||
ipc.on(...forwardToCurrentWebview("UPDATE_NOT_AVAILABLE"))
|
||||
ipc.on(...forwardToCurrentWebview("UPDATE_MANUALLY"))
|
||||
ipc.on(...forwardToCurrentWebview("UPDATE_AVAILABLE"))
|
||||
ipc.on(...forwardToCurrentWebview("MODULE_INSTALL_PROGRESS"))
|
||||
ipc.on(...forwardToCurrentWebview("UPDATE_DOWNLOADED"))
|
||||
ipc.on(...forwardToCurrentWebview("MODULE_INSTALLED"))
|
||||
ipc.on(...forwardToCurrentWebview("CHECKING_FOR_UPDATES"))
|
||||
ipc.on(...forwardToCurrentWebview("UPDATER_HISTORY_RESPONSE"))
|
||||
ipc.on(...forwardToCurrentWebview("ACCESSIBILITY_SUPPORT_CHANGED"))
|
||||
ipc.on(...forwardToCurrentWebview("HELP_OPEN"))
|
||||
ipc.on(...forwardToCurrentWebview("USER_SETTINGS_OPEN"))
|
||||
ipc.on(...forwardToCurrentWebview("MAIN_WINDOW_PATH"))
|
||||
/** discord_desktop_core Development */
|
||||
ipc.on(...forwardToCurrentWebview("NAVIGATE_BACK"))
|
||||
ipc.on(...forwardToCurrentWebview("NAVIGATE_FORWARD"))
|
||||
|
||||
ipc.on("RELOAD", () => {
|
||||
let webview = webviews.get(document.querySelector(".chrome-tab[active]"))
|
||||
if(!webview)return
|
||||
webview.reload()
|
||||
})
|
||||
ipc.on("NEW_TAB", () => {
|
||||
chrtabs.addTab({
|
||||
title: 'Lightcord',
|
||||
favicon: faviconURL
|
||||
})
|
||||
})
|
||||
ipc.on("CLOSE_TAB", () => {
|
||||
let active = document.querySelector("div.chrome-tab[active]")
|
||||
if(!active)return
|
||||
chrtabs.removeTab(active)
|
||||
})
|
||||
ipc.on("OPEN_DEVTOOLS", () => {
|
||||
let webview = webviews.get(document.querySelector(".chrome-tab[active]"))
|
||||
if(!webview)return
|
||||
webview.openDevTools()
|
||||
})
|
||||
let chrtabs
|
||||
window.onload = () => {
|
||||
const ChromeTabs = require("chrome-tabs")
|
||||
require("chrome-tabs/css/chrome-tabs.css")
|
||||
require("chrome-tabs/css/chrome-tabs-dark-theme.css")
|
||||
require("./controls.css")
|
||||
|
||||
let tabs = document.querySelector(".chrome-tabs")
|
||||
let chromeTabs = new ChromeTabs()
|
||||
chrtabs = chromeTabs
|
||||
chromeTabs.init(tabs)
|
||||
|
||||
tabs.addEventListener('activeTabChange', ({detail}) => {
|
||||
let webview = webviews.get(detail.tabEl)
|
||||
if(!webview){
|
||||
chromeTabs.removeTab(detail.tabEl)
|
||||
return
|
||||
}
|
||||
let active = Array.from(webviews.values()).find(e => e.classList.contains("active-webview"))
|
||||
if(active)active.classList.remove("active-webview")
|
||||
webview.classList.add("active-webview")
|
||||
})
|
||||
tabs.addEventListener('tabAdd', ({detail}) => {
|
||||
chromeTabs.updateTab(detail.tabEl, {
|
||||
title: "Lightcord Loading...",
|
||||
favicon: faviconURL
|
||||
})
|
||||
let webview = document.createElement("webview")
|
||||
webview.src = "https://discord.com/app"
|
||||
webview.classList.add("discord-webview")
|
||||
webview.classList.add("webview-active")
|
||||
webview.setAttribute("preload", pathToFileURL(join(__dirname, "../tabPreload.js")))
|
||||
webview.shadowRoot.childNodes.item(1).style.height = "100%"
|
||||
webview.enableremotemodule = true
|
||||
webview.nodeintegration = false
|
||||
webview.spellcheck = true
|
||||
webview.webpreferences = "nativeWindowOpen=yes"
|
||||
webview.enableblinkfeatures = "EnumerateDevices,AudioOutputDevices"
|
||||
webview.addEventListener("ipc-message", function(...ev){
|
||||
ipc.send(ev[0].channel.replace("DISCORD_", ""), ev.slice(1))
|
||||
})
|
||||
webview.addEventListener('page-title-updated', () => {
|
||||
let el = Array.from(webviews.entries()).find(e => e[1] === webview)[0]
|
||||
if(!el)return
|
||||
chromeTabs.updateTab(el, {
|
||||
favicon: faviconURL,
|
||||
title: webview.getTitle()
|
||||
})
|
||||
})
|
||||
webviews.set(detail.tabEl, webview)
|
||||
document.querySelector(".documentFull").appendChild(webview)
|
||||
let r
|
||||
webview.ready = new Promise(resolve => (r = resolve))
|
||||
webview.addEventListener("dom-ready", () => {
|
||||
r()
|
||||
})
|
||||
webview.addEventListener("will-navigate", (e) => {
|
||||
e.preventDefault()
|
||||
console.log(e, e.url)
|
||||
})
|
||||
})
|
||||
tabs.addEventListener('tabRemove', ({detail}) => {
|
||||
let webview = webviews.get(detail.tabEl)
|
||||
if(!webview)return
|
||||
webview.remove()
|
||||
webviews.delete(detail.tabEl)
|
||||
if(document.querySelector(".chrome-tabs-content").childNodes.length === 0){
|
||||
window.close()
|
||||
}
|
||||
})
|
||||
|
||||
window.addEventListener('keydown', (event) => {
|
||||
if(event.ctrlKey){
|
||||
if(event.key === 't'){
|
||||
chromeTabs.addTab({
|
||||
title: 'Lightcord',
|
||||
favicon: faviconURL
|
||||
})
|
||||
}else if(event.key === "w"){
|
||||
let active = document.querySelector("div.chrome-tab[active]")
|
||||
if(!active)return
|
||||
chromeTabs.removeTab(active)
|
||||
}
|
||||
}
|
||||
})
|
||||
setImmediate(() => {
|
||||
chromeTabs.addTab({
|
||||
title: 'Lightcord Loading...',
|
||||
favicon: faviconURL
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
require.extensions[".css"] = (m, filename) => {
|
||||
let content = fs.readFileSync(filename, "binary")
|
||||
let style = document.createElement("style")
|
||||
style.id = btoa(filename)
|
||||
style.innerHTML = content
|
||||
document.head.appendChild(style)
|
||||
m.exports = {
|
||||
id: style.id,
|
||||
remove(){
|
||||
return style.remove()
|
||||
}
|
||||
}
|
||||
return m.exports
|
||||
}
|
||||
|
||||
const faviconURL = pathToFileURL(join(__dirname, "../images/discord.png"))
|
|
@ -0,0 +1,3 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = require('./bootstrapModules').updater;
|
|
@ -1,31 +1,33 @@
|
|||
'use strict';
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.exposeModuleResource = exposeModuleResource;
|
||||
|
||||
var _fs = require('fs');
|
||||
var _fs = _interopRequireDefault(require("fs"));
|
||||
|
||||
var _fs2 = _interopRequireDefault(_fs);
|
||||
var _path = _interopRequireDefault(require("path"));
|
||||
|
||||
var _path = require('path');
|
||||
var paths = _interopRequireWildcard(require("./paths"));
|
||||
|
||||
var _path2 = _interopRequireDefault(_path);
|
||||
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
|
||||
|
||||
var _paths = require('./paths');
|
||||
|
||||
var paths = _interopRequireWildcard(_paths);
|
||||
|
||||
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
|
||||
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
// Miscellaneous utility functions.
|
||||
function exposeModuleResource(asarPath, fileName) {
|
||||
const appPath = _path2.default.resolve(__dirname, '..');
|
||||
const fullPathToAsarFile = _path2.default.join(appPath, asarPath, fileName);
|
||||
const data = _fs2.default.readFileSync(fullPathToAsarFile);
|
||||
const nativeFilePath = _path2.default.join(paths.getUserData(), fileName);
|
||||
_fs2.default.writeFileSync(nativeFilePath, data);
|
||||
const appPath = _path.default.resolve(__dirname, '..');
|
||||
|
||||
const fullPathToAsarFile = _path.default.join(appPath, asarPath, fileName);
|
||||
|
||||
const data = _fs.default.readFileSync(fullPathToAsarFile);
|
||||
|
||||
const nativeFilePath = _path.default.join(paths.getUserData(), fileName);
|
||||
|
||||
_fs.default.writeFileSync(nativeFilePath, data);
|
||||
|
||||
return nativeFilePath;
|
||||
} // Miscellaneous utility functions.
|
||||
}
|
|
@ -1,14 +1,12 @@
|
|||
'use strict';
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
|
||||
exports.default = void 0;
|
||||
|
||||
// copied from discord_app/lib because including from there is broken.
|
||||
|
||||
class Backoff {
|
||||
|
||||
/**
|
||||
* Create a backoff instance can automatically backoff retries.
|
||||
*/
|
||||
|
@ -16,56 +14,64 @@ class Backoff {
|
|||
this.min = min;
|
||||
this.max = max != null ? max : min * 10;
|
||||
this.jitter = jitter;
|
||||
|
||||
this._current = min;
|
||||
this._timeoutId = null;
|
||||
this._fails = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of failures.
|
||||
*/
|
||||
|
||||
|
||||
get fails() {
|
||||
return this._fails;
|
||||
}
|
||||
|
||||
/**
|
||||
* Current backoff value in milliseconds.
|
||||
*/
|
||||
|
||||
|
||||
get current() {
|
||||
return this._current;
|
||||
}
|
||||
|
||||
/**
|
||||
* A callback is going to fire.
|
||||
*/
|
||||
|
||||
|
||||
get pending() {
|
||||
return this._timeoutId != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear any pending callbacks and reset the backoff.
|
||||
*/
|
||||
|
||||
|
||||
succeed() {
|
||||
this.cancel();
|
||||
this._fails = 0;
|
||||
this._current = this.min;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment the backoff and schedule a callback if provided.
|
||||
*/
|
||||
|
||||
|
||||
fail(callback) {
|
||||
this._fails += 1;
|
||||
let delay = this._current * 2;
|
||||
|
||||
if (this.jitter) {
|
||||
delay *= Math.random();
|
||||
}
|
||||
|
||||
this._current = Math.min(this._current + delay, this.max);
|
||||
|
||||
if (callback != null) {
|
||||
if (this._timeoutId != null) {
|
||||
throw new Error('callback already pending');
|
||||
}
|
||||
|
||||
this._timeoutId = setTimeout(() => {
|
||||
try {
|
||||
if (callback != null) {
|
||||
|
@ -76,18 +82,22 @@ class Backoff {
|
|||
}
|
||||
}, this._current);
|
||||
}
|
||||
|
||||
return this._current;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear any pending callbacks.
|
||||
*/
|
||||
|
||||
|
||||
cancel() {
|
||||
if (this._timeoutId != null) {
|
||||
clearTimeout(this._timeoutId);
|
||||
this._timeoutId = null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
exports.default = Backoff;
|
||||
module.exports = exports.default;
|
|
@ -1,8 +1,10 @@
|
|||
'use strict';
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
|
||||
class FeatureFlags {
|
||||
constructor() {
|
||||
this.flags = new Set();
|
||||
|
@ -24,6 +26,8 @@ class FeatureFlags {
|
|||
|
||||
this.flags.add(feature);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
exports.default = FeatureFlags;
|
||||
module.exports = exports.default;
|
|
@ -1,16 +1,13 @@
|
|||
'use strict';
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
|
||||
var _fs = require('fs');
|
||||
var _fs = _interopRequireDefault(require("fs"));
|
||||
|
||||
var _fs2 = _interopRequireDefault(_fs);
|
||||
|
||||
var _path = require('path');
|
||||
|
||||
var _path2 = _interopRequireDefault(_path);
|
||||
var _path = _interopRequireDefault(require("path"));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
|
@ -18,20 +15,22 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
|
|||
// if this is fine, remove this todo
|
||||
class Settings {
|
||||
constructor(root) {
|
||||
this.path = _path2.default.join(root, 'settings.json');
|
||||
this.path = _path.default.join(root, 'settings.json');
|
||||
|
||||
try {
|
||||
this.lastSaved = _fs2.default.readFileSync(this.path);
|
||||
this.lastSaved = _fs.default.readFileSync(this.path);
|
||||
this.settings = JSON.parse(this.lastSaved);
|
||||
} catch (e) {
|
||||
this.lastSaved = '';
|
||||
this.settings = {};
|
||||
}
|
||||
|
||||
this.lastModified = this._lastModified();
|
||||
}
|
||||
|
||||
_lastModified() {
|
||||
try {
|
||||
return _fs2.default.statSync(this.path).mtime.getTime();
|
||||
return _fs.default.statSync(this.path).mtime.getTime();
|
||||
} catch (e) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -57,15 +56,20 @@ class Settings {
|
|||
|
||||
try {
|
||||
const toSave = JSON.stringify(this.settings, null, 2);
|
||||
|
||||
if (this.lastSaved != toSave) {
|
||||
this.lastSaved = toSave;
|
||||
_fs2.default.writeFileSync(this.path, toSave);
|
||||
|
||||
_fs.default.writeFileSync(this.path, toSave);
|
||||
|
||||
this.lastModified = this._lastModified();
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn('Failed saving settings with error: ', err);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
exports.default = Settings;
|
||||
module.exports = exports.default;
|
|
@ -0,0 +1,79 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.init = init;
|
||||
exports.isInitialized = isInitialized;
|
||||
exports.metadata = void 0;
|
||||
|
||||
const electron = require('electron');
|
||||
|
||||
const childProcess = require('child_process');
|
||||
|
||||
const {
|
||||
flatten
|
||||
} = require('./crashReporterUtils');
|
||||
|
||||
let initialized = false;
|
||||
const metadata = {};
|
||||
exports.metadata = metadata;
|
||||
const DEFAULT_SENTRY_KEY = '384ce4413de74fe0be270abe03b2b35a';
|
||||
const TEST_SENTRY_KEY = '1a27a96457b24ff286a000266c573919';
|
||||
const CHANNEL_SENTRY_KEYS = {
|
||||
stable: DEFAULT_SENTRY_KEY,
|
||||
ptb: TEST_SENTRY_KEY,
|
||||
canary: TEST_SENTRY_KEY,
|
||||
development: TEST_SENTRY_KEY
|
||||
};
|
||||
|
||||
function getCrashReporterArgs(metadata) {
|
||||
// NB: we need to flatten the metadata because modern electron caps metadata values at 127 bytes,
|
||||
// which our sentry subobject can easily exceed.
|
||||
let flat_metadata = flatten(metadata);
|
||||
const channel = metadata['channel'];
|
||||
const sentryKey = CHANNEL_SENTRY_KEYS[channel] != null ? CHANNEL_SENTRY_KEYS[channel] : DEFAULT_SENTRY_KEY;
|
||||
return {
|
||||
productName: 'Discord',
|
||||
companyName: 'Discord Inc.',
|
||||
submitURL: `https://sentry.io/api/146342/minidump/?sentry_key=${sentryKey}`,
|
||||
uploadToServer: true,
|
||||
ignoreSystemCrashHandler: false,
|
||||
extra: flat_metadata
|
||||
};
|
||||
}
|
||||
|
||||
function init(buildInfo) {
|
||||
if (initialized) {
|
||||
console.warn('Ignoring double initialization of crash reporter.');
|
||||
return;
|
||||
}
|
||||
|
||||
metadata['channel'] = buildInfo.releaseChannel;
|
||||
const sentryMetadata = metadata['sentry'] != null ? metadata['sentry'] : {};
|
||||
sentryMetadata['environment'] = buildInfo.releaseChannel;
|
||||
sentryMetadata['release'] = buildInfo.version;
|
||||
metadata['sentry'] = sentryMetadata;
|
||||
|
||||
if (process.platform === 'linux') {
|
||||
const XDG_CURRENT_DESKTOP = process.env.XDG_CURRENT_DESKTOP || 'unknown';
|
||||
const GDMSESSION = process.env.GDMSESSION || 'unknown';
|
||||
metadata['wm'] = `${XDG_CURRENT_DESKTOP},${GDMSESSION}`;
|
||||
|
||||
try {
|
||||
metadata['distro'] = childProcess.execFileSync('lsb_release', ['-ds'], {
|
||||
timeout: 100,
|
||||
maxBuffer: 512,
|
||||
encoding: 'utf-8'
|
||||
}).trim();
|
||||
} catch (_) {} // just in case lsb_release doesn't exist
|
||||
|
||||
}
|
||||
|
||||
const config = getCrashReporterArgs(metadata);
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
function isInitialized() {
|
||||
return initialized;
|
||||
}
|
|
@ -1,10 +1,14 @@
|
|||
'use strict';
|
||||
"use strict";
|
||||
|
||||
const process = require('process');
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.flatten = flatten;
|
||||
exports.reconcileCrashReporterMetadata = reconcileCrashReporterMetadata;
|
||||
|
||||
function getElectronMajorVersion() {
|
||||
return process.versions.electron != null ? parseInt(process.versions.electron.split('.')[0]) : 0;
|
||||
}
|
||||
const {
|
||||
getElectronMajorVersion
|
||||
} = require('./processUtils');
|
||||
|
||||
function flatten(metadata, prefix, root) {
|
||||
root = root ? root : {};
|
||||
|
@ -23,7 +27,7 @@ function flatten(metadata, prefix, root) {
|
|||
}
|
||||
|
||||
function reconcileCrashReporterMetadata(crashReporter, metadata) {
|
||||
if (getElectronMajorVersion() < 9) {
|
||||
if (getElectronMajorVersion() < 8) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -42,9 +46,3 @@ function reconcileCrashReporterMetadata(crashReporter, metadata) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getElectronMajorVersion,
|
||||
flatten,
|
||||
reconcileCrashReporterMetadata
|
||||
};
|
|
@ -1,150 +1,8 @@
|
|||
'use strict';
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.supportsEventObjects = exports.events = exports.NO_PENDING_UPDATES = exports.INSTALLING_MODULE_PROGRESS = exports.INSTALLING_MODULE = exports.INSTALLING_MODULES_FINISHED = exports.DOWNLOADED_MODULE = exports.UPDATE_MANUALLY = exports.DOWNLOADING_MODULES_FINISHED = exports.DOWNLOADING_MODULE_PROGRESS = exports.DOWNLOADING_MODULE = exports.UPDATE_CHECK_FINISHED = exports.INSTALLED_MODULE = exports.CHECKING_FOR_UPDATES = undefined;
|
||||
|
||||
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
|
||||
|
||||
let checkForModuleUpdates = (() => {
|
||||
var _ref = _asyncToGenerator(function* () {
|
||||
const query = _extends({}, remoteQuery, { _: Math.floor(Date.now() / 1000 / 60 / 5) });
|
||||
const url = `${remoteBaseURL}/versions.json`;
|
||||
logger.log(`Checking for module updates at ${url}`);
|
||||
|
||||
let response;
|
||||
try {
|
||||
response = yield request.get({ url, qs: query, timeout: REQUEST_TIMEOUT });
|
||||
checkingForUpdates = false;
|
||||
} catch (err) {
|
||||
checkingForUpdates = false;
|
||||
logger.log(`Failed fetching module versions: ${String(err)}`);
|
||||
|
||||
events.append({
|
||||
type: UPDATE_CHECK_FINISHED,
|
||||
succeeded: false,
|
||||
updateCount: 0,
|
||||
manualRequired: false
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
remoteModuleVersions = JSON.parse(response.body);
|
||||
if (settings.get(USE_LOCAL_MODULE_VERSIONS)) {
|
||||
try {
|
||||
remoteModuleVersions = JSON.parse(_fs2.default.readFileSync(localModuleVersionsFilePath));
|
||||
console.log('Using local module versions: ', remoteModuleVersions);
|
||||
} catch (err) {
|
||||
console.warn('Failed to parse local module versions: ', err);
|
||||
}
|
||||
}
|
||||
|
||||
const updatesToDownload = [];
|
||||
for (const moduleName of Object.keys(installedModules)) {
|
||||
const installedModule = installedModules[moduleName];
|
||||
const installed = installedModule.installedVersion;
|
||||
if (installed === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const update = installedModule.updateVersion || 0;
|
||||
const remote = remoteModuleVersions[getRemoteModuleName(moduleName)] || 0;
|
||||
if (installed !== remote && update !== remote) {
|
||||
logger.log(`Module update available: ${moduleName}@${remote} [installed: ${installed}]`);
|
||||
updatesToDownload.push({ name: moduleName, version: remote });
|
||||
}
|
||||
}
|
||||
|
||||
events.append({
|
||||
type: UPDATE_CHECK_FINISHED,
|
||||
succeeded: true,
|
||||
updateCount: updatesToDownload.length,
|
||||
manualRequired: false
|
||||
});
|
||||
|
||||
if (updatesToDownload.length === 0) {
|
||||
logger.log(`No module updates available.`);
|
||||
} else {
|
||||
updatesToDownload.forEach(function (e) {
|
||||
return addModuleToDownloadQueue(e.name, e.version);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return function checkForModuleUpdates() {
|
||||
return _ref.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
let processDownloadQueue = (() => {
|
||||
var _ref2 = _asyncToGenerator(function* () {
|
||||
if (download.active) return;
|
||||
if (download.queue.length === 0) return;
|
||||
|
||||
download.active = true;
|
||||
|
||||
const queuedModule = download.queue[download.next];
|
||||
download.next += 1;
|
||||
|
||||
events.append({
|
||||
type: DOWNLOADING_MODULE,
|
||||
name: queuedModule.name,
|
||||
current: download.next,
|
||||
total: download.queue.length,
|
||||
foreground: !runningInBackground
|
||||
});
|
||||
|
||||
let progress = 0;
|
||||
let receivedBytes = 0;
|
||||
|
||||
const url = `${remoteBaseURL}/${encodeURIComponent(getRemoteModuleName(queuedModule.name))}/${encodeURIComponent(queuedModule.version)}`;
|
||||
logger.log(`Fetching ${queuedModule.name}@${queuedModule.version} from ${url}`);
|
||||
const headers = {};
|
||||
if (queuedModule.authToken) {
|
||||
headers['Authorization'] = queuedModule.authToken;
|
||||
}
|
||||
|
||||
const moduleZipPath = _path2.default.join(moduleDownloadPath, `${queuedModule.name}-${queuedModule.version}.zip`);
|
||||
const stream = _fs2.default.createWriteStream(moduleZipPath);
|
||||
stream.on('progress', function ({ receivedBytes: newReceivedBytes, totalBytes }) {
|
||||
receivedBytes = newReceivedBytes;
|
||||
const newProgress = Math.min(Math.floor(100 * (receivedBytes / totalBytes)), 100);
|
||||
if (progress !== newProgress) {
|
||||
progress = newProgress;
|
||||
logger.log(`Streaming ${queuedModule.name}@${queuedModule.version} to ${moduleZipPath}: ${progress}%`);
|
||||
events.append({
|
||||
type: DOWNLOADING_MODULE_PROGRESS,
|
||||
name: queuedModule.name,
|
||||
progress: progress
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
logger.log(`Streaming ${queuedModule.name}@${queuedModule.version} to ${moduleZipPath}`);
|
||||
|
||||
try {
|
||||
const response = yield request.get({
|
||||
url,
|
||||
qs: remoteQuery,
|
||||
headers,
|
||||
timeout: REQUEST_TIMEOUT,
|
||||
stream
|
||||
});
|
||||
|
||||
finishModuleDownload(queuedModule.name, queuedModule.version, moduleZipPath, receivedBytes, response.statusCode === 200);
|
||||
} catch (err) {
|
||||
logger.log(`Failed fetching module ${queuedModule.name}@${queuedModule.version}: ${String(err)}`);
|
||||
finishModuleDownload(queuedModule.name, queuedModule.version, null, receivedBytes, false);
|
||||
}
|
||||
});
|
||||
|
||||
return function processDownloadQueue() {
|
||||
return _ref2.apply(this, arguments);
|
||||
};
|
||||
})();
|
||||
|
||||
exports.initPathsOnly = initPathsOnly;
|
||||
exports.init = init;
|
||||
exports.checkForUpdates = checkForUpdates;
|
||||
|
@ -154,66 +12,63 @@ exports.isInstalled = isInstalled;
|
|||
exports.getInstalled = getInstalled;
|
||||
exports.install = install;
|
||||
exports.installPendingUpdates = installPendingUpdates;
|
||||
exports.supportsEventObjects = exports.events = exports.NO_PENDING_UPDATES = exports.INSTALLING_MODULE_PROGRESS = exports.INSTALLING_MODULE = exports.INSTALLING_MODULES_FINISHED = exports.DOWNLOADED_MODULE = exports.UPDATE_MANUALLY = exports.DOWNLOADING_MODULES_FINISHED = exports.DOWNLOADING_MODULE_PROGRESS = exports.DOWNLOADING_MODULE = exports.UPDATE_CHECK_FINISHED = exports.INSTALLED_MODULE = exports.CHECKING_FOR_UPDATES = void 0;
|
||||
|
||||
var _fs = require('fs');
|
||||
var _fs = _interopRequireDefault(require("fs"));
|
||||
|
||||
var _fs2 = _interopRequireDefault(_fs);
|
||||
var _path = _interopRequireDefault(require("path"));
|
||||
|
||||
var _path = require('path');
|
||||
var _module = _interopRequireDefault(require("module"));
|
||||
|
||||
var _path2 = _interopRequireDefault(_path);
|
||||
var _events = require("events");
|
||||
|
||||
var _module = require('module');
|
||||
var _mkdirp = _interopRequireDefault(require("mkdirp"));
|
||||
|
||||
var _module2 = _interopRequireDefault(_module);
|
||||
var _process = require("process");
|
||||
|
||||
var _events = require('events');
|
||||
var _yauzl = _interopRequireDefault(require("yauzl"));
|
||||
|
||||
var _mkdirp = require('mkdirp');
|
||||
var _Backoff = _interopRequireDefault(require("./Backoff"));
|
||||
|
||||
var _mkdirp2 = _interopRequireDefault(_mkdirp);
|
||||
var paths = _interopRequireWildcard(require("./paths"));
|
||||
|
||||
var _process = require('process');
|
||||
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
|
||||
|
||||
var _yauzl = require('yauzl');
|
||||
|
||||
var _yauzl2 = _interopRequireDefault(_yauzl);
|
||||
|
||||
var _Backoff = require('./Backoff');
|
||||
|
||||
var _Backoff2 = _interopRequireDefault(_Backoff);
|
||||
|
||||
var _paths = require('./paths');
|
||||
|
||||
var paths = _interopRequireWildcard(_paths);
|
||||
|
||||
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
|
||||
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } // Manages additional module installation and management.
|
||||
// Manages additional module installation and management.
|
||||
// We add the module folder path to require() lookup paths here.
|
||||
|
||||
// undocumented node API
|
||||
const originalFs = require('original-fs'); // events
|
||||
|
||||
|
||||
const originalFs = require('original-fs');
|
||||
const CHECKING_FOR_UPDATES = 'checking-for-updates';
|
||||
exports.CHECKING_FOR_UPDATES = CHECKING_FOR_UPDATES;
|
||||
const INSTALLED_MODULE = 'installed-module';
|
||||
exports.INSTALLED_MODULE = INSTALLED_MODULE;
|
||||
const UPDATE_CHECK_FINISHED = 'update-check-finished';
|
||||
exports.UPDATE_CHECK_FINISHED = UPDATE_CHECK_FINISHED;
|
||||
const DOWNLOADING_MODULE = 'downloading-module';
|
||||
exports.DOWNLOADING_MODULE = DOWNLOADING_MODULE;
|
||||
const DOWNLOADING_MODULE_PROGRESS = 'downloading-module-progress';
|
||||
exports.DOWNLOADING_MODULE_PROGRESS = DOWNLOADING_MODULE_PROGRESS;
|
||||
const DOWNLOADING_MODULES_FINISHED = 'downloading-modules-finished';
|
||||
exports.DOWNLOADING_MODULES_FINISHED = DOWNLOADING_MODULES_FINISHED;
|
||||
const UPDATE_MANUALLY = 'update-manually';
|
||||
exports.UPDATE_MANUALLY = UPDATE_MANUALLY;
|
||||
const DOWNLOADED_MODULE = 'downloaded-module';
|
||||
exports.DOWNLOADED_MODULE = DOWNLOADED_MODULE;
|
||||
const INSTALLING_MODULES_FINISHED = 'installing-modules-finished';
|
||||
exports.INSTALLING_MODULES_FINISHED = INSTALLING_MODULES_FINISHED;
|
||||
const INSTALLING_MODULE = 'installing-module';
|
||||
exports.INSTALLING_MODULE = INSTALLING_MODULE;
|
||||
const INSTALLING_MODULE_PROGRESS = 'installing-module-progress';
|
||||
exports.INSTALLING_MODULE_PROGRESS = INSTALLING_MODULE_PROGRESS;
|
||||
const NO_PENDING_UPDATES = 'no-pending-updates'; // settings
|
||||
|
||||
// events
|
||||
const CHECKING_FOR_UPDATES = exports.CHECKING_FOR_UPDATES = 'checking-for-updates';
|
||||
const INSTALLED_MODULE = exports.INSTALLED_MODULE = 'installed-module';
|
||||
const UPDATE_CHECK_FINISHED = exports.UPDATE_CHECK_FINISHED = 'update-check-finished';
|
||||
const DOWNLOADING_MODULE = exports.DOWNLOADING_MODULE = 'downloading-module';
|
||||
const DOWNLOADING_MODULE_PROGRESS = exports.DOWNLOADING_MODULE_PROGRESS = 'downloading-module-progress';
|
||||
const DOWNLOADING_MODULES_FINISHED = exports.DOWNLOADING_MODULES_FINISHED = 'downloading-modules-finished';
|
||||
const UPDATE_MANUALLY = exports.UPDATE_MANUALLY = 'update-manually';
|
||||
const DOWNLOADED_MODULE = exports.DOWNLOADED_MODULE = 'downloaded-module';
|
||||
const INSTALLING_MODULES_FINISHED = exports.INSTALLING_MODULES_FINISHED = 'installing-modules-finished';
|
||||
const INSTALLING_MODULE = exports.INSTALLING_MODULE = 'installing-module';
|
||||
const INSTALLING_MODULE_PROGRESS = exports.INSTALLING_MODULE_PROGRESS = 'installing-module-progress';
|
||||
const NO_PENDING_UPDATES = exports.NO_PENDING_UPDATES = 'no-pending-updates';
|
||||
|
||||
// settings
|
||||
exports.NO_PENDING_UPDATES = NO_PENDING_UPDATES;
|
||||
const ALWAYS_ALLOW_UPDATES = 'ALWAYS_ALLOW_UPDATES';
|
||||
const SKIP_HOST_UPDATE = 'SKIP_HOST_UPDATE';
|
||||
const SKIP_MODULE_UPDATE = 'SKIP_MODULE_UPDATE';
|
||||
|
@ -239,12 +94,15 @@ class Events extends _events.EventEmitter {
|
|||
_eventIsInteresting(evt) {
|
||||
return evt.type !== DOWNLOADING_MODULE_PROGRESS && evt.type !== INSTALLING_MODULE_PROGRESS;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class LogStream {
|
||||
constructor(logPath) {
|
||||
try {
|
||||
this.logStream = _fs2.default.createWriteStream(logPath, { flags: 'a' });
|
||||
this.logStream = _fs.default.createWriteStream(logPath, {
|
||||
flags: 'a'
|
||||
});
|
||||
} catch (e) {
|
||||
console.error(`Failed to create ${logPath}: ${String(e)}`);
|
||||
}
|
||||
|
@ -253,6 +111,7 @@ class LogStream {
|
|||
log(message) {
|
||||
message = `[Modules] ${message}`;
|
||||
console.log(message);
|
||||
|
||||
if (this.logStream) {
|
||||
this.logStream.write(message);
|
||||
this.logStream.write('\r\n');
|
||||
|
@ -265,14 +124,17 @@ class LogStream {
|
|||
this.logStream = null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const request = require('../app_bootstrap/request');
|
||||
const REQUEST_TIMEOUT = 15000;
|
||||
const backoff = new _Backoff2.default(1000, 20000);
|
||||
const events = exports.events = new Events();
|
||||
const supportsEventObjects = exports.supportsEventObjects = true;
|
||||
|
||||
const REQUEST_TIMEOUT = 15000;
|
||||
const backoff = new _Backoff.default(1000, 20000);
|
||||
const events = new Events();
|
||||
exports.events = events;
|
||||
const supportsEventObjects = true;
|
||||
exports.supportsEventObjects = supportsEventObjects;
|
||||
let logger;
|
||||
let locallyInstalledModules;
|
||||
let moduleInstallPath;
|
||||
|
@ -300,21 +162,22 @@ let runningInBackground = false;
|
|||
function initPathsOnly(_buildInfo) {
|
||||
if (locallyInstalledModules || moduleInstallPath) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If we have `localModulesRoot` in our buildInfo file, we do not fetch modules
|
||||
} // If we have `localModulesRoot` in our buildInfo file, we do not fetch modules
|
||||
// from remote, and rely on our locally bundled ones.
|
||||
// Typically used for development mode, or private builds.
|
||||
|
||||
|
||||
locallyInstalledModules = _buildInfo.localModulesRoot != null;
|
||||
|
||||
if (locallyInstalledModules) {
|
||||
if (_module2.default.globalPaths.indexOf(_buildInfo.localModulesRoot) === -1) {
|
||||
_module2.default.globalPaths.push(_buildInfo.localModulesRoot);
|
||||
if (_module.default.globalPaths.indexOf(_buildInfo.localModulesRoot) === -1) {
|
||||
_module.default.globalPaths.push(_buildInfo.localModulesRoot);
|
||||
}
|
||||
} else {
|
||||
moduleInstallPath = _path2.default.join(paths.getUserDataVersioned(), 'modules');
|
||||
if (_module2.default.globalPaths.indexOf(moduleInstallPath) === -1) {
|
||||
_module2.default.globalPaths.push(moduleInstallPath);
|
||||
moduleInstallPath = _path.default.join(paths.getUserDataVersioned(), 'modules');
|
||||
|
||||
if (_module.default.globalPaths.indexOf(moduleInstallPath) === -1) {
|
||||
_module.default.globalPaths.push(moduleInstallPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -324,21 +187,18 @@ function init(_endpoint, _settings, _buildInfo) {
|
|||
settings = _settings;
|
||||
const buildInfo = _buildInfo;
|
||||
updatable = buildInfo.version != '0.0.0' && !buildInfo.debug || settings.get(ALWAYS_ALLOW_UPDATES);
|
||||
|
||||
initPathsOnly(buildInfo);
|
||||
|
||||
logger = new LogStream(_path2.default.join(paths.getUserData(), 'modules.log'));
|
||||
logger = new LogStream(_path.default.join(paths.getUserData(), 'modules.log'));
|
||||
bootstrapping = false;
|
||||
hostUpdateAvailable = false;
|
||||
checkingForUpdates = false;
|
||||
skipHostUpdate = settings.get(SKIP_HOST_UPDATE) || !updatable;
|
||||
skipModuleUpdate = settings.get(SKIP_MODULE_UPDATE) || locallyInstalledModules || !updatable;
|
||||
localModuleVersionsFilePath = _path2.default.join(paths.getUserData(), 'local_module_versions.json');
|
||||
bootstrapManifestFilePath = _path2.default.join(paths.getResources(), 'bootstrap', 'manifest.json');
|
||||
localModuleVersionsFilePath = _path.default.join(paths.getUserData(), 'local_module_versions.json');
|
||||
bootstrapManifestFilePath = _path.default.join(paths.getResources(), 'bootstrap', 'manifest.json');
|
||||
installedModules = {};
|
||||
remoteModuleVersions = {};
|
||||
newInstallInProgress = {};
|
||||
|
||||
download = {
|
||||
// currently downloading
|
||||
active: false,
|
||||
|
@ -349,7 +209,6 @@ function init(_endpoint, _settings, _buildInfo) {
|
|||
// download failure count
|
||||
failures: 0
|
||||
};
|
||||
|
||||
unzip = {
|
||||
// currently unzipping
|
||||
active: false,
|
||||
|
@ -360,35 +219,34 @@ function init(_endpoint, _settings, _buildInfo) {
|
|||
// unzip failure count
|
||||
failures: 0
|
||||
};
|
||||
|
||||
logger.log(`Modules initializing`);
|
||||
logger.log(`Distribution: ${locallyInstalledModules ? 'local' : 'remote'}`);
|
||||
logger.log(`Host updates: ${skipHostUpdate ? 'disabled' : 'enabled'}`);
|
||||
logger.log(`Module updates: ${skipModuleUpdate ? 'disabled' : 'enabled'}`);
|
||||
|
||||
if (!locallyInstalledModules) {
|
||||
installedModulesFilePath = _path2.default.join(moduleInstallPath, 'installed.json');
|
||||
moduleDownloadPath = _path2.default.join(moduleInstallPath, 'pending');
|
||||
_mkdirp2.default.sync(moduleDownloadPath);
|
||||
installedModulesFilePath = _path.default.join(moduleInstallPath, 'installed.json');
|
||||
moduleDownloadPath = _path.default.join(moduleInstallPath, 'pending');
|
||||
|
||||
_mkdirp.default.sync(moduleDownloadPath);
|
||||
|
||||
logger.log(`Module install path: ${moduleInstallPath}`);
|
||||
logger.log(`Module installed file path: ${installedModulesFilePath}`);
|
||||
logger.log(`Module download path: ${moduleDownloadPath}`);
|
||||
|
||||
let failedLoadingInstalledModules = false;
|
||||
|
||||
try {
|
||||
installedModules = JSON.parse(_fs2.default.readFileSync(installedModulesFilePath));
|
||||
installedModules = JSON.parse(_fs.default.readFileSync(installedModulesFilePath));
|
||||
} catch (err) {
|
||||
failedLoadingInstalledModules = true;
|
||||
}
|
||||
|
||||
cleanDownloadedModules(installedModules);
|
||||
|
||||
bootstrapping = failedLoadingInstalledModules || settings.get(ALWAYS_BOOTSTRAP_MODULES);
|
||||
}
|
||||
|
||||
hostUpdater = require('../app_bootstrap/hostUpdater');
|
||||
// TODO: hostUpdater constants
|
||||
hostUpdater = require('../app_bootstrap/hostUpdater'); // TODO: hostUpdater constants
|
||||
|
||||
hostUpdater.on('checking-for-update', () => events.append({
|
||||
type: CHECKING_FOR_UPDATES
|
||||
}));
|
||||
|
@ -399,22 +257,25 @@ function init(_endpoint, _settings, _buildInfo) {
|
|||
hostUpdater.on('update-downloaded', () => hostOnUpdateDownloaded());
|
||||
hostUpdater.on('error', err => hostOnError(err));
|
||||
const setFeedURL = hostUpdater.setFeedURL.bind(hostUpdater);
|
||||
remoteBaseURL = `${endpoint}/modules/${buildInfo.releaseChannel}`; // eslint-disable-next-line camelcase
|
||||
|
||||
remoteBaseURL = `${endpoint}/modules/${buildInfo.releaseChannel}`;
|
||||
// eslint-disable-next-line camelcase
|
||||
remoteQuery = { host_version: buildInfo.version };
|
||||
remoteQuery = {
|
||||
host_version: buildInfo.version
|
||||
};
|
||||
|
||||
switch (process.platform) {
|
||||
case 'darwin':
|
||||
setFeedURL(`${endpoint}/updates/${buildInfo.releaseChannel}?platform=osx&version=${buildInfo.version}`);
|
||||
remoteQuery.platform = 'osx';
|
||||
break;
|
||||
|
||||
case 'win32':
|
||||
// Squirrel for Windows can't handle query params
|
||||
// https://github.com/Squirrel/Squirrel.Windows/issues/132
|
||||
setFeedURL(`${endpoint}/updates/${buildInfo.releaseChannel}`);
|
||||
remoteQuery.platform = 'win';
|
||||
break;
|
||||
|
||||
case 'linux':
|
||||
setFeedURL(`${endpoint}/updates/${buildInfo.releaseChannel}?platform=linux&version=${buildInfo.version}`);
|
||||
remoteQuery.platform = 'linux';
|
||||
|
@ -424,10 +285,12 @@ function init(_endpoint, _settings, _buildInfo) {
|
|||
|
||||
function cleanDownloadedModules(installedModules) {
|
||||
try {
|
||||
const entries = _fs2.default.readdirSync(moduleDownloadPath) || [];
|
||||
const entries = _fs.default.readdirSync(moduleDownloadPath) || [];
|
||||
entries.forEach(entry => {
|
||||
const entryPath = _path2.default.join(moduleDownloadPath, entry);
|
||||
const entryPath = _path.default.join(moduleDownloadPath, entry);
|
||||
|
||||
let isStale = true;
|
||||
|
||||
for (const moduleName of Object.keys(installedModules)) {
|
||||
if (entryPath === installedModules[moduleName].updateZipfile) {
|
||||
isStale = false;
|
||||
|
@ -436,7 +299,7 @@ function cleanDownloadedModules(installedModules) {
|
|||
}
|
||||
|
||||
if (isStale) {
|
||||
_fs2.default.unlinkSync(_path2.default.join(moduleDownloadPath, entry));
|
||||
_fs.default.unlinkSync(_path.default.join(moduleDownloadPath, entry));
|
||||
}
|
||||
});
|
||||
} catch (err) {
|
||||
|
@ -474,6 +337,7 @@ function hostOnUpdateProgress(progress) {
|
|||
|
||||
function hostOnUpdateNotAvailable() {
|
||||
logger.log(`Host is up to date.`);
|
||||
|
||||
if (!skipModuleUpdate) {
|
||||
checkForModuleUpdates();
|
||||
} else {
|
||||
|
@ -520,16 +384,16 @@ function hostOnUpdateDownloaded() {
|
|||
}
|
||||
|
||||
function hostOnError(err) {
|
||||
logger.log(`Host update failed: ${err}`);
|
||||
|
||||
// [adill] osx unsigned builds will fire this code signing error inside setFeedURL and
|
||||
logger.log(`Host update failed: ${err}`); // [adill] osx unsigned builds will fire this code signing error inside setFeedURL and
|
||||
// if we don't do anything about it hostUpdater.checkForUpdates() will never respond.
|
||||
|
||||
if (err && String(err).indexOf('Could not get code signature for running application') !== -1) {
|
||||
console.warn('Skipping host updates due to code signing failure.');
|
||||
skipHostUpdate = true;
|
||||
}
|
||||
|
||||
checkingForUpdates = false;
|
||||
|
||||
if (!hostUpdateAvailable) {
|
||||
events.append({
|
||||
type: UPDATE_CHECK_FINISHED,
|
||||
|
@ -555,22 +419,24 @@ function hostOnError(err) {
|
|||
|
||||
function checkForUpdates() {
|
||||
if (checkingForUpdates) return;
|
||||
|
||||
checkingForUpdates = true;
|
||||
hostUpdateAvailable = false;
|
||||
|
||||
if (skipHostUpdate) {
|
||||
events.append({ type: CHECKING_FOR_UPDATES });
|
||||
events.append({
|
||||
type: CHECKING_FOR_UPDATES
|
||||
});
|
||||
hostOnUpdateNotAvailable();
|
||||
} else {
|
||||
logger.log('Checking for host updates.');
|
||||
hostUpdater.checkForUpdates();
|
||||
}
|
||||
}
|
||||
|
||||
// Indicates that the initial update process is complete and that future updates
|
||||
} // Indicates that the initial update process is complete and that future updates
|
||||
// are background updates. This merely affects the content of the events sent to
|
||||
// the app so that analytics can correctly attribute module download/installs
|
||||
// depending on whether they were ui-blocking or not.
|
||||
|
||||
|
||||
function setInBackground() {
|
||||
runningInBackground = true;
|
||||
}
|
||||
|
@ -583,14 +449,154 @@ function getRemoteModuleName(name) {
|
|||
return name;
|
||||
}
|
||||
|
||||
async function checkForModuleUpdates() {
|
||||
const query = { ...remoteQuery,
|
||||
_: Math.floor(Date.now() / 1000 / 60 / 5)
|
||||
};
|
||||
const url = `${remoteBaseURL}/versions.json`;
|
||||
logger.log(`Checking for module updates at ${url}`);
|
||||
let response;
|
||||
|
||||
try {
|
||||
response = await request.get({
|
||||
url,
|
||||
qs: query,
|
||||
timeout: REQUEST_TIMEOUT
|
||||
});
|
||||
checkingForUpdates = false;
|
||||
} catch (err) {
|
||||
checkingForUpdates = false;
|
||||
logger.log(`Failed fetching module versions: ${String(err)}`);
|
||||
events.append({
|
||||
type: UPDATE_CHECK_FINISHED,
|
||||
succeeded: false,
|
||||
updateCount: 0,
|
||||
manualRequired: false
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
remoteModuleVersions = JSON.parse(response.body);
|
||||
|
||||
if (settings.get(USE_LOCAL_MODULE_VERSIONS)) {
|
||||
try {
|
||||
remoteModuleVersions = JSON.parse(_fs.default.readFileSync(localModuleVersionsFilePath));
|
||||
console.log('Using local module versions: ', remoteModuleVersions);
|
||||
} catch (err) {
|
||||
console.warn('Failed to parse local module versions: ', err);
|
||||
}
|
||||
}
|
||||
|
||||
const updatesToDownload = [];
|
||||
|
||||
for (const moduleName of Object.keys(installedModules)) {
|
||||
const installedModule = installedModules[moduleName];
|
||||
const installed = installedModule.installedVersion;
|
||||
|
||||
if (installed === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const update = installedModule.updateVersion || 0;
|
||||
const remote = remoteModuleVersions[getRemoteModuleName(moduleName)] || 0;
|
||||
|
||||
if (installed !== remote && update !== remote) {
|
||||
logger.log(`Module update available: ${moduleName}@${remote} [installed: ${installed}]`);
|
||||
updatesToDownload.push({
|
||||
name: moduleName,
|
||||
version: remote
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
events.append({
|
||||
type: UPDATE_CHECK_FINISHED,
|
||||
succeeded: true,
|
||||
updateCount: updatesToDownload.length,
|
||||
manualRequired: false
|
||||
});
|
||||
|
||||
if (updatesToDownload.length === 0) {
|
||||
logger.log(`No module updates available.`);
|
||||
} else {
|
||||
updatesToDownload.forEach(e => addModuleToDownloadQueue(e.name, e.version));
|
||||
}
|
||||
}
|
||||
|
||||
function addModuleToDownloadQueue(name, version, authToken) {
|
||||
download.queue.push({ name, version, authToken });
|
||||
download.queue.push({
|
||||
name,
|
||||
version,
|
||||
authToken
|
||||
});
|
||||
process.nextTick(() => processDownloadQueue());
|
||||
}
|
||||
|
||||
async function processDownloadQueue() {
|
||||
if (download.active) return;
|
||||
if (download.queue.length === 0) return;
|
||||
download.active = true;
|
||||
const queuedModule = download.queue[download.next];
|
||||
download.next += 1;
|
||||
events.append({
|
||||
type: DOWNLOADING_MODULE,
|
||||
name: queuedModule.name,
|
||||
current: download.next,
|
||||
total: download.queue.length,
|
||||
foreground: !runningInBackground
|
||||
});
|
||||
let progress = 0;
|
||||
let receivedBytes = 0;
|
||||
const url = `${remoteBaseURL}/${encodeURIComponent(getRemoteModuleName(queuedModule.name))}/${encodeURIComponent(queuedModule.version)}`;
|
||||
logger.log(`Fetching ${queuedModule.name}@${queuedModule.version} from ${url}`);
|
||||
const headers = {};
|
||||
|
||||
if (queuedModule.authToken) {
|
||||
headers['Authorization'] = queuedModule.authToken;
|
||||
}
|
||||
|
||||
const moduleZipPath = _path.default.join(moduleDownloadPath, `${queuedModule.name}-${queuedModule.version}.zip`);
|
||||
|
||||
const stream = _fs.default.createWriteStream(moduleZipPath);
|
||||
|
||||
stream.on('progress', ({
|
||||
receivedBytes: newReceivedBytes,
|
||||
totalBytes
|
||||
}) => {
|
||||
receivedBytes = newReceivedBytes;
|
||||
const newProgress = Math.min(Math.floor(100 * (receivedBytes / totalBytes)), 100);
|
||||
|
||||
if (progress !== newProgress) {
|
||||
progress = newProgress;
|
||||
logger.log(`Streaming ${queuedModule.name}@${queuedModule.version} to ${moduleZipPath}: ${progress}%`);
|
||||
events.append({
|
||||
type: DOWNLOADING_MODULE_PROGRESS,
|
||||
name: queuedModule.name,
|
||||
progress: progress
|
||||
});
|
||||
}
|
||||
});
|
||||
logger.log(`Streaming ${queuedModule.name}@${queuedModule.version} to ${moduleZipPath}`);
|
||||
|
||||
try {
|
||||
const response = await request.get({
|
||||
url,
|
||||
qs: remoteQuery,
|
||||
headers,
|
||||
timeout: REQUEST_TIMEOUT,
|
||||
stream
|
||||
});
|
||||
finishModuleDownload(queuedModule.name, queuedModule.version, moduleZipPath, receivedBytes, response.statusCode === 200);
|
||||
} catch (err) {
|
||||
logger.log(`Failed fetching module ${queuedModule.name}@${queuedModule.version}: ${String(err)}`);
|
||||
finishModuleDownload(queuedModule.name, queuedModule.version, null, receivedBytes, false);
|
||||
}
|
||||
}
|
||||
|
||||
function commitInstalledModules() {
|
||||
const data = JSON.stringify(installedModules, null, 2);
|
||||
_fs2.default.writeFileSync(installedModulesFilePath, data);
|
||||
|
||||
_fs.default.writeFileSync(installedModulesFilePath, data);
|
||||
}
|
||||
|
||||
function finishModuleDownload(name, version, zipfile, receivedBytes, succeeded) {
|
||||
|
@ -648,21 +654,22 @@ function finishModuleDownload(name, version, zipfile, receivedBytes, succeeded)
|
|||
}
|
||||
|
||||
function addModuleToUnzipQueue(name, version, zipfile) {
|
||||
unzip.queue.push({ name, version, zipfile });
|
||||
unzip.queue.push({
|
||||
name,
|
||||
version,
|
||||
zipfile
|
||||
});
|
||||
process.nextTick(() => processUnzipQueue());
|
||||
}
|
||||
|
||||
function processUnzipQueue() {
|
||||
if (unzip.active) return;
|
||||
if (unzip.queue.length === 0) return;
|
||||
|
||||
unzip.active = true;
|
||||
|
||||
const queuedModule = unzip.queue[unzip.next];
|
||||
const installedModule = installedModules[queuedModule.name];
|
||||
const installedVersion = installedModule != null ? installedModule.installedVersion : null;
|
||||
unzip.next += 1;
|
||||
|
||||
events.append({
|
||||
type: INSTALLING_MODULE,
|
||||
name: queuedModule.name,
|
||||
|
@ -672,22 +679,25 @@ function processUnzipQueue() {
|
|||
oldVersion: installedVersion,
|
||||
newVersion: queuedModule.version
|
||||
});
|
||||
|
||||
let hasErrored = false;
|
||||
|
||||
const onError = (error, zipfile) => {
|
||||
if (hasErrored) return;
|
||||
hasErrored = true;
|
||||
|
||||
logger.log(`Failed installing ${queuedModule.name}@${queuedModule.version}: ${String(error)}`);
|
||||
succeeded = false;
|
||||
|
||||
if (zipfile) {
|
||||
zipfile.close();
|
||||
}
|
||||
|
||||
finishModuleUnzip(queuedModule, succeeded);
|
||||
};
|
||||
|
||||
let succeeded = true;
|
||||
const extractRoot = _path2.default.join(moduleInstallPath, queuedModule.name);
|
||||
|
||||
const extractRoot = _path.default.join(moduleInstallPath, queuedModule.name);
|
||||
|
||||
logger.log(`Installing ${queuedModule.name}@${queuedModule.version} from ${queuedModule.zipfile}`);
|
||||
|
||||
const processZipfile = (err, zipfile) => {
|
||||
|
@ -698,7 +708,6 @@ function processUnzipQueue() {
|
|||
|
||||
const totalEntries = zipfile.entryCount;
|
||||
let processedEntries = 0;
|
||||
|
||||
zipfile.on('entry', entry => {
|
||||
processedEntries += 1;
|
||||
const percent = Math.min(Math.floor(processedEntries / totalEntries * 100), 100);
|
||||
|
@ -706,9 +715,8 @@ function processUnzipQueue() {
|
|||
type: INSTALLING_MODULE_PROGRESS,
|
||||
name: queuedModule.name,
|
||||
progress: percent
|
||||
});
|
||||
}); // skip directories
|
||||
|
||||
// skip directories
|
||||
if (/\/$/.test(entry.fileName)) {
|
||||
zipfile.readEntry();
|
||||
return;
|
||||
|
@ -721,61 +729,62 @@ function processUnzipQueue() {
|
|||
}
|
||||
|
||||
stream.on('error', e => onError(e, zipfile));
|
||||
|
||||
(0, _mkdirp2.default)(_path2.default.join(extractRoot, _path2.default.dirname(entry.fileName)), err => {
|
||||
(0, _mkdirp.default)(_path.default.join(extractRoot, _path.default.dirname(entry.fileName)), err => {
|
||||
if (err) {
|
||||
onError(err, zipfile);
|
||||
return;
|
||||
}
|
||||
|
||||
// [adill] createWriteStream via original-fs is broken in Electron 4.0.0-beta.6 with .asar files
|
||||
} // [adill] createWriteStream via original-fs is broken in Electron 4.0.0-beta.6 with .asar files
|
||||
// so we unzip to a temporary filename and rename it afterwards
|
||||
const tempFileName = _path2.default.join(extractRoot, entry.fileName + '.tmp');
|
||||
const finalFileName = _path2.default.join(extractRoot, entry.fileName);
|
||||
const writeStream = originalFs.createWriteStream(tempFileName);
|
||||
|
||||
|
||||
const tempFileName = _path.default.join(extractRoot, entry.fileName + '.tmp');
|
||||
|
||||
const finalFileName = _path.default.join(extractRoot, entry.fileName);
|
||||
|
||||
const writeStream = originalFs.createWriteStream(tempFileName);
|
||||
writeStream.on('error', e => {
|
||||
stream.destroy();
|
||||
|
||||
try {
|
||||
originalFs.unlinkSync(tempFileName);
|
||||
} catch (err) {}
|
||||
|
||||
onError(e, zipfile);
|
||||
});
|
||||
|
||||
writeStream.on('finish', () => {
|
||||
try {
|
||||
originalFs.unlinkSync(finalFileName);
|
||||
} catch (err) {}
|
||||
|
||||
try {
|
||||
originalFs.renameSync(tempFileName, finalFileName);
|
||||
} catch (err) {
|
||||
onError(err, zipfile);
|
||||
return;
|
||||
}
|
||||
|
||||
zipfile.readEntry();
|
||||
});
|
||||
|
||||
stream.pipe(writeStream);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
zipfile.on('error', err => {
|
||||
onError(err, zipfile);
|
||||
});
|
||||
|
||||
zipfile.on('end', () => {
|
||||
if (!succeeded) return;
|
||||
|
||||
installedModules[queuedModule.name].installedVersion = queuedModule.version;
|
||||
finishModuleUnzip(queuedModule, succeeded);
|
||||
});
|
||||
|
||||
zipfile.readEntry();
|
||||
};
|
||||
|
||||
try {
|
||||
_yauzl2.default.open(queuedModule.zipfile, { lazyEntries: true, autoClose: true }, processZipfile);
|
||||
_yauzl.default.open(queuedModule.zipfile, {
|
||||
lazyEntries: true,
|
||||
autoClose: true
|
||||
}, processZipfile);
|
||||
} catch (err) {
|
||||
onError(err, null);
|
||||
}
|
||||
|
@ -823,6 +832,7 @@ function finishModuleUnzip(unzippedModule, succeeded) {
|
|||
|
||||
function quitAndInstallUpdates() {
|
||||
logger.log(`Relaunching to install ${hostUpdateAvailable ? 'host' : 'module'} updates...`);
|
||||
|
||||
if (hostUpdateAvailable) {
|
||||
hostUpdater.quitAndInstall();
|
||||
} else {
|
||||
|
@ -832,7 +842,11 @@ function quitAndInstallUpdates() {
|
|||
|
||||
function relaunch() {
|
||||
logger.end();
|
||||
const { app } = require('electron');
|
||||
|
||||
const {
|
||||
app
|
||||
} = require('electron');
|
||||
|
||||
app.relaunch();
|
||||
app.quit();
|
||||
}
|
||||
|
@ -840,19 +854,26 @@ function relaunch() {
|
|||
function isInstalled(name, version) {
|
||||
const metadata = installedModules[name];
|
||||
if (locallyInstalledModules) return true;
|
||||
|
||||
if (metadata && metadata.installedVersion > 0) {
|
||||
if (!version) return true;
|
||||
if (metadata.installedVersion === version) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function getInstalled() {
|
||||
return _extends({}, installedModules);
|
||||
return { ...installedModules
|
||||
};
|
||||
}
|
||||
|
||||
function install(name, defer, options) {
|
||||
let { version, authToken } = options || {};
|
||||
let {
|
||||
version,
|
||||
authToken
|
||||
} = options || {};
|
||||
|
||||
if (isInstalled(name, version)) {
|
||||
if (!defer) {
|
||||
events.append({
|
||||
|
@ -863,6 +884,7 @@ function install(name, defer, options) {
|
|||
succeeded: true
|
||||
});
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -877,14 +899,19 @@ function install(name, defer, options) {
|
|||
if (version) {
|
||||
throw new Error(`Cannot defer install for a specific version module (${name}, ${version})`);
|
||||
}
|
||||
|
||||
logger.log(`Deferred install for ${name}...`);
|
||||
installedModules[name] = { installedVersion: 0 };
|
||||
installedModules[name] = {
|
||||
installedVersion: 0
|
||||
};
|
||||
commitInstalledModules();
|
||||
} else {
|
||||
logger.log(`Starting to install ${name}...`);
|
||||
|
||||
if (!version) {
|
||||
version = remoteModuleVersions[name] || 0;
|
||||
}
|
||||
|
||||
newInstallInProgress[name] = version;
|
||||
addModuleToDownloadQueue(name, version, authToken);
|
||||
}
|
||||
|
@ -895,22 +922,36 @@ function installPendingUpdates() {
|
|||
|
||||
if (bootstrapping) {
|
||||
let modules = {};
|
||||
|
||||
try {
|
||||
modules = JSON.parse(_fs2.default.readFileSync(bootstrapManifestFilePath));
|
||||
modules = JSON.parse(_fs.default.readFileSync(bootstrapManifestFilePath));
|
||||
} catch (err) {}
|
||||
|
||||
for (const moduleName of Object.keys(modules)) {
|
||||
installedModules[moduleName] = { installedVersion: 0 };
|
||||
const zipfile = _path2.default.join(paths.getResources(), 'bootstrap', `${moduleName}.zip`);
|
||||
updatesToInstall.push({ moduleName, update: modules[moduleName], zipfile });
|
||||
installedModules[moduleName] = {
|
||||
installedVersion: 0
|
||||
};
|
||||
|
||||
const zipfile = _path.default.join(paths.getResources(), 'bootstrap', `${moduleName}.zip`);
|
||||
|
||||
updatesToInstall.push({
|
||||
moduleName,
|
||||
update: modules[moduleName],
|
||||
zipfile
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
for (const moduleName of Object.keys(installedModules)) {
|
||||
const update = installedModules[moduleName].updateVersion || 0;
|
||||
const zipfile = installedModules[moduleName].updateZipfile;
|
||||
|
||||
if (update > 0 && zipfile != null) {
|
||||
updatesToInstall.push({ moduleName, update, zipfile });
|
||||
updatesToInstall.push({
|
||||
moduleName,
|
||||
update,
|
||||
zipfile
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
'use strict';
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
|
@ -8,23 +8,16 @@ exports.init = init;
|
|||
exports.getUserData = getUserData;
|
||||
exports.getUserDataVersioned = getUserDataVersioned;
|
||||
exports.getResources = getResources;
|
||||
exports.getModulePath = getModulePath;
|
||||
exports.getModuleDataPath = getModuleDataPath;
|
||||
exports.getInstallPath = getInstallPath;
|
||||
|
||||
var _fs = require('fs');
|
||||
var _fs = _interopRequireDefault(require("fs"));
|
||||
|
||||
var _fs2 = _interopRequireDefault(_fs);
|
||||
var _mkdirp = _interopRequireDefault(require("mkdirp"));
|
||||
|
||||
var _mkdirp = require('mkdirp');
|
||||
var _path = _interopRequireDefault(require("path"));
|
||||
|
||||
var _mkdirp2 = _interopRequireDefault(_mkdirp);
|
||||
|
||||
var _path = require('path');
|
||||
|
||||
var _path2 = _interopRequireDefault(_path);
|
||||
|
||||
var _rimraf = require('rimraf');
|
||||
|
||||
var _rimraf2 = _interopRequireDefault(_rimraf);
|
||||
var _rimraf = _interopRequireDefault(require("rimraf"));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
|
@ -34,26 +27,31 @@ const originalFs = require('original-fs');
|
|||
let userDataPath = null;
|
||||
let userDataVersionedPath = null;
|
||||
let resourcesPath = null;
|
||||
let modulePath = null;
|
||||
let moduleDataPath = null;
|
||||
let installPath = null;
|
||||
|
||||
function determineAppUserDataRoot() {
|
||||
const { app } = require('electron');
|
||||
const {
|
||||
app
|
||||
} = require('electron');
|
||||
|
||||
return app.getPath('appData');
|
||||
}
|
||||
|
||||
function determineUserData(userDataRoot, buildInfo) {
|
||||
return _path2.default.join(userDataRoot, 'discord' + (buildInfo.releaseChannel == 'stable' ? '' : buildInfo.releaseChannel));
|
||||
}
|
||||
return _path.default.join(userDataRoot, 'discord' + (buildInfo.releaseChannel == 'stable' ? '' : buildInfo.releaseChannel));
|
||||
} // cleans old version data in the background
|
||||
|
||||
|
||||
// cleans old version data in the background
|
||||
function cleanOldVersions(buildInfo) {
|
||||
const entries = _fs2.default.readdirSync(userDataPath) || [];
|
||||
const entries = _fs.default.readdirSync(userDataPath) || [];
|
||||
entries.forEach(entry => {
|
||||
const fullPath = _path2.default.join(userDataPath, entry);
|
||||
if (_fs2.default.statSync(fullPath).isDirectory() && entry.indexOf(buildInfo.version) === -1) {
|
||||
const fullPath = _path.default.join(userDataPath, entry);
|
||||
|
||||
if (_fs.default.lstatSync(fullPath).isDirectory() && entry.indexOf(buildInfo.version) === -1) {
|
||||
if (entry.match('^[0-9]+.[0-9]+.[0-9]+') != null) {
|
||||
console.log('Removing old directory ', entry);
|
||||
(0, _rimraf2.default)(fullPath, originalFs, error => {
|
||||
(0, _rimraf.default)(fullPath, originalFs, error => {
|
||||
if (error) {
|
||||
console.warn('...failed with error: ', error);
|
||||
}
|
||||
|
@ -64,19 +62,32 @@ function cleanOldVersions(buildInfo) {
|
|||
}
|
||||
|
||||
function init(buildInfo) {
|
||||
resourcesPath = _path2.default.join(require.main.filename, '..', '..', '..');
|
||||
|
||||
resourcesPath = _path.default.join(require.main.filename, '..', '..', '..');
|
||||
const userDataRoot = determineAppUserDataRoot();
|
||||
|
||||
userDataPath = determineUserData(userDataRoot, buildInfo);
|
||||
|
||||
const { app } = require('electron');
|
||||
const {
|
||||
app
|
||||
} = require('electron');
|
||||
|
||||
app.setPath('userData', userDataPath);
|
||||
userDataVersionedPath = _path.default.join(userDataPath, buildInfo.version);
|
||||
|
||||
userDataVersionedPath = _path2.default.join(userDataPath, buildInfo.version);
|
||||
_mkdirp2.default.sync(userDataVersionedPath);
|
||||
_mkdirp.default.sync(userDataVersionedPath);
|
||||
|
||||
modulePath = buildInfo.localModulesRoot ? buildInfo.localModulesRoot : _path2.default.join(userDataVersionedPath, 'modules');
|
||||
if (buildInfo.localModulesRoot != null) {
|
||||
moduleDataPath = buildInfo.localModulesRoot;
|
||||
} else if (buildInfo.newUpdater) {
|
||||
moduleDataPath = _path.default.join(userDataPath, 'module_data');
|
||||
} else {
|
||||
moduleDataPath = _path.default.join(userDataVersionedPath, 'modules');
|
||||
}
|
||||
|
||||
const exeDir = _path.default.dirname(app.getPath('exe'));
|
||||
|
||||
if (/^app-[0-9]+\.[0-9]+\.[0-9]+/.test(_path.default.basename(exeDir))) {
|
||||
installPath = _path.default.join(exeDir, '..');
|
||||
}
|
||||
}
|
||||
|
||||
function getUserData() {
|
||||
|
@ -91,6 +102,10 @@ function getResources() {
|
|||
return resourcesPath;
|
||||
}
|
||||
|
||||
function getModulePath() {
|
||||
return modulePath;
|
||||
function getModuleDataPath() {
|
||||
return moduleDataPath;
|
||||
}
|
||||
|
||||
function getInstallPath() {
|
||||
return installPath;
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.getElectronMajorVersion = getElectronMajorVersion;
|
||||
|
||||
const process = require('process');
|
||||
|
||||
function getElectronMajorVersion() {
|
||||
return process.versions.electron != null ? parseInt(process.versions.electron.split('.')[0]) : 0;
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.saferShellOpenExternal = saferShellOpenExternal;
|
||||
|
||||
var _electron = require("electron");
|
||||
|
||||
var _url = _interopRequireDefault(require("url"));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
const BLOCKED_URL_PROTOCOLS = ['file:', 'javascript:', 'vbscript:', 'data:', 'about:', 'chrome:', 'ms-cxh:', 'ms-cxh-full:', 'ms-word:'];
|
||||
|
||||
function saferShellOpenExternal(externalUrl) {
|
||||
let parsedUrl;
|
||||
|
||||
try {
|
||||
parsedUrl = _url.default.parse(externalUrl);
|
||||
} catch (_) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (parsedUrl.protocol == null || BLOCKED_URL_PROTOCOLS.includes(parsedUrl.protocol.toLowerCase())) {
|
||||
return;
|
||||
}
|
||||
|
||||
_electron.shell.openExternal(externalUrl);
|
||||
}
|
|
@ -0,0 +1,403 @@
|
|||
"use strict";
|
||||
|
||||
// Too much Rust integration stuff in here.
|
||||
|
||||
/* eslint camelcase: 0 */
|
||||
const childProcess = require('child_process');
|
||||
|
||||
const {
|
||||
app
|
||||
} = require('electron');
|
||||
|
||||
const {
|
||||
EventEmitter
|
||||
} = require('events');
|
||||
|
||||
const NodeModule = require('module');
|
||||
|
||||
const path = require('path');
|
||||
|
||||
const {
|
||||
hrtime
|
||||
} = require('process');
|
||||
|
||||
let instance;
|
||||
const TASK_STATE_COMPLETE = 'Complete';
|
||||
const TASK_STATE_FAILED = 'Failed';
|
||||
const TASK_STATE_WAITING = 'Waiting';
|
||||
const TASK_STATE_WORKING = 'Working';
|
||||
|
||||
class Updater extends EventEmitter {
|
||||
constructor(options) {
|
||||
super();
|
||||
let nativeUpdaterModule = options.nativeUpdaterModule;
|
||||
|
||||
if (nativeUpdaterModule == null) {
|
||||
try {
|
||||
// eslint-disable-next-line import/no-unresolved
|
||||
nativeUpdaterModule = require('../../../updater');
|
||||
} catch (e) {
|
||||
if (e.code === 'MODULE_NOT_FOUND') {
|
||||
return;
|
||||
}
|
||||
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
this.committedHostVersion = null;
|
||||
this.committedModules = new Set();
|
||||
this.rootPath = options.root_path;
|
||||
this.nextRequestId = 0;
|
||||
this.requests = new Map();
|
||||
this.updateEventHistory = [];
|
||||
this.isRunningInBackground = false;
|
||||
this.currentlyDownloading = {};
|
||||
this.currentlyInstalling = {};
|
||||
this.hasEmittedUnhandledException = false;
|
||||
this.nativeUpdater = new nativeUpdaterModule.Updater({
|
||||
response_handler: this._handleResponse.bind(this),
|
||||
...options
|
||||
});
|
||||
}
|
||||
|
||||
get valid() {
|
||||
return this.nativeUpdater != null;
|
||||
}
|
||||
|
||||
_sendRequest(detail, progressCallback = null) {
|
||||
if (!this.valid) {
|
||||
// The dumb linters are mad at each other.
|
||||
// eslint-disable-next-line quotes
|
||||
throw new Error("Can't send request to updater because the native updater isn't loaded.");
|
||||
}
|
||||
|
||||
const requestId = this.nextRequestId++;
|
||||
return new Promise((resolve, reject) => {
|
||||
this.requests.set(requestId, {
|
||||
resolve,
|
||||
reject,
|
||||
progressCallback
|
||||
});
|
||||
this.nativeUpdater.command(JSON.stringify([requestId, detail]));
|
||||
});
|
||||
}
|
||||
|
||||
_sendRequestSync(detail) {
|
||||
if (!this.valid) {
|
||||
// eslint-disable-next-line quotes
|
||||
throw new Error("Can't send request to updater because the native updater isn't loaded.");
|
||||
}
|
||||
|
||||
const requestId = this.nextRequestId++;
|
||||
return this.nativeUpdater.command_blocking(JSON.stringify([requestId, detail]));
|
||||
}
|
||||
|
||||
_handleResponse(response) {
|
||||
try {
|
||||
const [id, detail] = JSON.parse(response);
|
||||
const request = this.requests.get(id);
|
||||
|
||||
if (request == null) {
|
||||
console.error('Received response ', detail, ' for a request (', id, ') not in the updater request map.');
|
||||
return;
|
||||
}
|
||||
|
||||
if (detail['Error'] != null) {
|
||||
request.reject(new Error(detail['Error']));
|
||||
this.requests.delete(id);
|
||||
} else if (detail === 'Ok') {
|
||||
request.resolve();
|
||||
this.requests.delete(id);
|
||||
} else if (detail['VersionInfo'] != null) {
|
||||
request.resolve(detail['VersionInfo']);
|
||||
this.requests.delete(id);
|
||||
} else if (detail['ManifestInfo'] != null) {
|
||||
request.resolve(detail['ManifestInfo']);
|
||||
this.requests.delete(id);
|
||||
} else if (detail['TaskProgress'] != null) {
|
||||
const msg = detail['TaskProgress'];
|
||||
const progress = {
|
||||
task: msg[0],
|
||||
state: msg[1],
|
||||
percent: msg[2],
|
||||
bytesProcessed: msg[3]
|
||||
};
|
||||
|
||||
this._recordTaskProgress(progress);
|
||||
|
||||
if (request.progressCallback != null) {
|
||||
request.progressCallback(progress);
|
||||
}
|
||||
|
||||
if (progress.task['HostInstall'] != null && progress.state === 'Complete') {
|
||||
this.emit('host-updated');
|
||||
}
|
||||
} else {
|
||||
console.warn('Unknown updater response', detail);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Unhandled exception in updater response handler:', e); // Report the first time this happens, but don't spam.
|
||||
|
||||
if (!this.hasEmittedUnhandledException) {
|
||||
this.hasEmittedUnhandledException = true;
|
||||
this.emit('unhandled-exception', e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_handleSyncResponse(response) {
|
||||
const detail = JSON.parse(response);
|
||||
|
||||
if (detail['Error'] != null) {
|
||||
throw new Error(detail['Error']);
|
||||
} else if (detail === 'Ok') {
|
||||
return;
|
||||
} else if (detail['VersionInfo'] != null) {
|
||||
return detail['VersionInfo'];
|
||||
}
|
||||
|
||||
console.warn('Unknown updater response', detail);
|
||||
}
|
||||
|
||||
_getHostPath() {
|
||||
const [major, minor, revision] = this.committedHostVersion;
|
||||
const hostVersionStr = `${major}.${minor}.${revision}`;
|
||||
return path.join(this.rootPath, `app-${hostVersionStr}`);
|
||||
}
|
||||
|
||||
_startCurrentVersionInner(options, versions) {
|
||||
if (this.committedHostVersion == null) {
|
||||
this.committedHostVersion = versions.current_host;
|
||||
}
|
||||
|
||||
const hostPath = this._getHostPath();
|
||||
|
||||
const hostExePath = path.join(hostPath, path.basename(process.execPath));
|
||||
|
||||
if (path.resolve(hostExePath) != path.resolve(process.execPath) && !(options === null || options === void 0 ? void 0 : options.allowObsoleteHost)) {
|
||||
app.once('will-quit', () => {
|
||||
// TODO(eiz): the actual, correct way to do this (win32) is to inherit a
|
||||
// handle to the current process into a new child process which then
|
||||
// waits for that process handle to exit, then runs the new electron.
|
||||
// This requires either implementing a separate updater exe process (big
|
||||
// todo item atm) or likely modifying Electron?
|
||||
//
|
||||
// I intend to do it properly once the new production updater .exe is a
|
||||
// thing.
|
||||
childProcess.spawn(hostExePath, [], {
|
||||
detached: true,
|
||||
stdio: 'inherit'
|
||||
});
|
||||
});
|
||||
console.log(`Restarting from ${path.resolve(process.execPath)} to ${path.resolve(hostExePath)}`);
|
||||
app.quit();
|
||||
return;
|
||||
}
|
||||
|
||||
this._commitModulesInner(versions);
|
||||
}
|
||||
|
||||
_commitModulesInner(versions) {
|
||||
const hostPath = this._getHostPath();
|
||||
|
||||
const modulesPath = path.join(hostPath, 'modules');
|
||||
|
||||
for (const module in versions.current_modules) {
|
||||
const moduleVersion = versions.current_modules[module];
|
||||
const moduleSearchPath = path.join(modulesPath, `${module}-${moduleVersion}`);
|
||||
|
||||
if (!this.committedModules.has(module) && NodeModule.globalPaths.indexOf(moduleSearchPath) === -1) {
|
||||
this.committedModules.add(module);
|
||||
NodeModule.globalPaths.push(moduleSearchPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_recordDownloadProgress(name, progress) {
|
||||
const now = String(hrtime.bigint());
|
||||
|
||||
if (progress.state === TASK_STATE_WORKING && !this.currentlyDownloading[name]) {
|
||||
this.currentlyDownloading[name] = true;
|
||||
this.updateEventHistory.push({
|
||||
type: 'downloading-module',
|
||||
name: name,
|
||||
now: now
|
||||
});
|
||||
} else if (progress.state === TASK_STATE_COMPLETE || progress.state === TASK_STATE_FAILED) {
|
||||
this.currentlyDownloading[name] = false;
|
||||
this.updateEventHistory.push({
|
||||
type: 'downloaded-module',
|
||||
name: name,
|
||||
now: now,
|
||||
succeeded: progress.state === TASK_STATE_COMPLETE,
|
||||
receivedBytes: progress.bytesProcessed
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
_recordInstallProgress(name, progress, newVersion, isDelta) {
|
||||
const now = String(hrtime.bigint());
|
||||
|
||||
if (progress.state === TASK_STATE_WORKING && !this.currentlyInstalling[name]) {
|
||||
this.currentlyInstalling[name] = true;
|
||||
this.updateEventHistory.push({
|
||||
type: 'installing-module',
|
||||
name,
|
||||
now,
|
||||
newVersion,
|
||||
foreground: !this.isRunningInBackground
|
||||
});
|
||||
} else if (progress.state === TASK_STATE_COMPLETE || progress.state === TASK_STATE_FAILED) {
|
||||
this.currentlyInstalling[name] = false;
|
||||
this.updateEventHistory.push({
|
||||
type: 'installed-module',
|
||||
name,
|
||||
now,
|
||||
newVersion,
|
||||
succeeded: progress.state === TASK_STATE_COMPLETE,
|
||||
delta: isDelta,
|
||||
foreground: !this.isRunningInBackground
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
_recordTaskProgress(progress) {
|
||||
if (progress.task.HostDownload != null) {
|
||||
this._recordDownloadProgress('host', progress);
|
||||
} else if (progress.task.HostInstall != null) {
|
||||
this._recordInstallProgress('host', progress, null, progress.task.HostInstall.from_version != null);
|
||||
} else if (progress.task.ModuleDownload != null) {
|
||||
this._recordDownloadProgress(progress.task.ModuleDownload.version.module.name, progress);
|
||||
} else if (progress.task.ModuleInstall != null) {
|
||||
this._recordInstallProgress(progress.task.ModuleInstall.version.module.name, progress, progress.task.ModuleInstall.version.version, progress.task.ModuleInstall.from_version != null);
|
||||
}
|
||||
}
|
||||
|
||||
queryCurrentVersions() {
|
||||
return this._sendRequest('QueryCurrentVersions');
|
||||
}
|
||||
|
||||
queryCurrentVersionsSync() {
|
||||
return this._handleSyncResponse(this._sendRequestSync('QueryCurrentVersions'));
|
||||
}
|
||||
|
||||
repair(progressCallback) {
|
||||
return this._sendRequest('Repair', progressCallback);
|
||||
}
|
||||
|
||||
collectGarbage() {
|
||||
return this._sendRequest('CollectGarbage');
|
||||
}
|
||||
|
||||
setRunningManifest(manifest) {
|
||||
return this._sendRequest({
|
||||
SetManifests: ['Running', manifest]
|
||||
});
|
||||
}
|
||||
|
||||
setPinnedManifestSync(manifest) {
|
||||
return this._handleSyncResponse(this._sendRequestSync({
|
||||
SetManifests: ['Pinned', manifest]
|
||||
}));
|
||||
}
|
||||
|
||||
installModule(name, progressCallback) {
|
||||
return this._sendRequest({
|
||||
InstallModule: name
|
||||
}, progressCallback);
|
||||
}
|
||||
|
||||
updateToLatest(progressCallback) {
|
||||
return this._sendRequest('UpdateToLatest', progressCallback);
|
||||
} // If the running host is current, adopt the current installed modules and
|
||||
// set up the module search path accordingly. If the running host is not
|
||||
// current, start the new current host and exit this process.
|
||||
|
||||
|
||||
async startCurrentVersion(options) {
|
||||
const versions = await this.queryCurrentVersions();
|
||||
await this.setRunningManifest(versions.last_successful_update);
|
||||
|
||||
this._startCurrentVersionInner(options, versions);
|
||||
}
|
||||
|
||||
startCurrentVersionSync(options) {
|
||||
const versions = this.queryCurrentVersionsSync();
|
||||
|
||||
this._startCurrentVersionInner(options, versions);
|
||||
}
|
||||
|
||||
async commitModules(versions) {
|
||||
if (this.committedHostVersion == null) {
|
||||
throw new Error('Cannot commit modules before host version.');
|
||||
}
|
||||
|
||||
if (versions == null) {
|
||||
versions = await this.queryCurrentVersions();
|
||||
}
|
||||
|
||||
this._commitModulesInner(versions);
|
||||
}
|
||||
|
||||
setRunningInBackground() {
|
||||
this.isRunningInBackground = true;
|
||||
}
|
||||
|
||||
queryAndTruncateHistory() {
|
||||
const history = this.updateEventHistory;
|
||||
this.updateEventHistory = [];
|
||||
return history;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function getUpdaterPlatformName(platform) {
|
||||
switch (platform) {
|
||||
case 'darwin':
|
||||
return 'osx';
|
||||
|
||||
case 'win32':
|
||||
return 'win';
|
||||
|
||||
default:
|
||||
return platform;
|
||||
}
|
||||
}
|
||||
|
||||
function tryInitUpdater(buildInfo, repositoryUrl) {
|
||||
// We can't require this in module scope because it's not part of the
|
||||
// bootstrapper, which carries a copy of the Updater class.
|
||||
const paths = require('./paths');
|
||||
|
||||
const rootPath = paths.getInstallPath(); // If we're not running from an actual install directory, don't bother trying
|
||||
// to initialize the updater.
|
||||
|
||||
if (rootPath == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
instance = new Updater({
|
||||
release_channel: buildInfo.releaseChannel,
|
||||
platform: getUpdaterPlatformName(process.platform),
|
||||
repository_url: repositoryUrl,
|
||||
root_path: rootPath
|
||||
});
|
||||
return instance.valid;
|
||||
}
|
||||
|
||||
function getUpdater() {
|
||||
if (instance != null && instance.valid) {
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
Updater,
|
||||
tryInitUpdater,
|
||||
getUpdater,
|
||||
TASK_STATE_COMPLETE,
|
||||
TASK_STATE_FAILED,
|
||||
TASK_STATE_WAITING,
|
||||
TASK_STATE_WORKING
|
||||
};
|