Compare commits
16 Commits
Author | SHA1 | Date |
---|---|---|
|| Prof. - Xadk3!#0000 || @naryal2580 | ccc5f78652 | |
|| Prof. - Xadk3!#0000 || @naryal2580 | 23219a5e70 | |
|| Prof. - Xadk3!#0000 || @naryal2580 | 0d16d3d3ae | |
|| Prof. - Xadk3!#0000 || @naryal2580 | c7923f9fab | |
|| Prof. - Xadk3!#0000 || @naryal2580 | 9743775dda | |
|| Prof. - Xadk3!#0000 || @naryal2580 | 083065721f | |
|| Prof. - Xadk3!#0000 || @naryal2580 | 7958464d6e | |
|| Prof. - Xadk3!#0000 || @naryal2580 | 780ad9a200 | |
|| Prof. - Xadk3! | 5ac24c8cea | |
|| Prof. - Xadk3! | 9d7a050bb6 | |
|| Prof. - Xadk3! | 73924c3f4b | |
|| Prof. - Xadk3! | 1ebb037c2c | |
|| Prof. - Xadk3! | 7b6ea86317 | |
Prof. - Xadk3! | ebb19e63c0 | |
Prof. - Xadk3! | 8cbf89c729 | |
Prof. - Xadk3! | 9596304b38 |
|
@ -4,4 +4,8 @@ src/package-lock.json
|
|||
_*
|
||||
miniSrc/
|
||||
|
||||
*.crswap # crostini tmp files
|
||||
*.crswap # crostini tmp files
|
||||
|
||||
# Added by cargo
|
||||
|
||||
/target
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
"use strict";
|
||||
|
||||
var _appSettings = require("./appSettings");
|
||||
// bootstrap constants
|
||||
// after startup, these constants will be merged into core module constants
|
||||
// since they are used in both locations (see app/Constants.js)
|
||||
|
||||
const {
|
||||
releaseChannel
|
||||
} = require('./buildInfo');
|
||||
const settings = (0, _appSettings.getSettings)();
|
||||
function capitalizeFirstLetter(s) {
|
||||
return s.charAt(0).toUpperCase() + s.slice(1);
|
||||
}
|
||||
const appNameSuffix = releaseChannel === 'stable' ? '' : capitalizeFirstLetter(releaseChannel);
|
||||
const APP_COMPANY = 'Discord Inc';
|
||||
const APP_DESCRIPTION = 'Discord - https://discord.com';
|
||||
const APP_NAME = 'Discord' + appNameSuffix;
|
||||
const APP_NAME_FOR_HUMANS = 'Discord' + (appNameSuffix !== '' ? ' ' + appNameSuffix : '');
|
||||
const APP_ID_BASE = 'com.squirrel';
|
||||
const APP_ID = `${APP_ID_BASE}.${APP_NAME}.${APP_NAME}`;
|
||||
const APP_PROTOCOL = 'Discord';
|
||||
const API_ENDPOINT = settings.get('API_ENDPOINT') || 'https://discord.com/api';
|
||||
const UPDATE_ENDPOINT = settings.get('UPDATE_ENDPOINT') || API_ENDPOINT;
|
||||
const NEW_UPDATE_ENDPOINT = settings.get('NEW_UPDATE_ENDPOINT') || 'https://updates.discord.com/';
|
||||
const bootstrapConstants = {
|
||||
APP_COMPANY,
|
||||
APP_DESCRIPTION,
|
||||
APP_NAME,
|
||||
APP_NAME_FOR_HUMANS,
|
||||
APP_ID,
|
||||
APP_PROTOCOL,
|
||||
API_ENDPOINT,
|
||||
NEW_UPDATE_ENDPOINT,
|
||||
UPDATE_ENDPOINT
|
||||
};
|
||||
module.exports = bootstrapConstants;
|
|
@ -0,0 +1,17 @@
|
|||
"use strict";
|
||||
|
||||
// this file is here for two reasons:
|
||||
// 1. web requires ./GPUSettings file from electron app (bad!), and requires are
|
||||
// relative to process.main (bootstrap's index.js)
|
||||
// 2. GPUSettings has been refactored into GPUSettings, and because we want to
|
||||
// be able to update GPUSettings OTA, we will have the core module provide
|
||||
// us with the GPUSettings
|
||||
// so tl;dr this is core module's GPUSettings, providing compat for web
|
||||
|
||||
exports.replace = function (GPUSettings) {
|
||||
// replacing module.exports directly would have no effect, since requires are cached
|
||||
// so we mutate the existing object
|
||||
for (const name of Object.keys(GPUSettings)) {
|
||||
exports[name] = GPUSettings[name];
|
||||
}
|
||||
};
|
|
@ -0,0 +1,19 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.getSettings = getSettings;
|
||||
exports.init = init;
|
||||
var _Settings = _interopRequireDefault(require("../common/Settings"));
|
||||
var paths = _interopRequireWildcard(require("../common/paths"));
|
||||
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
||||
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && 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 }; }
|
||||
let settings;
|
||||
function init() {
|
||||
settings = new _Settings.default(paths.getUserData());
|
||||
}
|
||||
function getSettings() {
|
||||
return settings;
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.focusSplash = focusSplash;
|
||||
exports.update = update;
|
||||
var _fs = _interopRequireDefault(require("fs"));
|
||||
var _path = _interopRequireDefault(require("path"));
|
||||
var moduleUpdater = _interopRequireWildcard(require("../common/moduleUpdater"));
|
||||
var paths = _interopRequireWildcard(require("../common/paths"));
|
||||
var _updater = require("../common/updater");
|
||||
var _appSettings = require("./appSettings");
|
||||
var autoStart = _interopRequireWildcard(require("./autoStart"));
|
||||
var _buildInfo = _interopRequireDefault(require("./buildInfo"));
|
||||
var _errorHandler = require("./errorHandler");
|
||||
var firstRun = _interopRequireWildcard(require("./firstRun"));
|
||||
var splashScreen = _interopRequireWildcard(require("./splashScreen"));
|
||||
var _Constants = require("./Constants");
|
||||
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
||||
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && 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 }; }
|
||||
// settings
|
||||
const USE_PINNED_UPDATE_MANIFEST = 'USE_PINNED_UPDATE_MANIFEST';
|
||||
function update(startMinimized, doneCallback, showCallback) {
|
||||
const settings = (0, _appSettings.getSettings)();
|
||||
if ((0, _updater.tryInitUpdater)(_buildInfo.default, _Constants.NEW_UPDATE_ENDPOINT)) {
|
||||
const updater = (0, _updater.getUpdater)();
|
||||
const usePinnedUpdateManifest = settings.get(USE_PINNED_UPDATE_MANIFEST);
|
||||
updater.on('host-updated', () => {
|
||||
autoStart.update(() => {});
|
||||
});
|
||||
updater.on('unhandled-exception', _errorHandler.fatal);
|
||||
updater.on(_updater.INCONSISTENT_INSTALLER_STATE_ERROR, _errorHandler.fatal);
|
||||
updater.on('update-error', _errorHandler.handled);
|
||||
updater.on('starting-new-host', () => {
|
||||
// dont run stale launch events--the host we're updating to will run its own callbacks
|
||||
splashScreen.events.removeListener(splashScreen.APP_SHOULD_LAUNCH, doneCallback);
|
||||
splashScreen.events.removeListener(splashScreen.APP_SHOULD_SHOW, showCallback);
|
||||
});
|
||||
if (usePinnedUpdateManifest) {
|
||||
const manifestPath = _path.default.join(paths.getUserData(), 'pinned_update.json');
|
||||
updater.setPinnedManifestSync(JSON.parse(_fs.default.readFileSync(manifestPath)));
|
||||
}
|
||||
firstRun.performFirstRunTasks(updater);
|
||||
} else {
|
||||
moduleUpdater.init(_Constants.UPDATE_ENDPOINT, settings, _buildInfo.default);
|
||||
}
|
||||
splashScreen.initSplash(startMinimized);
|
||||
splashScreen.events.once(splashScreen.APP_SHOULD_LAUNCH, doneCallback);
|
||||
splashScreen.events.once(splashScreen.APP_SHOULD_SHOW, showCallback);
|
||||
}
|
||||
function focusSplash() {
|
||||
splashScreen.focusWindow();
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.install = install;
|
||||
exports.isInstalled = isInstalled;
|
||||
exports.uninstall = uninstall;
|
||||
exports.update = update;
|
||||
function install(callback) {
|
||||
return callback();
|
||||
}
|
||||
function update(callback) {
|
||||
return callback();
|
||||
}
|
||||
function isInstalled(callback) {
|
||||
return callback(false);
|
||||
}
|
||||
function uninstall(callback) {
|
||||
return callback();
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = require('./' + process.platform);
|
|
@ -0,0 +1,71 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.install = install;
|
||||
exports.isInstalled = isInstalled;
|
||||
exports.uninstall = uninstall;
|
||||
exports.update = update;
|
||||
var _fs = _interopRequireDefault(require("fs"));
|
||||
var _path = _interopRequireDefault(require("path"));
|
||||
var _electron = require("electron");
|
||||
var _buildInfo = _interopRequireDefault(require("../buildInfo"));
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
// TODO: We should use Constant's APP_NAME, but only once
|
||||
// we set up backwards compat with this.
|
||||
const appName = _path.default.basename(process.execPath, '.exe');
|
||||
const exePath = _electron.app.getPath('exe');
|
||||
const exeDir = _path.default.dirname(exePath);
|
||||
const iconPath = _path.default.join(exeDir, 'discord.png');
|
||||
const autostartDir = _path.default.join(_electron.app.getPath('appData'), 'autostart');
|
||||
const electronAppName = _electron.app.name ? _electron.app.name : _electron.app.getName();
|
||||
const autostartFileName = _path.default.join(autostartDir, electronAppName + '-' + _buildInfo.default.releaseChannel + '.desktop');
|
||||
const desktopFile = `[Desktop Entry]
|
||||
Type=Application
|
||||
Exec=${exePath}
|
||||
Hidden=false
|
||||
NoDisplay=false
|
||||
Name=${appName}
|
||||
Icon=${iconPath}
|
||||
Comment=Text and voice chat for gamers.
|
||||
X-GNOME-Autostart-enabled=true
|
||||
`;
|
||||
function ensureDir() {
|
||||
try {
|
||||
_fs.default.mkdirSync(autostartDir);
|
||||
return true;
|
||||
} catch (e) {
|
||||
// catch for when it already exists.
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function install(callback) {
|
||||
// TODO: This could fail. We should read its return value
|
||||
ensureDir();
|
||||
try {
|
||||
return _fs.default.writeFile(autostartFileName, desktopFile, callback);
|
||||
} catch (e) {
|
||||
// I guess we don't autostart then
|
||||
return callback();
|
||||
}
|
||||
}
|
||||
function update(callback) {
|
||||
// TODO: We might need to implement this later on
|
||||
return callback();
|
||||
}
|
||||
function isInstalled(callback) {
|
||||
try {
|
||||
_fs.default.stat(autostartFileName, (err, stats) => {
|
||||
if (err) {
|
||||
return callback(false);
|
||||
}
|
||||
return callback(stats.isFile());
|
||||
});
|
||||
} catch (e) {
|
||||
return callback(false);
|
||||
}
|
||||
}
|
||||
function uninstall(callback) {
|
||||
return _fs.default.unlink(autostartFileName, callback);
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.install = install;
|
||||
exports.isInstalled = isInstalled;
|
||||
exports.uninstall = uninstall;
|
||||
exports.update = update;
|
||||
var _path = _interopRequireDefault(require("path"));
|
||||
var windowsUtils = _interopRequireWildcard(require("../windowsUtils"));
|
||||
var _appSettings = require("../appSettings");
|
||||
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
||||
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && 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 = (0, _appSettings.getSettings)();
|
||||
|
||||
// TODO: We should use Constant's APP_NAME, but only once
|
||||
// we set up backwards compat with this.
|
||||
const appName = _path.default.basename(process.execPath, '.exe');
|
||||
const fullExeName = _path.default.basename(process.execPath);
|
||||
const updatePath = _path.default.join(_path.default.dirname(process.execPath), '..', 'Update.exe');
|
||||
function install(callback) {
|
||||
const startMinimized = settings.get('START_MINIMIZED', false);
|
||||
let execPath = `"${updatePath}" --processStart ${fullExeName}`;
|
||||
if (startMinimized) {
|
||||
execPath = `${execPath} --process-start-args --start-minimized`;
|
||||
}
|
||||
const queue = [['HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run', '/v', appName, '/d', execPath]];
|
||||
windowsUtils.addToRegistry(queue, callback);
|
||||
}
|
||||
function update(callback) {
|
||||
isInstalled(installed => {
|
||||
if (installed) {
|
||||
install(callback);
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
});
|
||||
}
|
||||
function isInstalled(callback) {
|
||||
const queryValue = ['HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run', '/v', appName];
|
||||
queryValue.unshift('query');
|
||||
windowsUtils.spawnReg(queryValue, (error, stdout) => {
|
||||
const doesOldKeyExist = stdout.indexOf(appName) >= 0;
|
||||
callback(doesOldKeyExist);
|
||||
});
|
||||
}
|
||||
function uninstall(callback) {
|
||||
const queryValue = ['HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run', '/v', appName, '/f'];
|
||||
queryValue.unshift('delete');
|
||||
windowsUtils.spawnReg(queryValue, (error, stdout) => {
|
||||
callback();
|
||||
});
|
||||
}
|
|
@ -0,0 +1,167 @@
|
|||
"use strict";
|
||||
|
||||
// bootstrap, or what runs before the rest of desktop does
|
||||
// responsible for handling updates and updating modules before continuing startup
|
||||
|
||||
if (process.platform === 'linux') {
|
||||
// Some people are reporting audio problems on Linux that are fixed by setting
|
||||
// an environment variable PULSE_LATENCY_MSEC=30 -- the "real" fix is to see
|
||||
// what conditions require this and set this then (also to set it directly in
|
||||
// our webrtc setup code rather than here) but this should fix the bug for now.
|
||||
if (process.env.PULSE_LATENCY_MSEC === undefined) {
|
||||
process.env.PULSE_LATENCY_MSEC = 30;
|
||||
}
|
||||
}
|
||||
const {
|
||||
app,
|
||||
Menu
|
||||
} = require('electron');
|
||||
const sentry = require('@sentry/node');
|
||||
const buildInfo = require('./buildInfo');
|
||||
app.setVersion(buildInfo.version);
|
||||
|
||||
// expose releaseChannel to a global, since it's used by splash screen
|
||||
global.releaseChannel = buildInfo.releaseChannel;
|
||||
const errorHandler = require('./errorHandler');
|
||||
errorHandler.init();
|
||||
const crashReporterSetup = require('../common/crashReporterSetup');
|
||||
crashReporterSetup.init(buildInfo, sentry);
|
||||
const paths = require('../common/paths');
|
||||
paths.init(buildInfo);
|
||||
global.moduleDataPath = paths.getModuleDataPath();
|
||||
const appSettings = require('./appSettings');
|
||||
appSettings.init();
|
||||
const Constants = require('./Constants');
|
||||
const GPUSettings = require('./GPUSettings');
|
||||
function setupHardwareAcceleration() {
|
||||
const settings = appSettings.getSettings();
|
||||
// TODO: this is a copy of gpuSettings.getEnableHardwareAcceleration
|
||||
if (!settings.get('enableHardwareAcceleration', true)) {
|
||||
app.disableHardwareAcceleration();
|
||||
}
|
||||
}
|
||||
setupHardwareAcceleration();
|
||||
|
||||
// [adill] work around chrome 66 disabling autoplay by default
|
||||
app.commandLine.appendSwitch('autoplay-policy', 'no-user-gesture-required');
|
||||
|
||||
// WinRetrieveSuggestionsOnlyOnDemand: Work around electron 13 bug w/ async spellchecking on Windows.
|
||||
// HardwareMediaKeyHandling,MediaSessionService: Prevent Discord from registering as a media service.
|
||||
app.commandLine.appendSwitch('disable-features', 'WinRetrieveSuggestionsOnlyOnDemand,HardwareMediaKeyHandling,MediaSessionService');
|
||||
function hasArgvFlag(flag) {
|
||||
return (process.argv || []).slice(1).includes(flag);
|
||||
}
|
||||
console.log(`${Constants.APP_NAME} ${app.getVersion()}`);
|
||||
let pendingAppQuit = false;
|
||||
if (process.platform === 'win32') {
|
||||
// this tells Windows (in particular Windows 10) which icon to associate your app with, important for correctly
|
||||
// pinning app to task bar.
|
||||
app.setAppUserModelId(Constants.APP_ID);
|
||||
const {
|
||||
handleStartupEvent
|
||||
} = require('./squirrelUpdate');
|
||||
// TODO: Isn't using argv[1] fragile?
|
||||
const squirrelCommand = process.argv[1];
|
||||
// TODO: Is protocol case sensitive?
|
||||
if (handleStartupEvent(Constants.APP_PROTOCOL, app, squirrelCommand)) {
|
||||
pendingAppQuit = true;
|
||||
}
|
||||
}
|
||||
const appUpdater = require('./appUpdater');
|
||||
const moduleUpdater = require('../common/moduleUpdater');
|
||||
const updater = require('../common/updater');
|
||||
const splashScreen = require('./splashScreen');
|
||||
const autoStart = require('./autoStart');
|
||||
const requireNative = require('./requireNative');
|
||||
let coreModule;
|
||||
const allowMultipleInstances = hasArgvFlag('--multi-instance');
|
||||
const isFirstInstance = allowMultipleInstances ? true : app.requestSingleInstanceLock();
|
||||
function extractUrlFromArgs(args) {
|
||||
const urlArgIndex = args.indexOf('--url');
|
||||
if (urlArgIndex < 0) {
|
||||
return null;
|
||||
}
|
||||
const passThroughArgsIndex = args.indexOf('--');
|
||||
if (passThroughArgsIndex < 0 || passThroughArgsIndex < urlArgIndex) {
|
||||
return null;
|
||||
}
|
||||
const url = args[passThroughArgsIndex + 1];
|
||||
if (url == null) {
|
||||
return null;
|
||||
}
|
||||
return url;
|
||||
}
|
||||
let initialUrl = extractUrlFromArgs(process.argv);
|
||||
if (!allowMultipleInstances) {
|
||||
app.on('second-instance', (_event, args, _workingDirectory) => {
|
||||
if (args != null && args.indexOf('--squirrel-uninstall') > -1) {
|
||||
app.quit();
|
||||
return;
|
||||
}
|
||||
const url = extractUrlFromArgs(args);
|
||||
if (coreModule) {
|
||||
// url can be null, as a user opening the executable again will focus the app from background
|
||||
coreModule.handleOpenUrl(url);
|
||||
} else if (url != null) {
|
||||
initialUrl = url;
|
||||
}
|
||||
if (!coreModule) {
|
||||
appUpdater.focusSplash();
|
||||
}
|
||||
});
|
||||
}
|
||||
app.on('will-finish-launching', () => {
|
||||
// on macos protocol links are handled entirely through this event
|
||||
app.on('open-url', (event, url) => {
|
||||
event.preventDefault();
|
||||
if (coreModule) {
|
||||
coreModule.handleOpenUrl(url);
|
||||
} else {
|
||||
initialUrl = url;
|
||||
}
|
||||
});
|
||||
});
|
||||
function startUpdate() {
|
||||
console.log('Starting updater.');
|
||||
const startMinimized = hasArgvFlag('--start-minimized');
|
||||
appUpdater.update(startMinimized, () => {
|
||||
try {
|
||||
coreModule = requireNative('discord_desktop_core');
|
||||
coreModule.startup({
|
||||
paths,
|
||||
splashScreen,
|
||||
moduleUpdater,
|
||||
autoStart,
|
||||
buildInfo,
|
||||
appSettings,
|
||||
Constants,
|
||||
GPUSettings,
|
||||
updater,
|
||||
crashReporterSetup
|
||||
});
|
||||
if (initialUrl != null) {
|
||||
coreModule.handleOpenUrl(initialUrl);
|
||||
initialUrl = null;
|
||||
}
|
||||
} catch (err) {
|
||||
return errorHandler.fatal(err);
|
||||
}
|
||||
}, () => {
|
||||
coreModule.setMainWindowVisible(!startMinimized);
|
||||
});
|
||||
}
|
||||
function startApp() {
|
||||
console.log('Starting app.');
|
||||
paths.cleanOldVersions(buildInfo);
|
||||
const startupMenu = require('./startupMenu');
|
||||
Menu.setApplicationMenu(startupMenu);
|
||||
startUpdate();
|
||||
}
|
||||
if (pendingAppQuit) {
|
||||
console.log('Startup prevented.');
|
||||
} else if (!isFirstInstance && !allowMultipleInstances) {
|
||||
console.log('Quitting secondary instance.');
|
||||
app.quit();
|
||||
} else {
|
||||
app.whenReady().then(() => startApp());
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
var _path = _interopRequireDefault(require("path"));
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
const buildInfo = require(_path.default.join(process.resourcesPath, 'build_info.json'));
|
||||
var _default = buildInfo;
|
||||
exports.default = _default;
|
||||
module.exports = exports.default;
|
|
@ -0,0 +1,14 @@
|
|||
[
|
||||
"Upsorbing the Contents",
|
||||
"Additive Parsing the Load",
|
||||
"Commence Monosaturated Goodening",
|
||||
"Kick Off the Multi-Core Widening",
|
||||
"Bastening the Game Turkey",
|
||||
"Abstracting the Rummage Disc",
|
||||
"Undecerealenizing the Process",
|
||||
"Postrefragmenting the Widget Layer",
|
||||
"Satisfying the Constraints",
|
||||
"Abnoramalzing Some of the Matrices",
|
||||
"Optimizing the People",
|
||||
"Proclaigerizing the Network"
|
||||
]
|
|
@ -0,0 +1,85 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.fatal = fatal;
|
||||
exports.handled = handled;
|
||||
exports.init = init;
|
||||
var Sentry = _interopRequireWildcard(require("@sentry/node"));
|
||||
var _electron = require("electron");
|
||||
var _process = _interopRequireDefault(require("process"));
|
||||
var _crashReporterSetup = require("../common/crashReporterSetup");
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
||||
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && 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 HANDLED_ERROR_INTERVAL = 3;
|
||||
const HANDLED_ERROR_LIMIT = 10;
|
||||
let handledErrorCounter = 0;
|
||||
let totalHandledErrors = 0;
|
||||
const consoleOutputOnly = _process.default.env.DISCORD_TEST != null;
|
||||
function isErrorSafeToSuppress(error) {
|
||||
return /attempting to call a function in a renderer window/i.test(error.message);
|
||||
}
|
||||
function captureJSException(error) {
|
||||
Sentry.captureException(error, scope => {
|
||||
scope.clear();
|
||||
scope.setTag('nativeBuildNumber', _crashReporterSetup.metadata.nativeBuildNumber);
|
||||
scope.setUser(_crashReporterSetup.metadata.sentry.user);
|
||||
scope.setExtras({
|
||||
environment: _crashReporterSetup.metadata.sentry.environment,
|
||||
release: _crashReporterSetup.metadata.sentry.release,
|
||||
nativeBuildNumber: _crashReporterSetup.metadata.nativeBuildNumber
|
||||
});
|
||||
return scope;
|
||||
});
|
||||
}
|
||||
function init() {
|
||||
_process.default.on('uncaughtException', error => {
|
||||
const stack = error.stack ? error.stack : String(error);
|
||||
const message = `Uncaught exception:\n ${stack}`;
|
||||
console.warn(message);
|
||||
captureJSException(error);
|
||||
if (!isErrorSafeToSuppress(error)) {
|
||||
if (consoleOutputOnly) {
|
||||
console.error(`${message} error: ${error}`);
|
||||
_process.default.exit(-1);
|
||||
}
|
||||
_electron.dialog.showErrorBox('A JavaScript error occurred in the main process', message);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// show a similar error message to the error handler, except exit out the app
|
||||
// after the error message has been closed
|
||||
function fatal(err) {
|
||||
const options = {
|
||||
type: 'error',
|
||||
message: 'A fatal Javascript error occured',
|
||||
detail: err && err.stack ? err.stack : String(err)
|
||||
};
|
||||
if (consoleOutputOnly) {
|
||||
console.error(`fatal: ${err}\n${err === null || err === void 0 ? void 0 : err.stack}`);
|
||||
_process.default.exit(-1);
|
||||
}
|
||||
const callback = _ => _electron.app.quit();
|
||||
const electronMajor = parseInt(_process.default.versions.electron.split('.')[0]);
|
||||
if (electronMajor >= 6) {
|
||||
_electron.dialog.showMessageBox(null, options).then(callback);
|
||||
} else {
|
||||
_electron.dialog.showMessageBox(options, callback);
|
||||
}
|
||||
captureJSException(err);
|
||||
}
|
||||
|
||||
// capture a handled error for telemetry purposes, e.g. finding update loops.
|
||||
function handled(err) {
|
||||
if (global.releaseChannel !== 'ptb' && global.releaseChannel !== 'canary' && global.releaseChannel !== 'development') {
|
||||
return;
|
||||
}
|
||||
if (totalHandledErrors < HANDLED_ERROR_LIMIT && handledErrorCounter++ % HANDLED_ERROR_INTERVAL == 0) {
|
||||
console.warn('Reporting non-fatal error', err);
|
||||
captureJSException(err);
|
||||
totalHandledErrors++;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.performFirstRunTasks = performFirstRunTasks;
|
||||
function performFirstRunTasks(_updater) {
|
||||
//
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = require('./' + process.platform);
|
|
@ -0,0 +1,9 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.performFirstRunTasks = performFirstRunTasks;
|
||||
function performFirstRunTasks(_updater) {
|
||||
//
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.performFirstRunTasks = performFirstRunTasks;
|
||||
var _fs = _interopRequireDefault(require("fs"));
|
||||
var _path = _interopRequireDefault(require("path"));
|
||||
var paths = _interopRequireWildcard(require("../../common/paths"));
|
||||
var _errorHandler = require("../errorHandler");
|
||||
var _squirrelUpdate = require("../squirrelUpdate");
|
||||
var _Constants = require("../Constants");
|
||||
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
||||
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && 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 appFolder = _path.default.resolve(process.execPath, '..');
|
||||
const rootFolder = _path.default.resolve(appFolder, '..');
|
||||
const exeName = _path.default.basename(process.execPath);
|
||||
const updateExe = _path.default.join(rootFolder, 'Update.exe');
|
||||
function copyIconToRoot() {
|
||||
const icoSrc = _path.default.join(appFolder, 'app.ico');
|
||||
const icoDest = _path.default.join(rootFolder, 'app.ico');
|
||||
try {
|
||||
const ico = _fs.default.readFileSync(icoSrc);
|
||||
_fs.default.writeFileSync(icoDest, ico);
|
||||
return icoDest;
|
||||
} catch (e) {
|
||||
return icoSrc;
|
||||
}
|
||||
}
|
||||
function updateShortcuts(updater) {
|
||||
const shortcutFileName = `${_Constants.APP_NAME_FOR_HUMANS}.lnk`;
|
||||
const shortcutPaths = [_path.default.join(updater.getKnownFolder('desktop'), shortcutFileName), _path.default.join(updater.getKnownFolder('programs'), _Constants.APP_COMPANY, shortcutFileName)];
|
||||
const iconPath = copyIconToRoot();
|
||||
for (const shortcutPath of shortcutPaths) {
|
||||
if (!_fs.default.existsSync(shortcutPath)) {
|
||||
// If the user deleted the shortcut, don't recreate it.
|
||||
continue;
|
||||
}
|
||||
updater.createShortcut({
|
||||
/* eslint-disable camelcase */
|
||||
target_path: updateExe,
|
||||
shortcut_path: shortcutPath,
|
||||
arguments: `--processStart ${exeName}`,
|
||||
icon_path: iconPath,
|
||||
icon_index: 0,
|
||||
description: _Constants.APP_DESCRIPTION,
|
||||
app_user_model_id: _Constants.APP_ID,
|
||||
working_directory: appFolder
|
||||
/* eslint-enable camelcase */
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function performFirstRunTasks(updater) {
|
||||
const firstRunCompletePath = _path.default.join(paths.getUserDataVersioned(), '.first-run');
|
||||
if (!_fs.default.existsSync(firstRunCompletePath)) {
|
||||
let updatedShortcuts = false;
|
||||
try {
|
||||
updateShortcuts(updater);
|
||||
updatedShortcuts = true;
|
||||
} catch (e) {
|
||||
(0, _errorHandler.handled)(e);
|
||||
}
|
||||
(0, _squirrelUpdate.installProtocol)(_Constants.APP_PROTOCOL, () => {
|
||||
try {
|
||||
if (updatedShortcuts) {
|
||||
_fs.default.writeFileSync(firstRunCompletePath, 'true');
|
||||
}
|
||||
} catch (e) {
|
||||
(0, _errorHandler.handled)(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,164 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
var _electron = require("electron");
|
||||
var _events = require("events");
|
||||
var _request = _interopRequireDefault(require("./request"));
|
||||
var squirrelUpdate = _interopRequireWildcard(require("./squirrelUpdate"));
|
||||
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
||||
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && 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 }; }
|
||||
/* eslint-disable no-console */
|
||||
|
||||
function versionParse(verString) {
|
||||
return verString.split('.').map(i => parseInt(i));
|
||||
}
|
||||
function versionNewer(verA, verB) {
|
||||
let i = 0;
|
||||
while (true) {
|
||||
const a = verA[i];
|
||||
const b = verB[i];
|
||||
i++;
|
||||
if (a === undefined) {
|
||||
return false;
|
||||
} else {
|
||||
if (b === undefined || a > b) {
|
||||
return true;
|
||||
}
|
||||
if (a < b) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
class AutoUpdaterWin32 extends _events.EventEmitter {
|
||||
constructor() {
|
||||
super();
|
||||
this.updateUrl = null;
|
||||
this.updateVersion = null;
|
||||
}
|
||||
setFeedURL(updateUrl) {
|
||||
this.updateUrl = updateUrl;
|
||||
}
|
||||
quitAndInstall() {
|
||||
if (squirrelUpdate.updateExistsSync()) {
|
||||
squirrelUpdate.restart(_electron.app, this.updateVersion ?? _electron.app.getVersion());
|
||||
} else {
|
||||
/* eslint-disable-next-line */
|
||||
require('auto-updater').quitAndInstall();
|
||||
}
|
||||
}
|
||||
downloadAndInstallUpdate(callback) {
|
||||
squirrelUpdate.spawnUpdateInstall(this.updateUrl, progress => {
|
||||
this.emit('update-progress', progress);
|
||||
}).catch(err => callback(err)).then(() => callback());
|
||||
}
|
||||
checkForUpdates() {
|
||||
if (this.updateUrl == null) {
|
||||
throw new Error('Update URL is not set');
|
||||
}
|
||||
this.emit('checking-for-update');
|
||||
if (!squirrelUpdate.updateExistsSync()) {
|
||||
this.emit('update-not-available');
|
||||
return;
|
||||
}
|
||||
squirrelUpdate.spawnUpdate(['--check', this.updateUrl], (error, stdout) => {
|
||||
if (error != null) {
|
||||
this.emit('error', error);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
// Last line of the output is JSON details about the releases
|
||||
const json = stdout.trim().split('\n').pop();
|
||||
const releasesFound = JSON.parse(json).releasesToApply;
|
||||
if (releasesFound == null || releasesFound.length === 0) {
|
||||
this.emit('update-not-available');
|
||||
return;
|
||||
}
|
||||
const update = releasesFound.pop();
|
||||
this.emit('update-available');
|
||||
this.downloadAndInstallUpdate(error => {
|
||||
if (error != null) {
|
||||
this.emit('error', error);
|
||||
return;
|
||||
}
|
||||
this.updateVersion = update.version;
|
||||
this.emit('update-downloaded', {}, update.release, update.version, new Date(), this.updateUrl, this.quitAndInstall.bind(this));
|
||||
});
|
||||
} catch (error) {
|
||||
error.stdout = stdout;
|
||||
this.emit('error', error);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// todo
|
||||
class AutoUpdaterLinux extends _events.EventEmitter {
|
||||
constructor() {
|
||||
super();
|
||||
this.updateUrl = null;
|
||||
}
|
||||
setFeedURL(url) {
|
||||
this.updateUrl = url;
|
||||
}
|
||||
quitAndInstall() {
|
||||
// Just restart. The splash screen will hit the update manually state and
|
||||
// prompt the user to download the new package.
|
||||
_electron.app.relaunch();
|
||||
_electron.app.quit();
|
||||
}
|
||||
async checkForUpdates() {
|
||||
const currVersion = versionParse(_electron.app.getVersion());
|
||||
this.emit('checking-for-update');
|
||||
try {
|
||||
const response = await _request.default.get(this.updateUrl);
|
||||
if (response.statusCode === 204) {
|
||||
// you are up to date
|
||||
this.emit('update-not-available');
|
||||
return;
|
||||
}
|
||||
let latestVerStr = '';
|
||||
let latestVersion = [];
|
||||
try {
|
||||
const latestMetadata = JSON.parse(response.body);
|
||||
latestVerStr = latestMetadata.name;
|
||||
latestVersion = versionParse(latestVerStr);
|
||||
} catch (_) {}
|
||||
if (versionNewer(latestVersion, currVersion)) {
|
||||
console.log('[Updates] You are out of date!');
|
||||
// you need to update
|
||||
this.emit('update-manually', latestVerStr);
|
||||
} else {
|
||||
console.log('[Updates] You are living in the future!');
|
||||
this.emit('update-not-available');
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('[Updates] Error fetching ' + this.updateUrl + ': ' + err.message);
|
||||
this.emit('error', err);
|
||||
}
|
||||
}
|
||||
}
|
||||
let autoUpdater;
|
||||
|
||||
// TODO
|
||||
// events: checking-for-update, update-available, update-not-available, update-manually, update-downloaded, error
|
||||
// also, checkForUpdates, setFeedURL, quitAndInstall
|
||||
// also, see electron.autoUpdater, and its API
|
||||
switch (process.platform) {
|
||||
case 'darwin':
|
||||
autoUpdater = require('electron').autoUpdater;
|
||||
break;
|
||||
case 'win32':
|
||||
autoUpdater = new AutoUpdaterWin32();
|
||||
break;
|
||||
case 'linux':
|
||||
autoUpdater = new AutoUpdaterLinux();
|
||||
break;
|
||||
}
|
||||
var _default = autoUpdater;
|
||||
exports.default = _default;
|
||||
module.exports = exports.default;
|
Binary file not shown.
After Width: | Height: | Size: 6.2 KiB |
|
@ -0,0 +1,39 @@
|
|||
"use strict";
|
||||
|
||||
const buildInfo = require('./buildInfo');
|
||||
const paths = require('../common/paths');
|
||||
paths.init(buildInfo);
|
||||
const moduleUpdater = require('../common/moduleUpdater');
|
||||
const updater = require('../common/updater');
|
||||
const requireNative = require('./requireNative');
|
||||
function getAppMode() {
|
||||
if (process.argv && process.argv.includes('--overlay-host')) {
|
||||
return 'overlay-host';
|
||||
}
|
||||
return 'app';
|
||||
}
|
||||
const mode = getAppMode();
|
||||
if (mode === 'app') {
|
||||
require('./bootstrap');
|
||||
} else if (mode === 'overlay-host') {
|
||||
// Initialize the update system just enough to find installed native modules.
|
||||
const appSettings = require('./appSettings');
|
||||
appSettings.init();
|
||||
const {
|
||||
NEW_UPDATE_ENDPOINT
|
||||
} = require('./Constants');
|
||||
if (buildInfo.newUpdater) {
|
||||
if (!updater.tryInitUpdater(buildInfo, NEW_UPDATE_ENDPOINT)) {
|
||||
throw new Error('Failed to initialize modules in overlay host.');
|
||||
}
|
||||
|
||||
// Load the module search path but if there's a pending host update, don't
|
||||
// restart into it.
|
||||
updater.getUpdater().startCurrentVersionSync({
|
||||
allowObsoleteHost: true
|
||||
});
|
||||
} else {
|
||||
moduleUpdater.initPathsOnly(buildInfo);
|
||||
}
|
||||
requireNative('discord_overlay2/standalone_host.js');
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
// used in devtools to hook in additional dev tools
|
||||
// require('electron').remote.require('./installDevTools')()
|
||||
|
||||
function installDevTools() {
|
||||
console.log(`Installing Devtron`);
|
||||
const devtron = require('devtron');
|
||||
devtron.uninstall();
|
||||
devtron.install();
|
||||
console.log(`Installed Devtron`);
|
||||
}
|
||||
var _default = installDevTools;
|
||||
exports.default = _default;
|
||||
module.exports = exports.default;
|
|
@ -0,0 +1,13 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
var _electron = require("electron");
|
||||
var _default = {
|
||||
on: (event, callback) => _electron.ipcMain.on(`DISCORD_${event}`, callback),
|
||||
removeListener: (event, callback) => _electron.ipcMain.removeListener(`DISCORD_${event}`, callback)
|
||||
};
|
||||
exports.default = _default;
|
||||
module.exports = exports.default;
|
|
@ -0,0 +1,162 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
var _electron = require("electron");
|
||||
var _querystring = _interopRequireDefault(require("querystring"));
|
||||
var _request = _interopRequireDefault(require("request"));
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
const DEFAULT_REQUEST_TIMEOUT = 30000;
|
||||
function makeHTTPResponse({
|
||||
method,
|
||||
url,
|
||||
headers,
|
||||
statusCode,
|
||||
statusMessage
|
||||
}, body) {
|
||||
return {
|
||||
method,
|
||||
url,
|
||||
headers,
|
||||
statusCode,
|
||||
statusMessage,
|
||||
body
|
||||
};
|
||||
}
|
||||
function makeHTTPStatusError(response) {
|
||||
const err = new Error(`HTTP Error: Status Code ${response.statusCode}`);
|
||||
err.response = response;
|
||||
return err;
|
||||
}
|
||||
function handleHTTPResponse(resolve, reject, response, stream) {
|
||||
const totalBytes = parseInt(response.headers['content-length'] || 1, 10);
|
||||
let receivedBytes = 0;
|
||||
const chunks = [];
|
||||
|
||||
// don't stream response if it's a failure
|
||||
if (response.statusCode >= 300) {
|
||||
stream = null;
|
||||
}
|
||||
response.on('data', chunk => {
|
||||
if (stream != null) {
|
||||
receivedBytes += chunk.length;
|
||||
stream.write(chunk);
|
||||
stream.emit('progress', {
|
||||
totalBytes,
|
||||
receivedBytes
|
||||
});
|
||||
return;
|
||||
}
|
||||
chunks.push(chunk);
|
||||
});
|
||||
response.on('end', () => {
|
||||
if (stream != null) {
|
||||
stream.on('finish', () => resolve(makeHTTPResponse(response, null)));
|
||||
stream.end();
|
||||
return;
|
||||
}
|
||||
const res = makeHTTPResponse(response, Buffer.concat(chunks));
|
||||
if (res.statusCode >= 300) {
|
||||
reject(makeHTTPStatusError(res));
|
||||
return;
|
||||
}
|
||||
resolve(res);
|
||||
});
|
||||
}
|
||||
function nodeRequest({
|
||||
method,
|
||||
url,
|
||||
headers,
|
||||
qs,
|
||||
timeout,
|
||||
body,
|
||||
stream
|
||||
}) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const req = (0, _request.default)({
|
||||
method,
|
||||
url,
|
||||
qs,
|
||||
headers,
|
||||
followAllRedirects: true,
|
||||
encoding: null,
|
||||
timeout: timeout != null ? timeout : DEFAULT_REQUEST_TIMEOUT,
|
||||
body
|
||||
});
|
||||
req.on('response', response => handleHTTPResponse(resolve, reject, response, stream));
|
||||
req.on('error', err => reject(err));
|
||||
});
|
||||
}
|
||||
async function electronRequest({
|
||||
method,
|
||||
url,
|
||||
headers,
|
||||
qs,
|
||||
timeout,
|
||||
body,
|
||||
stream
|
||||
}) {
|
||||
await _electron.app.whenReady();
|
||||
const {
|
||||
net,
|
||||
session
|
||||
} = require('electron');
|
||||
const req = net.request({
|
||||
method,
|
||||
url: `${url}${qs != null ? `?${_querystring.default.stringify(qs)}` : ''}`,
|
||||
redirect: 'follow',
|
||||
session: session.defaultSession
|
||||
});
|
||||
if (headers != null) {
|
||||
for (const headerKey of Object.keys(headers)) {
|
||||
req.setHeader(headerKey, headers[headerKey]);
|
||||
}
|
||||
}
|
||||
if (body != null) {
|
||||
req.write(body, 'utf-8');
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
const reqTimeout = setTimeout(() => {
|
||||
req.abort();
|
||||
reject(new Error(`network timeout: ${url}`));
|
||||
}, timeout != null ? timeout : DEFAULT_REQUEST_TIMEOUT);
|
||||
req.on('login', (authInfo, callback) => callback());
|
||||
req.on('response', response => {
|
||||
clearTimeout(reqTimeout);
|
||||
handleHTTPResponse(resolve, reject, response, stream);
|
||||
});
|
||||
req.on('error', err => {
|
||||
clearTimeout(reqTimeout);
|
||||
reject(err);
|
||||
});
|
||||
req.end();
|
||||
});
|
||||
}
|
||||
async function requestWithMethod(method, options) {
|
||||
if (typeof options === 'string') {
|
||||
options = {
|
||||
url: options
|
||||
};
|
||||
}
|
||||
options = {
|
||||
...options,
|
||||
method
|
||||
};
|
||||
try {
|
||||
return await electronRequest(options);
|
||||
} catch (err) {
|
||||
console.log(`Error downloading with electron net: ${err.message}`);
|
||||
console.log('Falling back to node net library..');
|
||||
}
|
||||
return nodeRequest(options);
|
||||
}
|
||||
|
||||
// only supports get for now, since retrying is non-idempotent and
|
||||
// we'd want to grovel the errors to make sure it's safe to retry
|
||||
var _default = {
|
||||
get: requestWithMethod.bind(null, 'GET')
|
||||
};
|
||||
exports.default = _default;
|
||||
module.exports = exports.default;
|
|
@ -0,0 +1,5 @@
|
|||
"use strict";
|
||||
|
||||
// require(), with paths specialized for requiring only native modules.
|
||||
module.paths = [];
|
||||
module.exports = require;
|
Binary file not shown.
After Width: | Height: | Size: 6.2 KiB |
|
@ -2,9 +2,10 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Discord Updater</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="notifications-mount"></div>
|
||||
<div id="splash-mount"></div>
|
||||
<script src="index.js"></script>
|
||||
</body>
|
||||
</html>
|
File diff suppressed because one or more lines are too long
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"width": 400,
|
||||
"height": 106,
|
||||
"width": "300px",
|
||||
"height": "300px",
|
||||
"inDuration": 700,
|
||||
"outDuration": 333
|
||||
}
|
|
@ -0,0 +1,421 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.events = exports.APP_SHOULD_SHOW = exports.APP_SHOULD_LAUNCH = void 0;
|
||||
exports.focusWindow = focusWindow;
|
||||
exports.initSplash = initSplash;
|
||||
exports.pageReady = pageReady;
|
||||
var _electron = require("electron");
|
||||
var _events = require("events");
|
||||
var _fs = _interopRequireDefault(require("fs"));
|
||||
var _path = _interopRequireDefault(require("path"));
|
||||
var _url = _interopRequireDefault(require("url"));
|
||||
var _Backoff = _interopRequireDefault(require("../common/Backoff"));
|
||||
var moduleUpdater = _interopRequireWildcard(require("../common/moduleUpdater"));
|
||||
var paths = _interopRequireWildcard(require("../common/paths"));
|
||||
var _securityUtils = require("../common/securityUtils");
|
||||
var _updater = require("../common/updater");
|
||||
var _ipcMain = _interopRequireDefault(require("./ipcMain"));
|
||||
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
||||
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && 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 UPDATE_TIMEOUT_WAIT = 10000;
|
||||
const RETRY_CAP_SECONDS = 60;
|
||||
// citron note: atom seems to add about 50px height to the frame on mac but not windows
|
||||
// TODO: see if we can eliminate fudge by using useContentSize BrowserWindow option
|
||||
const LOADING_WINDOW_WIDTH = 300;
|
||||
const LOADING_WINDOW_HEIGHT = process.platform === 'darwin' ? 300 : 350;
|
||||
|
||||
// TODO: addModulesListener events should use Module's constants
|
||||
const CHECKING_FOR_UPDATES = 'checking-for-updates';
|
||||
const UPDATE_CHECK_FINISHED = 'update-check-finished';
|
||||
const UPDATE_FAILURE = 'update-failure';
|
||||
const LAUNCHING = 'launching';
|
||||
const DOWNLOADING_MODULE = 'downloading-module';
|
||||
const DOWNLOADING_UPDATES = 'downloading-updates';
|
||||
const DOWNLOADING_MODULES_FINISHED = 'downloading-modules-finished';
|
||||
const DOWNLOADING_MODULE_PROGRESS = 'downloading-module-progress';
|
||||
const DOWNLOADED_MODULE = 'downloaded-module';
|
||||
const NO_PENDING_UPDATES = 'no-pending-updates';
|
||||
const INSTALLING_MODULE = 'installing-module';
|
||||
const INSTALLING_UPDATES = 'installing-updates';
|
||||
const INSTALLED_MODULE = 'installed-module';
|
||||
const INSTALLING_MODULE_PROGRESS = 'installing-module-progress';
|
||||
const INSTALLING_MODULES_FINISHED = 'installing-modules-finished';
|
||||
const UPDATE_MANUALLY = 'update-manually';
|
||||
const APP_SHOULD_LAUNCH = 'APP_SHOULD_LAUNCH';
|
||||
exports.APP_SHOULD_LAUNCH = APP_SHOULD_LAUNCH;
|
||||
const APP_SHOULD_SHOW = 'APP_SHOULD_SHOW';
|
||||
exports.APP_SHOULD_SHOW = APP_SHOULD_SHOW;
|
||||
const events = new _events.EventEmitter();
|
||||
exports.events = events;
|
||||
function webContentsSend(win, event, ...args) {
|
||||
if (win != null && win.webContents != null) {
|
||||
win.webContents.send(`DISCORD_${event}`, ...args);
|
||||
}
|
||||
}
|
||||
let splashWindow;
|
||||
let modulesListeners;
|
||||
let updateTimeout;
|
||||
let updateAttempt;
|
||||
let splashState;
|
||||
let launchedMainWindow;
|
||||
let quoteCachePath;
|
||||
let restartRequired = false;
|
||||
let newUpdater;
|
||||
const updateBackoff = new _Backoff.default(1000, 30000);
|
||||
|
||||
// TODO(eiz): some of this logic should probably not live in the splash.
|
||||
//
|
||||
// Disabled because Rust interop stuff is going on in here.
|
||||
/* eslint-disable camelcase */
|
||||
class TaskProgress {
|
||||
constructor() {
|
||||
this.inProgress = new Map();
|
||||
this.finished = new Set();
|
||||
this.allTasks = new Set();
|
||||
}
|
||||
recordProgress(progress, task) {
|
||||
this.allTasks.add(task.package_sha256);
|
||||
if (progress.state !== _updater.TASK_STATE_WAITING) {
|
||||
this.inProgress.set(task.package_sha256, progress.percent);
|
||||
if (progress.state === _updater.TASK_STATE_COMPLETE) {
|
||||
this.finished.add(task.package_sha256);
|
||||
}
|
||||
}
|
||||
}
|
||||
updateSplashState(newState) {
|
||||
if (this.inProgress.size > 0 && this.inProgress.size > this.finished.size) {
|
||||
let totalPercent = 0;
|
||||
for (const item of this.inProgress.values()) {
|
||||
totalPercent += item;
|
||||
}
|
||||
totalPercent /= this.allTasks.size;
|
||||
splashState = {
|
||||
current: this.finished.size + 1,
|
||||
total: this.allTasks.size,
|
||||
progress: totalPercent
|
||||
};
|
||||
updateSplashState(newState);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
async function updateUntilCurrent() {
|
||||
const retryOptions = {
|
||||
skip_host_delta: false,
|
||||
skip_module_delta: {}
|
||||
};
|
||||
while (true) {
|
||||
updateSplashState(CHECKING_FOR_UPDATES);
|
||||
try {
|
||||
let installedAnything = false;
|
||||
const downloads = new TaskProgress();
|
||||
const installs = new TaskProgress();
|
||||
await newUpdater.updateToLatestWithOptions(retryOptions, progress => {
|
||||
const task = progress.task;
|
||||
const downloadTask = task.HostDownload || task.ModuleDownload;
|
||||
const installTask = task.HostInstall || task.ModuleInstall;
|
||||
installedAnything = true;
|
||||
if (downloadTask != null) {
|
||||
downloads.recordProgress(progress, downloadTask);
|
||||
}
|
||||
if (installTask != null) {
|
||||
installs.recordProgress(progress, installTask);
|
||||
if (progress.state.Failed != null) {
|
||||
if (task.HostInstall != null) {
|
||||
retryOptions.skip_host_delta = true;
|
||||
} else if (task.ModuleInstall != null) {
|
||||
retryOptions.skip_module_delta[installTask.version.module.name] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!downloads.updateSplashState(DOWNLOADING_UPDATES)) {
|
||||
installs.updateSplashState(INSTALLING_UPDATES);
|
||||
}
|
||||
});
|
||||
if (!installedAnything) {
|
||||
await newUpdater.startCurrentVersion();
|
||||
newUpdater.setRunningInBackground();
|
||||
newUpdater.collectGarbage();
|
||||
launchMainWindow();
|
||||
updateBackoff.succeed();
|
||||
updateSplashState(LAUNCHING);
|
||||
return;
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Update failed', e);
|
||||
await new Promise(resolve => {
|
||||
const delayMs = updateBackoff.fail(resolve);
|
||||
splashState.seconds = Math.round(delayMs / 1000);
|
||||
updateSplashState(UPDATE_FAILURE);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
/* eslint-enable camelcase */
|
||||
|
||||
function initOldUpdater() {
|
||||
modulesListeners = {};
|
||||
addModulesListener(CHECKING_FOR_UPDATES, () => {
|
||||
startUpdateTimeout();
|
||||
updateSplashState(CHECKING_FOR_UPDATES);
|
||||
});
|
||||
addModulesListener(UPDATE_CHECK_FINISHED, ({
|
||||
succeeded,
|
||||
updateCount,
|
||||
manualRequired
|
||||
}) => {
|
||||
stopUpdateTimeout();
|
||||
if (!succeeded) {
|
||||
scheduleUpdateCheck();
|
||||
updateSplashState(UPDATE_FAILURE);
|
||||
} else if (updateCount === 0) {
|
||||
moduleUpdater.setInBackground();
|
||||
launchMainWindow();
|
||||
updateSplashState(LAUNCHING);
|
||||
}
|
||||
});
|
||||
addModulesListener(DOWNLOADING_MODULE, ({
|
||||
name,
|
||||
current,
|
||||
total
|
||||
}) => {
|
||||
stopUpdateTimeout();
|
||||
splashState = {
|
||||
current,
|
||||
total
|
||||
};
|
||||
updateSplashState(DOWNLOADING_UPDATES);
|
||||
});
|
||||
addModulesListener(DOWNLOADING_MODULE_PROGRESS, ({
|
||||
name,
|
||||
progress
|
||||
}) => {
|
||||
splashState.progress = progress;
|
||||
updateSplashState(DOWNLOADING_UPDATES);
|
||||
});
|
||||
addModulesListener(DOWNLOADED_MODULE, ({
|
||||
name,
|
||||
current,
|
||||
total,
|
||||
succeeded
|
||||
}) => {
|
||||
delete splashState.progress;
|
||||
if (name === 'host') {
|
||||
restartRequired = true;
|
||||
}
|
||||
});
|
||||
addModulesListener(DOWNLOADING_MODULES_FINISHED, ({
|
||||
succeeded,
|
||||
failed
|
||||
}) => {
|
||||
if (failed > 0) {
|
||||
scheduleUpdateCheck();
|
||||
updateSplashState(UPDATE_FAILURE);
|
||||
} else {
|
||||
process.nextTick(() => {
|
||||
if (restartRequired) {
|
||||
moduleUpdater.quitAndInstallUpdates();
|
||||
} else {
|
||||
moduleUpdater.installPendingUpdates();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
addModulesListener(NO_PENDING_UPDATES, () => moduleUpdater.checkForUpdates());
|
||||
addModulesListener(INSTALLING_MODULE, ({
|
||||
name,
|
||||
current,
|
||||
total
|
||||
}) => {
|
||||
splashState = {
|
||||
current,
|
||||
total
|
||||
};
|
||||
updateSplashState(INSTALLING_UPDATES);
|
||||
});
|
||||
addModulesListener(INSTALLED_MODULE, ({
|
||||
name,
|
||||
current,
|
||||
total,
|
||||
succeeded
|
||||
}) => delete splashState.progress);
|
||||
addModulesListener(INSTALLING_MODULE_PROGRESS, ({
|
||||
name,
|
||||
progress
|
||||
}) => {
|
||||
splashState.progress = progress;
|
||||
updateSplashState(INSTALLING_UPDATES);
|
||||
});
|
||||
addModulesListener(INSTALLING_MODULES_FINISHED, ({
|
||||
succeeded,
|
||||
failed
|
||||
}) => moduleUpdater.checkForUpdates());
|
||||
addModulesListener(UPDATE_MANUALLY, ({
|
||||
newVersion
|
||||
}) => {
|
||||
splashState.newVersion = newVersion;
|
||||
updateSplashState(UPDATE_MANUALLY);
|
||||
});
|
||||
}
|
||||
function initSplash(startMinimized = false) {
|
||||
splashState = {};
|
||||
launchedMainWindow = false;
|
||||
updateAttempt = 0;
|
||||
newUpdater = (0, _updater.getUpdater)();
|
||||
if (newUpdater == null) {
|
||||
initOldUpdater();
|
||||
}
|
||||
launchSplashWindow(startMinimized);
|
||||
quoteCachePath = _path.default.join(paths.getUserData(), 'quotes.json');
|
||||
_ipcMain.default.on('UPDATED_QUOTES', (_event, quotes) => cacheLatestQuotes(quotes));
|
||||
}
|
||||
function destroySplash() {
|
||||
stopUpdateTimeout();
|
||||
if (splashWindow) {
|
||||
splashWindow.setSkipTaskbar(true);
|
||||
// defer the window hiding for a short moment so it gets covered by the main window
|
||||
const _nukeWindow = () => {
|
||||
if (splashWindow != null) {
|
||||
splashWindow.hide();
|
||||
splashWindow.close();
|
||||
splashWindow = null;
|
||||
}
|
||||
};
|
||||
setTimeout(_nukeWindow, 100);
|
||||
}
|
||||
}
|
||||
function addModulesListener(event, listener) {
|
||||
if (newUpdater != null) return;
|
||||
modulesListeners[event] = listener;
|
||||
moduleUpdater.events.addListener(event, listener);
|
||||
}
|
||||
function removeModulesListeners() {
|
||||
if (newUpdater != null) return;
|
||||
for (const event of Object.keys(modulesListeners)) {
|
||||
moduleUpdater.events.removeListener(event, modulesListeners[event]);
|
||||
}
|
||||
}
|
||||
function startUpdateTimeout() {
|
||||
if (!updateTimeout) {
|
||||
updateTimeout = setTimeout(() => scheduleUpdateCheck(), UPDATE_TIMEOUT_WAIT);
|
||||
}
|
||||
}
|
||||
function stopUpdateTimeout() {
|
||||
if (updateTimeout) {
|
||||
clearTimeout(updateTimeout);
|
||||
updateTimeout = null;
|
||||
}
|
||||
}
|
||||
function updateSplashState(event) {
|
||||
if (splashWindow != null && !splashWindow.isDestroyed() && !splashWindow.webContents.isDestroyed()) {
|
||||
webContentsSend(splashWindow, 'SPLASH_UPDATE_STATE', {
|
||||
status: event,
|
||||
...splashState
|
||||
});
|
||||
}
|
||||
}
|
||||
function launchSplashWindow(startMinimized) {
|
||||
const windowConfig = {
|
||||
width: LOADING_WINDOW_WIDTH,
|
||||
height: LOADING_WINDOW_HEIGHT,
|
||||
transparent: false,
|
||||
frame: false,
|
||||
resizable: false,
|
||||
center: true,
|
||||
show: false,
|
||||
webPreferences: {
|
||||
nodeIntegration: false,
|
||||
sandbox: false,
|
||||
enableRemoteModule: false,
|
||||
contextIsolation: true,
|
||||
preload: _path.default.join(__dirname, 'splashScreenPreload.js')
|
||||
}
|
||||
};
|
||||
splashWindow = new _electron.BrowserWindow(windowConfig);
|
||||
|
||||
// prevent users from dropping links to navigate in splash window
|
||||
splashWindow.webContents.on('will-navigate', e => e.preventDefault());
|
||||
splashWindow.webContents.on('new-window', (e, windowURL) => {
|
||||
e.preventDefault();
|
||||
(0, _securityUtils.saferShellOpenExternal)(windowURL);
|
||||
// exit, but delay half a second because openExternal is about to fire
|
||||
// some events to things that are freed by app.quit.
|
||||
setTimeout(_electron.app.quit, 500);
|
||||
});
|
||||
if (process.platform !== 'darwin') {
|
||||
// citron note: this causes a crash on quit while the window is open on osx
|
||||
splashWindow.on('closed', () => {
|
||||
splashWindow = null;
|
||||
if (!launchedMainWindow) {
|
||||
// user has closed this window before we launched the app, so let's quit
|
||||
_electron.app.quit();
|
||||
}
|
||||
});
|
||||
}
|
||||
_ipcMain.default.on('SPLASH_SCREEN_READY', () => {
|
||||
const cachedQuote = chooseCachedQuote();
|
||||
if (cachedQuote) {
|
||||
webContentsSend(splashWindow, 'SPLASH_SCREEN_QUOTE', cachedQuote);
|
||||
}
|
||||
if (splashWindow && !startMinimized) {
|
||||
splashWindow.show();
|
||||
}
|
||||
if (newUpdater != null) {
|
||||
updateUntilCurrent();
|
||||
} else {
|
||||
moduleUpdater.installPendingUpdates();
|
||||
}
|
||||
});
|
||||
_ipcMain.default.on('SPLASH_SCREEN_QUIT', () => {
|
||||
_electron.app.quit();
|
||||
});
|
||||
const splashUrl = _url.default.format({
|
||||
protocol: 'file',
|
||||
slashes: true,
|
||||
pathname: _path.default.join(__dirname, 'splash', 'index.html')
|
||||
});
|
||||
splashWindow.loadURL(splashUrl);
|
||||
}
|
||||
function launchMainWindow() {
|
||||
removeModulesListeners();
|
||||
if (!launchedMainWindow && splashWindow != null) {
|
||||
launchedMainWindow = true;
|
||||
events.emit(APP_SHOULD_LAUNCH);
|
||||
}
|
||||
}
|
||||
function scheduleUpdateCheck() {
|
||||
// TODO: can we use backoff here?
|
||||
updateAttempt += 1;
|
||||
const retryInSeconds = Math.min(updateAttempt * 10, RETRY_CAP_SECONDS);
|
||||
splashState.seconds = retryInSeconds;
|
||||
setTimeout(() => moduleUpdater.checkForUpdates(), retryInSeconds * 1000);
|
||||
}
|
||||
function focusWindow() {
|
||||
if (splashWindow != null) {
|
||||
splashWindow.focus();
|
||||
}
|
||||
}
|
||||
function pageReady() {
|
||||
destroySplash();
|
||||
process.nextTick(() => events.emit(APP_SHOULD_SHOW));
|
||||
}
|
||||
function cacheLatestQuotes(quotes) {
|
||||
_fs.default.writeFile(quoteCachePath, JSON.stringify(quotes), e => {
|
||||
if (e) {
|
||||
console.warn('Failed updating quote cache with error: ', e);
|
||||
}
|
||||
});
|
||||
}
|
||||
function chooseCachedQuote() {
|
||||
let cachedQuote = null;
|
||||
try {
|
||||
const cachedQuotes = JSON.parse(_fs.default.readFileSync(quoteCachePath));
|
||||
cachedQuote = cachedQuotes[Math.floor(Math.random() * cachedQuotes.length)];
|
||||
} catch (_err) {}
|
||||
return cachedQuote;
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
"use strict";
|
||||
|
||||
const {
|
||||
app,
|
||||
contextBridge,
|
||||
ipcRenderer
|
||||
} = require('electron');
|
||||
const {
|
||||
saferShellOpenExternal
|
||||
} = require('../common/securityUtils');
|
||||
contextBridge.exposeInMainWorld('DiscordSplash', {
|
||||
getReleaseChannel: () => {
|
||||
const buildInfo = require('./buildInfo');
|
||||
return buildInfo.releaseChannel;
|
||||
},
|
||||
signalReady: () => {
|
||||
ipcRenderer.send('DISCORD_SPLASH_SCREEN_READY');
|
||||
},
|
||||
onStateUpdate: callback => {
|
||||
ipcRenderer.on('DISCORD_SPLASH_UPDATE_STATE', (_, state) => {
|
||||
callback(state);
|
||||
});
|
||||
},
|
||||
onQuoteUpdate: callback => {
|
||||
ipcRenderer.on('DISCORD_SPLASH_SCREEN_QUOTE', (_, quote) => {
|
||||
callback(quote);
|
||||
});
|
||||
},
|
||||
openUrl: saferShellOpenExternal,
|
||||
quitDiscord: () => {
|
||||
ipcRenderer.send('DISCORD_SPLASH_SCREEN_QUIT');
|
||||
}
|
||||
});
|
|
@ -0,0 +1,189 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.handleStartupEvent = handleStartupEvent;
|
||||
exports.installProtocol = installProtocol;
|
||||
exports.restart = restart;
|
||||
exports.spawnUpdate = spawnUpdate;
|
||||
exports.spawnUpdateInstall = spawnUpdateInstall;
|
||||
exports.updateExistsSync = updateExistsSync;
|
||||
var _child_process = _interopRequireDefault(require("child_process"));
|
||||
var _fs = _interopRequireDefault(require("fs"));
|
||||
var _path = _interopRequireDefault(require("path"));
|
||||
var autoStart = _interopRequireWildcard(require("./autoStart"));
|
||||
var windowsUtils = _interopRequireWildcard(require("./windowsUtils"));
|
||||
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
||||
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && 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 }; }
|
||||
// citron note: this assumes the execPath is in the format Discord/someVersion/Discord.exe
|
||||
const appFolder = _path.default.resolve(process.execPath, '..');
|
||||
const rootFolder = _path.default.resolve(appFolder, '..');
|
||||
const exeName = _path.default.basename(process.execPath);
|
||||
const updateExe = _path.default.join(rootFolder, 'Update.exe');
|
||||
|
||||
// Specialized spawn function specifically used for spawning the updater in
|
||||
// update mode. Calls back with progress percentages.
|
||||
// Returns Promise.
|
||||
function spawnUpdateInstall(updateUrl, progressCallback) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const proc = _child_process.default.spawn(updateExe, ['--update', updateUrl]);
|
||||
proc.on('error', reject);
|
||||
proc.on('exit', code => {
|
||||
if (code !== 0) {
|
||||
return reject(new Error(`Update failed with exit code ${code}`));
|
||||
}
|
||||
return resolve();
|
||||
});
|
||||
let lastProgress = -1;
|
||||
function parseProgress() {
|
||||
const lines = stdout.split(/\r?\n/);
|
||||
if (lines.length === 1) return;
|
||||
// return the last (possibly incomplete) line to stdout for parsing again
|
||||
stdout = lines.pop();
|
||||
let currentProgress;
|
||||
for (const line of lines) {
|
||||
if (!/^\d\d?$/.test(line)) continue;
|
||||
const progress = Number(line);
|
||||
// make sure that this number is steadily increasing
|
||||
if (lastProgress > progress) continue;
|
||||
currentProgress = progress;
|
||||
}
|
||||
if (currentProgress == null) return;
|
||||
lastProgress = currentProgress;
|
||||
progressCallback(Math.min(currentProgress, 100));
|
||||
}
|
||||
let stdout = '';
|
||||
proc.stdout.on('data', chunk => {
|
||||
stdout += String(chunk);
|
||||
parseProgress();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Spawn the Update.exe with the given arguments and invoke the callback when
|
||||
// the command completes.
|
||||
function spawnUpdate(args, callback) {
|
||||
windowsUtils.spawn(updateExe, args, callback);
|
||||
}
|
||||
|
||||
// Create a desktop and start menu shortcut by using the command line API
|
||||
// provided by Squirrel's Update.exe
|
||||
function createShortcuts(callback, updateOnly) {
|
||||
// move icon out to a more stable location, to keep shortcuts from breaking as much
|
||||
const icoSrc = _path.default.join(appFolder, 'app.ico');
|
||||
const icoDest = _path.default.join(rootFolder, 'app.ico');
|
||||
let icoForTarget = icoDest;
|
||||
try {
|
||||
const ico = _fs.default.readFileSync(icoSrc);
|
||||
_fs.default.writeFileSync(icoDest, ico);
|
||||
} catch (e) {
|
||||
// if we can't write there for some reason, just use the source.
|
||||
icoForTarget = icoSrc;
|
||||
}
|
||||
const createShortcutArgs = ['--createShortcut', exeName, '--setupIcon', icoForTarget];
|
||||
if (updateOnly) {
|
||||
createShortcutArgs.push('--updateOnly');
|
||||
}
|
||||
spawnUpdate(createShortcutArgs, callback);
|
||||
}
|
||||
|
||||
// Add a protocol registration for this application.
|
||||
function installProtocol(protocol, callback) {
|
||||
const queue = [['HKCU\\Software\\Classes\\' + protocol, '/ve', '/d', `URL:${protocol} Protocol`], ['HKCU\\Software\\Classes\\' + protocol, '/v', 'URL Protocol'], ['HKCU\\Software\\Classes\\' + protocol + '\\DefaultIcon', '/ve', '/d', '"' + process.execPath + '",-1'], ['HKCU\\Software\\Classes\\' + protocol + '\\shell\\open\\command', '/ve', '/d', `"${process.execPath}" --url -- "%1"`]];
|
||||
windowsUtils.addToRegistry(queue, callback);
|
||||
}
|
||||
function terminate(app) {
|
||||
app.quit();
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
// Remove the desktop and start menu shortcuts by using the command line API
|
||||
// provided by Squirrel's Update.exe
|
||||
function removeShortcuts(callback) {
|
||||
spawnUpdate(['--removeShortcut', exeName], callback);
|
||||
}
|
||||
|
||||
// Update the desktop and start menu shortcuts by using the command line API
|
||||
// provided by Squirrel's Update.exe
|
||||
function updateShortcuts(callback) {
|
||||
createShortcuts(callback, true);
|
||||
}
|
||||
|
||||
// Purge the protocol for this applicationstart.
|
||||
function uninstallProtocol(protocol, callback) {
|
||||
windowsUtils.spawnReg(['delete', 'HKCU\\Software\\Classes\\' + protocol, '/f'], callback);
|
||||
}
|
||||
function maybeInstallNewUpdaterSeedDb() {
|
||||
const installerDbSrc = _path.default.join(appFolder, 'installer.db');
|
||||
const installerDbDest = _path.default.join(rootFolder, 'installer.db');
|
||||
if (_fs.default.existsSync(installerDbSrc)) {
|
||||
_fs.default.renameSync(installerDbSrc, installerDbDest);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle squirrel events denoted by --squirrel-* command line arguments.
|
||||
// returns `true` if regular startup should be prevented
|
||||
function handleStartupEvent(protocol, app, squirrelCommand) {
|
||||
switch (squirrelCommand) {
|
||||
case '--squirrel-install':
|
||||
createShortcuts(() => {
|
||||
autoStart.install(() => {
|
||||
installProtocol(protocol, () => {
|
||||
terminate(app);
|
||||
});
|
||||
});
|
||||
}, false);
|
||||
return true;
|
||||
case '--squirrel-updated':
|
||||
updateShortcuts(() => {
|
||||
autoStart.update(() => {
|
||||
installProtocol(protocol, () => {
|
||||
terminate(app);
|
||||
});
|
||||
});
|
||||
});
|
||||
return true;
|
||||
case '--squirrel-uninstall':
|
||||
removeShortcuts(() => {
|
||||
autoStart.uninstall(() => {
|
||||
uninstallProtocol(protocol, () => {
|
||||
terminate(app);
|
||||
});
|
||||
});
|
||||
});
|
||||
return true;
|
||||
case '--squirrel-obsolete':
|
||||
terminate(app);
|
||||
return true;
|
||||
case '--squirrel-firstrun':
|
||||
// Squirrel doesn't have a way to include app-level files. We get around
|
||||
// this for new updater hosts, which rely on a seeded manifest, by
|
||||
// bubbling the db up from the versioned-app directory if it exists.
|
||||
//
|
||||
// Additionally, we run this in --squirrel-firstrun, not
|
||||
// --squirrel-install, because the latter is unreliable with unicode
|
||||
// paths. yay!
|
||||
maybeInstallNewUpdaterSeedDb();
|
||||
return false;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Are we using Squirrel for updates?
|
||||
function updateExistsSync() {
|
||||
return _fs.default.existsSync(updateExe);
|
||||
}
|
||||
|
||||
// Restart app as the new version
|
||||
function restart(app, newVersion) {
|
||||
app.once('will-quit', () => {
|
||||
const execPath = _path.default.resolve(rootFolder, `app-${newVersion}/${exeName}`);
|
||||
_child_process.default.spawn(execPath, [], {
|
||||
detached: true
|
||||
});
|
||||
});
|
||||
app.quit();
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
var _electron = require("electron");
|
||||
var _default = [{
|
||||
label: 'Discord',
|
||||
submenu: [{
|
||||
label: 'Quit',
|
||||
click: () => _electron.app.quit(),
|
||||
accelerator: 'Command+Q'
|
||||
}]
|
||||
}];
|
||||
exports.default = _default;
|
||||
module.exports = exports.default;
|
|
@ -0,0 +1,11 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
var _electron = require("electron");
|
||||
const menu = require('./' + process.platform);
|
||||
var _default = _electron.Menu.buildFromTemplate(menu);
|
||||
exports.default = _default;
|
||||
module.exports = exports.default;
|
|
@ -0,0 +1,17 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
var _electron = require("electron");
|
||||
var _default = [{
|
||||
label: '&File',
|
||||
submenu: [{
|
||||
label: '&Exit',
|
||||
click: () => _electron.app.quit(),
|
||||
accelerator: 'Control+Q'
|
||||
}]
|
||||
}];
|
||||
exports.default = _default;
|
||||
module.exports = exports.default;
|
|
@ -0,0 +1,17 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
var _electron = require("electron");
|
||||
var _default = [{
|
||||
label: '&File',
|
||||
submenu: [{
|
||||
label: '&Exit',
|
||||
click: () => _electron.app.quit(),
|
||||
accelerator: 'Alt+F4'
|
||||
}]
|
||||
}];
|
||||
exports.default = _default;
|
||||
module.exports = exports.default;
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,76 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.addToRegistry = addToRegistry;
|
||||
exports.spawn = spawn;
|
||||
exports.spawnReg = spawnReg;
|
||||
var _child_process = _interopRequireDefault(require("child_process"));
|
||||
var _path = _interopRequireDefault(require("path"));
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
const regExe = process.env.SystemRoot ? _path.default.join(process.env.SystemRoot, 'System32', 'reg.exe') : 'reg.exe';
|
||||
|
||||
// Spawn a command and invoke the callback when it completes with an error
|
||||
// and the output from standard out.
|
||||
function spawn(command, args, callback) {
|
||||
let stdout = '';
|
||||
let spawnedProcess;
|
||||
try {
|
||||
// TODO: contrary to below, it should not throw any error
|
||||
spawnedProcess = _child_process.default.spawn(command, args);
|
||||
} catch (err) {
|
||||
// Spawn can throw an error
|
||||
process.nextTick(() => {
|
||||
if (callback != null) {
|
||||
callback(err, stdout);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: we need to specify the encoding for the data if we're going to concat it as a string
|
||||
spawnedProcess.stdout.on('data', data => {
|
||||
stdout += data;
|
||||
});
|
||||
let err = null;
|
||||
// TODO: close event might not get called, we should
|
||||
// callback on error https://nodejs.org/api/child_process.html#child_process_event_error
|
||||
spawnedProcess.on('error', err => {
|
||||
// TODO: there should always be an error
|
||||
if (err != null) {
|
||||
err = err;
|
||||
}
|
||||
});
|
||||
|
||||
// TODO: don't listen to close, but listen to exit instead
|
||||
spawnedProcess.on('close', (code, signal) => {
|
||||
if (err === null && code !== 0) {
|
||||
err = new Error('Command failed: ' + (signal || code));
|
||||
}
|
||||
if (err != null) {
|
||||
err.code = err.code || code;
|
||||
err.stdout = err.stdout || stdout;
|
||||
}
|
||||
if (callback != null) {
|
||||
callback(err, stdout);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Spawn reg.exe and callback when it completes
|
||||
function spawnReg(args, callback) {
|
||||
return spawn(regExe, args, callback);
|
||||
}
|
||||
|
||||
// TODO: since we're doing this one by one, we could have a more graceful way of processing the queue
|
||||
// rather than mutating the array
|
||||
function addToRegistry(queue, callback) {
|
||||
if (queue.length === 0) {
|
||||
return callback && callback();
|
||||
}
|
||||
const args = queue.shift();
|
||||
args.unshift('add');
|
||||
args.push('/f');
|
||||
return spawnReg(args, () => addToRegistry(queue, callback));
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"name": "discord",
|
||||
"description": "Discord Client for Desktop - Bootstrapper",
|
||||
"main": "app_bootstrap/index.js",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@sentry/node": "7.47.0",
|
||||
"mkdirp": "^0.5.1",
|
||||
"request": "2.88.0",
|
||||
"rimraf": "^2.6.3",
|
||||
"yauzl": "^2.10.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/electron": "1.6.10",
|
||||
"devtron": "1.4.0"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"discord_desktop_core": 0,
|
||||
"discord_erlpack": 0,
|
||||
"discord_spellcheck": 0,
|
||||
"discord_utils": 0,
|
||||
"discord_voice": 0
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"releaseChannel": "stable",
|
||||
"version": "0.0.27"
|
||||
}
|
16
CONTRIBUTORS
16
CONTRIBUTORS
|
@ -1,16 +0,0 @@
|
|||
# People who can (and typically have) contributed to this repository.
|
||||
#
|
||||
# This script is generated by contributors.sh
|
||||
#
|
||||
|
||||
alsoGAMER <35269770+alsoGAMER@users.noreply.github.com>
|
||||
CanadaHonk <19228318+CanadaHonk@users.noreply.github.com>
|
||||
CanadaHonk <oj@oojmed.com>
|
||||
Ian Manske <IanManske@pm.me>
|
||||
Julian Pettersen <darlion2301@hotmail.com>
|
||||
Kat <61893437+TransKat@users.noreply.github.com>
|
||||
Kyiro <54126666+Kyiro@users.noreply.github.com>
|
||||
Oj <oj@oojmed.com>
|
||||
|| Prof. - Xadk3!#0000 || @naryal2580 <naryal2580@proton.me>
|
||||
|| Prof. - Xadk3! <naryal2580@gmail.com>
|
||||
|| Prof. - Xadk3! <root@nick.cf>
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,14 @@
|
|||
[package]
|
||||
name = "OpenAsar"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
nostr-sdk = "0.20.1"
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
|
||||
[[bin]]
|
||||
name = "OpenAsar"
|
||||
path = "main.rs"
|
Binary file not shown.
|
@ -0,0 +1,11 @@
|
|||
#!/bin/sh
|
||||
|
||||
if [ ! "$1" ]; then
|
||||
echo "Enter PATH to krisp's Node file."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
NODE_PATH="$1"
|
||||
PATCHED_NODE_PATH="$(echo $NODE_PATH | cut -d '.' -f 1)_patched.node"
|
||||
|
||||
xxd -p -c 0 "$NODE_PATH" | sed -E \'s/(4889dfe8........85c0)745c/\19090/' | xxd -p -r -c 0 > "$PATCHED_NODE_PATH"
|
|
@ -1,13 +0,0 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
file="$(git rev-parse --show-toplevel)/CONTRIBUTORS"
|
||||
|
||||
cat <<EOF > "$file"
|
||||
# People who can (and typically have) contributed to this repository.
|
||||
#
|
||||
# This script is generated by $(basename "$0")
|
||||
#
|
||||
|
||||
EOF
|
||||
|
||||
git log --format='%aN <%aE>' | sort -uf >> "$file"
|
|
@ -1,54 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
// before we can set up (and export) our constants, we first need to grab bootstrap's constants
|
||||
// so we can merge them in with our constants
|
||||
function init(bootstrapConstants) {
|
||||
const APP_NAME = bootstrapConstants.APP_NAME;
|
||||
const API_ENDPOINT = bootstrapConstants.API_ENDPOINT;
|
||||
const NEW_UPDATE_ENDPOINT = bootstrapConstants.NEW_UPDATE_ENDPOINT;
|
||||
const UPDATE_ENDPOINT = bootstrapConstants.UPDATE_ENDPOINT;
|
||||
const APP_ID = bootstrapConstants.APP_ID;
|
||||
const DEFAULT_MAIN_WINDOW_ID = 0;
|
||||
const MAIN_APP_DIRNAME = __dirname;
|
||||
const UpdaterEvents = {
|
||||
UPDATE_NOT_AVAILABLE: 'UPDATE_NOT_AVAILABLE',
|
||||
CHECKING_FOR_UPDATES: 'CHECKING_FOR_UPDATES',
|
||||
UPDATE_ERROR: 'UPDATE_ERROR',
|
||||
UPDATE_MANUALLY: 'UPDATE_MANUALLY',
|
||||
UPDATE_AVAILABLE: 'UPDATE_AVAILABLE',
|
||||
MODULE_INSTALL_PROGRESS: 'MODULE_INSTALL_PROGRESS',
|
||||
UPDATE_DOWNLOADED: 'UPDATE_DOWNLOADED',
|
||||
MODULE_INSTALLED: 'MODULE_INSTALLED',
|
||||
CHECK_FOR_UPDATES: 'CHECK_FOR_UPDATES',
|
||||
QUIT_AND_INSTALL: 'QUIT_AND_INSTALL',
|
||||
MODULE_INSTALL: 'MODULE_INSTALL',
|
||||
MODULE_QUERY: 'MODULE_QUERY',
|
||||
UPDATER_HISTORY_QUERY_AND_TRUNCATE: 'UPDATER_HISTORY_QUERY_AND_TRUNCATE',
|
||||
UPDATER_HISTORY_RESPONSE: 'UPDATER_HISTORY_RESPONSE'
|
||||
};
|
||||
const MenuEvents = {
|
||||
OPEN_HELP: 'menu:open-help',
|
||||
OPEN_SETTINGS: 'menu:open-settings',
|
||||
CHECK_FOR_UPDATES: 'menu:check-for-updates'
|
||||
};
|
||||
const exported = {
|
||||
APP_NAME,
|
||||
DEFAULT_MAIN_WINDOW_ID,
|
||||
MAIN_APP_DIRNAME,
|
||||
APP_ID,
|
||||
API_ENDPOINT,
|
||||
NEW_UPDATE_ENDPOINT,
|
||||
UPDATE_ENDPOINT,
|
||||
UpdaterEvents,
|
||||
MenuEvents
|
||||
};
|
||||
for (const [k, v] of Object.entries(exported)) {
|
||||
module.exports[k] = v;
|
||||
}
|
||||
}
|
||||
module.exports = {
|
||||
init
|
||||
};
|
|
@ -1,20 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.getEnableHardwareAcceleration = getEnableHardwareAcceleration;
|
||||
exports.setEnableHardwareAcceleration = setEnableHardwareAcceleration;
|
||||
var _electron = require("electron");
|
||||
var _appSettings = require("./bootstrapModules/appSettings");
|
||||
const settings = _appSettings.appSettings.getSettings();
|
||||
function getEnableHardwareAcceleration() {
|
||||
// TODO: This should probably a constant
|
||||
return settings.get('enableHardwareAcceleration', true);
|
||||
}
|
||||
function setEnableHardwareAcceleration(enableHardwareAcceleration) {
|
||||
settings.set('enableHardwareAcceleration', enableHardwareAcceleration);
|
||||
settings.save();
|
||||
_electron.app.relaunch();
|
||||
_electron.app.exit(0);
|
||||
}
|
|
@ -1,86 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.hasInit = void 0;
|
||||
exports.init = init;
|
||||
var _electron = require("electron");
|
||||
var _utils = require("./utils");
|
||||
var _mainScreen = require("./mainScreen");
|
||||
var _ipcMain = _interopRequireDefault(require("./ipcMain"));
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
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;
|
||||
if (hasInit) {
|
||||
console.warn('appBadge: Has already init! Cancelling init.');
|
||||
return;
|
||||
}
|
||||
exports.hasInit = hasInit = true;
|
||||
lastIndex = null;
|
||||
appIcons = [];
|
||||
const resourcePath = `app/images/badges`;
|
||||
for (let i = 1; i <= 11; i++) {
|
||||
appIcons.push((0, _utils.exposeModuleResource)(resourcePath, `badge-${i}.ico`));
|
||||
}
|
||||
_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);
|
||||
|
||||
// Prevent setting a new icon when the icon is the same
|
||||
if (lastIndex !== index) {
|
||||
if (index == null) {
|
||||
win.setOverlayIcon(null, description);
|
||||
} else {
|
||||
win.setOverlayIcon(appIcons[index], description);
|
||||
}
|
||||
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
|
||||
description: `Unread messages`
|
||||
};
|
||||
}
|
||||
|
||||
// Clear overlay icon
|
||||
if (count === 0) {
|
||||
return {
|
||||
index: null,
|
||||
// null is used to clear the overlay icon
|
||||
description: 'No Notifications'
|
||||
};
|
||||
}
|
||||
|
||||
// Notification badge
|
||||
const index = Math.max(1, Math.min(count, 10)) - 1; // arrays are 0 based
|
||||
return {
|
||||
index,
|
||||
description: `${index} notifications`
|
||||
};
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.hasInit = void 0;
|
||||
exports.init = init;
|
||||
var _autoStart = require("./bootstrapModules/autoStart");
|
||||
var _appSettings = require("./bootstrapModules/appSettings");
|
||||
var _ipcMain = _interopRequireDefault(require("./ipcMain"));
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
const settings = _appSettings.appSettings.getSettings();
|
||||
const NOOP = () => {};
|
||||
let hasInit = false;
|
||||
exports.hasInit = hasInit;
|
||||
function init() {
|
||||
if (hasInit) {
|
||||
console.warn('appConfig: Has already init! Cancelling init.');
|
||||
return;
|
||||
}
|
||||
exports.hasInit = hasInit = true;
|
||||
_ipcMain.default.on('TOGGLE_MINIMIZE_TO_TRAY', (_event, value) => setMinimizeOnClose(value));
|
||||
_ipcMain.default.on('TOGGLE_OPEN_ON_STARTUP', (_event, value) => toggleRunOnStartup(value));
|
||||
_ipcMain.default.on('TOGGLE_START_MINIMIZED', (_event, value) => toggleStartMinimized(value));
|
||||
_ipcMain.default.on('UPDATE_OPEN_ON_STARTUP', _event => updateOpenOnStartup());
|
||||
}
|
||||
function setMinimizeOnClose(minimizeToTray) {
|
||||
settings.set('MINIMIZE_TO_TRAY', minimizeToTray);
|
||||
}
|
||||
function toggleRunOnStartup(openOnStartup) {
|
||||
settings.set('OPEN_ON_STARTUP', openOnStartup);
|
||||
if (openOnStartup) {
|
||||
_autoStart.autoStart.install(NOOP);
|
||||
} else {
|
||||
_autoStart.autoStart.uninstall(NOOP);
|
||||
}
|
||||
}
|
||||
function toggleStartMinimized(startMinimized) {
|
||||
settings.set('START_MINIMIZED', startMinimized);
|
||||
_autoStart.autoStart.isInstalled(installed => {
|
||||
// Only update the registry for this toggle if the app was already set to autorun
|
||||
if (installed) {
|
||||
_autoStart.autoStart.install(NOOP);
|
||||
}
|
||||
});
|
||||
}
|
||||
function updateOpenOnStartup() {
|
||||
_autoStart.autoStart.update(NOOP);
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.getFeatures = getFeatures;
|
||||
exports.init = init;
|
||||
var _FeatureFlags = _interopRequireDefault(require("../common/FeatureFlags"));
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
let features;
|
||||
function init() {
|
||||
features = new _FeatureFlags.default();
|
||||
}
|
||||
function getFeatures() {
|
||||
return features;
|
||||
}
|
|
@ -1,150 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
var _electron = require("electron");
|
||||
var _securityUtils = require("../../common/securityUtils");
|
||||
var Constants = _interopRequireWildcard(require("../Constants"));
|
||||
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
||||
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && 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;
|
||||
}
|
||||
var _default = enableDevtools => [{
|
||||
label: 'Discord',
|
||||
submenu: [{
|
||||
label: 'About Discord',
|
||||
selector: 'orderFrontStandardAboutPanel:'
|
||||
}, {
|
||||
label: 'Check for Updates...',
|
||||
click: () => _electron.app.emit(MenuEvents.CHECK_FOR_UPDATES)
|
||||
}, {
|
||||
label: 'Acknowledgements',
|
||||
click: () => (0, _securityUtils.saferShellOpenExternal)('https://discord.com/acknowledgements')
|
||||
}, SEPARATOR, {
|
||||
label: 'Preferences',
|
||||
click: () => _electron.app.emit(MenuEvents.OPEN_SETTINGS),
|
||||
accelerator: 'Command+,'
|
||||
}, SEPARATOR, {
|
||||
label: 'Services',
|
||||
submenu: []
|
||||
}, SEPARATOR, {
|
||||
label: 'Hide Discord',
|
||||
selector: 'hide:',
|
||||
accelerator: 'Command+H'
|
||||
}, {
|
||||
label: 'Hide Others',
|
||||
selector: 'hideOtherApplications:',
|
||||
accelerator: 'Command+Alt+H'
|
||||
}, {
|
||||
label: 'Show All',
|
||||
selector: 'unhideAllApplications:'
|
||||
}, SEPARATOR, {
|
||||
label: 'Quit',
|
||||
click: () => _electron.app.quit(),
|
||||
accelerator: 'Command+Q'
|
||||
}]
|
||||
}, {
|
||||
label: 'Edit',
|
||||
submenu: [{
|
||||
role: 'undo',
|
||||
accelerator: 'Command+Z'
|
||||
}, {
|
||||
role: 'redo',
|
||||
accelerator: 'Shift+Command+Z'
|
||||
}, SEPARATOR, {
|
||||
role: 'cut',
|
||||
accelerator: 'Command+X'
|
||||
}, {
|
||||
role: 'copy',
|
||||
accelerator: 'Command+C'
|
||||
}, {
|
||||
role: 'paste',
|
||||
accelerator: 'Command+V'
|
||||
}, {
|
||||
role: 'selectAll',
|
||||
accelerator: 'Command+A'
|
||||
}]
|
||||
}, {
|
||||
label: 'View',
|
||||
submenu: [{
|
||||
label: 'Reload',
|
||||
click: () => {
|
||||
const window = getWindow();
|
||||
if (window) {
|
||||
window.webContents.reloadIgnoringCache();
|
||||
}
|
||||
},
|
||||
accelerator: 'Command+R'
|
||||
}, {
|
||||
label: 'Toggle Full Screen',
|
||||
click: () => {
|
||||
const window = getWindow();
|
||||
if (window) {
|
||||
window.setFullScreen(!window.isFullScreen());
|
||||
}
|
||||
},
|
||||
accelerator: 'Command+Control+F'
|
||||
}, ...(enableDevtools ? [SEPARATOR, {
|
||||
label: 'Developer',
|
||||
submenu: [{
|
||||
label: 'Toggle Developer Tools',
|
||||
click: () => {
|
||||
const window = getWindow();
|
||||
if (window) {
|
||||
window.toggleDevTools();
|
||||
}
|
||||
},
|
||||
accelerator: 'Alt+Command+I'
|
||||
}]
|
||||
}] : [])]
|
||||
}, {
|
||||
label: 'Window',
|
||||
submenu: [{
|
||||
label: 'Minimize',
|
||||
selector: 'performMiniaturize:',
|
||||
accelerator: 'Command+M'
|
||||
}, {
|
||||
label: 'Zoom',
|
||||
selector: 'performZoom:'
|
||||
}, {
|
||||
label: 'Close',
|
||||
accelerator: 'Command+W',
|
||||
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:'
|
||||
}]
|
||||
}, {
|
||||
label: 'Help',
|
||||
submenu: [{
|
||||
label: 'Discord Help',
|
||||
click: () => _electron.app.emit(MenuEvents.OPEN_HELP)
|
||||
}]
|
||||
}];
|
||||
exports.default = _default;
|
||||
module.exports = exports.default;
|
|
@ -1,11 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
var _electron = require("electron");
|
||||
const createMenu = require('./' + process.platform);
|
||||
var _default = enableDevtools => _electron.Menu.buildFromTemplate(createMenu(enableDevtools));
|
||||
exports.default = _default;
|
||||
module.exports = exports.default;
|
|
@ -1,78 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
var _electron = require("electron");
|
||||
var Constants = _interopRequireWildcard(require("../Constants"));
|
||||
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
||||
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && 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'
|
||||
};
|
||||
var _default = enableDevtools => [{
|
||||
label: '&File',
|
||||
submenu: [{
|
||||
label: '&Options',
|
||||
click: () => _electron.app.emit(MenuEvents.OPEN_SETTINGS),
|
||||
accelerator: 'Control+,'
|
||||
}, SEPARATOR, {
|
||||
label: 'E&xit',
|
||||
click: () => _electron.app.quit(),
|
||||
accelerator: 'Control+Q'
|
||||
}]
|
||||
}, {
|
||||
label: '&Edit',
|
||||
submenu: [{
|
||||
role: 'undo',
|
||||
accelerator: 'Control+Z'
|
||||
}, {
|
||||
role: 'redo',
|
||||
accelerator: 'Shift+Control+Z'
|
||||
}, SEPARATOR, {
|
||||
role: 'cut',
|
||||
accelerator: 'Control+X'
|
||||
}, {
|
||||
role: 'copy',
|
||||
accelerator: 'Control+C'
|
||||
}, {
|
||||
role: 'paste',
|
||||
accelerator: 'Control+V'
|
||||
}, {
|
||||
role: 'selectAll',
|
||||
accelerator: 'Control+A'
|
||||
}]
|
||||
}, {
|
||||
label: '&View',
|
||||
submenu: [{
|
||||
label: '&Reload',
|
||||
click: () => _electron.BrowserWindow.getFocusedWindow().webContents.reloadIgnoringCache(),
|
||||
accelerator: 'Control+R'
|
||||
}, {
|
||||
label: 'Toggle &Full Screen',
|
||||
click: () => _electron.BrowserWindow.getFocusedWindow().setFullScreen(!_electron.BrowserWindow.getFocusedWindow().isFullScreen()),
|
||||
accelerator: 'Control+Shift+F'
|
||||
}, ...(enableDevtools ? [SEPARATOR, {
|
||||
label: '&Developer',
|
||||
submenu: [{
|
||||
label: 'Toggle Developer &Tools',
|
||||
click: () => _electron.BrowserWindow.getFocusedWindow().toggleDevTools(),
|
||||
accelerator: 'Control+Shift+I'
|
||||
}]
|
||||
}] : [])]
|
||||
}, {
|
||||
label: '&Help',
|
||||
submenu: [{
|
||||
label: 'Check for Updates',
|
||||
click: () => _electron.app.emit(MenuEvents.CHECK_FOR_UPDATES)
|
||||
}, SEPARATOR, {
|
||||
label: 'Discord Help',
|
||||
click: () => _electron.app.emit(MenuEvents.OPEN_HELP)
|
||||
}]
|
||||
}];
|
||||
exports.default = _default;
|
||||
module.exports = exports.default;
|
|
@ -1,57 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
var _electron = require("electron");
|
||||
var Constants = _interopRequireWildcard(require("../Constants"));
|
||||
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
||||
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && 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'
|
||||
};
|
||||
var _default = enableDevtools => [{
|
||||
label: '&File',
|
||||
submenu: [{
|
||||
label: '&Options',
|
||||
click: () => _electron.app.emit(MenuEvents.OPEN_SETTINGS),
|
||||
accelerator: 'Ctrl+,'
|
||||
}, SEPARATOR, {
|
||||
label: '&Exit',
|
||||
click: () => _electron.app.quit(),
|
||||
accelerator: 'Alt+F4'
|
||||
}]
|
||||
}, {
|
||||
label: '&View',
|
||||
submenu: [{
|
||||
label: '&Reload',
|
||||
click: () => _electron.BrowserWindow.getFocusedWindow().webContents.reloadIgnoringCache(),
|
||||
accelerator: 'Control+R'
|
||||
}, {
|
||||
label: 'Toggle &Full Screen',
|
||||
click: () => _electron.BrowserWindow.getFocusedWindow().setFullScreen(!_electron.BrowserWindow.getFocusedWindow().isFullScreen()),
|
||||
accelerator: 'Control+Shift+F'
|
||||
}, ...(enableDevtools ? [SEPARATOR, {
|
||||
label: '&Developer',
|
||||
submenu: [{
|
||||
label: 'Toggle Developer &Tools',
|
||||
click: () => _electron.BrowserWindow.getFocusedWindow().toggleDevTools(),
|
||||
accelerator: 'Control+Shift+I'
|
||||
}]
|
||||
}] : [])]
|
||||
}, {
|
||||
label: '&Help',
|
||||
submenu: [{
|
||||
label: 'Check for Updates',
|
||||
click: () => _electron.app.emit(MenuEvents.CHECK_FOR_UPDATES)
|
||||
}, SEPARATOR, {
|
||||
label: 'Discord Help',
|
||||
click: () => _electron.app.emit(MenuEvents.OPEN_HELP)
|
||||
}]
|
||||
}];
|
||||
exports.default = _default;
|
||||
module.exports = exports.default;
|
|
@ -1,12 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
Object.defineProperty(exports, "appSettings", {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return _bootstrapModules.appSettings;
|
||||
}
|
||||
});
|
||||
var _bootstrapModules = require("./bootstrapModules");
|
|
@ -1,12 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
Object.defineProperty(exports, "autoStart", {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return _bootstrapModules.autoStart;
|
||||
}
|
||||
});
|
||||
var _bootstrapModules = require("./bootstrapModules");
|
|
@ -1,52 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.crashReporterSetup = exports.buildInfo = exports.autoStart = exports.appSettings = exports.GPUSettings = exports.Constants = void 0;
|
||||
exports.init = init;
|
||||
exports.updater = exports.splashScreen = exports.requireNative = exports.paths = exports.moduleUpdater = void 0;
|
||||
let hasInit = false;
|
||||
|
||||
// NOTE: We may want to instead of initializing these to null, instead initialize them to their normal files.
|
||||
// This way each one (see `crashReporterSetup`) would not need to do their own self-detection of loading when
|
||||
// inside the overlay (or any future relevant code).
|
||||
let paths = null;
|
||||
exports.paths = paths;
|
||||
let splashScreen = null;
|
||||
exports.splashScreen = splashScreen;
|
||||
let autoStart = null;
|
||||
exports.autoStart = autoStart;
|
||||
let requireNative = null;
|
||||
exports.requireNative = requireNative;
|
||||
let appSettings = null;
|
||||
exports.appSettings = appSettings;
|
||||
let Constants = null;
|
||||
exports.Constants = Constants;
|
||||
let GPUSettings = null;
|
||||
exports.GPUSettings = GPUSettings;
|
||||
let buildInfo = null;
|
||||
exports.buildInfo = buildInfo;
|
||||
let moduleUpdater = null;
|
||||
exports.moduleUpdater = moduleUpdater;
|
||||
let updater = null;
|
||||
exports.updater = updater;
|
||||
let crashReporterSetup = null;
|
||||
exports.crashReporterSetup = crashReporterSetup;
|
||||
function init(bootstrapModules) {
|
||||
if (hasInit) {
|
||||
throw new Error(`bootstrapModules has already init`);
|
||||
}
|
||||
exports.paths = paths = bootstrapModules.paths;
|
||||
exports.splashScreen = splashScreen = bootstrapModules.splashScreen;
|
||||
exports.autoStart = autoStart = bootstrapModules.autoStart;
|
||||
exports.requireNative = requireNative = bootstrapModules.requireNative;
|
||||
exports.appSettings = appSettings = bootstrapModules.appSettings;
|
||||
exports.Constants = Constants = bootstrapModules.Constants;
|
||||
exports.GPUSettings = GPUSettings = bootstrapModules.GPUSettings;
|
||||
exports.buildInfo = buildInfo = bootstrapModules.buildInfo;
|
||||
exports.moduleUpdater = moduleUpdater = bootstrapModules.moduleUpdater;
|
||||
exports.updater = updater = bootstrapModules.updater;
|
||||
exports.crashReporterSetup = crashReporterSetup = bootstrapModules.crashReporterSetup;
|
||||
hasInit = true;
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
Object.defineProperty(exports, "buildInfo", {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return _bootstrapModules.buildInfo;
|
||||
}
|
||||
});
|
||||
var _bootstrapModules = require("./bootstrapModules");
|
|
@ -1,10 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.crashReporterSetup = void 0;
|
||||
var _bootstrapModules = require("./bootstrapModules");
|
||||
// Note: bootstrapCrashReporterSetup will not be set in the overlay.
|
||||
const crashReporterSetup = _bootstrapModules.crashReporterSetup ?? require('../../common/crashReporterSetup');
|
||||
exports.crashReporterSetup = crashReporterSetup;
|
|
@ -1,12 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
Object.defineProperty(exports, "moduleUpdater", {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return _bootstrapModules.moduleUpdater;
|
||||
}
|
||||
});
|
||||
var _bootstrapModules = require("./bootstrapModules");
|
|
@ -1,12 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
Object.defineProperty(exports, "paths", {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return _bootstrapModules.paths;
|
||||
}
|
||||
});
|
||||
var _bootstrapModules = require("./bootstrapModules");
|
|
@ -1,12 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
Object.defineProperty(exports, "splashScreen", {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return _bootstrapModules.splashScreen;
|
||||
}
|
||||
});
|
||||
var _bootstrapModules = require("./bootstrapModules");
|
|
@ -1,12 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
Object.defineProperty(exports, "updater", {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return _bootstrapModules.updater;
|
||||
}
|
||||
});
|
||||
var _bootstrapModules = require("./bootstrapModules");
|
File diff suppressed because it is too large
Load Diff
|
@ -1,8 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
var _electron = _interopRequireDefault(require("electron"));
|
||||
var _DiscordIPC = require("../common/DiscordIPC");
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
_DiscordIPC.DiscordIPC.main.handle(_DiscordIPC.IPCEvents.ACCESSIBILITY_GET_ENABLED, _ => {
|
||||
return Promise.resolve(_electron.default.app.accessibilitySupportEnabled);
|
||||
});
|
|
@ -1,96 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.injectBuildInfo = injectBuildInfo;
|
||||
exports.injectModuleUpdater = injectModuleUpdater;
|
||||
exports.injectUpdater = injectUpdater;
|
||||
var _electron = _interopRequireDefault(require("electron"));
|
||||
var _DiscordIPC = require("../common/DiscordIPC");
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
/* eslint-disable require-await */
|
||||
|
||||
let injectedBuildInfo = null;
|
||||
let injectedModuleUpdater = null;
|
||||
let injectedUpdater = null;
|
||||
function injectBuildInfo(buildInfo) {
|
||||
injectedBuildInfo = buildInfo;
|
||||
}
|
||||
function injectModuleUpdater(moduleUpdater) {
|
||||
injectedModuleUpdater = moduleUpdater;
|
||||
}
|
||||
function injectUpdater(updater) {
|
||||
injectedUpdater = updater;
|
||||
}
|
||||
_DiscordIPC.DiscordIPC.main.on(_DiscordIPC.IPCEvents.APP_GET_RELEASE_CHANNEL_SYNC, event => {
|
||||
event.returnValue = injectedBuildInfo.releaseChannel;
|
||||
});
|
||||
_DiscordIPC.DiscordIPC.main.on(_DiscordIPC.IPCEvents.APP_GET_HOST_VERSION_SYNC, event => {
|
||||
event.returnValue = _electron.default.app.getVersion();
|
||||
});
|
||||
async function newUpdaterGetModuleVersions(updater) {
|
||||
// eslint-disable-next-line camelcase
|
||||
return (await updater.queryCurrentVersions()).current_modules;
|
||||
}
|
||||
function newUpdaterGetBuildNumber(updater) {
|
||||
const version = updater.queryCurrentVersionsSync();
|
||||
// eslint-disable-next-line camelcase
|
||||
if (version.running_update != null) {
|
||||
return version.running_update.metadata_version;
|
||||
}
|
||||
return version.last_successful_update.metadata_version;
|
||||
}
|
||||
_DiscordIPC.DiscordIPC.main.on(_DiscordIPC.IPCEvents.APP_GET_BUILD_NUMBER, event => {
|
||||
var _injectedUpdater;
|
||||
const newUpdater = (_injectedUpdater = injectedUpdater) === null || _injectedUpdater === void 0 ? void 0 : _injectedUpdater.getUpdater();
|
||||
if (newUpdater != null) {
|
||||
event.returnValue = newUpdaterGetBuildNumber(newUpdater);
|
||||
return;
|
||||
}
|
||||
event.returnValue = null;
|
||||
});
|
||||
_DiscordIPC.DiscordIPC.main.handle(_DiscordIPC.IPCEvents.APP_GET_MODULE_VERSIONS, async _ => {
|
||||
var _injectedUpdater2;
|
||||
const newUpdater = (_injectedUpdater2 = injectedUpdater) === null || _injectedUpdater2 === void 0 ? void 0 : _injectedUpdater2.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;
|
||||
});
|
||||
_DiscordIPC.DiscordIPC.main.handle(_DiscordIPC.IPCEvents.APP_GET_PATH, async (_, path) => {
|
||||
// TODO: Fix argument in AsyncIPCEventMap.
|
||||
return _electron.default.app.getPath(path);
|
||||
});
|
||||
_DiscordIPC.DiscordIPC.main.handle(_DiscordIPC.IPCEvents.APP_SET_BADGE_COUNT, async (_, count) => {
|
||||
_electron.default.app.setBadgeCount(count);
|
||||
});
|
||||
_DiscordIPC.DiscordIPC.main.handle(_DiscordIPC.IPCEvents.APP_DOCK_SET_BADGE, async (_, badge) => {
|
||||
if (_electron.default.app.dock != null) {
|
||||
_electron.default.app.dock.setBadge(badge);
|
||||
}
|
||||
});
|
||||
_DiscordIPC.DiscordIPC.main.handle(_DiscordIPC.IPCEvents.APP_DOCK_BOUNCE, async (_, type) => {
|
||||
if (_electron.default.app.dock != null) {
|
||||
return _electron.default.app.dock.bounce(type);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
});
|
||||
_DiscordIPC.DiscordIPC.main.handle(_DiscordIPC.IPCEvents.APP_DOCK_CANCEL_BOUNCE, async (_, id) => {
|
||||
if (_electron.default.app.dock != null) {
|
||||
_electron.default.app.dock.cancelBounce(id);
|
||||
}
|
||||
});
|
||||
_DiscordIPC.DiscordIPC.main.handle(_DiscordIPC.IPCEvents.APP_RELAUNCH, async _ => {
|
||||
_electron.default.app.relaunch();
|
||||
_electron.default.app.exit(0);
|
||||
});
|
||||
_DiscordIPC.DiscordIPC.main.handle(_DiscordIPC.IPCEvents.APP_GET_DEFAULT_DOUBLE_CLICK_ACTION, async _ => {
|
||||
return _electron.default.systemPreferences.getUserDefault('AppleActionOnDoubleClick', 'string');
|
||||
});
|
|
@ -1,19 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
// @ts-nocheck
|
||||
/* eslint-disable */
|
||||
const electron = require('electron');
|
||||
const {
|
||||
CLIPBOARD_COPY,
|
||||
CLIPBOARD_CUT,
|
||||
CLIPBOARD_PASTE
|
||||
} = require('../common/constants').IPCEvents;
|
||||
electron.ipcMain.handle(CLIPBOARD_COPY, async _ => {
|
||||
electron.webContents.getFocusedWebContents().copy();
|
||||
});
|
||||
electron.ipcMain.handle(CLIPBOARD_CUT, async _ => {
|
||||
electron.webContents.getFocusedWebContents().cut();
|
||||
});
|
||||
electron.ipcMain.handle(CLIPBOARD_PASTE, async _ => {
|
||||
electron.webContents.getFocusedWebContents().paste();
|
||||
});
|
|
@ -1,134 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
var _buffer = _interopRequireDefault(require("buffer"));
|
||||
var _promises = _interopRequireDefault(require("fs/promises"));
|
||||
var _path = _interopRequireDefault(require("path"));
|
||||
var _DiscordIPC = require("../common/DiscordIPC");
|
||||
var _fileutils = require("../common/fileutils");
|
||||
var _utils = require("../common/utils");
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
/* eslint-disable no-console */
|
||||
|
||||
const MAX_LENGTH = _buffer.default.constants.MAX_LENGTH;
|
||||
const DISCORD_HEADER_NAME = 'dscl';
|
||||
const INVALID_FILE_ERROR = 'Invalid file';
|
||||
class InvalidFileError extends Error {}
|
||||
function verifyIsMP4(buffer) {
|
||||
if (getBoxHeaderName(buffer, 0) !== 'ftyp') {
|
||||
throw new InvalidFileError(INVALID_FILE_ERROR);
|
||||
}
|
||||
}
|
||||
function verifyHasMP4Extension(filename) {
|
||||
if (_path.default.parse(filename).ext !== '.mp4') {
|
||||
throw new InvalidFileError(INVALID_FILE_ERROR);
|
||||
}
|
||||
}
|
||||
function getBoxSize(buffer, startIndex) {
|
||||
return buffer.readUInt32BE(startIndex);
|
||||
}
|
||||
function getBoxHeaderName(buffer, startIndex) {
|
||||
return buffer.toString('ascii', startIndex + 4, startIndex + 8);
|
||||
}
|
||||
function verifyValidClip(buffer) {
|
||||
let currIndex = 0;
|
||||
while (currIndex < buffer.byteLength) {
|
||||
const boxHeaderName = getBoxHeaderName(buffer, currIndex);
|
||||
if (boxHeaderName === DISCORD_HEADER_NAME) {
|
||||
return;
|
||||
}
|
||||
const boxSize = getBoxSize(buffer, currIndex);
|
||||
//box size must be at least 8 to account for header, so return false for malformed file
|
||||
if (boxSize < 8) {
|
||||
throw new InvalidFileError(INVALID_FILE_ERROR);
|
||||
}
|
||||
currIndex += boxSize;
|
||||
}
|
||||
throw new InvalidFileError(INVALID_FILE_ERROR);
|
||||
}
|
||||
async function loadClip(filename) {
|
||||
try {
|
||||
verifyHasMP4Extension(filename);
|
||||
const result = await (0, _fileutils.readFulfilledFiles)([filename], MAX_LENGTH, true);
|
||||
const buffer = result[0].data;
|
||||
verifyIsMP4(buffer);
|
||||
verifyValidClip(buffer);
|
||||
return result[0];
|
||||
} catch (e) {
|
||||
if (e instanceof InvalidFileError) {
|
||||
console.log(`Invalid clips file: ${e}`);
|
||||
} else {
|
||||
console.error(`Invalid clips file: ${e}`);
|
||||
}
|
||||
throw new Error(INVALID_FILE_ERROR);
|
||||
}
|
||||
}
|
||||
async function getClipMetadata(filename, dirPath) {
|
||||
try {
|
||||
verifyHasMP4Extension(filename);
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
const filepath = _path.default.join(dirPath, filename);
|
||||
const handle = await _promises.default.open(filepath, 'r');
|
||||
const stats = await handle.stat();
|
||||
let currIndex = 0;
|
||||
const mp4HeaderBuffer = Buffer.alloc(8);
|
||||
try {
|
||||
await handle.read({
|
||||
buffer: mp4HeaderBuffer,
|
||||
position: 0
|
||||
});
|
||||
verifyIsMP4(mp4HeaderBuffer);
|
||||
currIndex += getBoxSize(mp4HeaderBuffer, currIndex);
|
||||
while (currIndex < stats.size) {
|
||||
await handle.read({
|
||||
buffer: mp4HeaderBuffer,
|
||||
position: currIndex
|
||||
});
|
||||
const boxSize = getBoxSize(mp4HeaderBuffer, 0);
|
||||
if (boxSize < 8) {
|
||||
return null;
|
||||
}
|
||||
const header = getBoxHeaderName(mp4HeaderBuffer, 0);
|
||||
if (header === DISCORD_HEADER_NAME) {
|
||||
const metadataBuffer = Buffer.alloc(boxSize - 8);
|
||||
await handle.read({
|
||||
buffer: metadataBuffer,
|
||||
position: currIndex + 8
|
||||
});
|
||||
const metadata = JSON.parse(metadataBuffer.toString('utf-8'));
|
||||
return {
|
||||
filepath: filepath,
|
||||
metadata: metadata
|
||||
};
|
||||
}
|
||||
currIndex += boxSize;
|
||||
}
|
||||
return null;
|
||||
} catch (e) {
|
||||
console.log(`error: ${e}`);
|
||||
return null;
|
||||
} finally {
|
||||
await handle.close();
|
||||
}
|
||||
}
|
||||
async function deleteClip(path) {
|
||||
try {
|
||||
await loadClip(path);
|
||||
await (0, _fileutils.deleteFile)(path);
|
||||
} catch (e) {
|
||||
console.log(`Invalid clips file to delete: ${e}`);
|
||||
throw new Error(INVALID_FILE_ERROR);
|
||||
}
|
||||
}
|
||||
_DiscordIPC.DiscordIPC.main.handle(_DiscordIPC.IPCEvents.LOAD_CLIP, (_, path) => {
|
||||
return loadClip(path);
|
||||
});
|
||||
_DiscordIPC.DiscordIPC.main.handle(_DiscordIPC.IPCEvents.LOAD_CLIPS_DIRECTORY, async (_, dirPath) => {
|
||||
const filenames = await (0, _fileutils.getFilesnamesFromDirectory)(dirPath);
|
||||
const filteredFiles = (await Promise.all(filenames.map(filename => getClipMetadata(filename, dirPath)))).filter(_utils.isNotNullish);
|
||||
return filteredFiles;
|
||||
});
|
||||
_DiscordIPC.DiscordIPC.main.handle(_DiscordIPC.IPCEvents.DELETE_CLIP, (_, path) => {
|
||||
return deleteClip(path);
|
||||
});
|
|
@ -1,26 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
// @ts-nocheck
|
||||
/* eslint-disable */
|
||||
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,25 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
var _assert = _interopRequireDefault(require("assert"));
|
||||
var _electron = _interopRequireDefault(require("electron"));
|
||||
var _lodash = _interopRequireDefault(require("lodash"));
|
||||
var _crashReporterUtils = require("../../../common/crashReporterUtils");
|
||||
var _crashReporterSetup = require("../../bootstrapModules/crashReporterSetup");
|
||||
var _DiscordIPC = require("../common/DiscordIPC");
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
_DiscordIPC.DiscordIPC.main.handle(_DiscordIPC.IPCEvents.CRASH_REPORTER_UPDATE_METADATA, (_, additionalMetadata) => {
|
||||
const metadata = _crashReporterSetup.crashReporterSetup.metadata;
|
||||
(0, _assert.default)(metadata != null, 'Metadata imported improperly.');
|
||||
const finalMetadata = _lodash.default.defaultsDeep(metadata, additionalMetadata ?? {});
|
||||
(0, _crashReporterUtils.reconcileCrashReporterMetadata)(_electron.default.crashReporter, finalMetadata);
|
||||
return Promise.resolve({
|
||||
metadata: finalMetadata
|
||||
});
|
||||
});
|
||||
|
||||
// Internal test for unhandled JS exception
|
||||
_electron.default.ipcMain.handle(_DiscordIPC.IPCEvents.UNHANDLED_JS_EXCEPTION, _ => {
|
||||
setTimeout(() => {
|
||||
throw new Error('UNHANDLED_EXCEPTION ' + process.type);
|
||||
}, 50);
|
||||
});
|
|
@ -1,8 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
var _electron = _interopRequireDefault(require("electron"));
|
||||
var _DiscordIPC = require("../common/DiscordIPC");
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
_DiscordIPC.DiscordIPC.main.handle(_DiscordIPC.IPCEvents.DESKTOP_CAPTURER_GET_SOURCES, (_, opts) => {
|
||||
return _electron.default.desktopCapturer.getSources(opts);
|
||||
});
|
|
@ -1,25 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.injectFeaturesBackend = injectFeaturesBackend;
|
||||
var _DiscordIPC = require("../common/DiscordIPC");
|
||||
let injectedFeatures = null;
|
||||
function getFeatures() {
|
||||
return injectedFeatures != null ? injectedFeatures : {
|
||||
getSupported: () => {
|
||||
return [];
|
||||
},
|
||||
supports: () => {
|
||||
return false;
|
||||
},
|
||||
declareSupported: () => {}
|
||||
};
|
||||
}
|
||||
function injectFeaturesBackend(features) {
|
||||
injectedFeatures = features;
|
||||
}
|
||||
_DiscordIPC.DiscordIPC.main.on(_DiscordIPC.IPCEvents.FEATURES_GET_BROWSER_FEATURES, event => {
|
||||
event.returnValue = getFeatures().getSupported();
|
||||
});
|
|
@ -1,32 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
var _electron = _interopRequireDefault(require("electron"));
|
||||
var _DiscordIPC = require("../common/DiscordIPC");
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
/* eslint-disable require-await */
|
||||
|
||||
function getModulePath() {
|
||||
// The smoketest's need to be able to:
|
||||
// 1) store multiple running instances data separately,
|
||||
// 2) have it in a known location so it can be used as a build artifact.
|
||||
if (process.env.DISCORD_USER_DATA_DIR != null) {
|
||||
return process.env.DISCORD_USER_DATA_DIR;
|
||||
}
|
||||
return global.moduleDataPath ?? global.modulePath;
|
||||
}
|
||||
_DiscordIPC.DiscordIPC.main.handle(_DiscordIPC.IPCEvents.FILE_MANAGER_GET_MODULE_PATH, async _ => {
|
||||
return getModulePath();
|
||||
});
|
||||
_DiscordIPC.DiscordIPC.main.handle(_DiscordIPC.IPCEvents.FILE_MANAGER_SHOW_SAVE_DIALOG, async (_, dialogOptions) => {
|
||||
return await _electron.default.dialog.showSaveDialog(dialogOptions);
|
||||
});
|
||||
_DiscordIPC.DiscordIPC.main.handle(_DiscordIPC.IPCEvents.FILE_MANAGER_SHOW_OPEN_DIALOG, async (_, dialogOptions) => {
|
||||
return await _electron.default.dialog.showOpenDialog(dialogOptions);
|
||||
});
|
||||
_DiscordIPC.DiscordIPC.main.handle(_DiscordIPC.IPCEvents.FILE_MANAGER_SHOW_ITEM_IN_FOLDER, async (_, path) => {
|
||||
_electron.default.shell.showItemInFolder(path);
|
||||
});
|
||||
_DiscordIPC.DiscordIPC.main.on(_DiscordIPC.IPCEvents.FILE_MANAGER_GET_MODULE_DATA_PATH_SYNC, event => {
|
||||
// This is kind of a lie... we offer no promise that moduleDataPath or modulePath are set.
|
||||
event.returnValue = getModulePath();
|
||||
});
|
|
@ -1,89 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
var _electron = _interopRequireDefault(require("electron"));
|
||||
var _path = _interopRequireDefault(require("path"));
|
||||
var _url = require("url");
|
||||
var _processUtils = require("../../../common/processUtils");
|
||||
var _mainScreen = require("../../mainScreen");
|
||||
var _DiscordIPC = require("../common/DiscordIPC");
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
/* eslint-disable no-console */
|
||||
|
||||
let interactiveWindow = null;
|
||||
// let transparentWindow: electron.BrowserWindow | null = null;
|
||||
|
||||
// We need to be restrictive about what url's are accepted.
|
||||
function isValidUrl(url) {
|
||||
try {
|
||||
const parsedUrl = new _url.URL(url);
|
||||
if (parsedUrl.origin !== _mainScreen.WEBAPP_ENDPOINT) {
|
||||
console.error(`isValidUrl: "${parsedUrl.origin}" !== "${_mainScreen.WEBAPP_ENDPOINT}" (${url})`);
|
||||
return false;
|
||||
}
|
||||
if (parsedUrl.pathname !== '/overlay') {
|
||||
console.error(`isValidUrl: Invalid pathname "${parsedUrl.pathname}" (${url})`);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} catch (e) {
|
||||
console.error(`isValidUrl: Error "${e}" (${url})`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
_DiscordIPC.DiscordIPC.main.handle(_DiscordIPC.IPCEvents.GLOBAL_OVERLAY_OPEN, (_, url) => {
|
||||
if (!_processUtils.IS_WIN) {
|
||||
console.log('GLOBAL_OVERLAY_OPEN: Windows only.');
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
// TODO: Check if the url has changed...?
|
||||
if (interactiveWindow != null) {
|
||||
console.log('GLOBAL_OVERLAY_OPEN: Window already open.');
|
||||
return Promise.resolve();
|
||||
}
|
||||
if (!isValidUrl(url)) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
// The title is randomized to prevent multiple instances from having conflicting titles.
|
||||
// We may want a global lock on there being a single global overlay tho.
|
||||
// TODO: The titlebar is blanked out by the javascript code, which is fine'ish for now because the mixture
|
||||
// of window class and window title are unique for the time being.
|
||||
const windowOptions = {
|
||||
width: 0,
|
||||
height: 0,
|
||||
x: 0,
|
||||
y: 0,
|
||||
transparent: true,
|
||||
title: 'Discord_Overlay3' + Math.round(Math.random() * 1e9).toString(16),
|
||||
// TODO: For some reason, it does not workout if the window starts hidden. Perhaps it's not loading and the native
|
||||
// code isn't firing?
|
||||
// show: false, // It's shown when initialized by the native code.
|
||||
frame: false,
|
||||
// Sets WS_EX_NOACTIVATE, which keeps it out of the taskbar prior to our initialization running.
|
||||
// Disabled for the time being as it appears to make opening dev tools impossible.
|
||||
// focusable: true,
|
||||
webPreferences: {
|
||||
preload: _path.default.join(__dirname, '..', '..', 'mainScreenPreload.js'),
|
||||
nodeIntegration: false,
|
||||
sandbox: false,
|
||||
contextIsolation: true
|
||||
}
|
||||
};
|
||||
try {
|
||||
interactiveWindow = new _electron.default.BrowserWindow(windowOptions);
|
||||
interactiveWindow.once('closed', () => {
|
||||
// Untested code path.
|
||||
interactiveWindow = null;
|
||||
console.log('GLOBAL_OVERLAY_OPEN: closed');
|
||||
});
|
||||
|
||||
// Enable when finally working on the non-interactive layer.
|
||||
// transparentWindow = new electron.BrowserWindow(windowOptions);
|
||||
|
||||
interactiveWindow.loadURL(url + '#global_overlay');
|
||||
} catch (e) {
|
||||
console.log(`GLOBAL_OVERLAY_OPEN: Error "${e.text}"\n${e.stack}`);
|
||||
}
|
||||
return Promise.resolve();
|
||||
});
|
|
@ -1,25 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.injectGpuSettingsBackend = injectGpuSettingsBackend;
|
||||
// @ts-nocheck
|
||||
/* eslint-disable */
|
||||
const electron = require('electron');
|
||||
const {
|
||||
GPU_SETTINGS_SET_ENABLE_HWACCEL,
|
||||
GPU_SETTINGS_GET_ENABLE_HWACCEL_SYNC
|
||||
} = require('../common/constants').IPCEvents;
|
||||
let injectedGpuSettings = null;
|
||||
function injectGpuSettingsBackend(gpuSettings) {
|
||||
injectedGpuSettings = gpuSettings;
|
||||
}
|
||||
electron.ipcMain.handle(GPU_SETTINGS_SET_ENABLE_HWACCEL, async (_, enable) => {
|
||||
if (injectedGpuSettings) {
|
||||
injectedGpuSettings.setEnableHardwareAcceleration(enable);
|
||||
}
|
||||
});
|
||||
electron.ipcMain.on(GPU_SETTINGS_GET_ENABLE_HWACCEL_SYNC, event => {
|
||||
event.returnValue = injectedGpuSettings != null ? injectedGpuSettings.getEnableHardwareAcceleration() : false;
|
||||
});
|
|
@ -1,97 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.injectModuleUpdater = injectModuleUpdater;
|
||||
exports.injectUpdater = injectUpdater;
|
||||
const childProcess = require('child_process');
|
||||
const electron = require('electron');
|
||||
const {
|
||||
once
|
||||
} = require('events');
|
||||
const path = require('path');
|
||||
const process = require('process');
|
||||
const {
|
||||
getGlobalPaths
|
||||
} = require('../../../common/nodeGlobalPaths');
|
||||
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,
|
||||
browserModulePaths: getGlobalPaths()
|
||||
};
|
||||
});
|
||||
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((resolve, reject) => {
|
||||
const installedHandler = installedModuleEvent => {
|
||||
if (installedModuleEvent.name === moduleName) {
|
||||
updater.events.removeListener(updater.INSTALLED_MODULE, installedHandler);
|
||||
if (installedModuleEvent.succeeded) {
|
||||
resolve();
|
||||
} else {
|
||||
reject(new Error(`Failed to install ${moduleName}`));
|
||||
}
|
||||
}
|
||||
};
|
||||
updater.events.on(updater.INSTALLED_MODULE, installedHandler);
|
||||
});
|
||||
updater.install(moduleName, false);
|
||||
await waitForInstall;
|
||||
});
|
||||
electron.ipcMain.on(NATIVE_MODULES_GET_HAS_NEW_UPDATER, event => {
|
||||
var _injectedUpdater2;
|
||||
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,33 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
const electron = require('electron');
|
||||
const {
|
||||
POWER_MONITOR_RESUME,
|
||||
POWER_MONITOR_SUSPEND,
|
||||
POWER_MONITOR_LOCK_SCREEN,
|
||||
POWER_MONITOR_UNLOCK_SCREEN,
|
||||
POWER_MONITOR_GET_SYSTEM_IDLE_TIME
|
||||
} = require('../common/constants').IPCEvents;
|
||||
electron.ipcMain.handle(POWER_MONITOR_GET_SYSTEM_IDLE_TIME, async _ => {
|
||||
return electron.powerMonitor.getSystemIdleTime() * 1000;
|
||||
});
|
||||
function sendToAllWindows(channel) {
|
||||
electron.BrowserWindow.getAllWindows().forEach(win => {
|
||||
const contents = win.webContents;
|
||||
if (contents != null) {
|
||||
contents.send(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,25 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
const electron = require('electron');
|
||||
const {
|
||||
POWER_SAVE_BLOCKER_BLOCK_DISPLAY_SLEEP,
|
||||
POWER_SAVE_BLOCKER_UNBLOCK_DISPLAY_SLEEP,
|
||||
POWER_SAVE_BLOCKER_CLEANUP_DISPLAY_SLEEP
|
||||
} = require('../common/constants').IPCEvents;
|
||||
const powerSaveBlockerIds = new Set();
|
||||
electron.ipcMain.handle(POWER_SAVE_BLOCKER_BLOCK_DISPLAY_SLEEP, async _ => {
|
||||
const newId = electron.powerSaveBlocker.start('prevent-display-sleep');
|
||||
powerSaveBlockerIds.add(newId);
|
||||
return newId;
|
||||
});
|
||||
electron.ipcMain.handle(POWER_SAVE_BLOCKER_UNBLOCK_DISPLAY_SLEEP, async (_, id) => {
|
||||
electron.powerSaveBlocker.stop(id);
|
||||
powerSaveBlockerIds.delete(id);
|
||||
});
|
||||
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();
|
||||
});
|
|
@ -1,80 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.processUtilsSettings = void 0;
|
||||
var _electron = _interopRequireDefault(require("electron"));
|
||||
var _os = _interopRequireDefault(require("os"));
|
||||
var _process = _interopRequireDefault(require("process"));
|
||||
var _systeminformation = _interopRequireDefault(require("systeminformation"));
|
||||
var _DiscordIPC = require("../common/DiscordIPC");
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
// Since crashes normally happen inside of the renderer process, we can store crash information inside of the
|
||||
// browser/main process, and report it back after the next startup.
|
||||
// lastRunsStoredInformation is set from currentStoredInformation, and currentStoredInformation is cleared on startup.
|
||||
const processUtilsSettings = {
|
||||
rendererCrashReason: null,
|
||||
rendererCrashExitCode: null,
|
||||
lastRunsStoredInformation: {},
|
||||
currentStoredInformation: {}
|
||||
};
|
||||
exports.processUtilsSettings = processUtilsSettings;
|
||||
_DiscordIPC.DiscordIPC.main.handle(_DiscordIPC.IPCEvents.PROCESS_UTILS_GET_CPU_USAGE, _ => {
|
||||
let totalProcessorUsagePercent = 0.0;
|
||||
for (const processMetric of _electron.default.app.getAppMetrics()) {
|
||||
totalProcessorUsagePercent += processMetric.cpu.percentCPUUsage;
|
||||
}
|
||||
return Promise.resolve(totalProcessorUsagePercent);
|
||||
});
|
||||
_DiscordIPC.DiscordIPC.main.handle(_DiscordIPC.IPCEvents.PROCESS_UTILS_GET_LAST_CRASH, _ => {
|
||||
return Promise.resolve({
|
||||
..._electron.default.crashReporter.getLastCrashReport(),
|
||||
rendererCrashReason: processUtilsSettings.rendererCrashReason,
|
||||
rendererCrashExitCode: processUtilsSettings.rendererCrashExitCode,
|
||||
storedInformation: processUtilsSettings.lastRunsStoredInformation
|
||||
});
|
||||
});
|
||||
_DiscordIPC.DiscordIPC.main.handle(_DiscordIPC.IPCEvents.PROCESS_UTILS_GET_MEMORY_INFO, _ => {
|
||||
return _process.default.getProcessMemoryInfo();
|
||||
});
|
||||
_DiscordIPC.DiscordIPC.main.handle(_DiscordIPC.IPCEvents.PROCESS_UTILS_GET_SYSTEM_INFO, async _ => {
|
||||
const gpuInfo = await _systeminformation.default.graphics();
|
||||
return {
|
||||
cpus: _os.default.cpus().map(cpu => ({
|
||||
model: cpu.model,
|
||||
speed: cpu.speed
|
||||
})),
|
||||
gpus: gpuInfo.controllers.map(({
|
||||
model,
|
||||
vendor,
|
||||
vram
|
||||
}) => ({
|
||||
model,
|
||||
vendor,
|
||||
memory: vram ?? -1
|
||||
})),
|
||||
total_memory: _os.default.totalmem()
|
||||
};
|
||||
});
|
||||
_DiscordIPC.DiscordIPC.main.handle(_DiscordIPC.IPCEvents.PROCESS_UTILS_FLUSH_DNS_CACHE, _ => {
|
||||
const defaultSession = _electron.default.session.defaultSession;
|
||||
if (defaultSession != null && defaultSession.clearHostResolverCache != null) {
|
||||
defaultSession.clearHostResolverCache();
|
||||
}
|
||||
return Promise.resolve();
|
||||
});
|
||||
_DiscordIPC.DiscordIPC.main.handle(_DiscordIPC.IPCEvents.PROCESS_UTILS_FLUSH_COOKIES, _ => {
|
||||
return _electron.default.session.defaultSession.cookies.flushStore();
|
||||
});
|
||||
_DiscordIPC.DiscordIPC.main.handle(_DiscordIPC.IPCEvents.PROCESS_UTILS_FLUSH_STORAGE_DATA, _ => {
|
||||
_electron.default.session.defaultSession.flushStorageData();
|
||||
return Promise.resolve();
|
||||
});
|
||||
_DiscordIPC.DiscordIPC.main.on(_DiscordIPC.IPCEvents.PROCESS_UTILS_GET_MAIN_ARGV_SYNC, event => {
|
||||
event.returnValue = _process.default.argv;
|
||||
});
|
||||
_DiscordIPC.DiscordIPC.main.handle(_DiscordIPC.IPCEvents.PROCESS_UTILS_SET_CRASH_INFORMATION, (_, crashInformation, state) => {
|
||||
processUtilsSettings.currentStoredInformation[crashInformation] = state;
|
||||
return Promise.resolve();
|
||||
});
|
|
@ -1,29 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
const electron = require('electron');
|
||||
const {
|
||||
SAFE_STORAGE_IS_ENCRYPTION_AVAILABLE,
|
||||
SAFE_STORAGE_ENCRYPT_STRING,
|
||||
SAFE_STORAGE_DECRYPT_STRING
|
||||
} = require('../common/constants').IPCEvents;
|
||||
electron.ipcMain.on(SAFE_STORAGE_IS_ENCRYPTION_AVAILABLE, event => {
|
||||
event.returnValue = electron.safeStorage != null && electron.safeStorage.isEncryptionAvailable();
|
||||
});
|
||||
electron.ipcMain.on(SAFE_STORAGE_ENCRYPT_STRING, (event, plainText) => {
|
||||
if (plainText) {
|
||||
event.returnValue = electron.safeStorage.encryptString(plainText).toString('base64');
|
||||
} else {
|
||||
event.returnValue = null;
|
||||
}
|
||||
});
|
||||
electron.ipcMain.on(SAFE_STORAGE_DECRYPT_STRING, (event, encrypted) => {
|
||||
if (encrypted) {
|
||||
try {
|
||||
event.returnValue = electron.safeStorage.decryptString(Buffer.from(encrypted, 'base64'));
|
||||
} catch {
|
||||
event.returnValue = null;
|
||||
}
|
||||
} else {
|
||||
event.returnValue = null;
|
||||
}
|
||||
});
|
|
@ -1,36 +0,0 @@
|
|||
"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;
|
||||
let injectedSettings = null;
|
||||
function getSettings() {
|
||||
return injectedSettings != null ? injectedSettings : {
|
||||
get: () => {},
|
||||
set: () => {},
|
||||
save: () => {}
|
||||
};
|
||||
}
|
||||
function injectSettingsBackend(settings) {
|
||||
injectedSettings = settings;
|
||||
}
|
||||
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,39 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
const electron = require('electron');
|
||||
const {
|
||||
SPELLCHECK_REPLACE_MISSPELLING,
|
||||
SPELLCHECK_GET_AVAILABLE_DICTIONARIES,
|
||||
SPELLCHECK_SET_LOCALE,
|
||||
SPELLCHECK_SET_LEARNED_WORDS
|
||||
} = require('../common/constants').IPCEvents;
|
||||
let _learnedWords = new Set();
|
||||
let _hasLoadedLearnedWords = false;
|
||||
electron.ipcMain.handle(SPELLCHECK_REPLACE_MISSPELLING, async (event, correction) => {
|
||||
event.sender.replaceMisspelling(correction);
|
||||
});
|
||||
electron.ipcMain.handle(SPELLCHECK_GET_AVAILABLE_DICTIONARIES, async _ => {
|
||||
return electron.session.defaultSession.availableSpellCheckerLanguages;
|
||||
});
|
||||
electron.ipcMain.handle(SPELLCHECK_SET_LOCALE, async (_, locale) => {
|
||||
electron.session.defaultSession.setSpellCheckerLanguages([locale]);
|
||||
});
|
||||
electron.ipcMain.handle(SPELLCHECK_SET_LEARNED_WORDS, async (_, newLearnedWords) => {
|
||||
const session = electron.session.defaultSession;
|
||||
if (!_hasLoadedLearnedWords) {
|
||||
const dictionaryContents = await session.listWordsInSpellCheckerDictionary();
|
||||
_learnedWords = new Set(dictionaryContents);
|
||||
_hasLoadedLearnedWords = true;
|
||||
}
|
||||
_learnedWords.forEach(word => {
|
||||
if (!newLearnedWords.has(word)) {
|
||||
session.removeWordFromSpellCheckerDictionary(word);
|
||||
}
|
||||
});
|
||||
newLearnedWords.forEach(word => {
|
||||
if (!_learnedWords.has(word)) {
|
||||
session.addWordToSpellCheckerDictionary(word);
|
||||
}
|
||||
});
|
||||
_learnedWords = new Set(newLearnedWords);
|
||||
});
|
|
@ -1,54 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
var _electron = _interopRequireDefault(require("electron"));
|
||||
var _fs = _interopRequireDefault(require("fs"));
|
||||
var _path = _interopRequireDefault(require("path"));
|
||||
var _appFeatures = require("../../appFeatures");
|
||||
var _paths = require("../../bootstrapModules/paths");
|
||||
var _constants = require("../common/constants");
|
||||
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.paths.getUserData(), 'userDataCache.json');
|
||||
}
|
||||
function getMigratedPath() {
|
||||
return _path.default.join(_paths.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,97 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.injectGetWindow = injectGetWindow;
|
||||
const electron = require('electron');
|
||||
const process = require('process');
|
||||
const {
|
||||
WINDOW_BLUR,
|
||||
WINDOW_CLOSE,
|
||||
WINDOW_FOCUS,
|
||||
WINDOW_MAXIMIZE,
|
||||
WINDOW_MINIMIZE,
|
||||
WINDOW_RESTORE,
|
||||
WINDOW_FLASH_FRAME,
|
||||
WINDOW_TOGGLE_FULLSCREEN,
|
||||
WINDOW_SET_BACKGROUND_THROTTLING,
|
||||
WINDOW_SET_PROGRESS_BAR,
|
||||
WINDOW_IS_ALWAYS_ON_TOP,
|
||||
WINDOW_SET_ALWAYS_ON_TOP
|
||||
} = require('../common/constants').IPCEvents;
|
||||
let injectedGetWindow = _key => {
|
||||
return null;
|
||||
};
|
||||
function injectGetWindow(getWindow) {
|
||||
injectedGetWindow = getWindow;
|
||||
}
|
||||
electron.ipcMain.handle(WINDOW_FLASH_FRAME, async (_, flag) => {
|
||||
const currentWindow = injectedGetWindow();
|
||||
if (currentWindow == null || currentWindow.flashFrame == null) return;
|
||||
currentWindow.flashFrame(!currentWindow.isFocused() && flag);
|
||||
});
|
||||
electron.ipcMain.handle(WINDOW_MINIMIZE, async (_, key) => {
|
||||
const win = injectedGetWindow(key);
|
||||
if (win == null) return;
|
||||
win.minimize();
|
||||
});
|
||||
electron.ipcMain.handle(WINDOW_RESTORE, async (_, key) => {
|
||||
const win = injectedGetWindow(key);
|
||||
if (win == null) return;
|
||||
win.restore();
|
||||
});
|
||||
electron.ipcMain.handle(WINDOW_MAXIMIZE, async (_, key) => {
|
||||
const win = injectedGetWindow(key);
|
||||
if (win == null) return;
|
||||
if (win.isMaximized()) {
|
||||
win.unmaximize();
|
||||
} else {
|
||||
win.maximize();
|
||||
}
|
||||
});
|
||||
electron.ipcMain.handle(WINDOW_FOCUS, async (_, key) => {
|
||||
const win = injectedGetWindow(key);
|
||||
if (win == null) return;
|
||||
win.show();
|
||||
win.setSkipTaskbar(false);
|
||||
});
|
||||
electron.ipcMain.handle(WINDOW_SET_ALWAYS_ON_TOP, async (_, key, enabled) => {
|
||||
const win = injectedGetWindow(key);
|
||||
if (win == null) return;
|
||||
win.setAlwaysOnTop(enabled);
|
||||
});
|
||||
electron.ipcMain.handle(WINDOW_IS_ALWAYS_ON_TOP, async (_, key) => {
|
||||
const win = injectedGetWindow(key);
|
||||
if (win == null) return false;
|
||||
return win.isAlwaysOnTop();
|
||||
});
|
||||
electron.ipcMain.handle(WINDOW_BLUR, async (_, key) => {
|
||||
const win = injectedGetWindow(key);
|
||||
if (win != null && !win.isDestroyed()) {
|
||||
win.blur();
|
||||
}
|
||||
});
|
||||
electron.ipcMain.handle(WINDOW_SET_PROGRESS_BAR, async (_, key, progress) => {
|
||||
const win = injectedGetWindow(key);
|
||||
if (win == null) return;
|
||||
win.setProgressBar(progress);
|
||||
});
|
||||
electron.ipcMain.handle(WINDOW_TOGGLE_FULLSCREEN, async (_, key) => {
|
||||
const currentWindow = injectedGetWindow(key);
|
||||
currentWindow.setFullScreen(!currentWindow.isFullScreen());
|
||||
});
|
||||
electron.ipcMain.handle(WINDOW_CLOSE, async (_, key) => {
|
||||
if (key == null && process.platform === 'darwin') {
|
||||
electron.Menu.sendActionToFirstResponder('hide:');
|
||||
} else {
|
||||
const win = injectedGetWindow(key);
|
||||
if (win == null) return;
|
||||
win.close();
|
||||
}
|
||||
});
|
||||
electron.ipcMain.handle(WINDOW_SET_BACKGROUND_THROTTLING, async (_, enabled) => {
|
||||
const win = injectedGetWindow();
|
||||
if (win == null) return;
|
||||
win.webContents.setBackgroundThrottling(enabled);
|
||||
});
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue