diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..9053717 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,30 @@ +{ + "root":true, + "env": { + "browser": true, + "es2021": true, + "node": true, + "jest/globals": true + }, + "extends": [ + "eslint:recommended", + "plugin:react/recommended", + "plugin:prettier/recommended" + ], + "parser": "babel-eslint", + "parserOptions": { + "ecmaFeatures": { + "jsx": true + }, + "ecmaVersion": 12, + "sourceType": "module" + }, + "plugins": [ + "prettier", + "react", + "jest" + ], + "rules": { + "prettier/prettier": "warn" + } +} diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..1bdf446 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,8 @@ +{ + "trailingComma": "es5", + "tabWidth": 2, + "semi": true, + "singleQuote": true, + "jsxBracketSameLine": true, + "printWidth": 100 +} diff --git a/.vim/coc-settings.json b/.vim/coc-settings.json index ae5fe8f..cc6e9fb 100644 --- a/.vim/coc-settings.json +++ b/.vim/coc-settings.json @@ -1,14 +1,36 @@ { "cSpell.words": [ + "APPIMAGE", + "APPPLATFORM", + "Bodhi", + "Filebase", + "GUID's", + "HKCC", + "HKCR", + "HKCU", "HKEY", "HKLM", + "LOCALAPPDATA", "Redistributable", + "Skylink's", "Skylinks", "Skynet", "Unmount", + "WINFSP", + "blockstorage", + "centos", + "fontawesome", + "fortawesome", "msiexec", + "norestart", + "randomstring", + "reduxjs", "relver", + "scprime", "siaprime", - "skylink" + "skylink", + "undocked", + "valign", + "windir" ] -} \ No newline at end of file +} diff --git a/.vimrc b/.vimrc index cbde2c6..b8dd2cb 100644 --- a/.vimrc +++ b/.vimrc @@ -1,6 +1,6 @@ set autoread set path+=.,public/**,src/**,test/** -if has('win32') +if has('win32') || has('win64') let &makeprg="create_dist.cmd" else let &makeprg="./create_dist.sh" diff --git a/CHANGELOG.md b/CHANGELOG.md index 302c676..4a367af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,150 +1,178 @@ # Changelog +## 1.3.4 +- \#55: Enable 'Activate' release instead of 'Install' in notification pop-up +- \#58: Add authentication support for Skynet premium portals +- \#59: Add agent string / API key support for Skynet portals +- Ability to export Skylink's to json file +- Ability to import Skylink's from json file + ## 1.3.3 -* \#49: Download progress is not visible if dependencies are missing -* \#51: javascript error -* \#52: Mount location is not set error on new install -* \#53: Busy notification is still visible when 'Install' button is available -* \#54: Unable to download UI update while dependencies are being checked -* Disabled 'Install' button in new release notification + +- \#49: Download progress is not visible if dependencies are missing +- \#51: javascript error +- \#52: Mount location is not set error on new install +- \#53: Busy notification is still visible when 'Install' button is available +- \#54: Unable to download UI update while dependencies are being checked +- Disabled 'Install' button in new release notification ## 1.3.2 -* \#48: Support pinning files to cache -* Fixed Skynet export display -* Properly detect existing remote -* Reduced number of Linux binaries to: - * CentOS 7 - * Solus -* S3 mount support [disabled] + +- \#48: Support pinning files to cache +- Fixed Skynet export display +- Properly detect existing remote +- Reduced number of Linux binaries to: + - CentOS 7 + - Solus +- S3 mount support [disabled] ## 1.3.1 -* \#45: Skynet mount support + +- \#45: Skynet mount support ## 1.3.0 -* \#38: Enhance new repertory release available notification -* \#46: Fix Mount Manager unmount and mount detection -* Skynet support -* Synchronize UI major/minor version with `repertory` major/minor version -* Added `Password` component -* Reduced number of Linux binaries to: - * CentOS 7 - * Debian 9 - * Debian 10 - * Solus -* Added `FocusTrap` to modals + +- \#38: Enhance new repertory release available notification +- \#46: Fix Mount Manager unmount and mount detection +- Skynet support +- Synchronize UI major/minor version with `repertory` major/minor version +- Added `Password` component +- Reduced number of Linux binaries to: + - CentOS 7 + - Debian 9 + - Debian 10 + - Solus +- Added `FocusTrap` to modals ## 1.1.4 -* \#39: Cleanup old releases and UI upgrades + +- \#39: Cleanup old releases and UI upgrades ## 1.1.3 -* CentOS 8 support -* Support remote send and receive timeouts -* Support WinFSP mount manager -* Fix `spawn()` failure on Windows when paths contain spaces + +- CentOS 8 support +- Support remote send and receive timeouts +- Support WinFSP mount manager +- Fix `spawn()` failure on Windows when paths contain spaces ## 1.1.2 -* Style changes + +- Style changes ## 1.1.1 -* \#43: Support for remote UNIX mounts -* Improved mount state detection + +- \#43: Support for remote UNIX mounts +- Improved mount state detection ## 1.1.0 -* \#40: Support for remote Windows mounts -* \#42: Failing to unmount on OS X -* Allow enabling dev tools (Ctrl-Shift-I or F12) -* ScPrime re-brand -* Ubuntu 19.10 support -* Linux Mint 19.2 support -* Fedora 31 support + +- \#40: Support for remote Windows mounts +- \#42: Failing to unmount on OS X +- Allow enabling dev tools (Ctrl-Shift-I or F12) +- ScPrime re-brand +- Ubuntu 19.10 support +- Linux Mint 19.2 support +- Fedora 31 support ## 1.0.11 (Linux only) -* Fix Ubuntu 19.10 detection + +- Fix Ubuntu 19.10 detection ## 1.0.10 -* Fix VC runtime detection (detect additional GUID's) - + +- Fix VC runtime detection (detect additional GUID's) + ## 1.0.9 (Alpha Testing Release) -* \#40: Support for remote Windows mounts -* ScPrime re-brand -* Fix VC runtime detection (detect additional GUID's) + +- \#40: Support for remote Windows mounts +- ScPrime re-brand +- Fix VC runtime detection (detect additional GUID's) ## 1.0.8 -* \#8: Add tooltips to settings -* \#36: Add ability to select Linux distribution type if OS is unsupported -* \#37: Version check fails with incorrect message when VC runtime is missing -* Added additional WinFsp uninstall strings + +- \#8: Add tooltips to settings +- \#36: Add ability to select Linux distribution type if OS is unsupported +- \#37: Version check fails with incorrect message when VC runtime is missing +- Added additional WinFsp uninstall strings ## 1.0.7 -* \#31: New installation displays 'Mount location is not set' on Windows -* \#33: Add 'Microsoft Visual C++ Redistributable' as dependency installation on Windows -* \#32: Don't display network error message when check for UI updates fails -* \#30: Add uninstall feature with reboot to handle WinFSP upgrades/downgrades -* \#34: Allow cancelling/closing dependency installation if version count > 1 -* Handle incorrect download sizes for dependencies and releases - + +- \#31: New installation displays 'Mount location is not set' on Windows +- \#33: Add 'Microsoft Visual C++ Redistributable' as dependency installation on Windows +- \#32: Don't display network error message when check for UI updates fails +- \#30: Add uninstall feature with reboot to handle WinFSP upgrades/downgrades +- \#34: Allow cancelling/closing dependency installation if version count > 1 +- Handle incorrect download sizes for dependencies and releases + ## 1.0.6 -* Additional Linux distribution support: - * Antergos - * Manjaro -* Download latest `detect_linux.sh` if bundled script returns `unknown` -* Display error message if OS is detected as `unknown` + +- Additional Linux distribution support: + - Antergos + - Manjaro +- Download latest `detect_linux.sh` if bundled script returns `unknown` +- Display error message if OS is detected as `unknown` ## 1.0.5 -* \#29: Mounts aren't being detected properly when switching releases -* Display window when dependencies are missing -* Display window when UI upgrade is available -* Display window and unmount all drives if release is no longer available - * Will primarily affect pre-release versions (Alpha, Beta, and RC) + +- \#29: Mounts aren't being detected properly when switching releases +- Display window when dependencies are missing +- Display window when UI upgrade is available +- Display window and unmount all drives if release is no longer available + - Will primarily affect pre-release versions (Alpha, Beta, and RC) ## 1.0.4 -* \#27: Implement Bitbucket backup download location -* \#28: Fix Linux upgrade -* Additional Linux distribution support: - * Debian 10 - * OpenSUSE Leap 15.0 - * OpenSUSE Leap 15.1 - * OpenSUSE Tumbleweed + +- \#27: Implement Bitbucket backup download location +- \#28: Fix Linux upgrade +- Additional Linux distribution support: + - Debian 10 + - OpenSUSE Leap 15.0 + - OpenSUSE Leap 15.1 + - OpenSUSE Tumbleweed ## 1.0.3 -* Linux distribution support - * Arch Linux - * Bodhi 5.0.0 - * CentOS 7 - * Debian 9 - * Elementary OS 5.0 - * Fedora 28 - * Fedora 29 - * Fedora 30 - * Linux Mint 19 - * Linux Mint 19.1 - * Solus - * Ubuntu 18.04 - * Ubuntu 18.10 - * Ubuntu 19.04 -* Removed `react-css-modules` dependency -* Removed Hyperspace (no active development/insufficient host network) -* Restore main window on error message + +- Linux distribution support + - Arch Linux + - Bodhi 5.0.0 + - CentOS 7 + - Debian 9 + - Elementary OS 5.0 + - Fedora 28 + - Fedora 29 + - Fedora 30 + - Linux Mint 19 + - Linux Mint 19.1 + - Solus + - Ubuntu 18.04 + - Ubuntu 18.10 + - Ubuntu 19.04 +- Removed `react-css-modules` dependency +- Removed Hyperspace (no active development/insufficient host network) +- Restore main window on error message ## 1.0.2 -* Option to launch application hidden (notification icon only) -* Close window to notification area -* Unmount on application exit -* Ability to cancel mount retry on unexpected failure -* OS X support -* SiaPrime support -* Partial Linux support -* Electron to v4 -* Prevent mount if dependencies are missing + +- Option to launch application hidden (notification icon only) +- Close window to notification area +- Unmount on application exit +- Ability to cancel mount retry on unexpected failure +- OS X support +- SiaPrime support +- Partial Linux support +- Electron to v4 +- Prevent mount if dependencies are missing ## 1.0.1 -* Added configuration settings for Repertory 1.0.0-alpha.2 and above -* Fixed memory leak on component unmount -* Added error display -* Lighter tray icon on Windows -* Tray icon indicates mount status on Windows -* Various fixes/layout changes + +- Added configuration settings for Repertory 1.0.0-alpha.2 and above +- Fixed memory leak on component unmount +- Added error display +- Lighter tray icon on Windows +- Tray icon indicates mount status on Windows +- Various fixes/layout changes ## 1.0.0 -* Initial release -* Windows support + +- Initial release +- Windows support diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 1fa2ca9..ba1a274 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -1,4 +1,5 @@ # Repertory UI -* Lars Floe -* Oleg Nypadymka -* Scott E. Graves + +- Lars Floe +- Oleg Nypadymka +- Scott E. Graves diff --git a/README.md b/README.md index 6825fba..e48c91f 100644 --- a/README.md +++ b/README.md @@ -12,13 +12,13 @@ Skynet support is considered EXPERIMENTAL. Files added to Skynet should not be c * ScPrime >=1.4.1.2 ## Downloads -* **Repertory UI v1.3.3 Linux - 64-bit** [](https://bitbucket.org/blockstorage/repertory-ui/downloads/repertory-ui_1.3.3_linux_x86_64.AppImage) +* **Repertory UI v1.3.4 Linux + 64-bit** [](https://bitbucket.org/blockstorage/repertory-ui/downloads/repertory-ui_1.3.4_linux_x86_64.AppImage) * NOTE: Linux distributions require `fuse` and `libfuse` to be installed. -* **Repertory UI v1.3.3 OS X - 64-bit** [](https://bitbucket.org/blockstorage/repertory-ui/downloads/repertory-ui_1.3.3_mac.dmg) -* **Repertory UI v1.3.3 Windows - 64-bit** [](https://bitbucket.org/blockstorage/repertory-ui/downloads/repertory-ui_1.3.3_win.exe) +* **Repertory UI v1.3.4 OS X + 64-bit** [](https://bitbucket.org/blockstorage/repertory-ui/downloads/repertory-ui_1.3.4_mac.dmg) +* **Repertory UI v1.3.4 Windows + 64-bit** [](https://bitbucket.org/blockstorage/repertory-ui/downloads/repertory-ui_1.3.4_win.exe) ## Supported Platforms * OS X 64-bit diff --git a/create_dist.sh b/create_dist.sh index fb3f4f2..2c74258 100755 --- a/create_dist.sh +++ b/create_dist.sh @@ -26,7 +26,7 @@ if beginsWith darwin "$OSTYPE"; then JQ_EXEC=jq-osx-amd64 SHA256_EXEC="shasum -a 256 -b" else - DISTRO_LIST="centos7 debian9 debian10 solus" + DISTRO_LIST="centos7 solus" OUT_FILE=repertory-ui_${APP_VER}_linux_x86_64.AppImage BASE64_EXEC="base64 -w0" JQ_EXEC=jq-linux64 diff --git a/package.json b/package.json index ecc6c73..ff4d9dc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "repertory-ui", - "version": "1.3.3", + "version": "1.3.4", "private": true, "author": "scott.e.graves@protonmail.com", "description": "GUI for Repertory - Repertory allows you to mount Sia, Skynet, and/or ScPrime storage solutions via FUSE on Linux/OS X or via WinFSP on Windows.", @@ -10,21 +10,22 @@ "@fortawesome/react-fontawesome": "^0.1.13", "@reduxjs/toolkit": "^1.5.0", "auto-launch": "^5.0.5", - "axios": "^0.21.0", + "axios": "^0.21.1", "devtron": "^1.4.0", - "electron-debug": "^3.1.0", - "electron-log": "^4.3.0", - "focus-trap-react": "^8.3.2", + "electron-debug": "^3.2.0", + "electron-log": "^4.3.2", + "focus-trap-react": "^8.4.2", "font-awesome": "^4.7.0", - "node-cron": "^1.2.1", + "node-cron": "1.2.1", + "prop-types": "^15.7.2", "randomstring": "^1.1.5", - "react": "^16.14.0", + "react": "16.14.0", "react-checkbox-tree": "^1.6.0", - "react-dom": "^16.14.0", - "react-loader-spinner": "^3.1.14", + "react-dom": "16.14.0", + "react-loader-spinner": "^4.0.0", "react-redux": "^7.2.2", "react-scripts": "4.0.3", - "react-tooltip": "^4.2.11", + "react-tooltip": "^4.2.15", "redux": "^4.0.5", "redux-thunk": "^2.3.0", "unzipper": "^0.10.11", @@ -36,6 +37,12 @@ "electron": "5.0.13", "electron-builder": "22.9.1", "electron-webpack": "^2.8.2", + "eslint": "^7.22.0", + "eslint-config-prettier": "^8.3.0", + "eslint-plugin-jest": "^24.3.2", + "eslint-plugin-prettier": "^3.4.0", + "eslint-plugin-react": "^7.23.0", + "prettier": "2.2.1", "webpack": "4.44.2", "webpack-dev-server": "3.11.1" }, diff --git a/public/electron.js b/public/electron.js index 9e2b41e..7d4c2ec 100644 --- a/public/electron.js +++ b/public/electron.js @@ -1,12 +1,4 @@ -const { - app, - BrowserWindow, - dialog, - ipcMain, - Menu, - nativeImage, - Tray -} = require('electron'); +const { app, BrowserWindow, dialog, ipcMain, Menu, nativeImage, Tray } = require('electron'); const AutoLaunch = require('auto-launch'); const Constants = require('../src/constants'); const fs = require('fs'); @@ -44,12 +36,12 @@ const UpgradeIPC = require('../src/renderer/ipc/UpgradeIPC'); const platform = os.platform(); const dimensions = { - height: (platform === 'win32') ? 326 : (platform === 'darwin') ? 322 : 300, - width: (platform === 'win32') ? 468 : 628, + height: platform === 'win32' || platform === 'darwin' ? 420 : 400, + width: platform === 'win32' ? 468 : 628, }; let isShutdown = false; -let isQuiting = false; +let isQuitting = false; let isInstalling = false; let launchHidden = false; let cleanupReleases = false; @@ -88,7 +80,7 @@ const createWindow = () => { if (platform === 'linux') { extra = { icon: path.join(__dirname, '../build/', 'logo.png'), - } + }; } // Create the browser window. @@ -102,27 +94,29 @@ const createWindow = () => { ...extra, webPreferences: { nodeIntegration: true, - webSecurity: !process.env.ELECTRON_START_URL - } + webSecurity: !process.env.ELECTRON_START_URL, + }, }); if (platform === 'linux') { mainWindow.setMenuBarVisibility(false); } else { mainWindow.removeMenu(); } - if ((platform === 'darwin') && launchHidden) { + if (platform === 'darwin' && launchHidden) { app.dock.hide(); } // and load the index.html of the app. - const startUrl = process.env.ELECTRON_START_URL || url.format({ - pathname: path.join(__dirname, '../build/index.html'), - protocol: 'file:', - slashes: true - }); + const startUrl = + process.env.ELECTRON_START_URL || + url.format({ + pathname: path.join(__dirname, '../build/index.html'), + protocol: 'file:', + slashes: true, + }); mainWindow.on('close', function (event) { - if (!isQuiting) { + if (!isQuitting) { event.preventDefault(); if (mainWindow.isVisible()) { setWindowVisibility(false); @@ -140,9 +134,12 @@ const createWindow = () => { MountsIPC.unmountAllDrives(); }); - const appPath = (platform === 'win32') ? path.resolve(path.join(app.getAppPath(), '..\\..\\repertory-ui.exe')) : - (platform === 'darwin') ? path.resolve(path.join(path.dirname(app.getAppPath()), '../MacOS/repertory-ui')) : - process.env.APPIMAGE; + const appPath = + platform === 'win32' + ? path.resolve(path.join(app.getAppPath(), '..\\..\\repertory-ui.exe')) + : platform === 'darwin' + ? path.resolve(path.join(path.dirname(app.getAppPath()), '../MacOS/repertory-ui')) + : process.env.APPIMAGE; const autoLauncher = new AutoLaunch({ name: 'Repertory UI', @@ -151,51 +148,56 @@ const createWindow = () => { trayContextMenu = Menu.buildFromTemplate([ { - label: 'Visible', type: 'checkbox', click(item) { + label: 'Visible', + type: 'checkbox', + click(item) { setWindowVisibility(item.checked); }, checked: !launchHidden, }, + { type: 'separator' }, { - type: 'separator' - }, - { - label: 'Auto-start', type: 'checkbox', click(item) { + label: 'Auto-start', + type: 'checkbox', + click(item) { if (item.checked) { autoLauncher.enable(); } else { autoLauncher.disable(); } - } + }, }, { - label: 'Launch Hidden', type: 'checkbox', click(item) { + label: 'Launch Hidden', + type: 'checkbox', + click(item) { launchHidden = !!item.checked; saveUiSettings(); }, checked: launchHidden, }, + { type: 'separator' }, { - type: 'separator' - }, - { - label: 'Delete Old Releases', type: 'checkbox', click(item) { + label: 'Delete Old Releases', + type: 'checkbox', + click(item) { cleanupReleases = !!item.checked; saveUiSettings(); }, checked: cleanupReleases, }, + { type: 'separator' }, { - type: 'separator' - }, - { - label: 'Exit and Unmount', click() { + label: 'Exit and Unmount', + click() { closeApplication(); - } - } + }, + }, ]); - const image = nativeImage.createFromPath(path.join(__dirname, (platform === 'darwin') ? '../build/logo_mac.png' : '../build/logo.png')); + const image = nativeImage.createFromPath( + path.join(__dirname, platform === 'darwin' ? '../build/logo_mac.png' : '../build/logo.png') + ); mainWindowTray = new Tray(image); autoLauncher @@ -203,7 +205,7 @@ const createWindow = () => { .then((enabled) => { trayContextMenu.items[2].checked = enabled; mainWindowTray.setToolTip('Repertory UI'); - mainWindowTray.setContextMenu(trayContextMenu) + mainWindowTray.setContextMenu(trayContextMenu); }) .catch(() => { closeApplication(); @@ -225,37 +227,46 @@ const loadUiSettings = () => { cleanupReleases = !!settings.cleanup_releases; PlatformIPC.setPlatformOverride(settings.platform_override); } - } catch (e) { - } + } catch (e) {} }; const saveUiSettings = () => { const settingFile = path.join(helpers.getDataDirectory(), 'ui.json'); try { - fs.writeFileSync(settingFile, JSON.stringify({ - cleanup_releases: cleanupReleases, - launch_hidden: launchHidden, - platform_override: PlatformIPC.getPlatformOverride(), - }), 'utf-8'); - } catch (e) { - } + fs.writeFileSync( + settingFile, + JSON.stringify({ + cleanup_releases: cleanupReleases, + launch_hidden: launchHidden, + platform_override: PlatformIPC.getPlatformOverride(), + }), + 'utf-8' + ); + } catch (e) {} }; -const setIsInstalling = installing => { +const setIsInstalling = (installing) => { isInstalling = installing; }; -const setTrayImage = driveInUse => { +const setTrayImage = (driveInUse) => { let image; if (driveInUse) { - image = nativeImage.createFromPath(path.join(__dirname, platform === 'darwin' ? '../build/logo_both_mac.png' : '../build/logo_both.png')); + image = nativeImage.createFromPath( + path.join( + __dirname, + platform === 'darwin' ? '../build/logo_both_mac.png' : '../build/logo_both.png' + ) + ); } else { - image = nativeImage.createFromPath(path.join(__dirname, platform === 'darwin' ? '../build/logo_mac.png' : '../build/logo.png')); + image = nativeImage.createFromPath( + path.join(__dirname, platform === 'darwin' ? '../build/logo_mac.png' : '../build/logo.png') + ); } mainWindowTray.setImage(image); }; -const setWindowVisibility = show => { +const setWindowVisibility = (show) => { if (show) { mainWindow.show(); if (platform === 'darwin') { @@ -277,7 +288,7 @@ const setWindowVisibility = show => { if (trayContextMenu && mainWindowTray) { trayContextMenu.items[0].checked = show; - mainWindowTray.setContextMenu(trayContextMenu) + mainWindowTray.setContextMenu(trayContextMenu); } }; @@ -288,13 +299,13 @@ const standardIPCReply = (event, channel, data, error) => { ...data, Error: error instanceof Error ? error.toString() : error, Success: !error, - } + }, }); } }; app.on('before-quit', function () { - isQuiting = true; + isQuitting = true; }); let instanceLock = app.requestSingleInstanceLock(); diff --git a/public/index.html b/public/index.html index 4691c3f..94789b2 100644 --- a/public/index.html +++ b/public/index.html @@ -1,16 +1,22 @@ - - - + + + - - - + + + `ENOENT` and `EPERM` on // Windows. - if (err.code === 'ENOENT') { // Throw the original parentDir error on - // curDir `ENOENT` failure. + if (err.code === 'ENOENT') { + // Throw the original parentDir error on + // curDir `ENOENT` failure. throw new Error(`EACCES: permission denied, mkdir '${parentDir}'`); } - const caughtErr = [ 'EACCES', 'EPERM', 'EISDIR' ].indexOf(err.code) > -1; - if (!caughtErr || (caughtErr && (targetDir === curDir))) { + const caughtErr = ['EACCES', 'EPERM', 'EISDIR'].indexOf(err.code) > -1; + if (!caughtErr || (caughtErr && targetDir === curDir)) { throw err; // Throw if it's just the last created dir. } } @@ -936,7 +1035,7 @@ module.exports.mkDirByPathSync = (targetDir, }, initDir); }; -module.exports.performWindowsUninstall = names => { +module.exports.performWindowsUninstall = (names) => { return new Promise((resolve, reject) => { if (os.platform() !== 'win32') { reject('Windows OS is not being used'); @@ -944,58 +1043,58 @@ module.exports.performWindowsUninstall = names => { const cmd = path.join(process.env.windir, 'system32', 'reg.exe'); const args = [ 'QUERY', - 'HKLM\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall' + IS_64BIT + ? 'HKLM\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall' + : 'HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall', ]; _execProcessGetOutput(cmd, null, args) - .then(lines => { - const parseLine = index => { - if (index < lines.length) { - const line = lines[index]; - if (line.startsWith('HKEY_LOCAL_MACHINE\\')) { - let args2 = JSON.parse(JSON.stringify(args)); - args2[1] = 'HKLM\\' + line.substr(19); - args2.push('/v'); - args2.push('DisplayName'); - args2.push('/t'); - args2.push('REG_SZ'); - _execProcessGetOutput(cmd, null, args2) - .then(lines => { - const value = lines[2] - .trim() - .substr(args2[3].length) - .trim() - .substr(6) - .trim(); - if (names.includes(value)) { - const items = line.split('\\'); - const productCode = items[items.length - 1]; - _executeProcess('msiexec.exe', null, - [ '/x', productCode, '/norestart' ]) - .then(code => { - if ((code === 0) || (code === 3010) || - (code === 1641)) { - resolve(true); - } else { - reject('[' + value + - '] uninstall failed: ' + code); - } - }) - .catch(err => { reject(err); }); - } else { - parseLine(++index); - } - }) - .catch(() => { parseLine(++index); }); + .then((lines) => { + const parseLine = (index) => { + if (index < lines.length) { + const line = lines[index]; + if (line.startsWith('HKEY_LOCAL_MACHINE\\')) { + let args2 = JSON.parse(JSON.stringify(args)); + args2[1] = 'HKLM\\' + line.substr(19); + args2.push('/v'); + args2.push('DisplayName'); + args2.push('/t'); + args2.push('REG_SZ'); + _execProcessGetOutput(cmd, null, args2) + .then((lines) => { + const value = lines[2].trim().substr(args2[3].length).trim().substr(6).trim(); + if (names.includes(value)) { + const items = line.split('\\'); + const productCode = items[items.length - 1]; + _executeProcess('msiexec.exe', null, ['/x', productCode, '/norestart']) + .then((code) => { + if (code === 0 || code === 3010 || code === 1641) { + resolve(true); + } else { + reject('[' + value + '] uninstall failed: ' + code); + } + }) + .catch((err) => { + reject(err); + }); } else { parseLine(++index); } - } else { - resolve(false); - } - }; - parseLine(0); - }) - .catch(err => { reject(err); }); + }) + .catch(() => { + parseLine(++index); + }); + } else { + parseLine(++index); + } + } else { + resolve(false); + } + }; + parseLine(0); + }) + .catch((err) => { + reject(err); + }); } }); }; @@ -1004,46 +1103,78 @@ module.exports.removeDirectoryRecursively = _removeDirectoryRecursively; module.exports.resolvePath = _resolvePath; -module.exports.setConfigValue = - (name, value, provider, remote, s3, version) => { - return new Promise((resolve, reject) => { - const repertoryExec = _getRepertoryExec(version); - const processOptions = { - cwd : repertoryExec.working, - detached : true, - shell : false, - windowsHide : true, - }; - - const args = _getDefaultRepertoryArgs(provider, remote, s3); - args.push('-set'); - args.push(name); - args.push(value); - - const process = new spawn(repertoryExec.cmd, args, processOptions); - - process.on('error', (err) => { reject(err); }); - - process.on('exit', code => { - if (code !== 0) { - reject(new Error('Failed to set configuration value: ' + code)); - } else { - resolve(); - } - }); - - process.unref(); - }); +module.exports.setConfigValue = (name, value, provider, remote, s3, version) => { + return new Promise((resolve, reject) => { + const repertoryExec = _getRepertoryExec(version); + const processOptions = { + cwd: repertoryExec.working, + detached: true, + shell: false, + windowsHide: true, }; + const args = _getDefaultRepertoryArgs(provider, remote, s3); + args.push('-set'); + args.push(name); + args.push(value); + + const process = new spawn(repertoryExec.cmd, args, processOptions); + + process.on('error', (err) => { + reject(err); + }); + + process.on('exit', (code) => { + if (code !== 0) { + reject(new Error('Failed to set configuration value: ' + code)); + } else { + resolve(); + } + }); + + process.unref(); + }); +}; + +module.exports.testSkynetLogon = (version, authURL, authUser, authPassword, agentString, apiKey) => { + return new Promise((resolve, reject) => { + const repertoryExec = _getRepertoryExec(version); + const processOptions = { + cwd: repertoryExec.working, + detached: true, + shell: false, + windowsHide: true, + }; + + const args = _getDefaultRepertoryArgs('Skynet'); + args.push('-tsa'); + args.push(authURL); + args.push(authUser); + args.push(authPassword); + args.push(agentString || ''); + args.push(apiKey || ''); + + const process = new spawn(repertoryExec.cmd, args, processOptions); + process.on('error', (err) => { + reject(err); + }); + + process.on('exit', (code) => { + resolve(code === 0); + }); + + process.unref(); + }); +}; + module.exports.stopMountProcess = (version, provider, remote, s3) => { return new Promise((resolve, reject) => { const repertoryExec = _getRepertoryExec(version); const processOptions = { - cwd : repertoryExec.working, - detached : os.platform() === 'darwin', - shell : os.platform() !== 'darwin', - windowsHide : true, + cwd: repertoryExec.working, + detached: os.platform() === 'darwin', + shell: os.platform() !== 'darwin', + windowsHide: true, }; const args = _getDefaultRepertoryArgs(provider, remote, s3); @@ -1051,11 +1182,13 @@ module.exports.stopMountProcess = (version, provider, remote, s3) => { const process = new spawn(repertoryExec.cmd, args, processOptions); const pid = process.pid; - process.on('error', (err) => { reject(err); }); + process.on('error', (err) => { + reject(err); + }); process.on('exit', (code) => { resolve({ - PID : pid, - Code : code, + PID: pid, + Code: code, }); }); @@ -1068,10 +1201,10 @@ module.exports.stopMountProcess = (version, provider, remote, s3) => { module.exports.stopMountProcessSync = (version, provider, remote, s3) => { const repertoryExec = _getRepertoryExec(version); const processOptions = { - cwd : repertoryExec.working, - detached : true, - shell : os.platform() !== 'darwin', - windowsHide : true, + cwd: repertoryExec.working, + detached: true, + shell: os.platform() !== 'darwin', + windowsHide: true, }; const args = _getDefaultRepertoryArgs(provider, remote, s3); @@ -1081,18 +1214,20 @@ module.exports.stopMountProcessSync = (version, provider, remote, s3) => { process.unref(); }; -module.exports.testRepertoryBinary = version => { +module.exports.testRepertoryBinary = (version) => { return new Promise((resolve, reject) => { const repertoryExec = _getRepertoryExec(version); - _executeProcess(repertoryExec.cmd, repertoryExec.working, [ '-dc' ]) - .then(code => { - if (code === 0) { - resolve(); - } else { - reject(new Error('Invalid exit code: ' + code)); - } - }) - .catch(error => { reject(error); }); + _executeProcess(repertoryExec.cmd, repertoryExec.working, ['-dc']) + .then((code) => { + if (code === 0) { + resolve(); + } else { + reject(new Error('Invalid exit code: ' + code)); + } + }) + .catch((error) => { + reject(error); + }); }); }; @@ -1103,12 +1238,12 @@ module.exports.verifyHash = (file, hash) => { let args; if (platform === 'darwin') { command = 'shasum'; - args = [ '-b', '-a', '256', file ]; + args = ['-b', '-a', '256', file]; } else if (platform === 'linux') { command = 'sha256sum'; - args = [ '-b', file, '-z' ]; + args = ['-b', file, '-z']; } else { - reject(new Error('Platform not supported: ' + os.platform())) + reject(new Error('Platform not supported: ' + os.platform())); } if (command) { execFile(command, args, (err, stdout) => { @@ -1129,27 +1264,27 @@ module.exports.verifyHash = (file, hash) => { module.exports.verifySignature = (file, signatureFile, publicKeyFile) => { return new Promise((resolve, reject) => { - const executeVerify = openssl => { - execFile(openssl, - [ - 'dgst', '-sha256', '-verify', publicKeyFile, '-signature', - signatureFile, file - ], - (err, stdout) => { - if (err) { - reject(err); - } else { - resolve(stdout); - } - }); + const executeVerify = (openssl) => { + execFile( + openssl, + ['dgst', '-sha256', '-verify', publicKeyFile, '-signature', signatureFile, file], + (err, stdout) => { + if (err) { + reject(err); + } else { + resolve(stdout); + } + }, + ); }; if (os.platform() === 'win32') { const Registry = require('winreg'); const regKey = new Registry({ - hive : Registry.HKLM, - key : - 'SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (64-bit)_is1' + hive: Registry.HKLM, + key: IS_64BIT + ? 'SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (64-bit)_is1' + : 'SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (32-bit)_is1', }); regKey.valueExists('InstallLocation', (err, exists) => { if (err) { @@ -1169,7 +1304,7 @@ module.exports.verifySignature = (file, signatureFile, publicKeyFile) => { } else if (os.platform() === 'linux') { executeVerify('openssl'); } else { - reject(new Error('Platform not supported: ' + os.platform())) + reject(new Error('Platform not supported: ' + os.platform())); } }); }; diff --git a/src/helpers.test.js b/src/helpers.test.js index bbeeba6..6b547c8 100644 --- a/src/helpers.test.js +++ b/src/helpers.test.js @@ -8,28 +8,30 @@ test('verify signature success', () => { .verifySignature( path.resolve('test/test_verify_signature.dat'), path.resolve('test/test_verify_signature.dat.sig'), - path.resolve('blockstorage_dev_public.pem')) - .then(stdout => { + path.resolve('blockstorage_dev_public.pem') + ) + .then((stdout) => { expect(stdout).toBeDefined(); }); }); test('verify signature fail', () => { - return expect(helpers - .verifySignature( + return expect( + helpers.verifySignature( path.resolve('test/test_verify_signature_fail.dat'), path.resolve('test/test_verify_signature.dat.sig'), - path.resolve('blockstorage_dev_public.pem'))) - .rejects - .toThrow() + path.resolve('blockstorage_dev_public.pem') + ) + ).rejects.toThrow(); }); test('create temp signature files', () => { - const b64signature = fs.readFileSync(path.resolve('test/test_create_signature.sig.b64'), {encoding: 'utf8'}).replace(/(\r\n|\n|\r)/gm,""); - const data = helpers - .createSignatureFiles( - b64signature, - Constants.DEV_PUBLIC_KEY); + const b64signature = fs + .readFileSync(path.resolve('test/test_create_signature.sig.b64'), { + encoding: 'utf8', + }) + .replace(/(\r\n|\n|\r)/gm, ''); + const data = helpers.createSignatureFiles(b64signature, Constants.DEV_PUBLIC_KEY); expect(data).toBeDefined(); expect(data.PublicKeyFile).toBeDefined(); expect(data.SignatureFile).toBeDefined(); @@ -37,22 +39,33 @@ test('create temp signature files', () => { expect(fs.statSync(data.SignatureFile).isFile()).toBe(true); expect(fs.statSync(data.PublicKeyFile).isFile()).toBe(true); - const b64signature2 = fs.readFileSync(data.SignatureFile).toString('base64').replace(/(\r\n|\n|\r)/gm,""); + const b64signature2 = fs + .readFileSync(data.SignatureFile) + .toString('base64') + .replace(/(\r\n|\n|\r)/gm, ''); expect(b64signature2).toEqual(b64signature); - expect(fs.readFileSync(data.PublicKeyFile, {encoding: 'utf8'})).toEqual(Constants.DEV_PUBLIC_KEY); + expect(fs.readFileSync(data.PublicKeyFile, { encoding: 'utf8' })).toEqual( + Constants.DEV_PUBLIC_KEY + ); fs.unlinkSync(data.PublicKeyFile); fs.unlinkSync(data.SignatureFile); }); -test('verify sha56 success', ()=> { - const hash = fs.readFileSync('test/test_verify_sha256.dat.sha256', {encoding: 'utf8'}); - return expect(helpers.verifyHash(path.resolve('test/test_verify_sha256.dat'), hash)) - .resolves.toBe(hash) +test('verify sha56 success', () => { + const hash = fs.readFileSync('test/test_verify_sha256.dat.sha256', { + encoding: 'utf8', + }); + return expect( + helpers.verifyHash(path.resolve('test/test_verify_sha256.dat'), hash) + ).resolves.toBe(hash); }); -test('verify sha56 fail', ()=> { - const hash = fs.readFileSync('test/test_verify_sha256.dat.sha256', {encoding: 'utf8'}); - return expect(helpers.verifyHash(path.resolve('test/test_verify_sha256_fail.dat'), hash)) - .rejects.toThrow(); -}); \ No newline at end of file +test('verify sha56 fail', () => { + const hash = fs.readFileSync('test/test_verify_sha256.dat.sha256', { + encoding: 'utf8', + }); + return expect( + helpers.verifyHash(path.resolve('test/test_verify_sha256_fail.dat'), hash) + ).rejects.toThrow(); +}); diff --git a/src/index.css b/src/index.css index 2d99227..d3669bf 100644 --- a/src/index.css +++ b/src/index.css @@ -6,7 +6,7 @@ --control_border: 1px solid rgba(80, 80, 90, 0.9); --control_box_shadow: 2px 2px 2px black; --control_transparent_background: rgba(10, 10, 16, 0.5); - --control_dark_transparent_background: rgba(10, 10, 16, 0.7); + --control_dark_transparent_background: rgba(10, 10, 16, 0.75); --text_color: rgba(200, 200, 240, 0.65); --text_color_hover: rgba(200, 200, 225, 0.65); @@ -35,7 +35,8 @@ a { font-weight: bold; } -html, body { +html, +body { height: 100%; width: 100%; margin: 0; @@ -52,7 +53,9 @@ p { text-align: center; } -h1, h2, h3 { +h1, +h2, +h3 { padding: 0; margin: 0; font-weight: bold; @@ -65,7 +68,8 @@ h1 { color: var(--heading_text_color); } -h2, h3 { +h2, +h3 { color: var(--heading_other_text_color); } @@ -81,19 +85,23 @@ p { overflow-y: scroll; } -.scrollable-content, ::-webkit-scrollbar { +.scrollable-content, +::-webkit-scrollbar { width: 8px; height: 8px; } -.scrollable-content, ::-webkit-scrollbar * { +.scrollable-content, +::-webkit-scrollbar * { background: transparent; } -.scrollable-content, ::-webkit-scrollbar-thumb { +.scrollable-content, +::-webkit-scrollbar-thumb { background: var(--control_background_hover) !important; } -.scrollbar-corner, ::-webkit-scrollbar-corner { +.scrollbar-corner, +::-webkit-scrollbar-corner { background: transparent; } diff --git a/src/index.js b/src/index.js index ade35e7..4012d58 100644 --- a/src/index.js +++ b/src/index.js @@ -3,16 +3,16 @@ import 'react-checkbox-tree/lib/react-checkbox-tree.css'; import React from 'react'; import ReactDOM from 'react-dom'; -import {Provider} from 'react-redux'; +import { Provider } from 'react-redux'; import packageJson from '../package.json'; import App from './App.jsx'; -import {setProviderState} from './redux/actions/mount_actions'; -import {setActiveRelease} from './redux/actions/release_version_actions'; +import { setProviderState } from './redux/actions/mount_actions'; +import { setActiveRelease } from './redux/actions/release_version_actions'; import createAppStore from './redux/store/createAppStore'; import * as serviceWorker from './serviceWorker'; -import {getIPCRenderer} from './utils'; +import { getIPCRenderer } from './utils.jsx'; const Constants = require('./constants'); @@ -44,17 +44,17 @@ if (ipcRenderer) { } store.dispatch(setProviderState(provider, state)); } - store.dispatch( - setActiveRelease(result.data.Release, result.data.Version)); + store.dispatch(setActiveRelease(result.data.Release, result.data.Version)); } else { store = createAppStore(platformInfo, packageJson.version, {}); } - ReactDOM.render(( + ReactDOM.render( - - - ), document.getElementById('root')); + + , + document.getElementById('root') + ); serviceWorker.unregister(); }); ipcRenderer.send(Constants.IPC_Get_State); diff --git a/src/redux/actions/common_actions.js b/src/redux/actions/common_actions.js index 3074efc..c3557f5 100644 --- a/src/redux/actions/common_actions.js +++ b/src/redux/actions/common_actions.js @@ -1,31 +1,15 @@ +import { createAction } from '@reduxjs/toolkit'; +import { createResponseDialogAction } from '../utils'; + +export const confirmYesNoAction = createResponseDialogAction('common', 'confirmYesNo'); + import * as Constants from '../../constants'; -import {createAction} from '@reduxjs/toolkit'; -import {getIPCRenderer} from '../../utils'; +import { getIPCRenderer } from '../../utils.jsx'; const ipcRenderer = getIPCRenderer(); -let yesNoResolvers = []; -export const confirmYesNo = title => { - return dispatch => { - return new Promise(resolve => { - dispatch(handleConfirmYesNo(true, title, resolve)); - }); - }; -}; - -export const DISPLAY_CONFIRM_YES_NO = 'common/displayConfirmYesNo'; -const displayConfirmYesNo = (show, title) => { - return { - type: DISPLAY_CONFIRM_YES_NO, - payload: { - show, - title - }, - }; -}; - -export const displaySelectAppPlatform = display => { - return dispatch => { +export const displaySelectAppPlatform = (display) => { + return (dispatch) => { if (display) { dispatch(showWindow()); } @@ -34,69 +18,47 @@ export const displaySelectAppPlatform = display => { }; }; -export const hideConfirmYesNo = confirmed => { - return dispatch => { - dispatch(handleConfirmYesNo(false, confirmed)); - }; -}; - -const handleConfirmYesNo = (show, titleOrConfirmed, resolve) => { - return dispatch => { - if (show) { - yesNoResolvers.push(resolve); - dispatch(displayConfirmYesNo(show, titleOrConfirmed)); - } else { - yesNoResolvers[0](titleOrConfirmed); - yesNoResolvers.splice(0, 1); - dispatch(displayConfirmYesNo(false)); - } - }; -}; - export const NOTIFY_APPLICATION_BUSY = 'common/notifyApplicationBusy'; export const notifyApplicationBusy = (busy, transparent) => { return { type: NOTIFY_APPLICATION_BUSY, - payload: { - busy, - transparent - }, + payload: { busy, transparent }, }; }; export const notifyRebootRequired = createAction('common/notifyRebootRequired'); export const rebootSystem = () => { - return dispatch => { + return (dispatch) => { dispatch(setApplicationReady(false)); if (ipcRenderer) { ipcRenderer.send(Constants.IPC_Reboot_System); } - } + }; }; export const saveState = () => { - return (dispatch, getState) => { + return (_, getState) => { const state = getState(); if (state.common.AppReady) { let currentState = { Release: state.relver.Release, RemoteMounts: state.mounts.RemoteMounts, + S3Mounts: state.mounts.S3Mounts, Version: state.relver.Version, }; const providerList = [ ...Constants.PROVIDER_LIST, ...state.mounts.RemoteMounts, + ...state.mounts.S3Mounts, ]; for (const provider of providerList) { currentState[provider] = state.mounts.ProviderState[provider]; } if (ipcRenderer) { - ipcRenderer.send(Constants.IPC_Save_State, { - State: currentState - }); + ipcRenderer.send(Constants.IPC_Save_State, { State: currentState }); } } }; @@ -106,7 +68,7 @@ export const setAllowMount = createAction('common/setAllowMount'); export const setApplicationReady = createAction('common/setApplicationReady'); export const SET_DISPLAY_SELECT_APPPLATFORM = 'common/displaySelectAppPlatform'; -export const setDisplaySelectAppPlatform = display => { +export const setDisplaySelectAppPlatform = (display) => { return { type: SET_DISPLAY_SELECT_APPPLATFORM, payload: display, @@ -116,14 +78,14 @@ export const setDisplaySelectAppPlatform = display => { export const setLinuxAppPlatform = createAction('common/setLinuxAppPlatform'); export const setRebootRequired = () => { - return dispatch => { + return (dispatch) => { dispatch(showWindow()); dispatch(notifyRebootRequired(true)); }; }; export const showWindow = () => { - return dispatch => { + return () => { if (ipcRenderer) { ipcRenderer.send(Constants.IPC_Show_Window); } @@ -131,7 +93,7 @@ export const showWindow = () => { }; export const shutdownApplication = () => { - return dispatch => { + return (dispatch) => { dispatch(setApplicationReady(false)); if (ipcRenderer) { ipcRenderer.send(Constants.IPC_Shutdown); diff --git a/src/redux/actions/download_actions.js b/src/redux/actions/download_actions.js index 1cbb3a8..492d6a2 100644 --- a/src/redux/actions/download_actions.js +++ b/src/redux/actions/download_actions.js @@ -1,26 +1,21 @@ +import { createAction } from '@reduxjs/toolkit'; + import * as Constants from '../../constants'; -import {createAction} from '@reduxjs/toolkit'; -import {getIPCRenderer} from '../../utils'; -import {notifyError} from './error_actions'; +import { getIPCRenderer } from '../../utils.jsx'; + +import { notifyError } from './error_actions'; import { installAndTestRelease, installDependency, installRelease, - installUpgrade + installUpgrade, } from './install_actions'; export const setAllowDownload = createAction('download/setAllowDownload'); export const SET_DOWNLOAD_BEGIN = 'download/setDownloadBegin'; export const setDownloadBegin = (name, type, url) => { - return { - type: SET_DOWNLOAD_BEGIN, - payload: { - name, - type, - url - } - }; + return { type: SET_DOWNLOAD_BEGIN, payload: { name, type, url } }; }; export const setDownloadEnd = createAction('download/setDownloadEnd'); @@ -32,27 +27,28 @@ export const downloadItem = (name, type, urls, isWinFSP, testVersion, appPlatfor urls = [urls]; } - const downloadComplete = result => { + const downloadComplete = (result) => { if (result.Success) { switch (type) { - case Constants.INSTALL_TYPES.Dependency: - dispatch(installDependency(result.Destination, result.URL, isWinFSP)); - break; - case Constants.INSTALL_TYPES.Release: - dispatch(installRelease(result.Destination)); - break; - case Constants.INSTALL_TYPES.TestRelease: - dispatch(installAndTestRelease(result.Destination, testVersion, appPlatform)); - break; - case Constants.INSTALL_TYPES.Upgrade: - //const info = this.props.LocationsLookup[this.props.AppPlatform][this.props.VersionLookup[this.props.AppPlatform][0]]; - const sha256 = null;//info.sha256; - const signature = null;//info.sig; - dispatch(installUpgrade(result.Destination, sha256, signature, !!result.SkipVerification)); - break; - default: - dispatch(notifyError('Unknown download type: ' + type)); - break; + case Constants.INSTALL_TYPES.Dependency: + dispatch(installDependency(result.Destination, result.URL, isWinFSP)); + break; + case Constants.INSTALL_TYPES.Release: + dispatch(installRelease(result.Destination)); + break; + case Constants.INSTALL_TYPES.TestRelease: + dispatch(installAndTestRelease(result.Destination, testVersion, appPlatform)); + break; + case Constants.INSTALL_TYPES.Upgrade: + // const info = + // this.props.LocationsLookup[this.props.AppPlatform][this.props.VersionLookup[this.props.AppPlatform][0]]; + //const sha256 = null; // info.sha256; + //const signature = null; // info.sig; + dispatch(installUpgrade(result.Destination, null, null, !!result.SkipVerification)); + break; + default: + dispatch(notifyError('Unknown download type: ' + type)); + break; } } else { if (type === Constants.INSTALL_TYPES.TestRelease) { @@ -62,10 +58,10 @@ export const downloadItem = (name, type, urls, isWinFSP, testVersion, appPlatfor } }; - const downloadAtIndex = index => { + const downloadAtIndex = (index) => { const url = urls[index]; const state = getState(); - if ((index > 0) || (!state.download.DownloadActive && state.download.AllowDownload)) { + if (index > 0 || (!state.download.DownloadActive && state.download.AllowDownload)) { const ipcRenderer = getIPCRenderer(); if (ipcRenderer) { dispatch(setDownloadBegin(name, type, url)); @@ -76,7 +72,7 @@ export const downloadItem = (name, type, urls, isWinFSP, testVersion, appPlatfor const downloadFileComplete = (_, arg) => { ipcRenderer.removeListener(Constants.IPC_Download_File_Progress, downloadFileProgress); - if (!arg.data.Success && (++index < urls.length)) { + if (!arg.data.Success && ++index < urls.length) { downloadAtIndex(index); } else { downloadComplete(arg.data); diff --git a/src/redux/actions/error_actions.js b/src/redux/actions/error_actions.js index 0fdcf4c..3ff7316 100644 --- a/src/redux/actions/error_actions.js +++ b/src/redux/actions/error_actions.js @@ -1,7 +1,4 @@ -import { - showWindow, - shutdownApplication -} from './common_actions'; +import { showWindow, shutdownApplication } from './common_actions'; let ErrorActions = []; @@ -36,13 +33,13 @@ export const dismissError = () => { }; export const dismissInfo = () => { - return dispatch => { + return (dispatch) => { dispatch(clearInfo()); }; }; export const notifyError = (msg, critical, callback) => { - return dispatch => { + return (dispatch) => { ErrorActions = [callback, ...ErrorActions]; msg = msg ? msg.toString() : 'Unknown Error'; dispatch(setErrorInfo(msg, critical)); @@ -50,33 +47,23 @@ export const notifyError = (msg, critical, callback) => { }; }; -export const notifyInfo = (title, msg) => { - return dispatch => { +export const notifyInfo = (title, msg, saveToFile, fileName, extension) => { + return (dispatch) => { title = title ? title.toString() : 'Information'; msg = msg ? msg.toString() : ''; - dispatch(setInfo(title, msg)); + dispatch(setInfo(title, msg, saveToFile, fileName, extension)); }; }; export const SET_ERROR_INFO = 'error/setErrorInfo'; export const setErrorInfo = (msg, critical) => { - return { - type: SET_ERROR_INFO, - payload: { - msg, - critical - } - } + return { type: SET_ERROR_INFO, payload: { msg, critical } }; }; - export const SET_INFO = 'error/setInfo'; -export const setInfo = (title, msg) => { +export const setInfo = (title, msg, saveToFile, fileName, extension) => { return { type: SET_INFO, - payload: { - title, - msg - } - } -}; \ No newline at end of file + payload: { title, msg, saveToFile, fileName, extension }, + }; +}; diff --git a/src/redux/actions/host_actions.js b/src/redux/actions/host_actions.js new file mode 100644 index 0000000..5ec5186 --- /dev/null +++ b/src/redux/actions/host_actions.js @@ -0,0 +1,3 @@ +import { createResponseDialogAction } from '../utils'; + +export const addEditHostAction = createResponseDialogAction('host', 'displayAddEditHost'); diff --git a/src/redux/actions/install_actions.js b/src/redux/actions/install_actions.js index d211fe6..b605d4d 100644 --- a/src/redux/actions/install_actions.js +++ b/src/redux/actions/install_actions.js @@ -1,35 +1,34 @@ +import { createAction } from '@reduxjs/toolkit'; + import * as Constants from '../../constants'; -import {createAction} from '@reduxjs/toolkit'; +import { getIPCRenderer, getSelectedVersionFromState } from '../../utils.jsx'; + import { - getIPCRenderer, - getSelectedVersionFromState -} from '../../utils'; -import {notifyError} from './error_actions'; -import {downloadItem, setAllowDownload} from './download_actions'; -import { - loadReleases, - setActiveRelease, - setInstalledVersion, - setReleaseUpgradeAvailable, - setNewReleasesAvailable2, -} from './release_version_actions'; -import { - confirmYesNo, + confirmYesNoAction, displaySelectAppPlatform, setAllowMount, setApplicationReady, setLinuxAppPlatform, setRebootRequired, showWindow, - shutdownApplication + shutdownApplication, } from './common_actions'; -import {unmountAll} from './mount_actions'; +import { downloadItem, setAllowDownload } from './download_actions'; +import { notifyError } from './error_actions'; +import { unmountAll } from './mount_actions'; +import { + loadReleases, + setActiveRelease, + setInstalledVersion, + setNewReleasesAvailable2, + setReleaseUpgradeAvailable, +} from './release_version_actions'; const ipcRenderer = getIPCRenderer(); export const checkInstalled = (dependencies, version) => { return (dispatch, getState) => { - const checkInstalledComplete = (event, arg) => { + const checkInstalledComplete = (_, arg) => { const result = arg.data; const updateState = () => { const installedVersion = result.Success && result.Exists ? result.Version : 'none'; @@ -40,7 +39,8 @@ export const checkInstalled = (dependencies, version) => { let upgradeAvailable = false; if (installedVersion !== 'none') { - const latestVersion = state.relver.VersionLookup[Constants.RELEASE_TYPES[release]].length - 1; + const latestVersion = + state.relver.VersionLookup[Constants.RELEASE_TYPES[release]].length - 1; if (version === -1) { version = latestVersion; dispatch(setActiveRelease(release, version)); @@ -57,11 +57,13 @@ export const checkInstalled = (dependencies, version) => { const autoInstallRelease = getState().install.AutoInstallRelease; dispatch(setAutoInstallRelease(false)); - if (result.Dependencies && (result.Dependencies.length > 0)) { + if (result.Dependencies && result.Dependencies.length > 0) { dispatch(showWindow()); - } else if ((installedVersion === 'none') && autoInstallRelease) { + } else if (installedVersion === 'none' && autoInstallRelease) { dispatch(setAllowMount(false)); - const versionString = getState().relver.VersionLookup[Constants.RELEASE_TYPES[release]][version]; + const versionString = getState().relver.VersionLookup[Constants.RELEASE_TYPES[release]][ + version + ]; const urls = getState().relver.LocationsLookup[versionString].urls; const fileName = versionString + '.zip'; dispatch(downloadItem(fileName, Constants.INSTALL_TYPES.Release, urls)); @@ -89,9 +91,12 @@ export const checkVersionInstalled = () => { dispatch(setAllowDownload(false)); const selectedVersion = getSelectedVersionFromState(state); - if (selectedVersion && (selectedVersion !== 'unavailable')) { + if (selectedVersion && selectedVersion !== 'unavailable') { let dependencies = []; - if (state.relver.LocationsLookup[selectedVersion] && state.relver.LocationsLookup[selectedVersion].dependencies) { + if ( + state.relver.LocationsLookup[selectedVersion] && + state.relver.LocationsLookup[selectedVersion].dependencies + ) { dependencies = state.relver.LocationsLookup[selectedVersion].dependencies; } dispatch(checkInstalled(dependencies, selectedVersion)); @@ -107,9 +112,9 @@ export const installDependency = (source, url, isWinFSP) => { if (ipcRenderer && !getState().install.InstallActive) { dispatch(setInstallActive(Constants.INSTALL_TYPES.Dependency)); - const installDependencyComplete = (event, arg) => { + const installDependencyComplete = (_, arg) => { const result = arg.data; - const handleCompleted = ()=> { + const handleCompleted = () => { if (result.RebootRequired) { dispatch(setRebootRequired()); } else { @@ -122,10 +127,10 @@ export const installDependency = (source, url, isWinFSP) => { }; if (result.Success && source.toLowerCase().endsWith('.dmg')) { - const dep = getState().install.MissingDependencies.find(d => { + const dep = getState().install.MissingDependencies.find((d) => { return d.download === url; }); - const i = setInterval(()=> { + const i = setInterval(() => { const ret = ipcRenderer.sendSync(Constants.IPC_Check_Dependency_Installed + '_sync', { File: dep.file, }); @@ -160,7 +165,7 @@ export const installAndTestRelease = (source, version, appPlatform) => { FilePath: source, }); - ipcRenderer.once(Constants.IPC_Test_Release_Reply, (event, arg) => { + ipcRenderer.once(Constants.IPC_Test_Release_Reply, (_, arg) => { if (arg.data.Success) { ipcRenderer.sendSync(Constants.IPC_Set_Linux_AppPlatform, { AppPlatform: appPlatform, @@ -177,7 +182,7 @@ export const installAndTestRelease = (source, version, appPlatform) => { }); ipcRenderer.send(Constants.IPC_Test_Release, { Version: version, - }) + }); }; ipcRenderer.once(Constants.IPC_Extract_Release_Complete, extractReleaseComplete); @@ -201,26 +206,26 @@ export const installReleaseByVersion = (release, version) => { }; if (getState().mounts.MountsBusy) { - dispatch(confirmYesNo('Unmount all drives?')) - .then(confirmed => { - if (confirmed) { + dispatch(confirmYesNoAction.display(true, null, { title: 'Unmount all drives?' })) + .then(({ changed }) => { + if (changed) { dispatch(unmountAll(install)); } }) - .catch(error => notifyError(error)); + .catch((error) => notifyError(error)); } else { install(); } }; }; -export const installRelease = source => { +export const installRelease = (source) => { return (dispatch, getState) => { if (ipcRenderer && !getState().install.InstallActive) { dispatch(setInstallActive(Constants.INSTALL_TYPES.Release)); const version = getSelectedVersionFromState(getState()); - const extractReleaseComplete = (event, arg) => { + const extractReleaseComplete = (_, arg) => { ipcRenderer.send(Constants.IPC_Delete_File, { FilePath: source, }); @@ -249,19 +254,26 @@ export const installUpgrade = (source, sha256, signature, skipVerification) => { dispatch(setInstallActive(Constants.INSTALL_TYPES.Upgrade)); dispatch(setApplicationReady(false)); - const installUpgradeComplete = (event, arg) => { + const installUpgradeComplete = (_, arg) => { const result = arg.data; if (result.Success) { dispatch(shutdownApplication()); } else { dispatch(setApplicationReady(true)); dispatch(setInstallComplete(result)); - dispatch(notifyError(result.Error, false, () => { - // TODO Prompt to verify - if (result.AllowSkipVerification) { - dispatch(installUpgrade(source, sha256, signature, true)); - } - }, false)); + dispatch( + notifyError( + result.Error, + false, + () => { + // TODO Prompt to verify + if (result.AllowSkipVerification) { + dispatch(installUpgrade(source, sha256, signature, true)); + } + }, + false + ) + ); } }; diff --git a/src/redux/actions/mount_actions.js b/src/redux/actions/mount_actions.js index 18fc6ba..d07e0cc 100644 --- a/src/redux/actions/mount_actions.js +++ b/src/redux/actions/mount_actions.js @@ -1,10 +1,10 @@ -import {createAction} from '@reduxjs/toolkit'; +import { createAction } from '@reduxjs/toolkit'; import * as Constants from '../../constants'; -import {getIPCRenderer} from '../../utils'; +import { getIPCRenderer } from '../../utils.jsx'; -import {confirmYesNo, saveState} from './common_actions'; -import {notifyError} from './error_actions'; +import { confirmYesNoAction, saveState } from './common_actions'; +import { notifyError } from './error_actions'; export const addRemoteMount = (hostNameOrIp, port, token) => { return (dispatch, getState) => { @@ -23,18 +23,17 @@ export const addRemoteMount = (hostNameOrIp, port, token) => { Version: getState().relver.InstalledVersion, }); } else { - dispatch( - notifyError('Failed to set \'RemoteToken\': ' + arg.data.Error)); + dispatch(notifyError('Failed to create remote mount: ' + arg.data.Error)); dispatch(setBusy(false)); } }); ipcRenderer.send(Constants.IPC_Set_Config_Values, { Items: [ - {Name: 'RemoteMount.RemoteHostNameOrIp', Value: hostNameOrIp}, - {Name: 'RemoteMount.RemoteToken', Value: token}, - {Name: 'RemoteMount.RemotePort', Value: port}, - {Name: 'RemoteMount.IsRemoteMount', Value: 'true'}, + { Name: 'RemoteMount.RemoteHostNameOrIp', Value: hostNameOrIp }, + { Name: 'RemoteMount.RemoteToken', Value: token }, + { Name: 'RemoteMount.RemotePort', Value: port.toString() }, + { Name: 'RemoteMount.IsRemoteMount', Value: 'true' }, ], Provider: provider, Remote: true, @@ -59,19 +58,18 @@ export const addS3Mount = (name, accessKey, secretKey, region, bucketName, url) Version: getState().relver.InstalledVersion, }); } else { - dispatch( - notifyError('Failed to create S3 instance: ' + arg.data.Error)); + dispatch(notifyError('Failed to create S3 instance: ' + arg.data.Error)); dispatch(setBusy(false)); } }); ipcRenderer.send(Constants.IPC_Set_Config_Values, { Items: [ - {Name: 'S3Config.AccessKey', Value: accessKey}, - {Name: 'S3Config.SecretKey', Value: secretKey}, - {Name: 'S3Config.Region', Value: region}, - {Name: 'S3Config.BucketName', Value: bucketName}, - {Name: 'S3Config.URL', Value: url}, + { Name: 'S3Config.AccessKey', Value: accessKey }, + { Name: 'S3Config.SecretKey', Value: secretKey }, + { Name: 'S3Config.Region', Value: region }, + { Name: 'S3Config.BucketName', Value: bucketName }, + { Name: 'S3Config.URL', Value: url }, ], Provider: provider, S3: true, @@ -95,20 +93,23 @@ export const displayConfiguration = (provider, remote, s3) => { }; }; -export const removeMount = provider => { - return dispatch => { +export const removeMount = (provider) => { + return (dispatch) => { const isRemote = provider.startsWith('Remote'); - dispatch(confirmYesNo('Delete [' + provider.substr(isRemote ? 6 : 2) + ']?')) - .then(confirmed => { - if (confirmed) { + dispatch( + confirmYesNoAction.display(true, null, { + title: 'Delete [' + provider.substr(isRemote ? 6 : 2) + ']?', + }) + ).then(({ changed }) => { + if (changed) { dispatch(removeMount2(provider)); } }); }; }; -const removeMount2 = provider => { - return dispatch => { +const removeMount2 = (provider) => { + return (dispatch) => { const ipcRenderer = getIPCRenderer(); ipcRenderer.once(Constants.IPC_Remove_Mount_Reply, (_, arg) => { if (arg.data.Success) { @@ -119,7 +120,7 @@ const removeMount2 = provider => { const isRemote = provider.startsWith('Remote'); ipcRenderer.send(Constants.IPC_Remove_Mount, { Remote: isRemote, - Name: provider.substr(isRemote ? 6 : 2) + Name: provider.substr(isRemote ? 6 : 2), }); }; }; @@ -128,44 +129,38 @@ export const removeMount3 = createAction('mounts/removeMount3'); export const RESET_MOUNTS_STATE = 'mounts/resetMountsState'; export const resetMountsState = () => { - return {type: RESET_MOUNTS_STATE, payload: null,} + return { type: RESET_MOUNTS_STATE, payload: null }; }; export const SET_ALLOW_MOUNT = 'mounts/setAllowMount'; -export const setAllowMount = - (provider, - allow) => { - return {type: SET_ALLOW_MOUNT, payload: {provider, allow}}; - }; +export const setAllowMount = (provider, allow) => { + return { type: SET_ALLOW_MOUNT, payload: { provider, allow } }; +}; export const SET_AUTO_MOUNT_PROCESSED = 'mounts/setAutoMountProcessed'; export const setAutoMountProcessed = (provider, processed) => { - return {type: SET_AUTO_MOUNT_PROCESSED, payload: {provider, processed}}; + return { type: SET_AUTO_MOUNT_PROCESSED, payload: { provider, processed } }; }; export const setBusy = createAction('mounts/setBusy'); export const SET_MOUNT_STATE = 'mounts/setMountState'; -export const setMountState = - (provider, - state) => { - return {type: SET_MOUNT_STATE, payload: {provider, state}}; - }; +export const setMountState = (provider, state) => { + return { type: SET_MOUNT_STATE, payload: { provider, state } }; +}; export const SET_MOUNTED = 'mounts/setMounted'; -export const setMounted = - (provider, - mounted) => { - return {type: SET_MOUNTED, payload: {provider, mounted}}; - }; +export const setMounted = (provider, mounted) => { + return { type: SET_MOUNTED, payload: { provider, mounted } }; +}; export const SET_PROVIDER_STATE = 'mounts/setProviderState'; export const setProviderState = (provider, state) => { - return {type: SET_PROVIDER_STATE, payload: {provider, state}} + return { type: SET_PROVIDER_STATE, payload: { provider, state } }; }; -export const unmountAll = completedCallback => { - return dispatch => { +export const unmountAll = (completedCallback) => { + return (dispatch) => { const ipcRenderer = getIPCRenderer(); const unmountedCallback = () => { dispatch(resetMountsState()); @@ -173,5 +168,5 @@ export const unmountAll = completedCallback => { }; ipcRenderer.once(Constants.IPC_Unmount_All_Drives_Reply, unmountedCallback); ipcRenderer.send(Constants.IPC_Unmount_All_Drives); - } + }; }; diff --git a/src/redux/actions/pinned_manager_actions.js b/src/redux/actions/pinned_manager_actions.js index e93252b..a6989dd 100644 --- a/src/redux/actions/pinned_manager_actions.js +++ b/src/redux/actions/pinned_manager_actions.js @@ -1,4 +1,3 @@ -import {createAction} from '@reduxjs/toolkit'; +import { createAction } from '@reduxjs/toolkit'; export const displayPinnedManager = createAction('pinned/displayPinnedManager'); - diff --git a/src/redux/actions/release_version_actions.js b/src/redux/actions/release_version_actions.js index c12c839..912290a 100644 --- a/src/redux/actions/release_version_actions.js +++ b/src/redux/actions/release_version_actions.js @@ -1,23 +1,18 @@ +import { createAction } from '@reduxjs/toolkit'; import axios from 'axios'; + import * as Constants from '../../constants'; -import {createAction} from '@reduxjs/toolkit'; -import {notifyError} from './error_actions'; -import { - saveState, - setAllowMount, - setApplicationReady, - showWindow -} from './common_actions'; -import { - checkVersionInstalled, - setDismissDependencies -} from './install_actions'; -import {unmountAll} from './mount_actions'; import { checkNewReleases, getIPCRenderer, - getNewReleases, getSelectedVersionFromState -} from '../../utils'; + getNewReleases, + getSelectedVersionFromState, +} from '../../utils.jsx'; + +import { saveState, setAllowMount, setApplicationReady, showWindow } from './common_actions'; +import { notifyError } from './error_actions'; +import { checkVersionInstalled, setDismissDependencies } from './install_actions'; +import { unmountAll } from './mount_actions'; export const CLEAR_UI_UPGRADE = 'relver/clearUIUpgrade'; export const clearUIUpgrade = () => { @@ -27,12 +22,12 @@ export const clearUIUpgrade = () => { }; }; -const cleanupOldReleases = versionList => { - return dispatch => { +const cleanupOldReleases = (versionList) => { + return () => { const ipcRenderer = getIPCRenderer(); if (ipcRenderer) { ipcRenderer.sendSync(Constants.IPC_Cleanup_Releases + '_sync', { - version_list: versionList + version_list: versionList, }); } }; @@ -42,32 +37,40 @@ export const detectUIUpgrade = () => { return (dispatch, getState) => { axios .get(Constants.UI_RELEASES_URL) - .then(response => { + .then((response) => { const state = getState(); const appPlatform = state.common.AppPlatform; const version = state.common.Version; const data = response.data; - if (data.Versions && + if ( + data.Versions && data.Versions[appPlatform] && - (data.Versions[appPlatform].length > 0) && - (data.Versions[appPlatform][0] !== version)) { - dispatch(setUIUpgradeData(data.Locations[appPlatform][data.Versions[appPlatform][0]], data.Versions[appPlatform][0])); + data.Versions[appPlatform].length > 0 && + data.Versions[appPlatform][0] !== version + ) { + dispatch( + setUIUpgradeData( + data.Locations[appPlatform][data.Versions[appPlatform][0]], + data.Versions[appPlatform][0] + ) + ); if (!state.relver.UpgradeDismissed) { dispatch(showWindow()); } } else { dispatch(clearUIUpgrade()); } - }).catch(() => { + }) + .catch(() => { dispatch(clearUIUpgrade()); - }); + }); }; }; export const loadReleases = () => { return (dispatch, getState) => { - const dispatchActions = (locationsLookup, versionLookup)=> { + const dispatchActions = (locationsLookup, versionLookup) => { const state = getState().relver; let release = state.Release; if (release >= Constants.RELEASE_TYPES.length) { @@ -78,19 +81,21 @@ export const loadReleases = () => { let version = state.Version; if (versionLookup[Constants.RELEASE_TYPES[release]][0] === 'unavailable') { release = Constants.DEFAULT_RELEASE; - version = latestVersion = versionLookup[Constants.RELEASE_TYPES[release]].length - 1 - } else if ((version === -1) || !versionLookup[Constants.RELEASE_TYPES[release]][version]) { + version = latestVersion = versionLookup[Constants.RELEASE_TYPES[release]].length - 1; + } else if (version === -1 || !versionLookup[Constants.RELEASE_TYPES[release]][version]) { version = latestVersion; } dispatch(setReleaseData(locationsLookup, versionLookup)); const dispatchActions = (processAllowDismiss = true) => { - dispatch(setReleaseUpgradeAvailable((version !== latestVersion))); + dispatch(setReleaseUpgradeAvailable(version !== latestVersion)); dispatch(setApplicationReady(true)); dispatch(detectUIUpgrade()); if (processAllowDismiss) { - dispatch(setAllowDismissDependencies(versionLookup[Constants.RELEASE_TYPES[release]].length > 1)); + dispatch( + setAllowDismissDependencies(versionLookup[Constants.RELEASE_TYPES[release]].length > 1) + ); } dispatch(checkVersionInstalled()); @@ -98,16 +103,18 @@ export const loadReleases = () => { for (const key of Object.keys(locationsLookup)) { versionList.push(key); } - dispatch(cleanupOldReleases(versionList)) + dispatch(cleanupOldReleases(versionList)); }; - if ((version !== state.Version) || (release !== state.Release)) { - dispatch(unmountAll(() => { - dispatch(setActiveRelease(release, version)); - dispatchActions(false); - dispatch(showWindow()); - dispatch(saveState()); - })); + if (version !== state.Version || release !== state.Release) { + dispatch( + unmountAll(() => { + dispatch(setActiveRelease(release, version)); + dispatchActions(false); + dispatch(showWindow()); + dispatch(saveState()); + }) + ); } else { dispatchActions(); } @@ -115,7 +122,7 @@ export const loadReleases = () => { axios .get(Constants.RELEASES_URL) - .then(response => { + .then((response) => { const appPlatform = getState().common.AppPlatform; const versionLookup = { Release: response.data.Versions.Release[appPlatform], @@ -129,14 +136,21 @@ export const loadReleases = () => { const storedReleases = localStorage.getItem('releases'); let newReleases = []; - if (storedReleases && (storedReleases.length > 0)) { - newReleases = getNewReleases(JSON.parse(storedReleases).VersionLookup, versionLookup, getSelectedVersionFromState(getState())); + if (storedReleases && storedReleases.length > 0) { + newReleases = getNewReleases( + JSON.parse(storedReleases).VersionLookup, + versionLookup, + getSelectedVersionFromState(getState()) + ); } - localStorage.setItem('releases', JSON.stringify({ - LocationsLookup: locationsLookup, - VersionLookup: versionLookup - })); + localStorage.setItem( + 'releases', + JSON.stringify({ + LocationsLookup: locationsLookup, + VersionLookup: versionLookup, + }) + ); dispatchActions(locationsLookup, versionLookup); dispatch(setNewReleasesAvailable(newReleases)); @@ -144,12 +158,15 @@ export const loadReleases = () => { dispatch(setNewReleasesAvailable2(newReleases)); localStorage.setItem('previous_releases', storedReleases); dispatch(showWindow()); - } else if ((newReleases = checkNewReleases(getSelectedVersionFromState(getState()))).length > 0) { + } else if ( + (newReleases = checkNewReleases(getSelectedVersionFromState(getState()))).length > 0 + ) { dispatch(setNewReleasesAvailable2(newReleases)); } - }).catch(error => { + }) + .catch((error) => { const releases = localStorage.getItem('releases'); - if (releases && (releases.length > 0)) { + if (releases && releases.length > 0) { const obj = JSON.parse(releases); const locationsLookup = obj.LocationsLookup; const versionLookup = obj.VersionLookup; @@ -166,10 +183,7 @@ export const NOTIFY_ACTIVE_RELEASE = 'relver/notifyActiveRelease'; export const notifyActiveRelease = (release, version) => { return { type: NOTIFY_ACTIVE_RELEASE, - payload: { - release: release, - version: version - }, + payload: { release: release, version: version }, }; }; @@ -183,7 +197,7 @@ export const setActiveRelease = (release, version) => { version = -1; } const versions = relver.VersionLookup[Constants.RELEASE_TYPES[release]]; - dispatch(setAllowDismissDependencies(versions && (versions.length > 1))); + dispatch(setAllowDismissDependencies(versions && versions.length > 1)); dispatch(setDismissDependencies(false)); dispatch(notifyActiveRelease(release, version)); if (common.AppReady) { @@ -200,14 +214,14 @@ export const setNewReleasesAvailable = createAction('relver/setNewReleasesAvaila export const setNewReleasesAvailable2 = createAction('relver/setNewReleasesAvailable2'); export const SET_RELEASE_DATA = 'relver/setReleaseData'; -export const setReleaseData = (locationsLookup, versionLookup)=> { +export const setReleaseData = (locationsLookup, versionLookup) => { return { type: SET_RELEASE_DATA, payload: { locations: locationsLookup, versions: versionLookup, - } - } + }, + }; }; export const setReleaseUpgradeAvailable = createAction('relver/setReleaseUpgradeAvailable'); @@ -219,6 +233,6 @@ export const setUIUpgradeData = (upgradeData, version) => { payload: { upgrade_data: upgradeData, version: version, - } - } + }, + }; }; diff --git a/src/redux/actions/skynet_actions.js b/src/redux/actions/skynet_actions.js index e3719fb..048156d 100644 --- a/src/redux/actions/skynet_actions.js +++ b/src/redux/actions/skynet_actions.js @@ -1,4 +1,4 @@ -import {createAction} from '@reduxjs/toolkit'; +import { createAction } from '@reduxjs/toolkit'; export const displaySkynetExport = createAction('skynet/displaySkynetExport'); export const displaySkynetImport = createAction('skynet/displaySkynetImport'); diff --git a/src/redux/reducers/common_reducer.js b/src/redux/reducers/common_reducer.js index cec3735..6efc45a 100644 --- a/src/redux/reducers/common_reducer.js +++ b/src/redux/reducers/common_reducer.js @@ -1,71 +1,66 @@ -import {createReducer} from '@reduxjs/toolkit'; +import { createReducer } from '@reduxjs/toolkit'; import { - DISPLAY_CONFIRM_YES_NO, + confirmYesNoAction, NOTIFY_APPLICATION_BUSY, notifyRebootRequired, + SET_DISPLAY_SELECT_APPPLATFORM, setAllowMount, setApplicationReady, setLinuxAppPlatform, - SET_DISPLAY_SELECT_APPPLATFORM } from '../actions/common_actions'; export const createCommonReducer = (platformInfo, version) => { - return createReducer({ - AllowMount: false, - AppBusy: false, - AppBusyTransparent: false, - AppPlatform: platformInfo.AppPlatform, - AppReady: false, - DisplayConfirmYesNo: false, - ConfirmTitle: null, - DisplaySelectAppPlatform: false, - Platform: platformInfo.Platform, - RebootRequired: false, - Version: version, - }, { - [DISPLAY_CONFIRM_YES_NO]: (state, action) => { - return { - ...state, - DisplayConfirmYesNo: action.payload.show, - ConfirmTitle: action.payload.show ? action.payload.title : null, - } + return createReducer( + { + AllowMount: false, + AppBusy: false, + AppBusyTransparent: false, + AppPlatform: platformInfo.AppPlatform, + AppReady: false, + DisplayConfirmYesNo: false, + ConfirmTitle: null, + DisplaySelectAppPlatform: false, + Platform: platformInfo.Platform, + RebootRequired: false, + Version: version, }, - [SET_DISPLAY_SELECT_APPPLATFORM]: (state, action) => { - return { - ...state, - DisplaySelectAppPlatform: action.payload, - } - }, - [setAllowMount]: (state, action) => { - return { - ...state, - AllowMount: action.payload, - } - }, - [setApplicationReady]: (state, action) => { - return { - ...state, - AppReady: action.payload, - }; - }, - [setLinuxAppPlatform]: (state, action) => { - return { - ...state, - AppPlatform: action.payload, - } - }, - [NOTIFY_APPLICATION_BUSY]: (state, action) => { - return { - ...state, - AppBusy: action.payload.busy, - AppBusyTransparent: action.payload.busy && action.payload.transparent, - }; - }, - [notifyRebootRequired]: (state, action) => { - return { - ...state, - RebootRequired: action.payload, - }; - }, - }); + { + [confirmYesNoAction.action_type]: (state, action) => { + return { + ...state, + DisplayConfirmYesNo: action.payload.display, + ConfirmTitle: + action.payload.display && action.payload.data ? action.payload.data.title : null, + }; + }, + [SET_DISPLAY_SELECT_APPPLATFORM]: (state, action) => { + return { ...state, DisplaySelectAppPlatform: action.payload }; + }, + [setAllowMount]: (state, action) => { + return { ...state, AllowMount: action.payload }; + }, + [setApplicationReady]: (state, action) => { + return { + ...state, + AppReady: action.payload, + }; + }, + [setLinuxAppPlatform]: (state, action) => { + return { ...state, AppPlatform: action.payload }; + }, + [NOTIFY_APPLICATION_BUSY]: (state, action) => { + return { + ...state, + AppBusy: action.payload.busy, + AppBusyTransparent: action.payload.busy && action.payload.transparent, + }; + }, + [notifyRebootRequired]: (state, action) => { + return { + ...state, + RebootRequired: action.payload, + }; + }, + } + ); }; diff --git a/src/redux/reducers/download_reducer.js b/src/redux/reducers/download_reducer.js index 4177ff5..6ffde68 100644 --- a/src/redux/reducers/download_reducer.js +++ b/src/redux/reducers/download_reducer.js @@ -1,9 +1,10 @@ -import {createReducer} from '@reduxjs/toolkit'; +import { createReducer } from '@reduxjs/toolkit'; + import { - setAllowDownload, SET_DOWNLOAD_BEGIN, + setAllowDownload, setDownloadEnd, - setDownloadProgress + setDownloadProgress, } from '../actions/download_actions'; const defaultDownloadState = { @@ -17,37 +18,37 @@ const defaultDownloadState = { DownloadType: null, }; -export const downloadReducer = createReducer({ - ...defaultDownloadState, - AllowDownload: false, -}, { - [setAllowDownload]: (state, action) => { - return { - ...state, - AllowDownload: action.payload, - }; +export const downloadReducer = createReducer( + { + ...defaultDownloadState, + AllowDownload: false, }, - [SET_DOWNLOAD_BEGIN]: (state, action) => { - return { - ...state, - ...defaultDownloadState, - DownloadActive: true, - DownloadName: action.payload.name, - DownloadType: action.payload.type, - DownloadURL: action.payload.url, - } - }, - [setDownloadEnd]: (state, action) => { - return { - ...state, - ...defaultDownloadState, - DownloadResult: action.payload, - }; - }, - [setDownloadProgress]: (state, action) => { - return { - ...state, - DownloadProgress: action.payload, - } + { + [setAllowDownload]: (state, action) => { + return { + ...state, + AllowDownload: action.payload, + }; + }, + [SET_DOWNLOAD_BEGIN]: (state, action) => { + return { + ...state, + ...defaultDownloadState, + DownloadActive: true, + DownloadName: action.payload.name, + DownloadType: action.payload.type, + DownloadURL: action.payload.url, + }; + }, + [setDownloadEnd]: (state, action) => { + return { + ...state, + ...defaultDownloadState, + DownloadResult: action.payload, + }; + }, + [setDownloadProgress]: (state, action) => { + return { ...state, DownloadProgress: action.payload }; + }, } -}); +); diff --git a/src/redux/reducers/error_reducer.js b/src/redux/reducers/error_reducer.js index e780dee..15cd243 100644 --- a/src/redux/reducers/error_reducer.js +++ b/src/redux/reducers/error_reducer.js @@ -1,52 +1,52 @@ -import {createReducer} from '@reduxjs/toolkit'; -import { - CLEAR_ERROR, - CLEAR_INFO, - SET_ERROR_INFO, - SET_INFO -} from '../actions/error_actions'; +import { createReducer } from '@reduxjs/toolkit'; +import { CLEAR_ERROR, CLEAR_INFO, SET_ERROR_INFO, SET_INFO } from '../actions/error_actions'; -export const errorReducer = createReducer({ - DisplayError: false, - DisplayInfo: false, - ErrorCritical: false, - ErrorStack: [], - InfoStack: [], -}, { - [CLEAR_ERROR]: state => { - const errorStack = (state.ErrorStack.length > 0) ? state.ErrorStack.slice(1) : []; - return { - ...state, - DisplayError: (errorStack.length > 0), - ErrorStack: errorStack, - } +export const errorReducer = createReducer( + { + DisplayError: false, + DisplayInfo: false, + ErrorCritical: false, + ErrorStack: [], + InfoStack: [], }, - [CLEAR_INFO]: state => { - const infoStack = (state.InfoStack.length > 0) ? state.InfoStack.slice(1) : []; - return { - ...state, - DisplayInfo: (infoStack.length > 0), - InfoStack: infoStack, - } - }, - [SET_ERROR_INFO]: (state, action) => { - const errorStack = [action.payload.msg, ...state.ErrorStack]; - return { - ...state, - DisplayError: true, - ErrorCritical: state.ErrorCritical || action.payload.critical, - ErrorStack: errorStack, - } - }, - [SET_INFO]: (state, action) => { - const infoStack = [{ - title: action.payload.title, - message: action.payload.msg - }, ...state.InfoStack]; - return { - ...state, - DisplayInfo: true, - InfoStack: infoStack, - } + { + [CLEAR_ERROR]: (state) => { + const errorStack = state.ErrorStack.length > 0 ? state.ErrorStack.slice(1) : []; + return { + ...state, + DisplayError: errorStack.length > 0, + ErrorStack: errorStack, + }; + }, + [CLEAR_INFO]: (state) => { + const infoStack = state.InfoStack.length > 0 ? state.InfoStack.slice(1) : []; + return { + ...state, + DisplayInfo: infoStack.length > 0, + InfoStack: infoStack, + }; + }, + [SET_ERROR_INFO]: (state, action) => { + const errorStack = [action.payload.msg, ...state.ErrorStack]; + return { + ...state, + DisplayError: true, + ErrorCritical: state.ErrorCritical || action.payload.critical, + ErrorStack: errorStack, + }; + }, + [SET_INFO]: (state, action) => { + const infoStack = [ + { + title: action.payload.title, + message: action.payload.msg, + saveToFile: action.payload.saveToFile, + fileName: action.payload.fileName, + extension: action.payload.extension, + }, + ...state.InfoStack, + ]; + return { ...state, DisplayInfo: true, InfoStack: infoStack }; + }, } -}); +); diff --git a/src/redux/reducers/host_reducer.js b/src/redux/reducers/host_reducer.js new file mode 100644 index 0000000..ce3eccd --- /dev/null +++ b/src/redux/reducers/host_reducer.js @@ -0,0 +1,20 @@ +import { createReducer } from '@reduxjs/toolkit'; +import { addEditHostAction } from '../actions/host_actions'; + +export const hostReducer = createReducer( + { + DisplayAddEditHost: false, + HostData: {}, + HostList: [], + }, + { + [addEditHostAction.action_type]: (state, action) => { + return { + ...state, + DisplayAddEditHost: action.payload.display, + HostData: action.payload.data ? action.payload.data.host_data || {} : {}, + HostList: action.payload.data ? action.payload.data.host_list || [] : [], + }; + }, + } +); diff --git a/src/redux/reducers/install_reducer.js b/src/redux/reducers/install_reducer.js index 8ec65f7..3981062 100644 --- a/src/redux/reducers/install_reducer.js +++ b/src/redux/reducers/install_reducer.js @@ -1,60 +1,51 @@ -import {createReducer} from '@reduxjs/toolkit'; +import { createReducer } from '@reduxjs/toolkit'; import { setAutoInstallRelease, setDismissDependencies, setInstallActive, setInstallComplete, setInstallTestActive, - setMissingDependencies + setMissingDependencies, } from '../actions/install_actions'; -export const installReducer = createReducer({ - AutoInstallRelease: false, - DismissDependencies: false, - InstallActive: false, - InstallResult: null, - InstallTestActive: false, - InstallType: null, - MissingDependencies: [], -}, { - [setAutoInstallRelease]: (state, action) => { - return { - ...state, - AutoInstallRelease: action.payload, - } +export const installReducer = createReducer( + { + AutoInstallRelease: false, + DismissDependencies: false, + InstallActive: false, + InstallResult: null, + InstallTestActive: false, + InstallType: null, + MissingDependencies: [], }, - [setDismissDependencies]: (state, action) => { - return { - ...state, - DismissDependencies: action.payload, - } - }, - [setInstallActive]: (state, action) => { - return { - ...state, - InstallActive: true, - InstallResult: null, - InstallType: action.payload, - }; - }, - [setInstallComplete]: (state, action) => { - return { - ...state, - InstallActive: false, - InstallResult: action.payload, - InstallType: null, - } - }, - [setInstallTestActive]: (state, action) => { - return { - ...state, - InstallTestActive: action.payload, - } - }, - [setMissingDependencies]: (state, action) => { - return { - ...state, - MissingDependencies: action.payload, - } + { + [setAutoInstallRelease]: (state, action) => { + return { ...state, AutoInstallRelease: action.payload }; + }, + [setDismissDependencies]: (state, action) => { + return { ...state, DismissDependencies: action.payload }; + }, + [setInstallActive]: (state, action) => { + return { + ...state, + InstallActive: true, + InstallResult: null, + InstallType: action.payload, + }; + }, + [setInstallComplete]: (state, action) => { + return { + ...state, + InstallActive: false, + InstallResult: action.payload, + InstallType: null, + }; + }, + [setInstallTestActive]: (state, action) => { + return { ...state, InstallTestActive: action.payload }; + }, + [setMissingDependencies]: (state, action) => { + return { ...state, MissingDependencies: action.payload }; + }, } -}); +); diff --git a/src/redux/reducers/mount_reducer.js b/src/redux/reducers/mount_reducer.js index 8648a76..e96bec2 100644 --- a/src/redux/reducers/mount_reducer.js +++ b/src/redux/reducers/mount_reducer.js @@ -1,4 +1,4 @@ -import {createReducer} from '@reduxjs/toolkit'; +import { createReducer } from '@reduxjs/toolkit'; import * as Constants from '../../constants'; import { @@ -12,49 +12,49 @@ import { SET_MOUNT_STATE, SET_MOUNTED, SET_PROVIDER_STATE, - setBusy + setBusy, } from '../actions/mount_actions'; -export const createMountReducer = state => { +export const createMountReducer = (state) => { let providerList = [ ...Constants.PROVIDER_LIST, ...(state.RemoteMounts || []), ...(state.S3Mounts || []), ]; const providerState = providerList - .map(provider => { - return { - [provider]: { - AutoMount: false, - AutoRestart: false, - MountLocation: '', - } - } - }) - .reduce((map, obj) => { - return {...map, ...obj} - }); - - const mountState = providerList - .map(provider => { - return { - [provider]: { - AllowMount: false, - DriveLetters: [], - Mounted: false, - } - } - }) - .reduce((map, obj) => { - return {...map, ...obj} - }); - - const autoMountProcessed = - providerList.map(provider => { - return {[provider]: false,} + .map((provider) => { + return { + [provider]: { + AutoMount: false, + AutoRestart: false, + MountLocation: '', + }, + }; }) .reduce((map, obj) => { - return {...map, ...obj} + return { ...map, ...obj }; + }); + + const mountState = providerList + .map((provider) => { + return { + [provider]: { + AllowMount: false, + DriveLetters: [], + Mounted: false, + }, + }; + }) + .reduce((map, obj) => { + return { ...map, ...obj }; + }); + + const autoMountProcessed = providerList + .map((provider) => { + return { [provider]: false }; + }) + .reduce((map, obj) => { + return { ...map, ...obj }; }); return createReducer( @@ -71,52 +71,56 @@ export const createMountReducer = state => { }, { [addRemoteMount2]: (state, action) => { - let mountState = {...state.MountState}; + let mountState = { ...state.MountState }; mountState[action.payload] = { AllowMount: false, DriveLetters: [], Mounted: false, }; - let providerState = {...state.ProviderState}; + let providerState = { ...state.ProviderState }; providerState[action.payload] = { AutoMount: false, AutoRestart: false, MountLocation: '', }; - let autoMountProcessed = {...state.AutoMountProcessed}; + let autoMountProcessed = { ...state.AutoMountProcessed }; autoMountProcessed[action.payload] = true; return { - ...state, AutoMountProcessed: autoMountProcessed, - MountState: mountState, ProviderState: providerState, + ...state, + AutoMountProcessed: autoMountProcessed, + MountState: mountState, + ProviderState: providerState, RemoteMounts: [...state.RemoteMounts, action.payload], - } + }; }, [addS3Mount2]: (state, action) => { - let mountState = {...state.MountState}; + let mountState = { ...state.MountState }; mountState[action.payload] = { AllowMount: false, DriveLetters: [], Mounted: false, }; - let providerState = {...state.ProviderState}; + let providerState = { ...state.ProviderState }; providerState[action.payload] = { AutoMount: false, AutoRestart: false, MountLocation: '', }; - let autoMountProcessed = {...state.AutoMountProcessed}; + let autoMountProcessed = { ...state.AutoMountProcessed }; autoMountProcessed[action.payload] = true; return { - ...state, AutoMountProcessed: autoMountProcessed, - MountState: mountState, ProviderState: providerState, + ...state, + AutoMountProcessed: autoMountProcessed, + MountState: mountState, + ProviderState: providerState, S3Mounts: [...state.S3Mounts, action.payload], - } + }; }, [DISPLAY_CONFIGURATION]: (state, action) => { return { @@ -127,19 +131,17 @@ export const createMountReducer = state => { }; }, [removeMount3]: (state, action) => { - let mountState = {...state.MountState}; + let mountState = { ...state.MountState }; delete mountState[action.payload]; - let providerState = {...state.ProviderState}; + let providerState = { ...state.ProviderState }; delete providerState[action.payload]; - let autoMountProcessed = {...state.AutoMountProcessed}; + let autoMountProcessed = { ...state.AutoMountProcessed }; delete autoMountProcessed[action.payload]; - const remoteMounts = - state.RemoteMounts.filter(i => i !== action.payload); - const s3Mounts = - state.S3Mounts.filter(i => i !== action.payload); + const remoteMounts = state.RemoteMounts.filter((i) => i !== action.payload); + const s3Mounts = state.S3Mounts.filter((i) => i !== action.payload); return { ...state, AutoMountProcessed: autoMountProcessed, @@ -149,8 +151,8 @@ export const createMountReducer = state => { S3Mounts: s3Mounts, }; }, - [RESET_MOUNTS_STATE]: (state, action) => { - return {...state, MountsBusy: false, MountState: mountState,} + [RESET_MOUNTS_STATE]: (state) => { + return { ...state, MountsBusy: false, MountState: mountState }; }, [SET_AUTO_MOUNT_PROCESSED]: (state, action) => { return { @@ -158,7 +160,7 @@ export const createMountReducer = state => { AutoMountProcessed: { ...state.AutoMountProcessed, [action.payload.provider]: action.payload.processed, - } + }, }; }, [SET_ALLOW_MOUNT]: (state, action) => { @@ -169,15 +171,13 @@ export const createMountReducer = state => { [action.payload.provider]: { ...state.MountState[action.payload.provider], AllowMount: action.payload.allow, - } - } + }, + }, }; }, - [setBusy]: - (state, - action) => { - return {...state, MountsBusy: action.payload}; - }, + [setBusy]: (state, action) => { + return { ...state, MountsBusy: action.payload }; + }, [SET_MOUNT_STATE]: (state, action) => { return { ...state, @@ -185,9 +185,9 @@ export const createMountReducer = state => { ...state.MountState, [action.payload.provider]: { ...state.MountState[action.payload.provider], - ...action.payload.state + ...action.payload.state, }, - } + }, }; }, [SET_MOUNTED]: (state, action) => { @@ -198,8 +198,8 @@ export const createMountReducer = state => { [action.payload.provider]: { ...state.MountState[action.payload.provider], Mounted: action.payload.mounted, - } - } + }, + }, }; }, [SET_PROVIDER_STATE]: (state, action) => { @@ -209,10 +209,11 @@ export const createMountReducer = state => { ...state.ProviderState, [action.payload.provider]: { ...state.ProviderState[action.payload.provider], - ...action.payload.state + ...action.payload.state, }, - } + }, }; - } - }); + }, + } + ); }; diff --git a/src/redux/reducers/pinned_manager_reducer.js b/src/redux/reducers/pinned_manager_reducer.js index 9893cd4..1a55024 100644 --- a/src/redux/reducers/pinned_manager_reducer.js +++ b/src/redux/reducers/pinned_manager_reducer.js @@ -1,13 +1,16 @@ -import {createReducer} from '@reduxjs/toolkit'; -import {displayPinnedManager} from '../actions/pinned_manager_actions'; +import { createReducer } from '@reduxjs/toolkit'; +import { displayPinnedManager } from '../actions/pinned_manager_actions'; -export const pinnedManagerReducer = createReducer({ - DisplayPinnedManager: false, -}, { - [displayPinnedManager]: (state, action) => { - return { - ...state, - DisplayPinnedManager: action.payload, - }; +export const pinnedManagerReducer = createReducer( + { + DisplayPinnedManager: false, }, -}); + { + [displayPinnedManager]: (state, action) => { + return { + ...state, + DisplayPinnedManager: action.payload, + }; + }, + } +); diff --git a/src/redux/reducers/release_version_reducer.js b/src/redux/reducers/release_version_reducer.js index 77667ac..ffb27e4 100644 --- a/src/redux/reducers/release_version_reducer.js +++ b/src/redux/reducers/release_version_reducer.js @@ -1,11 +1,10 @@ -import {createReducer} from '@reduxjs/toolkit'; -import * as Actions from '../actions/release_version_actions'; -import * as Constants from '../../constants'; +import { createReducer } from '@reduxjs/toolkit'; -const versionLookup = Constants.RELEASE_TYPES.map(k=> { - return { - [k]: ['unavailable'] - }; +import * as Constants from '../../constants'; +import * as Actions from '../actions/release_version_actions'; + +const versionLookup = Constants.RELEASE_TYPES.map((k) => { + return { [k]: ['unavailable'] }; }).reduce((map, obj) => { return { ...map, @@ -13,95 +12,95 @@ const versionLookup = Constants.RELEASE_TYPES.map(k=> { }; }); -export const releaseVersionReducer = createReducer({ - AllowDismissDependencies: false, - DismissNewReleasesAvailable: true, - InstalledVersion: 'none', - LocationsLookup: {}, - NewReleasesAvailable: [], - NewReleasesAvailable2: [], - Release: Constants.DEFAULT_RELEASE, - ReleaseUpgradeAvailable: false, - UpgradeAvailable: false, - UpgradeData: null, - UpgradeVersion: null, - UpgradeDismissed: false, - Version: -1, - VersionLookup: versionLookup, -}, { - [Actions.CLEAR_UI_UPGRADE]: state => { - return { - ...state, - UpgradeAvailable: false, - UpgradeDismissed: false, - UpgradeData: null, - UpgradeVersion: null, - }; +export const releaseVersionReducer = createReducer( + { + AllowDismissDependencies: false, + DismissNewReleasesAvailable: true, + InstalledVersion: 'none', + LocationsLookup: {}, + NewReleasesAvailable: [], + NewReleasesAvailable2: [], + Release: Constants.DEFAULT_RELEASE, + ReleaseUpgradeAvailable: false, + UpgradeAvailable: false, + UpgradeData: null, + UpgradeVersion: null, + UpgradeDismissed: false, + Version: -1, + VersionLookup: versionLookup, }, - [Actions.NOTIFY_ACTIVE_RELEASE]: (state, action) => { - return { - ...state, - Release: action.payload.release, - Version: action.payload.version - }; - }, - [Actions.setAllowDismissDependencies]: (state, action) => { - return { - ...state, - AllowDismissDependencies: action.payload, - }; - }, - [Actions.setDismissNewReleasesAvailable]: (state, action) => { - return { - ...state, - DismissNewReleasesAvailable: action.payload, - }; - }, - [Actions.setDismissUIUpgrade]: (state, action) => { - return { - ...state, - UpgradeDismissed: action.payload, - }; - }, - [Actions.setInstalledVersion]: (state, action) => { - return { - ...state, - InstalledVersion: action.payload, - } - }, - [Actions.setNewReleasesAvailable]: (state, action) => { - return { - ...state, - DismissNewReleasesAvailable: false, - NewReleasesAvailable: action.payload, - }; - }, - [Actions.setNewReleasesAvailable2]: (state, action) => { - return { - ...state, - NewReleasesAvailable2: action.payload, - }; - }, - [Actions.SET_RELEASE_DATA]: (state, action) => { - return { - ...state, - LocationsLookup: action.payload.locations, - VersionLookup: action.payload.versions, - }; - }, - [Actions.setReleaseUpgradeAvailable]: (state, action) => { - return { - ...state, - ReleaseUpgradeAvailable: action.payload, - }; - }, - [Actions.SET_UI_UPGRADE_DATA]: (state, action) => { - return { - ...state, - UpgradeAvailable: true, - UpgradeData: action.payload.upgrade_data, - UpgradeVersion: action.payload.version, - UpgradeDismissed: false, - }; + { + [Actions.CLEAR_UI_UPGRADE]: (state) => { + return { + ...state, + UpgradeAvailable: false, + UpgradeDismissed: false, + UpgradeData: null, + UpgradeVersion: null, + }; + }, + [Actions.NOTIFY_ACTIVE_RELEASE]: (state, action) => { + return { + ...state, + Release: action.payload.release, + Version: action.payload.version, + }; + }, + [Actions.setAllowDismissDependencies]: (state, action) => { + return { + ...state, + AllowDismissDependencies: action.payload, + }; + }, + [Actions.setDismissNewReleasesAvailable]: (state, action) => { + return { + ...state, + DismissNewReleasesAvailable: action.payload, + }; + }, + [Actions.setDismissUIUpgrade]: (state, action) => { + return { + ...state, + UpgradeDismissed: action.payload, + }; + }, + [Actions.setInstalledVersion]: (state, action) => { + return { ...state, InstalledVersion: action.payload }; + }, + [Actions.setNewReleasesAvailable]: (state, action) => { + return { + ...state, + DismissNewReleasesAvailable: false, + NewReleasesAvailable: action.payload, + }; + }, + [Actions.setNewReleasesAvailable2]: (state, action) => { + return { + ...state, + NewReleasesAvailable2: action.payload, + }; + }, + [Actions.SET_RELEASE_DATA]: (state, action) => { + return { + ...state, + LocationsLookup: action.payload.locations, + VersionLookup: action.payload.versions, + }; + }, + [Actions.setReleaseUpgradeAvailable]: (state, action) => { + return { + ...state, + ReleaseUpgradeAvailable: action.payload, + }; + }, + [Actions.SET_UI_UPGRADE_DATA]: (state, action) => { + return { + ...state, + UpgradeAvailable: true, + UpgradeData: action.payload.upgrade_data, + UpgradeVersion: action.payload.version, + UpgradeDismissed: false, + }; + }, } -}); +); diff --git a/src/redux/reducers/skynet_reducer.js b/src/redux/reducers/skynet_reducer.js index d256aca..30ea4ac 100644 --- a/src/redux/reducers/skynet_reducer.js +++ b/src/redux/reducers/skynet_reducer.js @@ -1,20 +1,17 @@ -import {createReducer} from '@reduxjs/toolkit'; +import { createReducer } from '@reduxjs/toolkit'; import * as Actions from '../actions/skynet_actions'; -export const skynetReducer = createReducer({ - DisplayExport: false, - DisplayImport: false, -}, { - [Actions.displaySkynetExport]: (state, action) => { - return { - ...state, - DisplayExport: action.payload, - } +export const skynetReducer = createReducer( + { + DisplayExport: false, + DisplayImport: false, }, - [Actions.displaySkynetImport]: (state, action) => { - return { - ...state, - DisplayImport: action.payload, - } - }, -}); + { + [Actions.displaySkynetExport]: (state, action) => { + return { ...state, DisplayExport: action.payload }; + }, + [Actions.displaySkynetImport]: (state, action) => { + return { ...state, DisplayImport: action.payload }; + }, + } +); diff --git a/src/redux/store/createAppStore.js b/src/redux/store/createAppStore.js index 8165bfd..e26dbec 100644 --- a/src/redux/store/createAppStore.js +++ b/src/redux/store/createAppStore.js @@ -1,18 +1,21 @@ -import {configureStore, getDefaultMiddleware} from '@reduxjs/toolkit'; -import {createCommonReducer} from '../reducers/common_reducer'; -import {downloadReducer} from '../reducers/download_reducer'; -import {errorReducer} from '../reducers/error_reducer'; -import {installReducer} from '../reducers/install_reducer'; -import {createMountReducer} from '../reducers/mount_reducer'; -import {releaseVersionReducer} from '../reducers/release_version_reducer'; -import {skynetReducer} from '../reducers/skynet_reducer'; -import {pinnedManagerReducer} from '../reducers/pinned_manager_reducer' +import { configureStore, getDefaultMiddleware } from '@reduxjs/toolkit'; + +import { createCommonReducer } from '../reducers/common_reducer'; +import { downloadReducer } from '../reducers/download_reducer'; +import { errorReducer } from '../reducers/error_reducer'; +import { installReducer } from '../reducers/install_reducer'; +import { createMountReducer } from '../reducers/mount_reducer'; +import { pinnedManagerReducer } from '../reducers/pinned_manager_reducer'; +import { releaseVersionReducer } from '../reducers/release_version_reducer'; +import { skynetReducer } from '../reducers/skynet_reducer'; +import { hostReducer } from '../reducers/host_reducer'; export default function createAppStore(platformInfo, version, state) { const reducer = { common: createCommonReducer(platformInfo, version), download: downloadReducer, error: errorReducer, + host: hostReducer, install: installReducer, mounts: createMountReducer(state), relver: releaseVersionReducer, @@ -25,6 +28,6 @@ export default function createAppStore(platformInfo, version, state) { return configureStore({ reducer, middleware, - devTools: process.env.NODE_ENV !== 'production' + devTools: process.env.NODE_ENV !== 'production', }); } diff --git a/src/redux/utils.js b/src/redux/utils.js new file mode 100644 index 0000000..10a1cf5 --- /dev/null +++ b/src/redux/utils.js @@ -0,0 +1,47 @@ +export const createResponseDialogAction = (type, name) => { + let resolverList = []; + + const display = (show, cb, data) => { + return (dispatch) => { + if (cb) { + dispatch(display(show, null, data)).then(({ changed, data }) => cb(changed, data)); + } else { + return new Promise((resolve) => { + dispatch(handleDisplay(show, data, resolve)); + }); + } + }; + }; + + const handleDisplay = (show, data, resolve) => { + return (dispatch) => { + if (show) { + resolverList.push(resolve); + dispatch(displayAction(show, data)); + } else { + dispatch(complete(false)); + } + }; + }; + + const complete = (changed, data) => { + return (dispatch) => { + if (changed) { + resolverList[0]({ changed, data }); + } + resolverList.splice(0, 1); + dispatch(displayAction(false)); + }; + }; + + const DISPLAY_ACTION = type + '/' + name; + const displayAction = (display, data) => { + return { type: DISPLAY_ACTION, payload: { display, data } }; + }; + + return { + action_type: DISPLAY_ACTION, + complete, + display, + }; +}; diff --git a/src/renderer/ipc/AppIPC.js b/src/renderer/ipc/AppIPC.js index 9473440..11cdc72 100644 --- a/src/renderer/ipc/AppIPC.js +++ b/src/renderer/ipc/AppIPC.js @@ -1,6 +1,6 @@ const Constants = require('../../constants'); -const addListeners = (ipcMain, {closeApplication, setWindowVisibility}) => { +const addListeners = (ipcMain, { closeApplication, setWindowVisibility }) => { ipcMain.on(Constants.IPC_Shutdown, () => { closeApplication(); }); @@ -9,12 +9,10 @@ const addListeners = (ipcMain, {closeApplication, setWindowVisibility}) => { setWindowVisibility(true); }); - ipcMain.on(Constants.IPC_Show_Window + '_sync', event => { + ipcMain.on(Constants.IPC_Show_Window + '_sync', (event) => { setWindowVisibility(true); event.returnValue = true; }); }; -module.exports = { - addListeners -}; +module.exports = { addListeners }; diff --git a/src/renderer/ipc/ConfigIPC.js b/src/renderer/ipc/ConfigIPC.js index 81f0e7e..772fdbb 100644 --- a/src/renderer/ipc/ConfigIPC.js +++ b/src/renderer/ipc/ConfigIPC.js @@ -1,48 +1,55 @@ const Constants = require('../../constants'); const helpers = require('../../helpers'); -const addListeners = (ipcMain, {standardIPCReply}) => { +const addListeners = (ipcMain, { standardIPCReply }) => { ipcMain.on(Constants.IPC_Get_Config, (event, data) => { helpers - .getConfig(data.Version, data.Provider, data.Remote, data.S3) - .then((data) => { - if (data.Code === 0) { - standardIPCReply(event, Constants.IPC_Get_Config_Reply, { - Config: data.Data, - }); - } else { - standardIPCReply(event, Constants.IPC_Get_Config_Reply, {}, data.Code); - } - }) - .catch(error => { - standardIPCReply(event, Constants.IPC_Get_Config_Reply, {}, error); - }); + .getConfig(data.Version, data.Provider, data.Remote, data.S3) + .then((data) => { + if (data.Code === 0) { + standardIPCReply(event, Constants.IPC_Get_Config_Reply, { + Config: data.Data, + }); + } else { + standardIPCReply(event, Constants.IPC_Get_Config_Reply, {}, data.Code); + } + }) + .catch((error) => { + standardIPCReply(event, Constants.IPC_Get_Config_Reply, {}, error); + }); }); ipcMain.on(Constants.IPC_Get_Config_Template, (event, data) => { helpers - .getConfigTemplate(data.Version, data.Provider, data.Remote, data.S3) - .then((data) => { - standardIPCReply(event, Constants.IPC_Get_Config_Template_Reply, { - Template: data, + .getConfigTemplate(data.Version, data.Provider, data.Remote, data.S3) + .then((data) => { + standardIPCReply(event, Constants.IPC_Get_Config_Template_Reply, { + Template: data, + }); + }) + .catch((error) => { + standardIPCReply(event, Constants.IPC_Get_Config_Template_Reply, {}, error); }); - }) - .catch(error => { - standardIPCReply(event, Constants.IPC_Get_Config_Template_Reply, {}, error); - }); }); ipcMain.on(Constants.IPC_Set_Config_Values, (event, data) => { const setConfigValue = (i) => { if (i < data.Items.length) { helpers - .setConfigValue(data.Items[i].Name, data.Items[i].Value, data.Provider, data.Remote, data.S3, data.Version) - .then(() => { - setConfigValue(++i); - }) - .catch(error => { - standardIPCReply(event, Constants.IPC_Set_Config_Values_Reply, {}, error); - }); + .setConfigValue( + data.Items[i].Name, + data.Items[i].Value, + data.Provider, + data.Remote, + data.S3, + data.Version + ) + .then(() => { + setConfigValue(++i); + }) + .catch((error) => { + standardIPCReply(event, Constants.IPC_Set_Config_Values_Reply, {}, error); + }); } else { standardIPCReply(event, Constants.IPC_Set_Config_Values_Reply, {}); } @@ -51,6 +58,4 @@ const addListeners = (ipcMain, {standardIPCReply}) => { }); }; -module.exports = { - addListeners -}; +module.exports = { addListeners }; diff --git a/src/renderer/ipc/DaemonIPC.js b/src/renderer/ipc/DaemonIPC.js index 6e4ec62..23b9732 100644 --- a/src/renderer/ipc/DaemonIPC.js +++ b/src/renderer/ipc/DaemonIPC.js @@ -1,47 +1,46 @@ const Constants = require('../../constants'); const helpers = require('../../helpers'); -const addListeners = (ipcMain, {standardIPCReply}) => { +const addListeners = (ipcMain, { standardIPCReply }) => { ipcMain.on(Constants.IPC_Check_Daemon_Version, (event, data) => { helpers - .checkDaemonVersion(data.Version, data.Provider) - .then(code => { - standardIPCReply(event, Constants.IPC_Check_Daemon_Version_Reply, { - Valid: (code === 0), - Code: code, + .checkDaemonVersion(data.Version, data.Provider) + .then((code) => { + standardIPCReply(event, Constants.IPC_Check_Daemon_Version_Reply, { + Valid: code === 0, + Code: code, + }); + }) + .catch((e) => { + standardIPCReply( + event, + Constants.IPC_Check_Daemon_Version_Reply, + { + Valid: false, + }, + e + ); }); - }) - .catch(e => { - standardIPCReply(event, Constants.IPC_Check_Daemon_Version_Reply, { - Valid: false, - }, e); - }); }); ipcMain.on(Constants.IPC_Check_Daemon_Version + '_sync', (event, data) => { helpers - .checkDaemonVersion(data.Version, data.Provider) - .then(code => { - event.returnValue = { - data: { - Success: true, - Valid: (code === 0), - Code: code, - }, - }; - }) - .catch(e => { - event.returnValue = { - data: { - Error: e.toString(), - Success: false, - Valid: false - }, - }; - }); + .checkDaemonVersion(data.Version, data.Provider) + .then((code) => { + event.returnValue = { + data: { + Success: true, + Valid: code === 0, + Code: code, + }, + }; + }) + .catch((e) => { + event.returnValue = { + data: { Error: e.toString(), Success: false, Valid: false }, + }; + }); }); }; -module.exports = { - addListeners -}; +module.exports = { addListeners }; diff --git a/src/renderer/ipc/DependencyIPC.js b/src/renderer/ipc/DependencyIPC.js index 8f74bf0..5c60718 100644 --- a/src/renderer/ipc/DependencyIPC.js +++ b/src/renderer/ipc/DependencyIPC.js @@ -2,7 +2,7 @@ const Constants = require('../../constants'); const fs = require('fs'); const helpers = require('../../helpers'); -const addListeners = (ipcMain, {standardIPCReply}) => { +const addListeners = (ipcMain, { standardIPCReply }) => { ipcMain.on(Constants.IPC_Check_Dependency_Installed, (event, data) => { try { const exists = fs.lstatSync(data.File).isFile(); @@ -13,7 +13,7 @@ const addListeners = (ipcMain, {standardIPCReply}) => { }); } catch (e) { standardIPCReply(event, Constants.IPC_Check_Dependency_Installed_Reply, { - data : { + data: { Exists: false, }, }); @@ -30,9 +30,7 @@ const addListeners = (ipcMain, {standardIPCReply}) => { }; } catch (e) { event.returnValue = { - data: { - Exists: false - }, + data: { Exists: false }, }; } }); @@ -40,56 +38,71 @@ const addListeners = (ipcMain, {standardIPCReply}) => { ipcMain.on(Constants.IPC_Install_Dependency, (event, data) => { if (data.Source.toLowerCase().endsWith('.dmg')) { helpers - .executeAsync('open', ['-a', 'Finder', '-W', data.Source]) - .then(() => { - standardIPCReply(event, Constants.IPC_Install_Dependency_Reply, { - Source: data.Source, - URL: data.URL, - }); - }) - .catch(error=> { - standardIPCReply(event, Constants.IPC_Install_Dependency_Reply, { - Source: data.Source, - URL: data.URL, - }, error); - }); - } else { - const execInstall = () => { - helpers - .executeAndWait(data.Source) + .executeAsync('open', ['-a', 'Finder', '-W', data.Source]) .then(() => { standardIPCReply(event, Constants.IPC_Install_Dependency_Reply, { Source: data.Source, URL: data.URL, }); }) - .catch(error => { - standardIPCReply(event, Constants.IPC_Install_Dependency_Reply, { - Source: data.Source, - URL: data.URL, - }, error); + .catch((error) => { + standardIPCReply( + event, + Constants.IPC_Install_Dependency_Reply, + { + Source: data.Source, + URL: data.URL, + }, + error + ); }); - }; - if (data.IsWinFSP) { + } else { + const execInstall = () => { helpers - .performWindowsUninstall(Constants.WINFSP_VERSION_NAMES) - .then(uninstalled => { - if (uninstalled) { + .executeAndWait(data.Source) + .then(() => { standardIPCReply(event, Constants.IPC_Install_Dependency_Reply, { - RebootRequired: true, Source: data.Source, URL: data.URL, }); - } else { - execInstall(); - } - }) - .catch(error => { - standardIPCReply(event, Constants.IPC_Install_Dependency_Reply, { - Source: data.Source, - URL: data.URL, - }, error); - }); + }) + .catch((error) => { + standardIPCReply( + event, + Constants.IPC_Install_Dependency_Reply, + { + Source: data.Source, + URL: data.URL, + }, + error + ); + }); + }; + if (data.IsWinFSP) { + helpers + .performWindowsUninstall(Constants.WINFSP_VERSION_NAMES) + .then((uninstalled) => { + if (uninstalled) { + standardIPCReply(event, Constants.IPC_Install_Dependency_Reply, { + RebootRequired: true, + Source: data.Source, + URL: data.URL, + }); + } else { + execInstall(); + } + }) + .catch((error) => { + standardIPCReply( + event, + Constants.IPC_Install_Dependency_Reply, + { + Source: data.Source, + URL: data.URL, + }, + error + ); + }); } else { execInstall(); } @@ -97,6 +110,4 @@ const addListeners = (ipcMain, {standardIPCReply}) => { }); }; -module.exports = { - addListeners -}; +module.exports = { addListeners }; diff --git a/src/renderer/ipc/DownloadIPC.js b/src/renderer/ipc/DownloadIPC.js index 366d72e..407ee9f 100644 --- a/src/renderer/ipc/DownloadIPC.js +++ b/src/renderer/ipc/DownloadIPC.js @@ -2,24 +2,32 @@ const Constants = require('../../constants'); const helpers = require('../../helpers'); const path = require('path'); -const addListeners = (ipcMain, {standardIPCReply}) => { +const addListeners = (ipcMain, { standardIPCReply }) => { ipcMain.on(Constants.IPC_Download_File, (event, data) => { const destination = path.join(helpers.getDataDirectory(), data.Filename); - helpers.downloadFile(data.URL, destination, (progress) => { - standardIPCReply(event, Constants.IPC_Download_File_Progress, { - Destination: destination, - Progress: progress, - URL: data.URL, - }); - }, error => { - standardIPCReply(event, Constants.IPC_Download_File_Complete, { - Destination: destination, - URL: data.URL, - }, error); - }); + helpers.downloadFile( + data.URL, + destination, + (progress) => { + standardIPCReply(event, Constants.IPC_Download_File_Progress, { + Destination: destination, + Progress: progress, + URL: data.URL, + }); + }, + (error) => { + standardIPCReply( + event, + Constants.IPC_Download_File_Complete, + { + Destination: destination, + URL: data.URL, + }, + error + ); + } + ); }); }; -module.exports = { - addListeners -}; +module.exports = { addListeners }; diff --git a/src/renderer/ipc/FilesystemIPC.js b/src/renderer/ipc/FilesystemIPC.js index cb71d62..d50b82e 100644 --- a/src/renderer/ipc/FilesystemIPC.js +++ b/src/renderer/ipc/FilesystemIPC.js @@ -1,31 +1,86 @@ const Constants = require('../../constants'); const fs = require('fs'); -const addListeners = (ipcMain, {getMainWindow, dialog}) => { +const addListeners = (ipcMain, { getMainWindow, dialog }) => { ipcMain.on(Constants.IPC_Browse_Directory + '_sync', (event, data) => { - dialog.showOpenDialog(getMainWindow(), { - defaultPath: data.Location, - properties: ['openDirectory'], - title: data.Title, - }, (filePaths) => { - if (filePaths && (filePaths.length > 0)) { - event.returnValue = filePaths[0]; - } else { - event.returnValue = ''; + dialog.showOpenDialog( + getMainWindow(), + { + defaultPath: data.Location, + properties: ['openDirectory'], + title: data.Title, + }, + (filePaths) => { + if (filePaths && filePaths.length > 0) { + event.returnValue = filePaths[0]; + } else { + event.returnValue = ''; + } } - }); + ); }); - ipcMain.on(Constants.IPC_Delete_File, (event, data) => { + ipcMain.on(Constants.IPC_Browse_File + '_sync', (event, data) => { + dialog.showOpenDialog( + getMainWindow(), + { + defaultPath: data.Location, + properties: ['openFile'], + title: data.Title, + }, + (filePaths) => { + if (filePaths && filePaths.length > 0) { + event.returnValue = filePaths[0]; + } else { + event.returnValue = ''; + } + } + ); + }); + + ipcMain.on(Constants.IPC_Delete_File, (_, data) => { try { if (fs.existsSync(data.FilePath)) { fs.unlinkSync(data.FilePath); } - } catch (e) { + } catch (e) {} + }); + + ipcMain.on(Constants.IPC_Select_File + '_sync', (event, data) => { + dialog.showSaveDialog( + getMainWindow(), + { + defaultPath: data.Location, + properties: ['createDirectory', 'showOverwriteConfirmation'], + title: data.Title, + }, + (filePath) => { + if (filePath && filePath.length > 0) { + event.returnValue = filePath; + } else { + event.returnValue = ''; + } + } + ); + }); + + ipcMain.on(Constants.IPC_Read_File + '_sync', (event, data) => { + try { + const contents = fs.readFileSync(data.Location, 'utf8').toString(); + event.returnValue = { success: true, contents }; + } catch (err) { + event.returnValue = { success: false, error: err.toString() }; + } + }); + + ipcMain.on(Constants.IPC_Save_File + '_sync', (event, data) => { + try { + fs.writeFileSync(data.Location, data.Data, 'utf8'); + event.returnValue = { success: true }; + } catch (err) { + event.returnValue = { success: false, error: err.toString() }; } }); }; -module.exports = { - addListeners -}; +module.exports = { addListeners }; diff --git a/src/renderer/ipc/MountsIPC.js b/src/renderer/ipc/MountsIPC.js index ef1cdeb..bedd695 100644 --- a/src/renderer/ipc/MountsIPC.js +++ b/src/renderer/ipc/MountsIPC.js @@ -10,7 +10,7 @@ let manualMountDetection = {}; let mountedData = {}; let mountedLocations = []; -const clearManualMountDetection = provider => { +const clearManualMountDetection = (provider) => { if (manualMountDetection[provider]) { clearInterval(manualMountDetection[provider]); delete manualMountDetection[provider]; @@ -20,28 +20,28 @@ const clearManualMountDetection = provider => { const monitorMount = (sender, provider, providerList, version, pid, location) => { manualMountDetection[provider] = setInterval(() => { helpers - .detectRepertoryMounts(version, providerList) - .then(result => { - if (result[provider].PID !== pid) { - if (result[provider].PID === -1) { - clearManualMountDetection(provider); - sender.send(Constants.IPC_Unmount_Drive_Reply, { - data: { - Expected: expectedUnmount[provider], - Location: location, - Provider: provider, - Error: Error(provider + ' Unmounted').toString(), - Success: false, - } - }); - } else { - pid = result[provider].PID; + .detectRepertoryMounts(version, providerList) + .then((result) => { + if (result[provider].PID !== pid) { + if (result[provider].PID === -1) { + clearManualMountDetection(provider); + sender.send(Constants.IPC_Unmount_Drive_Reply, { + data: { + Expected: expectedUnmount[provider], + Location: location, + Provider: provider, + Error: Error(provider + ' Unmounted').toString(), + Success: false, + }, + }); + } else { + pid = result[provider].PID; + } } - } - }) - .catch(e => { - console.log(e); - }); + }) + .catch((e) => { + console.log(e); + }); }, 6000); }; @@ -62,12 +62,9 @@ const unmountAllDrives = () => { mountedData = {}; }; -const addListeners = (ipcMain, {setTrayImage, standardIPCReply}) => { +const addListeners = (ipcMain, { setTrayImage, standardIPCReply }) => { ipcMain.on(Constants.IPC_Check_Mount_Location + '_sync', (event, data) => { - let response = { - Success: true, - Error: '' - }; + let response = { Success: true, Error: '' }; try { if (fs.existsSync(data.Location) && fs.statSync(data.Location).isDirectory()) { @@ -90,11 +87,7 @@ const addListeners = (ipcMain, {setTrayImage, standardIPCReply}) => { const provider = data.Provider; let driveLetters = {}; - const providerList = [ - ...Constants.PROVIDER_LIST, - ...data.RemoteMounts, - ...data.S3Mounts, - ]; + const providerList = [...Constants.PROVIDER_LIST, ...data.RemoteMounts, ...data.S3Mounts]; for (const provider of providerList) { driveLetters[provider] = []; } @@ -106,8 +99,7 @@ const addListeners = (ipcMain, {setTrayImage, standardIPCReply}) => { if (Object.keys(locations).length > 0) { for (const provider of providerList) { driveInUse = locations[provider].startsWith(drive); - if (driveInUse) - break; + if (driveInUse) break; } } if (!driveInUse) { @@ -117,17 +109,18 @@ const addListeners = (ipcMain, {setTrayImage, standardIPCReply}) => { driveLetters[provider].push(drive); } } - } catch (e) { - } + } catch (e) {} } } if (Object.keys(locations).length > 0) { for (const provider of providerList) { if (locations[provider].length > 0) { - if (!driveLetters[provider].find((driveLetter) => { - return driveLetter === locations[provider]; - })) { + if ( + !driveLetters[provider].find((driveLetter) => { + return driveLetter === locations[provider]; + }) + ) { driveLetters[provider].push(locations[provider]); } } @@ -135,66 +128,79 @@ const addListeners = (ipcMain, {setTrayImage, standardIPCReply}) => { } }; - const setImage = locations => { + const setImage = (locations) => { let driveInUse; if (Object.keys(locations).length > 0) { for (const provider of providerList) { driveInUse = locations[provider] && locations[provider].length > 0; - if (driveInUse) - break; + if (driveInUse) break; } } - setTrayImage(driveInUse) + setTrayImage(driveInUse); }; helpers - .detectRepertoryMounts(data.Version, providerList) - .then((results) => { - let storageData = {}; - let locations = {}; - for (const provider of providerList) { - storageData[provider] = results[provider] ? results[provider] : { - Active: false, - Location: '', - PID: -1, - }; - locations[provider] = storageData[provider].Location; + .detectRepertoryMounts(data.Version, providerList) + .then((results) => { + let storageData = {}; + let locations = {}; + for (const provider of providerList) { + storageData[provider] = results[provider] + ? results[provider] + : { + Active: false, + Location: '', + PID: -1, + }; + locations[provider] = storageData[provider].Location; - if (storageData[provider].PID !== -1) { - expectedUnmount[provider] = false; - if (firstMountCheck) { - monitorMount(event.sender, provider, providerList, data.Version, storageData[provider].PID, storageData[provider].Location); + if (storageData[provider].PID !== -1) { + expectedUnmount[provider] = false; + if (firstMountCheck) { + monitorMount( + event.sender, + provider, + providerList, + data.Version, + storageData[provider].PID, + storageData[provider].Location + ); + } } } - } - if (os.platform() === 'win32') { - grabDriveLetters(locations); - } + if (os.platform() === 'win32') { + grabDriveLetters(locations); + } - setImage(locations); - if (firstMountCheck) { - firstMountCheck = false; - } - standardIPCReply(event, Constants.IPC_Detect_Mount_Reply, { - Active: storageData[provider].Active, - DriveLetters: driveLetters[provider], - Location: locations[provider], - PID: storageData[provider].PID, - Provider: provider, + setImage(locations); + if (firstMountCheck) { + firstMountCheck = false; + } + standardIPCReply(event, Constants.IPC_Detect_Mount_Reply, { + Active: storageData[provider].Active, + DriveLetters: driveLetters[provider], + Location: locations[provider], + PID: storageData[provider].PID, + Provider: provider, + }); + }) + .catch((error) => { + if (os.platform() === 'win32') { + grabDriveLetters({}); + } + setImage({}); + standardIPCReply( + event, + Constants.IPC_Detect_Mount_Reply, + { + DriveLetters: driveLetters[provider], + Provider: provider, + }, + error + ); }); - }) - .catch(error => { - if (os.platform() === 'win32') { - grabDriveLetters({}); - } - setImage({}); - standardIPCReply(event, Constants.IPC_Detect_Mount_Reply, { - DriveLetters: driveLetters[provider], - Provider: provider, - }, error); - }); }); ipcMain.on(Constants.IPC_Mount_Drive, (event, data) => { @@ -216,28 +222,40 @@ const addListeners = (ipcMain, {setTrayImage, standardIPCReply}) => { delete mountedData[data.Location]; } - standardIPCReply(event, Constants.IPC_Unmount_Drive_Reply, { - Expected: expectedUnmount[data.Provider], - Location: data.Location, - Provider: data.Provider, - Remote: data.Remote, - S3: data.S3, - }, error || Error(data.Provider + ' Unmounted')); + standardIPCReply( + event, + Constants.IPC_Unmount_Drive_Reply, + { + Expected: expectedUnmount[data.Provider], + Location: data.Location, + Provider: data.Provider, + Remote: data.Remote, + S3: data.S3, + }, + error || Error(data.Provider + ' Unmounted') + ); }; helpers - .executeMount(data.Version, data.Provider, data.Remote, data.S3, data.Location, (error, pid) => { - errorHandler(pid, error); - }) - .then(() => { - standardIPCReply(event, Constants.IPC_Mount_Drive_Reply, { - Provider: data.Provider, - Remote: data.Remote, - S3: data.S3, + .executeMount( + data.Version, + data.Provider, + data.Remote, + data.S3, + data.Location, + (error, pid) => { + errorHandler(pid, error); + } + ) + .then(() => { + standardIPCReply(event, Constants.IPC_Mount_Drive_Reply, { + Provider: data.Provider, + Remote: data.Remote, + S3: data.S3, + }); + }) + .catch((error) => { + errorHandler(-1, error); }); - }) - .catch(error => { - errorHandler(-1, error); - }); } }); @@ -245,17 +263,26 @@ const addListeners = (ipcMain, {setTrayImage, standardIPCReply}) => { if (data.Remote) { data.Name = data.Name.replace(':', '_'); } - const dataDirectory = path.resolve(path.join(helpers.getDataDirectory(), '..', data.Remote ? 'remote' : 's3', data.Name)); + const dataDirectory = path.resolve( + path.join(helpers.getDataDirectory(), '..', data.Remote ? 'remote' : 's3', data.Name) + ); try { helpers.removeDirectoryRecursively(dataDirectory); - standardIPCReply(event, Constants.IPC_Remove_Mount_Reply, {DataDirectory: dataDirectory}); + standardIPCReply(event, Constants.IPC_Remove_Mount_Reply, { + DataDirectory: dataDirectory, + }); } catch (e) { - standardIPCReply(event, Constants.IPC_Remove_Mount_Reply, {DataDirectory: dataDirectory}, e); + standardIPCReply( + event, + Constants.IPC_Remove_Mount_Reply, + { DataDirectory: dataDirectory }, + e + ); } }); - ipcMain.on(Constants.IPC_Unmount_All_Drives, event => { + ipcMain.on(Constants.IPC_Unmount_All_Drives, (event) => { unmountAllDrives(); standardIPCReply(event, Constants.IPC_Unmount_All_Drives_Reply); }); @@ -265,17 +292,17 @@ const addListeners = (ipcMain, {setTrayImage, standardIPCReply}) => { expectedUnmount[data.Provider] = true; helpers - .stopMountProcess(data.Version, data.Provider, data.Remote, data.S3) - .then(result => { - console.log(result); - }) - .catch(e => { - console.log(e); - }); + .stopMountProcess(data.Version, data.Provider, data.Remote, data.S3) + .then((result) => { + console.log(result); + }) + .catch((e) => { + console.log(e); + }); }); }; module.exports = { addListeners, - unmountAllDrives + unmountAllDrives, }; diff --git a/src/renderer/ipc/PinnedIPC.js b/src/renderer/ipc/PinnedIPC.js index 2cc26d7..d3bce3b 100644 --- a/src/renderer/ipc/PinnedIPC.js +++ b/src/renderer/ipc/PinnedIPC.js @@ -1,49 +1,45 @@ const Constants = require('../../constants'); const helpers = require('../../helpers'); -const addListeners = (ipcMain, {standardIPCReply}) => { +const addListeners = (ipcMain, { standardIPCReply }) => { ipcMain.on(Constants.IPC_Get_Directory_Items, (event, data) => { helpers - .grabDirectoryItems(data.Path, data.Version, data.Provider, data.Remote, data.S3) - .then(data => { - standardIPCReply(event, Constants.IPC_Get_Directory_Items_Reply, { - Items: data.items, + .grabDirectoryItems(data.Path, data.Version, data.Provider, data.Remote, data.S3) + .then((data) => { + standardIPCReply(event, Constants.IPC_Get_Directory_Items_Reply, { + Items: data.items, + }); + }) + .catch((e) => { + standardIPCReply(event, Constants.IPC_Get_Directory_Items_Reply, {}, e); }); - }) - .catch(e => { - standardIPCReply(event, Constants.IPC_Get_Directory_Items_Reply, {}, e); - }); }); ipcMain.on(Constants.IPC_Get_Pinned_Files, (event, data) => { helpers - .grabDirectoryItems(data.Path, data.Version, data.Provider, data.Remote, data.S3) - .then(data => { - standardIPCReply(event, Constants.IPC_Get_Directory_Items_Reply, { - Items: data.items, + .grabDirectoryItems(data.Path, data.Version, data.Provider, data.Remote, data.S3) + .then((data) => { + standardIPCReply(event, Constants.IPC_Get_Directory_Items_Reply, { + Items: data.items, + }); + }) + .catch((e) => { + standardIPCReply(event, Constants.IPC_Get_Directory_Items_Reply, {}, e); }); - }) - .catch(e => { - standardIPCReply(event, Constants.IPC_Get_Directory_Items_Reply, {}, e); - }); }); - ipcMain.on(Constants.IPC_Get_Pinned_Files_Status, (event, data) => { - - }); + ipcMain.on(Constants.IPC_Get_Pinned_Files_Status, (event, data) => {}); ipcMain.on(Constants.IPC_Set_Pinned + '_sync', (event, data) => { helpers - .setPinned(data.Path, data.Pinned, data.Version, data.Provider, data.Remote, data.S3) - .then(success => { - event.returnValue = success; - }) - .catch(e => { - event.returnValue = false; - }); + .setPinned(data.Path, data.Pinned, data.Version, data.Provider, data.Remote, data.S3) + .then((success) => { + event.returnValue = success; + }) + .catch((e) => { + event.returnValue = false; + }); }); }; -module.exports = { - addListeners -}; +module.exports = { addListeners }; diff --git a/src/renderer/ipc/PlatformIPC.js b/src/renderer/ipc/PlatformIPC.js index 16ec438..9501d08 100644 --- a/src/renderer/ipc/PlatformIPC.js +++ b/src/renderer/ipc/PlatformIPC.js @@ -10,11 +10,11 @@ const getPlatformOverride = () => { return _platformOverride; }; -const setPlatformOverride = platformOverride => { +const setPlatformOverride = (platformOverride) => { _platformOverride = platformOverride; }; -const addListeners = (ipcMain, {detectScript, saveUiSettings}) => { +const addListeners = (ipcMain, { detectScript, saveUiSettings }) => { ipcMain.on(Constants.IPC_Get_Platform, (event) => { const sendResponse = (appPlatform, platform) => { event.sender.send(Constants.IPC_Get_Platform_Reply, { @@ -25,40 +25,39 @@ const addListeners = (ipcMain, {detectScript, saveUiSettings}) => { const platform = os.platform(); if (platform === 'linux') { - if (_platformOverride && (_platformOverride.length > 0)) { + if (_platformOverride && _platformOverride.length > 0) { sendResponse(_platformOverride, 'linux'); } else { const scriptFile = path.join(os.tmpdir(), 'repertory_detect_linux.sh'); fs.writeFileSync(scriptFile, detectScript); helpers - .executeScript(scriptFile) - .then(data => { - let appPlatform = data.replace(/(\r\n|\n|\r)/gm, ""); - if (appPlatform === 'unknown') { - helpers - .downloadFile(Constants.LINUX_DETECT_SCRIPT_URL, scriptFile, null, err => { - if (err) { - sendResponse(appPlatform, platform); - } else { - helpers - .executeScript(scriptFile) - .then(data => { - appPlatform = data.replace(/(\r\n|\n|\r)/gm, ""); + .executeScript(scriptFile) + .then((data) => { + let appPlatform = data.replace(/(\r\n|\n|\r)/gm, ''); + if (appPlatform === 'unknown') { + helpers.downloadFile(Constants.LINUX_DETECT_SCRIPT_URL, scriptFile, null, (err) => { + if (err) { sendResponse(appPlatform, platform); - }) - .catch(() => { - sendResponse(appPlatform, platform); - }); - } - }); - } else { - sendResponse(appPlatform, platform); - } - }) - .catch(() => { - sendResponse(platform, platform); - }); + } else { + helpers + .executeScript(scriptFile) + .then((data) => { + appPlatform = data.replace(/(\r\n|\n|\r)/gm, ''); + sendResponse(appPlatform, platform); + }) + .catch(() => { + sendResponse(appPlatform, platform); + }); + } + }); + } else { + sendResponse(appPlatform, platform); + } + }) + .catch(() => { + sendResponse(platform, platform); + }); } } else { sendResponse(platform, platform); @@ -75,5 +74,5 @@ const addListeners = (ipcMain, {detectScript, saveUiSettings}) => { module.exports = { getPlatformOverride, setPlatformOverride, - addListeners + addListeners, }; diff --git a/src/renderer/ipc/ReleaseIPC.js b/src/renderer/ipc/ReleaseIPC.js index f2d7a77..017907b 100644 --- a/src/renderer/ipc/ReleaseIPC.js +++ b/src/renderer/ipc/ReleaseIPC.js @@ -5,28 +5,33 @@ const os = require('os'); const path = require('path'); const unzip = require('unzipper'); -const addListeners = (ipcMain, {getCleanupReleases, standardIPCReply}) => { +const addListeners = (ipcMain, { getCleanupReleases, standardIPCReply }) => { ipcMain.on(Constants.IPC_Check_Installed, (event, data) => { const destination = path.join(helpers.getDataDirectory(), data.Version); helpers - .getMissingDependencies(data.Dependencies) - .then((dependencies) => { - let exists = false; - try { - exists = fs.existsSync(destination) && fs.lstatSync(destination).isDirectory(); - } catch (e) { - } - standardIPCReply(event, Constants.IPC_Check_Installed_Reply, { - Dependencies: dependencies, - Exists: exists, - Version: data.Version, + .getMissingDependencies(data.Dependencies) + .then((dependencies) => { + let exists = false; + try { + exists = fs.existsSync(destination) && fs.lstatSync(destination).isDirectory(); + } catch (e) {} + standardIPCReply(event, Constants.IPC_Check_Installed_Reply, { + Dependencies: dependencies, + Exists: exists, + Version: data.Version, + }); + }) + .catch((error) => { + standardIPCReply( + event, + Constants.IPC_Check_Installed_Reply, + { + Dependencies: [], + Version: data.Version, + }, + error + ); }); - }).catch(error => { - standardIPCReply(event, Constants.IPC_Check_Installed_Reply, { - Dependencies: [], - Version: data.Version, - }, error); - }); }); ipcMain.on(Constants.IPC_Cleanup_Releases + '_sync', (event, data) => { @@ -44,52 +49,59 @@ const addListeners = (ipcMain, {getCleanupReleases, standardIPCReply}) => { const stream = fs.createReadStream(data.Source); stream - .pipe(unzip.Extract({ path: destination })) - .on('error', error => { - try { - helpers.removeDirectoryRecursively(destination); - } catch (e) { - } - stream.close(); - standardIPCReply(event, Constants.IPC_Extract_Release_Complete, { - Source: data.Source, - }, error); - }) - .on('finish', () => { - stream.close(); - if (os.platform() !== 'win32') { - helpers - .executeAndWait("chmod +x \"" + path.join(destination, 'repertory') + "\"") - .then(() => { + .pipe(unzip.Extract({ path: destination })) + .on('error', (error) => { + try { + helpers.removeDirectoryRecursively(destination); + } catch (e) {} + stream.close(); + standardIPCReply( + event, + Constants.IPC_Extract_Release_Complete, + { + Source: data.Source, + }, + error + ); + }) + .on('finish', () => { + stream.close(); + if (os.platform() !== 'win32') { + helpers + .executeAndWait('chmod +x "' + path.join(destination, 'repertory') + '"') + .then(() => { + standardIPCReply(event, Constants.IPC_Extract_Release_Complete, { + Source: data.Source, + }); + }) + .catch((error) => { + standardIPCReply( + event, + Constants.IPC_Extract_Release_Complete, + { + Source: data.Source, + }, + error + ); + }); + } else { standardIPCReply(event, Constants.IPC_Extract_Release_Complete, { Source: data.Source, }); - }) - .catch(error => { - standardIPCReply(event, Constants.IPC_Extract_Release_Complete, { - Source: data.Source, - }, error); - }) - } else { - standardIPCReply(event, Constants.IPC_Extract_Release_Complete, { - Source: data.Source, - }); - } - }); + } + }); }); ipcMain.on(Constants.IPC_Test_Release, (event, data) => { helpers - .testRepertoryBinary(data.Version) - .then(() => { - standardIPCReply(event, Constants.IPC_Test_Release_Reply, {}); - }) - .catch(error => { - standardIPCReply(event, Constants.IPC_Test_Release_Reply, {}, error); - }); + .testRepertoryBinary(data.Version) + .then(() => { + standardIPCReply(event, Constants.IPC_Test_Release_Reply, {}); + }) + .catch((error) => { + standardIPCReply(event, Constants.IPC_Test_Release_Reply, {}, error); + }); }); }; -module.exports = { - addListeners -}; +module.exports = { addListeners }; diff --git a/src/renderer/ipc/SkynetIPC.js b/src/renderer/ipc/SkynetIPC.js index f8e115a..9fde643 100644 --- a/src/renderer/ipc/SkynetIPC.js +++ b/src/renderer/ipc/SkynetIPC.js @@ -1,16 +1,16 @@ const Constants = require('../../constants'); const helpers = require('../../helpers'); -const addListeners = (ipcMain, {standardIPCReply}) => { +const addListeners = (ipcMain, { standardIPCReply }) => { ipcMain.on(Constants.IPC_Export_Skylinks, (event, data) => { helpers .exportSkylinks(data.Version, data.Paths) - .then(result => { + .then((result) => { standardIPCReply(event, Constants.IPC_Export_Skylinks_Reply, { Result: result, }); }) - .catch(error => { + .catch((error) => { standardIPCReply(event, Constants.IPC_Export_Skylinks_Reply, {}, error); }); }); @@ -18,12 +18,12 @@ const addListeners = (ipcMain, {standardIPCReply}) => { ipcMain.on(Constants.IPC_Grab_Skynet_Tree, (event, data) => { helpers .grabSkynetFileTree(data.Version) - .then(result => { + .then((result) => { standardIPCReply(event, Constants.IPC_Grab_Skynet_Tree_Reply, { Result: result, }); }) - .catch(error => { + .catch((error) => { standardIPCReply(event, Constants.IPC_Grab_Skynet_Tree_Reply, {}, error); }); }); @@ -31,17 +31,30 @@ const addListeners = (ipcMain, {standardIPCReply}) => { ipcMain.on(Constants.IPC_Import_Skylinks, (event, data) => { helpers .importSkylinks(data.Version, data.JsonArray) - .then(result => { + .then((result) => { standardIPCReply(event, Constants.IPC_Import_Skylinks_Reply, { Result: result, }); }) - .catch(error => { + .catch((error) => { standardIPCReply(event, Constants.IPC_Import_Skylinks_Reply, {}, error); }); }); + + ipcMain.on(Constants.IPC_Skynet_Test_Logon, (event, data) => { + helpers + .testSkynetLogon(data.Version, data.AuthURL, data.AuthUser, data.AuthPassword) + .then((success) => { + if (success) { + standardIPCReply(event, Constants.IPC_Skynet_Test_Logon_Reply, {}); + } else { + standardIPCReply(event, Constants.IPC_Skynet_Test_Logon_Reply, {}, 'Logon failed. Please check credentials'); + } + }) + .catch((error) => { + standardIPCReply(event, Constants.IPC_Skynet_Test_Logon_Reply, {}, error); + }); + }); }; -module.exports = { - addListeners -}; +module.exports = { addListeners }; diff --git a/src/renderer/ipc/StateIPC.js b/src/renderer/ipc/StateIPC.js index ba25560..e760cae 100644 --- a/src/renderer/ipc/StateIPC.js +++ b/src/renderer/ipc/StateIPC.js @@ -3,18 +3,19 @@ const fs = require('fs'); const helpers = require('../../helpers'); const path = require('path'); -const getDirectories = source => { +const getDirectories = (source) => { try { - return fs.readdirSync(source, {withFileTypes: true}) - .filter(dirent => dirent.isDirectory()) - .map(dirent => dirent.name); + return fs + .readdirSync(source, { withFileTypes: true }) + .filter((dirent) => dirent.isDirectory()) + .map((dirent) => dirent.name); } catch { return []; } -} +}; -const addListeners = ipcMain => { - ipcMain.on(Constants.IPC_Get_State, event => { +const addListeners = (ipcMain) => { + ipcMain.on(Constants.IPC_Get_State, (event) => { helpers.mkDirByPathSync(helpers.getDataDirectory()); let data = {}; @@ -32,7 +33,7 @@ const addListeners = ipcMain => { AutoMount: false, AutoRestart: true, MountLocation: '', - } + }; } } @@ -69,13 +70,11 @@ const addListeners = ipcMain => { }); }); - ipcMain.on(Constants.IPC_Save_State, (event, data) => { + ipcMain.on(Constants.IPC_Save_State, (_, data) => { helpers.mkDirByPathSync(helpers.getDataDirectory()); const configFile = path.join(helpers.getDataDirectory(), 'settings.json'); fs.writeFileSync(configFile, JSON.stringify(data.State), 'utf8'); }); }; -module.exports = { - addListeners -}; +module.exports = { addListeners }; diff --git a/src/renderer/ipc/SystemIPC.js b/src/renderer/ipc/SystemIPC.js index a6298c5..bea47be 100644 --- a/src/renderer/ipc/SystemIPC.js +++ b/src/renderer/ipc/SystemIPC.js @@ -2,7 +2,7 @@ const Constants = require('../../constants'); const os = require('os'); const helpers = require('../../helpers'); -const addListeners = (ipcMain, {closeApplication}) => { +const addListeners = (ipcMain, { closeApplication }) => { ipcMain.on(Constants.IPC_Reboot_System, () => { if (os.platform() === 'win32') { helpers.executeAsync('shutdown.exe', ['/r', '/t', '30']); @@ -11,6 +11,4 @@ const addListeners = (ipcMain, {closeApplication}) => { }); }; -module.exports = { - addListeners -}; +module.exports = { addListeners }; diff --git a/src/renderer/ipc/UpgradeIPC.js b/src/renderer/ipc/UpgradeIPC.js index b717ab8..8fdceac 100644 --- a/src/renderer/ipc/UpgradeIPC.js +++ b/src/renderer/ipc/UpgradeIPC.js @@ -3,7 +3,7 @@ const fs = require('fs'); const helpers = require('../../helpers'); const os = require('os'); -const addListeners = (ipcMain, {setIsInstalling, unmountAllDrives, standardIPCReply}) => { +const addListeners = (ipcMain, { setIsInstalling, unmountAllDrives, standardIPCReply }) => { ipcMain.on(Constants.IPC_Install_Upgrade, (event, data) => { let allowSkipVerification = true; @@ -19,22 +19,28 @@ const addListeners = (ipcMain, {setIsInstalling, unmountAllDrives, standardIPCRe if (tempPub) { fs.unlinkSync(tempPub); } - } catch (e) { - } + } catch (e) {} }; - const errorHandler = err => { + const errorHandler = (err) => { cleanupFiles(); setIsInstalling(false); - standardIPCReply(event, Constants.IPC_Install_Upgrade_Reply, { - AllowSkipVerification: allowSkipVerification, - Source: data.Source, - }, err); + standardIPCReply( + event, + Constants.IPC_Install_Upgrade_Reply, + { + AllowSkipVerification: allowSkipVerification, + Source: data.Source, + }, + err + ); }; // TODO Enable verification in 1.0.4 - const hasSignature = false;//!data.SkipVerification && data.Signature && (data.Signature.length > 0); - const hasHash = false;//!data.SkipVerification && data.Sha256 && (data.Sha256.length > 0); + const hasSignature = false; //! data.SkipVerification && data.Signature + //! && (data.Signature.length > 0); + const hasHash = false; //! data.SkipVerification && data.Sha256 && + //! (data.Sha256.length > 0); if (hasSignature) { try { const files = helpers.createSignatureFiles(data.Signature, Constants.DEV_PUBLIC_KEY); @@ -69,35 +75,35 @@ const addListeners = (ipcMain, {setIsInstalling, unmountAllDrives, standardIPCRe const executeInstall = () => { setIsInstalling(true); helpers - .executeAsync(command, args) - .then(() => { - cleanupFiles(); - standardIPCReply(event, Constants.IPC_Install_Upgrade_Reply) - }) - .catch(error => { - setIsInstalling(false); - errorHandler(error); - }); + .executeAsync(command, args) + .then(() => { + cleanupFiles(); + standardIPCReply(event, Constants.IPC_Install_Upgrade_Reply); + }) + .catch((error) => { + setIsInstalling(false); + errorHandler(error); + }); }; if (hasSignature) { helpers - .verifySignature(data.Source, tempSig, tempPub) - .then(() => { - executeInstall(); - }) - .catch(() => { - errorHandler(Error('Failed to verify installation package signature')); - }); + .verifySignature(data.Source, tempSig, tempPub) + .then(() => { + executeInstall(); + }) + .catch(() => { + errorHandler(Error('Failed to verify installation package signature')); + }); } else if (hasHash) { helpers - .verifyHash(data.Source, data.Sha256) - .then(()=> { - executeInstall(); - }) - .catch(() => { - errorHandler(Error('Failed to verify installation package hash')); - }); + .verifyHash(data.Source, data.Sha256) + .then(() => { + executeInstall(); + }) + .catch(() => { + errorHandler(Error('Failed to verify installation package hash')); + }); } else { if (platform === 'darwin') { setTimeout(executeInstall, 3000); @@ -111,6 +117,4 @@ const addListeners = (ipcMain, {setIsInstalling, unmountAllDrives, standardIPCRe }); }; -module.exports = { - addListeners -}; +module.exports = { addListeners }; diff --git a/src/serviceWorker.js b/src/serviceWorker.js index f8c7e50..7e472c4 100644 --- a/src/serviceWorker.js +++ b/src/serviceWorker.js @@ -15,9 +15,7 @@ const isLocalhost = Boolean( // [::1] is the IPv6 localhost address. window.location.hostname === '[::1]' || // 127.0.0.1/8 is considered localhost for IPv4. - window.location.hostname.match( - /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ - ) + window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/) ); export function register(config) { @@ -57,7 +55,7 @@ export function register(config) { function registerValidSW(swUrl, config) { navigator.serviceWorker .register(swUrl) - .then(registration => { + .then((registration) => { registration.onupdatefound = () => { const installingWorker = registration.installing; if (installingWorker == null) { @@ -93,7 +91,7 @@ function registerValidSW(swUrl, config) { }; }; }) - .catch(error => { + .catch((error) => { console.error('Error during service worker registration:', error); }); } @@ -101,7 +99,7 @@ function registerValidSW(swUrl, config) { function checkValidServiceWorker(swUrl, config) { // Check if the service worker can be found. If it can't reload the page. fetch(swUrl) - .then(response => { + .then((response) => { // Ensure service worker exists, and that we really are getting a JS file. const contentType = response.headers.get('content-type'); if ( @@ -109,7 +107,7 @@ function checkValidServiceWorker(swUrl, config) { (contentType != null && contentType.indexOf('javascript') === -1) ) { // No service worker found. Probably a different app. Reload the page. - navigator.serviceWorker.ready.then(registration => { + navigator.serviceWorker.ready.then((registration) => { registration.unregister().then(() => { window.location.reload(); }); @@ -120,15 +118,13 @@ function checkValidServiceWorker(swUrl, config) { } }) .catch(() => { - console.log( - 'No internet connection found. App is running in offline mode.' - ); + console.log('No internet connection found. App is running in offline mode.'); }); } export function unregister() { if ('serviceWorker' in navigator) { - navigator.serviceWorker.ready.then(registration => { + navigator.serviceWorker.ready.then((registration) => { registration.unregister(); }); } diff --git a/src/utils.js b/src/utils.js deleted file mode 100644 index 34ddf5d..0000000 --- a/src/utils.js +++ /dev/null @@ -1,106 +0,0 @@ -import React from 'react'; -import * as Constants from './constants'; -import Modal from './components/UI/Modal/Modal'; -import axios from 'axios'; - -const ipcRenderer = (!process.versions.hasOwnProperty('electron') && window && window.require) ? - window.require('electron').ipcRenderer : - null; - -export const checkNewReleases = selectedVersion => { - let previousReleases = localStorage.getItem('previous_releases'); - if (previousReleases) { - previousReleases = JSON.parse(previousReleases).VersionLookup; - - let currentReleases = localStorage.getItem('releases'); - if (currentReleases) { - currentReleases = JSON.parse(currentReleases).VersionLookup; - return getNewReleases(previousReleases, currentReleases, selectedVersion); - } - } - - return []; -}; - -export const createModalConditionally = (condition, jsx, critical, disableFocusTrap, transparent) => { - const modalProps = {critical: critical, disableFocusTrap: disableFocusTrap, transparent: transparent}; - return condition ? ({jsx}) : null; -}; - -export const extractFileNameFromURL = url => { - const parts = url.split('/'); - return parts[parts.length - 1]; -}; - -export const formatLinesForDisplay = lines => { - let msg = ''; - for (let i = 1; i < lines.length; i++) { - if (i > 1) { - msg += '\n'; - } - msg += (lines[i].replace(/(\\#)/gm, '#') + '\n'); - } - return msg; -}; - -export const getChangesForRepertoryVersion = version => { - return new Promise((resolve, reject) => { - const url = 'https://bitbucket.org/blockstorage/repertory/raw/' + - Constants.REPERTORY_BRANCH + '/CHANGELOG.md'; - axios - .get(url, { - responseType: 'text', - }) - .then(response => { - try { - let found = false; - let ended = false; - let lines = response.data - .replace(/(\r\n)/gm, '\n') - .split('\n') - .filter(l => { - return !ended && (l.length > 0) && (found - ? !(ended = l.startsWith('## ')) - : (found = l.startsWith(`## ${version}`))); - }); - resolve(lines); - } catch (e) { - reject(e); - } - }) - .catch(error => { - reject(error); - }); - }); -}; - -export const getIPCRenderer = () => { - return ipcRenderer; -}; - -export const getNewReleases = (existingLocations, newLocations, selectedVersion) => { - const ret = []; - if (existingLocations && newLocations) { - Constants.RELEASE_TYPES.forEach(release => { - newLocations[release] - .filter(version => (version !== selectedVersion) && !existingLocations[release].includes(version) && (version !== 'unavailable')) - .forEach(version => { - ret.splice(0, 0, { - Display: version, - Release: Constants.RELEASE_TYPES.indexOf(release), - Version: newLocations[release].indexOf(version), - VersionString: version, - }); - }); - }); - } - - return ret; -}; - -export const getSelectedVersionFromState = state => { - return (state.relver.Version === -1) ? - 'unavailable' : - state.relver.VersionLookup[Constants.RELEASE_TYPES[state.relver.Release]][state.relver.Version]; -}; - diff --git a/src/utils.jsx b/src/utils.jsx new file mode 100644 index 0000000..ae3bab9 --- /dev/null +++ b/src/utils.jsx @@ -0,0 +1,190 @@ +import axios from 'axios'; +import React from 'react'; + +import Modal from './components/UI/Modal/Modal'; +import * as Constants from './constants'; + +const ipcRenderer = + !Object.prototype.hasOwnProperty.call(process.versions, 'electron') && window && window.require + ? window.require('electron').ipcRenderer + : null; + +export const checkNewReleases = (selectedVersion) => { + let previousReleases = localStorage.getItem('previous_releases'); + if (previousReleases) { + previousReleases = JSON.parse(previousReleases).VersionLookup; + + let currentReleases = localStorage.getItem('releases'); + if (currentReleases) { + currentReleases = JSON.parse(currentReleases).VersionLookup; + return getNewReleases(previousReleases, currentReleases, selectedVersion); + } + } + + return []; +}; + +export const createDismissDisplay = (closeHandler, preventClick) => { + return ( + + ); +}; + +export const createModalConditionally = ( + condition, + jsx, + critical, + disableFocusTrap, + transparent +) => { + const modalProps = { + critical: critical, + disableFocusTrap: disableFocusTrap, + transparent: transparent, + }; + return condition ? {jsx} : null; +}; + +export const extractFileNameFromURL = (url) => { + const parts = url.split('/'); + return parts[parts.length - 1]; +}; + +export const formatLinesForDisplay = (lines) => { + let msg = ''; + for (let i = 1; i < lines.length; i++) { + if (i > 1) { + msg += '\n'; + } + msg += lines[i].replace(/(\\#)/gm, '#') + '\n'; + } + return msg; +}; + +export const getChangesForRepertoryVersion = (version) => { + return new Promise((resolve, reject) => { + const url = + 'https://bitbucket.org/blockstorage/repertory/raw/' + + Constants.REPERTORY_BRANCH + + '/CHANGELOG.md'; + axios + .get(url, { + responseType: 'text', + }) + .then((response) => { + try { + let found = false; + let ended = false; + let lines = response.data + .replace(/(\r\n)/gm, '\n') + .split('\n') + .filter((l) => { + return ( + !ended && + l.length > 0 && + (found ? !(ended = l.startsWith('## ')) : (found = l.startsWith(`## ${version}`))) + ); + }); + resolve(lines); + } catch (e) { + reject(e); + } + }) + .catch((error) => { + reject(error); + }); + }); +}; + +export const getIPCRenderer = () => { + return ipcRenderer; +}; + +export const getNewReleases = (existingLocations, newLocations, selectedVersion) => { + const ret = []; + if (existingLocations && newLocations) { + Constants.RELEASE_TYPES.forEach((release) => { + newLocations[release] + .filter( + (version) => + version !== selectedVersion && + !existingLocations[release].includes(version) && + version !== 'unavailable' + ) + .forEach((version) => { + ret.splice(0, 0, { + Display: version, + Release: Constants.RELEASE_TYPES.indexOf(release), + Version: newLocations[release].indexOf(version), + VersionString: version, + }); + }); + }); + } + + return ret; +}; + +export const getSelectedVersionFromState = (state) => { + return state.relver.Version === -1 + ? 'unavailable' + : state.relver.VersionLookup[Constants.RELEASE_TYPES[state.relver.Release]][ + state.relver.Version + ]; +}; + +export const promptLocationAndSaveFile = (fileName, data, notifyError) => { + const location = ipcRenderer.sendSync(Constants.IPC_Select_File + '_sync', { + Location: fileName, + Title: 'Save File', + }); + if (location && location.length > 0) { + const ret = ipcRenderer.sendSync(Constants.IPC_Save_File + '_sync', { + Location: location, + Data: data, + }); + if (ret.success) { + return true; + } + + notifyError(ret.error); + } + + return false; +}; + +export const promptLocationAndReadFile = (notifyError) => { + const location = ipcRenderer.sendSync(Constants.IPC_Browse_File + '_sync', { + Title: 'Open File', + }); + if (location && location.length > 0) { + const ret = ipcRenderer.sendSync(Constants.IPC_Read_File + '_sync', { + Location: location, + }); + if (ret.success) { + return ret.contents; + } + + notifyError(ret.error); + } + + return false; +};