diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..a746ad4 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,22 @@ +module.exports = { + "env": { + "browser": true, + "es2021": true + }, + "extends": "eslint:recommended", + "parserOptions": { + "ecmaVersion": 13, + "sourceType": "module" + }, + "globals": { + "__dirname": true, + "converse": true, + "exports": true, + "module": true, + "process": true, + "require": true, + }, + "rules": { + "prefer-const": "error", + } +}; diff --git a/libs/converse.js/3rdparty/LICENSE b/3rdparty/LICENSE similarity index 100% rename from libs/converse.js/3rdparty/LICENSE rename to 3rdparty/LICENSE diff --git a/libs/converse.js/3rdparty/libsignal-protocol.js b/3rdparty/libsignal-protocol.js similarity index 100% rename from libs/converse.js/3rdparty/libsignal-protocol.js rename to 3rdparty/libsignal-protocol.js diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..8533e98 --- /dev/null +++ b/Makefile @@ -0,0 +1,16 @@ +BIN ?= ./node_modules/.bin/ +ESLINT ?= ./node_modules/.bin/eslint + +node_modules: package.json package-lock.json + npm i + +build: node_modules + $(BIN)/electron-rebuild + +serve: build + npm start + +.PHONY: eslint +eslint: node_modules + $(ESLINT) *.js + $(ESLINT) app/**/*.js diff --git a/app/controllers/about-controller.js b/app/controllers/about-controller.js deleted file mode 100644 index 72366bb..0000000 --- a/app/controllers/about-controller.js +++ /dev/null @@ -1,10 +0,0 @@ -let angApp = require(__dirname+'/../init') - -angApp.controller('AboutController', function($scope, AppStateService, AppInfo) { - - $scope.appInfo = AppInfo - - $scope.closeAbout = () => { - AppStateService.set(AppStateService.APP_STATE_DEFAULT) - } -}) \ No newline at end of file diff --git a/app/controllers/default-controller.js b/app/controllers/default-controller.js deleted file mode 100644 index f2ebe99..0000000 --- a/app/controllers/default-controller.js +++ /dev/null @@ -1,47 +0,0 @@ -let angApp = require(__dirname+'/../init') - -angApp.controller('DefaultController', function($scope, $timeout, $http, AppInfo) { - - $scope.appInfo = AppInfo - - let getUpdateInfo = () => { - $http({ - url: $scope.appInfo.APP_RELEASES_CHECK_URL, - method: 'GET' - }).then((response) => { - let releaseTag = response.data[0].tag_name - let releaseVersion = parseInt(releaseTag.replace(/v|\./g, '')) - let appVersion = parseInt($scope.appInfo.APP_VERSION.replace(/v|\./g, '')) - if (appVersion < releaseVersion ) { - $scope.checkingForUpdate = 'updateAvailable' - } - else { - $scope.checkingForUpdate = 'latest' - } - }).catch((error) => { - $scope.checkingForUpdate = 'checkErr' - }) - } - - let checkForUpdate = (timeout = 5000) => { - $scope.checkingForUpdate = 'inProgress' - $timeout(() => { - getUpdateInfo() - }, timeout) - } - - let checkForUpdateDelayed = (timeout = 5000) => { - $timeout(() => { - checkForUpdate() - }, timeout) - } - - checkForUpdateDelayed() - - $scope.checkRetry = ($event) => { - $event.preventDefault() - checkForUpdate() - } - - -}) \ No newline at end of file diff --git a/app/controllers/footer-controller.js b/app/controllers/footer-controller.js deleted file mode 100644 index 6747c82..0000000 --- a/app/controllers/footer-controller.js +++ /dev/null @@ -1,7 +0,0 @@ -let angApp = require(__dirname+'/../init') - -angApp.controller('FooterController', function($scope, AppInfo) { - - $scope.appInfo = AppInfo - -}) \ No newline at end of file diff --git a/app/controllers/login-controller.js b/app/controllers/login-controller.js deleted file mode 100644 index c364351..0000000 --- a/app/controllers/login-controller.js +++ /dev/null @@ -1,21 +0,0 @@ -let angApp = require(__dirname+'/../init') - -angApp.controller('LoginController', function($scope, DesktopService, CredentialsService) { - - $scope.help = {} - - $scope.showHelp = (item) => { - $scope.help[item] = typeof $scope.help[item] === 'undefined' ? true : !$scope.help[item]; - } - - $scope.addAccountAndLoginAction = () => { - CredentialsService.addCredentials($scope.credentials.connectionManager, - $scope.credentials.login, - $scope.credentials.password - ) - DesktopService.getCredentialsAndLogin() - $scope.accountForm.$setPristine() - $scope.accountForm.$setUntouched() - $scope.credentials = {} - } -}) \ No newline at end of file diff --git a/app/controllers/settings-controller.js b/app/controllers/settings-controller.js deleted file mode 100644 index be5154f..0000000 --- a/app/controllers/settings-controller.js +++ /dev/null @@ -1,40 +0,0 @@ -let angApp = require(__dirname+'/../init') - -angApp.controller('SettingsController', function ($scope, $rootScope, AppStateService, SettingsService) { - - let formInitialized = false - $scope.settingsChanged = false - $scope.settingsSaved = false - - const settingsSetPristine = () => { - $scope.settingsChanged = false - formInitialized = false - } - - $scope.closeSettings = () => { - $scope.settings = SettingsService.loadAll() - settingsSetPristine() - AppStateService.set(AppStateService.APP_STATE_DEFAULT) - } - - $scope.saveSettings = () => { - $scope.settingsSaved = true - SettingsService.saveAll($scope.settings) - settingsSetPristine() - } - - $scope.restartApp = () => { - $rootScope.$broadcast('app:restart') - } - - $scope.settings = SettingsService.loadAll() - - $scope.$watch("settings", () => { - if (!formInitialized) { - formInitialized = true - } else { - $scope.settingsChanged = true - } - }, true) - -}) \ No newline at end of file diff --git a/app/converse-plugins/desktop-credentials.js b/app/converse-plugins/desktop-credentials.js new file mode 100644 index 0000000..08b0a24 --- /dev/null +++ b/app/converse-plugins/desktop-credentials.js @@ -0,0 +1,24 @@ +const { addCredentials } = require('../credentials.js'); +const { getCredentials, removeCredentials } = require('../credentials.js'); + +converse.plugins.add('converse-desktop-credentials', { + + initialize () { + const { _converse } = this; + const { api } = _converse; + + api.listen.on('afterResourceBinding', () => { + if (_converse.connection.pass) { + addCredentials( + converse.connectionManager, + _converse.bare_jid, + _converse.connection.pass + ); + } + }); + + api.listen.on('logout', () => { + getCredentials().then((result) => removeCredentials(result.login)) + }); + } +}); diff --git a/app/credentials.js b/app/credentials.js new file mode 100644 index 0000000..ce0e9dd --- /dev/null +++ b/app/credentials.js @@ -0,0 +1,49 @@ +/* global require, module */ + +const settings = require('electron-settings'); +const keytar = require('keytar') + +function addCredentials (connectionManager, login, password) { + const xmppService = login.split('@').pop() + settings.setSync('connectionManager', connectionManager) + settings.setSync('login', login) + keytar.setPassword(xmppService, login, password) +} + +function getCredentials () { + const credentials = {} + credentials.login = settings.getSync('login') + return new Promise((resolve) => { + if (credentials.login) { + credentials.connectionManager = settings.getSync('connectionManager') + credentials.xmppService = credentials.login.split('@').pop() + let password = keytar.getPassword(credentials.xmppService, credentials.login) + password.then((result) => { + credentials.password = result + resolve(credentials) + }) + } else { + resolve({}); + } + }); +} + +function removeCredentials (login) { + const xmppService = login.split('@').pop() + const passwordDelete = keytar.deletePassword(xmppService, login) + return new Promise((resolve, reject) => { + passwordDelete.then(() => { + settings.unsetSync('login') + settings.unsetSync('connectionManager') + resolve() + }, (error) => { + reject(error) + }) + }) +} + +module.exports = { + addCredentials, + getCredentials, + removeCredentials +} diff --git a/app/init.js b/app/init.js deleted file mode 100644 index 266e9d5..0000000 --- a/app/init.js +++ /dev/null @@ -1,14 +0,0 @@ -const angular = require('angular') -let angApp = angular.module('app', []) - -angApp.constant('AppInfo', { - APP_NAME: 'Converse Desktop', - APP_VERSION: 'v0.1.0', - APP_HOME: 'https://github.com/conversejs/converse-desktop', - APP_RELEASES_CHECK_URL: 'https://api.github.com/repos/conversejs/converse-desktop/releases', - APP_RELEASES_URL: 'https://github.com/conversejs/converse-desktop/releases', - CONVERSE_VERSION: 'v7.0.4', - ELECTRON_VERSION: '11.2.3' -}); - -module.exports = angApp diff --git a/app/services/app-state-service.js b/app/services/app-state-service.js deleted file mode 100644 index 9c4ba66..0000000 --- a/app/services/app-state-service.js +++ /dev/null @@ -1,22 +0,0 @@ -let angApp = require(__dirname + '/../init') - -angApp.factory('AppStateService', [ '$rootScope', ($rootScope) => { - - let stateService = {} - - stateService.APP_STATE_LOGIN = 'login' - stateService.APP_STATE_DEFAULT = 'default' - stateService.APP_STATE_SETTINGS = 'settings' - stateService.APP_STATE_ABOUT = 'about' - - stateService.set = (state) => { - stateService.previousState = typeof stateService.state !== 'undefined' ? - stateService.state : stateService.APP_STATE_DEFAULT - stateService.state = state - $rootScope.$broadcast('app:state:changed', stateService.state) - } - - stateService.set(stateService.APP_STATE_DEFAULT) - - return stateService -}]) \ No newline at end of file diff --git a/app/services/credentials-service.js b/app/services/credentials-service.js deleted file mode 100644 index cd6831f..0000000 --- a/app/services/credentials-service.js +++ /dev/null @@ -1,54 +0,0 @@ -let angApp = require(__dirname+'/../init') - -angApp.factory('CredentialsService', () => { - - const keytar = require('keytar') - const settings = require('electron-settings') - - let credentialsService = {} - - credentialsService.getCredentials = () => { - let credentials = {} - credentials.login = settings.getSync('login') - let promise = new Promise((resolve, reject) => { - if (credentials.login) { - credentials.connectionManager = settings.getSync('connectionManager') - credentials.xmppService = credentials.login.split('@').pop() - let password = keytar.getPassword(credentials.xmppService, credentials.login) - password.then((result) => { - credentials.password = result - resolve(credentials) - }) - } - else { - reject(Error('No login stored')) - } - }) - return promise - } - - credentialsService.addCredentials = (connectionManager, login, password) => { - let xmppService = login.split('@').pop() - settings.setSync('connectionManager', connectionManager) - settings.setSync('login', login) - keytar.setPassword(xmppService, login, password) - } - - credentialsService.removeCredentials = (login) => { - let xmppService = login.split('@').pop() - passwordDelete = keytar.deletePassword(xmppService, login) - let promise = new Promise((resolve, reject) => { - passwordDelete.then((result) => { - settings.unsetSync('login') - settings.unsetSync('connectionManager') - resolve() - }, (error) => { - reject(error) - }) - }) - return promise - } - - return credentialsService -}) - diff --git a/app/services/desktop-service.js b/app/services/desktop-service.js deleted file mode 100644 index ebaec6a..0000000 --- a/app/services/desktop-service.js +++ /dev/null @@ -1,96 +0,0 @@ -let angApp = require(__dirname + '/../init') - -const desktopPlugin = require(__dirname +'/../../libs/converse.js/converse-desktop/desktop-plugin') - -angApp.factory('DesktopService', ( - $window, $timeout, CredentialsService, SystemService, AppStateService, - SettingsService, XmppHelperService - ) => { - - let desktopService = {} - - desktopService._notifyMessage = () => { - SystemService.playAudio() - SystemService.showEnvelope() - } - - desktopService._hideNotifyMessage = () => { - SystemService.hideEnvelope() - } - - desktopService.logout = () => { - let credentials = CredentialsService.getCredentials() - credentials.then((result) => { - let remove = CredentialsService.removeCredentials(result.login) - console.log('Remove credentials on logout') - remove.then(() => { - AppStateService.set(AppStateService.APP_STATE_LOGIN) - }) - }) - } - - desktopService.initConverse = (connectionManager, login, password) => { - AppStateService.set(AppStateService.APP_STATE_DEFAULT) // Always set to default state before init - desktopPlugin.register(login) - let lang = navigator.language - let allowBookmarks = SettingsService.get('allowBookmarks') - let omemoDefault = SettingsService.get('omemoDefault') - let xmppResource = XmppHelperService.getResourceFromJid(login) - if (!xmppResource) { - xmppResource = '.' + (Math.random().toString(36)+'00000000000000000').slice(2, 7) // Generate 5 char unique str - login = login + '/converseDesktop'+xmppResource - } - let conversejsParams = { - assets_path: './node_modules/converse.js/dist/', - allow_bookmarks: allowBookmarks, - auto_login: true, - auto_reconnect: true, - // debug: true, - i18n: lang, - jid: login, - omemo_default: omemoDefault, - password: password, - play_sounds: false, - priority: 50, - view_mode: 'embedded', - whitelisted_plugins: ['converseDesktop'], - } - if (connectionManager.startsWith('ws')) { - conversejsParams.websocket_url = connectionManager - } else { - conversejsParams.bosh_service_url = connectionManager - } - $timeout(() => { - converse.initialize(conversejsParams) - }, 50) - } - - desktopService.getCredentialsAndLogin = () => { - let credentials = CredentialsService.getCredentials() - credentials.then((result) => { - desktopService.initConverse(result.connectionManager, result.login, result.password) - }, (error) => { - AppStateService.set(AppStateService.APP_STATE_LOGIN) - }) - } - - - desktopService.chatToOpen = null - - $window.document.addEventListener('conversejs-logout', function (e) { - desktopService.logout() - }) - - $window.document.addEventListener('conversejs-unread', function (e) { - let sender = e.detail - desktopService.chatToOpen = sender - desktopService._notifyMessage() - }) - - $window.document.addEventListener('conversejs-no-unread', function (e) { - desktopService._hideNotifyMessage() - }) - - return desktopService - -}) \ No newline at end of file diff --git a/app/services/settings-service.js b/app/services/settings-service.js deleted file mode 100644 index 0d19ac6..0000000 --- a/app/services/settings-service.js +++ /dev/null @@ -1,109 +0,0 @@ -let angApp = require(__dirname+'/../init') - -angApp.factory('SettingsService', () => { - - let settingsService = {} - - const electronSettings = require('electron-settings') - - const settings = { - converseDesktop: { - runMinimized: { - default: false, - title: 'Run minimized', - hint: 'Default: false. Whether run Converse Desktop minimized to tray or not.' - }, - minimizeOnClose: { - default: false, - title: 'Minimize on close', - hint: 'Default: false. Minimize or close Converse Desktop window.' - }, - preserveWindowSize: { - default: true, - title: 'Preserve window size', - hint: 'Default: true, 800x600 otherwise.' - }, - preserveWindowPosition: { - default: true, - title: 'Preserve window position', - hint: 'Default: true, screen center otherwise.' - } - }, - conversejs: { - allowBookmarks: { - default: false, - title: 'Allow server bookmarks', - hint: 'Default: false. Enables/disables chatroom bookmarks functionality.' - }, - omemoDefault: { - default: false, - title: 'Use OMEMO encryption by default', - hint: 'Default: false. Use OMEMO encryption by default when the chat supports it.' - } - } - } - - const iterateSettings = (callback, settingsObj) => { - if(typeof settingsObj === "undefined") { - settingsObj = settings - } - angular.forEach(settingsObj, (value, key) => { - let settingsList = settingsObj[key] - angular.forEach(settingsList, (value, key) => { - let itemDefault = settingsList[key]['default'] - callback(key, itemDefault, settingsList) - }) - }) - } - - // Callback - // TODO: replace with promise? - const saveDefault = (key, value) => { - if (!electronSettings.hasSync(key)) { - electronSettings.setSync(key, value) - } - } - - // Callback - const save = (key, defaultValue, settingsList) => { - let value = settingsList[key]['value'] - electronSettings.setSync(key, value) - } - - // Callback - const loadAll = (key, defaultValue, settingsList) => { - if (!electronSettings.hasSync(key)) { - settingsList[key]['value'] = defaultValue - } - settingsList[key]['value'] = electronSettings.getSync(key) - } - - /** - * SettingsService - */ - settingsService.initDefaults = () => { - iterateSettings(saveDefault) - // Logout for versions with BOSH only - if (electronSettings.hasSync('bosh')) { - electronSettings.unsetSync('bosh') - electronSettings.unsetSync('login') - } - } - - settingsService.get = (key) => { - return electronSettings.getSync(key) - } - - settingsService.loadAll = () => { - let currentSettings = angular.copy(settings) - iterateSettings(loadAll, currentSettings) - return currentSettings - } - - settingsService.saveAll = (currentSettings) => { - iterateSettings(save, currentSettings) - } - - return settingsService -}) - diff --git a/app/services/system-service.js b/app/services/system-service.js deleted file mode 100644 index 98f2af1..0000000 --- a/app/services/system-service.js +++ /dev/null @@ -1,28 +0,0 @@ -let angApp = require(__dirname + '/../init') - -angApp.factory('SystemService', () => { - - const remote = require('electron').remote - - let systemService = {} - - systemService.playAudio = () => { - var audio = new Audio(__dirname + '/../../resources/sounds/graceful.ogg') - audio.play() - } - - systemService.showEnvelope = () => { - remote.require('./main').trayService.showEnvelope() - } - - systemService.hideEnvelope = () => { - remote.require('./main').trayService.hideEnvelope() - } - - systemService.reloadWindow = () => { - remote.getCurrentWindow().reload() - } - - return systemService - -}) \ No newline at end of file diff --git a/app/services/xmpp-helper-service.js b/app/services/xmpp-helper-service.js deleted file mode 100644 index 74408ab..0000000 --- a/app/services/xmpp-helper-service.js +++ /dev/null @@ -1,25 +0,0 @@ -let angApp = require(__dirname + '/../init') - -angApp.factory('XmppHelperService', [() => { - - let xmppHelperService = {} - - /** - * Use function copy from Strophe js lib because converse.js Strophe library - * is under private _api and unavailable before converse.js is initialized. - * This function is used _before_ converse.js is initialized. - * - * Get the resource portion of a JID String. - * @param {string} jid A JID. - * @return {string | null} A String containing the resource. - */ - xmppHelperService.getResourceFromJid = (jid) => { - if (!jid) { return null } - const s = jid.split("/") - if (s.length < 2) { return null } - s.splice(0, 1) - return s.join('/') - } - - return xmppHelperService -}]) \ No newline at end of file diff --git a/app/views/about/page.html b/app/views/about/page.html deleted file mode 100644 index a959743..0000000 --- a/app/views/about/page.html +++ /dev/null @@ -1,35 +0,0 @@ -
-
-
- -
-

About {{appInfo.APP_NAME}} {{appInfo.APP_VERSION}}

-
Jabber/XMPP client based on Converse.js and Electron
-
 
-
- Version of converse.js is {{appInfo.CONVERSE_VERSION}} -
-
- Version of electron is {{appInfo.ELECTRON_VERSION}} -
-
 
-
- Thanks to - all contributors -
-
 
-
-
- -
- -
-
 
- -
-
- - \ No newline at end of file diff --git a/app/views/default/page.html b/app/views/default/page.html deleted file mode 100644 index de6efd7..0000000 --- a/app/views/default/page.html +++ /dev/null @@ -1,24 +0,0 @@ -
-
- -

{{appInfo.APP_NAME}}

-
- {{appInfo.APP_VERSION}} - - checking for update... - - >_< check for update failed retry - - latest version - - Update available - - -
-
-
-
-
-
diff --git a/app/views/login/page.html b/app/views/login/page.html deleted file mode 100644 index e7e0525..0000000 --- a/app/views/login/page.html +++ /dev/null @@ -1,43 +0,0 @@ -
-

Welcome to Converse Desktop

-
Jabber/XMPP client based on Converse.js and Electron
-
-
- - - - - -
-
-
- \ No newline at end of file diff --git a/app/views/settings/page.html b/app/views/settings/page.html deleted file mode 100644 index 9595e03..0000000 --- a/app/views/settings/page.html +++ /dev/null @@ -1,28 +0,0 @@ -
-
-

Chimeverse settings

-
- -
{{item.hint}}
-
-

Converse.js settings

-
- -
{{item.hint}}
-
- -
- - -
-
-
- \ No newline at end of file diff --git a/app/views/shared/_footer.html b/app/views/shared/_footer.html deleted file mode 100644 index 950c838..0000000 --- a/app/views/shared/_footer.html +++ /dev/null @@ -1,4 +0,0 @@ - \ No newline at end of file diff --git a/index.html b/index.html index 931266a..44f8030 100644 --- a/index.html +++ b/index.html @@ -7,28 +7,17 @@ - - - -
-
-
- -
-
- -
-
- -
-
- + +
+
+
+ @@ -37,27 +26,15 @@ delete window.require - + - - \ No newline at end of file + diff --git a/libs/converse.js/converse-desktop/desktop-plugin.js b/libs/converse.js/converse-desktop/desktop-plugin.js deleted file mode 100644 index 931f59a..0000000 --- a/libs/converse.js/converse-desktop/desktop-plugin.js +++ /dev/null @@ -1,67 +0,0 @@ -let desktopPlugin = {} - -desktopPlugin.register = (login) => { - converse.plugins.add('converseDesktop', { - initialize: (event) => { - let _converse = event.properties._converse - let Strophe = converse.env.Strophe - - /** - * Check if message stanza has some body payload - * @param {*} stanzaNodes - */ - let isBodyMessage = (stanzaNodes) => { - let result = false - Object.keys(stanzaNodes).some((key) => { - if (stanzaNodes[key].nodeName == 'body') { - result = true - } - }) - return result - } - - Promise.all([ - _converse.api.waitUntil('rosterContactsFetched'), - _converse.api.waitUntil('chatBoxesFetched') - ]).then(() => { - _converse.api.listen.on('logout', () => { - let event = new CustomEvent('conversejs-logout') - document.dispatchEvent(event) - }) - _converse.api.listen.on('message', (data) => { - // Display notifications only for "payloaded" messages - if (isBodyMessage(data.stanza.childNodes)) { - let sender = data.stanza.attributes.from.nodeValue - let senderJid = Strophe.getBareJidFromJid(sender) - let loginJid = Strophe.getBareJidFromJid(login) - if (senderJid != loginJid) { - console.log(senderJid) - let event = new CustomEvent('conversejs-unread', {detail: senderJid}) - document.dispatchEvent(event) - } - } - }) - _converse.api.listen.on('chatBoxFocused', () => { - let event = new CustomEvent('conversejs-no-unread') - document.dispatchEvent(event) - //chimeverseService._hideNotifyMessage() - }) - window.document.addEventListener('converse-force-logout', function (e) { - console.log('Get converse-force-logout event') - console.log('Logout form plugin') - _converse.api.user.logout() - //chimeverseService.logout() - }) - window.document.addEventListener('conversejs-open-chat', function (e) { - let chatToOpen = e.detail - console.log('Get open-unread-chat event: '+chatToOpen) - if (chatToOpen !== null) { - _converse.api.chats.open(chatToOpen) - } - }) - }) - } - }) -} - -module.exports = desktopPlugin \ No newline at end of file diff --git a/main.js b/main.js index 6335b91..cb34722 100644 --- a/main.js +++ b/main.js @@ -8,7 +8,7 @@ let mainWindow // Require other app modules const trayService = require(__dirname+'/modules/tray-service') const menuService = require(__dirname+'/modules/menu-service') -const settingsService = require(__dirname+'/modules/settings-service') +// const settingsService = require(__dirname+'/modules/settings-service') const isMac = process.platform === 'darwin' const isWin = process.platform === 'win32' @@ -23,41 +23,19 @@ function initApp() { function createWindow () { // Main window options - let mainWindowOptions = { - width: 800, - height: 600, - minWidth: 780, - minHeight: 560, + const mainWindowOptions = { + zoomToPageWidth: true, webPreferences: { nodeIntegration: true, contextIsolation: false, enableRemoteModule: true - } - } - - // Load app settings - let runMinimized = settingsService.get('runMinimized') - if (runMinimized) { - mainWindowOptions.show = !runMinimized - } - let preserveWindowSize = settingsService.get('preserveWindowSize') - if (preserveWindowSize) { - let width = settingsService.get('windowWidth') - let height = settingsService.get('windowHeight') - if (width) mainWindowOptions.width = width - if (height) mainWindowOptions.height = height - } - - let preserveWindowPosition = settingsService.get('preserveWindowPosition') - if (preserveWindowPosition) { - let windowX = settingsService.get('windowX') - let windowY = settingsService.get('windowY') - if (windowX) mainWindowOptions.x = windowX - if (windowY) mainWindowOptions.y = windowY + }, + icon: './resources/images/logo.png', } // Create the browser window. mainWindow = new BrowserWindow(mainWindowOptions) + mainWindow.maximize(); // and load the index.html of the app. mainWindow.loadFile('index.html') @@ -72,35 +50,15 @@ function createWindow () { // mainWindow.webContents.openDevTools() // Before close - let minimizeOnClose = settingsService.get('minimizeOnClose') + // const minimizeOnClose = settingsService.get('minimizeOnClose'); + const minimizeOnClose = false; // XXX: this doesn't seem to work if (minimizeOnClose) { mainWindow.on('close', (e) => { if (!app.isQuitting) { e.preventDefault() mainWindow.hide() } - }) - } - - // Save window size - if (preserveWindowSize) { - mainWindow.on('resize', (e) => { - let newSize = mainWindow.getSize() - let width = newSize[0] - let height = newSize[1] - settingsService.set('windowWidth', width) - settingsService.set('windowHeight', height) - }) - } - - // Save window position - if (preserveWindowPosition !== 'undefined') { - mainWindow.on('move', (e) => { - let newPosition = mainWindow.getPosition() - let windowX = newPosition[0] - let windowY = newPosition[1] - settingsService.set('windowX', windowX) - settingsService.set('windowY', windowY) + return false; }) } @@ -115,7 +73,7 @@ function createWindow () { } // Handle restart - ipcMain.on('app-restart', (evt, arg) => { + ipcMain.on('app-restart', () => { app.isQuitting = true app.relaunch() app.exit() diff --git a/modules/menu-service.js b/modules/menu-service.js index 55f0280..d8d1d09 100644 --- a/modules/menu-service.js +++ b/modules/menu-service.js @@ -1,61 +1,24 @@ /** * Module for Menu functions. */ - const {app, Menu, BrowserWindow} = require('electron') -let menuService = {} +const menuService = {} menuService.createMenu = () => { - - const isMac = process.platform === 'darwin' - - const about = { - label: 'About Converse Desktop', - click: () => { - // @see https://github.com/electron/electron/issues/16558#issuecomment-484460276 - // let activeWindow = BrowserWindow.getFocusedWindow() - let activeWindow = BrowserWindow.getAllWindows()[0] - activeWindow.show() - activeWindow.webContents.send('about-page-event') - } - } - const application = { label: 'Converse Desktop', submenu: [ - ... isMac ? [about] : [], { label: 'Reconnect', accelerator: 'CmdOrCtrl+R', click: () => { - let activeWindow = BrowserWindow.getAllWindows()[0] + const activeWindow = BrowserWindow.getAllWindows()[0] activeWindow.show() activeWindow.reload() } }, - { - label: 'Force logout', - accelerator: 'CmdOrCtrl+D', - click: () => { - let activeWindow = BrowserWindow.getAllWindows()[0] - activeWindow.show() - activeWindow.webContents.send('force-logout-event') - } - }, - { - type: 'separator', - }, - { - label: 'Preferences', - accelerator: 'CmdOrCtrl+,', - click: () => { - let activeWindow = BrowserWindow.getAllWindows()[0] - activeWindow.show() - activeWindow.webContents.send('preferences-event') - } - }, { type: 'separator', }, @@ -110,12 +73,11 @@ menuService.createMenu = () => { const help = { label: 'Help', submenu: [ - ... !isMac ? [about] : [], { label: 'Debug info', accelerator: 'F12', click: () => { - let activeWindow = BrowserWindow.getAllWindows()[0] + const activeWindow = BrowserWindow.getAllWindows()[0] activeWindow.webContents.openDevTools() } } diff --git a/modules/settings-service.js b/modules/settings-service.js index 1f93bb0..fd503b8 100644 --- a/modules/settings-service.js +++ b/modules/settings-service.js @@ -7,7 +7,7 @@ const electronSettings = require('electron-settings') let settingsService = {} settingsService.get = (itemKey) => { - settingValue = electronSettings.getSync(itemKey) + const settingValue = electronSettings.getSync(itemKey) if (typeof settingValue === 'undefined' || settingValue === null) { return false } @@ -18,4 +18,4 @@ settingsService.set = (itemKey, settingValue) => { electronSettings.setSync(itemKey, settingValue) } -module.exports = settingsService \ No newline at end of file +module.exports = settingsService diff --git a/modules/tray-service.js b/modules/tray-service.js index 4c7aabd..e6facae 100644 --- a/modules/tray-service.js +++ b/modules/tray-service.js @@ -9,17 +9,15 @@ const path = require('path') let trayServiceWindow = null let tray = null -let trayService = {} +const trayService = {} -let getTrayServiceIcon = (iconName = 'icon') => { +const getTrayServiceIcon = (iconName = 'icon') => { let iconImage = '' if (process.platform === 'darwin') { iconImage = iconName+'Template' - } - else if (process.platform === 'win32') { + } else if (process.platform === 'win32') { iconImage = iconName+'-16x16' - } - else { + } else { iconImage = iconName+'-48x48' } return path.join(__dirname, '/../resources/images/' + iconImage + '.png') @@ -27,12 +25,12 @@ let getTrayServiceIcon = (iconName = 'icon') => { trayService.initTray = (window) => { trayServiceWindow = window - let iconPath = getTrayServiceIcon() + const iconPath = getTrayServiceIcon() tray = new Tray(iconPath) tray.setToolTip('Converse Desktop') tray.on('click', function() { // Sent open-related-chat event only on click - let activeWindow = BrowserWindow.getAllWindows()[0] + const activeWindow = BrowserWindow.getAllWindows()[0] activeWindow.webContents.send('open-unread-chat') trayService.hideEnvelope() trayServiceWindow.show() @@ -40,12 +38,12 @@ trayService.initTray = (window) => { } trayService.showEnvelope = () => { - let iconPath = getTrayServiceIcon('envelope') + const iconPath = getTrayServiceIcon('envelope') tray.setImage(iconPath) } trayService.hideEnvelope = () => { - let iconPath = getTrayServiceIcon() + const iconPath = getTrayServiceIcon() tray.setImage(iconPath) } diff --git a/package.json b/package.json index 3d716cd..edfeb56 100644 --- a/package.json +++ b/package.json @@ -20,16 +20,16 @@ "Electron", "OMEMO" ], - "author": "Nick Denry ", "license": "MPL-2.0", "devDependencies": { "electron": "11.2.3", "electron-builder": "^22.9.1", - "electron-packager": "^15.2.0" + "electron-packager": "^15.2.0", + "electron-rebuild": "^3.2.5", + "eslint": "^8.4.1" }, "dependencies": { - "angular": "^1.7.9", - "converse.js": "7.0.4", + "converse.js": "conversejs/converse.js#ba6da97416b912a35060a4c5667bc77f76852780", "electron-settings": "^4.0.2", "github-buttons": "^2.8.0", "keytar": "^7.3.0", @@ -59,7 +59,7 @@ }, "linux": { "artifactName": "converse_desktop-${version}_${arch}.${ext}", - "icon": "resources/images/logo@2x.png", + "icon": "resources/images/logo.png", "target": [ "deb", "tar.gz" diff --git a/renderer.js b/renderer.js deleted file mode 100644 index ccb308d..0000000 --- a/renderer.js +++ /dev/null @@ -1,64 +0,0 @@ -// This file is required by the index.html file and will -// be executed in the renderer process for that window. -// All of the Node.js APIs are available in this process. - -var angApp = require('./app/init') - -require('./app/services/credentials-service') -require('./app/services/settings-service') -require('./app/services/system-service') -require('./app/services/app-state-service') -require('./app/services/xmpp-helper-service') -require('./app/services/desktop-service') -require('./app/controllers/settings-controller') -require('./app/controllers/login-controller') -require('./app/controllers/default-controller') -require('./app/controllers/about-controller') -require('./app/controllers/footer-controller') - -angApp.controller('AppController', function ($scope, $timeout, DesktopService, SettingsService, AppStateService) { - - const { ipcRenderer } = require('electron') - - // Menu force logout event - ipcRenderer.on('force-logout-event', () => { - DesktopService.logout() - let event = new CustomEvent("converse-force-logout") // Dispatch to the plugin - document.dispatchEvent(event) - }) - - // Menu settings event - ipcRenderer.on('preferences-event', () => { - AppStateService.set(AppStateService.APP_STATE_SETTINGS) - }) - - // Menu about event - ipcRenderer.on('about-page-event', () => { - AppStateService.set(AppStateService.APP_STATE_ABOUT) - }) - - // Menu about event - ipcRenderer.on('open-unread-chat', () => { - let event = new CustomEvent('conversejs-open-chat', {detail: DesktopService.chatToOpen}) - document.dispatchEvent(event) - }) - - AppStateService.set(AppStateService.APP_STATE_DEFAULT) - - $scope.$on('app:state:changed', (event, data) => { - // @see https://docs.angularjs.org/error/$rootScope/inprog - $timeout(() => { - $scope.state = data - console.log('Switch to the "' + $scope.state +'" state') - }, 0) - }) - - $scope.$on('app:restart', (event, data) => { - ipcRenderer.send('app-restart') - }) - - SettingsService.initDefaults() - - DesktopService.getCredentialsAndLogin() - -}) diff --git a/resources/css/app.css b/resources/css/app.css index 261a781..931582e 100644 --- a/resources/css/app.css +++ b/resources/css/app.css @@ -20,16 +20,6 @@ a { color: #777; } -.main-background { - background: #f8f8f8; - height: 100%; - left: 0px; - position: fixed; - top: 0px; - width: 100%; - z-index: -1; -} - .conversejs-adoption { background: transparent; pointer-events: none; diff --git a/resources/css/page-about.css b/resources/css/page-about.css deleted file mode 100644 index 0e69140..0000000 --- a/resources/css/page-about.css +++ /dev/null @@ -1,39 +0,0 @@ -.page-about { - color: #777; - left: 50%; - position: absolute; - top: 47%; - transform: translate(-50%, -50%); -} - -.about-card { - background: #fff; - box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.1); - margin-top: 30px; - min-width: 400px; - padding: 30px; -} - -.about-card__content { - display: flex; -} - -.about__action { - text-align: center; -} - -.about__close-button { - border: 0px solid #ddd; - background: rgb(5,93,228); - background: linear-gradient(0deg, rgba(5,93,228,1) 0%, rgba(76,145,255,1) 100%); - color: #fff; - cursor: pointer; - display: inline-block; - font-size: 18px; - outline: none; - padding: 10px 30px; - } - - .about__copyright { - text-align: center; - } \ No newline at end of file diff --git a/resources/css/page-login.css b/resources/css/page-login.css deleted file mode 100644 index 7bf56bb..0000000 --- a/resources/css/page-login.css +++ /dev/null @@ -1,100 +0,0 @@ -.login-form { - color: #777; - left: 50%; - position: absolute; - top: 47%; - transform: translate(-50%, -50%); -} - -.login-form__title { - font-size: 28px; - text-align: center; - font-weight: normal; - margin: 0px 0px 15px 0px; -} - -.login-form__description { - text-align: center; -} - -.login-form__card { - background: #fff; - box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.1); - margin-top: 30px; - padding: 30px; -} - -.login-form__wrapper { - margin-bottom: 15px;; -} - -.login-form__input-group { - border: 1px solid #ddd; - border-radius: 0px; - padding: 0px 0px 0px 30px; - position: relative; -} - -.login-form__input-group:active, -.login-form__input-group:focus, -.login-form__input-group:hover { - border: 1px solid #aaa; -} - -.login-form__input-group .group-prepend { - position: absolute; - left: 15px; - top: 12px; -} - -.login-form__input-group .group-append--backgrounded { - background: #f2f2f2; - cursor: pointer; - padding: 12px; - position: absolute; - right: 0px; - top: 0 px; -} - -.login-form__input { - border: 0px; - color: #222; - font-size: 18px; - outline: none; - padding: 10px; - width: 290px; -} - -.login-form__input::placeholder { /* Most modern browsers support this now. */ - color: #ccc; - } - - .login-form__input--with-append { - width: 260px; - } - - .login-form__input-help { - font-size: 13px; - margin: 4px; - } - - .login-form__button { - border: 1px solid #ddd; - background: rgb(5,93,228); - background: linear-gradient(0deg, rgba(5,93,228,1) 0%, rgba(76,145,255,1) 100%); - color: #fff; - display: inline-block; - font-size: 18px; - outline: none; - padding: 10px 30px; - width: 100%; - } - - .login-form__button:disabled { - background: #eee; - } - - .login-form__credentials-message { - font-size: 14px; - text-align: center; - } \ No newline at end of file diff --git a/resources/images/envelope-16x16.png b/resources/images/envelope-16x16.png deleted file mode 100644 index 95ef4ac..0000000 Binary files a/resources/images/envelope-16x16.png and /dev/null differ diff --git a/resources/images/envelope-48x48.png b/resources/images/envelope-48x48.png deleted file mode 100644 index f435c1e..0000000 Binary files a/resources/images/envelope-48x48.png and /dev/null differ diff --git a/resources/images/envelopeTemplate.png b/resources/images/envelopeTemplate.png deleted file mode 100644 index 76b6287..0000000 Binary files a/resources/images/envelopeTemplate.png and /dev/null differ diff --git a/resources/images/envelopeTemplate@2x.png b/resources/images/envelopeTemplate@2x.png deleted file mode 100644 index 089fbbe..0000000 Binary files a/resources/images/envelopeTemplate@2x.png and /dev/null differ diff --git a/resources/images/icon-16x16.png b/resources/images/icon-16x16.png index 272cd85..a5d3430 100644 Binary files a/resources/images/icon-16x16.png and b/resources/images/icon-16x16.png differ diff --git a/resources/images/icon-48x48.png b/resources/images/icon-48x48.png index 0bd6e89..7bc0058 100644 Binary files a/resources/images/icon-48x48.png and b/resources/images/icon-48x48.png differ diff --git a/resources/images/iconTemplate.png b/resources/images/iconTemplate.png deleted file mode 100644 index c0ed3c6..0000000 Binary files a/resources/images/iconTemplate.png and /dev/null differ diff --git a/resources/images/iconTemplate@2x.png b/resources/images/iconTemplate@2x.png deleted file mode 100644 index 750808e..0000000 Binary files a/resources/images/iconTemplate@2x.png and /dev/null differ diff --git a/resources/images/logo.ico b/resources/images/logo.ico index af90768..edadbfc 100644 Binary files a/resources/images/logo.ico and b/resources/images/logo.ico differ diff --git a/resources/images/logo.png b/resources/images/logo.png index df79547..f85f008 100644 Binary files a/resources/images/logo.png and b/resources/images/logo.png differ diff --git a/setup.js b/setup.js new file mode 100644 index 0000000..a677813 --- /dev/null +++ b/setup.js @@ -0,0 +1,46 @@ +require('./app/converse-plugins/desktop-credentials.js'); +const{ getCredentials } = require('./app/credentials.js') + + +async function initialize () { + let websocket_url, bosh_service_url; + const { connectionManager, login, password } = await getCredentials() + + converse.connectionManager = connectionManager; + + if (connectionManager?.startsWith('ws')) { + websocket_url = connectionManager + } else if (connectionManager?.startsWith('http')) { + bosh_service_url = connectionManager + } else { + bosh_service_url = 'https://conversejs.org/http-bind/'; + } + + converse.plugins.add('converse-debug', { + initialize () { + const { _converse } = this; + window._converse = _converse; + } + }); + + converse.initialize({ + assets_path: './node_modules/converse.js/dist/', + auto_login: login && password, + bosh_service_url, + i18n: navigator.language, + jid: login, + loglevel: 'debug', + muc_respect_autojoin: true, + muc_show_logs_before_join: true, + password: password, + play_sounds: false, + priority: 50, + prune_messages_above: 250, + theme: 'concord', + view_mode: 'fullscreen', + websocket_url, + whitelisted_plugins: ['converse-debug', 'converse-desktop-credentials'], + }); +} + +initialize();