diff --git a/Gruntfile.js b/Gruntfile.js index 683ff77a4e4..23bf64ebf53 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -17,9 +17,9 @@ * */ -const electron_packager = require('electron-packager'); +const electronPackager = require('electron-packager'); const {createWindowsInstaller} = require('electron-winstaller'); -const electron_builder = require('electron-builder'); +const electronBuilder = require('electron-builder'); const ELECTRON_PACKAGE_JSON = 'electron/package.json'; const PACKAGE_JSON = 'package.json'; @@ -28,7 +28,7 @@ const INFO_JSON = 'info.json'; const LINUX_DESKTOP = { "Version": "1.1", "Name": "Wire", - "GenericName": "Secure messenger", + "GenericName": "The most secure collaboration platform", "Categories": "Network;InstantMessaging;Chat;VideoConference", "Keywords": "chat;encrypt;e2e;messenger;videocall", "StartupWMClass": "Wire" @@ -36,12 +36,11 @@ const LINUX_DESKTOP = { module.exports = function(grunt) { require('load-grunt-tasks')(grunt, {pattern: ['grunt-*']}); - const path = require('path'); grunt.initConfig({ pkg: grunt.file.readJSON(PACKAGE_JSON), info: grunt.file.readJSON(INFO_JSON), - build_number: `${process.env.BUILD_NUMBER || '0'}`, + buildNumber: `${process.env.BUILD_NUMBER || '0'}`, clean: { wrap: 'wrap', @@ -82,7 +81,7 @@ module.exports = function(grunt) { asar: true, appCopyright: '<%= info.copyright %>', appVersion: '<%= info.version %>', - buildVersion: '<%= build_number %>', + buildVersion: '<%= buildNumber %>', ignore: 'electron/renderer/src', protocols: [{name: '', schemes: ['wire']}], }, @@ -204,7 +203,7 @@ module.exports = function(grunt) { internal: { title: '<%= info.nameInternal %>', description: '<%= info.description %>', - version: '<%= info.version %>.<%= build_number %>', + version: '<%= info.version %>.<%= buildNumber %>', appDirectory: 'wrap/build/<%= info.nameInternal %>-win32-ia32', outputDirectory: 'wrap/internal/<%= info.nameInternal %>-win32-ia32', authors: '<%= info.nameInternal %>', @@ -218,7 +217,7 @@ module.exports = function(grunt) { prod: { title: '<%= info.name %>', description: '<%= info.description %>', - version: '<%= info.version %>.<%= build_number %>', + version: '<%= info.version %>.<%= buildNumber %>', appDirectory: 'wrap/build/<%= info.name %>-win32-ia32', outputDirectory: 'wrap/prod/<%= info.name %>-win32-ia32', authors: '<%= info.name %>', @@ -264,50 +263,48 @@ module.exports = function(grunt) { grunt.config.set('info', info); grunt.file.write(INFO_JSON, `${JSON.stringify(info, null, 2)}\n`); - const electron_pkg = grunt.file.readJSON(ELECTRON_PACKAGE_JSON); - electron_pkg.version = `${info.version}`; - grunt.file.write(ELECTRON_PACKAGE_JSON, `${JSON.stringify(electron_pkg, null, 2)}\n`); + const electronPkg = grunt.file.readJSON(ELECTRON_PACKAGE_JSON); + electronPkg.version = `${info.version}`; + grunt.file.write(ELECTRON_PACKAGE_JSON, `${JSON.stringify(electronPkg, null, 2)}\n`); grunt.log.write(`Version number increased to ${info.version} `).ok(); }); grunt.registerTask('release-internal', () => { const info = grunt.config.get('info'); - const build_number = grunt.config.get('build_number'); - const commit_id = grunt.config('gitinfo.local.branch.current.shortSHA'); - const electron_pkg = grunt.file.readJSON(ELECTRON_PACKAGE_JSON); - electron_pkg.updateWinUrl = info.updateWinUrlInternal; - electron_pkg.environment = 'internal'; - electron_pkg.name = info.nameInternal.toLowerCase(); - electron_pkg.productName = info.nameInternal; - electron_pkg.version = build_number === '0' - ? `${info.version}.0-${commit_id}-internal` - : `${info.version}.${build_number}-internal`; - grunt.file.write(ELECTRON_PACKAGE_JSON, `${JSON.stringify(electron_pkg, null, 2)}\n`); - grunt.log.write(`Releases URL points to ${electron_pkg.updateWinUrl} `).ok(); + const buildNumber = grunt.config.get('buildNumber'); + const commitId = grunt.config('gitinfo.local.branch.current.shortSHA'); + const electronPkg = grunt.file.readJSON(ELECTRON_PACKAGE_JSON); + electronPkg.updateWinUrl = info.updateWinUrlInternal; + electronPkg.environment = 'internal'; + electronPkg.name = info.nameInternal.toLowerCase(); + electronPkg.productName = info.nameInternal; + electronPkg.version = buildNumber === '0' + ? `${info.version}.0-${commitId}-internal` + : `${info.version}.${buildNumber}-internal`; + grunt.file.write(ELECTRON_PACKAGE_JSON, `${JSON.stringify(electronPkg, null, 2)}\n`); + grunt.log.write(`Releases URL points to ${electronPkg.updateWinUrl} `).ok(); }); grunt.registerTask('release-prod', () => { const info = grunt.config.get('info'); - const build_number = grunt.config.get('build_number'); - const commit_id = grunt.config('gitinfo.local.branch.current.shortSHA'); - const electron_pkg = grunt.file.readJSON(ELECTRON_PACKAGE_JSON); - electron_pkg.updateWinUrl = info.updateWinUrlProd; - electron_pkg.environment = 'production'; - electron_pkg.name = info.name.toLowerCase(); - electron_pkg.productName = info.name; - if (build_number === '0') { - electron_pkg.version = `${info.version}.0-${commit_id}`; - } else { - electron_pkg.version = `${info.version}.${build_number}`; - } - grunt.file.write(ELECTRON_PACKAGE_JSON, `${JSON.stringify(electron_pkg, null, 2)}\n`); - grunt.log.write(`Releases URL points to ${electron_pkg.updateWinUrl} `).ok(); + const buildNumber = grunt.config.get('buildNumber'); + const commitId = grunt.config('gitinfo.local.branch.current.shortSHA'); + const electronPkg = grunt.file.readJSON(ELECTRON_PACKAGE_JSON); + electronPkg.updateWinUrl = info.updateWinUrlProd; + electronPkg.environment = 'production'; + electronPkg.name = info.name.toLohostnameShouldBePinnedwerCase(); + electronPkg.productName = info.name; + electronPkg.version = buildNumber === '0' + ? `${info.version}.0-${commitId}` + : `${info.version}.${buildNumber}`; + grunt.file.write(ELECTRON_PACKAGE_JSON, `${JSON.stringify(electronPkg, null, 2)}\n`); + grunt.log.write(`Releases URL points to ${electronPkg.updateWinUrl} `).ok(); }); grunt.registerMultiTask('electron', 'Package Electron apps', function() { const done = this.async(); - electron_packager(this.options(), function(error) { + electronPackager(this.options(), error => { if (error) { return grunt.warn(error); } @@ -316,7 +313,6 @@ module.exports = function(grunt) { }); grunt.registerMultiTask('electronbuilder', 'Build Electron apps', function() { - const done = this.async(); const options = this.options(); const {targets} = options; delete options.targets; @@ -324,32 +320,32 @@ module.exports = function(grunt) { delete options.arch; if (arch === 'all') { - return electron_builder.build({ - targets: electron_builder.Platform.LINUX.createTarget( + return electronBuilder.build({ + targets: electronBuilder.Platform.LINUX.createTarget( targets, - electron_builder.Arch.ia32, - electron_builder.Arch.x64, + electronBuilder.Arch.ia32, + electronBuilder.Arch.x64, ), config: options, }); } - electron_builder.build({ - targets: electron_builder.Platform.LINUX.createTarget(targets, electron_builder.archFromString(arch)), + electronBuilder.build({ + targets: electronBuilder.Platform.LINUX.createTarget(targets, electronBuilder.archFromString(arch)), config: options, }); }); grunt.registerTask('update-keys', function() { const options = this.options(); - const config_string = grunt.file.read(options.config); + const configString = grunt.file.read(options.config); - if (config_string) { - const new_config_string = config_string + if (configString) { + const newConfigString = configString .replace(`RAYGUN_API_KEY: ''`, `RAYGUN_API_KEY: '${process.env.RAYGUN_API_KEY || ''}'`) .replace(`GOOGLE_CLIENT_ID: ''`, `GOOGLE_CLIENT_ID: '${process.env.GOOGLE_CLIENT_ID || ''}'`) .replace(`GOOGLE_CLIENT_SECRET: ''`, `GOOGLE_CLIENT_SECRET: '${process.env.GOOGLE_CLIENT_SECRET || ''}'`); - return grunt.file.write(options.config, new_config_string); + return grunt.file.write(options.config, newConfigString); } grunt.warn('Failed updating keys in config'); @@ -370,7 +366,7 @@ module.exports = function(grunt) { `${options.name} Helper EH.app/`, `${options.name} Helper NP.app/Contents/MacOS/${options.name} Helper NP`, `${options.name} Helper NP.app/`, - ].forEach((framework) => + ].forEach(framework => execSync(`codesign --deep -fs '${options.sign.app}' --entitlements '${options.child}' '${options.dir}/Contents/Frameworks/${framework}'`), ); diff --git a/electron/js/certutils.js b/electron/js/certutils.js index b2418bb1b86..3d801d00544 100644 --- a/electron/js/certutils.js +++ b/electron/js/certutils.js @@ -59,11 +59,9 @@ const pins = [ ]; module.exports = { - hostnameShouldBePinned (hostname) { - return pins.some(pin => pin.url.test(hostname.toLowerCase().trim())); - }, + hostnameShouldBePinned: hostname => pins.some(pin => pin.url.test(hostname.toLowerCase().trim())), - verifyPinning (hostname, certificate) { + verifyPinning: (hostname, certificate) => { const {data: certData = '', issuerCert: {data: issuerCertData = ''} = {}} = certificate; let issuerCertHex, publicKey, publicKeyBytes, publicKeyFingerprint; diff --git a/electron/js/config.js b/electron/js/config.js index bddbef37f4b..985e1ec66ef 100644 --- a/electron/js/config.js +++ b/electron/js/config.js @@ -17,7 +17,6 @@ * */ - const pkg = require('./../package.json'); const config = { diff --git a/electron/js/environment.js b/electron/js/environment.js index 27f8b7293bd..adc2ed05dba 100644 --- a/electron/js/environment.js +++ b/electron/js/environment.js @@ -17,7 +17,6 @@ * */ - const pkg = require('./../package.json'); const settings = require('./lib/settings'); @@ -53,45 +52,48 @@ const URL_WEBAPP = { STAGING: 'https://wire-webapp-staging.zinfra.io', }; -const _app = { +const app = { ENV: pkg.environment, IS_DEVELOPMENT: pkg.environment !== 'production', IS_PRODUCTION: pkg.environment === 'production', UPDATE_URL_WIN: pkg.updateWinUrl, }; -const _getEnvironment = () => { +const getEnvironment = () => { return currentEnvironment = currentEnvironment || settings.restore('env', TYPE.INTERNAL); }; -const _is_prod_environment = () => { +const isProdEnvironment = () => { return [ TYPE.INTERNAL, TYPE.PRODUCTION, - ].includes(_getEnvironment()); + ].includes(getEnvironment()); }; -const _platform = { +const platform = { IS_LINUX: process.platform === 'linux', IS_MAC_OS: process.platform === 'darwin', IS_WINDOWS: process.platform === 'win32', }; -const _setEnvironment = (env) => { +const setEnvironment = (env) => { currentEnvironment = env || settings.restore('env', TYPE.INTERNAL); settings.save('env', currentEnvironment); }; -const _web = { - get_url_admin: () => _is_prod_environment() ? URL_ADMIN.PRODUCTION : URL_ADMIN.STAGING, - get_url_support: () => URL_SUPPORT, - get_url_webapp: (env) => { +const web = { + getAdminUrl: path => { + const baseUrl = isProdEnvironment() ? URL_ADMIN.PRODUCTION : URL_ADMIN.STAGING; + return `${baseUrl}${path ? path : ''}`; + }, + getSupportUrl: path => `${URL_SUPPORT}${path ? path : ''}`, + getWebappUrl: (env) => { if (env) { return env; } - if (_app.IS_DEVELOPMENT) { - switch (_getEnvironment()) { + if (app.IS_DEVELOPMENT) { + switch (getEnvironment()) { case TYPE.DEV: return URL_WEBAPP.DEV; case TYPE.EDGE: @@ -109,14 +111,17 @@ const _web = { return URL_WEBAPP.PRODUCTION; }, - get_url_website: () => _is_prod_environment() ? URL_WEBSITE.PRODUCTION : URL_WEBSITE.STAGING, + getWebsiteUrl: path => { + const baseUrl = isProdEnvironment() ? URL_WEBSITE.PRODUCTION : URL_WEBSITE.STAGING; + return `${baseUrl}${path ? path : ''}`; + }, }; module.exports = { - TYPE: TYPE, - app: _app, - getEnvironment: _getEnvironment, - platform: _platform, - setEnvironment: _setEnvironment, - web: _web, + TYPE, + app, + getEnvironment, + platform, + setEnvironment, + web, }; diff --git a/electron/js/lib/download.js b/electron/js/lib/download.js index 67d3d1512f3..ca224c480e2 100644 --- a/electron/js/lib/download.js +++ b/electron/js/lib/download.js @@ -17,10 +17,8 @@ * */ - const fs = require('fs'); const imageType = require('image-type'); - const {dialog} = require('electron'); module.exports = (fileName, bytes) => { diff --git a/electron/js/lib/eventType.js b/electron/js/lib/eventType.js new file mode 100644 index 00000000000..4bc2139f32e --- /dev/null +++ b/electron/js/lib/eventType.js @@ -0,0 +1,74 @@ +/* + * Wire + * Copyright (C) 2018 Wire Swiss GmbH + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + * + */ + +module.exports = { + ABOUT: { + LOADED: 'EVENT_TYPE.ABOUT.LOADED', + LOCALE_RENDER: 'EVENT_TYPE.ABOUT.LOCALE_RENDER', + LOCALE_VALUES: 'EVENT_TYPE.ABOUT.LOCALE_VALUES', + SHOW: 'EVENT_TYPE.ABOUT.SHOW', + }, + ACCOUNT: { + DELETE_DATA: 'EVENT_TYPE.ACCOUNT.DELETE_DATA', + UPDATE_INFO: 'EVENT_TYPE.ACCOUNT.UPDATE_INFO', + }, + ACTION: { + NOTIFICATION_CLICK: 'EVENT_TYPE.ACTION.NOTIFICATION_CLICK', + SAVE_PICTURE: 'EVENT_TYPE.ACTION.SAVE_PICTURE', + SIGN_OUT: 'EVENT_TYPE.ACTION.SIGN_OUT', + }, + CONVERSATION: { + ADD_PEOPLE: 'EVENT_TYPE.CONVERSATION.ADD_PEOPLE', + ARCHIVE: 'EVENT_TYPE.CONVERSATION.ARCHIVE', + CALL: 'EVENT_TYPE.CONVERSATION.CALL', + DELETE: 'EVENT_TYPE.CONVERSATION.DELETE', + PEOPLE: 'EVENT_TYPE.CONVERSATION.PEOPLE', + PING: 'EVENT_TYPE.CONVERSATION.PING', + SHOW: 'EVENT_TYPE.CONVERSATION.SHOW', + SHOW_NEXT: 'EVENT_TYPE.CONVERSATION.SHOW_NEXT', + SHOW_PREVIOUS: 'EVENT_TYPE.CONVERSATION.SHOW_PREVIOUS', + START: 'EVENT_TYPE.CONVERSATION.START', + TOGGLE_MUTE: 'EVENT_TYPE.CONVERSATION.TOGGLE_MUTE', + VIDEO_CALL: 'EVENT_TYPE.CONVERSATION.VIDEO_CALL', + }, + GOOGLE_OAUTH: { + ERROR: 'EVENT_TYPE.GOOGLE_OAUTH.ERROR', + REQUEST: 'EVENT_TYPE.GOOGLE_OAUTH.REQUEST', + SUCCESS: 'EVENT_TYPE.GOOGLE_OAUTH.SUCCESS', + }, + LIFECYCLE: { + SIGN_OUT: 'EVENT_TYPE.LIFECYCLE.SIGN_OUT', + SIGNED_IN: 'EVENT_TYPE.LIFECYCLE.SIGNED_IN', + SIGNED_OUT: 'EVENT_TYPE.LIFECYCLE.SIGNED_OUT', + UNREAD_COUNT: 'EVENT_TYPE.LIFECYCLE.UNREAD_COUNT', + }, + PREFERENCES: { + SHOW: 'EVENT_TYPE.PREFERENCES.SHOW', + }, + UI: { + BADGE_COUNT: 'EVENT_TYPE.UI.BADGE_COUNT', + SYSTEM_MENU: 'EVENT_TYPE.UI.SYSTEM_MENU', + WEBAPP_VERSION: 'EVENT_TYPE.UI.WEBAPP_VERSION', + }, + WRAPPER: { + RELAUNCH: 'EVENT_TYPE.WRAPPER.RELAUNCH', + UPDATE: 'EVENT_TYPE.WRAPPER.UPDATE', + UPDATE_AVAILABLE: 'EVENT_TYPE.WRAPPER.UPDATE_AVAILABLE', + }, +}; diff --git a/electron/js/lib/googleAuth.js b/electron/js/lib/googleAuth.js index 0d0aa72e12a..9baad9db9ce 100644 --- a/electron/js/lib/googleAuth.js +++ b/electron/js/lib/googleAuth.js @@ -17,7 +17,6 @@ * */ - const {BrowserWindow} = require('electron'); const qs = require('querystring'); @@ -25,7 +24,7 @@ const google = require('googleapis'); const request = require('request'); const OAuth2 = google.auth.OAuth2; -const _authorizeApp = (url) => { +const authorizeApp = url => { return new Promise((resolve, reject) => { const win = new BrowserWindow({ 'title': '', @@ -41,12 +40,13 @@ const _authorizeApp = (url) => { setImmediate(() => { const title = win.getTitle(); + const [, , returnValue] = title.split(/[ =]/); if (title.startsWith('Denied')) { - reject(new Error(title.split(/[ =]/)[2])); + reject(new Error(returnValue)); win.removeAllListeners('closed'); win.close(); } else if (title.startsWith('Success')) { - resolve(title.split(/[ =]/)[2]); + resolve(returnValue); win.removeAllListeners('closed'); win.close(); } @@ -55,9 +55,9 @@ const _authorizeApp = (url) => { }); }; -const _getAccessToken = (scopes, clientId, clientSecret) => { +const getAccessToken = (scopes, clientId, clientSecret) => { return new Promise((resolve, reject) => { - _getAuthorizationCode(scopes, clientId, clientSecret) + getAuthorizationCode(scopes, clientId, clientSecret) .then((code) => { const data = qs.stringify({ client_id: clientId, @@ -78,7 +78,7 @@ const _getAccessToken = (scopes, clientId, clientSecret) => { }); }; -const _getAuthenticationUrl = (scopes, clientId, clientSecret) => { +const getAuthenticationUrl = (scopes, clientId, clientSecret) => { const oauth2Client = new OAuth2( clientId, clientSecret, @@ -87,12 +87,11 @@ const _getAuthenticationUrl = (scopes, clientId, clientSecret) => { return oauth2Client.generateAuthUrl({scope: scopes}); }; -const _getAuthorizationCode = (scopes, clientId, clientSecret) => { - const url = _getAuthenticationUrl(scopes, clientId, clientSecret); - return _authorizeApp(url); +const getAuthorizationCode = (scopes, clientId, clientSecret) => { + const url = getAuthenticationUrl(scopes, clientId, clientSecret); + return authorizeApp(url); }; - module.exports = { - getAccessToken: _getAccessToken, + getAccessToken, }; diff --git a/electron/js/lib/openGraph.js b/electron/js/lib/openGraph.js index ecfafece1c2..7d76bb28b48 100644 --- a/electron/js/lib/openGraph.js +++ b/electron/js/lib/openGraph.js @@ -18,21 +18,21 @@ */ -const og = require('open-graph'); +const openGraph = require('open-graph'); const request = require('request'); -const _arrayify = (obj = []) => Array.isArray(obj) ? obj : [obj]; +const arrayify = (value = []) => Array.isArray(value) ? value : [value]; -const _bufferToBase64 = (buffer, mimeType) => { +const bufferToBase64 = (buffer, mimeType) => { const bufferBase64encoded = Buffer.from(buffer).toString('base64'); return 'data:' + mimeType + ';base64,' + bufferBase64encoded; }; -const _fetchImageAsBase64 = (url) => { +const fetchImageAsBase64 = url => { return new Promise((resolve) => { request({encoding: null, url: encodeURI(url)}, (error, response, body) => { if (!error && response.statusCode === 200) { - resolve(_bufferToBase64(body, response.headers['content-type'])); + resolve(bufferToBase64(body, response.headers['content-type'])); } else { // we just skip images that failed to download resolve(); @@ -41,13 +41,13 @@ const _fetchImageAsBase64 = (url) => { }); }; -const _fetchOpenGraphData = (url) => { +const fetchOpenGraphData = url => { return new Promise((resolve, reject) => { - og(url, (error, meta) => error ? reject(error) : resolve(meta)); + openGraph(url, (error, meta) => error ? reject(error) : resolve(meta)); }); }; -const _updateMetaDataWithImage = (meta, image) => { +const updateMetaDataWithImage = (meta, image) => { if (image) { meta.image.data = image; } else { @@ -57,14 +57,14 @@ const _updateMetaDataWithImage = (meta, image) => { return meta; }; -const _getOpenGraphData = (url, callback) => { - return _fetchOpenGraphData(url) - .then((meta) => { +const getOpenGraphData = (url, callback) => { + return fetchOpenGraphData(url) + .then(meta => { if (meta.image && meta.image.url) { - const [imageUrl] = _arrayify(meta.image.url); + const [imageUrl] = arrayify(meta.image.url); - return _fetchImageAsBase64(imageUrl) - .then((uri) => _updateMetaDataWithImage(meta, uri)) + return fetchImageAsBase64(imageUrl) + .then(uri => updateMetaDataWithImage(meta, uri)) .catch(() => meta); } @@ -86,4 +86,4 @@ const _getOpenGraphData = (url, callback) => { }); }; -module.exports = _getOpenGraphData; +module.exports = getOpenGraphData; diff --git a/electron/js/lib/pointInRect.js b/electron/js/lib/pointInRect.js index 9881f8008b4..670ba4f7648 100644 --- a/electron/js/lib/pointInRect.js +++ b/electron/js/lib/pointInRect.js @@ -20,8 +20,8 @@ module.exports = (point, rectangle) => { const [x, y] = point; - const x_in_range = x >= rectangle.x && x <= rectangle.x + rectangle.width; - const y_in_range = y >= rectangle.y && y <= rectangle.y + rectangle.height; + const xInRange = x >= rectangle.x && x <= rectangle.x + rectangle.width; + const yInRange = y >= rectangle.y && y <= rectangle.y + rectangle.height; - return x_in_range && y_in_range; + return xInRange && yInRange; }; diff --git a/electron/js/lib/settings.js b/electron/js/lib/settings.js index 9a0b469a1e4..ece65e5b764 100644 --- a/electron/js/lib/settings.js +++ b/electron/js/lib/settings.js @@ -35,7 +35,7 @@ class ConfigurationPersistence { this.debug('Reading config file'); try { - global._ConfigurationPersistence = this._readFromFile(); + global._ConfigurationPersistence = this.readFromFile(); } catch (error) { this.debug('Unable to parse the init file. Details: %s', error); global._ConfigurationPersistence = {}; @@ -79,7 +79,7 @@ class ConfigurationPersistence { }); } - _readFromFile() { + readFromFile() { this.debug('Reading user configuration file...'); const dataInJSON = JSON.parse(fs.readFileSync(INIT_JSON, 'utf8')); this.debug('%o', dataInJSON); diff --git a/electron/js/menu/context.js b/electron/js/menu/context.js index bcf41005bd5..b8e8b7b8431 100644 --- a/electron/js/menu/context.js +++ b/electron/js/menu/context.js @@ -17,7 +17,6 @@ * */ - const {clipboard, remote, ipcRenderer, webFrame} = require('electron'); const Menu = remote.Menu; const webContents = remote.getCurrentWebContents(); @@ -25,12 +24,14 @@ const webContents = remote.getCurrentWebContents(); const config = require('./../config'); const locale = require('./../../locale/locale'); const settings = require('./../lib/settings'); +const EVENT_TYPE = require('./../lib/eventType'); let textMenu; /////////////////////////////////////////////////////////////////////////////// // Default /////////////////////////////////////////////////////////////////////////////// + let copyContext = ''; const defaultMenu = Menu.buildFromTemplate([ @@ -43,6 +44,7 @@ const defaultMenu = Menu.buildFromTemplate([ /////////////////////////////////////////////////////////////////////////////// // Text /////////////////////////////////////////////////////////////////////////////// + const selection = { isMisspelled: false, suggestions: [], @@ -97,6 +99,7 @@ const createTextMenu = () => { /////////////////////////////////////////////////////////////////////////////// // Images /////////////////////////////////////////////////////////////////////////////// + const imageMenu = Menu.buildFromTemplate([ { click: () => savePicture(imageMenu.file, imageMenu.image), @@ -141,31 +144,18 @@ window.addEventListener('contextmenu', (event) => { }, false); -window.addEventListener('click', (event) => { - const element = event.target; - - if (element.classList.contains('icon-more') && !element.classList.contains('context-menu') && element.parentElement.previousElementSibling) { - // get center-column - const id = element.parentElement.previousElementSibling.getAttribute('data-uie-uid'); - if (createConversationMenu(id)) { - event.stopPropagation(); - } - } -}, true); - - const savePicture = (fileName, url) => { fetch(url) .then((response) => response.arrayBuffer()) - .then((arrayBuffer) => ipcRenderer.send('save-picture', fileName, new Uint8Array(arrayBuffer))); + .then((arrayBuffer) => ipcRenderer.send(EVENT_TYPE.ACTION.SAVE_PICTURE, fileName, new Uint8Array(arrayBuffer))); }; - /////////////////////////////////////////////////////////////////////////////// // Spell Checker /////////////////////////////////////////////////////////////////////////////// -const is_spellcheck_supported = config.SPELLCHECK.SUPPORTED_LANGUAGES.includes(locale.getCurrent()); -if (is_spellcheck_supported) { + +const isSpellCheckSupported = config.SPELLCHECK.SUPPORTED_LANGUAGES.includes(locale.getCurrent()); +if (isSpellCheckSupported) { const spellchecker = require('spellchecker'); webFrame.setSpellCheckProvider(locale.getCurrent(), false, { diff --git a/electron/js/menu/developer.js b/electron/js/menu/developer.js index 1685c1de9cf..92572067a76 100644 --- a/electron/js/menu/developer.js +++ b/electron/js/menu/developer.js @@ -17,7 +17,6 @@ * */ - const {MenuItem} = require('electron'); const config = require('./../config'); const environment = require('./../environment'); diff --git a/electron/js/menu/system.js b/electron/js/menu/system.js index c96c17d2d23..04ba0c18d44 100644 --- a/electron/js/menu/system.js +++ b/electron/js/menu/system.js @@ -27,6 +27,7 @@ const environment = require('./../environment'); const locale = require('./../../locale/locale'); const windowManager = require('./../window-manager'); const settings = require('./../lib/settings'); +const EVENT_TYPE = require('./../lib/eventType'); let menu; @@ -36,23 +37,20 @@ const launcher = new autoLaunch({ path: launchCmd, }); - const getPrimaryWindow = () => windowManager.getPrimaryWindow(); // TODO: disable menus when not in focus const sendAction = (action) => { const primaryWindow = getPrimaryWindow(); if (primaryWindow) { - getPrimaryWindow().webContents.send('system-menu', action); + getPrimaryWindow().webContents.send(EVENT_TYPE.UI.SYSTEM_MENU, action); } }; - const separatorTemplate = { type: 'separator', }; - const createLanguageTemplate = (languageCode) => { return { click: () => changeLocale(languageCode), @@ -61,7 +59,7 @@ const createLanguageTemplate = (languageCode) => { }; }; -const createLanguageSubmenu = ()=> { +const createLanguageSubmenu = () => { return Object.keys(locale.SUPPORTED_LANGUAGES) .map((supportedLanguage) => createLanguageTemplate(supportedLanguage)); }; @@ -72,12 +70,12 @@ const localeTemplate = { }; const aboutTemplate = { - click: () => menu.emit('about-wire'), + click: () => menu.emit(EVENT_TYPE.ABOUT.SHOW), i18n: 'menuAbout', }; const signOutTemplate = { - click: () => sendAction('sign-out'), + click: () => sendAction(EVENT_TYPE.ACTION.SIGN_OUT), i18n: 'menuSignOut', }; @@ -86,45 +84,45 @@ const conversationTemplate = { submenu: [ { accelerator: 'CmdOrCtrl+N', - click: () => sendAction('conversation-start'), + click: () => sendAction(EVENT_TYPE.CONVERSATION.START), i18n: 'menuStart', }, separatorTemplate, { accelerator: 'CmdOrCtrl+K', - click: () => sendAction('conversation-ping'), + click: () => sendAction(EVENT_TYPE.CONVERSATION.PING), i18n: 'menuPing', }, { - click: () => sendAction('conversation-call'), + click: () => sendAction(EVENT_TYPE.CONVERSATION.CALL), i18n: 'menuCall', }, { - click: () => sendAction('conversation-video-call'), + click: () => sendAction(EVENT_TYPE.CONVERSATION.VIDEO_CALL), i18n: 'menuVideoCall', }, separatorTemplate, { accelerator: 'CmdOrCtrl+I', - click: () => sendAction('conversation-people'), + click: () => sendAction(EVENT_TYPE.CONVERSATION.PEOPLE), i18n: 'menuPeople', }, { accelerator: 'Shift+CmdOrCtrl+K', - click: () => sendAction('conversation-add-people'), + click: () => sendAction(EVENT_TYPE.CONVERSATION.ADD_PEOPLE), i18n: 'menuAddPeople', }, separatorTemplate, { accelerator: 'CmdOrCtrl+D', - click: () => sendAction('conversation-archive'), + click: () => sendAction(EVENT_TYPE.CONVERSATION.ARCHIVE), i18n: 'menuArchive', }, { accelerator: 'CmdOrCtrl+Alt+M', - click: () => sendAction('conversation-silence'), + click: () => sendAction(EVENT_TYPE.CONVERSATION.TOGGLE_MUTE), i18n: 'menuMute', }, { - click: () => sendAction('conversation-delete'), + click: () => sendAction(EVENT_TYPE.CONVERSATION.DELETE), i18n: 'menuDelete', }, ], @@ -174,7 +172,7 @@ const toggleAutoLaunchTemplate = { type: 'checkbox', }; -const supportsSpellcheck = config.SPELLCHECK.SUPPORTED_LANGUAGES.includes(locale.getCurrent()); +const supportsSpellCheck = config.SPELLCHECK.SUPPORTED_LANGUAGES.includes(locale.getCurrent()); const editTemplate = { i18n: 'menuEdit', @@ -207,9 +205,9 @@ const editTemplate = { }, separatorTemplate, { - checked: supportsSpellcheck && settings.restore('spelling', false), + checked: supportsSpellCheck && settings.restore('spelling', false), click: (event) => settings.save('spelling', event.checked), - enabled: supportsSpellcheck, + enabled: supportsSpellCheck, i18n: 'menuSpelling', type: 'checkbox', }, @@ -231,12 +229,12 @@ const windowTemplate = { separatorTemplate, { accelerator: environment.platform.IS_MAC_OS ? 'Alt+Cmd+Up' : 'Alt+Shift+Up', - click: () => sendAction('conversation-next'), + click: () => sendAction(EVENT_TYPE.CONVERSATION.SHOW_NEXT), i18n: 'menuNextConversation', }, { accelerator: environment.platform.IS_MAC_OS ? 'Alt+Cmd+Down' : 'Alt+Shift+Down', - click: () => sendAction('conversation-prev'), + click: () => sendAction(EVENT_TYPE.CONVERSATION.SHOW_PREVIOUS), i18n: 'menuPreviousConversation', }, ], @@ -247,23 +245,23 @@ const helpTemplate = { role: 'help', submenu: [ { - click: () => shell.openExternal(environment.web.get_url_website() + config.URL.LEGAL), + click: () => shell.openExternal(environment.web.getWebsiteUrl(config.URL.LEGAL)), i18n: 'menuLegal', }, { - click: () => shell.openExternal(environment.web.get_url_website() + config.URL.PRIVACY), + click: () => shell.openExternal(environment.web.getWebsiteUrl(config.URL.PRIVACY)), i18n: 'menuPrivacy', }, { - click: () => shell.openExternal(environment.web.get_url_website() + config.URL.LICENSES), + click: () => shell.openExternal(environment.web.getWebsiteUrl(config.URL.LICENSES)), i18n: 'menuLicense', }, { - click: () => shell.openExternal(environment.web.get_url_support()), + click: () => shell.openExternal(environment.web.getSupportUrl()), i18n: 'menuSupport', }, { - click: () => shell.openExternal(environment.web.get_url_website()), + click: () => shell.openExternal(environment.web.getWebsiteUrl()), i18n: 'menuWireURL', }, ], @@ -275,7 +273,7 @@ const darwinTemplate = { aboutTemplate, separatorTemplate, { accelerator: 'Command+,', - click: () => sendAction('preferences-show'), + click: () => sendAction(EVENT_TYPE.PREFERENCES.SHOW), i18n: 'menuPreferences', }, separatorTemplate, @@ -313,7 +311,7 @@ const win32Template = { submenu: [ { accelerator: 'Ctrl+,', - click: () => sendAction('preferences-show'), + click: () => sendAction(EVENT_TYPE.PREFERENCES.SHOW), i18n: 'menuSettings', }, localeTemplate, @@ -332,7 +330,7 @@ const linuxTemplate = { label: config.NAME, submenu: [ { - click: () => sendAction('preferences-show'), + click: () => sendAction(EVENT_TYPE.PREFERENCES.SHOW), i18n: 'menuPreferences', }, separatorTemplate, @@ -356,7 +354,6 @@ const menuTemplate = [ helpTemplate, ]; - const processMenu = (template, language) => { for (const item of template) { if (item.submenu) { @@ -395,7 +392,6 @@ const changeLocale = (language) => { }); }; - module.exports = { createMenu: () => { if (environment.platform.IS_MAC_OS) { @@ -421,7 +417,7 @@ module.exports = { if (environment.platform.IS_LINUX) { menuTemplate.unshift(linuxTemplate); editTemplate.submenu.push(separatorTemplate, { - click: () => sendAction('preferences-show'), + click: () => sendAction(EVENT_TYPE.PREFERENCES.SHOW), i18n: 'menuPreferences', }); windowTemplate.submenu.push( diff --git a/electron/js/menu/tray.js b/electron/js/menu/tray.js index 5bb301be79a..caa19a1b412 100644 --- a/electron/js/menu/tray.js +++ b/electron/js/menu/tray.js @@ -17,8 +17,6 @@ * */ - - const {app, Menu, Tray} = require('electron'); const path = require('path'); @@ -37,7 +35,7 @@ let lastUnreadCount = 0; let appIcon = null; -const _createTrayIcon = () => { +const createTrayIcon = () => { if (!environment.platform.IS_MAC_OS) { appIcon = new Tray(iconPath); const contextMenu = Menu.buildFromTemplate([ @@ -56,11 +54,11 @@ const _createTrayIcon = () => { } }; -const _updateBadgeIcon = (win, count) => { +const updateBadgeIcon = (win, count) => { if (count) { - _useBadgeIcon(); + useBadgeIcon(); } else { - _useDefaultIcon(); + useDefaultIcon(); } if (environment.platform.IS_WINDOWS) { @@ -72,19 +70,19 @@ const _updateBadgeIcon = (win, count) => { lastUnreadCount = count; }; -const _useDefaultIcon = () => { +const useDefaultIcon = () => { if (appIcon) { appIcon.setImage(iconPath); } }; -const _useBadgeIcon = () => { +const useBadgeIcon = () => { if (appIcon) { appIcon.setImage(iconBadgePath); } }; module.exports = { - createTrayIcon: _createTrayIcon, - updateBadgeIcon: _updateBadgeIcon, + createTrayIcon, + updateBadgeIcon, }; diff --git a/electron/js/preload-about.js b/electron/js/preload-about.js index 0d77e137510..0c07f4a6e69 100644 --- a/electron/js/preload-about.js +++ b/electron/js/preload-about.js @@ -18,21 +18,17 @@ */ const {ipcRenderer} = require('electron'); +const EVENT_TYPE = require('lib/eventType'); -ipcRenderer.once('about-locale-render', (sender, labels) => { +ipcRenderer.once(EVENT_TYPE.ABOUT.LOCALE_RENDER, (sender, labels) => { for (const label in labels) { document.querySelector(`[data-string="${label}"]`).innerHTML = labels[label]; } }); -ipcRenderer.once('about-loaded', (sender, details) => { +ipcRenderer.once(EVENT_TYPE.ABOUT.LOADED, (sender, details) => { document.getElementById('name').innerHTML = details.productName; - - if (details.electronVersion) { - document.getElementById('version').innerHTML = details.electronVersion; - } else { - document.getElementById('version').innerHTML = 'Development'; - } + document.getElementById('version').innerHTML = details.electronVersion || 'Development'; if (details.webappVersion) { document.getElementById('webappVersion').innerHTML = details.webappVersion; @@ -45,5 +41,5 @@ ipcRenderer.once('about-loaded', (sender, details) => { for (const label of document.querySelectorAll('[data-string]')) { labels.push(label.dataset.string); } - ipcRenderer.send('about-locale-values', labels); + ipcRenderer.send(EVENT_TYPE.ABOUT.LOCALE_VALUES, labels); }); diff --git a/electron/js/preload.js b/electron/js/preload.js index a3231c53d22..360a6a852f8 100644 --- a/electron/js/preload.js +++ b/electron/js/preload.js @@ -17,9 +17,10 @@ * */ -const { ipcRenderer, webFrame } = require('electron'); +const {ipcRenderer, webFrame} = require('electron'); const environment = require('./environment'); const locale = require('../locale/locale'); +const EVENT_TYPE = require('lib/eventType'); webFrame.setVisualZoomLevelLimits(1, 1); webFrame.setLayoutZoomLevelLimits(1, 1); @@ -33,7 +34,7 @@ const getSelectedWebview = () => document.querySelector('.Webview:not(.hide)'); const getWebviewById = id => document.querySelector(`.Webview[data-accountid="${id}"]`); const subscribeToMainProcessEvents = () => { - ipcRenderer.on('system-menu', (event, action) => { + ipcRenderer.on(EVENT_TYPE.UI.SYSTEM_MENU, (event, action) => { const selectedWebview = getSelectedWebview(); if (selectedWebview) { selectedWebview.send(action); @@ -43,19 +44,19 @@ const subscribeToMainProcessEvents = () => { const setupIpcInterface = () => { window.sendBadgeCount = count => { - ipcRenderer.send('badge-count', count); + ipcRenderer.send(EVENT_TYPE.UI.BADGE_COUNT, count); }; window.sendDeleteAccount = (accountID, sessionID) => { const accountWebview = getWebviewById(accountID); accountWebview.getWebContents().session.clearStorageData(); - ipcRenderer.send('delete-account-data', accountID, sessionID); + ipcRenderer.send(EVENT_TYPE.ACCOUNT.DELETE_DATA, accountID, sessionID); }; window.sendLogoutAccount = accountId => { const accountWebview = getWebviewById(accountId); if (accountWebview) { - accountWebview.send('sign-out'); + accountWebview.send(EVENT_TYPE.ACTION.SIGN_OUT); } }; }; diff --git a/electron/js/squirrel.js b/electron/js/squirrel.js index 54bab76aa28..50f813cbd40 100644 --- a/electron/js/squirrel.js +++ b/electron/js/squirrel.js @@ -17,7 +17,6 @@ * */ - // https://github.com/atom/atom/blob/master/src/main-process/squirrel-update.coffee const {app} = require('electron'); @@ -39,6 +38,16 @@ let linkName = config.NAME + '.lnk'; let taskbarLink = path.resolve(path.join(process.env.APPDATA, 'Microsoft', 'Internet Explorer', 'Quick Launch', 'User Pinned', 'TaskBar', linkName)); +const SQUIRREL_EVENT = { + CREATE_SHORTCUT: '--createShortcut', + INSTALL: '--squirrel-install', + OBSOLETE: '--squirrel-obsolete', + REMOVE_SHORTCUT: '--removeShortcut', + UNINSTALL: '--squirrel-uninstall', + UPDATE: '--update', + UPDATED: '--squirrel-updated', +}; + const spawn = (command, args, callback) => { let error; let spawnedProcess; @@ -49,22 +58,14 @@ const spawn = (command, args, callback) => { spawnedProcess = cp.spawn(command, args); } catch (_error) { error = _error; - process.nextTick(function() { - return typeof callback === 'function' ? callback(error, stdout) : void 0; - }); - return; - }; - - spawnedProcess.stdout.on('data', function(data) { - return stdout += data; - }); + return process.nextTick(() => typeof callback === 'function' ? callback(error, stdout) : void 0); + } - error = null; - spawnedProcess.on('error', function(processError) { - return error != null ? error : error = processError; - }); + spawnedProcess.stdout.on('data', data => stdout += data); - spawnedProcess.on('close', function(code, signal) { + error = null; + spawnedProcess.on('error', processError => error != null ? error : error = processError); + spawnedProcess.on('close', (code, signal) => { if (code !== 0) { if (error == null) { error = new Error('Command failed: ' + (signal != null ? signal : code)); @@ -84,61 +85,60 @@ const spawn = (command, args, callback) => { }); }; - const spawnUpdate = (args, callback) => { spawn(updateDotExe, args, callback); }; - -const createStartShortcut = (callback) => { - spawnUpdate(['--createShortcut', exeName, '-l=StartMenu'], callback); +const createStartShortcut = callback => { + spawnUpdate([SQUIRREL_EVENT.CREATE_SHORTCUT, exeName, '-l=StartMenu'], callback); }; - -const createDesktopShortcut = (callback) => { - spawnUpdate(['--createShortcut', exeName, '-l=Desktop'], callback); +const createDesktopShortcut = callback => { + spawnUpdate([SQUIRREL_EVENT.CREATE_SHORTCUT, exeName, '-l=Desktop'], callback); }; - -const removeShortcuts = (callback) => { - spawnUpdate(['--removeShortcut', exeName, '-l=Desktop,Startup,StartMenu'], () => fs.unlink(taskbarLink, callback)); +const removeShortcuts = callback => { + spawnUpdate([SQUIRREL_EVENT.REMOVE_SHORTCUT, exeName, '-l=Desktop,Startup,StartMenu'], () => fs.unlink(taskbarLink, callback)); }; - const installUpdate = () => { - spawnUpdate(['--update', environment.app.UPDATE_URL_WIN]); + spawnUpdate([SQUIRREL_EVENT.UPDATE, environment.app.UPDATE_URL_WIN]); }; - const scheduleUpdate = () => { setTimeout(installUpdate, config.UPDATE.DELAY); setInterval(installUpdate, config.UPDATE.INTERVAL); }; - -const handleSquirrelEvent = (shouldQuit) => { +const handleSquirrelEvent = shouldQuit => { const [, squirrelEvent] = process.argv; switch (squirrelEvent) { - case '--squirrel-install': + case SQUIRREL_EVENT.INSTALL: { createStartShortcut(() => { createDesktopShortcut(() => { app.quit(); }); }); return true; - case '--squirrel-updated': + } + + case SQUIRREL_EVENT.UPDATED: { app.exit(); return true; - case '--squirrel-uninstall': - removeShortcuts(() => { - app.quit(); - }); + } + + case SQUIRREL_EVENT.UNINSTALL: { + removeShortcuts(() => app.quit()); return true; - case '--squirrel-obsolete': + } + + case SQUIRREL_EVENT.OBSOLETE: { app.quit(); return true; + } } + if (shouldQuit) { // Using exit instead of quit for the time being // see: https://github.com/electron/electron/issues/8862#issuecomment-294303518 @@ -150,6 +150,6 @@ const handleSquirrelEvent = (shouldQuit) => { module.exports = { - handleSquirrelEvent: handleSquirrelEvent, - installUpdate: installUpdate, + handleSquirrelEvent, + installUpdate, }; diff --git a/electron/js/util.js b/electron/js/util.js index 7c63c48280e..bcdc3e1cf78 100644 --- a/electron/js/util.js +++ b/electron/js/util.js @@ -17,7 +17,6 @@ * */ - const electron = require('electron'); const url = require('url'); /*eslint-disable no-unused-vars*/ @@ -25,16 +24,12 @@ const debug = require('debug'); const utilDebug = debug('utilDebug'); /*eslint-enable no-unused-vars*/ -const config = require('./config'); -const environment = require('./environment'); const pointInRectangle = require('./lib/pointInRect'); module.exports = { - capitalize: (input) => { - return input.charAt(0).toUpperCase() + input.substr(1); - }, + capitalize: input => input.charAt(0).toUpperCase() + input.substr(1), - isInView: (win) => { + isInView: win => { const windowBounds = win.getBounds(); const nearestWorkArea = electron.screen.getDisplayMatching(windowBounds).workArea; @@ -44,64 +39,5 @@ module.exports = { return upperLeftVisible || lowerRightVisible; }, - isMatchingEmbed: (_url) => { - const hostname = url.parse(_url).hostname; - - for (const embedDomain of config.EMBED_DOMAINS) { - // If the hostname match - if (typeof embedDomain.hostname === 'object' && embedDomain.hostname.includes(hostname)) { - - utilDebug('Allowing %s', embedDomain.name); - return true; - } - } - - return false; - }, - - isMatchingEmbedOpenExternalWhitelist: (domain, _url) => { - const currentHostname = url.parse(domain).hostname; - const linkHostname = url.parse(_url).hostname; - - for (const embedDomain of config.EMBED_DOMAINS) { - // If the hostname match - if (typeof embedDomain.hostname === 'object' && embedDomain.hostname.includes(currentHostname)) { - - // And the link to open is allowed - return embedDomain.allowedExternalLinks.includes(linkHostname); - } - } - - return false; - }, - - isMatchingHost: (_url, _baseUrl) => { - return url.parse(_url).host === url.parse(_baseUrl).host; - }, - - resizeToBig: (win) => { - if (!environment.platform.IS_MAC_OS) { - win.setMenuBarVisibility(true); - } - - win.setMinimumSize(config.WINDOW.MAIN.MIN_WIDTH, config.WINDOW.MAIN.MIN_HEIGHT); - win.setSize(config.WINDOW.MAIN.DEFAULT_WIDTH, config.WINDOW.MAIN.DEFAULT_HEIGHT); - win.setResizable(true); - win.setMaximizable(true); - win.center(); - }, - - resizeToSmall: (win) => { - if (!environment.platform.IS_MAC_OS) { - win.setMenuBarVisibility(false); - } - - const height = config.WINDOW.AUTH.HEIGHT + (environment.platform.IS_WINDOWS ? 40 : 0); - win.setFullScreen(false); - win.setMaximizable(false); - win.setMinimumSize(config.WINDOW.AUTH.WIDTH, height); - win.setSize(config.WINDOW.AUTH.WIDTH, height); - win.setResizable(false); - win.center(); - }, + isMatchingHost: (_url, _baseUrl) => url.parse(_url).host === url.parse(_baseUrl).host, }; diff --git a/electron/js/window-manager.js b/electron/js/window-manager.js index 6a0e89fcc48..dda5a860198 100644 --- a/electron/js/window-manager.js +++ b/electron/js/window-manager.js @@ -17,18 +17,16 @@ * */ - const {BrowserWindow} = require('electron'); let primaryWindowId; +const getPrimaryWindow = () => primaryWindowId ? BrowserWindow.fromId(primaryWindowId) : BrowserWindow.getAllWindows()[0]; -const _getPrimaryWindow = () => primaryWindowId ? BrowserWindow.fromId(primaryWindowId) : BrowserWindow.getAllWindows()[0]; - -const _setPrimaryWindowId = (newPrimaryWindowId) => primaryWindowId = newPrimaryWindowId; +const setPrimaryWindowId = (newPrimaryWindowId) => primaryWindowId = newPrimaryWindowId; -const _showPrimaryWindow = () => { - const win = _getPrimaryWindow(); +const showPrimaryWindow = () => { + const win = getPrimaryWindow(); if (win.isMinimized()) { win.restore(); @@ -41,7 +39,7 @@ const _showPrimaryWindow = () => { module.exports = { - getPrimaryWindow: _getPrimaryWindow, - setPrimaryWindowId: _setPrimaryWindowId, - showPrimaryWindow: _showPrimaryWindow, + getPrimaryWindow, + setPrimaryWindowId, + showPrimaryWindow, }; diff --git a/electron/locale/locale.js b/electron/locale/locale.js index 95f8c9eaabc..3d253da7fd3 100644 --- a/electron/locale/locale.js +++ b/electron/locale/locale.js @@ -45,28 +45,28 @@ const tr = require('./strings-tr'); const uk = require('./strings-uk'); const SUPPORTED_LANGUAGES = { - 'en': 'English', - 'cs': 'Čeština', - 'da': 'Dansk', - 'de': 'Deutsch', - 'el': 'Ελληνικά', - 'et': 'Eesti', - 'es': 'Español', - 'fr': 'Français', - 'hr': 'Hrvatski', - 'it': 'Italiano', - 'lt': 'Lietuvos', - 'hu': 'Magyar', - 'nl': 'Nederlands', - 'pl': 'Polski', - 'pt': 'Português do Brasil', - 'ro': 'Română', - 'ru': 'Русский', - 'sk': 'Slovenčina', - 'sl': 'Slovenščina', - 'fi': 'Suomi', - 'tr': 'Türkçe', - 'uk': 'Українська', + en: 'English', + cs: 'Čeština', + da: 'Dansk', + de: 'Deutsch', + el: 'Ελληνικά', + et: 'Eesti', + es: 'Español', + fr: 'Français', + hr: 'Hrvatski', + it: 'Italiano', + lt: 'Lietuvos', + hu: 'Magyar', + nl: 'Nederlands', + pl: 'Polski', + pt: 'Português do Brasil', + ro: 'Română', + ru: 'Русский', + sk: 'Slovenčina', + sl: 'Slovenščina', + fi: 'Suomi', + tr: 'Türkçe', + uk: 'Українська', }; let current; @@ -81,7 +81,7 @@ const getCurrent = () => { return current; }; -const parseLocale = (locale) => { +const parseLocale = locale => { const languageKeys = getSupportedLanguageKeys(); return languageKeys.find((languageKey) => languageKey === locale) || languageKeys[0]; }; @@ -91,36 +91,36 @@ const getText = (string_identifier) => { return strings[string_identifier] || en[string_identifier] || ''; }; -const setLocale = (locale) => { +const setLocale = locale => { current = parseLocale(locale); settings.save('locale', current); }; module.exports = { - cs: cs, - da: da, - de: de, - el: el, - en: en, - es: es, - et: et, - fi: fi, - fr: fr, - hr: hr, - hu: hu, - it: it, - lt: lt, - nl: nl, - pl: pl, - pt: pt, - ro: ro, - ru: ru, - sk: sk, - sl: sl, - tr: tr, - uk: uk, - getCurrent: getCurrent, - getText: getText, - setLocale: setLocale, - SUPPORTED_LANGUAGES: SUPPORTED_LANGUAGES, + cs, + da, + de, + el, + en, + es, + et, + fi, + fr, + hr, + hu, + it, + lt, + nl, + pl, + pt, + ro, + ru, + sk, + sl, + tr, + uk, + getCurrent, + getText, + setLocale, + SUPPORTED_LANGUAGES, }; diff --git a/electron/main.js b/electron/main.js index 2a302662764..c0f60760cbd 100644 --- a/electron/main.js +++ b/electron/main.js @@ -56,10 +56,11 @@ const systemMenu = require('./js/menu/system'); const tray = require('./js/menu/tray'); const util = require('./js/util'); const windowManager = require('./js/window-manager'); +const EVENT_TYPE = require('./js/lib/eventType'); // Config const argv = minimist(process.argv.slice(1)); -const BASE_URL = environment.web.get_url_webapp(argv.env); +const BASE_URL = environment.web.getWebappUrl(argv.env); const pkg = require('./package.json'); // Icon @@ -121,7 +122,7 @@ if (environment.platform.IS_WINDOWS) { const squirrel = require('./js/squirrel'); squirrel.handleSquirrelEvent(shouldQuit); - ipcMain.on('wrapper-update', () => squirrel.installUpdate()); + ipcMain.on(EVENT_TYPE.WRAPPER.UPDATE, () => squirrel.installUpdate()); // Stop further execution on update to prevent second tray icon if (shouldQuit) { @@ -145,30 +146,30 @@ if (environment.platform.IS_LINUX) { /////////////////////////////////////////////////////////////////////////////// // IPC events /////////////////////////////////////////////////////////////////////////////// -ipcMain.once('webapp-version', (event, version) => { +ipcMain.once(EVENT_TYPE.UI.WEBAPP_VERSION, (event, version) => { webappVersion = version; }); -ipcMain.on('save-picture', (event, fileName, bytes) => { +ipcMain.on(EVENT_TYPE.ACTION.SAVE_PICTURE, (event, fileName, bytes) => { download(fileName, bytes); }); -ipcMain.on('notification-click', () => { +ipcMain.on(EVENT_TYPE.ACTION.NOTIFICATION_CLICK, () => { windowManager.showPrimaryWindow(); }); -ipcMain.on('badge-count', (event, count) => { +ipcMain.on(EVENT_TYPE.UI.BADGE_COUNT, (event, count) => { tray.updateBadgeIcon(main, count); }); -ipcMain.on('google-auth-request', event => { +ipcMain.on(EVENT_TYPE.GOOGLE_OAUTH.REQUEST, event => { googleAuth .getAccessToken(config.GOOGLE_SCOPES, config.GOOGLE_CLIENT_ID, config.GOOGLE_CLIENT_SECRET) .then(code => event.sender.send('google-auth-success', code.access_token)) .catch(error => event.sender.send('google-auth-error', error)); }); -ipcMain.on('delete-account-data', (e, accountID, sessionID) => { +ipcMain.on(EVENT_TYPE.ACCOUNT.DELETE_DATA, (event, accountID, sessionID) => { // delete webview partition try { if (sessionID) { @@ -191,7 +192,7 @@ ipcMain.on('delete-account-data', (e, accountID, sessionID) => { } }); -ipcMain.on('wrapper-relaunch', () => relaunchApp()); +ipcMain.on(EVENT_TYPE.WRAPPER.RELAUNCH, () => relaunchApp()); const relaunchApp = () => { app.relaunch(); @@ -372,7 +373,7 @@ const showAboutWindow = () => { }); // Locales - ipcMain.on('about-locale-values', (event, labels) => { + ipcMain.on(EVENT_TYPE.ABOUT.LOCALE_VALUES, (event, labels) => { if (event.sender.id !== about.webContents.id) { return; } @@ -380,7 +381,7 @@ const showAboutWindow = () => { for (const label of labels) { resultLabels[label] = locale.getText(label); } - event.sender.send('about-locale-render', resultLabels); + event.sender.send(EVENT_TYPE.ABOUT.LOCALE_RENDER, resultLabels); }); // Close window via escape @@ -397,7 +398,7 @@ const showAboutWindow = () => { about.loadURL(ABOUT_HTML); about.webContents.on('dom-ready', () => { - about.webContents.send('about-loaded', { + about.webContents.send(EVENT_TYPE.ABOUT.LOADED, { webappVersion: webappVersion, productName: pkg.productName, electronVersion: pkg.version, @@ -438,9 +439,7 @@ app.on('ready', () => { if (environment.app.IS_DEVELOPMENT) { appMenu.append(developerMenu); } - appMenu.on('about-wire', () => { - showAboutWindow(); - }); + appMenu.on(EVENT_TYPE.ABOUT.SHOW, () => showAboutWindow()); Menu.setApplicationMenu(appMenu); tray.createTrayIcon(); @@ -490,6 +489,7 @@ class ElectronWrapperInit { webviewProtectionDebug('Opening an external window from a webview. URL: %s', _url); shell.openExternal(_url); }; + const willNavigateInWebview = (event, _url) => { // Ensure navigation is to a whitelisted domain if (util.isMatchingHost(_url, BASE_URL)) { @@ -503,7 +503,7 @@ class ElectronWrapperInit { app.on('web-contents-created', (event, contents) => { switch (contents.getType()) { case 'window': - contents.on('will-attach-webview', (e, webPreferences, params) => { + contents.on('will-attach-webview', (event, webPreferences, params) => { const _url = params.src; // Use secure defaults @@ -516,7 +516,7 @@ class ElectronWrapperInit { // Verify the URL being loaded if (!util.isMatchingHost(_url, BASE_URL)) { - e.preventDefault(); + event.preventDefault(); webviewProtectionDebug('Prevented to show an unauthorized . URL: %s', _url); } }); @@ -524,12 +524,8 @@ class ElectronWrapperInit { case 'webview': // Open webview links outside of the app - contents.on('new-window', (e, _url) => { - openLinkInNewWindow(e, _url); - }); - contents.on('will-navigate', (e, _url) => { - willNavigateInWebview(e, _url); - }); + contents.on('new-window', openLinkInNewWindow); + contents.on('will-navigate', willNavigateInWebview); contents.session.setCertificateVerifyProc((request, cb) => { const {hostname = '', certificate = {}, error} = request; diff --git a/electron/renderer/src/actions/index.js b/electron/renderer/src/actions/index.js index 6ad42397f40..8633aa8136b 100644 --- a/electron/renderer/src/actions/index.js +++ b/electron/renderer/src/actions/index.js @@ -2,70 +2,59 @@ import uuid from 'uuid/v4'; import verifyObjectProperties from '../lib/verifyObjectProperties'; export const ADD_ACCOUNT = 'ADD_ACCOUNT'; +export const DELETE_ACCOUNT = 'DELETE_ACCOUNT'; export const SWITCH_ACCOUNT = 'SWITCH_ACCOUNT'; export const UPDATE_ACCOUNT = 'UPDATE_ACCOUNT'; export const UPDATE_ACCOUNT_BADGE = 'UPDATE_ACCOUNT_BADGE'; -export const DELETE_ACCOUNT = 'DELETE_ACCOUNT'; export const UPDATE_ACCOUNT_LIFECYCLE = 'UPDATE_ACCOUNT_LIFECYCLE'; -export const addAccount = (withSession = true) => { - const sessionID = withSession ? uuid() : undefined; - return { - sessionID: sessionID, - type: ADD_ACCOUNT, - }; -}; - -export const updateAccount = (id, data) => { - return { - data, - id, - type: UPDATE_ACCOUNT, - }; -}; - -export const updateAccountLifecycle = (id, data) => { - return { - data, - id, - type: UPDATE_ACCOUNT_LIFECYCLE, - }; -}; - -export const switchAccount = id => { - return { - id, - type: SWITCH_ACCOUNT, - }; -}; - -export const updateAccountBadge = (id, count) => { - return { - count, - id, - type: UPDATE_ACCOUNT_BADGE, - }; -}; - -export const deleteAccount = id => { - return { - id, - type: DELETE_ACCOUNT, - }; -}; - -export const setAccountContextHidden = () => { - return { - type: 'HIDE_CONTEXT_MENUS', - }; -}; - -export const toggleAddAccountMenuVisibility = (x, y) => { - return { - payload: { position: { x, y } }, - type: 'TOGGLE_ADD_ACCOUNT_VISIBILITY', - }; -}; +export const addAccount = (withSession = true) => ({ + sessionID: withSession ? uuid() : undefined, + type: ADD_ACCOUNT, +}); + +export const deleteAccount = id => ({ + id, + type: DELETE_ACCOUNT, +}); + +export const switchAccount = id => ({ + id, + type: SWITCH_ACCOUNT, +}); + +export const updateAccount = (id, data) => ({ + data, + id, + type: UPDATE_ACCOUNT, +}); + +export const updateAccountLifecycle = (id, data) => ({ + data, + id, + type: UPDATE_ACCOUNT_LIFECYCLE, +}); + +export const updateAccountBadge = (id, count) => ({ + count, + id, + type: UPDATE_ACCOUNT_BADGE, +}); + +export const HIDE_CONTEXT_MENUS = 'HIDE_CONTEXT_MENUS'; +export const TOGGLE_ADD_ACCOUNT_VISIBILITY = 'TOGGLE_ADD_ACCOUNT_VISIBILITY'; +export const TOGGLE_EDIT_ACCOUNT_VISIBILITY = 'TOGGLE_EDIT_ACCOUNT_VISIBILITY'; + +export const setAccountContextHidden = () => ({ + type: HIDE_CONTEXT_MENUS, +}); + +export const toggleAddAccountMenuVisibility = (x, y) => ({ + payload: { + position: {x, y}, + }, + type: TOGGLE_ADD_ACCOUNT_VISIBILITY, +}); export const toggleEditAccountMenuVisibility = ( x, @@ -74,18 +63,16 @@ export const toggleEditAccountMenuVisibility = ( sessionId, lifecycle, isAtLeastAdmin -) => { - return { - payload: { - accountId, - isAtLeastAdmin, - lifecycle, - position: { x, y }, - sessionId, - }, - type: 'TOGGLE_EDIT_ACCOUNT_VISIBILITY', - }; -}; +) => ({ + payload: { + accountId, + isAtLeastAdmin, + lifecycle, + position: {x, y}, + sessionId, + }, + type: TOGGLE_EDIT_ACCOUNT_VISIBILITY, +}); export const abortAccountCreation = id => { return (dispatch, getState) => { @@ -102,6 +89,18 @@ export const abortAccountCreation = id => { }; }; +export const addAccountWithSession = () => { + return (dispatch, getState) => { + const hasReachedAccountLimit = getState().accounts.length >= 3; + + if (hasReachedAccountLimit) { + console.warn('Reached number of maximum accounts'); + } else { + dispatch(addAccount()); + } + }; +}; + export const updateAccountData = (id, data) => { return (dispatch, getState) => { const validatedAccountData = verifyObjectProperties(data, { @@ -135,15 +134,3 @@ export const updateAccountBadgeCount = (id, count) => { } }; }; - -export const addAccountWithSession = () => { - return (dispatch, getState) => { - const hasReachedAccountLimit = getState().accounts.length >= 3; - - if (hasReachedAccountLimit) { - console.warn('Reached number of maximum accounts'); - } else { - dispatch(addAccount()); - } - }; -}; diff --git a/electron/renderer/src/components/App.js b/electron/renderer/src/components/App.js index 60a89406557..5e208e221fc 100644 --- a/electron/renderer/src/components/App.js +++ b/electron/renderer/src/components/App.js @@ -30,11 +30,11 @@ const App = props => (
{ - const modKeyPressed = (window.isMac && e.metaKey) || e.ctrlKey; - const isValidKey = ['1', '2', '3'].includes(e.key); - if (modKeyPressed && isValidKey && props.accountIds[e.key - 1]) { - props.switchAccount(props.accountIds[e.key - 1]); + onKeyDown={event => { + const modKeyPressed = (window.isMac && event.metaKey) || event.ctrlKey; + const isValidKey = ['1', '2', '3'].includes(event.key); + if (modKeyPressed && isValidKey && props.accountIds[event.key - 1]) { + props.switchAccount(props.accountIds[event.key - 1]); } }} > @@ -44,4 +44,4 @@ const App = props => ( ); -export default connect(({ accounts }) => ({ accountIds: accounts.map(account => account.id) }), { switchAccount })(App); +export default connect(({accounts}) => ({accountIds: accounts.map(account => account.id)}), {switchAccount})(App); diff --git a/electron/renderer/src/components/IsOnline.js b/electron/renderer/src/components/IsOnline.js index 09e9506d4c1..b6dd304b1d8 100644 --- a/electron/renderer/src/components/IsOnline.js +++ b/electron/renderer/src/components/IsOnline.js @@ -32,9 +32,9 @@ class IsOnline extends Component { componentDidMount() { if (this.state.isOnline === false) { - window.addEventListener('online', (event) => { - this.setState({ isOnline: true }); - }, { once: true }); + window.addEventListener('online', event => { + this.setState({isOnline: true}); + }, {once: true}); } } diff --git a/electron/renderer/src/components/PersonalIcon.js b/electron/renderer/src/components/PersonalIcon.js index 6c1170e0636..bb865227a9b 100644 --- a/electron/renderer/src/components/PersonalIcon.js +++ b/electron/renderer/src/components/PersonalIcon.js @@ -24,7 +24,7 @@ import { colorFromId } from '../lib/accentColor'; import './PersonalIcon.css'; -const PersonalIcon = ({ account, accentID, onClick }) => +const PersonalIcon = ({account, accentID, onClick}) =>
{account.visible &&
diff --git a/electron/renderer/src/components/Sidebar.css b/electron/renderer/src/components/Sidebar.css index fdb9d05ccc4..0248535c6bc 100644 --- a/electron/renderer/src/components/Sidebar.css +++ b/electron/renderer/src/components/Sidebar.css @@ -55,6 +55,10 @@ border-radius: 50%; } +.Sidebar-icon-cursor { + cursor: pointer; +} + .Sidebar-account-add { width: 28px; height: 28px; diff --git a/electron/renderer/src/components/Sidebar.js b/electron/renderer/src/components/Sidebar.js index 7385aad46f5..177593419dc 100644 --- a/electron/renderer/src/components/Sidebar.js +++ b/electron/renderer/src/components/Sidebar.js @@ -17,9 +17,9 @@ * */ -import { colorFromId } from '../lib/accentColor'; -import { connect } from 'react-redux'; -import { preventFocus } from '../lib/util'; +import {colorFromId} from '../lib/accentColor'; +import {connect} from 'react-redux'; +import {preventFocus} from '../lib/util'; import AddAccountMenuTrigger from './context/AddAccountMenuTrigger'; import AddAccountMenu from './context/AddAccountMenu'; import EditAccountMenu from './context/EditAccountMenu'; @@ -35,18 +35,17 @@ import { import './Sidebar.css'; -function className(account) { - return [ - 'Sidebar-icon', - account.badgeCount > 0 ? 'Sidebar-icon-badge' : '', - ].join(' '); -} - const centerOfEventTarget = event => { const cRect = event.target.getBoundingClientRect(); return [cRect.left + cRect.width / 2, cRect.top + cRect.height / 2]; }; +const getClassName = account => { + const showIconBadge = account.badgeCount > 0 ? ' Sidebar-icon-badge' : ''; + const showIconCursor = account.visible ? '' : ' Sidebar-icon-cursor'; + return `Sidebar-icon${showIconBadge}${showIconCursor}`; +}; + const Sidebar = ({ accounts, currentAccentID, @@ -59,15 +58,15 @@ const Sidebar = ({ }) => (
{accounts.map(account => (
connected.switchAccount(account.id)} onContextMenu={preventFocus(event => { const isAtLeastAdmin = [ @@ -110,7 +109,7 @@ const Sidebar = ({ ); export default connect( - ({ accounts, contextMenuState }) => ({ + ({accounts, contextMenuState}) => ({ accounts, currentAccentID: (accounts.find(account => account.visible) || {}).accentID, hasCreatedAccount: accounts.some(account => account.userID !== undefined), diff --git a/electron/renderer/src/components/TeamIcon.js b/electron/renderer/src/components/TeamIcon.js index d8a8b8630bb..3e4d8eff625 100644 --- a/electron/renderer/src/components/TeamIcon.js +++ b/electron/renderer/src/components/TeamIcon.js @@ -24,7 +24,7 @@ import { colorFromId } from '../lib/accentColor'; import './TeamIcon.css'; -const TeamIcon = ({ account, accentID }) => +const TeamIcon = ({account, accentID}) =>
{account.visible && @@ -34,7 +34,7 @@ const TeamIcon = ({ account, accentID }) => - { [...account.name][0] } + {[...account.name][0]}
; TeamIcon.propTypes = { diff --git a/electron/renderer/src/components/Webview.js b/electron/renderer/src/components/Webview.js index ba4e742d98b..803a9a7f03e 100644 --- a/electron/renderer/src/components/Webview.js +++ b/electron/renderer/src/components/Webview.js @@ -58,15 +58,14 @@ class Webview extends Component { } _focusWebview() { - const is_visible = this.props.visible === true; - if (is_visible) { + if (this.props.visible) { this.webview.focus(); } } render() { const {visible, partition, src, onPageTitleUpdated, onIpcMessage, ...validProps} = this.props; // eslint-disable-line no-unused-vars - return this.webview = webview } />; + return this.webview = webview} />; } } diff --git a/electron/renderer/src/components/Webviews.css b/electron/renderer/src/components/Webviews.css index ba44b05628e..dbe76a26550 100644 --- a/electron/renderer/src/components/Webviews.css +++ b/electron/renderer/src/components/Webviews.css @@ -26,6 +26,7 @@ } .Webviews-close { + cursor: pointer; position: absolute; top: 24px; right: 24px; diff --git a/electron/renderer/src/components/Webviews.js b/electron/renderer/src/components/Webviews.js index d0b7c65d969..da1128958e1 100644 --- a/electron/renderer/src/components/Webviews.js +++ b/electron/renderer/src/components/Webviews.js @@ -17,11 +17,10 @@ * */ -import React, { Component } from 'react'; - +import React, {Component} from 'react'; import Webview from './Webview'; - import './Webviews.css'; +import * as EVENT_TYPE from '../lib/eventType'; class Webviews extends Component { constructor(props) { @@ -67,9 +66,6 @@ class Webviews extends Component { // pass account id to webview so we can access it in the preload script url.searchParams.set('id', account.id); - // when landing on auth page for login mode - url.hash = 'login'; - return url.href; } @@ -85,36 +81,38 @@ class Webviews extends Component { window.sendBadgeCount(accumulatedCount); } - _onIpcMessage(account, { channel, args }) { + _onIpcMessage(account, {channel, args}) { switch (channel) { - case 'notification-click': { - this.props.switchAccount(account.id); + case EVENT_TYPE.ACCOUNT.UPDATE_INFO: { + const [accountData] = args; + this.props.updateAccountData(account.id, accountData); break; } - case 'lifecycle-signed-in': - case 'lifecycle-signed-out': { - this.props.updateAccountLifecycle(account.id, channel); + case EVENT_TYPE.ACTION.NOTIFICATION_CLICK: { + this.props.switchAccount(account.id); break; } - case 'lifecycle-unread-count': { - this._onUnreadCountUpdated(account.id, args[0]); + case EVENT_TYPE.LIFECYCLE.SIGNED_IN: + case EVENT_TYPE.LIFECYCLE.SIGN_OUT: { + this.props.updateAccountLifecycle(account.id, channel); break; } - case 'signed-out': { + case EVENT_TYPE.LIFECYCLE.SIGNED_OUT: { this._deleteWebview(account); break; } - case 'team-info': { - this.props.updateAccountData(account.id, args[0]); + case EVENT_TYPE.LIFECYCLE.UNREAD_COUNT: { + const [badgeCount] = args; + this._onUnreadCountUpdated(account.id, badgeCount); break; } } - this.setState({ canDelete: { ...this.state.canDelete, [account.id]: this._canDeleteWebview(account) } }); + this.setState({canDelete: {...this.state.canDelete, [account.id]: this._canDeleteWebview(account)}}); } _onWebviewClose(account) { diff --git a/electron/renderer/src/components/context/AddAccountMenu.js b/electron/renderer/src/components/context/AddAccountMenu.js index 54f37982acb..a13223b9124 100644 --- a/electron/renderer/src/components/context/AddAccountMenu.js +++ b/electron/renderer/src/components/context/AddAccountMenu.js @@ -24,7 +24,7 @@ import ContextMenu from './ContextMenu'; import ContextMenuItem from './ContextMenuItem'; import { addAccountWithSession } from '../../actions/'; -function AddAccountMenu({ ...connected }) { +function AddAccountMenu({...connected}) { return ( window.open('https://wire.com/create-team/?pk_campaign=client&pk_kwd=desktop')}> @@ -35,4 +35,4 @@ function AddAccountMenu({ ...connected }) { ); } -export default connect(null, { addAccountWithSession })(AddAccountMenu); +export default connect(null, {addAccountWithSession})(AddAccountMenu); diff --git a/electron/renderer/src/components/context/AddAccountMenuTrigger.js b/electron/renderer/src/components/context/AddAccountMenuTrigger.js index 6273d745657..b6b55635124 100644 --- a/electron/renderer/src/components/context/AddAccountMenuTrigger.js +++ b/electron/renderer/src/components/context/AddAccountMenuTrigger.js @@ -19,7 +19,7 @@ import React from 'react'; -const AddAccountMenuTrigger = ({ onClick, forceVisible }) => ( +const AddAccountMenuTrigger = ({onClick, forceVisible}) => (
({ position: state.contextMenuState.position, }), - { setAccountContextHidden } + {setAccountContextHidden} )(ContextMenu); diff --git a/electron/renderer/src/components/context/EditAccountMenu.js b/electron/renderer/src/components/context/EditAccountMenu.js index c5621670ddf..f6cb56f6b19 100644 --- a/electron/renderer/src/components/context/EditAccountMenu.js +++ b/electron/renderer/src/components/context/EditAccountMenu.js @@ -18,11 +18,12 @@ */ import React from 'react'; -import { connect } from 'react-redux'; -import { getText } from '../../lib/locale'; +import {connect} from 'react-redux'; +import {getText} from '../../lib/locale'; import ContextMenu from './ContextMenu'; import ContextMenuItem from './ContextMenuItem'; -import { abortAccountCreation, switchAccount } from '../../actions/'; +import {abortAccountCreation, switchAccount} from '../../actions/'; +import * as EVENT_TYPE from '../../lib/eventType'; function EditAccountMenu({ accountId, @@ -40,7 +41,7 @@ function EditAccountMenu({ {getText('wrapperManageTeam')} )} - {lifecycle === 'lifecycle-signed-in' && ( + {lifecycle === EVENT_TYPE.LIFECYCLE.SIGNED_IN && ( { connected.switchAccount(accountId); @@ -63,7 +64,7 @@ function EditAccountMenu({ } export default connect( - ({ contextMenuState }) => ({ + ({contextMenuState}) => ({ accountId: contextMenuState.accountId, isAtLeastAdmin: contextMenuState.isAtLeastAdmin, lifecycle: contextMenuState.lifecycle, diff --git a/electron/renderer/src/containers/WebviewsContainer.js b/electron/renderer/src/containers/WebviewsContainer.js index ee1341d3002..7933d4f83fb 100644 --- a/electron/renderer/src/containers/WebviewsContainer.js +++ b/electron/renderer/src/containers/WebviewsContainer.js @@ -28,7 +28,7 @@ import { } from '../actions'; import Webviews from '../components/Webviews'; -const WebviewsContainer = connect(state => ({ accounts: state.accounts }), { +const WebviewsContainer = connect(state => ({accounts: state.accounts}), { abortAccountCreation, switchAccount, updateAccountBadgeCount, diff --git a/electron/renderer/src/index.js b/electron/renderer/src/index.js index 5f64f2cd70f..c58af035c5f 100644 --- a/electron/renderer/src/index.js +++ b/electron/renderer/src/index.js @@ -18,16 +18,16 @@ */ import React from 'react'; -import { render } from 'react-dom'; -import { applyMiddleware, createStore } from 'redux'; -import { Provider } from 'react-redux'; +import {render} from 'react-dom'; +import {applyMiddleware, createStore} from 'redux'; +import {Provider} from 'react-redux'; import thunk from 'redux-thunk'; import logger from 'redux-logger'; import throttle from 'lodash/throttle'; import App from './components/App'; import appStore from './reducers'; -import { loadState, saveState } from './lib/localStorage'; +import {loadState, saveState} from './lib/localStorage'; import './Index.css'; diff --git a/electron/renderer/src/lib/accentColor.js b/electron/renderer/src/lib/accentColor.js index c09fe50c326..bfa0866de9b 100644 --- a/electron/renderer/src/lib/accentColor.js +++ b/electron/renderer/src/lib/accentColor.js @@ -62,7 +62,7 @@ export const ACCENT_COLORS = [ VIOLET, ]; -export function colorFromId(id) { +export const colorFromId = id => { const accentColor = ACCENT_COLORS.find((color) => color.id === id); return accentColor && accentColor.color; -} \ No newline at end of file +}; diff --git a/electron/renderer/src/lib/eventType.js b/electron/renderer/src/lib/eventType.js new file mode 100644 index 00000000000..2a8eb57da06 --- /dev/null +++ b/electron/renderer/src/lib/eventType.js @@ -0,0 +1,33 @@ +/* + * Wire + * Copyright (C) 2018 Wire Swiss GmbH + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + * + */ + +export const ACCOUNT = { + UPDATE_INFO: 'EVENT_TYPE.ACCOUNT.UPDATE_INFO', +}; + +export const ACTION = { + NOTIFICATION_CLICK: 'EVENT_TYPE.ACTION.NOTIFICATION_CLICK', +}; + +export const LIFECYCLE = { + SIGN_OUT: 'EVENT_TYPE.LIFECYCLE.SIGN_OUT', + SIGNED_IN: 'EVENT_TYPE.LIFECYCLE.SIGNED_IN', + SIGNED_OUT: 'EVENT_TYPE.LIFECYCLE.SIGNED_OUT', + UNREAD_COUNT: 'EVENT_TYPE.LIFECYCLE.UNREAD_COUNT', +}; diff --git a/electron/renderer/src/lib/localStorage.js b/electron/renderer/src/lib/localStorage.js index d3276c5756f..70b1498864b 100644 --- a/electron/renderer/src/lib/localStorage.js +++ b/electron/renderer/src/lib/localStorage.js @@ -17,23 +17,22 @@ * */ +const STATE_NAME = 'state'; + export const loadState = () => { try { - const serializedState = localStorage.getItem('state'); - if (serializedState === null) { - return undefined; - } - return JSON.parse(serializedState); + const serializedState = localStorage.getItem(STATE_NAME); + return !!serializedState ? JSON.parse(serializedState) : undefined; } catch (error) { console.error('ERROR: Failed to load state ', error.message); return undefined; } }; -export const saveState = (state) => { +export const saveState = state => { try { const serializedState = JSON.stringify(state); - localStorage.setItem('state', serializedState); + localStorage.setItem(STATE_NAME, serializedState); } catch (error) { console.error('ERROR: Failed to save state ', error.message); } diff --git a/electron/renderer/src/lib/locale.js b/electron/renderer/src/lib/locale.js index 4ba1d3db039..faf11fe1d43 100644 --- a/electron/renderer/src/lib/locale.js +++ b/electron/renderer/src/lib/locale.js @@ -1,6 +1,4 @@ window.locStrings = window.locStrings || {}; window.locStringsDefault = window.locStringsDefault || {}; -export function getText(id) { - return locStrings[id] || locStringsDefault[id] || id; -} +export const getText = id => locStrings[id] || locStringsDefault[id] || id; diff --git a/electron/renderer/src/lib/util.js b/electron/renderer/src/lib/util.js index 765bb375568..783fa508ce1 100644 --- a/electron/renderer/src/lib/util.js +++ b/electron/renderer/src/lib/util.js @@ -19,10 +19,10 @@ export const noop = () => {}; -export function preventFocus(func = noop) { - return function(event) { +export const preventFocus = (fn = noop) => { + return event => { event.stopPropagation(); event.preventDefault(); - func(event); + fn(event); }; -} +}; diff --git a/electron/renderer/src/lib/verifyObjectProperties.js b/electron/renderer/src/lib/verifyObjectProperties.js index 5ed7d2901e8..c1186257b42 100644 --- a/electron/renderer/src/lib/verifyObjectProperties.js +++ b/electron/renderer/src/lib/verifyObjectProperties.js @@ -17,10 +17,10 @@ * */ -function is(type, obj) { - const getType = Object.prototype.toString.call(obj).slice(8, -1); - return obj && getType === type; -} +const isType = (type, object) => { + const getType = Object.prototype.toString.call(object).slice(8, -1); + return object && getType === type; +}; export default function(data, config) { const validatedData = {}; @@ -31,7 +31,7 @@ export default function(data, config) { return true; } - const isValid = is(config[key], data[key]); + const isValid = isType(config[key], data[key]); if (isValid) { validatedData[key] = data[key]; } diff --git a/electron/renderer/src/reducers/__tests__/accounts.spec.js b/electron/renderer/src/reducers/__tests__/accountReducer.spec.js similarity index 69% rename from electron/renderer/src/reducers/__tests__/accounts.spec.js rename to electron/renderer/src/reducers/__tests__/accountReducer.spec.js index c583f774b6d..76a3f82305b 100644 --- a/electron/renderer/src/reducers/__tests__/accounts.spec.js +++ b/electron/renderer/src/reducers/__tests__/accountReducer.spec.js @@ -17,7 +17,7 @@ * */ -import reducer from '../accounts'; +import accountReducer from '../accountReducer'; import { updateAccount, addAccount, @@ -28,11 +28,11 @@ import { describe('accounts reducer', () => { it('should return the initial state with one account', () => { - expect(reducer(undefined, {}).length).toEqual(1); + expect(accountReducer(undefined, {}).length).toEqual(1); }); it('should return a state with a new account', () => { - const state = [{ + const initialState = [{ accentID: undefined, badgeCount: 0, id: '046da4f1-39be-4b8b-823b-e71f12811454', @@ -43,16 +43,17 @@ describe('accounts reducer', () => { userID: undefined, visible: true, }]; - const newState = reducer(state, addAccount()); + const newState = accountReducer(initialState, addAccount()); + const [firstAccount, secondAccount] = newState; expect(newState.length).toEqual(2); - expect(newState[0].visible).toBeFalsy(); - expect(newState[1].visible).toBeTruthy(); - expect(newState[1].sessionID).toBeDefined(); + expect(firstAccount.visible).toBeFalsy(); + expect(secondAccount.visible).toBeTruthy(); + expect(secondAccount.sessionID).toBeDefined(); }); it('should return a state with a new account without a session', () => { - const state = [{ + const initialState = [{ accentID: undefined, badgeCount: 0, id: '046da4f1-39be-4b8b-823b-e71f12811454', @@ -63,16 +64,17 @@ describe('accounts reducer', () => { userID: undefined, visible: true, }]; - const newState = reducer(state, addAccount(false)); + const newState = accountReducer(initialState, addAccount(false)); + const [firstAccount, secondAccount] = newState; expect(newState.length).toEqual(2); - expect(newState[0].visible).toBeFalsy(); - expect(newState[1].visible).toBeTruthy(); - expect(newState[1].sessionID).not.toBeDefined(); + expect(firstAccount.visible).toBeFalsy(); + expect(secondAccount.visible).toBeTruthy(); + expect(secondAccount.sessionID).not.toBeDefined(); }); it('should return a state with only the specified account visible', () => { - const state = [{ + const initialState = [{ accentID: undefined, badgeCount: 0, id: '046da4f1-39be-4b8b-823b-e71f12811454', @@ -93,14 +95,14 @@ describe('accounts reducer', () => { userID: undefined, visible: false, }]; - const newState = reducer(state, switchAccount(state[1].id)); + const [firstAccount, secondAccount] = accountReducer(initialState, switchAccount(initialState[1].id)); - expect(newState[0].visible).toBeFalsy(); - expect(newState[1].visible).toBeTruthy(); + expect(firstAccount.visible).toBeFalsy(); + expect(secondAccount.visible).toBeTruthy(); }); it('should return a state with an updated account', () => { - const state = [{ + const initialState = [{ accentID: undefined, badgeCount: 0, id: '046da4f1-39be-4b8b-823b-e71f12811454', @@ -121,14 +123,15 @@ describe('accounts reducer', () => { userID: undefined, visible: false, }]; - const newState = reducer(state, updateAccount(state[0].id, { userID: 'f4b9a5d0-3e36-4e6f-a404-ba22d23e3730'})); + const accountData = {userID: 'f4b9a5d0-3e36-4e6f-a404-ba22d23e3730'}; + const [firstAccount, secondAccount] = accountReducer(initialState, updateAccount(initialState[0].id, accountData)); - expect(newState[0].userID).toEqual('f4b9a5d0-3e36-4e6f-a404-ba22d23e3730'); - expect(newState[1].userID).toBeUndefined(); + expect(firstAccount.userID).toEqual('f4b9a5d0-3e36-4e6f-a404-ba22d23e3730'); + expect(secondAccount.userID).toBeUndefined(); }); it('should return a state with an updated badge count', () => { - const state = [{ + const initialState = [{ accentID: undefined, badgeCount: 0, id: '046da4f1-39be-4b8b-823b-e71f12811454', @@ -149,14 +152,14 @@ describe('accounts reducer', () => { userID: undefined, visible: false, }]; - const newState = reducer(state, updateAccountBadge(state[1].id, 12)); + const [firstAccount, secondAccount] = accountReducer(initialState, updateAccountBadge(initialState[1].id, 12)); - expect(newState[0].badgeCount).toEqual(0); - expect(newState[1].badgeCount).toEqual(12); + expect(firstAccount.badgeCount).toEqual(0); + expect(secondAccount.badgeCount).toEqual(12); }); it('should return a state without the deleted account', () => { - const state = [{ + const initialState = [{ accentID: undefined, badgeCount: 0, id: '046da4f1-39be-4b8b-823b-e71f12811454', @@ -177,10 +180,10 @@ describe('accounts reducer', () => { userID: undefined, visible: false, }]; - const newState = reducer(state, deleteAccount(state[0].id)); + const newState = accountReducer(initialState, deleteAccount(initialState[0].id)); + const [firstAccount] = newState; expect(newState.length).toEqual(1); - expect(newState[0].id).toEqual('d01eb964-bf56-4668-8883-dc248b58b1ca'); + expect(firstAccount.id).toEqual('d01eb964-bf56-4668-8883-dc248b58b1ca'); }); - }); diff --git a/electron/renderer/src/reducers/accountReducer.js b/electron/renderer/src/reducers/accountReducer.js new file mode 100644 index 00000000000..720c0726479 --- /dev/null +++ b/electron/renderer/src/reducers/accountReducer.js @@ -0,0 +1,81 @@ +/* + * Wire + * Copyright (C) 2018 Wire Swiss GmbH + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + * + */ + +import uuid from 'uuid/v4'; +import * as ActionCreator from '../actions'; + +const createAccount = sessionId => ({ + accentID: undefined, + badgeCount: 0, + id: uuid(), + lifecycle: undefined, + name: undefined, + picture: undefined, + sessionID: sessionId, + teamID: undefined, + userID: undefined, + visible: true, +}); + +const accountReducer = (state = [createAccount()], action) => { + switch (action.type) { + case ActionCreator.ADD_ACCOUNT: { + const newState = state.map(account => ({...account, visible: false})); + newState.push(createAccount(action.sessionID)); + return newState; + } + + case ActionCreator.DELETE_ACCOUNT: { + return state.filter(account => account.id !== action.id); + } + + case ActionCreator.SWITCH_ACCOUNT: { + return state.map(account => { + const isMatchingAccount = account.id === action.id; + return {...account, visible: isMatchingAccount}; + }); + } + + case ActionCreator.UPDATE_ACCOUNT: { + return state.map(account => { + const isMatchingAccount = account.id === action.id; + return isMatchingAccount ? {...account, ...action.data} : account; + }); + } + + case ActionCreator.UPDATE_ACCOUNT_BADGE: { + return state.map(account => { + const isMatchingAccount = account.id === action.id; + return isMatchingAccount ? {...account, badgeCount: action.count} : account; + }); + } + + case ActionCreator.UPDATE_ACCOUNT_LIFECYCLE: { + return state.map(account => { + const isMatchingAccount = account.id === action.id; + return isMatchingAccount ? {...account, lifecycle: action.data} : account; + }); + } + + default: + return state; + } +}; + +export default accountReducer; diff --git a/electron/renderer/src/reducers/accounts.js b/electron/renderer/src/reducers/accounts.js deleted file mode 100644 index 76c4512be7d..00000000000 --- a/electron/renderer/src/reducers/accounts.js +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Wire - * Copyright (C) 2018 Wire Swiss GmbH - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see http://www.gnu.org/licenses/. - * - */ - -import uuid from 'uuid/v4'; - -function createAccount(sessionID) { - return { - accentID: undefined, - badgeCount: 0, - id: uuid(), - lifecycle: undefined, - name: undefined, - picture: undefined, - sessionID: sessionID, - teamID: undefined, - userID: undefined, - visible: true, - }; -} - -const accounts = (state = [createAccount()], action) => { - switch (action.type) { - case 'ADD_ACCOUNT': - return [ - ...state.map(account => ({ ...account, visible: false })), - createAccount(action.sessionID), - ]; - case 'UPDATE_ACCOUNT': - return state.map(account => { - return account.id === action.id - ? { ...account, ...action.data } - : account; - }); - case 'UPDATE_ACCOUNT_BADGE': - return state.map(account => { - return account.id === action.id - ? { ...account, badgeCount: action.count } - : account; - }); - case 'UPDATE_ACCOUNT_LIFECYCLE': - return state.map(account => { - return account.id === action.id - ? { ...account, lifecycle: action.data } - : account; - }); - case 'SWITCH_ACCOUNT': - return state.map(account => { - return { - ...account, - visible: account.id === action.id, - }; - }); - case 'DELETE_ACCOUNT': - return state.filter(account => account.id !== action.id); - default: - return state; - } -}; - -export default accounts; diff --git a/electron/renderer/src/reducers/contextMenu.js b/electron/renderer/src/reducers/contextMenuReducer.js similarity index 79% rename from electron/renderer/src/reducers/contextMenu.js rename to electron/renderer/src/reducers/contextMenuReducer.js index 2e049298816..c2f4340510e 100644 --- a/electron/renderer/src/reducers/contextMenu.js +++ b/electron/renderer/src/reducers/contextMenuReducer.js @@ -17,7 +17,9 @@ * */ -const defaultState = { +import * as ActionCreator from '../actions'; + +const DEFAULT_STATE = { accountId: '', isAddAccountMenuVisible: false, isAtLeastAdmin: false, @@ -27,20 +29,22 @@ const defaultState = { sessionId: '', }; -const accounts = (state = defaultState, action) => { +const contextMenuReducer = (state = DEFAULT_STATE, action) => { switch (action.type) { - case 'HIDE_CONTEXT_MENUS': - return { - ...defaultState, - }; - case 'TOGGLE_ADD_ACCOUNT_VISIBILITY': + case ActionCreator.HIDE_CONTEXT_MENUS: { + return {...DEFAULT_STATE}; + } + + case ActionCreator.TOGGLE_ADD_ACCOUNT_VISIBILITY: { return { ...state, isAddAccountMenuVisible: !state.isAddAccountMenuVisible, isEditAccountMenuVisible: false, position: action.payload.position, }; - case 'TOGGLE_EDIT_ACCOUNT_VISIBILITY': + } + + case ActionCreator.TOGGLE_EDIT_ACCOUNT_VISIBILITY: { return { ...state, accountId: action.payload.accountId, @@ -51,9 +55,11 @@ const accounts = (state = defaultState, action) => { position: action.payload.position, sessionId: action.payload.sessionId, }; + } + default: return state; } }; -export default accounts; +export default contextMenuReducer; diff --git a/electron/renderer/src/reducers/index.js b/electron/renderer/src/reducers/index.js index 51d776a8f15..2ce7d286fb5 100644 --- a/electron/renderer/src/reducers/index.js +++ b/electron/renderer/src/reducers/index.js @@ -17,13 +17,13 @@ * */ -import { combineReducers } from 'redux'; -import accounts from './accounts'; -import contextMenuState from './contextMenu'; +import {combineReducers} from 'redux'; +import accountsReducer from './accountReducer'; +import contextMenuReducer from './contextMenuReducer'; const store = combineReducers({ - accounts, - contextMenuState, + accountsReducer, + contextMenuReducer, }); export default store; diff --git a/electron/renderer/static/webview-preload.js b/electron/renderer/static/webview-preload.js index 90d934facf2..2a90720bdd9 100644 --- a/electron/renderer/static/webview-preload.js +++ b/electron/renderer/static/webview-preload.js @@ -22,9 +22,10 @@ const environment = require('../../js/environment'); const fs = require('fs-extra'); const path = require('path'); const winston = require('winston'); +const EVENT_TYPE = require('../../js/lib/eventType'); -const { desktopCapturer, ipcRenderer, remote, webFrame } = require('electron'); -const { app } = remote; +const {desktopCapturer, ipcRenderer, remote, webFrame} = require('electron'); +const {app} = remote; webFrame.setVisualZoomLevelLimits(1, 1); webFrame.setLayoutZoomLevelLimits(1, 1); @@ -32,96 +33,91 @@ webFrame.registerURLSchemeAsBypassingCSP('file'); const subscribeToWebappEvents = () => { amplify.subscribe(z.event.WebApp.LIFECYCLE.RESTART, update_source => { - if (update_source === z.lifecycle.UPDATE_SOURCE.DESKTOP) { - ipcRenderer.send('wrapper-update'); - } else { - ipcRenderer.send('wrapper-relaunch'); - } + const isUpdateSourceDesktop = update_source === z.lifecycle.UPDATE_SOURCE.DESKTOP; + const eventType = isUpdateSourceDesktop ? EVENT_TYPE.WRAPPER.UPDATE : EVENT_TYPE.WRAPPER.RELAUNCH; + ipcRenderer.send(eventType); }); amplify.subscribe(z.event.WebApp.LIFECYCLE.LOADED, () => { - ipcRenderer.sendToHost('lifecycle-signed-in'); + ipcRenderer.sendToHost(EVENT_TYPE.LIFECYCLE.SIGNED_IN); }); amplify.subscribe(z.event.WebApp.LIFECYCLE.SIGN_OUT, () => { - ipcRenderer.sendToHost('lifecycle-signed-out'); + ipcRenderer.sendToHost(EVENT_TYPE.LIFECYCLE.SIGN_OUT); }); amplify.subscribe(z.event.WebApp.LIFECYCLE.SIGNED_OUT, clearData => { if (clearData) { - ipcRenderer.sendToHost('signed-out'); + ipcRenderer.sendToHost(EVENT_TYPE.LIFECYCLE.SIGNED_OUT); } }); amplify.subscribe(z.event.WebApp.LIFECYCLE.UNREAD_COUNT, count => { - ipcRenderer.sendToHost('lifecycle-unread-count', count); + ipcRenderer.sendToHost(EVENT_TYPE.LIFECYCLE.UNREAD_COUNT, count); }); amplify.subscribe(z.event.WebApp.NOTIFICATION.CLICK, () => { - ipcRenderer.send('notification-click'); - ipcRenderer.sendToHost('notification-click'); + ipcRenderer.send(EVENT_TYPE.ACTION.NOTIFICATION_CLICK); + ipcRenderer.sendToHost(EVENT_TYPE.ACTION.NOTIFICATION_CLICK); }); amplify.subscribe(z.event.WebApp.TEAM.INFO, info => { - ipcRenderer.sendToHost('team-info', info); + ipcRenderer.sendToHost(EVENT_TYPE.ACCOUNT.UPDATE_INFO, info); }); }; const subscribeToMainProcessEvents = () => { - ipcRenderer.on('conversation-add-people', () => - amplify.publish(z.event.WebApp.SHORTCUT.ADD_PEOPLE) - ); - ipcRenderer.on('conversation-archive', () => - amplify.publish(z.event.WebApp.SHORTCUT.ARCHIVE) - ); - ipcRenderer.on('conversation-call', () => - amplify.publish(z.event.WebApp.CALL.STATE.TOGGLE, false) - ); - ipcRenderer.on('conversation-delete', () => - amplify.publish(z.event.WebApp.SHORTCUT.DELETE) - ); - ipcRenderer.on('conversation-next', () => - amplify.publish(z.event.WebApp.SHORTCUT.NEXT) - ); - ipcRenderer.on('conversation-people', () => - amplify.publish(z.event.WebApp.SHORTCUT.PEOPLE) - ); - ipcRenderer.on('conversation-ping', () => - amplify.publish(z.event.WebApp.SHORTCUT.PING) - ); - ipcRenderer.on('conversation-prev', () => - amplify.publish(z.event.WebApp.SHORTCUT.PREV) - ); - ipcRenderer.on('conversation-show', conversation_id => - amplify.publish(z.event.WebApp.CONVERSATION.SHOW, conversation_id) - ); - ipcRenderer.on('conversation-silence', () => - amplify.publish(z.event.WebApp.SHORTCUT.SILENCE) - ); - ipcRenderer.on('conversation-start', () => - amplify.publish(z.event.WebApp.SHORTCUT.START) - ); - ipcRenderer.on('conversation-video-call', () => - amplify.publish(z.event.WebApp.CALL.STATE.TOGGLE, true) - ); - ipcRenderer.on('preferences-show', () => - amplify.publish(z.event.WebApp.PREFERENCES.MANAGE_ACCOUNT) - ); - ipcRenderer.on('sign-out', () => - amplify.publish(z.event.WebApp.LIFECYCLE.ASK_TO_CLEAR_DATA) - ); - ipcRenderer.on('wrapper-update-available', () => - amplify.publish( - z.event.WebApp.LIFECYCLE.UPDATE, - z.announce.UPDATE_SOURCE.DESKTOP - ) - ); + ipcRenderer.on(EVENT_TYPE.CONVERSATION.ADD_PEOPLE, () => { + amplify.publish(z.event.WebApp.SHORTCUT.ADD_PEOPLE); + }); + ipcRenderer.on(EVENT_TYPE.CONVERSATION.ARCHIVE, () => { + amplify.publish(z.event.WebApp.SHORTCUT.ARCHIVE); + }); + ipcRenderer.on(EVENT_TYPE.CONVERSATION.CALL, () => { + amplify.publish(z.event.WebApp.CALL.STATE.TOGGLE, false); + }); + ipcRenderer.on(EVENT_TYPE.CONVERSATION.DELETE, () => { + amplify.publish(z.event.WebApp.SHORTCUT.DELETE); + }); + ipcRenderer.on(EVENT_TYPE.CONVERSATION.SHOW_NEXT, () => { + amplify.publish(z.event.WebApp.SHORTCUT.NEXT); + }); + ipcRenderer.on(EVENT_TYPE.CONVERSATION.PEOPLE, () => { + amplify.publish(z.event.WebApp.SHORTCUT.PEOPLE); + }); + ipcRenderer.on(EVENT_TYPE.CONVERSATION.PING, () => { + amplify.publish(z.event.WebApp.SHORTCUT.PING); + }); + ipcRenderer.on(EVENT_TYPE.CONVERSATION.SHOW_PREVIOUS, () => { + amplify.publish(z.event.WebApp.SHORTCUT.PREV); + }); + ipcRenderer.on(EVENT_TYPE.CONVERSATION.SHOW, conversationId => { + amplify.publish(z.event.WebApp.CONVERSATION.SHOW, conversationId); + }); + ipcRenderer.on(EVENT_TYPE.CONVERSATION.TOGGLE_MUTE, () => { + amplify.publish(z.event.WebApp.SHORTCUT.SILENCE); + }); + ipcRenderer.on(EVENT_TYPE.CONVERSATION.START, () => { + amplify.publish(z.event.WebApp.SHORTCUT.START); + }); + ipcRenderer.on(EVENT_TYPE.CONVERSATION.VIDEO_CALL, () => { + amplify.publish(z.event.WebApp.CALL.STATE.TOGGLE, true); + }); + ipcRenderer.on(EVENT_TYPE.PREFERENCES.SHOW, () => { + amplify.publish(z.event.WebApp.PREFERENCES.MANAGE_ACCOUNT); + }); + ipcRenderer.on(EVENT_TYPE.ACTION.SIGN_OUT, () => { + amplify.publish(z.event.WebApp.LIFECYCLE.ASK_TO_CLEAR_DATA); + }); + ipcRenderer.on(EVENT_TYPE.WRAPPER.UPDATE_AVAILABLE, () => { + amplify.publish(z.event.WebApp.LIFECYCLE.UPDATE, z.lifecycle.UPDATE_SOURCE.DESKTOP); + }); }; -const exposeAddressbook = () => { +const exposeAddressBook = () => { let cachedAddressBook; - const getAdressBook = () => { + const getAddressBook = () => { if (!cachedAddressBook) { try { cachedAddressBook = require('node-addressbook'); @@ -133,7 +129,7 @@ const exposeAddressbook = () => { }; if (environment.platform.IS_MAC_OS) { - Object.defineProperty(window, 'wAddressBook', { get: getAdressBook }); + Object.defineProperty(window, 'wAddressBook', { get: getAddressBook }); } }; @@ -145,9 +141,9 @@ const replaceGoogleAuth = () => { // hijack google authenticate method window.wire.app.service.connect_google._authenticate = () => { return new Promise((resolve, reject) => { - ipcRenderer.send('google-auth-request'); - ipcRenderer.once('google-auth-success', (event, token) => resolve(token)); - ipcRenderer.once('google-auth-error', reject); + ipcRenderer.send(EVENT_TYPE.GOOGLE_OAUTH.REQUEST); + ipcRenderer.once(EVENT_TYPE.GOOGLE_OAUTH.SUCCESS, (event, token) => resolve(token)); + ipcRenderer.once(EVENT_TYPE.GOOGLE_OAUTH.ERROR, reject); }); }; }; @@ -156,12 +152,7 @@ const enableFileLogging = () => { const id = new URL(window.location).searchParams.get('id'); if (id) { - const logFilePath = path.join( - app.getPath('userData'), - 'logs', - id, - config.LOG_FILE_NAME - ); + const logFilePath = path.join(app.getPath('userData'), 'logs', id, config.LOG_FILE_NAME); fs.createFileSync(logFilePath); const logger = new winston.Logger(); @@ -177,16 +168,13 @@ const enableFileLogging = () => { } }; -const reportWebappVersion = () => { - ipcRenderer.send('webapp-version', z.util.Environment.version(false)); -}; +const reportWebappVersion = () => ipcRenderer.send(EVENT_TYPE.UI.WEBAPP_VERSION, z.util.Environment.version(false)); const checkAvailability = callback => { const intervalId = setInterval(() => { if (window.wire) { clearInterval(intervalId); - callback(); - return; + return callback(); } if (navigator.onLine) { @@ -197,10 +185,6 @@ const checkAvailability = callback => { }, 500); }; -const forceEmailLogin = () => { - window.location.hash = '#login'; -}; - // https://github.com/electron/electron/issues/2984 const _setImmediate = setImmediate; process.once('loaded', () => { @@ -208,18 +192,13 @@ process.once('loaded', () => { global.desktopCapturer = desktopCapturer; global.environment = environment; global.openGraph = require('../../js/lib/openGraph'); - global.notification_icon = path.join( - app.getAppPath(), - 'img', - 'notification.png' - ); + global.notification_icon = path.join(app.getAppPath(), 'img', 'notification.png'); enableFileLogging(); - forceEmailLogin(); }); window.addEventListener('DOMContentLoaded', () => { checkAvailability(() => { - exposeAddressbook(); + exposeAddressBook(); subscribeToMainProcessEvents(); subscribeToWebappEvents();