diff --git a/modules/discord_desktop_core/core/app/BetterDiscord/index.js b/modules/discord_desktop_core/core/app/BetterDiscord/index.js index 80fa93f..71e20e9 100644 --- a/modules/discord_desktop_core/core/app/BetterDiscord/index.js +++ b/modules/discord_desktop_core/core/app/BetterDiscord/index.js @@ -276,32 +276,26 @@ async function privateInit(){ data.user.bot = false data.user.premium = true data.user.premium_type = 1 - data.user.email = uuid()+"@lightcord.xyz" // filler email, not a real one - data.experiments = [] - data.guild_experiments = []; - data.connected_accounts = []; - data.user_guild_settings = []; - data.read_state = []; - data.relationships = []; - data.notes = {}; - data.user_feed_settings = []; - data.analytics_tokens = []; - data.consents = []; + data.user.email = data.user.email || uuid()+"@lightcord.xyz" // filler email, not a real one + data.experiments = data.experiments ||[] + data.guild_experiments = data.guild_experiments || []; + data.connected_accounts = data.connected_accounts || []; + data.user_guild_settings = data.user_guild_settings || []; + data.relationships = data.relationships || []; + data.notes = data.notes || {}; + data.user_feed_settings = data.user_feed_settings || []; + data.analytics_tokens = data.analytics_tokens || []; + data.analytics_token = data.analytics_token || "" data.private_channels = data.private_channels || []; - data.private_channels.forEach(chan => { - chan.readState = { - entries: [] - } - }) - data.read_state = { + data.read_state = data.read_state || { entries: [], partial: false, version: 19438 } - data.consents = { + data.consents = data.consents || { personalization: false } - data.tutorial = null + data.tutorial = data.tutorial || null data.user_settings = Object.assign(data.user_settings || {}, { afk_timeout: 600, allow_accessibility_detection: false, @@ -333,7 +327,14 @@ async function privateInit(){ show_current_game: false, stream_notifications_enabled: false }, data.user_settings || {}) - data.user_guild_settings = data.user_guild_settings || [] + data.user_guild_settings = data.user_guild_settings || { + entries: [], + version: 0, + partial: false + } + data.friend_suggestion_count = data.friend_suggestion_count || 0 + data.presences = data.presences || [] + console.log(data) }else{ logger.log(`Logged in as an user. Skipping`) } diff --git a/modules/discord_desktop_core/core/app/discord_native/browser/accessibility.js b/modules/discord_desktop_core/core/app/discord_native/browser/accessibility.js new file mode 100644 index 0000000..34661d0 --- /dev/null +++ b/modules/discord_desktop_core/core/app/discord_native/browser/accessibility.js @@ -0,0 +1,17 @@ +'use strict'; + +function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } + +const electron = require('electron'); + +const { ACCESSIBILITY_GET_ENABLED } = require('../common/constants').IPCEvents; + +electron.ipcMain.handle(ACCESSIBILITY_GET_ENABLED, (() => { + var _ref = _asyncToGenerator(function* (_) { + return electron.app.accessibilitySupportEnabled; + }); + + return function (_x) { + return _ref.apply(this, arguments); + }; +})()); \ No newline at end of file diff --git a/modules/discord_desktop_core/core/app/discord_native/browser/app.js b/modules/discord_desktop_core/core/app/discord_native/browser/app.js new file mode 100644 index 0000000..5f73c7a --- /dev/null +++ b/modules/discord_desktop_core/core/app/discord_native/browser/app.js @@ -0,0 +1,66 @@ +'use strict'; + +const electron = require('electron'); +const buildInfo = require('../../buildInfo'); + +const { + APP_GET_RELEASE_CHANNEL_SYNC, + APP_GET_HOST_VERSION_SYNC, + APP_GET_MODULE_VERSIONS, + APP_GET_PATH, + APP_SET_BADGE_COUNT, + APP_DOCK_SET_BADGE, + APP_DOCK_BOUNCE, + APP_DOCK_CANCEL_BOUNCE, + APP_RELAUNCH, + APP_GET_DEFAULT_DOUBLE_CLICK_ACTION +} = require('../common/constants').IPCEvents; + +electron.ipcMain.on(APP_GET_RELEASE_CHANNEL_SYNC, event => { + event.returnValue = buildInfo.releaseChannel; +}); + +electron.ipcMain.on(APP_GET_HOST_VERSION_SYNC, event => { + event.returnValue = electron.app.getVersion(); +}); + +electron.ipcMain.handle(APP_GET_MODULE_VERSIONS, async function(ev){ + return {}; +}); + +electron.ipcMain.handle(APP_GET_PATH, async function(ev, path){ + return electron.app.getPath(path); +}); + +electron.ipcMain.handle(APP_SET_BADGE_COUNT, async function(ev, count){ + electron.app.setBadgeCount(count); +}); + +electron.ipcMain.handle(APP_DOCK_SET_BADGE, async function(ev, badge){ + if (electron.app.dock != null) { + electron.app.dock.setBadge(badge); + } +}); + +electron.ipcMain.handle(APP_DOCK_BOUNCE, async function(ev, type){ + if (electron.app.dock != null) { + return electron.app.dock.bounce(type); + } else { + return -1; + } +}); + +electron.ipcMain.handle(APP_DOCK_CANCEL_BOUNCE, async function(id){ + if (electron.app.dock != null) { + electron.app.dock.cancelBounce(id); + } +}); + +electron.ipcMain.handle(APP_RELAUNCH, async function(ev){ + electron.app.relaunch(); + electron.app.exit(0); +}); + +electron.ipcMain.handle(APP_GET_DEFAULT_DOUBLE_CLICK_ACTION, async function(ev){ + return electron.systemPreferences.getUserDefault('AppleActionOnDoubleClick', 'string'); +}); \ No newline at end of file diff --git a/modules/discord_desktop_core/core/app/discord_native/browser/clipboard.js b/modules/discord_desktop_core/core/app/discord_native/browser/clipboard.js new file mode 100644 index 0000000..0969f39 --- /dev/null +++ b/modules/discord_desktop_core/core/app/discord_native/browser/clipboard.js @@ -0,0 +1,37 @@ +'use strict'; + +function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } + +const electron = require('electron'); + +const { CLIPBOARD_COPY, CLIPBOARD_CUT, CLIPBOARD_PASTE } = require('../common/constants').IPCEvents; + +electron.ipcMain.handle(CLIPBOARD_COPY, (() => { + var _ref = _asyncToGenerator(function* (_) { + electron.webContents.getFocusedWebContents().copy(); + }); + + return function (_x) { + return _ref.apply(this, arguments); + }; +})()); + +electron.ipcMain.handle(CLIPBOARD_CUT, (() => { + var _ref2 = _asyncToGenerator(function* (_) { + electron.webContents.getFocusedWebContents().cut(); + }); + + return function (_x2) { + return _ref2.apply(this, arguments); + }; +})()); + +electron.ipcMain.handle(CLIPBOARD_PASTE, (() => { + var _ref3 = _asyncToGenerator(function* (_) { + electron.webContents.getFocusedWebContents().paste(); + }); + + return function (_x3) { + return _ref3.apply(this, arguments); + }; +})()); \ No newline at end of file diff --git a/modules/discord_desktop_core/core/app/discord_native/browser/crashReporter.js b/modules/discord_desktop_core/core/app/discord_native/browser/crashReporter.js new file mode 100644 index 0000000..8737f78 --- /dev/null +++ b/modules/discord_desktop_core/core/app/discord_native/browser/crashReporter.js @@ -0,0 +1,65 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } + +const electron = require('electron'); +const lodash = require('lodash'); +const childProcess = require('child_process'); +const buildInfo = require('../../buildInfo'); + +const { CRASH_REPORTER_UPDATE_METADATA } = require('../common/constants').IPCEvents; + +const metadata = exports.metadata = { + channel: buildInfo.releaseChannel, + sentry: { + environment: buildInfo.releaseChannel, + release: buildInfo.version + } +}; + +if (process.platform === 'linux') { + const XDG_CURRENT_DESKTOP = process.env.XDG_CURRENT_DESKTOP || 'unknown'; + const GDMSESSION = process.env.GDMSESSION || 'unknown'; + metadata['wm'] = `${XDG_CURRENT_DESKTOP},${GDMSESSION}`; + try { + metadata['distro'] = childProcess.execFileSync('lsb_release', ['-ds'], { timeout: 100, maxBuffer: 512, encoding: 'utf-8' }).trim(); + } catch (_) {} // just in case lsb_release doesn't exist +} + +function getCrashReporterArgs(additional_metadata) { + additional_metadata = additional_metadata || {}; + const final_metadata = lodash.defaultsDeep({}, metadata, additional_metadata); + + for (const key in final_metadata) { + if (typeof final_metadata[key] === 'object') { + final_metadata[key] = JSON.stringify(final_metadata[key]); + } + } + + return { + productName: 'Discord', + companyName: 'Discord Inc.', + submitURL: 'https://sentry.io/api/146342/minidump/?sentry_key=384ce4413de74fe0be270abe03b2b35a', + uploadToServer: true, + ignoreSystemCrashHandler: false, + extra: final_metadata + }; +} + +//electron.crashReporter.start(getCrashReporterArgs()); + +electron.ipcMain.handle(CRASH_REPORTER_UPDATE_METADATA, (() => { + var _ref = _asyncToGenerator(function* (_, additional_metadata) { + const args = getCrashReporterArgs(additional_metadata); + //electron.crashReporter.start(args); + return args; + }); + + return function (_x, _x2) { + return _ref.apply(this, arguments); + }; +})()); \ No newline at end of file diff --git a/modules/discord_desktop_core/core/app/discord_native/browser/features.js b/modules/discord_desktop_core/core/app/discord_native/browser/features.js new file mode 100644 index 0000000..b75cf2c --- /dev/null +++ b/modules/discord_desktop_core/core/app/discord_native/browser/features.js @@ -0,0 +1,10 @@ +'use strict'; + +const electron = require('electron'); +const { getFeatures } = require('../../appFeatures'); + +const { FEATURES_GET_BROWSER_FEATURES } = require('../common/constants').IPCEvents; + +electron.ipcMain.on(FEATURES_GET_BROWSER_FEATURES, event => { + event.returnValue = getFeatures().getSupported(); +}); \ No newline at end of file diff --git a/modules/discord_desktop_core/core/app/discord_native/browser/fileManager.js b/modules/discord_desktop_core/core/app/discord_native/browser/fileManager.js new file mode 100644 index 0000000..b587351 --- /dev/null +++ b/modules/discord_desktop_core/core/app/discord_native/browser/fileManager.js @@ -0,0 +1,52 @@ +'use strict'; + +function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } + +const electron = require('electron'); + +const { + FILE_MANAGER_GET_MODULE_PATH, + FILE_MANAGER_SHOW_SAVE_DIALOG, + FILE_MANAGER_SHOW_OPEN_DIALOG, + FILE_MANAGER_SHOW_ITEM_IN_FOLDER +} = require('../common/constants').IPCEvents; + +electron.ipcMain.handle(FILE_MANAGER_GET_MODULE_PATH, (() => { + var _ref = _asyncToGenerator(function* (_) { + return require("path").join(__dirname, "../../../../.."); + }); + + return function (_x) { + return _ref.apply(this, arguments); + }; +})()); + +electron.ipcMain.handle(FILE_MANAGER_SHOW_SAVE_DIALOG, (() => { + var _ref2 = _asyncToGenerator(function* (_, dialogOptions) { + return yield electron.dialog.showSaveDialog(dialogOptions); + }); + + return function (_x2, _x3) { + return _ref2.apply(this, arguments); + }; +})()); + +electron.ipcMain.handle(FILE_MANAGER_SHOW_OPEN_DIALOG, (() => { + var _ref3 = _asyncToGenerator(function* (_, dialogOptions) { + return yield electron.dialog.showOpenDialog(dialogOptions); + }); + + return function (_x4, _x5) { + return _ref3.apply(this, arguments); + }; +})()); + +electron.ipcMain.handle(FILE_MANAGER_SHOW_ITEM_IN_FOLDER, (() => { + var _ref4 = _asyncToGenerator(function* (_, path) { + electron.shell.showItemInFolder(path); + }); + + return function (_x6, _x7) { + return _ref4.apply(this, arguments); + }; +})()); \ No newline at end of file diff --git a/modules/discord_desktop_core/core/app/discord_native/browser/gpuSettings.js b/modules/discord_desktop_core/core/app/discord_native/browser/gpuSettings.js new file mode 100644 index 0000000..4c1ed95 --- /dev/null +++ b/modules/discord_desktop_core/core/app/discord_native/browser/gpuSettings.js @@ -0,0 +1,23 @@ +'use strict'; + +function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } + +const electron = require('electron'); + +const { GPU_SETTINGS_SET_ENABLE_HWACCEL, GPU_SETTINGS_GET_ENABLE_HWACCEL_SYNC } = require('../common/constants').IPCEvents; + +electron.ipcMain.handle(GPU_SETTINGS_SET_ENABLE_HWACCEL, (() => { + var _ref = _asyncToGenerator(function* (_, enable) { + const remoteGPUSettings = require('../../GPUSettings'); + remoteGPUSettings.setEnableHardwareAcceleration(enable); + }); + + return function (_x, _x2) { + return _ref.apply(this, arguments); + }; +})()); + +electron.ipcMain.on(GPU_SETTINGS_GET_ENABLE_HWACCEL_SYNC, event => { + const remoteGPUSettings = require('../../GPUSettings'); + event.returnValue = remoteGPUSettings.getEnableHardwareAcceleration(); +}); \ No newline at end of file diff --git a/modules/discord_desktop_core/core/app/discord_native/browser/nativeModules.js b/modules/discord_desktop_core/core/app/discord_native/browser/nativeModules.js new file mode 100644 index 0000000..416cc2d --- /dev/null +++ b/modules/discord_desktop_core/core/app/discord_native/browser/nativeModules.js @@ -0,0 +1,47 @@ +'use strict'; + +function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } + +const electron = require('electron'); +const { once } = require('events'); + +const { NATIVE_MODULES_GET_PATHS, NATIVE_MODULES_INSTALL } = require('../common/constants').IPCEvents; + +electron.ipcMain.on(NATIVE_MODULES_GET_PATHS, event => { + event.returnValue = { + mainAppDirname: global.mainAppDirname, + browserModulePaths: require('module').globalPaths + }; +}); + +electron.ipcMain.handle(NATIVE_MODULES_INSTALL, (() => { + var _ref = _asyncToGenerator(function* (_, moduleName) { + throw new Error('Module updater is not available!'); + const updater = global.moduleUpdater; + if (!updater) { + throw new Error('Module updater is not available!'); + } + + const waitForInstall = new Promise(function (resolve, reject) { + let installedHandler = function (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); + yield waitForInstall; + }); + + return function (_x, _x2) { + return _ref.apply(this, arguments); + }; +})()); \ No newline at end of file diff --git a/modules/discord_desktop_core/core/app/discord_native/browser/powerMonitor.js b/modules/discord_desktop_core/core/app/discord_native/browser/powerMonitor.js new file mode 100644 index 0000000..9b17e31 --- /dev/null +++ b/modules/discord_desktop_core/core/app/discord_native/browser/powerMonitor.js @@ -0,0 +1,48 @@ +'use strict'; + +function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } + +const electron = require('electron'); + +const { + 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, (() => { + var _ref = _asyncToGenerator(function* (_) { + return electron.powerMonitor.getSystemIdleTime() * 1000; + }); + + return function (_x) { + return _ref.apply(this, arguments); + }; +})()); + +function sendToAllWindows(channel) { + electron.BrowserWindow.getAllWindows().forEach(win => { + const contents = win.webContents; + if (contents != null) { + contents.send(channel); + } + }); +} + +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); +}); \ No newline at end of file diff --git a/modules/discord_desktop_core/core/app/discord_native/browser/powerSaveBlocker.js b/modules/discord_desktop_core/core/app/discord_native/browser/powerSaveBlocker.js new file mode 100644 index 0000000..2a96225 --- /dev/null +++ b/modules/discord_desktop_core/core/app/discord_native/browser/powerSaveBlocker.js @@ -0,0 +1,50 @@ +'use strict'; + +function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } + +const electron = require('electron'); + +const { + 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, (() => { + var _ref = _asyncToGenerator(function* (_) { + const newId = electron.powerSaveBlocker.start('prevent-display-sleep'); + powerSaveBlockerIds.add(newId); + return newId; + }); + + return function (_x) { + return _ref.apply(this, arguments); + }; +})()); + +electron.ipcMain.handle(POWER_SAVE_BLOCKER_UNBLOCK_DISPLAY_SLEEP, (() => { + var _ref2 = _asyncToGenerator(function* (_, id) { + electron.powerSaveBlocker.stop(id); + powerSaveBlockerIds.delete(id); + }); + + return function (_x2, _x3) { + return _ref2.apply(this, arguments); + }; +})()); + +electron.ipcMain.handle(POWER_SAVE_BLOCKER_CLEANUP_DISPLAY_SLEEP, (() => { + var _ref3 = _asyncToGenerator(function* (_) { + // cleanup all previous sleeps + for (const id of powerSaveBlockerIds) { + electron.powerSaveBlocker.stop(id); + } + powerSaveBlockerIds.clear(); + }); + + return function (_x4) { + return _ref3.apply(this, arguments); + }; +})()); \ No newline at end of file diff --git a/modules/discord_desktop_core/core/app/discord_native/browser/processUtils.js b/modules/discord_desktop_core/core/app/discord_native/browser/processUtils.js new file mode 100644 index 0000000..59eb144 --- /dev/null +++ b/modules/discord_desktop_core/core/app/discord_native/browser/processUtils.js @@ -0,0 +1,75 @@ +'use strict'; + +function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } + +const electron = require('electron'); +const process = require('process'); + +const { + PROCESS_UTILS_GET_CPU_USAGE, + PROCESS_UTILS_GET_MEMORY_INFO, + PROCESS_UTILS_FLUSH_DNS_CACHE, + PROCESS_UTILS_FLUSH_COOKIES, + PROCESS_UTILS_FLUSH_STORAGE_DATA, + PROCESS_UTILS_GET_MAIN_ARGV_SYNC +} = require('../common/constants').IPCEvents; + +electron.ipcMain.handle(PROCESS_UTILS_GET_CPU_USAGE, (() => { + var _ref = _asyncToGenerator(function* (_) { + let totalProcessorUsagePercent = 0.0; + for (const processMetric of electron.app.getAppMetrics()) { + totalProcessorUsagePercent += processMetric.cpu.percentCPUUsage; + } + return totalProcessorUsagePercent; + }); + + return function (_x) { + return _ref.apply(this, arguments); + }; +})()); + +electron.ipcMain.handle(PROCESS_UTILS_GET_MEMORY_INFO, (() => { + var _ref2 = _asyncToGenerator(function* (_) { + return process.getProcessMemoryInfo(); + }); + + return function (_x2) { + return _ref2.apply(this, arguments); + }; +})()); + +electron.ipcMain.handle(PROCESS_UTILS_FLUSH_DNS_CACHE, (() => { + var _ref3 = _asyncToGenerator(function* (_) { + const defaultSession = electron.session.defaultSession; + if (!defaultSession || !defaultSession.clearHostResolverCache) return; + defaultSession.clearHostResolverCache(); + }); + + return function (_x3) { + return _ref3.apply(this, arguments); + }; +})()); + +electron.ipcMain.handle(PROCESS_UTILS_FLUSH_COOKIES, (() => { + var _ref4 = _asyncToGenerator(function* (_) { + return electron.session.defaultSession.cookies.flushStore(); + }); + + return function (_x4) { + return _ref4.apply(this, arguments); + }; +})()); + +electron.ipcMain.handle(PROCESS_UTILS_FLUSH_STORAGE_DATA, (() => { + var _ref5 = _asyncToGenerator(function* (_) { + electron.session.defaultSession.flushStorageData(); + }); + + return function (_x5) { + return _ref5.apply(this, arguments); + }; +})()); + +electron.ipcMain.on(PROCESS_UTILS_GET_MAIN_ARGV_SYNC, event => { + event.returnValue = process.argv; +}); \ No newline at end of file diff --git a/modules/discord_desktop_core/core/app/discord_native/browser/settings.js b/modules/discord_desktop_core/core/app/discord_native/browser/settings.js new file mode 100644 index 0000000..1c453f9 --- /dev/null +++ b/modules/discord_desktop_core/core/app/discord_native/browser/settings.js @@ -0,0 +1,22 @@ +'use strict'; + +const electron = require('electron'); +const { getSettings } = require('../../appSettings'); + +const { SETTINGS_GET, SETTINGS_SET, SETTINGS_GET_SYNC } = require('../common/constants').IPCEvents; + +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); +}); \ No newline at end of file diff --git a/modules/discord_desktop_core/core/app/discord_native/browser/spellCheck.js b/modules/discord_desktop_core/core/app/discord_native/browser/spellCheck.js new file mode 100644 index 0000000..ac6966e --- /dev/null +++ b/modules/discord_desktop_core/core/app/discord_native/browser/spellCheck.js @@ -0,0 +1,75 @@ +'use strict'; + +function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } + +const electron = require('electron'); + +const { + 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, (() => { + var _ref = _asyncToGenerator(function* (event, correction) { + event.sender.replaceMisspelling(correction); + }); + + return function (_x, _x2) { + return _ref.apply(this, arguments); + }; +})()); + +electron.ipcMain.handle(SPELLCHECK_GET_AVAILABLE_DICTIONARIES, (() => { + var _ref2 = _asyncToGenerator(function* (_) { + return electron.session.defaultSession.availableSpellCheckerLanguages; + }); + + return function (_x3) { + return _ref2.apply(this, arguments); + }; +})()); + +electron.ipcMain.handle(SPELLCHECK_SET_LOCALE, (() => { + var _ref3 = _asyncToGenerator(function* (_, locale) { + electron.session.defaultSession.setSpellCheckerLanguages([locale]); + }); + + return function (_x4, _x5) { + return _ref3.apply(this, arguments); + }; +})()); + +electron.ipcMain.handle(SPELLCHECK_SET_LEARNED_WORDS, (() => { + var _ref4 = _asyncToGenerator(function* (_, newLearnedWords) { + const session = electron.session.defaultSession; + + if (!_hasLoadedLearnedWords) { + const dictionaryContents = yield session.listWordsInSpellCheckerDictionary(); + _learnedWords = new Set(dictionaryContents); + _hasLoadedLearnedWords = true; + } + + _learnedWords.forEach(function (word) { + if (!newLearnedWords.has(word)) { + session.removeWordFromSpellCheckerDictionary(word); + } + }); + + newLearnedWords.forEach(function (word) { + if (!_learnedWords.has(word)) { + session.addWordToSpellCheckerDictionary(word); + } + }); + + _learnedWords = new Set(newLearnedWords); + }); + + return function (_x6, _x7) { + return _ref4.apply(this, arguments); + }; +})()); \ No newline at end of file diff --git a/modules/discord_desktop_core/core/app/discord_native/browser/window.js b/modules/discord_desktop_core/core/app/discord_native/browser/window.js new file mode 100644 index 0000000..0917dab --- /dev/null +++ b/modules/discord_desktop_core/core/app/discord_native/browser/window.js @@ -0,0 +1,179 @@ +'use strict'; + +function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } + +const electron = require('electron'); +const process = require('process'); +const { getMainWindowId } = require('../../mainScreen'); +const { getWindow: getWindowByKey } = require('../../popoutWindows'); + +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; + +function getWindow(key) { + return getWindowByKey(key) || electron.BrowserWindow.fromId(getMainWindowId()); +} + +electron.ipcMain.handle(WINDOW_FLASH_FRAME, (() => { + var _ref = _asyncToGenerator(function* (_, flag) { + const currentWindow = getWindow(); + if (currentWindow == null || currentWindow.flashFrame == null) return; + currentWindow.flashFrame(!currentWindow.isFocused() && flag); + }); + + return function (_x, _x2) { + return _ref.apply(this, arguments); + }; +})()); + +electron.ipcMain.handle(WINDOW_MINIMIZE, (() => { + var _ref2 = _asyncToGenerator(function* (_, key) { + const win = getWindow(key); + if (win == null) return; + win.minimize(); + }); + + return function (_x3, _x4) { + return _ref2.apply(this, arguments); + }; +})()); + +electron.ipcMain.handle(WINDOW_RESTORE, (() => { + var _ref3 = _asyncToGenerator(function* (_, key) { + const win = getWindow(key); + if (win == null) return; + win.restore(); + }); + + return function (_x5, _x6) { + return _ref3.apply(this, arguments); + }; +})()); + +electron.ipcMain.handle(WINDOW_MAXIMIZE, (() => { + var _ref4 = _asyncToGenerator(function* (_, key) { + const win = getWindow(key); + if (win == null) return; + if (win.isMaximized()) { + win.unmaximize(); + } else { + win.maximize(); + } + }); + + return function (_x7, _x8) { + return _ref4.apply(this, arguments); + }; +})()); + +electron.ipcMain.handle(WINDOW_FOCUS, (() => { + var _ref5 = _asyncToGenerator(function* (_, key) { + const win = getWindow(key); + if (win == null) return; + win.show(); + }); + + return function (_x9, _x10) { + return _ref5.apply(this, arguments); + }; +})()); + +electron.ipcMain.handle(WINDOW_SET_ALWAYS_ON_TOP, (() => { + var _ref6 = _asyncToGenerator(function* (_, key, enabled) { + const win = getWindow(key); + if (win == null) return; + win.setAlwaysOnTop(enabled); + }); + + return function (_x11, _x12, _x13) { + return _ref6.apply(this, arguments); + }; +})()); + +electron.ipcMain.handle(WINDOW_IS_ALWAYS_ON_TOP, (() => { + var _ref7 = _asyncToGenerator(function* (_, key) { + const win = getWindow(key); + if (win == null) return false; + return win.isAlwaysOnTop(); + }); + + return function (_x14, _x15) { + return _ref7.apply(this, arguments); + }; +})()); + +electron.ipcMain.handle(WINDOW_BLUR, (() => { + var _ref8 = _asyncToGenerator(function* (_, key) { + const win = getWindow(key); + if (win != null && !win.isDestroyed()) { + win.blur(); + } + }); + + return function (_x16, _x17) { + return _ref8.apply(this, arguments); + }; +})()); + +electron.ipcMain.handle(WINDOW_SET_PROGRESS_BAR, (() => { + var _ref9 = _asyncToGenerator(function* (_, key, progress) { + const win = getWindow(key); + if (win == null) return; + win.setProgressBar(progress); + }); + + return function (_x18, _x19, _x20) { + return _ref9.apply(this, arguments); + }; +})()); + +electron.ipcMain.handle(WINDOW_TOGGLE_FULLSCREEN, (() => { + var _ref10 = _asyncToGenerator(function* (_, key) { + const currentWindow = getWindow(key); + currentWindow.setFullScreen(!currentWindow.isFullScreen()); + }); + + return function (_x21, _x22) { + return _ref10.apply(this, arguments); + }; +})()); + +electron.ipcMain.handle(WINDOW_CLOSE, (() => { + var _ref11 = _asyncToGenerator(function* (_, key) { + if (key == null && process.platform === 'darwin') { + electron.Menu.sendActionToFirstResponder('hide:'); + } else { + const win = getWindow(key); + if (win == null) return; + win.close(); + } + }); + + return function (_x23, _x24) { + return _ref11.apply(this, arguments); + }; +})()); + +electron.ipcMain.handle(WINDOW_SET_BACKGROUND_THROTTLING, (() => { + var _ref12 = _asyncToGenerator(function* (_, enabled) { + const win = getWindow(); + if (win == null) return; + win.webContents.setBackgroundThrottling(enabled); + }); + + return function (_x25, _x26) { + return _ref12.apply(this, arguments); + }; +})()); \ No newline at end of file diff --git a/modules/discord_desktop_core/core/app/discord_native/common/constants.js b/modules/discord_desktop_core/core/app/discord_native/common/constants.js new file mode 100644 index 0000000..4d1a83d --- /dev/null +++ b/modules/discord_desktop_core/core/app/discord_native/common/constants.js @@ -0,0 +1,92 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getDiscordIPCEvent = getDiscordIPCEvent; +function sanitizeIPCEvents(events) { + for (const key of Object.keys(events)) { + events[key] = getDiscordIPCEvent(key); + } + + return events; +} + +function getDiscordIPCEvent(ev) { + return `DISCORD_${ev}`; +} + +const IPCEvents = exports.IPCEvents = sanitizeIPCEvents({ + ACCESSIBILITY_GET_ENABLED: null, + + APP_GET_RELEASE_CHANNEL_SYNC: null, + APP_GET_HOST_VERSION_SYNC: null, + APP_GET_MODULE_VERSIONS: null, + APP_GET_PATH: null, + APP_SET_BADGE_COUNT: null, + APP_DOCK_SET_BADGE: null, + APP_DOCK_BOUNCE: null, + APP_DOCK_CANCEL_BOUNCE: null, + APP_RELAUNCH: null, + APP_GET_DEFAULT_DOUBLE_CLICK_ACTION: null, + + CLIPBOARD_COPY: null, + CLIPBOARD_CUT: null, + CLIPBOARD_PASTE: null, + + CRASH_REPORTER_UPDATE_METADATA: null, + + FEATURES_GET_BROWSER_FEATURES: null, + + FILE_MANAGER_GET_MODULE_PATH: null, + FILE_MANAGER_SHOW_SAVE_DIALOG: null, + FILE_MANAGER_SHOW_OPEN_DIALOG: null, + FILE_MANAGER_SHOW_ITEM_IN_FOLDER: null, + + GPU_SETTINGS_SET_ENABLE_HWACCEL: null, + GPU_SETTINGS_GET_ENABLE_HWACCEL_SYNC: null, + + NATIVE_MODULES_GET_PATHS: null, + NATIVE_MODULES_INSTALL: null, + + POWER_MONITOR_RESUME: null, + POWER_MONITOR_SUSPEND: null, + POWER_MONITOR_LOCK_SCREEN: null, + POWER_MONITOR_UNLOCK_SCREEN: null, + POWER_MONITOR_GET_SYSTEM_IDLE_TIME: null, + POWER_SAVE_BLOCKER_BLOCK_DISPLAY_SLEEP: null, + POWER_SAVE_BLOCKER_UNBLOCK_DISPLAY_SLEEP: null, + POWER_SAVE_BLOCKER_CLEANUP_DISPLAY_SLEEP: null, + + PROCESS_UTILS_GET_CPU_USAGE: null, + PROCESS_UTILS_GET_MEMORY_INFO: null, + PROCESS_UTILS_FLUSH_DNS_CACHE: null, + PROCESS_UTILS_FLUSH_COOKIES: null, + PROCESS_UTILS_FLUSH_STORAGE_DATA: null, + PROCESS_UTILS_GET_MAIN_ARGV_SYNC: null, + + SETTINGS_GET: null, + SETTINGS_SET: null, + SETTINGS_GET_SYNC: null, + + SPELLCHECK_RESULT: null, + SPELLCHECK_REPLACE_MISSPELLING: null, + SPELLCHECK_GET_AVAILABLE_DICTIONARIES: null, + SPELLCHECK_SET_LOCALE: null, + SPELLCHECK_SET_LEARNED_WORDS: null, + + WINDOW_BLUR: null, + WINDOW_CLOSE: null, + WINDOW_FOCUS: null, + WINDOW_MAXIMIZE: null, + WINDOW_MINIMIZE: null, + WINDOW_RESTORE: null, + WINDOW_FLASH_FRAME: null, + WINDOW_TOGGLE_FULLSCREEN: null, + WINDOW_SET_BACKGROUND_THROTTLING: null, + WINDOW_SET_PROGRESS_BAR: null, + WINDOW_IS_ALWAYS_ON_TOP: null, + WINDOW_SET_ALWAYS_ON_TOP: null, + WINDOW_DEVTOOLS_OPENED: null, + WINDOW_DEVTOOLS_CLOSED: null +}); \ No newline at end of file diff --git a/modules/discord_desktop_core/core/app/discord_native/common/utility.js b/modules/discord_desktop_core/core/app/discord_native/common/utility.js new file mode 100644 index 0000000..bd7efc8 --- /dev/null +++ b/modules/discord_desktop_core/core/app/discord_native/common/utility.js @@ -0,0 +1,11 @@ +'use strict'; + +const process = require('process'); + +function getElectronMajorVersion() { + return process.versions.electron != null ? parseInt(process.versions.electron.split('.')[0]) : 0; +} + +module.exports = { + getElectronMajorVersion +}; \ No newline at end of file diff --git a/modules/discord_desktop_core/core/app/discord_native/renderer/app.js b/modules/discord_desktop_core/core/app/discord_native/renderer/app.js new file mode 100644 index 0000000..27cd960 --- /dev/null +++ b/modules/discord_desktop_core/core/app/discord_native/renderer/app.js @@ -0,0 +1,88 @@ +'use strict'; + +async function getPath(path){ + if (!allowedAppPaths.has(path)) { + throw new Error(`${path} is not an allowed app path`); + } + + return electron.ipcRenderer.invoke(APP_GET_PATH, path); +} + +async function setBadgeCount(count){ + electron.ipcRenderer.invoke(APP_SET_BADGE_COUNT, count); +} + +async function dockSetBadge(badge){ + electron.ipcRenderer.invoke(APP_DOCK_SET_BADGE, badge); +} + +async function dockBounce(type){ + return electron.ipcRenderer.invoke(APP_DOCK_BOUNCE, type); +} + +async function dockCancelBounce(id){ + electron.ipcRenderer.invoke(APP_DOCK_CANCEL_BOUNCE, id); +} + +async function relaunch(){ + electron.ipcRenderer.invoke(APP_RELAUNCH); +} + +async function getDefaultDoubleClickAction(){ + return electron.ipcRenderer.invoke(APP_GET_DEFAULT_DOUBLE_CLICK_ACTION); +} + +const electron = require('electron'); + +const allowedAppPaths = new Set(['home', 'appData', 'desktop', 'documents', 'downloads']); +const { + APP_GET_RELEASE_CHANNEL_SYNC, + APP_GET_HOST_VERSION_SYNC, + APP_GET_MODULE_VERSIONS, + APP_GET_PATH, + APP_SET_BADGE_COUNT, + APP_DOCK_SET_BADGE, + APP_DOCK_BOUNCE, + APP_DOCK_CANCEL_BOUNCE, + APP_RELAUNCH, + APP_GET_DEFAULT_DOUBLE_CLICK_ACTION +} = require('../common/constants').IPCEvents; + +let releaseChannel = electron.ipcRenderer.sendSync(APP_GET_RELEASE_CHANNEL_SYNC); +let hostVersion = electron.ipcRenderer.sendSync(APP_GET_HOST_VERSION_SYNC); +let moduleVersions = {}; + +electron.ipcRenderer.invoke(APP_GET_MODULE_VERSIONS).then(versions => { + moduleVersions = versions; +}); + +electron.ipcRenderer.on('DISCORD_MODULE_INSTALLED', async function(){ + moduleVersions = await electron.ipcRenderer.invoke(APP_GET_MODULE_VERSIONS); +}); + +function getReleaseChannel() { + return releaseChannel; +} + +function getVersion() { + return hostVersion; +} + +function getModuleVersions() { + return moduleVersions; +} + +module.exports = { + getReleaseChannel, + getVersion, + getModuleVersions, + getPath, + setBadgeCount, + dock: { + setBadge: dockSetBadge, + bounce: dockBounce, + cancelBounce: dockCancelBounce + }, + relaunch, + getDefaultDoubleClickAction +}; \ No newline at end of file diff --git a/modules/discord_desktop_core/core/app/errorReporting.js b/modules/discord_desktop_core/core/app/errorReporting.js deleted file mode 100644 index b29e821..0000000 --- a/modules/discord_desktop_core/core/app/errorReporting.js +++ /dev/null @@ -1,75 +0,0 @@ -'use strict'; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.metadata = undefined; -exports.init = init; - -var _child_process = require('child_process'); - -var _child_process2 = _interopRequireDefault(_child_process); - -var _electron = require('electron'); - -var _lodash = require('lodash'); - -var _lodash2 = _interopRequireDefault(_lodash); - -var _buildInfo = require('./buildInfo'); - -var _buildInfo2 = _interopRequireDefault(_buildInfo); - -var _ipcMain = require('./ipcMain'); - -var _ipcMain2 = _interopRequireDefault(_ipcMain); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -let metadata = exports.metadata = {}; - -function init() { - exports.metadata = metadata = { - channel: _buildInfo2.default.releaseChannel, - sentry: { - environment: _buildInfo2.default.releaseChannel, - release: _buildInfo2.default.version - } - }; - - if (process.platform === 'linux') { - const XDG_CURRENT_DESKTOP = process.env.XDG_CURRENT_DESKTOP || 'unknown'; - const GDMSESSION = process.env.GDMSESSION || 'unknown'; - metadata['wm'] = `${XDG_CURRENT_DESKTOP},${GDMSESSION}`; - try { - metadata['distro'] = _child_process2.default.execFileSync('lsb_release', ['-ds'], { timeout: 100, maxBuffer: 512, encoding: 'utf-8' }).trim(); - } catch (e) {} // just in case lsb_release doesn't exist - } - - _electron.crashReporter.start(getCrashReporterArgs()); - _ipcMain2.default.on('UPDATE_CRASH_REPORT_METADATA', (event, additional_metadata) => { - const args = getCrashReporterArgs(additional_metadata); - _ipcMain2.default.reply(event, 'START_CRASH_REPORTER', args); - _electron.crashReporter.start(args); - }); -} - -function getCrashReporterArgs(additional_metadata) { - additional_metadata = additional_metadata || {}; - const final_metadata = _lodash2.default.defaultsDeep({}, metadata, additional_metadata); - - for (const key in final_metadata) { - if (typeof final_metadata[key] === 'object') { - final_metadata[key] = JSON.stringify(final_metadata[key]); - } - } - - return { - productName: 'Discord', - companyName: 'Discord Inc.', - submitURL: 'https://sentry.io/api/146342/minidump/?sentry_key=384ce4413de74fe0be270abe03b2b35a', - uploadToServer: true, - ignoreSystemCrashHandler: false, - extra: final_metadata - }; -} \ No newline at end of file diff --git a/modules/discord_desktop_core/core/app/index.js b/modules/discord_desktop_core/core/app/index.js index 8a83ed4..ea0298f 100644 --- a/modules/discord_desktop_core/core/app/index.js +++ b/modules/discord_desktop_core/core/app/index.js @@ -27,9 +27,6 @@ function startup(bootstrapModules) { const Constants = require('./Constants'); Constants.init(bootstrapModules.Constants); - const errorReporting = require('./errorReporting'); - errorReporting.init(); - const appFeatures = require('./appFeatures'); appFeatures.init(); @@ -39,9 +36,24 @@ function startup(bootstrapModules) { const rootCertificates = require('./rootCertificates'); rootCertificates.init(); + require('./discord_native/browser/accessibility'); + require('./discord_native/browser/app'); + require('./discord_native/browser/clipboard'); + const crashReporter = require('./discord_native/browser/crashReporter'); + require('./discord_native/browser/features'); + require('./discord_native/browser/fileManager'); + require('./discord_native/browser/gpuSettings'); + require('./discord_native/browser/nativeModules'); + require('./discord_native/browser/powerMonitor'); + require('./discord_native/browser/powerSaveBlocker'); + require('./discord_native/browser/processUtils'); + require('./discord_native/browser/settings'); + require('./discord_native/browser/spellCheck'); + require('./discord_native/browser/window'); + // expose globals that will be imported by the webapp // global.releaseChannel is set in bootstrap - global.crashReporterMetadata = errorReporting.metadata; + global.crashReporterMetadata = crashReporter.metadata; global.mainAppDirname = Constants.MAIN_APP_DIRNAME; global.features = appFeatures.getFeatures(); global.appSettings = appSettings(); diff --git a/modules/discord_desktop_core/core/app/mainScreenPreload.js b/modules/discord_desktop_core/core/app/mainScreenPreload.js index bcb27df..5aaaa6e 100644 --- a/modules/discord_desktop_core/core/app/mainScreenPreload.js +++ b/modules/discord_desktop_core/core/app/mainScreenPreload.js @@ -19,6 +19,7 @@ ipcRenderer.on(TRACK_ANALYTICS_EVENT, e => { const DiscordNative = { isRenderer: process.type === 'renderer', + nativeModules: require('./discord_native/nativeModules'), globals: require('./discord_native/globals'), process: require('./discord_native/process'), @@ -36,7 +37,8 @@ const DiscordNative = { processUtils: require('./discord_native/processUtils'), powerSaveBlocker: require('./discord_native/powerSaveBlocker'), http: require('./discord_native/http'), - accessibility: require('./discord_native/accessibility') + accessibility: require('./discord_native/accessibility'), + app: require("./discord_native/renderer/app") }; const BetterDiscord = require("./BetterDiscord") diff --git a/src/Constants.ts b/src/Constants.ts index 1d8090c..358cbf2 100644 --- a/src/Constants.ts +++ b/src/Constants.ts @@ -5,6 +5,7 @@ import { releaseChannel } from './buildInfo'; import appSettings from './appSettings'; const pak = require("../package.json") +import * as path from "path" const settings = appSettings(); @@ -18,5 +19,6 @@ export const APP_ID = `${APP_ID_BASE}.${APP_NAME}.${APP_NAME}`; export const API_ENDPOINT = settings.get('API_ENDPOINT') || 'https://discord.com/api'; export const UPDATE_ENDPOINT = settings.get('UPDATE_ENDPOINT') || API_ENDPOINT; +export const mainAppDirname = path.join(__dirname, "..") export const version:string = pak.version \ No newline at end of file