Prettier support
This commit is contained in:
6
.prettierrc.json
Normal file
6
.prettierrc.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"trailingComma": "es5",
|
||||||
|
"tabWidth": 2,
|
||||||
|
"semi": true,
|
||||||
|
"singleQuote": true
|
||||||
|
}
|
||||||
@@ -1,14 +1,30 @@
|
|||||||
{
|
{
|
||||||
"cSpell.words": [
|
"cSpell.words": [
|
||||||
|
"APPIMAGE",
|
||||||
|
"APPPLATFORM",
|
||||||
|
"Filebase",
|
||||||
|
"HKCC",
|
||||||
|
"HKCR",
|
||||||
|
"HKCU",
|
||||||
"HKEY",
|
"HKEY",
|
||||||
"HKLM",
|
"HKLM",
|
||||||
|
"LOCALAPPDATA",
|
||||||
"Redistributable",
|
"Redistributable",
|
||||||
"Skylinks",
|
"Skylinks",
|
||||||
"Skynet",
|
"Skynet",
|
||||||
"Unmount",
|
"Unmount",
|
||||||
|
"WINFSP",
|
||||||
|
"blockstorage",
|
||||||
|
"centos",
|
||||||
"msiexec",
|
"msiexec",
|
||||||
|
"norestart",
|
||||||
|
"randomstring",
|
||||||
|
"reduxjs",
|
||||||
"relver",
|
"relver",
|
||||||
|
"scprime",
|
||||||
"siaprime",
|
"siaprime",
|
||||||
"skylink"
|
"skylink",
|
||||||
|
"undocked",
|
||||||
|
"windir"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
238
CHANGELOG.md
238
CHANGELOG.md
@@ -1,153 +1,175 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## 1.3.4
|
## 1.3.4
|
||||||
* \#55: Enable 'Activate' release instead of 'Install' in notification pop-up
|
|
||||||
|
- \#55: Enable 'Activate' release instead of 'Install' in notification pop-up
|
||||||
|
|
||||||
## 1.3.3
|
## 1.3.3
|
||||||
* \#49: Download progress is not visible if dependencies are missing
|
|
||||||
* \#51: javascript error
|
- \#49: Download progress is not visible if dependencies are missing
|
||||||
* \#52: Mount location is not set error on new install
|
- \#51: javascript error
|
||||||
* \#53: Busy notification is still visible when 'Install' button is available
|
- \#52: Mount location is not set error on new install
|
||||||
* \#54: Unable to download UI update while dependencies are being checked
|
- \#53: Busy notification is still visible when 'Install' button is available
|
||||||
* Disabled 'Install' button in new release notification
|
- \#54: Unable to download UI update while dependencies are being checked
|
||||||
|
- Disabled 'Install' button in new release notification
|
||||||
|
|
||||||
## 1.3.2
|
## 1.3.2
|
||||||
* \#48: Support pinning files to cache
|
|
||||||
* Fixed Skynet export display
|
- \#48: Support pinning files to cache
|
||||||
* Properly detect existing remote
|
- Fixed Skynet export display
|
||||||
* Reduced number of Linux binaries to:
|
- Properly detect existing remote
|
||||||
* CentOS 7
|
- Reduced number of Linux binaries to:
|
||||||
* Solus
|
- CentOS 7
|
||||||
* S3 mount support [disabled]
|
- Solus
|
||||||
|
- S3 mount support [disabled]
|
||||||
|
|
||||||
## 1.3.1
|
## 1.3.1
|
||||||
* \#45: Skynet mount support
|
|
||||||
|
- \#45: Skynet mount support
|
||||||
|
|
||||||
## 1.3.0
|
## 1.3.0
|
||||||
* \#38: Enhance new repertory release available notification
|
|
||||||
* \#46: Fix Mount Manager unmount and mount detection
|
- \#38: Enhance new repertory release available notification
|
||||||
* Skynet support
|
- \#46: Fix Mount Manager unmount and mount detection
|
||||||
* Synchronize UI major/minor version with `repertory` major/minor version
|
- Skynet support
|
||||||
* Added `Password` component
|
- Synchronize UI major/minor version with `repertory` major/minor version
|
||||||
* Reduced number of Linux binaries to:
|
- Added `Password` component
|
||||||
* CentOS 7
|
- Reduced number of Linux binaries to:
|
||||||
* Debian 9
|
- CentOS 7
|
||||||
* Debian 10
|
- Debian 9
|
||||||
* Solus
|
- Debian 10
|
||||||
* Added `FocusTrap` to modals
|
- Solus
|
||||||
|
- Added `FocusTrap` to modals
|
||||||
|
|
||||||
## 1.1.4
|
## 1.1.4
|
||||||
* \#39: Cleanup old releases and UI upgrades
|
|
||||||
|
- \#39: Cleanup old releases and UI upgrades
|
||||||
|
|
||||||
## 1.1.3
|
## 1.1.3
|
||||||
* CentOS 8 support
|
|
||||||
* Support remote send and receive timeouts
|
- CentOS 8 support
|
||||||
* Support WinFSP mount manager
|
- Support remote send and receive timeouts
|
||||||
* Fix `spawn()` failure on Windows when paths contain spaces
|
- Support WinFSP mount manager
|
||||||
|
- Fix `spawn()` failure on Windows when paths contain spaces
|
||||||
|
|
||||||
## 1.1.2
|
## 1.1.2
|
||||||
* Style changes
|
|
||||||
|
- Style changes
|
||||||
|
|
||||||
## 1.1.1
|
## 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
|
## 1.1.0
|
||||||
* \#40: Support for remote Windows mounts
|
|
||||||
* \#42: Failing to unmount on OS X
|
- \#40: Support for remote Windows mounts
|
||||||
* Allow enabling dev tools (Ctrl-Shift-I or F12)
|
- \#42: Failing to unmount on OS X
|
||||||
* ScPrime re-brand
|
- Allow enabling dev tools (Ctrl-Shift-I or F12)
|
||||||
* Ubuntu 19.10 support
|
- ScPrime re-brand
|
||||||
* Linux Mint 19.2 support
|
- Ubuntu 19.10 support
|
||||||
* Fedora 31 support
|
- Linux Mint 19.2 support
|
||||||
|
- Fedora 31 support
|
||||||
|
|
||||||
## 1.0.11 (Linux only)
|
## 1.0.11 (Linux only)
|
||||||
* Fix Ubuntu 19.10 detection
|
|
||||||
|
- Fix Ubuntu 19.10 detection
|
||||||
|
|
||||||
## 1.0.10
|
## 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)
|
## 1.0.9 (Alpha Testing Release)
|
||||||
* \#40: Support for remote Windows mounts
|
|
||||||
* ScPrime re-brand
|
- \#40: Support for remote Windows mounts
|
||||||
* Fix VC runtime detection (detect additional GUID's)
|
- ScPrime re-brand
|
||||||
|
- Fix VC runtime detection (detect additional GUID's)
|
||||||
|
|
||||||
## 1.0.8
|
## 1.0.8
|
||||||
* \#8: Add tooltips to settings
|
|
||||||
* \#36: Add ability to select Linux distribution type if OS is unsupported
|
- \#8: Add tooltips to settings
|
||||||
* \#37: Version check fails with incorrect message when VC runtime is missing
|
- \#36: Add ability to select Linux distribution type if OS is unsupported
|
||||||
* Added additional WinFsp uninstall strings
|
- \#37: Version check fails with incorrect message when VC runtime is missing
|
||||||
|
- Added additional WinFsp uninstall strings
|
||||||
|
|
||||||
## 1.0.7
|
## 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
|
- \#31: New installation displays 'Mount location is not set' on Windows
|
||||||
* \#32: Don't display network error message when check for UI updates fails
|
- \#33: Add 'Microsoft Visual C++ Redistributable' as dependency installation on Windows
|
||||||
* \#30: Add uninstall feature with reboot to handle WinFSP upgrades/downgrades
|
- \#32: Don't display network error message when check for UI updates fails
|
||||||
* \#34: Allow cancelling/closing dependency installation if version count > 1
|
- \#30: Add uninstall feature with reboot to handle WinFSP upgrades/downgrades
|
||||||
* Handle incorrect download sizes for dependencies and releases
|
- \#34: Allow cancelling/closing dependency installation if version count > 1
|
||||||
|
- Handle incorrect download sizes for dependencies and releases
|
||||||
|
|
||||||
## 1.0.6
|
## 1.0.6
|
||||||
* Additional Linux distribution support:
|
|
||||||
* Antergos
|
- Additional Linux distribution support:
|
||||||
* Manjaro
|
- Antergos
|
||||||
* Download latest `detect_linux.sh` if bundled script returns `unknown`
|
- Manjaro
|
||||||
* Display error message if OS is detected as `unknown`
|
- Download latest `detect_linux.sh` if bundled script returns `unknown`
|
||||||
|
- Display error message if OS is detected as `unknown`
|
||||||
|
|
||||||
## 1.0.5
|
## 1.0.5
|
||||||
* \#29: Mounts aren't being detected properly when switching releases
|
|
||||||
* Display window when dependencies are missing
|
- \#29: Mounts aren't being detected properly when switching releases
|
||||||
* Display window when UI upgrade is available
|
- Display window when dependencies are missing
|
||||||
* Display window and unmount all drives if release is no longer available
|
- Display window when UI upgrade is available
|
||||||
* Will primarily affect pre-release versions (Alpha, Beta, and RC)
|
- 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
|
## 1.0.4
|
||||||
* \#27: Implement Bitbucket backup download location
|
|
||||||
* \#28: Fix Linux upgrade
|
- \#27: Implement Bitbucket backup download location
|
||||||
* Additional Linux distribution support:
|
- \#28: Fix Linux upgrade
|
||||||
* Debian 10
|
- Additional Linux distribution support:
|
||||||
* OpenSUSE Leap 15.0
|
- Debian 10
|
||||||
* OpenSUSE Leap 15.1
|
- OpenSUSE Leap 15.0
|
||||||
* OpenSUSE Tumbleweed
|
- OpenSUSE Leap 15.1
|
||||||
|
- OpenSUSE Tumbleweed
|
||||||
|
|
||||||
## 1.0.3
|
## 1.0.3
|
||||||
* Linux distribution support
|
|
||||||
* Arch Linux
|
- Linux distribution support
|
||||||
* Bodhi 5.0.0
|
- Arch Linux
|
||||||
* CentOS 7
|
- Bodhi 5.0.0
|
||||||
* Debian 9
|
- CentOS 7
|
||||||
* Elementary OS 5.0
|
- Debian 9
|
||||||
* Fedora 28
|
- Elementary OS 5.0
|
||||||
* Fedora 29
|
- Fedora 28
|
||||||
* Fedora 30
|
- Fedora 29
|
||||||
* Linux Mint 19
|
- Fedora 30
|
||||||
* Linux Mint 19.1
|
- Linux Mint 19
|
||||||
* Solus
|
- Linux Mint 19.1
|
||||||
* Ubuntu 18.04
|
- Solus
|
||||||
* Ubuntu 18.10
|
- Ubuntu 18.04
|
||||||
* Ubuntu 19.04
|
- Ubuntu 18.10
|
||||||
* Removed `react-css-modules` dependency
|
- Ubuntu 19.04
|
||||||
* Removed Hyperspace (no active development/insufficient host network)
|
- Removed `react-css-modules` dependency
|
||||||
* Restore main window on error message
|
- Removed Hyperspace (no active development/insufficient host network)
|
||||||
|
- Restore main window on error message
|
||||||
|
|
||||||
## 1.0.2
|
## 1.0.2
|
||||||
* Option to launch application hidden (notification icon only)
|
|
||||||
* Close window to notification area
|
- Option to launch application hidden (notification icon only)
|
||||||
* Unmount on application exit
|
- Close window to notification area
|
||||||
* Ability to cancel mount retry on unexpected failure
|
- Unmount on application exit
|
||||||
* OS X support
|
- Ability to cancel mount retry on unexpected failure
|
||||||
* SiaPrime support
|
- OS X support
|
||||||
* Partial Linux support
|
- SiaPrime support
|
||||||
* Electron to v4
|
- Partial Linux support
|
||||||
* Prevent mount if dependencies are missing
|
- Electron to v4
|
||||||
|
- Prevent mount if dependencies are missing
|
||||||
|
|
||||||
## 1.0.1
|
## 1.0.1
|
||||||
* Added configuration settings for Repertory 1.0.0-alpha.2 and above
|
|
||||||
* Fixed memory leak on component unmount
|
- Added configuration settings for Repertory 1.0.0-alpha.2 and above
|
||||||
* Added error display
|
- Fixed memory leak on component unmount
|
||||||
* Lighter tray icon on Windows
|
- Added error display
|
||||||
* Tray icon indicates mount status on Windows
|
- Lighter tray icon on Windows
|
||||||
* Various fixes/layout changes
|
- Tray icon indicates mount status on Windows
|
||||||
|
- Various fixes/layout changes
|
||||||
|
|
||||||
## 1.0.0
|
## 1.0.0
|
||||||
* Initial release
|
|
||||||
* Windows support
|
- Initial release
|
||||||
|
- Windows support
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
# Repertory UI
|
# Repertory UI
|
||||||
* Lars Floe <lars@krankajen.se>
|
|
||||||
* Oleg Nypadymka <onypadymka@gmail.com>
|
- Lars Floe <lars@krankajen.se>
|
||||||
* Scott E. Graves <scott.e.graves@protonmail.com>
|
- Oleg Nypadymka <onypadymka@gmail.com>
|
||||||
|
- Scott E. Graves <scott.e.graves@protonmail.com>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ const {
|
|||||||
ipcMain,
|
ipcMain,
|
||||||
Menu,
|
Menu,
|
||||||
nativeImage,
|
nativeImage,
|
||||||
Tray
|
Tray,
|
||||||
} = require('electron');
|
} = require('electron');
|
||||||
const AutoLaunch = require('auto-launch');
|
const AutoLaunch = require('auto-launch');
|
||||||
const Constants = require('../src/constants');
|
const Constants = require('../src/constants');
|
||||||
@@ -44,12 +44,12 @@ const UpgradeIPC = require('../src/renderer/ipc/UpgradeIPC');
|
|||||||
const platform = os.platform();
|
const platform = os.platform();
|
||||||
|
|
||||||
const dimensions = {
|
const dimensions = {
|
||||||
height: (platform === 'win32') ? 326 : (platform === 'darwin') ? 322 : 300,
|
height: platform === 'win32' ? 326 : platform === 'darwin' ? 322 : 300,
|
||||||
width: (platform === 'win32') ? 468 : 628,
|
width: platform === 'win32' ? 468 : 628,
|
||||||
};
|
};
|
||||||
|
|
||||||
let isShutdown = false;
|
let isShutdown = false;
|
||||||
let isQuiting = false;
|
let isQuitting = false;
|
||||||
let isInstalling = false;
|
let isInstalling = false;
|
||||||
let launchHidden = false;
|
let launchHidden = false;
|
||||||
let cleanupReleases = false;
|
let cleanupReleases = false;
|
||||||
@@ -88,7 +88,7 @@ const createWindow = () => {
|
|||||||
if (platform === 'linux') {
|
if (platform === 'linux') {
|
||||||
extra = {
|
extra = {
|
||||||
icon: path.join(__dirname, '../build/', 'logo.png'),
|
icon: path.join(__dirname, '../build/', 'logo.png'),
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the browser window.
|
// Create the browser window.
|
||||||
@@ -102,27 +102,29 @@ const createWindow = () => {
|
|||||||
...extra,
|
...extra,
|
||||||
webPreferences: {
|
webPreferences: {
|
||||||
nodeIntegration: true,
|
nodeIntegration: true,
|
||||||
webSecurity: !process.env.ELECTRON_START_URL
|
webSecurity: !process.env.ELECTRON_START_URL,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
if (platform === 'linux') {
|
if (platform === 'linux') {
|
||||||
mainWindow.setMenuBarVisibility(false);
|
mainWindow.setMenuBarVisibility(false);
|
||||||
} else {
|
} else {
|
||||||
mainWindow.removeMenu();
|
mainWindow.removeMenu();
|
||||||
}
|
}
|
||||||
if ((platform === 'darwin') && launchHidden) {
|
if (platform === 'darwin' && launchHidden) {
|
||||||
app.dock.hide();
|
app.dock.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
// and load the index.html of the app.
|
// and load the index.html of the app.
|
||||||
const startUrl = process.env.ELECTRON_START_URL || url.format({
|
const startUrl =
|
||||||
|
process.env.ELECTRON_START_URL ||
|
||||||
|
url.format({
|
||||||
pathname: path.join(__dirname, '../build/index.html'),
|
pathname: path.join(__dirname, '../build/index.html'),
|
||||||
protocol: 'file:',
|
protocol: 'file:',
|
||||||
slashes: true
|
slashes: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
mainWindow.on('close', function (event) {
|
mainWindow.on('close', function (event) {
|
||||||
if (!isQuiting) {
|
if (!isQuitting) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
if (mainWindow.isVisible()) {
|
if (mainWindow.isVisible()) {
|
||||||
setWindowVisibility(false);
|
setWindowVisibility(false);
|
||||||
@@ -140,9 +142,14 @@ const createWindow = () => {
|
|||||||
MountsIPC.unmountAllDrives();
|
MountsIPC.unmountAllDrives();
|
||||||
});
|
});
|
||||||
|
|
||||||
const appPath = (platform === 'win32') ? path.resolve(path.join(app.getAppPath(), '..\\..\\repertory-ui.exe')) :
|
const appPath =
|
||||||
(platform === 'darwin') ? path.resolve(path.join(path.dirname(app.getAppPath()), '../MacOS/repertory-ui')) :
|
platform === 'win32'
|
||||||
process.env.APPIMAGE;
|
? 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({
|
const autoLauncher = new AutoLaunch({
|
||||||
name: 'Repertory UI',
|
name: 'Repertory UI',
|
||||||
@@ -151,51 +158,59 @@ const createWindow = () => {
|
|||||||
|
|
||||||
trayContextMenu = Menu.buildFromTemplate([
|
trayContextMenu = Menu.buildFromTemplate([
|
||||||
{
|
{
|
||||||
label: 'Visible', type: 'checkbox', click(item) {
|
label: 'Visible',
|
||||||
|
type: 'checkbox',
|
||||||
|
click(item) {
|
||||||
setWindowVisibility(item.checked);
|
setWindowVisibility(item.checked);
|
||||||
},
|
},
|
||||||
checked: !launchHidden,
|
checked: !launchHidden,
|
||||||
},
|
},
|
||||||
|
{ type: 'separator' },
|
||||||
{
|
{
|
||||||
type: 'separator'
|
label: 'Auto-start',
|
||||||
},
|
type: 'checkbox',
|
||||||
{
|
click(item) {
|
||||||
label: 'Auto-start', type: 'checkbox', click(item) {
|
|
||||||
if (item.checked) {
|
if (item.checked) {
|
||||||
autoLauncher.enable();
|
autoLauncher.enable();
|
||||||
} else {
|
} else {
|
||||||
autoLauncher.disable();
|
autoLauncher.disable();
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Launch Hidden', type: 'checkbox', click(item) {
|
label: 'Launch Hidden',
|
||||||
|
type: 'checkbox',
|
||||||
|
click(item) {
|
||||||
launchHidden = !!item.checked;
|
launchHidden = !!item.checked;
|
||||||
saveUiSettings();
|
saveUiSettings();
|
||||||
},
|
},
|
||||||
checked: launchHidden,
|
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;
|
cleanupReleases = !!item.checked;
|
||||||
saveUiSettings();
|
saveUiSettings();
|
||||||
},
|
},
|
||||||
checked: cleanupReleases,
|
checked: cleanupReleases,
|
||||||
},
|
},
|
||||||
|
{ type: 'separator' },
|
||||||
{
|
{
|
||||||
type: 'separator'
|
label: 'Exit and Unmount',
|
||||||
},
|
click() {
|
||||||
{
|
|
||||||
label: 'Exit and Unmount', click() {
|
|
||||||
closeApplication();
|
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);
|
mainWindowTray = new Tray(image);
|
||||||
|
|
||||||
autoLauncher
|
autoLauncher
|
||||||
@@ -203,7 +218,7 @@ const createWindow = () => {
|
|||||||
.then((enabled) => {
|
.then((enabled) => {
|
||||||
trayContextMenu.items[2].checked = enabled;
|
trayContextMenu.items[2].checked = enabled;
|
||||||
mainWindowTray.setToolTip('Repertory UI');
|
mainWindowTray.setToolTip('Repertory UI');
|
||||||
mainWindowTray.setContextMenu(trayContextMenu)
|
mainWindowTray.setContextMenu(trayContextMenu);
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
closeApplication();
|
closeApplication();
|
||||||
@@ -217,7 +232,10 @@ const getMainWindow = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const loadUiSettings = () => {
|
const loadUiSettings = () => {
|
||||||
const settingFile = path.join(helpers.resolvePath(Constants.DATA_LOCATIONS[platform]), 'ui.json');
|
const settingFile = path.join(
|
||||||
|
helpers.resolvePath(Constants.DATA_LOCATIONS[platform]),
|
||||||
|
'ui.json'
|
||||||
|
);
|
||||||
try {
|
try {
|
||||||
if (fs.statSync(settingFile).isFile()) {
|
if (fs.statSync(settingFile).isFile()) {
|
||||||
const settings = JSON.parse(fs.readFileSync(settingFile, 'utf8'));
|
const settings = JSON.parse(fs.readFileSync(settingFile, 'utf8'));
|
||||||
@@ -225,37 +243,51 @@ const loadUiSettings = () => {
|
|||||||
cleanupReleases = !!settings.cleanup_releases;
|
cleanupReleases = !!settings.cleanup_releases;
|
||||||
PlatformIPC.setPlatformOverride(settings.platform_override);
|
PlatformIPC.setPlatformOverride(settings.platform_override);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {}
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const saveUiSettings = () => {
|
const saveUiSettings = () => {
|
||||||
const settingFile = path.join(helpers.getDataDirectory(), 'ui.json');
|
const settingFile = path.join(helpers.getDataDirectory(), 'ui.json');
|
||||||
try {
|
try {
|
||||||
fs.writeFileSync(settingFile, JSON.stringify({
|
fs.writeFileSync(
|
||||||
|
settingFile,
|
||||||
|
JSON.stringify({
|
||||||
cleanup_releases: cleanupReleases,
|
cleanup_releases: cleanupReleases,
|
||||||
launch_hidden: launchHidden,
|
launch_hidden: launchHidden,
|
||||||
platform_override: PlatformIPC.getPlatformOverride(),
|
platform_override: PlatformIPC.getPlatformOverride(),
|
||||||
}), 'utf-8');
|
}),
|
||||||
} catch (e) {
|
'utf-8'
|
||||||
}
|
);
|
||||||
|
} catch (e) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
const setIsInstalling = installing => {
|
const setIsInstalling = (installing) => {
|
||||||
isInstalling = installing;
|
isInstalling = installing;
|
||||||
};
|
};
|
||||||
|
|
||||||
const setTrayImage = driveInUse => {
|
const setTrayImage = (driveInUse) => {
|
||||||
let image;
|
let image;
|
||||||
if (driveInUse) {
|
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 {
|
} 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);
|
mainWindowTray.setImage(image);
|
||||||
};
|
};
|
||||||
|
|
||||||
const setWindowVisibility = show => {
|
const setWindowVisibility = (show) => {
|
||||||
if (show) {
|
if (show) {
|
||||||
mainWindow.show();
|
mainWindow.show();
|
||||||
if (platform === 'darwin') {
|
if (platform === 'darwin') {
|
||||||
@@ -277,7 +309,7 @@ const setWindowVisibility = show => {
|
|||||||
|
|
||||||
if (trayContextMenu && mainWindowTray) {
|
if (trayContextMenu && mainWindowTray) {
|
||||||
trayContextMenu.items[0].checked = show;
|
trayContextMenu.items[0].checked = show;
|
||||||
mainWindowTray.setContextMenu(trayContextMenu)
|
mainWindowTray.setContextMenu(trayContextMenu);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -288,13 +320,13 @@ const standardIPCReply = (event, channel, data, error) => {
|
|||||||
...data,
|
...data,
|
||||||
Error: error instanceof Error ? error.toString() : error,
|
Error: error instanceof Error ? error.toString() : error,
|
||||||
Success: !error,
|
Success: !error,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
app.on('before-quit', function () {
|
app.on('before-quit', function () {
|
||||||
isQuiting = true;
|
isQuitting = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
let instanceLock = app.requestSingleInstanceLock();
|
let instanceLock = app.requestSingleInstanceLock();
|
||||||
|
|||||||
@@ -1,16 +1,22 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8"/>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
<meta
|
||||||
<meta name="theme-color" content="#000000">
|
name="viewport"
|
||||||
|
content="width=device-width, initial-scale=1, shrink-to-fit=no"
|
||||||
|
/>
|
||||||
|
<meta name="theme-color" content="#000000"/>
|
||||||
<!--
|
<!--
|
||||||
manifest.json provides metadata used when your web app is added to the
|
manifest.json provides metadata used when your web app is added to the
|
||||||
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
|
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
|
||||||
-->
|
-->
|
||||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
|
<link rel="manifest" href="%PUBLIC_URL%/manifest.json"/>
|
||||||
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
|
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico"/>
|
||||||
<link href="https://fonts.googleapis.com/css?family=Nunito:400,700" rel="stylesheet">
|
<link
|
||||||
|
href="https://fonts.googleapis.com/css?family=Nunito:400,700"
|
||||||
|
rel="stylesheet"
|
||||||
|
/>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Notice the use of %PUBLIC_URL% in the tags above.
|
Notice the use of %PUBLIC_URL% in the tags above.
|
||||||
@@ -24,9 +30,7 @@
|
|||||||
<title>Repertory UI</title>
|
<title>Repertory UI</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<noscript>
|
<noscript> You need to enable JavaScript to run this app.</noscript>
|
||||||
You need to enable JavaScript to run this app.
|
|
||||||
</noscript>
|
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
<!--
|
<!--
|
||||||
This HTML file is a template.
|
This HTML file is a template.
|
||||||
|
|||||||
282
src/App.jsx
282
src/App.jsx
@@ -2,7 +2,7 @@ import React from 'react';
|
|||||||
import './App.css';
|
import './App.css';
|
||||||
import Box from './components/UI/Box/Box';
|
import Box from './components/UI/Box/Box';
|
||||||
import Configuration from './containers/Configuration/Configuration';
|
import Configuration from './containers/Configuration/Configuration';
|
||||||
import {connect} from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import DependencyList from './components/DependencyList/DependencyList';
|
import DependencyList from './components/DependencyList/DependencyList';
|
||||||
import DownloadProgress from './components/DownloadProgress/DownloadProgress';
|
import DownloadProgress from './components/DownloadProgress/DownloadProgress';
|
||||||
import ErrorDetails from './components/ErrorDetails/ErrorDetails';
|
import ErrorDetails from './components/ErrorDetails/ErrorDetails';
|
||||||
@@ -11,17 +11,17 @@ import InfoDetails from './components/InfoDetails/InfoDetails';
|
|||||||
import IPCContainer from './containers/IPCContainer/IPCContainer';
|
import IPCContainer from './containers/IPCContainer/IPCContainer';
|
||||||
import Loading from './components/UI/Loading/Loading';
|
import Loading from './components/UI/Loading/Loading';
|
||||||
import MountItems from './containers/MountItems/MountItems';
|
import MountItems from './containers/MountItems/MountItems';
|
||||||
import NewReleases from './components/NewReleases/NewReleases';
|
import NewReleases from './components/NewReleases/NewReleases.jsx';
|
||||||
import {notifyError} from './redux/actions/error_actions';
|
import { notifyError } from './redux/actions/error_actions';
|
||||||
import Reboot from './components/Reboot/Reboot';
|
import Reboot from './components/Reboot/Reboot';
|
||||||
import {
|
import {
|
||||||
setDismissNewReleasesAvailable,
|
setDismissNewReleasesAvailable,
|
||||||
setNewReleasesAvailable
|
setNewReleasesAvailable,
|
||||||
} from './redux/actions/release_version_actions';
|
} from './redux/actions/release_version_actions';
|
||||||
import ReleaseVersionDisplay from './components/ReleaseVersionDisplay/ReleaseVersionDisplay';
|
import ReleaseVersionDisplay from './components/ReleaseVersionDisplay/ReleaseVersionDisplay';
|
||||||
import {
|
import {
|
||||||
displaySelectAppPlatform,
|
displaySelectAppPlatform,
|
||||||
saveState
|
saveState,
|
||||||
} from './redux/actions/common_actions';
|
} from './redux/actions/common_actions';
|
||||||
import SelectAppPlatform from './containers/SelectAppPlatform/SelectAppPlatform';
|
import SelectAppPlatform from './containers/SelectAppPlatform/SelectAppPlatform';
|
||||||
import Text from './components/UI/Text/Text';
|
import Text from './components/UI/Text/Text';
|
||||||
@@ -29,10 +29,10 @@ import UpgradeIcon from './components/UpgradeIcon/UpgradeIcon';
|
|||||||
import UpgradeUI from './components/UpgradeUI/UpgradeUI';
|
import UpgradeUI from './components/UpgradeUI/UpgradeUI';
|
||||||
import {
|
import {
|
||||||
loadReleases,
|
loadReleases,
|
||||||
setDismissUIUpgrade
|
setDismissUIUpgrade,
|
||||||
} from './redux/actions/release_version_actions';
|
} from './redux/actions/release_version_actions';
|
||||||
import YesNo from './components/YesNo/YesNo';
|
import YesNo from './components/YesNo/YesNo';
|
||||||
import {createModalConditionally} from './utils';
|
import { createModalConditionally } from './utils.jsx';
|
||||||
import SkynetImport from './containers/SkynetImport/SkynetImport';
|
import SkynetImport from './containers/SkynetImport/SkynetImport';
|
||||||
import ApplicationBusy from './components/ApplicationBusy/ApplicationBusy';
|
import ApplicationBusy from './components/ApplicationBusy/ApplicationBusy';
|
||||||
import SkynetExport from './containers/SkynetExport/SkynetExport';
|
import SkynetExport from './containers/SkynetExport/SkynetExport';
|
||||||
@@ -59,13 +59,17 @@ class App extends IPCContainer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate(prevProps) {
|
componentDidUpdate(prevProps) {
|
||||||
if ((prevProps.Release !== this.props.Release) ||
|
if (
|
||||||
(prevProps.ReleaseVersion !== this.props.ReleaseVersion) ||
|
prevProps.Release !== this.props.Release ||
|
||||||
(prevProps.VersionLookup !== this.props.VersionLookup)) {
|
prevProps.ReleaseVersion !== this.props.ReleaseVersion ||
|
||||||
|
prevProps.VersionLookup !== this.props.VersionLookup
|
||||||
|
) {
|
||||||
this.props.saveState();
|
this.props.saveState();
|
||||||
} else if (Object.keys(this.props.ProviderState).filter(k => {
|
} else if (
|
||||||
|
Object.keys(this.props.ProviderState).filter((k) => {
|
||||||
return this.props.ProviderState[k] !== prevProps.ProviderState[k];
|
return this.props.ProviderState[k] !== prevProps.ProviderState[k];
|
||||||
}).length > 0) {
|
}).length > 0
|
||||||
|
) {
|
||||||
this.props.saveState();
|
this.props.saveState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -76,14 +80,16 @@ class App extends IPCContainer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getSelectedVersion = () => {
|
getSelectedVersion = () => {
|
||||||
return (this.props.ReleaseVersion === -1) ?
|
return this.props.ReleaseVersion === -1
|
||||||
'unavailable' :
|
? 'unavailable'
|
||||||
this.props.VersionLookup[Constants.RELEASE_TYPES[this.props.Release]][this.props.ReleaseVersion];
|
: this.props.VersionLookup[Constants.RELEASE_TYPES[this.props.Release]][
|
||||||
|
this.props.ReleaseVersion
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
handleUpgradeIconClicked = () => {
|
handleUpgradeIconClicked = () => {
|
||||||
if (this.props.UpgradeAvailable) {
|
if (this.props.UpgradeAvailable) {
|
||||||
this.props.setDismissUIUpgrade(false)
|
this.props.setDismissUIUpgrade(false);
|
||||||
} else if (this.props.NewReleasesAvailable2.length > 0) {
|
} else if (this.props.NewReleasesAvailable2.length > 0) {
|
||||||
this.props.setNewReleasesAvailable(this.props.NewReleasesAvailable2);
|
this.props.setNewReleasesAvailable(this.props.NewReleasesAvailable2);
|
||||||
this.props.setDismissNewReleasesAvailable(false);
|
this.props.setDismissNewReleasesAvailable(false);
|
||||||
@@ -93,44 +99,54 @@ class App extends IPCContainer {
|
|||||||
render() {
|
render() {
|
||||||
const selectedVersion = this.getSelectedVersion();
|
const selectedVersion = this.getSelectedVersion();
|
||||||
|
|
||||||
const downloadEnabled = this.props.AllowDownload &&
|
const downloadEnabled =
|
||||||
|
this.props.AllowDownload &&
|
||||||
!this.props.MountsBusy &&
|
!this.props.MountsBusy &&
|
||||||
!this.props.DownloadActive &&
|
!this.props.DownloadActive &&
|
||||||
(selectedVersion !== 'unavailable') &&
|
selectedVersion !== 'unavailable' &&
|
||||||
(selectedVersion !== this.props.InstalledVersion);
|
selectedVersion !== this.props.InstalledVersion;
|
||||||
const missingDependencies = (this.props.MissingDependencies.length > 0) &&
|
const missingDependencies =
|
||||||
this.props.AllowMount;
|
this.props.MissingDependencies.length > 0 && this.props.AllowMount;
|
||||||
|
|
||||||
const allowMount = this.props.AllowMount &&
|
const allowMount =
|
||||||
|
this.props.AllowMount &&
|
||||||
this.props.InstalledVersion !== 'none' &&
|
this.props.InstalledVersion !== 'none' &&
|
||||||
!missingDependencies &&
|
!missingDependencies &&
|
||||||
!this.props.InstallActive;
|
!this.props.InstallActive;
|
||||||
|
|
||||||
const remoteSupported = this.props.LocationsLookup[selectedVersion] &&
|
const remoteSupported =
|
||||||
|
this.props.LocationsLookup[selectedVersion] &&
|
||||||
this.props.LocationsLookup[selectedVersion].supports_remote;
|
this.props.LocationsLookup[selectedVersion].supports_remote;
|
||||||
|
|
||||||
const s3Supported = this.props.LocationsLookup[selectedVersion] &&
|
const s3Supported =
|
||||||
|
this.props.LocationsLookup[selectedVersion] &&
|
||||||
this.props.LocationsLookup[selectedVersion].s3_support;
|
this.props.LocationsLookup[selectedVersion].s3_support;
|
||||||
|
|
||||||
const skynetSupported = this.props.LocationsLookup[selectedVersion] &&
|
const skynetSupported =
|
||||||
|
this.props.LocationsLookup[selectedVersion] &&
|
||||||
this.props.LocationsLookup[selectedVersion].skynet_support;
|
this.props.LocationsLookup[selectedVersion].skynet_support;
|
||||||
|
|
||||||
const scPrimeSupported = this.props.LocationsLookup[selectedVersion] &&
|
const scPrimeSupported =
|
||||||
|
this.props.LocationsLookup[selectedVersion] &&
|
||||||
this.props.LocationsLookup[selectedVersion].siaprime_support;
|
this.props.LocationsLookup[selectedVersion].siaprime_support;
|
||||||
|
|
||||||
const siaSupported = this.props.LocationsLookup[selectedVersion] &&
|
const siaSupported =
|
||||||
|
this.props.LocationsLookup[selectedVersion] &&
|
||||||
this.props.LocationsLookup[selectedVersion].sia_support;
|
this.props.LocationsLookup[selectedVersion].sia_support;
|
||||||
|
|
||||||
const showConfig = !missingDependencies &&
|
const showConfig =
|
||||||
|
!missingDependencies &&
|
||||||
!this.props.DisplayPinnedManager &&
|
!this.props.DisplayPinnedManager &&
|
||||||
this.props.DisplayConfiguration &&
|
this.props.DisplayConfiguration &&
|
||||||
!this.props.RebootRequired;
|
!this.props.RebootRequired;
|
||||||
|
|
||||||
const showPinnedManager = !missingDependencies &&
|
const showPinnedManager =
|
||||||
|
!missingDependencies &&
|
||||||
!this.props.RebootRequired &&
|
!this.props.RebootRequired &&
|
||||||
this.props.DisplayPinnedManager;
|
this.props.DisplayPinnedManager;
|
||||||
|
|
||||||
const showUpgrade = this.props.UpgradeAvailable &&
|
const showUpgrade =
|
||||||
|
this.props.UpgradeAvailable &&
|
||||||
!this.props.DisplayError &&
|
!this.props.DisplayError &&
|
||||||
!showConfig &&
|
!showConfig &&
|
||||||
!this.props.DownloadActive &&
|
!this.props.DownloadActive &&
|
||||||
@@ -138,14 +154,16 @@ class App extends IPCContainer {
|
|||||||
!this.props.InstallActive &&
|
!this.props.InstallActive &&
|
||||||
!this.props.RebootRequired;
|
!this.props.RebootRequired;
|
||||||
|
|
||||||
const showDependencies = !showUpgrade &&
|
const showDependencies =
|
||||||
|
!showUpgrade &&
|
||||||
missingDependencies &&
|
missingDependencies &&
|
||||||
!this.props.DownloadActive &&
|
!this.props.DownloadActive &&
|
||||||
!this.props.RebootRequired &&
|
!this.props.RebootRequired &&
|
||||||
!this.props.DismissDependencies &&
|
!this.props.DismissDependencies &&
|
||||||
this.props.AllowMount;
|
this.props.AllowMount;
|
||||||
|
|
||||||
const showNewReleases = !showConfig &&
|
const showNewReleases =
|
||||||
|
!showConfig &&
|
||||||
!this.props.DisplayConfirmYesNo &&
|
!this.props.DisplayConfirmYesNo &&
|
||||||
!showDependencies &&
|
!showDependencies &&
|
||||||
!this.props.DownloadActive &&
|
!this.props.DownloadActive &&
|
||||||
@@ -156,9 +174,10 @@ class App extends IPCContainer {
|
|||||||
!this.props.DisplaySelectAppPlatform &&
|
!this.props.DisplaySelectAppPlatform &&
|
||||||
!showUpgrade &&
|
!showUpgrade &&
|
||||||
!this.props.DismissNewReleasesAvailable &&
|
!this.props.DismissNewReleasesAvailable &&
|
||||||
(this.props.NewReleasesAvailable.length > 0);
|
this.props.NewReleasesAvailable.length > 0;
|
||||||
|
|
||||||
const showSkynetImport = !showConfig &&
|
const showSkynetImport =
|
||||||
|
!showConfig &&
|
||||||
!showDependencies &&
|
!showDependencies &&
|
||||||
!this.props.DownloadActive &&
|
!this.props.DownloadActive &&
|
||||||
!showNewReleases &&
|
!showNewReleases &&
|
||||||
@@ -167,7 +186,8 @@ class App extends IPCContainer {
|
|||||||
!showUpgrade &&
|
!showUpgrade &&
|
||||||
this.props.DisplayImport;
|
this.props.DisplayImport;
|
||||||
|
|
||||||
const showSkynetExport = !showConfig &&
|
const showSkynetExport =
|
||||||
|
!showConfig &&
|
||||||
!showDependencies &&
|
!showDependencies &&
|
||||||
!this.props.DownloadActive &&
|
!this.props.DownloadActive &&
|
||||||
!showNewReleases &&
|
!showNewReleases &&
|
||||||
@@ -176,66 +196,123 @@ class App extends IPCContainer {
|
|||||||
!showUpgrade &&
|
!showUpgrade &&
|
||||||
this.props.DisplayExport;
|
this.props.DisplayExport;
|
||||||
|
|
||||||
const configDisplay = createModalConditionally(showConfig, <Configuration
|
const configDisplay = createModalConditionally(
|
||||||
|
showConfig,
|
||||||
|
<Configuration
|
||||||
version={selectedVersion}
|
version={selectedVersion}
|
||||||
s3Supported={s3Supported}
|
s3Supported={s3Supported}
|
||||||
remoteSupported={remoteSupported}/>);
|
remoteSupported={remoteSupported}
|
||||||
const pinnedManagerDisplay = createModalConditionally(showPinnedManager, <PinnedManager
|
/>
|
||||||
version={selectedVersion}/>)
|
);
|
||||||
const confirmDisplay = createModalConditionally(this.props.DisplayConfirmYesNo, <YesNo/>);
|
const pinnedManagerDisplay = createModalConditionally(
|
||||||
const dependencyDisplay = createModalConditionally(showDependencies,
|
showPinnedManager,
|
||||||
<DependencyList/>, false, this.props.InstallActive);
|
<PinnedManager version={selectedVersion} />
|
||||||
const downloadDisplay = createModalConditionally(this.props.DownloadActive,
|
);
|
||||||
<DownloadProgress/>, false, true);
|
const confirmDisplay = createModalConditionally(
|
||||||
const errorDisplay = createModalConditionally(this.props.DisplayError, <ErrorDetails/>, true);
|
this.props.DisplayConfirmYesNo,
|
||||||
const infoDisplay = createModalConditionally(this.props.DisplayInfo, <InfoDetails/>, true);
|
<YesNo />
|
||||||
const newReleasesDisplay = createModalConditionally(showNewReleases, <NewReleases/>);
|
);
|
||||||
const rebootDisplay = createModalConditionally(this.props.RebootRequired, <Reboot/>);
|
const dependencyDisplay = createModalConditionally(
|
||||||
const selectAppPlatformDisplay = createModalConditionally(this.props.DisplaySelectAppPlatform,
|
showDependencies,
|
||||||
<SelectAppPlatform/>);
|
<DependencyList />,
|
||||||
const upgradeDisplay = createModalConditionally(showUpgrade, <UpgradeUI/>);
|
false,
|
||||||
const importDisplay = createModalConditionally(showSkynetImport, <SkynetImport
|
this.props.InstallActive
|
||||||
version={selectedVersion}/>);
|
);
|
||||||
const exportDisplay = createModalConditionally(showSkynetExport, <SkynetExport
|
const downloadDisplay = createModalConditionally(
|
||||||
version={selectedVersion}/>)
|
this.props.DownloadActive,
|
||||||
const appBusyDisplay = createModalConditionally(this.props.AppBusy,
|
<DownloadProgress />,
|
||||||
<ApplicationBusy/>, false, true, this.props.AppBusyTransparent);
|
false,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
const errorDisplay = createModalConditionally(
|
||||||
|
this.props.DisplayError,
|
||||||
|
<ErrorDetails />,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
const infoDisplay = createModalConditionally(
|
||||||
|
this.props.DisplayInfo,
|
||||||
|
<InfoDetails />,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
const newReleasesDisplay = createModalConditionally(
|
||||||
|
showNewReleases,
|
||||||
|
<NewReleases />
|
||||||
|
);
|
||||||
|
const rebootDisplay = createModalConditionally(
|
||||||
|
this.props.RebootRequired,
|
||||||
|
<Reboot />
|
||||||
|
);
|
||||||
|
const selectAppPlatformDisplay = createModalConditionally(
|
||||||
|
this.props.DisplaySelectAppPlatform,
|
||||||
|
<SelectAppPlatform />
|
||||||
|
);
|
||||||
|
const upgradeDisplay = createModalConditionally(showUpgrade, <UpgradeUI />);
|
||||||
|
const importDisplay = createModalConditionally(
|
||||||
|
showSkynetImport,
|
||||||
|
<SkynetImport version={selectedVersion} />
|
||||||
|
);
|
||||||
|
const exportDisplay = createModalConditionally(
|
||||||
|
showSkynetExport,
|
||||||
|
<SkynetExport version={selectedVersion} />
|
||||||
|
);
|
||||||
|
const appBusyDisplay = createModalConditionally(
|
||||||
|
this.props.AppBusy,
|
||||||
|
<ApplicationBusy />,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
this.props.AppBusyTransparent
|
||||||
|
);
|
||||||
|
|
||||||
let mainContent = [];
|
let mainContent = [];
|
||||||
if (this.props.DisplaySelectAppPlatform || !this.props.AppReady) {
|
if (this.props.DisplaySelectAppPlatform || !this.props.AppReady) {
|
||||||
mainContent = (
|
mainContent = (
|
||||||
<Box dxStyle={{height: '100%'}}>
|
<Box dxStyle={{ height: '100%' }}>
|
||||||
<Loading/>
|
<Loading />
|
||||||
</Box>);
|
</Box>
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
let key = 0;
|
let key = 0;
|
||||||
mainContent.push((
|
mainContent.push(
|
||||||
<Box key={'md_' + key++}
|
<Box
|
||||||
dxStyle={{padding: 'var(--default_spacing)', height: 'auto'}}>
|
key={'md_' + key++}
|
||||||
<ReleaseVersionDisplay downloadDisabled={!downloadEnabled}
|
dxStyle={{ padding: 'var(--default_spacing)', height: 'auto' }}
|
||||||
version={selectedVersion}/>
|
>
|
||||||
|
<ReleaseVersionDisplay
|
||||||
|
downloadDisabled={!downloadEnabled}
|
||||||
|
version={selectedVersion}
|
||||||
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
));
|
);
|
||||||
mainContent.push(<div key={'md_' + key++}
|
mainContent.push(
|
||||||
style={{paddingTop: 'var(--default_spacing)'}}/>);
|
<div
|
||||||
|
key={'md_' + key++}
|
||||||
|
style={{ paddingTop: 'var(--default_spacing)' }}
|
||||||
|
/>
|
||||||
|
);
|
||||||
if (allowMount) {
|
if (allowMount) {
|
||||||
mainContent.push((
|
mainContent.push(
|
||||||
<Box dxStyle={{padding: 'var(--default_spacing)', height: 'auto'}}
|
<Box
|
||||||
key={'md_' + key++}>
|
dxStyle={{ padding: 'var(--default_spacing)', height: 'auto' }}
|
||||||
<MountItems s3Supported={s3Supported}
|
key={'md_' + key++}
|
||||||
|
>
|
||||||
|
<MountItems
|
||||||
|
s3Supported={s3Supported}
|
||||||
remoteSupported={remoteSupported}
|
remoteSupported={remoteSupported}
|
||||||
scPrimeSupported={scPrimeSupported}
|
scPrimeSupported={scPrimeSupported}
|
||||||
siaSupported={siaSupported}
|
siaSupported={siaSupported}
|
||||||
skynetSupported={skynetSupported}/>
|
skynetSupported={skynetSupported}
|
||||||
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
));
|
);
|
||||||
} else if (!downloadEnabled && (selectedVersion !== 'unavailable')) {
|
} else if (!downloadEnabled && selectedVersion !== 'unavailable') {
|
||||||
mainContent.push((
|
mainContent.push(
|
||||||
<Box dxStyle={{padding: 'var(--default_spacing)', height: '170px'}}
|
<Box
|
||||||
key={'md_' + key++}>
|
dxStyle={{ padding: 'var(--default_spacing)', height: '170px' }}
|
||||||
<Loading/>
|
key={'md_' + key++}
|
||||||
|
>
|
||||||
|
<Loading />
|
||||||
</Box>
|
</Box>
|
||||||
));
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -245,27 +322,36 @@ class App extends IPCContainer {
|
|||||||
<div className={'AppHeader'}>
|
<div className={'AppHeader'}>
|
||||||
<Box>
|
<Box>
|
||||||
<Grid>
|
<Grid>
|
||||||
<Text col={0}
|
<Text
|
||||||
|
col={0}
|
||||||
colSpan={'remain'}
|
colSpan={'remain'}
|
||||||
row={0}
|
row={0}
|
||||||
rowSpan={'remain'}
|
rowSpan={'remain'}
|
||||||
text={'Repertory UI v' + this.props.Version}
|
text={'Repertory UI v' + this.props.Version}
|
||||||
textAlign={'center'}
|
textAlign={'center'}
|
||||||
type={'Heading1'}/>
|
type={'Heading1'}
|
||||||
|
/>
|
||||||
<UpgradeIcon
|
<UpgradeIcon
|
||||||
available={!missingDependencies && (this.props.UpgradeAvailable || (this.props.NewReleasesAvailable2.length > 0))}
|
available={
|
||||||
newReleases={!missingDependencies && (!this.props.UpgradeAvailable && (this.props.NewReleasesAvailable2.length > 0))}
|
!missingDependencies &&
|
||||||
|
(this.props.UpgradeAvailable ||
|
||||||
|
this.props.NewReleasesAvailable2.length > 0)
|
||||||
|
}
|
||||||
|
newReleases={
|
||||||
|
!missingDependencies &&
|
||||||
|
!this.props.UpgradeAvailable &&
|
||||||
|
this.props.NewReleasesAvailable2.length > 0
|
||||||
|
}
|
||||||
clicked={this.handleUpgradeIconClicked}
|
clicked={this.handleUpgradeIconClicked}
|
||||||
col={dimensions => dimensions.columns - 6}
|
col={(dimensions) => dimensions.columns - 6}
|
||||||
colSpan={5}
|
colSpan={5}
|
||||||
row={1}
|
row={1}
|
||||||
rowSpan={remain => remain - 1}/>
|
rowSpan={(remain) => remain - 1}
|
||||||
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Box>
|
</Box>
|
||||||
</div>
|
</div>
|
||||||
<div className={'AppContent'}>
|
<div className={'AppContent'}>{mainContent}</div>
|
||||||
{mainContent}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
{importDisplay}
|
{importDisplay}
|
||||||
{exportDisplay}
|
{exportDisplay}
|
||||||
@@ -286,7 +372,7 @@ class App extends IPCContainer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const mapStateToProps = state => {
|
const mapStateToProps = (state) => {
|
||||||
return {
|
return {
|
||||||
AllowDownload: state.download.AllowDownload,
|
AllowDownload: state.download.AllowDownload,
|
||||||
AllowMount: state.common.AllowMount,
|
AllowMount: state.common.AllowMount,
|
||||||
@@ -324,15 +410,19 @@ const mapStateToProps = state => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapDispatchToProps = dispatch => {
|
const mapDispatchToProps = (dispatch) => {
|
||||||
return {
|
return {
|
||||||
displaySelectAppPlatform: display => dispatch(displaySelectAppPlatform(display)),
|
displaySelectAppPlatform: (display) =>
|
||||||
|
dispatch(displaySelectAppPlatform(display)),
|
||||||
loadReleases: () => dispatch(loadReleases()),
|
loadReleases: () => dispatch(loadReleases()),
|
||||||
notifyError: (msg, critical, callback) => dispatch(notifyError(msg, critical, callback)),
|
notifyError: (msg, critical, callback) =>
|
||||||
|
dispatch(notifyError(msg, critical, callback)),
|
||||||
saveState: () => dispatch(saveState()),
|
saveState: () => dispatch(saveState()),
|
||||||
setDismissNewReleasesAvailable: dismiss => dispatch(setDismissNewReleasesAvailable(dismiss)),
|
setDismissNewReleasesAvailable: (dismiss) =>
|
||||||
setNewReleasesAvailable: items => dispatch(setNewReleasesAvailable(items)),
|
dispatch(setDismissNewReleasesAvailable(dismiss)),
|
||||||
setDismissUIUpgrade: dismiss => dispatch(setDismissUIUpgrade(dismiss)),
|
setNewReleasesAvailable: (items) =>
|
||||||
|
dispatch(setNewReleasesAvailable(items)),
|
||||||
|
setDismissUIUpgrade: (dismiss) => dispatch(setDismissUIUpgrade(dismiss)),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -3,18 +3,26 @@ import Box from '../UI/Box/Box';
|
|||||||
import Loader from 'react-loader-spinner';
|
import Loader from 'react-loader-spinner';
|
||||||
import Text from '../UI/Text/Text';
|
import Text from '../UI/Text/Text';
|
||||||
|
|
||||||
const ApplicationBusy = ({title}) => {
|
const ApplicationBusy = ({ title }) => {
|
||||||
return (
|
return (
|
||||||
<Box dxStyle={{padding: 'var(--default_spacing)'}}>
|
<Box dxStyle={{ padding: 'var(--default_spacing)' }}>
|
||||||
<Text
|
<Text
|
||||||
text={title || 'Please Wait...'}
|
text={title || 'Please Wait...'}
|
||||||
textAlign={'center'}
|
textAlign={'center'}
|
||||||
type={'Heading1'}/>
|
type={'Heading1'}
|
||||||
<div style={{paddingLeft: 'calc(50% - 16px)', paddingTop: 'var(--default_spacing)'}}>
|
/>
|
||||||
<Loader color={'var(--heading_text_color)'}
|
<div
|
||||||
|
style={{
|
||||||
|
paddingLeft: 'calc(50% - 16px)',
|
||||||
|
paddingTop: 'var(--default_spacing)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Loader
|
||||||
|
color={'var(--heading_text_color)'}
|
||||||
height={32}
|
height={32}
|
||||||
width={32}
|
width={32}
|
||||||
type='TailSpin'/>
|
type="TailSpin"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,17 +1,18 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import './Dependency.css';
|
import './Dependency.css';
|
||||||
import {connect} from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import * as Constants from '../../../constants';
|
import * as Constants from '../../../constants';
|
||||||
|
|
||||||
const mapStateToProps = state => {
|
const mapStateToProps = (state) => {
|
||||||
return {
|
return {
|
||||||
AllowDownload: (state.download.DownloadType !== Constants.INSTALL_TYPES.Dependency) &&
|
AllowDownload:
|
||||||
|
state.download.DownloadType !== Constants.INSTALL_TYPES.Dependency &&
|
||||||
!state.download.DownloadActive &&
|
!state.download.DownloadActive &&
|
||||||
!state.install.InstallActive,
|
!state.install.InstallActive,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connect(mapStateToProps)(props => {
|
export default connect(mapStateToProps)((props) => {
|
||||||
return (
|
return (
|
||||||
<div className={'Dependency'}>
|
<div className={'Dependency'}>
|
||||||
<table width="100%">
|
<table width="100%">
|
||||||
@@ -21,11 +22,20 @@ export default connect(mapStateToProps)(props => {
|
|||||||
<h3>{props.name}</h3>
|
<h3>{props.name}</h3>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{props.AllowDownload ?
|
{props.AllowDownload ? (
|
||||||
<a href={'#'}
|
<a
|
||||||
|
href={'#'}
|
||||||
className={'DependencyLink'}
|
className={'DependencyLink'}
|
||||||
onClick={()=>{props.onDownload(); return false;}}><u>Install</u></a> :
|
onClick={() => {
|
||||||
'Installing...'}
|
props.onDownload();
|
||||||
|
return false;
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<u>Install</u>
|
||||||
|
</a>
|
||||||
|
) : (
|
||||||
|
'Installing...'
|
||||||
|
)}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
@@ -1,3 +1,2 @@
|
|||||||
.DependencyList {
|
.DependencyList {
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,14 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import './DependencyList.css';
|
import './DependencyList.css';
|
||||||
import {connect} from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import * as Constants from '../../constants';
|
import * as Constants from '../../constants';
|
||||||
import Dependency from './Dependency/Dependency';
|
import Dependency from './Dependency/Dependency';
|
||||||
import Box from '../UI/Box/Box';
|
import Box from '../UI/Box/Box';
|
||||||
import {downloadItem} from '../../redux/actions/download_actions';
|
import { downloadItem } from '../../redux/actions/download_actions';
|
||||||
import {extractFileNameFromURL} from '../../utils';
|
import { extractFileNameFromURL } from '../../utils.jsx';
|
||||||
import {setDismissDependencies} from '../../redux/actions/install_actions';
|
import { setDismissDependencies } from '../../redux/actions/install_actions';
|
||||||
|
|
||||||
const mapStateToProps = state => {
|
const mapStateToProps = (state) => {
|
||||||
return {
|
return {
|
||||||
AllowDismissDependencies: state.relver.AllowDismissDependencies,
|
AllowDismissDependencies: state.relver.AllowDismissDependencies,
|
||||||
MissingDependencies: state.install.MissingDependencies,
|
MissingDependencies: state.install.MissingDependencies,
|
||||||
@@ -17,33 +17,80 @@ const mapStateToProps = state => {
|
|||||||
|
|
||||||
const mapDispatchToProps = (dispatch) => {
|
const mapDispatchToProps = (dispatch) => {
|
||||||
return {
|
return {
|
||||||
downloadItem: (name, type, url, isWinFSP) => dispatch(downloadItem(name, type, url, isWinFSP)),
|
downloadItem: (name, type, url, isWinFSP) =>
|
||||||
setDismissDependencies: dismiss => dispatch(setDismissDependencies(dismiss)),
|
dispatch(downloadItem(name, type, url, isWinFSP)),
|
||||||
|
setDismissDependencies: (dismiss) =>
|
||||||
|
dispatch(setDismissDependencies(dismiss)),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(props => {
|
export default connect(
|
||||||
const items = props.MissingDependencies.map((k, i)=> {
|
mapStateToProps,
|
||||||
|
mapDispatchToProps
|
||||||
|
)((props) => {
|
||||||
|
const items = props.MissingDependencies.map((k, i) => {
|
||||||
return (
|
return (
|
||||||
<Dependency key={i}
|
<Dependency
|
||||||
|
key={i}
|
||||||
name={k.display}
|
name={k.display}
|
||||||
onDownload={()=>props.downloadItem(extractFileNameFromURL(k.download), Constants.INSTALL_TYPES.Dependency, k.download, k.is_winfsp)}/>
|
onDownload={() =>
|
||||||
|
props.downloadItem(
|
||||||
|
extractFileNameFromURL(k.download),
|
||||||
|
Constants.INSTALL_TYPES.Dependency,
|
||||||
|
k.download,
|
||||||
|
k.is_winfsp
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
const dismissDisplay = (
|
const dismissDisplay = (
|
||||||
<div style={{float: 'right', margin: 0, paddingRight: '4px', boxSizing: 'border-box', display: 'block'}}>
|
<div
|
||||||
<a href={'#'}
|
style={{
|
||||||
onClick={props.AllowDismissDependencies ? () => props.setDismissDependencies(true) : e => e.preventDefault()}
|
float: 'right',
|
||||||
style={{cursor: props.AllowDismissDependencies ? 'pointer' : 'no-drop'}}>X</a>
|
margin: 0,
|
||||||
|
paddingRight: '4px',
|
||||||
|
boxSizing: 'border-box',
|
||||||
|
display: 'block',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
href={'#'}
|
||||||
|
onClick={
|
||||||
|
props.AllowDismissDependencies
|
||||||
|
? () => props.setDismissDependencies(true)
|
||||||
|
: (e) => e.preventDefault()
|
||||||
|
}
|
||||||
|
style={{
|
||||||
|
cursor: props.AllowDismissDependencies ? 'pointer' : 'no-drop',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
X
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box dxStyle={{width: '300px', height: 'auto', padding: '5px'}}>
|
<Box dxStyle={{ width: '300px', height: 'auto', padding: '5px' }}>
|
||||||
{dismissDisplay}
|
{dismissDisplay}
|
||||||
<div style={{width: '100%', height: 'auto', paddingBottom: '5px', boxSizing: 'border-box'}}>
|
<div
|
||||||
<h1 style={{width: '100%', textAlign: 'center', color: 'var(--text_color_error)'}}>Missing Dependencies</h1>
|
style={{
|
||||||
|
width: '100%',
|
||||||
|
height: 'auto',
|
||||||
|
paddingBottom: '5px',
|
||||||
|
boxSizing: 'border-box',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<h1
|
||||||
|
style={{
|
||||||
|
width: '100%',
|
||||||
|
textAlign: 'center',
|
||||||
|
color: 'var(--text_color_error)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Missing Dependencies
|
||||||
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
{items}
|
{items}
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import Box from '../UI/Box/Box';
|
import Box from '../UI/Box/Box';
|
||||||
import {connect} from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import './DownloadProgress.css';
|
import './DownloadProgress.css';
|
||||||
|
|
||||||
const mapStateToProps = state => {
|
const mapStateToProps = (state) => {
|
||||||
return {
|
return {
|
||||||
DownloadName: state.download.DownloadName,
|
DownloadName: state.download.DownloadName,
|
||||||
DownloadProgress: state.download.DownloadProgress,
|
DownloadProgress: state.download.DownloadProgress,
|
||||||
@@ -11,15 +11,21 @@ const mapStateToProps = state => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connect(mapStateToProps)(props => {
|
export default connect(mapStateToProps)((props) => {
|
||||||
const width = props.Platform === 'linux' ? '480px' : '380px';
|
const width = props.Platform === 'linux' ? '480px' : '380px';
|
||||||
return (
|
return (
|
||||||
<Box dxStyle={{width: width, height: 'auto', padding: '5px'}}>
|
<Box dxStyle={{ width: width, height: 'auto', padding: '5px' }}>
|
||||||
<div style={{width: '100%', height: 'auto'}}>
|
<div style={{ width: '100%', height: 'auto' }}>
|
||||||
<h1 style={{width: '100%', textAlign: 'center'}}>{'Downloading ' + props.DownloadName}</h1>
|
<h1 style={{ width: '100%', textAlign: 'center' }}>
|
||||||
|
{'Downloading ' + props.DownloadName}
|
||||||
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
<progress max={100.0} id={'download_progress'}
|
<progress
|
||||||
style={{width: '100%'}}
|
max={100.0}
|
||||||
value={props.DownloadProgress}/>
|
id={'download_progress'}
|
||||||
</Box>);
|
style={{ width: '100%' }}
|
||||||
|
value={props.DownloadProgress}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
});
|
});
|
||||||
@@ -1,25 +1,29 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {dismissError} from '../../redux/actions/error_actions';
|
import { dismissError } from '../../redux/actions/error_actions';
|
||||||
import {connect} from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import Box from '../UI/Box/Box';
|
import Box from '../UI/Box/Box';
|
||||||
import Button from '../UI/Button/Button';
|
import Button from '../UI/Button/Button';
|
||||||
import './ErrorDetails.css';
|
import './ErrorDetails.css';
|
||||||
|
|
||||||
const mapStateToProps = state => {
|
const mapStateToProps = (state) => {
|
||||||
return {
|
return {
|
||||||
ErrorMessage: state.error.ErrorStack.length > 0 ? state.error.ErrorStack[0] : '',
|
ErrorMessage:
|
||||||
|
state.error.ErrorStack.length > 0 ? state.error.ErrorStack[0] : '',
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapDispatchToProps = dispatch => {
|
const mapDispatchToProps = (dispatch) => {
|
||||||
return {
|
return {
|
||||||
dismissError: () => dispatch(dismissError()),
|
dismissError: () => dispatch(dismissError()),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(props => {
|
export default connect(
|
||||||
|
mapStateToProps,
|
||||||
|
mapDispatchToProps
|
||||||
|
)((props) => {
|
||||||
return (
|
return (
|
||||||
<Box dxDark dxStyle={{padding: 'var(--default_spacing)'}}>
|
<Box dxDark dxStyle={{ padding: 'var(--default_spacing)' }}>
|
||||||
<h1 className={'ErrorDetailsHeading'}>Application Error</h1>
|
<h1 className={'ErrorDetailsHeading'}>Application Error</h1>
|
||||||
<div className={'ErrorDetailsContent'}>
|
<div className={'ErrorDetailsContent'}>
|
||||||
<p>{props.ErrorMessage}</p>
|
<p>{props.ErrorMessage}</p>
|
||||||
|
|||||||
@@ -1,23 +1,27 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {dismissInfo} from '../../redux/actions/error_actions';
|
import { dismissInfo } from '../../redux/actions/error_actions';
|
||||||
import {connect} from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import Box from '../UI/Box/Box';
|
import Box from '../UI/Box/Box';
|
||||||
import Button from '../UI/Button/Button';
|
import Button from '../UI/Button/Button';
|
||||||
import './InfoDetails.css';
|
import './InfoDetails.css';
|
||||||
|
|
||||||
const mapStateToProps = state => {
|
const mapStateToProps = (state) => {
|
||||||
return {
|
return {
|
||||||
InfoMessage: state.error.InfoStack.length > 0 ? state.error.InfoStack[0] : '',
|
InfoMessage:
|
||||||
|
state.error.InfoStack.length > 0 ? state.error.InfoStack[0] : '',
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapDispatchToProps = dispatch => {
|
const mapDispatchToProps = (dispatch) => {
|
||||||
return {
|
return {
|
||||||
dismissInfo: () => dispatch(dismissInfo()),
|
dismissInfo: () => dispatch(dismissInfo()),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(props => {
|
export default connect(
|
||||||
|
mapStateToProps,
|
||||||
|
mapDispatchToProps
|
||||||
|
)((props) => {
|
||||||
let msg = props.InfoMessage.message;
|
let msg = props.InfoMessage.message;
|
||||||
const classes = ['InfoDetailsContent'];
|
const classes = ['InfoDetailsContent'];
|
||||||
|
|
||||||
@@ -37,7 +41,7 @@ export default connect(mapStateToProps, mapDispatchToProps)(props => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const scrollToTop = textArea => {
|
const scrollToTop = (textArea) => {
|
||||||
if (!textArea.firstClick) {
|
if (!textArea.firstClick) {
|
||||||
textArea.firstClick = true;
|
textArea.firstClick = true;
|
||||||
textArea.scrollTop = 0;
|
textArea.scrollTop = 0;
|
||||||
@@ -46,20 +50,20 @@ export default connect(mapStateToProps, mapDispatchToProps)(props => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box dxDark dxStyle={{padding: 'var(--default_spacing)'}}>
|
<Box dxDark dxStyle={{ padding: 'var(--default_spacing)' }}>
|
||||||
<h1 className={'InfoDetailsHeading'}>{props.InfoMessage.title}</h1>
|
<h1 className={'InfoDetailsHeading'}>{props.InfoMessage.title}</h1>
|
||||||
<div className={classes.join(' ')}>
|
<div className={classes.join(' ')}>
|
||||||
{
|
{copyable ? (
|
||||||
copyable ? (
|
<textarea
|
||||||
<textarea autoFocus
|
autoFocus
|
||||||
rows={9}
|
rows={9}
|
||||||
value={msg}
|
value={msg}
|
||||||
className={'SkynetImportTextArea'}
|
className={'SkynetImportTextArea'}
|
||||||
onClick={e => scrollToTop(e.target)}/>
|
onClick={(e) => scrollToTop(e.target)}
|
||||||
|
/>
|
||||||
) : (
|
) : (
|
||||||
<p style={{textAlign: 'left'}}>{msg}</p>
|
<p style={{ textAlign: 'left' }}>{msg}</p>
|
||||||
)
|
)}
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
<Button clicked={props.dismissInfo}>Dismiss</Button>
|
<Button clicked={props.dismissInfo}>Dismiss</Button>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@@ -1,83 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import {connect} from 'react-redux';
|
|
||||||
import * as Constants from '../../../constants';
|
|
||||||
import Button from '../../UI/Button/Button';
|
|
||||||
import {formatLinesForDisplay, getChangesForRepertoryVersion} from '../../../utils';
|
|
||||||
import {
|
|
||||||
notifyError,
|
|
||||||
notifyInfo
|
|
||||||
} from '../../../redux/actions/error_actions';
|
|
||||||
import {setActiveRelease} from '../../../redux/actions/release_version_actions';
|
|
||||||
import {unmountAll} from '../../../redux/actions/mount_actions';
|
|
||||||
|
|
||||||
const mapStateToProps = state => {
|
|
||||||
return {
|
|
||||||
ActiveRelease: state.relver.Release,
|
|
||||||
ActiveVersion: state.relver.Version,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const mapDispatchToProps = dispatch => {
|
|
||||||
return {
|
|
||||||
setActiveRelease: (release, version) => dispatch(setActiveRelease(release, version)),
|
|
||||||
notifyError: msg => dispatch(notifyError(msg)),
|
|
||||||
notifyInfo: (title, msg) => dispatch(notifyInfo(title, msg)),
|
|
||||||
unmountAll: completedCallback => dispatch(unmountAll(completedCallback)),
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(({
|
|
||||||
ActiveRelease,
|
|
||||||
ActiveVersion,
|
|
||||||
dismiss,
|
|
||||||
release,
|
|
||||||
lastItem,
|
|
||||||
notifyError,
|
|
||||||
notifyInfo,
|
|
||||||
setActiveRelease,
|
|
||||||
unmountAll,
|
|
||||||
}) => {
|
|
||||||
const title = '[' + Constants.RELEASE_TYPES[release.Release] + '] ' + release.Display;
|
|
||||||
const displayChanges = async () => {
|
|
||||||
try {
|
|
||||||
const lines = await getChangesForRepertoryVersion(release.VersionString);
|
|
||||||
notifyInfo(title, formatLinesForDisplay(lines));
|
|
||||||
} catch (e) {
|
|
||||||
notifyError(e);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const isActiveRelease = ((release.Release === ActiveRelease) && (release.Version === ActiveVersion));
|
|
||||||
const setReleaseAndVersion = () => {
|
|
||||||
dismiss();
|
|
||||||
unmountAll(() => {
|
|
||||||
setActiveRelease(release.Release, release.Version);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<h2>{title}</h2>
|
|
||||||
<table cellSpacing={0} cellPadding={0} width="97%">
|
|
||||||
<tbody>
|
|
||||||
<tr style={{height: '4px'}}/>
|
|
||||||
<tr>
|
|
||||||
<td width="50%">
|
|
||||||
<Button buttonStyles={{width: '100%'}} clicked={displayChanges}>Changes</Button>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div style={{width: 'var(--default_spacing)'}}/>
|
|
||||||
</td>
|
|
||||||
<td width="50%">
|
|
||||||
{!isActiveRelease ?
|
|
||||||
<Button buttonStyles={{width: '100%'}}
|
|
||||||
clicked={setReleaseAndVersion}>Activate</Button>
|
|
||||||
: null}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{lastItem ? null : <tr style={{height: 'var(--default_spacing)'}}/>}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
104
src/components/NewReleases/NewRelease/NewRelease.jsx
Normal file
104
src/components/NewReleases/NewRelease/NewRelease.jsx
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import * as Constants from '../../../constants';
|
||||||
|
import Button from '../../UI/Button/Button';
|
||||||
|
import {
|
||||||
|
formatLinesForDisplay,
|
||||||
|
getChangesForRepertoryVersion,
|
||||||
|
} from '../../../utils.jsx';
|
||||||
|
import { notifyError, notifyInfo } from '../../../redux/actions/error_actions';
|
||||||
|
import { setActiveRelease } from '../../../redux/actions/release_version_actions';
|
||||||
|
import { unmountAll } from '../../../redux/actions/mount_actions';
|
||||||
|
|
||||||
|
const mapStateToProps = (state) => {
|
||||||
|
return {
|
||||||
|
ActiveRelease: state.relver.Release,
|
||||||
|
ActiveVersion: state.relver.Version,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const mapDispatchToProps = (dispatch) => {
|
||||||
|
return {
|
||||||
|
setActiveRelease: (release, version) =>
|
||||||
|
dispatch(setActiveRelease(release, version)),
|
||||||
|
notifyError: (msg) => dispatch(notifyError(msg)),
|
||||||
|
notifyInfo: (title, msg) => dispatch(notifyInfo(title, msg)),
|
||||||
|
unmountAll: (completedCallback) => dispatch(unmountAll(completedCallback)),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default connect(
|
||||||
|
mapStateToProps,
|
||||||
|
mapDispatchToProps
|
||||||
|
)(
|
||||||
|
({
|
||||||
|
ActiveRelease,
|
||||||
|
ActiveVersion,
|
||||||
|
dismiss,
|
||||||
|
release,
|
||||||
|
lastItem,
|
||||||
|
notifyError,
|
||||||
|
notifyInfo,
|
||||||
|
setActiveRelease,
|
||||||
|
unmountAll,
|
||||||
|
}) => {
|
||||||
|
const title =
|
||||||
|
'[' + Constants.RELEASE_TYPES[release.Release] + '] ' + release.Display;
|
||||||
|
const displayChanges = async () => {
|
||||||
|
try {
|
||||||
|
const lines = await getChangesForRepertoryVersion(
|
||||||
|
release.VersionString
|
||||||
|
);
|
||||||
|
notifyInfo(title, formatLinesForDisplay(lines));
|
||||||
|
} catch (e) {
|
||||||
|
notifyError(e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const isActiveRelease =
|
||||||
|
release.Release === ActiveRelease && release.Version === ActiveVersion;
|
||||||
|
const setReleaseAndVersion = () => {
|
||||||
|
dismiss();
|
||||||
|
unmountAll(() => {
|
||||||
|
setActiveRelease(release.Release, release.Version);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h2>{title}</h2>
|
||||||
|
<table cellSpacing={0} cellPadding={0} width="97%">
|
||||||
|
<tbody>
|
||||||
|
<tr style={{ height: '4px' }} />
|
||||||
|
<tr>
|
||||||
|
<td width="50%">
|
||||||
|
<Button
|
||||||
|
buttonStyles={{ width: '100%' }}
|
||||||
|
clicked={displayChanges}
|
||||||
|
>
|
||||||
|
Changes
|
||||||
|
</Button>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div style={{ width: 'var(--default_spacing)' }} />
|
||||||
|
</td>
|
||||||
|
<td width="50%">
|
||||||
|
{!isActiveRelease ? (
|
||||||
|
<Button
|
||||||
|
buttonStyles={{ width: '100%' }}
|
||||||
|
clicked={setReleaseAndVersion}
|
||||||
|
>
|
||||||
|
Activate
|
||||||
|
</Button>
|
||||||
|
) : null}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{lastItem ? null : (
|
||||||
|
<tr style={{ height: 'var(--default_spacing)' }} />
|
||||||
|
)}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import {connect} from 'react-redux';
|
|
||||||
import Box from '../UI/Box/Box';
|
|
||||||
import Button from '../UI/Button/Button';
|
|
||||||
import NewRelease from './NewRelease/NewRelease';
|
|
||||||
import './NewReleases.css';
|
|
||||||
import {setDismissNewReleasesAvailable} from '../../redux/actions/release_version_actions';
|
|
||||||
|
|
||||||
const mapStateToProps = state => {
|
|
||||||
return {
|
|
||||||
NewReleasesAvailable: state.relver.NewReleasesAvailable,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const mapDispatchToProps = dispatch => {
|
|
||||||
return {
|
|
||||||
dismissNewReleasesAvailable: () => dispatch(setDismissNewReleasesAvailable(true)),
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(props => {
|
|
||||||
const newReleases = props.NewReleasesAvailable.map((i, idx) => {
|
|
||||||
return <NewRelease dismiss={props.dismissNewReleasesAvailable}
|
|
||||||
key={'new_release_' + i.Release + '_' + i.Version}
|
|
||||||
lastItem={idx === (props.NewReleasesAvailable.length - 1)}
|
|
||||||
release={i} />;
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Box dxDark dxStyle={{padding: 'var(--default_spacing)'}}>
|
|
||||||
<h1 className={'NewReleasesHeading'}>New Repertory Versions Available</h1>
|
|
||||||
<div className={'NewReleasesContent'}>
|
|
||||||
{newReleases}
|
|
||||||
</div>
|
|
||||||
<Button clicked={props.dismissNewReleasesAvailable}>Dismiss</Button>
|
|
||||||
</Box>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
44
src/components/NewReleases/NewReleases.jsx
Normal file
44
src/components/NewReleases/NewReleases.jsx
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import Box from '../UI/Box/Box';
|
||||||
|
import Button from '../UI/Button/Button';
|
||||||
|
import NewRelease from './NewRelease/NewRelease.jsx';
|
||||||
|
import './NewReleases.css';
|
||||||
|
import { setDismissNewReleasesAvailable } from '../../redux/actions/release_version_actions';
|
||||||
|
|
||||||
|
const mapStateToProps = (state) => {
|
||||||
|
return {
|
||||||
|
NewReleasesAvailable: state.relver.NewReleasesAvailable,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const mapDispatchToProps = (dispatch) => {
|
||||||
|
return {
|
||||||
|
dismissNewReleasesAvailable: () =>
|
||||||
|
dispatch(setDismissNewReleasesAvailable(true)),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default connect(
|
||||||
|
mapStateToProps,
|
||||||
|
mapDispatchToProps
|
||||||
|
)((props) => {
|
||||||
|
const newReleases = props.NewReleasesAvailable.map((i, idx) => {
|
||||||
|
return (
|
||||||
|
<NewRelease
|
||||||
|
dismiss={props.dismissNewReleasesAvailable}
|
||||||
|
key={'new_release_' + i.Release + '_' + i.Version}
|
||||||
|
lastItem={idx === props.NewReleasesAvailable.length - 1}
|
||||||
|
release={i}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box dxDark dxStyle={{ padding: 'var(--default_spacing)' }}>
|
||||||
|
<h1 className={'NewReleasesHeading'}>New Repertory Versions Available</h1>
|
||||||
|
<div className={'NewReleasesContent'}>{newReleases}</div>
|
||||||
|
<Button clicked={props.dismissNewReleasesAvailable}>Dismiss</Button>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
});
|
||||||
@@ -1,24 +1,27 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import './Reboot.css';
|
import './Reboot.css';
|
||||||
import {connect} from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import Box from '../UI/Box/Box';
|
import Box from '../UI/Box/Box';
|
||||||
import Button from '../UI/Button/Button';
|
import Button from '../UI/Button/Button';
|
||||||
import {rebootSystem} from '../../redux/actions/common_actions';
|
import { rebootSystem } from '../../redux/actions/common_actions';
|
||||||
|
|
||||||
const mapDispatchToProps = dispatch => {
|
const mapDispatchToProps = (dispatch) => {
|
||||||
return {
|
return {
|
||||||
rebootSystem: () => dispatch(rebootSystem()),
|
rebootSystem: () => dispatch(rebootSystem()),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connect(null, mapDispatchToProps)(props => {
|
export default connect(
|
||||||
|
null,
|
||||||
|
mapDispatchToProps
|
||||||
|
)((props) => {
|
||||||
return (
|
return (
|
||||||
<Box dxDark dxStyle={{padding: 'var(--default_spacing)'}}>
|
<Box dxDark dxStyle={{ padding: 'var(--default_spacing)' }}>
|
||||||
<h1 className={'RebootHeading'}>Reboot System</h1>
|
<h1 className={'RebootHeading'}>Reboot System</h1>
|
||||||
<div className={'RebootContent'}>
|
<div className={'RebootContent'}>
|
||||||
<p>Repertory requires a system reboot to continue.</p>
|
<p>Repertory requires a system reboot to continue.</p>
|
||||||
</div>
|
</div>
|
||||||
<Button clicked={()=>props.rebootSystem()}>Reboot Now</Button>
|
<Button clicked={() => props.rebootSystem()}>Reboot Now</Button>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -1,16 +1,16 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import './ReleaseVersionDisplay.css';
|
import './ReleaseVersionDisplay.css';
|
||||||
import * as Constants from '../../constants';
|
import * as Constants from '../../constants';
|
||||||
import {connect} from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import DropDown from '../UI/DropDown/DropDown';
|
import DropDown from '../UI/DropDown/DropDown';
|
||||||
import Grid from '../UI/Grid/Grid';
|
import Grid from '../UI/Grid/Grid';
|
||||||
import Text from '../UI/Text/Text';
|
import Text from '../UI/Text/Text';
|
||||||
import Button from '../UI/Button/Button';
|
import Button from '../UI/Button/Button';
|
||||||
import UpgradeIcon from '../UpgradeIcon/UpgradeIcon';
|
import UpgradeIcon from '../UpgradeIcon/UpgradeIcon';
|
||||||
import {setActiveRelease} from '../../redux/actions/release_version_actions';
|
import { setActiveRelease } from '../../redux/actions/release_version_actions';
|
||||||
import {downloadItem} from '../../redux/actions/download_actions';
|
import { downloadItem } from '../../redux/actions/download_actions';
|
||||||
|
|
||||||
const mapStateToProps = state => {
|
const mapStateToProps = (state) => {
|
||||||
return {
|
return {
|
||||||
AllowMount: state.common.AllowMount,
|
AllowMount: state.common.AllowMount,
|
||||||
AppPlatform: state.common.AppPlatform,
|
AppPlatform: state.common.AppPlatform,
|
||||||
@@ -28,128 +28,170 @@ const mapStateToProps = state => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapDispatchToProps = dispatch => {
|
const mapDispatchToProps = (dispatch) => {
|
||||||
return {
|
return {
|
||||||
downloadItem: (name, type, urls) => dispatch(downloadItem(name, type, urls)),
|
downloadItem: (name, type, urls) =>
|
||||||
setActiveRelease: (release, version) => dispatch(setActiveRelease(release, version)),
|
dispatch(downloadItem(name, type, urls)),
|
||||||
}
|
setActiveRelease: (release, version) =>
|
||||||
|
dispatch(setActiveRelease(release, version)),
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(props => {
|
export default connect(
|
||||||
|
mapStateToProps,
|
||||||
|
mapDispatchToProps
|
||||||
|
)((props) => {
|
||||||
const getSelectedVersion = () => {
|
const getSelectedVersion = () => {
|
||||||
return (props.ReleaseVersion === -1) ?
|
return props.ReleaseVersion === -1
|
||||||
'unavailable' :
|
? 'unavailable'
|
||||||
props.VersionLookup[Constants.RELEASE_TYPES[props.Release]][props.ReleaseVersion];
|
: props.VersionLookup[Constants.RELEASE_TYPES[props.Release]][
|
||||||
|
props.ReleaseVersion
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDownloadRelease = () => {
|
const handleDownloadRelease = () => {
|
||||||
const fileName = props.version + '.zip';
|
const fileName = props.version + '.zip';
|
||||||
props.downloadItem(fileName, Constants.INSTALL_TYPES.Release, props.LocationsLookup[props.version].urls);
|
props.downloadItem(
|
||||||
|
fileName,
|
||||||
|
Constants.INSTALL_TYPES.Release,
|
||||||
|
props.LocationsLookup[props.version].urls
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleReleaseChanged = e => {
|
const handleReleaseChanged = (e) => {
|
||||||
const release = Constants.RELEASE_TYPES.indexOf(e.target.value);
|
const release = Constants.RELEASE_TYPES.indexOf(e.target.value);
|
||||||
const releaseVersion = props.VersionLookup[Constants.RELEASE_TYPES[release]].length - 1;
|
const releaseVersion =
|
||||||
|
props.VersionLookup[Constants.RELEASE_TYPES[release]].length - 1;
|
||||||
props.setActiveRelease(release, releaseVersion);
|
props.setActiveRelease(release, releaseVersion);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleVersionChanged = e => {
|
const handleVersionChanged = (e) => {
|
||||||
const releaseVersion = props.VersionLookup[Constants.RELEASE_TYPES[props.Release]].indexOf(e.target.value);
|
const releaseVersion = props.VersionLookup[
|
||||||
|
Constants.RELEASE_TYPES[props.Release]
|
||||||
|
].indexOf(e.target.value);
|
||||||
props.setActiveRelease(props.Release, releaseVersion);
|
props.setActiveRelease(props.Release, releaseVersion);
|
||||||
};
|
};
|
||||||
|
|
||||||
const text = props.InstalledVersion + ' [' + props.AppPlatform + ']';
|
const text = props.InstalledVersion + ' [' + props.AppPlatform + ']';
|
||||||
const disabled = props.DownloadActive ||
|
const disabled =
|
||||||
|
props.DownloadActive ||
|
||||||
props.InstallActive ||
|
props.InstallActive ||
|
||||||
props.MountsBusy ||
|
props.MountsBusy ||
|
||||||
(!props.AllowMount && (getSelectedVersion() !== 'unavailable')) ;
|
(!props.AllowMount && getSelectedVersion() !== 'unavailable');
|
||||||
const releaseExtracting = (props.InstallType === Constants.INSTALL_TYPES.Release);
|
const releaseExtracting =
|
||||||
|
props.InstallType === Constants.INSTALL_TYPES.Release;
|
||||||
|
|
||||||
let optionsDisplay = [];
|
let optionsDisplay = [];
|
||||||
let key = 0;
|
let key = 0;
|
||||||
if (releaseExtracting) {
|
if (releaseExtracting) {
|
||||||
optionsDisplay.push((
|
optionsDisplay.push(
|
||||||
<Text col={dimensions => (dimensions.columns / 3) * 2}
|
<Text
|
||||||
|
col={(dimensions) => (dimensions.columns / 3) * 2}
|
||||||
colSpan={'remain'}
|
colSpan={'remain'}
|
||||||
key={key++}
|
key={key++}
|
||||||
rowSpan={4}
|
rowSpan={4}
|
||||||
text={'Activating'}
|
text={'Activating'}
|
||||||
textAlign={'left'}
|
textAlign={'left'}
|
||||||
type={'Heading2'}/>
|
type={'Heading2'}
|
||||||
));
|
/>
|
||||||
optionsDisplay.push((
|
);
|
||||||
<Text col={dimensions => (dimensions.columns / 3) * 2}
|
optionsDisplay.push(
|
||||||
|
<Text
|
||||||
|
col={(dimensions) => (dimensions.columns / 3) * 2}
|
||||||
colSpan={'remain'}
|
colSpan={'remain'}
|
||||||
key={key++}
|
key={key++}
|
||||||
row={5}
|
row={5}
|
||||||
rowSpan={7}
|
rowSpan={7}
|
||||||
text={text}
|
text={text}
|
||||||
textAlign={'left'}/>
|
textAlign={'left'}
|
||||||
));
|
/>
|
||||||
|
);
|
||||||
} else if (props.downloadDisabled || props.DismissDependencies) {
|
} else if (props.downloadDisabled || props.DismissDependencies) {
|
||||||
optionsDisplay.push((
|
optionsDisplay.push(
|
||||||
<Text col={dimensions => (dimensions.columns / 3) * 2}
|
<Text
|
||||||
|
col={(dimensions) => (dimensions.columns / 3) * 2}
|
||||||
colSpan={'remain'}
|
colSpan={'remain'}
|
||||||
key={key++}
|
key={key++}
|
||||||
rowSpan={4}
|
rowSpan={4}
|
||||||
text={'Installed'}
|
text={'Installed'}
|
||||||
textAlign={'left'}
|
textAlign={'left'}
|
||||||
type={'Heading2'}/>
|
type={'Heading2'}
|
||||||
));
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
optionsDisplay.push((
|
optionsDisplay.push(
|
||||||
<Text col={dimensions => (dimensions.columns / 3) * 2}
|
<Text
|
||||||
|
col={(dimensions) => (dimensions.columns / 3) * 2}
|
||||||
colSpan={'remain'}
|
colSpan={'remain'}
|
||||||
key={key++}
|
key={key++}
|
||||||
row={5}
|
row={5}
|
||||||
rowSpan={7}
|
rowSpan={7}
|
||||||
text={text}
|
text={text}
|
||||||
textAlign={'left'}/>
|
textAlign={'left'}
|
||||||
));
|
/>
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
optionsDisplay.push((
|
optionsDisplay.push(
|
||||||
<Button clicked={handleDownloadRelease}
|
<Button
|
||||||
col={dimensions => (dimensions.columns / 3) * 2}
|
clicked={handleDownloadRelease}
|
||||||
|
col={(dimensions) => (dimensions.columns / 3) * 2}
|
||||||
colSpan={20}
|
colSpan={20}
|
||||||
key={key++}
|
key={key++}
|
||||||
row={5}
|
row={5}
|
||||||
rowSpan={7}>Install</Button>
|
rowSpan={7}
|
||||||
));
|
>
|
||||||
|
Install
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Grid noScroll>
|
<Grid noScroll>
|
||||||
<Text colSpan={columns=>columns / 3}
|
<Text
|
||||||
|
colSpan={(columns) => columns / 3}
|
||||||
rowSpan={4}
|
rowSpan={4}
|
||||||
text={'Release'}
|
text={'Release'}
|
||||||
textAlign={'left'}
|
textAlign={'left'}
|
||||||
type={'Heading2'}/>
|
type={'Heading2'}
|
||||||
<DropDown changed={handleReleaseChanged}
|
/>
|
||||||
colSpan={remain=>remain / 3 - 1}
|
<DropDown
|
||||||
|
changed={handleReleaseChanged}
|
||||||
|
colSpan={(remain) => remain / 3 - 1}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
items={Constants.RELEASE_TYPES}
|
items={Constants.RELEASE_TYPES}
|
||||||
row={5}
|
row={5}
|
||||||
rowSpan={7}
|
rowSpan={7}
|
||||||
selected={Constants.RELEASE_TYPES[props.Release]}/>
|
selected={Constants.RELEASE_TYPES[props.Release]}
|
||||||
<Text col={dimensions => dimensions.columns / 3}
|
/>
|
||||||
colSpan={remain=>remain / 2}
|
<Text
|
||||||
|
col={(dimensions) => dimensions.columns / 3}
|
||||||
|
colSpan={(remain) => remain / 2}
|
||||||
rowSpan={4}
|
rowSpan={4}
|
||||||
text={'Version'}
|
text={'Version'}
|
||||||
textAlign={'left'}
|
textAlign={'left'}
|
||||||
type={'Heading2'}/>
|
type={'Heading2'}
|
||||||
<UpgradeIcon available={props.ReleaseUpgradeAvailable}
|
/>
|
||||||
col={dimensions => ((dimensions.columns / 3) * 2) - 6}
|
<UpgradeIcon
|
||||||
|
available={props.ReleaseUpgradeAvailable}
|
||||||
|
col={(dimensions) => (dimensions.columns / 3) * 2 - 6}
|
||||||
colSpan={4}
|
colSpan={4}
|
||||||
release
|
release
|
||||||
rowSpan={4}/>
|
rowSpan={4}
|
||||||
<DropDown changed={handleVersionChanged}
|
/>
|
||||||
col={dimensions => dimensions.columns / 3}
|
<DropDown
|
||||||
colSpan={remain=>remain / 2 - 1}
|
changed={handleVersionChanged}
|
||||||
|
col={(dimensions) => dimensions.columns / 3}
|
||||||
|
colSpan={(remain) => remain / 2 - 1}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
items={props.VersionLookup[Constants.RELEASE_TYPES[props.Release]]}
|
items={props.VersionLookup[Constants.RELEASE_TYPES[props.Release]]}
|
||||||
row={5}
|
row={5}
|
||||||
rowSpan={7}
|
rowSpan={7}
|
||||||
selected={props.VersionLookup[Constants.RELEASE_TYPES[props.Release]][props.ReleaseVersion]}/>
|
selected={
|
||||||
|
props.VersionLookup[Constants.RELEASE_TYPES[props.Release]][
|
||||||
|
props.ReleaseVersion
|
||||||
|
]
|
||||||
|
}
|
||||||
|
/>
|
||||||
{optionsDisplay}
|
{optionsDisplay}
|
||||||
</Grid>
|
</Grid>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import './Box.css';
|
import './Box.css';
|
||||||
|
|
||||||
const Box = props => {
|
const Box = (props) => {
|
||||||
const styleList = [];
|
const styleList = [];
|
||||||
styleList.push('Box');
|
styleList.push('Box');
|
||||||
if (props.dxDark) {
|
if (props.dxDark) {
|
||||||
@@ -20,7 +20,8 @@ const Box = props => {
|
|||||||
<div
|
<div
|
||||||
onClick={props.clicked}
|
onClick={props.clicked}
|
||||||
className={styleList.join(' ')}
|
className={styleList.join(' ')}
|
||||||
style={{...props.dxStyle}}>
|
style={{ ...props.dxStyle }}
|
||||||
|
>
|
||||||
{props.children}
|
{props.children}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,13 +1,17 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import './Button.css';
|
import './Button.css';
|
||||||
|
|
||||||
const Button = props => {
|
const Button = (props) => {
|
||||||
return (
|
return (
|
||||||
<button disabled={props.disabled}
|
<button
|
||||||
|
disabled={props.disabled}
|
||||||
autoFocus={props.autoFocus}
|
autoFocus={props.autoFocus}
|
||||||
className={'Button'}
|
className={'Button'}
|
||||||
style={props.buttonStyles}
|
style={props.buttonStyles}
|
||||||
onClick={props.clicked}>{props.children}</button>
|
onClick={props.clicked}
|
||||||
|
>
|
||||||
|
{props.children}
|
||||||
|
</button>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ label.CheckBoxLabel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Hide the browser's default checkbox */
|
/* Hide the browser's default checkbox */
|
||||||
label.CheckBoxLabel input[type=checkbox] {
|
label.CheckBoxLabel input[type='checkbox'] {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@@ -41,7 +41,7 @@ label.CheckBoxLabel input[type=checkbox] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* On mouse-over, add a grey background color */
|
/* On mouse-over, add a grey background color */
|
||||||
label.CheckBoxLabel:hover input[type=checkbox] ~ .CheckBoxCheckMark {
|
label.CheckBoxLabel:hover input[type='checkbox'] ~ .CheckBoxCheckMark {
|
||||||
background-color: var(--control_background_hover);
|
background-color: var(--control_background_hover);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,7 +52,7 @@ label.CheckBoxLabel input:checked ~ .CheckBoxCheckMark {
|
|||||||
|
|
||||||
/* Create the CheckBoxCheckMark/indicator (hidden when not checked) */
|
/* Create the CheckBoxCheckMark/indicator (hidden when not checked) */
|
||||||
.CheckBoxCheckMark:after {
|
.CheckBoxCheckMark:after {
|
||||||
content: "";
|
content: '';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,19 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import './CheckBox.css';
|
import './CheckBox.css';
|
||||||
|
|
||||||
const CheckBox = props => {
|
const CheckBox = (props) => {
|
||||||
return (
|
return (
|
||||||
<div className={'CheckBoxOwner'}>
|
<div className={'CheckBoxOwner'}>
|
||||||
<label className='CheckBoxLabel'>{props.label}
|
<label className="CheckBoxLabel">
|
||||||
<input checked={JSON.parse(props.checked)}
|
{props.label}
|
||||||
|
<input
|
||||||
|
checked={JSON.parse(props.checked)}
|
||||||
autoFocus={props.autoFocus}
|
autoFocus={props.autoFocus}
|
||||||
disabled={props.disabled}
|
disabled={props.disabled}
|
||||||
onChange={props.changed}
|
onChange={props.changed}
|
||||||
type='checkbox'/>
|
type="checkbox"
|
||||||
<span className='CheckBoxCheckMark'/>
|
/>
|
||||||
|
<span className="CheckBoxCheckMark" />
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -6,7 +6,8 @@
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.DropDownSelect, .DropDownSelect.Alt {
|
.DropDownSelect,
|
||||||
|
.DropDownSelect.Alt {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
display: block;
|
display: block;
|
||||||
|
|||||||
@@ -1,26 +1,32 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import './DropDown.css';
|
import './DropDown.css';
|
||||||
|
|
||||||
const DropDown = props => {
|
const DropDown = (props) => {
|
||||||
const options = props.items.map((s, i) => {
|
const options = props.items.map((s, i) => {
|
||||||
return (
|
return (
|
||||||
<option className={'DropDownOption'} key={i} value={s}>{s}</option>
|
<option className={'DropDownOption'} key={i} value={s}>
|
||||||
|
{s}
|
||||||
|
</option>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={'DropDown'}>
|
<div className={'DropDown'}>
|
||||||
<select
|
<select
|
||||||
className={'DropDownSelect' + (props.auto ? ' Auto ' : '') + (props.alt ? ' Alt ' : '')}
|
className={
|
||||||
|
'DropDownSelect' +
|
||||||
|
(props.auto ? ' Auto ' : '') +
|
||||||
|
(props.alt ? ' Alt ' : '')
|
||||||
|
}
|
||||||
autoFocus={props.autoFocus}
|
autoFocus={props.autoFocus}
|
||||||
disabled={props.disabled}
|
disabled={props.disabled}
|
||||||
onChange={props.changed}
|
onChange={props.changed}
|
||||||
value={props.selected}>
|
value={props.selected}
|
||||||
|
>
|
||||||
{options}
|
{options}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default DropDown;
|
export default DropDown;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, {Component} from 'react';
|
import React, { Component } from 'react';
|
||||||
import './Grid.css';
|
import './Grid.css';
|
||||||
import GridComponent from './GridComponent/GridComponent';
|
import GridComponent from './GridComponent/GridComponent';
|
||||||
|
|
||||||
@@ -10,14 +10,14 @@ export default class Grid extends Component {
|
|||||||
calculated: false,
|
calculated: false,
|
||||||
dimensions: {
|
dimensions: {
|
||||||
columns: 0,
|
columns: 0,
|
||||||
rows: 0
|
rows: 0,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
calculateDimensions = size => {
|
calculateDimensions = (size) => {
|
||||||
return {
|
return {
|
||||||
columns: Math.floor(size.width / this.getGridSize()),
|
columns: Math.floor(size.width / this.getGridSize()),
|
||||||
rows: Math.floor(size.height / this.getGridSize())
|
rows: Math.floor(size.height / this.getGridSize()),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -29,7 +29,7 @@ export default class Grid extends Component {
|
|||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
window.removeEventListener('resize', this.handleResize);
|
window.removeEventListener('resize', this.handleResize);
|
||||||
clearInterval(this.resizeTimeout);
|
clearInterval(this.resizeTimeout);
|
||||||
};
|
}
|
||||||
|
|
||||||
getGridSize = () => {
|
getGridSize = () => {
|
||||||
return this.props.gridSize || DEFAULT_GRID_SIZE;
|
return this.props.gridSize || DEFAULT_GRID_SIZE;
|
||||||
@@ -43,7 +43,7 @@ export default class Grid extends Component {
|
|||||||
const elem = this.refs.GridOwner;
|
const elem = this.refs.GridOwner;
|
||||||
return {
|
return {
|
||||||
height: elem ? elem.offsetHeight : 0,
|
height: elem ? elem.offsetHeight : 0,
|
||||||
width: elem ? elem.offsetWidth : 0
|
width: elem ? elem.offsetWidth : 0,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -54,15 +54,15 @@ export default class Grid extends Component {
|
|||||||
|
|
||||||
updateSize = () => {
|
updateSize = () => {
|
||||||
const state = {
|
const state = {
|
||||||
...this.state
|
...this.state,
|
||||||
};
|
};
|
||||||
const size = this.getSize();
|
const size = this.getSize();
|
||||||
const dimensions = this.calculateDimensions(size);
|
const dimensions = this.calculateDimensions(size);
|
||||||
if (state.dimensions !== dimensions) {
|
if (state.dimensions !== dimensions) {
|
||||||
this.setState({
|
this.setState({
|
||||||
calculated: true,
|
calculated: true,
|
||||||
dimensions: dimensions
|
dimensions: dimensions,
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -79,34 +79,44 @@ export default class Grid extends Component {
|
|||||||
children = React.Children.map(this.props.children, (child, i) => {
|
children = React.Children.map(this.props.children, (child, i) => {
|
||||||
if (child) {
|
if (child) {
|
||||||
let row = child.props.row || 0;
|
let row = child.props.row || 0;
|
||||||
if (typeof(row) === 'function') {
|
if (typeof row === 'function') {
|
||||||
row = row(dimensions);
|
row = row(dimensions);
|
||||||
}
|
}
|
||||||
|
|
||||||
let col = child.props.col || 0;
|
let col = child.props.col || 0;
|
||||||
if (typeof(col) === 'function') {
|
if (typeof col === 'function') {
|
||||||
col = col(dimensions);
|
col = col(dimensions);
|
||||||
}
|
}
|
||||||
|
|
||||||
let rowSpan = child.props.rowSpan;
|
let rowSpan = child.props.rowSpan;
|
||||||
if (typeof(rowSpan) === 'function') {
|
if (typeof rowSpan === 'function') {
|
||||||
rowSpan = rowSpan(dimensions.rows - row, dimensions.rows);
|
rowSpan = rowSpan(dimensions.rows - row, dimensions.rows);
|
||||||
}
|
}
|
||||||
|
|
||||||
let colSpan = child.props.colSpan;
|
let colSpan = child.props.colSpan;
|
||||||
if (typeof(colSpan) === 'function') {
|
if (typeof colSpan === 'function') {
|
||||||
colSpan = colSpan(dimensions.columns - col, dimensions.columns);
|
colSpan = colSpan(dimensions.columns - col, dimensions.columns);
|
||||||
}
|
}
|
||||||
|
|
||||||
rowSpan = rowSpan ? (rowSpan === 'remain' ? (dimensions.rows - row) : rowSpan) : null;
|
rowSpan = rowSpan
|
||||||
colSpan = colSpan ? (colSpan === 'remain' ? dimensions.columns - col : colSpan) : null;
|
? rowSpan === 'remain'
|
||||||
|
? dimensions.rows - row
|
||||||
|
: rowSpan
|
||||||
|
: null;
|
||||||
|
colSpan = colSpan
|
||||||
|
? colSpan === 'remain'
|
||||||
|
? dimensions.columns - col
|
||||||
|
: colSpan
|
||||||
|
: null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<GridComponent row={row}
|
<GridComponent
|
||||||
|
row={row}
|
||||||
col={col}
|
col={col}
|
||||||
rowSpan={rowSpan}
|
rowSpan={rowSpan}
|
||||||
colSpan={colSpan}
|
colSpan={colSpan}
|
||||||
key={'gc_' + i}>
|
key={'gc_' + i}
|
||||||
|
>
|
||||||
{child}
|
{child}
|
||||||
</GridComponent>
|
</GridComponent>
|
||||||
);
|
);
|
||||||
@@ -123,7 +133,7 @@ export default class Grid extends Component {
|
|||||||
gridTemplateRows: gridSizePx.repeat(dimensions.rows),
|
gridTemplateRows: gridSizePx.repeat(dimensions.rows),
|
||||||
gridAutoColumns: gridSizePx,
|
gridAutoColumns: gridSizePx,
|
||||||
gridAutoRows: gridSizePx,
|
gridAutoRows: gridSizePx,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if (this.props.noScroll) {
|
if (this.props.noScroll) {
|
||||||
@@ -132,13 +142,11 @@ export default class Grid extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div ref="GridOwner" className={'GridOwner'}>
|
||||||
ref='GridOwner'
|
|
||||||
className={'GridOwner'}>
|
|
||||||
<div className={'Grid'} {...style}>
|
<div className={'Grid'} {...style}>
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import './GridComponent.css';
|
import './GridComponent.css';
|
||||||
|
|
||||||
const GridComponent = props => {
|
const GridComponent = (props) => {
|
||||||
const style = {
|
const style = {
|
||||||
style: {
|
style: {
|
||||||
gridRowStart: Math.floor(props.row + 1),
|
gridRowStart: Math.floor(props.row + 1),
|
||||||
gridRowEnd: 'span ' + Math.floor(props.rowSpan || 1),
|
gridRowEnd: 'span ' + Math.floor(props.rowSpan || 1),
|
||||||
gridColumnStart: Math.floor(props.col + 1),
|
gridColumnStart: Math.floor(props.col + 1),
|
||||||
gridColumnEnd: 'span ' + Math.floor(props.colSpan || 1)
|
gridColumnEnd: 'span ' + Math.floor(props.colSpan || 1),
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -16,7 +16,6 @@ const GridComponent = props => {
|
|||||||
{props.children}
|
{props.children}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default GridComponent;
|
export default GridComponent;
|
||||||
|
|||||||
@@ -10,8 +10,9 @@
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
position: relative;
|
position: relative;
|
||||||
top: 50%; left: 50%;
|
top: 50%;
|
||||||
transform: translate(-50%,-50%);
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
width: 28px;
|
width: 28px;
|
||||||
height: 28px;
|
height: 28px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
|||||||
@@ -1,18 +1,20 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import './Loading.css'
|
import './Loading.css';
|
||||||
import Loader from 'react-loader-spinner';
|
import Loader from 'react-loader-spinner';
|
||||||
|
|
||||||
const Loading = () => {
|
const Loading = () => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div className={'Loading'}>
|
||||||
className={'Loading'}>
|
|
||||||
<div className={'LoadingContent'}>
|
<div className={'LoadingContent'}>
|
||||||
<Loader color={'var(--heading_text_color)'}
|
<Loader
|
||||||
|
color={'var(--heading_text_color)'}
|
||||||
height={28}
|
height={28}
|
||||||
width={28}
|
width={28}
|
||||||
type='ThreeDots'/>
|
type="ThreeDots"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>);
|
</div>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Loading;
|
export default Loading;
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import './Modal.css'
|
import './Modal.css';
|
||||||
import FocusTrap from 'focus-trap-react';
|
import FocusTrap from 'focus-trap-react';
|
||||||
|
|
||||||
const Modal = props => {
|
const Modal = (props) => {
|
||||||
let modalStyles = [];
|
let modalStyles = [];
|
||||||
let contentStyles = [];
|
let contentStyles = [];
|
||||||
modalStyles.push('Modal');
|
modalStyles.push('Modal');
|
||||||
@@ -19,12 +19,8 @@ const Modal = props => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<FocusTrap active={!props.disableFocusTrap}>
|
<FocusTrap active={!props.disableFocusTrap}>
|
||||||
<div
|
<div className={modalStyles.join(' ')} onClick={props.clicked}>
|
||||||
className={modalStyles.join(' ')}
|
<div className={contentStyles.join(' ')}>{props.children}</div>
|
||||||
onClick={props.clicked}>
|
|
||||||
<div className={contentStyles.join(' ')}>
|
|
||||||
{props.children}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</FocusTrap>
|
</FocusTrap>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
const RootElem = props => {
|
const RootElem = (props) => {
|
||||||
return (
|
return (
|
||||||
<div style={{margin: 0, padding: 0}} {...props}>
|
<div style={{ margin: 0, padding: 0 }} {...props}>
|
||||||
{props.children}
|
{props.children}
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default RootElem;
|
export default RootElem;
|
||||||
|
|||||||
@@ -1,28 +1,25 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import './Text.css';
|
import './Text.css';
|
||||||
|
|
||||||
const Text = props => {
|
const Text = (props) => {
|
||||||
const styleList = [];
|
const styleList = [];
|
||||||
styleList.push('Text');
|
styleList.push('Text');
|
||||||
if (props.type) {
|
if (props.type) {
|
||||||
styleList.push('Text' + props.type);
|
styleList.push('Text' + props.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
let style = {...props.style};
|
let style = { ...props.style };
|
||||||
if (props.textAlign) {
|
if (props.textAlign) {
|
||||||
style['textAlign'] = props.textAlign.toLowerCase();
|
style['textAlign'] = props.textAlign.toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
const text = (
|
const text = (
|
||||||
<div
|
<div className={styleList.join(' ')} style={style}>
|
||||||
className={styleList.join(' ')}
|
{props.text}
|
||||||
style={style}>{props.text}
|
</div>
|
||||||
</div>);
|
);
|
||||||
|
|
||||||
return props.noOwner ? text : (
|
return props.noOwner ? text : <div className={'TextOwner'}>{text}</div>;
|
||||||
<div className={'TextOwner'}>
|
|
||||||
{text}
|
|
||||||
</div>);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Text;
|
export default Text;
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
import React from 'react';
|
|
||||||
import './UpgradeIcon.css';
|
import './UpgradeIcon.css';
|
||||||
import ReactTooltip from 'react-tooltip';
|
|
||||||
import {faExclamationTriangle} from '@fortawesome/free-solid-svg-icons';
|
|
||||||
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
|
|
||||||
|
|
||||||
const UpgradeIcon = props => {
|
import { faExclamationTriangle } from '@fortawesome/free-solid-svg-icons';
|
||||||
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
|
import React from 'react';
|
||||||
|
import ReactTooltip from 'react-tooltip';
|
||||||
|
|
||||||
|
const UpgradeIcon = (props) => {
|
||||||
const styles = ['UpgradeIcon'];
|
const styles = ['UpgradeIcon'];
|
||||||
let placement = 'left';
|
let placement = 'left';
|
||||||
let toolTipText = 'UI Upgrade Available';
|
let toolTipText = 'UI Upgrade Available';
|
||||||
@@ -17,21 +18,18 @@ const UpgradeIcon = props => {
|
|||||||
toolTipText = 'New Release Available';
|
toolTipText = 'New Release Available';
|
||||||
}
|
}
|
||||||
|
|
||||||
return props
|
return props.available ? (
|
||||||
.available ?
|
|
||||||
(
|
|
||||||
<div className={'UpgradeIconOwner'}>
|
<div className={'UpgradeIconOwner'}>
|
||||||
<p data-tip='' data-for={placement}>
|
<p data-tip="" data-for={placement}>
|
||||||
<a href={'#'}
|
<a href={'#'} className={styles.join(' ')} onClick={props.clicked}>
|
||||||
className={styles.join(' ')}
|
<FontAwesomeIcon icon={faExclamationTriangle} />
|
||||||
onClick={props.clicked}>
|
|
||||||
<FontAwesomeIcon icon={faExclamationTriangle}/>
|
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
<ReactTooltip id={placement} place={placement}>{toolTipText}</ReactTooltip>
|
<ReactTooltip id={placement} place={placement}>
|
||||||
|
{toolTipText}
|
||||||
|
</ReactTooltip>
|
||||||
</div>
|
</div>
|
||||||
)
|
) : null;
|
||||||
: null;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default UpgradeIcon;
|
export default UpgradeIcon;
|
||||||
|
|||||||
@@ -1,55 +1,72 @@
|
|||||||
import {connect} from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import Button from '../UI/Button/Button';
|
import Button from '../UI/Button/Button';
|
||||||
import Box from '../UI/Box/Box';
|
import Box from '../UI/Box/Box';
|
||||||
import * as Constants from '../../constants';
|
import * as Constants from '../../constants';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import './UpgradeUI.css';
|
import './UpgradeUI.css';
|
||||||
import {setDismissUIUpgrade} from '../../redux/actions/release_version_actions';
|
import { setDismissUIUpgrade } from '../../redux/actions/release_version_actions';
|
||||||
import {downloadItem} from '../../redux/actions/download_actions';
|
import { downloadItem } from '../../redux/actions/download_actions';
|
||||||
|
|
||||||
const mapStateToProps = state => {
|
const mapStateToProps = (state) => {
|
||||||
return {
|
return {
|
||||||
Platform: state.common.Platform,
|
Platform: state.common.Platform,
|
||||||
UpgradeData: state.relver.UpgradeData,
|
UpgradeData: state.relver.UpgradeData,
|
||||||
UpgradeVersion: state.relver.UpgradeVersion,
|
UpgradeVersion: state.relver.UpgradeVersion,
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const mapDispatchToProps = dispatch => {
|
|
||||||
return {
|
|
||||||
downloadItem: (name, type, urls) => dispatch(downloadItem(name, type, urls)),
|
|
||||||
setDismissUIUpgrade: dismiss => dispatch(setDismissUIUpgrade(dismiss)),
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(props => {
|
const mapDispatchToProps = (dispatch) => {
|
||||||
|
return {
|
||||||
|
downloadItem: (name, type, urls) =>
|
||||||
|
dispatch(downloadItem(name, type, urls)),
|
||||||
|
setDismissUIUpgrade: (dismiss) => dispatch(setDismissUIUpgrade(dismiss)),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default connect(
|
||||||
|
mapStateToProps,
|
||||||
|
mapDispatchToProps
|
||||||
|
)((props) => {
|
||||||
const handleDownload = () => {
|
const handleDownload = () => {
|
||||||
const name = (props.Platform === 'win32') ?
|
const name =
|
||||||
'upgrade.exe' :
|
props.Platform === 'win32'
|
||||||
(props.Platform === 'darwin') ?
|
? 'upgrade.exe'
|
||||||
'upgrade.dmg' :
|
: props.Platform === 'darwin'
|
||||||
'repertory-ui_' + props.UpgradeVersion + '_linux_x86_64.AppImage';
|
? 'upgrade.dmg'
|
||||||
props.downloadItem(name, Constants.INSTALL_TYPES.Upgrade, props.UpgradeData.urls);
|
: 'repertory-ui_' + props.UpgradeVersion + '_linux_x86_64.AppImage';
|
||||||
|
props.downloadItem(
|
||||||
|
name,
|
||||||
|
Constants.INSTALL_TYPES.Upgrade,
|
||||||
|
props.UpgradeData.urls
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box dxStyle={{width: '180px', height: 'auto', padding: '5px'}}>
|
<Box dxStyle={{ width: '180px', height: 'auto', padding: '5px' }}>
|
||||||
<div style={{width: '100%', height: 'auto'}}>
|
<div style={{ width: '100%', height: 'auto' }}>
|
||||||
<h1 style={{width: '100%', textAlign: 'center'}}>UI Upgrade Available</h1>
|
<h1 style={{ width: '100%', textAlign: 'center' }}>
|
||||||
|
UI Upgrade Available
|
||||||
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
<table cellSpacing={5} width="100%">
|
<table cellSpacing={5} width="100%">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td width="50%">
|
<td width="50%">
|
||||||
<Button buttonStyles={{width: '100%'}}
|
<Button buttonStyles={{ width: '100%' }} clicked={handleDownload}>
|
||||||
clicked={handleDownload}>Install</Button>
|
Install
|
||||||
|
</Button>
|
||||||
</td>
|
</td>
|
||||||
<td width="50%">
|
<td width="50%">
|
||||||
<Button buttonStyles={{width: '100%'}}
|
<Button
|
||||||
clicked={() => props.setDismissUIUpgrade(true)}>Cancel</Button>
|
buttonStyles={{ width: '100%' }}
|
||||||
|
clicked={() => props.setDismissUIUpgrade(true)}
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</Box>);
|
</Box>
|
||||||
|
);
|
||||||
});
|
});
|
||||||
@@ -1,41 +1,59 @@
|
|||||||
import {connect} from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import Button from '../UI/Button/Button';
|
import Button from '../UI/Button/Button';
|
||||||
import Box from '../UI/Box/Box';
|
import Box from '../UI/Box/Box';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import './YesNo.css';
|
import './YesNo.css';
|
||||||
import {hideConfirmYesNo} from '../../redux/actions/common_actions';
|
import { hideConfirmYesNo } from '../../redux/actions/common_actions';
|
||||||
|
|
||||||
const mapStateToProps = state => {
|
const mapStateToProps = (state) => {
|
||||||
return {
|
return {
|
||||||
Title: state.common.ConfirmTitle,
|
Title: state.common.ConfirmTitle,
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const mapDispatchToProps = dispatch => {
|
|
||||||
return {
|
|
||||||
hideConfirmYesNo: confirmed => dispatch(hideConfirmYesNo(confirmed)),
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(props => {
|
const mapDispatchToProps = (dispatch) => {
|
||||||
|
return {
|
||||||
|
hideConfirmYesNo: (confirmed) => dispatch(hideConfirmYesNo(confirmed)),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default connect(
|
||||||
|
mapStateToProps,
|
||||||
|
mapDispatchToProps
|
||||||
|
)((props) => {
|
||||||
return (
|
return (
|
||||||
<Box dxStyle={{minWidth: '180px', height: 'auto', padding: 'var(--default_spacing)'}}>
|
<Box
|
||||||
<div style={{width: '100%', height: 'auto'}}>
|
dxStyle={{
|
||||||
<h1 style={{width: '100%', textAlign: 'center'}}>{props.Title}</h1>
|
minWidth: '180px',
|
||||||
|
height: 'auto',
|
||||||
|
padding: 'var(--default_spacing)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div style={{ width: '100%', height: 'auto' }}>
|
||||||
|
<h1 style={{ width: '100%', textAlign: 'center' }}>{props.Title}</h1>
|
||||||
</div>
|
</div>
|
||||||
<table cellSpacing={5} width="100%">
|
<table cellSpacing={5} width="100%">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td width="50%">
|
<td width="50%">
|
||||||
<Button buttonStyles={{width: '100%'}}
|
<Button
|
||||||
clicked={() => props.hideConfirmYesNo(true)}>Yes</Button>
|
buttonStyles={{ width: '100%' }}
|
||||||
|
clicked={() => props.hideConfirmYesNo(true)}
|
||||||
|
>
|
||||||
|
Yes
|
||||||
|
</Button>
|
||||||
</td>
|
</td>
|
||||||
<td width="50%">
|
<td width="50%">
|
||||||
<Button buttonStyles={{width: '100%'}}
|
<Button
|
||||||
clicked={() => props.hideConfirmYesNo(false)}>No</Button>
|
buttonStyles={{ width: '100%' }}
|
||||||
|
clicked={() => props.hideConfirmYesNo(false)}
|
||||||
|
>
|
||||||
|
No
|
||||||
|
</Button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</Box>);
|
</Box>
|
||||||
|
);
|
||||||
});
|
});
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
Object.defineProperty(exports, '__esModule', {value : true});
|
Object.defineProperty(exports, '__esModule', { value: true });
|
||||||
exports.DEV_PUBLIC_KEY =
|
exports.DEV_PUBLIC_KEY =
|
||||||
'-----BEGIN PUBLIC KEY-----\n' +
|
'-----BEGIN PUBLIC KEY-----\n' +
|
||||||
'MIIEIjANBgkqhkiG9w0BAQEFAAOCBA8AMIIECgKCBAEKfZmq5mMAtD4kSt2Gc/5J\n' +
|
'MIIEIjANBgkqhkiG9w0BAQEFAAOCBA8AMIIECgKCBAEKfZmq5mMAtD4kSt2Gc/5J\n' +
|
||||||
@@ -32,19 +32,21 @@ const _REPERTORY_UI_BRANCH = '1.3.x_branch';
|
|||||||
exports.REPERTORY_BRANCH = _REPERTORY_BRANCH;
|
exports.REPERTORY_BRANCH = _REPERTORY_BRANCH;
|
||||||
exports.REPERTORY_UI_BRANCH = _REPERTORY_UI_BRANCH;
|
exports.REPERTORY_UI_BRANCH = _REPERTORY_UI_BRANCH;
|
||||||
|
|
||||||
exports.RELEASES_URL = 'https://bitbucket.org/blockstorage/repertory/raw/' +
|
exports.RELEASES_URL =
|
||||||
_REPERTORY_BRANCH + '/releases_1.3.json';
|
'https://bitbucket.org/blockstorage/repertory/raw/' +
|
||||||
|
_REPERTORY_BRANCH +
|
||||||
|
'/releases_1.3.json';
|
||||||
exports.UI_RELEASES_URL =
|
exports.UI_RELEASES_URL =
|
||||||
'https://bitbucket.org/blockstorage/repertory-ui/raw/' +
|
'https://bitbucket.org/blockstorage/repertory-ui/raw/' +
|
||||||
_REPERTORY_UI_BRANCH + '/releases.json';
|
_REPERTORY_UI_BRANCH +
|
||||||
|
'/releases.json';
|
||||||
|
|
||||||
exports.LINUX_DETECT_SCRIPT_URL =
|
exports.LINUX_DETECT_SCRIPT_URL =
|
||||||
'https://bitbucket.org/blockstorage/repertory/raw/' + _REPERTORY_BRANCH +
|
'https://bitbucket.org/blockstorage/repertory/raw/' +
|
||||||
|
_REPERTORY_BRANCH +
|
||||||
'/detect_linux2.sh';
|
'/detect_linux2.sh';
|
||||||
|
|
||||||
exports.LINUX_SELECTABLE_PLATFORMS = [
|
exports.LINUX_SELECTABLE_PLATFORMS = ['centos7'];
|
||||||
'centos7',
|
|
||||||
];
|
|
||||||
|
|
||||||
exports.WINFSP_VERSION_NAMES = [
|
exports.WINFSP_VERSION_NAMES = [
|
||||||
'WinFsp 2019',
|
'WinFsp 2019',
|
||||||
@@ -68,55 +70,42 @@ exports.WINFSP_VERSION_NAMES = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
exports.DATA_LOCATIONS = {
|
exports.DATA_LOCATIONS = {
|
||||||
linux : '~/.local/repertory/ui',
|
linux: '~/.local/repertory/ui',
|
||||||
darwin : '~/Library/Application Support/repertory/ui',
|
darwin: '~/Library/Application Support/repertory/ui',
|
||||||
win32 : '%LOCALAPPDATA%\\repertory\\ui'
|
win32: '%LOCALAPPDATA%\\repertory\\ui',
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.REPERTORY_LOCATIONS = {
|
exports.REPERTORY_LOCATIONS = {
|
||||||
linux : '~/.local/repertory',
|
linux: '~/.local/repertory',
|
||||||
darwin : '~/Library/Application Support/repertory',
|
darwin: '~/Library/Application Support/repertory',
|
||||||
win32 : '%LOCALAPPDATA%\\repertory'
|
win32: '%LOCALAPPDATA%\\repertory',
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.S3_PROVIDER_LIST = [
|
exports.S3_PROVIDER_LIST = ['Filebase'];
|
||||||
'Filebase',
|
|
||||||
];
|
|
||||||
|
|
||||||
exports.S3_REGION_PROVIDER_REGION = [
|
exports.S3_REGION_PROVIDER_REGION = ['us-east-1'];
|
||||||
'us-east-1',
|
|
||||||
];
|
|
||||||
|
|
||||||
exports.S3_PROVIDER_URL = {
|
exports.S3_PROVIDER_URL = {
|
||||||
'Filebase' : 'https://s3.filebase.com',
|
Filebase: 'https://s3.filebase.com',
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.PROVIDER_LIST = [
|
exports.PROVIDER_LIST = ['Sia', 'Skynet', 'ScPrime'];
|
||||||
'Sia',
|
|
||||||
'Skynet',
|
|
||||||
'ScPrime',
|
|
||||||
];
|
|
||||||
|
|
||||||
exports.PROVIDER_ARG = {
|
exports.PROVIDER_ARG = {
|
||||||
sia : '',
|
sia: '',
|
||||||
skynet : '-sk',
|
skynet: '-sk',
|
||||||
scprime : '-sp',
|
scprime: '-sp',
|
||||||
s3 : '-s3',
|
s3: '-s3',
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.DEFAULT_RELEASE = 0;
|
exports.DEFAULT_RELEASE = 0;
|
||||||
exports.RELEASE_TYPES = [
|
exports.RELEASE_TYPES = ['Release', 'RC', 'Beta', 'Alpha'];
|
||||||
'Release',
|
|
||||||
'RC',
|
|
||||||
'Beta',
|
|
||||||
'Alpha',
|
|
||||||
];
|
|
||||||
|
|
||||||
exports.INSTALL_TYPES = {
|
exports.INSTALL_TYPES = {
|
||||||
Dependency : 'dependency',
|
Dependency: 'dependency',
|
||||||
Release : 'release',
|
Release: 'release',
|
||||||
TestRelease : 'test_release',
|
TestRelease: 'test_release',
|
||||||
Upgrade : 'upgrade',
|
Upgrade: 'upgrade',
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.IPC_Browse_Directory = 'browse_directory';
|
exports.IPC_Browse_Directory = 'browse_directory';
|
||||||
|
|||||||
@@ -1,29 +1,32 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {Component} from 'react';
|
import { Component } from 'react';
|
||||||
import './AddMount.css';
|
import './AddMount.css';
|
||||||
import {connect} from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import Button from '../../components/UI/Button/Button';
|
import Button from '../../components/UI/Button/Button';
|
||||||
import Box from '../../components/UI/Box/Box';
|
import Box from '../../components/UI/Box/Box';
|
||||||
import Text from '../../components/UI/Text/Text';
|
import Text from '../../components/UI/Text/Text';
|
||||||
import {notifyError} from '../../redux/actions/error_actions';
|
import { notifyError } from '../../redux/actions/error_actions';
|
||||||
import {addRemoteMount, addS3Mount} from '../../redux/actions/mount_actions';
|
import { addRemoteMount, addS3Mount } from '../../redux/actions/mount_actions';
|
||||||
import {createModalConditionally} from '../../utils';
|
import { createModalConditionally } from '../../utils.jsx';
|
||||||
import DropDown from '../../components/UI/DropDown/DropDown';
|
import DropDown from '../../components/UI/DropDown/DropDown';
|
||||||
import * as Constants from '../../constants';
|
import * as Constants from '../../constants';
|
||||||
|
|
||||||
const mapStateToProps = state => {
|
const mapStateToProps = (state) => {
|
||||||
return {
|
return {
|
||||||
RemoteMounts: state.mounts.RemoteMounts,
|
RemoteMounts: state.mounts.RemoteMounts,
|
||||||
S3Mounts: state.mounts.S3Mounts,
|
S3Mounts: state.mounts.S3Mounts,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapDispatchToProps = dispatch => {
|
const mapDispatchToProps = (dispatch) => {
|
||||||
return {
|
return {
|
||||||
addRemoteMount: (hostNameOrIp, port, token) => dispatch(addRemoteMount(hostNameOrIp, port, token)),
|
addRemoteMount: (hostNameOrIp, port, token) =>
|
||||||
addS3Mount: (name, accessKey, secretKey, region, bucketName, url) => dispatch(addS3Mount(name, accessKey, secretKey, region, bucketName, url)),
|
dispatch(addRemoteMount(hostNameOrIp, port, token)),
|
||||||
notifyError: (msg, critical, callback) => dispatch(notifyError(msg, critical, callback)),
|
addS3Mount: (name, accessKey, secretKey, region, bucketName, url) =>
|
||||||
}
|
dispatch(addS3Mount(name, accessKey, secretKey, region, bucketName, url)),
|
||||||
|
notifyError: (msg, critical, callback) =>
|
||||||
|
dispatch(notifyError(msg, critical, callback)),
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const default_state = {
|
const default_state = {
|
||||||
@@ -40,7 +43,11 @@ const default_state = {
|
|||||||
Token: '',
|
Token: '',
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(class extends Component {
|
export default connect(
|
||||||
|
mapStateToProps,
|
||||||
|
mapDispatchToProps
|
||||||
|
)(
|
||||||
|
class extends Component {
|
||||||
state = {
|
state = {
|
||||||
...default_state,
|
...default_state,
|
||||||
};
|
};
|
||||||
@@ -49,18 +56,26 @@ export default connect(mapStateToProps, mapDispatchToProps)(class extends Compon
|
|||||||
if (this.state.HostNameOrIp.length === 0) {
|
if (this.state.HostNameOrIp.length === 0) {
|
||||||
this.props.notifyError('Hostname or IP cannot be empty.');
|
this.props.notifyError('Hostname or IP cannot be empty.');
|
||||||
} else {
|
} else {
|
||||||
const provider = 'Remote' + this.state.HostNameOrIp + ':' + this.state.Port;
|
const provider =
|
||||||
|
'Remote' + this.state.HostNameOrIp + ':' + this.state.Port;
|
||||||
if (this.props.RemoteMounts.includes(provider)) {
|
if (this.props.RemoteMounts.includes(provider)) {
|
||||||
this.props.notifyError('Remote host already exists');
|
this.props.notifyError('Remote host already exists');
|
||||||
} else {
|
} else {
|
||||||
this.setState({
|
this.setState(
|
||||||
DisplayRemote: false
|
{
|
||||||
}, () => {
|
DisplayRemote: false,
|
||||||
this.props.addRemoteMount(this.state.HostNameOrIp, this.state.Port, this.state.Token);
|
},
|
||||||
|
() => {
|
||||||
|
this.props.addRemoteMount(
|
||||||
|
this.state.HostNameOrIp,
|
||||||
|
this.state.Port,
|
||||||
|
this.state.Token
|
||||||
|
);
|
||||||
this.setState({
|
this.setState({
|
||||||
...default_state,
|
...default_state,
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -71,21 +86,30 @@ export default connect(mapStateToProps, mapDispatchToProps)(class extends Compon
|
|||||||
} else if (this.state.AccessKey.length === 0) {
|
} else if (this.state.AccessKey.length === 0) {
|
||||||
this.props.notifyError('AccessKey cannot be empty.');
|
this.props.notifyError('AccessKey cannot be empty.');
|
||||||
} else if (this.state.SecretKey.length === 0) {
|
} else if (this.state.SecretKey.length === 0) {
|
||||||
this.props.notifyError('SecretKey cannot be empty.')
|
this.props.notifyError('SecretKey cannot be empty.');
|
||||||
} else {
|
} else {
|
||||||
const provider = 'S3' + this.state.Name;
|
const provider = 'S3' + this.state.Name;
|
||||||
if (this.props.S3Mounts.includes(provider)) {
|
if (this.props.S3Mounts.includes(provider)) {
|
||||||
this.props.notifyError('Remote host already exists');
|
this.props.notifyError('Remote host already exists');
|
||||||
} else {
|
} else {
|
||||||
this.setState({
|
this.setState(
|
||||||
DisplayS3: false
|
{
|
||||||
}, () => {
|
DisplayS3: false,
|
||||||
this.props.addS3Mount(this.state.Name, this.state.AccessKey, this.state.SecretKey,
|
},
|
||||||
this.state.Region, this.state.BucketName, Constants.S3_PROVIDER_URL[this.state.Provider]);
|
() => {
|
||||||
|
this.props.addS3Mount(
|
||||||
|
this.state.Name,
|
||||||
|
this.state.AccessKey,
|
||||||
|
this.state.SecretKey,
|
||||||
|
this.state.Region,
|
||||||
|
this.state.BucketName,
|
||||||
|
Constants.S3_PROVIDER_URL[this.state.Provider]
|
||||||
|
);
|
||||||
this.setState({
|
this.setState({
|
||||||
...default_state,
|
...default_state,
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -105,142 +129,202 @@ export default connect(mapStateToProps, mapDispatchToProps)(class extends Compon
|
|||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const displayAddRemote = createModalConditionally(this.state.DisplayRemote, (
|
const displayAddRemote = createModalConditionally(
|
||||||
<Box dxDark
|
this.state.DisplayRemote,
|
||||||
dxStyle={{width: 'auto', height: 'auto', padding: 'var(--default_spacing)'}}>
|
<Box
|
||||||
<h1 style={{textAlign: 'center', paddingBottom: 'var(--default_spacing)'}}>Add Remote
|
dxDark
|
||||||
Mount</h1>
|
dxStyle={{
|
||||||
<Text text={'Hostname or IP'}
|
width: 'auto',
|
||||||
textAlign={'left'}
|
height: 'auto',
|
||||||
type={'Heading2'}/>
|
padding: 'var(--default_spacing)',
|
||||||
<input onChange={e => this.setState({HostNameOrIp: e.target.value.trim()})}
|
}}
|
||||||
|
>
|
||||||
|
<h1
|
||||||
|
style={{
|
||||||
|
textAlign: 'center',
|
||||||
|
paddingBottom: 'var(--default_spacing)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Add Remote Mount
|
||||||
|
</h1>
|
||||||
|
<Text text={'Hostname or IP'} textAlign={'left'} type={'Heading2'} />
|
||||||
|
<input
|
||||||
|
onChange={(e) =>
|
||||||
|
this.setState({ HostNameOrIp: e.target.value.trim() })
|
||||||
|
}
|
||||||
className={'ConfigurationItemInput'}
|
className={'ConfigurationItemInput'}
|
||||||
type={'text'}
|
type={'text'}
|
||||||
value={this.state.HostNameOrIp}/>
|
value={this.state.HostNameOrIp}
|
||||||
<div style={{paddingTop: 'var(--default_spacing)'}}/>
|
/>
|
||||||
<Text text={'Port'}
|
<div style={{ paddingTop: 'var(--default_spacing)' }} />
|
||||||
textAlign={'left'}
|
<Text text={'Port'} textAlign={'left'} type={'Heading2'} />
|
||||||
type={'Heading2'}/>
|
<input
|
||||||
<input max={65535}
|
max={65535}
|
||||||
min={1025}
|
min={1025}
|
||||||
onChange={e => this.setState({Port: e.target.value})}
|
onChange={(e) => this.setState({ Port: e.target.value })}
|
||||||
className={'ConfigurationItemInput'}
|
className={'ConfigurationItemInput'}
|
||||||
type={'number'}
|
type={'number'}
|
||||||
value={this.state.Port}/>
|
value={this.state.Port}
|
||||||
<div style={{paddingTop: 'var(--default_spacing)'}}/>
|
/>
|
||||||
<Text text={'Remote Token'}
|
<div style={{ paddingTop: 'var(--default_spacing)' }} />
|
||||||
textAlign={'left'}
|
<Text text={'Remote Token'} textAlign={'left'} type={'Heading2'} />
|
||||||
type={'Heading2'}/>
|
<input
|
||||||
<input onChange={e => this.setState({Token: e.target.value})}
|
onChange={(e) => this.setState({ Token: e.target.value })}
|
||||||
className={'ConfigurationItemInput'}
|
className={'ConfigurationItemInput'}
|
||||||
type={'text'}
|
type={'text'}
|
||||||
value={this.state.Token}/>
|
value={this.state.Token}
|
||||||
<div style={{paddingTop: 'var(--default_spacing)'}}/>
|
/>
|
||||||
<div style={{display: 'flex', flexDirection: 'row'}}>
|
<div style={{ paddingTop: 'var(--default_spacing)' }} />
|
||||||
<Button buttonStyles={{width: '100%'}}
|
<div style={{ display: 'flex', flexDirection: 'row' }}>
|
||||||
clicked={() => this.addRemoteMount()}>OK</Button>
|
<Button
|
||||||
<div style={{paddingLeft: 'var(--default_spacing)'}}/>
|
buttonStyles={{ width: '100%' }}
|
||||||
<Button buttonStyles={{width: '100%'}}
|
clicked={() => this.addRemoteMount()}
|
||||||
clicked={() => this.setState({DisplayRemote: false})}>Cancel</Button>
|
>
|
||||||
|
OK
|
||||||
|
</Button>
|
||||||
|
<div style={{ paddingLeft: 'var(--default_spacing)' }} />
|
||||||
|
<Button
|
||||||
|
buttonStyles={{ width: '100%' }}
|
||||||
|
clicked={() => this.setState({ DisplayRemote: false })}
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</Box>
|
</Box>
|
||||||
));
|
);
|
||||||
|
|
||||||
const displayAddS3 = createModalConditionally(this.state.DisplayS3, (
|
const displayAddS3 = createModalConditionally(
|
||||||
<Box dxDark
|
this.state.DisplayS3,
|
||||||
dxStyle={{width: 'auto', height: 'auto', padding: 'var(--default_spacing)'}}>
|
<Box
|
||||||
<h1 style={{textAlign: 'center', paddingBottom: 'var(--default_spacing)'}}>Add S3
|
dxDark
|
||||||
Mount</h1>
|
dxStyle={{
|
||||||
<div style={{display: 'flex', flexDirection: 'row'}}>
|
width: 'auto',
|
||||||
<Text text={'Name'}
|
height: 'auto',
|
||||||
textAlign={'left'}
|
padding: 'var(--default_spacing)',
|
||||||
type={'Heading2'}/>
|
}}
|
||||||
<div style={{paddingLeft: 'var(--default_spacing)'}}/>
|
>
|
||||||
<Text text={'Provider'}
|
<h1
|
||||||
textAlign={'left'}
|
style={{
|
||||||
type={'Heading2'}/>
|
textAlign: 'center',
|
||||||
|
paddingBottom: 'var(--default_spacing)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Add S3 Mount
|
||||||
|
</h1>
|
||||||
|
<div style={{ display: 'flex', flexDirection: 'row' }}>
|
||||||
|
<Text text={'Name'} textAlign={'left'} type={'Heading2'} />
|
||||||
|
<div style={{ paddingLeft: 'var(--default_spacing)' }} />
|
||||||
|
<Text text={'Provider'} textAlign={'left'} type={'Heading2'} />
|
||||||
</div>
|
</div>
|
||||||
<div style={{display: 'flex', flexDirection: 'row'}}>
|
<div style={{ display: 'flex', flexDirection: 'row' }}>
|
||||||
<input onChange={e => this.setState({Name: e.target.value.trim()})}
|
<input
|
||||||
|
onChange={(e) => this.setState({ Name: e.target.value.trim() })}
|
||||||
className={'ConfigurationItemInput'}
|
className={'ConfigurationItemInput'}
|
||||||
style={{width: '100%'}}
|
style={{ width: '100%' }}
|
||||||
type={'text'}
|
type={'text'}
|
||||||
value={this.state.Name}/>
|
value={this.state.Name}
|
||||||
<div style={{paddingLeft: 'var(--default_spacing)'}}/>
|
/>
|
||||||
<DropDown changed={e => this.setState({Provider: e.target.value})}
|
<div style={{ paddingLeft: 'var(--default_spacing)' }} />
|
||||||
|
<DropDown
|
||||||
|
changed={(e) => this.setState({ Provider: e.target.value })}
|
||||||
items={Constants.S3_PROVIDER_LIST}
|
items={Constants.S3_PROVIDER_LIST}
|
||||||
selected={this.state.Provider}/>
|
selected={this.state.Provider}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div style={{paddingTop: 'var(--default_spacing)'}}/>
|
<div style={{ paddingTop: 'var(--default_spacing)' }} />
|
||||||
<div style={{display: 'flex', flexDirection: 'row'}}>
|
<div style={{ display: 'flex', flexDirection: 'row' }}>
|
||||||
<Text text={'Bucket Name (optional)'}
|
<Text
|
||||||
|
text={'Bucket Name (optional)'}
|
||||||
textAlign={'left'}
|
textAlign={'left'}
|
||||||
type={'Heading2'}/>
|
type={'Heading2'}
|
||||||
<div style={{paddingLeft: 'var(--default_spacing)'}}/>
|
/>
|
||||||
<Text text={'Region'}
|
<div style={{ paddingLeft: 'var(--default_spacing)' }} />
|
||||||
textAlign={'left'}
|
<Text text={'Region'} textAlign={'left'} type={'Heading2'} />
|
||||||
type={'Heading2'}/>
|
|
||||||
</div>
|
</div>
|
||||||
<div style={{display: 'flex', flexDirection: 'row'}}>
|
<div style={{ display: 'flex', flexDirection: 'row' }}>
|
||||||
<input onChange={e => this.setState({BucketName: e.target.value})}
|
<input
|
||||||
|
onChange={(e) => this.setState({ BucketName: e.target.value })}
|
||||||
className={'ConfigurationItemInput'}
|
className={'ConfigurationItemInput'}
|
||||||
style={{width: '100%'}}
|
style={{ width: '100%' }}
|
||||||
type={'text'}
|
type={'text'}
|
||||||
value={this.state.BucketName}/>
|
value={this.state.BucketName}
|
||||||
<div style={{paddingLeft: 'var(--default_spacing)'}}/>
|
/>
|
||||||
<input onChange={e => this.setState({Region: e.target.value})}
|
<div style={{ paddingLeft: 'var(--default_spacing)' }} />
|
||||||
|
<input
|
||||||
|
onChange={(e) => this.setState({ Region: e.target.value })}
|
||||||
className={'ConfigurationItemInput'}
|
className={'ConfigurationItemInput'}
|
||||||
type={'text'}
|
type={'text'}
|
||||||
value={this.state.Region}/>
|
value={this.state.Region}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div style={{paddingTop: 'var(--default_spacing)'}}/>
|
<div style={{ paddingTop: 'var(--default_spacing)' }} />
|
||||||
<div style={{display: 'flex', flexDirection: 'row'}}>
|
<div style={{ display: 'flex', flexDirection: 'row' }}>
|
||||||
<Text text={'Access Key'}
|
<Text text={'Access Key'} textAlign={'left'} type={'Heading2'} />
|
||||||
textAlign={'left'}
|
<div style={{ paddingLeft: 'var(--default_spacing)' }} />
|
||||||
type={'Heading2'}/>
|
<Text text={'Secret Key'} textAlign={'left'} type={'Heading2'} />
|
||||||
<div style={{paddingLeft: 'var(--default_spacing)'}}/>
|
|
||||||
<Text text={'Secret Key'}
|
|
||||||
textAlign={'left'}
|
|
||||||
type={'Heading2'}/>
|
|
||||||
</div>
|
</div>
|
||||||
<div style={{display: 'flex', flexDirection: 'row'}}>
|
<div style={{ display: 'flex', flexDirection: 'row' }}>
|
||||||
<input onChange={e => this.setState({AccessKey: e.target.value})}
|
<input
|
||||||
|
onChange={(e) => this.setState({ AccessKey: e.target.value })}
|
||||||
className={'ConfigurationItemInput'}
|
className={'ConfigurationItemInput'}
|
||||||
type={'text'}
|
type={'text'}
|
||||||
value={this.state.AccessKey}/>
|
value={this.state.AccessKey}
|
||||||
<div style={{paddingLeft: 'var(--default_spacing)'}}/>
|
/>
|
||||||
<input onChange={e => this.setState({SecretKey: e.target.value})}
|
<div style={{ paddingLeft: 'var(--default_spacing)' }} />
|
||||||
|
<input
|
||||||
|
onChange={(e) => this.setState({ SecretKey: e.target.value })}
|
||||||
className={'ConfigurationItemInput'}
|
className={'ConfigurationItemInput'}
|
||||||
type={'text'}
|
type={'text'}
|
||||||
value={this.state.SecretKey}/>
|
value={this.state.SecretKey}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div style={{paddingTop: 'calc(var(--default_spacing) * 2)'}}/>
|
<div style={{ paddingTop: 'calc(var(--default_spacing) * 2)' }} />
|
||||||
<div style={{display: 'flex', flexDirection: 'row'}}>
|
<div style={{ display: 'flex', flexDirection: 'row' }}>
|
||||||
<div style={{width: '200%'}}/>
|
<div style={{ width: '200%' }} />
|
||||||
<Button buttonStyles={{width: '100%'}}
|
<Button
|
||||||
clicked={() => this.addS3Mount()}>OK</Button>
|
buttonStyles={{ width: '100%' }}
|
||||||
<div style={{paddingLeft: 'var(--default_spacing)'}}/>
|
clicked={() => this.addS3Mount()}
|
||||||
<Button buttonStyles={{width: '100%'}}
|
>
|
||||||
clicked={() => this.setState({DisplayS3: false})}>Cancel</Button>
|
OK
|
||||||
|
</Button>
|
||||||
|
<div style={{ paddingLeft: 'var(--default_spacing)' }} />
|
||||||
|
<Button
|
||||||
|
buttonStyles={{ width: '100%' }}
|
||||||
|
clicked={() => this.setState({ DisplayS3: false })}
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</Box>
|
</Box>
|
||||||
));
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={'AddMount'}>
|
<div className={'AddMount'}>
|
||||||
{displayAddRemote}
|
{displayAddRemote}
|
||||||
{displayAddS3}
|
{displayAddS3}
|
||||||
<div className={'AddMountButtons'}>
|
<div className={'AddMountButtons'}>
|
||||||
{this.props.remoteSupported ?
|
{this.props.remoteSupported ? (
|
||||||
<Button className={'AddMountButton'}
|
<Button
|
||||||
clicked={this.handleAddRemoteMount}>Add Remote Mount</Button> : null}
|
className={'AddMountButton'}
|
||||||
{this.props.remoteSupported && this.props.s3Supported ?
|
clicked={this.handleAddRemoteMount}
|
||||||
<div style={{paddingRight: 'var(--default_spacing)'}}/> : null}
|
>
|
||||||
{this.props.s3Supported ?
|
Add Remote Mount
|
||||||
<Button className={'AddMountButton'}
|
</Button>
|
||||||
clicked={this.handleAddS3Mount}>Add S3 Mount</Button> : null}
|
) : null}
|
||||||
|
{this.props.remoteSupported && this.props.s3Supported ? (
|
||||||
|
<div style={{ paddingRight: 'var(--default_spacing)' }} />
|
||||||
|
) : null}
|
||||||
|
{this.props.s3Supported ? (
|
||||||
|
<Button
|
||||||
|
className={'AddMountButton'}
|
||||||
|
clicked={this.handleAddS3Mount}
|
||||||
|
>
|
||||||
|
Add S3 Mount
|
||||||
|
</Button>
|
||||||
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import './Configuration.css';
|
import './Configuration.css';
|
||||||
import {connect} from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import Box from '../../components/UI/Box/Box';
|
import Box from '../../components/UI/Box/Box';
|
||||||
import Button from '../../components/UI/Button/Button';
|
import Button from '../../components/UI/Button/Button';
|
||||||
import ConfigurationItem from './ConfigurationItem/ConfigurationItem';
|
import ConfigurationItem from './ConfigurationItem/ConfigurationItem';
|
||||||
import Modal from '../../components/UI/Modal/Modal';
|
import Modal from '../../components/UI/Modal/Modal';
|
||||||
import IPCContainer from '../IPCContainer/IPCContainer';
|
import IPCContainer from '../IPCContainer/IPCContainer';
|
||||||
import {displayConfiguration} from '../../redux/actions/mount_actions';
|
import { displayConfiguration } from '../../redux/actions/mount_actions';
|
||||||
import {notifyError} from '../../redux/actions/error_actions';
|
import { notifyError } from '../../redux/actions/error_actions';
|
||||||
import {displayPinnedManager} from '../../redux/actions/pinned_manager_actions';
|
import { displayPinnedManager } from '../../redux/actions/pinned_manager_actions';
|
||||||
|
|
||||||
const Constants = require('../../constants');
|
const Constants = require('../../constants');
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ class Configuration extends IPCContainer {
|
|||||||
ItemList: [],
|
ItemList: [],
|
||||||
Saving: false,
|
Saving: false,
|
||||||
ShowAdvanced: false,
|
ShowAdvanced: false,
|
||||||
Template: {}
|
Template: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
checkItemChanged = (itemA, itemB) => {
|
checkItemChanged = (itemA, itemB) => {
|
||||||
@@ -33,7 +33,7 @@ class Configuration extends IPCContainer {
|
|||||||
if (itemA.value.length !== itemB.value.length) {
|
if (itemA.value.length !== itemB.value.length) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return itemA.value.filter(i => !itemB.value.includes(i)).length !== 0;
|
return itemA.value.filter((i) => !itemB.value.includes(i)).length !== 0;
|
||||||
}
|
}
|
||||||
return itemA.value !== itemB.value;
|
return itemA.value !== itemB.value;
|
||||||
};
|
};
|
||||||
@@ -52,7 +52,9 @@ class Configuration extends IPCContainer {
|
|||||||
const changedObjectItems = [];
|
const changedObjectItems = [];
|
||||||
let j = 0;
|
let j = 0;
|
||||||
for (const item of this.state.ObjectLookup[key]) {
|
for (const item of this.state.ObjectLookup[key]) {
|
||||||
if (this.checkItemChanged(this.state.OriginalObjectLookup[key][j++], item)) {
|
if (
|
||||||
|
this.checkItemChanged(this.state.OriginalObjectLookup[key][j++], item)
|
||||||
|
) {
|
||||||
changedObjectItems.push(item);
|
changedObjectItems.push(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -65,7 +67,7 @@ class Configuration extends IPCContainer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((changedItems.length > 0) || changedObjectLookup) {
|
if (changedItems.length > 0 || changedObjectLookup) {
|
||||||
this.setState({
|
this.setState({
|
||||||
ChangedItems: changedItems,
|
ChangedItems: changedItems,
|
||||||
ChangedObjectLookup: changedObjectLookup,
|
ChangedObjectLookup: changedObjectLookup,
|
||||||
@@ -77,9 +79,18 @@ class Configuration extends IPCContainer {
|
|||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this._isMounted = true;
|
this._isMounted = true;
|
||||||
this.setRequestHandler(Constants.IPC_Get_Config_Template_Reply, this.onGetConfigTemplateReply);
|
this.setRequestHandler(
|
||||||
this.setRequestHandler(Constants.IPC_Get_Config_Reply, this.onGetConfigReply);
|
Constants.IPC_Get_Config_Template_Reply,
|
||||||
this.setRequestHandler(Constants.IPC_Set_Config_Values_Reply, this.onSetConfigValuesReply);
|
this.onGetConfigTemplateReply
|
||||||
|
);
|
||||||
|
this.setRequestHandler(
|
||||||
|
Constants.IPC_Get_Config_Reply,
|
||||||
|
this.onGetConfigReply
|
||||||
|
);
|
||||||
|
this.setRequestHandler(
|
||||||
|
Constants.IPC_Set_Config_Values_Reply,
|
||||||
|
this.onSetConfigValuesReply
|
||||||
|
);
|
||||||
this.sendRequest(Constants.IPC_Get_Config_Template, {
|
this.sendRequest(Constants.IPC_Get_Config_Template, {
|
||||||
Provider: this.props.DisplayConfiguration,
|
Provider: this.props.DisplayConfiguration,
|
||||||
Remote: this.props.DisplayRemoteConfiguration,
|
Remote: this.props.DisplayRemoteConfiguration,
|
||||||
@@ -95,25 +106,25 @@ class Configuration extends IPCContainer {
|
|||||||
|
|
||||||
createItemList = (config, template) => {
|
createItemList = (config, template) => {
|
||||||
const objectList = [];
|
const objectList = [];
|
||||||
const itemList = Object
|
const itemList = Object.keys(config)
|
||||||
.keys(config)
|
.map((key) => {
|
||||||
.map(key => {
|
|
||||||
return {
|
return {
|
||||||
advanced: template[key] ? template[key].advanced : false,
|
advanced: template[key] ? template[key].advanced : false,
|
||||||
hide_remote: template[key] ? template[key].hide_remote : false,
|
hide_remote: template[key] ? template[key].hide_remote : false,
|
||||||
label: key,
|
label: key,
|
||||||
remote: template[key] ? template[key].remote : false,
|
remote: template[key] ? template[key].remote : false,
|
||||||
type: template[key] ? template[key].type : null,
|
type: template[key] ? template[key].type : null,
|
||||||
value: (template[key] && (template[key].type === 'object')) ?
|
value:
|
||||||
config[key] :
|
template[key] && template[key].type === 'object'
|
||||||
(template[key] && (template[key].type === 'string_array')) ?
|
? config[key]
|
||||||
config[key] :
|
: template[key] && template[key].type === 'string_array'
|
||||||
config[key].toString(),
|
? config[key]
|
||||||
|
: config[key].toString(),
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
.filter(i => {
|
.filter((i) => {
|
||||||
let ret = template[i.label];
|
let ret = template[i.label];
|
||||||
if (ret && (template[i.label].type === 'object')) {
|
if (ret && template[i.label].type === 'object') {
|
||||||
objectList.push(i);
|
objectList.push(i);
|
||||||
ret = false;
|
ret = false;
|
||||||
}
|
}
|
||||||
@@ -122,28 +133,30 @@ class Configuration extends IPCContainer {
|
|||||||
return {
|
return {
|
||||||
ObjectList: objectList,
|
ObjectList: objectList,
|
||||||
ItemList: itemList,
|
ItemList: itemList,
|
||||||
}
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
handleItemChanged = (target, idx) => {
|
handleItemChanged = (target, idx) => {
|
||||||
const itemList = [
|
const itemList = [...this.state.ItemList];
|
||||||
...this.state.ItemList
|
itemList[idx].value =
|
||||||
];
|
target.type === 'textarea'
|
||||||
itemList[idx].value = target.type === 'textarea' ? target.string_array : target.value.toString();
|
? target.string_array
|
||||||
|
: target.value.toString();
|
||||||
this.setState({
|
this.setState({
|
||||||
ItemList: itemList
|
ItemList: itemList,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
handleObjectItemChanged = (target, name, idx) => {
|
handleObjectItemChanged = (target, name, idx) => {
|
||||||
const itemList = [
|
const itemList = [...this.state.ObjectLookup[name]];
|
||||||
...this.state.ObjectLookup[name]
|
|
||||||
];
|
|
||||||
const objectLookup = {
|
const objectLookup = {
|
||||||
...this.state.ObjectLookup,
|
...this.state.ObjectLookup,
|
||||||
};
|
};
|
||||||
|
|
||||||
itemList[idx].value = target.type === 'textarea' ? target.string_array : target.value.toString();
|
itemList[idx].value =
|
||||||
|
target.type === 'textarea'
|
||||||
|
? target.string_array
|
||||||
|
: target.value.toString();
|
||||||
objectLookup[name] = itemList;
|
objectLookup[name] = itemList;
|
||||||
this.setState({
|
this.setState({
|
||||||
ObjectLookup: objectLookup,
|
ObjectLookup: objectLookup,
|
||||||
@@ -157,12 +170,19 @@ class Configuration extends IPCContainer {
|
|||||||
|
|
||||||
let objectLookup = {};
|
let objectLookup = {};
|
||||||
for (const obj of list.ObjectList) {
|
for (const obj of list.ObjectList) {
|
||||||
const list2 = this.createItemList(obj.value, this.state.Template[obj.label].template);
|
const list2 = this.createItemList(
|
||||||
|
obj.value,
|
||||||
|
this.state.Template[obj.label].template
|
||||||
|
);
|
||||||
objectLookup[obj.label] = list2.ItemList;
|
objectLookup[obj.label] = list2.ItemList;
|
||||||
}
|
}
|
||||||
|
|
||||||
const isRemoteMount = this.props.remoteSupported &&
|
const isRemoteMount =
|
||||||
JSON.parse(objectLookup['RemoteMount'].find(s => s.label === 'IsRemoteMount').value);
|
this.props.remoteSupported &&
|
||||||
|
JSON.parse(
|
||||||
|
objectLookup['RemoteMount'].find((s) => s.label === 'IsRemoteMount')
|
||||||
|
.value
|
||||||
|
);
|
||||||
if (isRemoteMount) {
|
if (isRemoteMount) {
|
||||||
for (const obj of list.ObjectList) {
|
for (const obj of list.ObjectList) {
|
||||||
if (obj.hide_remote) {
|
if (obj.hide_remote) {
|
||||||
@@ -172,15 +192,16 @@ class Configuration extends IPCContainer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const objectLookupCopy = JSON.parse(JSON.stringify(objectLookup));
|
const objectLookupCopy = JSON.parse(JSON.stringify(objectLookup));
|
||||||
this.setState({
|
this.setState(
|
||||||
|
{
|
||||||
IsRemoteMount: isRemoteMount,
|
IsRemoteMount: isRemoteMount,
|
||||||
ItemList: list.ItemList,
|
ItemList: list.ItemList,
|
||||||
ObjectLookup: objectLookup,
|
ObjectLookup: objectLookup,
|
||||||
OriginalItemList: itemListCopy,
|
OriginalItemList: itemListCopy,
|
||||||
OriginalObjectLookup: objectLookupCopy,
|
OriginalObjectLookup: objectLookupCopy,
|
||||||
}, () => {
|
},
|
||||||
|
() => {}
|
||||||
});
|
);
|
||||||
} else {
|
} else {
|
||||||
this.props.notifyError(arg.data.Error);
|
this.props.notifyError(arg.data.Error);
|
||||||
}
|
}
|
||||||
@@ -188,16 +209,19 @@ class Configuration extends IPCContainer {
|
|||||||
|
|
||||||
onGetConfigTemplateReply = (event, arg) => {
|
onGetConfigTemplateReply = (event, arg) => {
|
||||||
if (arg.data.Success) {
|
if (arg.data.Success) {
|
||||||
this.setState({
|
this.setState(
|
||||||
|
{
|
||||||
Template: arg.data.Template,
|
Template: arg.data.Template,
|
||||||
}, () => {
|
},
|
||||||
|
() => {
|
||||||
this.sendRequest(Constants.IPC_Get_Config, {
|
this.sendRequest(Constants.IPC_Get_Config, {
|
||||||
Provider: this.props.DisplayConfiguration,
|
Provider: this.props.DisplayConfiguration,
|
||||||
Remote: this.props.DisplayRemoteConfiguration,
|
Remote: this.props.DisplayRemoteConfiguration,
|
||||||
S3: this.props.DisplayS3Configuration,
|
S3: this.props.DisplayS3Configuration,
|
||||||
Version: this.props.version,
|
Version: this.props.version,
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
this.props.notifyError(arg.data.Error, false, () => {
|
this.props.notifyError(arg.data.Error, false, () => {
|
||||||
if (this._isMounted) {
|
if (this._isMounted) {
|
||||||
@@ -212,16 +236,17 @@ class Configuration extends IPCContainer {
|
|||||||
};
|
};
|
||||||
|
|
||||||
saveAndClose = () => {
|
saveAndClose = () => {
|
||||||
this.setState({
|
this.setState(
|
||||||
|
{
|
||||||
Saving: true,
|
Saving: true,
|
||||||
}, () => {
|
},
|
||||||
|
() => {
|
||||||
const changedItems = [];
|
const changedItems = [];
|
||||||
for (const item of this.state.ChangedItems) {
|
for (const item of this.state.ChangedItems) {
|
||||||
changedItems.push({
|
changedItems.push({
|
||||||
Name: item.label,
|
Name: item.label,
|
||||||
Value: item.type === 'string_array' ?
|
Value:
|
||||||
item.value.join(';') :
|
item.type === 'string_array' ? item.value.join(';') : item.value,
|
||||||
item.value,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -230,9 +255,10 @@ class Configuration extends IPCContainer {
|
|||||||
for (const item of this.state.ChangedObjectLookup[key]) {
|
for (const item of this.state.ChangedObjectLookup[key]) {
|
||||||
changedItems.push({
|
changedItems.push({
|
||||||
Name: key + '.' + item.label,
|
Name: key + '.' + item.label,
|
||||||
Value: item.type === 'string_array' ?
|
Value:
|
||||||
item.value.join(';') :
|
item.type === 'string_array'
|
||||||
item.value,
|
? item.value.join(';')
|
||||||
|
: item.value,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -245,43 +271,66 @@ class Configuration extends IPCContainer {
|
|||||||
S3: this.props.DisplayS3Configuration,
|
S3: this.props.DisplayS3Configuration,
|
||||||
Version: this.props.version,
|
Version: this.props.version,
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
showRemoteConfigItem = (item, itemList) => {
|
showRemoteConfigItem = (item, itemList) => {
|
||||||
if (item.advanced &&
|
if (
|
||||||
|
item.advanced &&
|
||||||
item.remote &&
|
item.remote &&
|
||||||
this.props.remoteSupported &&
|
this.props.remoteSupported &&
|
||||||
(item.label !== 'IsRemoteMount')) {
|
item.label !== 'IsRemoteMount'
|
||||||
const isRemoteMount = JSON.parse(itemList.find(s => s.label === 'IsRemoteMount').value);
|
) {
|
||||||
const enableRemoteMount = !isRemoteMount &&
|
const isRemoteMount = JSON.parse(
|
||||||
JSON.parse(itemList.find(s => s.label === 'EnableRemoteMount').value);
|
itemList.find((s) => s.label === 'IsRemoteMount').value
|
||||||
return (item.label === 'RemoteHostNameOrIp') || (item.label === 'RemoteMaxConnections') ?
|
);
|
||||||
isRemoteMount :
|
const enableRemoteMount =
|
||||||
(item.label === 'RemoteReceiveTimeoutSeconds') || (item.label === 'RemoteSendTimeoutSeconds') || (item.label === 'RemotePort') || (item.label === 'RemoteToken') ?
|
!isRemoteMount &&
|
||||||
isRemoteMount || enableRemoteMount :
|
JSON.parse(itemList.find((s) => s.label === 'EnableRemoteMount').value);
|
||||||
(item.label === 'EnableRemoteMount') ?
|
return item.label === 'RemoteHostNameOrIp' ||
|
||||||
!isRemoteMount :
|
item.label === 'RemoteMaxConnections'
|
||||||
enableRemoteMount;
|
? isRemoteMount
|
||||||
|
: item.label === 'RemoteReceiveTimeoutSeconds' ||
|
||||||
|
item.label === 'RemoteSendTimeoutSeconds' ||
|
||||||
|
item.label === 'RemotePort' ||
|
||||||
|
item.label === 'RemoteToken'
|
||||||
|
? isRemoteMount || enableRemoteMount
|
||||||
|
: item.label === 'EnableRemoteMount'
|
||||||
|
? !isRemoteMount
|
||||||
|
: enableRemoteMount;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let confirmSave = null;
|
let confirmSave = null;
|
||||||
if ((this.state.ChangedItems.length > 0) || this.state.ChangedObjectLookup) {
|
if (this.state.ChangedItems.length > 0 || this.state.ChangedObjectLookup) {
|
||||||
confirmSave = (
|
confirmSave = (
|
||||||
<Modal>
|
<Modal>
|
||||||
<Box dxStyle={{width: '40vw', padding: 'var(--default_spacing)'}}>
|
<Box dxStyle={{ width: '40vw', padding: 'var(--default_spacing)' }}>
|
||||||
<h1 style={{width: '100%', textAlign: 'center'}}>Save Changes?</h1>
|
<h1 style={{ width: '100%', textAlign: 'center' }}>
|
||||||
<table width='100%'>
|
Save Changes?
|
||||||
|
</h1>
|
||||||
|
<table width="100%">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td align='center' width='50%'><Button clicked={this.saveAndClose}
|
<td align="center" width="50%">
|
||||||
disabled={this.state.Saving}>Yes</Button>
|
<Button
|
||||||
|
clicked={this.saveAndClose}
|
||||||
|
disabled={this.state.Saving}
|
||||||
|
>
|
||||||
|
Yes
|
||||||
|
</Button>
|
||||||
|
</td>
|
||||||
|
<td align="center" width="50%">
|
||||||
|
<Button
|
||||||
|
clicked={this.props.hideConfiguration}
|
||||||
|
disabled={this.state.Saving}
|
||||||
|
>
|
||||||
|
No
|
||||||
|
</Button>
|
||||||
</td>
|
</td>
|
||||||
<td align='center' width='50%'><Button clicked={this.props.hideConfiguration}
|
|
||||||
disabled={this.state.Saving}>No</Button></td>
|
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
@@ -294,84 +343,105 @@ class Configuration extends IPCContainer {
|
|||||||
|
|
||||||
let objectItems = [];
|
let objectItems = [];
|
||||||
for (const key of Object.keys(this.state.ObjectLookup)) {
|
for (const key of Object.keys(this.state.ObjectLookup)) {
|
||||||
objectItems.push((
|
objectItems.push(
|
||||||
<div key={key}>
|
<div key={key}>
|
||||||
<h2>{key}</h2>
|
<h2>{key}</h2>
|
||||||
<div>
|
<div>
|
||||||
{
|
{this.state.ObjectLookup[key].map((k, i) => {
|
||||||
this.state.ObjectLookup[key].map((k, i) => {
|
|
||||||
const shouldFocus = autoFocus;
|
const shouldFocus = autoFocus;
|
||||||
autoFocus = false;
|
autoFocus = false;
|
||||||
return (
|
return !k.advanced ||
|
||||||
(!k.advanced || (this.state.ShowAdvanced && k.advanced && !k.remote) || this.showRemoteConfigItem(k, this.state.ObjectLookup[key])) ?
|
(this.state.ShowAdvanced && k.advanced && !k.remote) ||
|
||||||
<ConfigurationItem advanced={k.advanced}
|
this.showRemoteConfigItem(k, this.state.ObjectLookup[key]) ? (
|
||||||
|
<ConfigurationItem
|
||||||
|
advanced={k.advanced}
|
||||||
autoFocus={shouldFocus}
|
autoFocus={shouldFocus}
|
||||||
changed={e => this.handleObjectItemChanged(e, key, i)}
|
changed={(e) => this.handleObjectItemChanged(e, key, i)}
|
||||||
grouping={key}
|
grouping={key}
|
||||||
items={this.state.Template[key].template[k.label].items}
|
items={this.state.Template[key].template[k.label].items}
|
||||||
key={i}
|
key={i}
|
||||||
label={k.label}
|
label={k.label}
|
||||||
readOnly={this.state.IsRemoteMount && ((k.label === 'RemoteHostNameOrIp') || (k.label === 'RemotePort'))}
|
readOnly={
|
||||||
template={this.state.Template[key].template[k.label]}
|
this.state.IsRemoteMount &&
|
||||||
value={k.value}/> :
|
(k.label === 'RemoteHostNameOrIp' ||
|
||||||
null)
|
k.label === 'RemotePort')
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
template={this.state.Template[key].template[k.label]}
|
||||||
|
value={k.value}
|
||||||
|
/>
|
||||||
|
) : null;
|
||||||
|
})}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
));
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const configurationItems = this.state.ItemList
|
const configurationItems = this.state.ItemList.map((k, i) => {
|
||||||
.map((k, i) => {
|
|
||||||
const shouldFocus = autoFocus;
|
const shouldFocus = autoFocus;
|
||||||
autoFocus = false;
|
autoFocus = false;
|
||||||
return (
|
return (!this.state.IsRemoteMount || !k.hide_remote) &&
|
||||||
((!this.state.IsRemoteMount || !k.hide_remote) && (!k.advanced || (this.state.ShowAdvanced && k.advanced))) ?
|
(!k.advanced || (this.state.ShowAdvanced && k.advanced)) ? (
|
||||||
<ConfigurationItem advanced={k.advanced}
|
<ConfigurationItem
|
||||||
|
advanced={k.advanced}
|
||||||
autoFocus={shouldFocus}
|
autoFocus={shouldFocus}
|
||||||
changed={e => this.handleItemChanged(e, i)}
|
changed={(e) => this.handleItemChanged(e, i)}
|
||||||
grouping={'Settings'}
|
grouping={'Settings'}
|
||||||
items={this.state.Template[k.label].items}
|
items={this.state.Template[k.label].items}
|
||||||
key={i}
|
key={i}
|
||||||
label={k.label}
|
label={k.label}
|
||||||
template={this.state.Template[k.label]}
|
template={this.state.Template[k.label]}
|
||||||
value={k.value}/> :
|
value={k.value}
|
||||||
null
|
/>
|
||||||
);
|
) : null;
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={'Configuration'}>
|
<div className={'Configuration'}>
|
||||||
{confirmSave}
|
{confirmSave}
|
||||||
<Box dxDark dxStyle={{padding: 'var(--default_spacing)'}}>
|
<Box dxDark dxStyle={{ padding: 'var(--default_spacing)' }}>
|
||||||
<div style={{
|
<div
|
||||||
|
style={{
|
||||||
float: 'right',
|
float: 'right',
|
||||||
margin: 0,
|
margin: 0,
|
||||||
padding: 0,
|
padding: 0,
|
||||||
marginTop: '-4px',
|
marginTop: '-4px',
|
||||||
boxSizing: 'border-box',
|
boxSizing: 'border-box',
|
||||||
display: 'block'
|
display: 'block',
|
||||||
}}>
|
}}
|
||||||
<a href={'#'}
|
>
|
||||||
|
<a
|
||||||
|
href={'#'}
|
||||||
onClick={this.checkSaveRequired}
|
onClick={this.checkSaveRequired}
|
||||||
style={{cursor: 'pointer'}}>X</a>
|
style={{ cursor: 'pointer' }}
|
||||||
|
>
|
||||||
|
X
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<h1 style={{width: '100%', textAlign: 'center'}}>{(
|
<h1 style={{ width: '100%', textAlign: 'center' }}>
|
||||||
this.props.DisplayRemoteConfiguration ?
|
{(this.props.DisplayRemoteConfiguration
|
||||||
this.props.DisplayConfiguration.substr(6) :
|
? this.props.DisplayConfiguration.substr(6)
|
||||||
this.props.DisplayConfiguration) + ' Configuration '}
|
: this.props.DisplayConfiguration) + ' Configuration '}
|
||||||
</h1>
|
</h1>
|
||||||
<div style={{overflowY: 'auto', height: '90%'}}>
|
<div style={{ overflowY: 'auto', height: '90%' }}>
|
||||||
{this.props.MState.Mounted && (configurationItems.length > 0) ? <Button
|
{this.props.MState.Mounted && configurationItems.length > 0 ? (
|
||||||
buttonStyles={{width: 'auto', height: 'auto', marginLeft: 'auto', marginRight: '4px'}}
|
<Button
|
||||||
|
buttonStyles={{
|
||||||
|
width: 'auto',
|
||||||
|
height: 'auto',
|
||||||
|
marginLeft: 'auto',
|
||||||
|
marginRight: '4px',
|
||||||
|
}}
|
||||||
clicked={() => {
|
clicked={() => {
|
||||||
this.props.displayPinnedManager(true);
|
this.props.displayPinnedManager(true);
|
||||||
return false;
|
return false;
|
||||||
}}> Pinned File Manager... </Button> : null}
|
}}
|
||||||
<div style={{marginBottom: '4px'}}/>
|
>
|
||||||
|
Pinned File Manager...
|
||||||
|
</Button>
|
||||||
|
) : null}
|
||||||
|
<div style={{ marginBottom: '4px' }} />
|
||||||
{objectItems}
|
{objectItems}
|
||||||
{(configurationItems.length > 0) ? <h2>Settings</h2> : null}
|
{configurationItems.length > 0 ? <h2>Settings</h2> : null}
|
||||||
{configurationItems}
|
{configurationItems}
|
||||||
</div>
|
</div>
|
||||||
</Box>
|
</Box>
|
||||||
@@ -380,22 +450,23 @@ class Configuration extends IPCContainer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const mapStateToProps = state => {
|
const mapStateToProps = (state) => {
|
||||||
return {
|
return {
|
||||||
DisplayConfiguration: state.mounts.DisplayConfiguration,
|
DisplayConfiguration: state.mounts.DisplayConfiguration,
|
||||||
DisplayRemoteConfiguration: state.mounts.DisplayRemoteConfiguration,
|
DisplayRemoteConfiguration: state.mounts.DisplayRemoteConfiguration,
|
||||||
DisplayS3Configuration: state.mounts.DisplayS3Configuration,
|
DisplayS3Configuration: state.mounts.DisplayS3Configuration,
|
||||||
MState: state.mounts.MountState[state.mounts.DisplayConfiguration],
|
MState: state.mounts.MountState[state.mounts.DisplayConfiguration],
|
||||||
Platform: state.common.Platform,
|
Platform: state.common.Platform,
|
||||||
}
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapDispatchToProps = dispatch => {
|
const mapDispatchToProps = (dispatch) => {
|
||||||
return {
|
return {
|
||||||
displayPinnedManager: display => dispatch(displayPinnedManager(display)),
|
displayPinnedManager: (display) => dispatch(displayPinnedManager(display)),
|
||||||
notifyError: (msg, critical, callback) => dispatch(notifyError(msg, critical, callback)),
|
notifyError: (msg, critical, callback) =>
|
||||||
|
dispatch(notifyError(msg, critical, callback)),
|
||||||
hideConfiguration: () => dispatch(displayConfiguration(null, false)),
|
hideConfiguration: () => dispatch(displayConfiguration(null, false)),
|
||||||
}
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(Configuration);
|
export default connect(mapStateToProps, mapDispatchToProps)(Configuration);
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ textarea.ConfigurationItemInput {
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
resize: none;
|
resize: none;
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
overflow:-moz-scrollbars-horizontal;
|
overflow: -moz-scrollbars-horizontal;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,31 +1,33 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import './ConfigurationItem.css';
|
import './ConfigurationItem.css';
|
||||||
import CheckBox from '../../../components/UI/CheckBox/CheckBox';
|
import CheckBox from '../../../components/UI/CheckBox/CheckBox';
|
||||||
import {connect} from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import {faInfoCircle} from '@fortawesome/free-solid-svg-icons';
|
import { faInfoCircle } from '@fortawesome/free-solid-svg-icons';
|
||||||
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
import {
|
import { notifyError, notifyInfo } from '../../../redux/actions/error_actions';
|
||||||
notifyError,
|
|
||||||
notifyInfo
|
|
||||||
} from '../../../redux/actions/error_actions';
|
|
||||||
import settings from '../../../assets/settings';
|
import settings from '../../../assets/settings';
|
||||||
import DropDown from '../../../components/UI/DropDown/DropDown';
|
import DropDown from '../../../components/UI/DropDown/DropDown';
|
||||||
import Password from '../../../containers/UI/Password/Password';
|
import Password from '../../../containers/UI/Password/Password';
|
||||||
|
|
||||||
const mapDispatchToProps = dispatch => {
|
const mapDispatchToProps = (dispatch) => {
|
||||||
return {
|
return {
|
||||||
notifyError: msg => dispatch(notifyError(msg)),
|
notifyError: (msg) => dispatch(notifyError(msg)),
|
||||||
notifyInfo: (title, msg) => dispatch(notifyInfo(title, msg)),
|
notifyInfo: (title, msg) => dispatch(notifyInfo(title, msg)),
|
||||||
}
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connect(null, mapDispatchToProps)(props => {
|
export default connect(
|
||||||
|
null,
|
||||||
|
mapDispatchToProps
|
||||||
|
)((props) => {
|
||||||
const handleChanged = (e) => {
|
const handleChanged = (e) => {
|
||||||
const target = e.target;
|
const target = e.target;
|
||||||
if (target.type === 'checkbox') {
|
if (target.type === 'checkbox') {
|
||||||
target.value = e.target.checked ? 'true' : 'false';
|
target.value = e.target.checked ? 'true' : 'false';
|
||||||
} else if (target.type === 'textarea') {
|
} else if (target.type === 'textarea') {
|
||||||
e.target.string_array = String(e.target.value).replace(/\r\n/g,'\n').split('\n');
|
e.target.string_array = String(e.target.value)
|
||||||
|
.replace(/\r\n/g, '\n')
|
||||||
|
.split('\n');
|
||||||
}
|
}
|
||||||
props.changed(target);
|
props.changed(target);
|
||||||
};
|
};
|
||||||
@@ -37,135 +39,184 @@ export default connect(null, mapDispatchToProps)(props => {
|
|||||||
props.notifyInfo(props.label, description);
|
props.notifyInfo(props.label, description);
|
||||||
};
|
};
|
||||||
|
|
||||||
infoDisplay = <a href={'#'}
|
infoDisplay = (
|
||||||
|
<a
|
||||||
|
href={'#'}
|
||||||
className={'ConfigurationInfo'}
|
className={'ConfigurationInfo'}
|
||||||
onClick={()=>{displayInfo(); return false;}}><FontAwesomeIcon icon={faInfoCircle}/></a>;
|
onClick={() => {
|
||||||
|
displayInfo();
|
||||||
|
return false;
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faInfoCircle} />
|
||||||
|
</a>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let data;
|
let data;
|
||||||
switch (props.template.type) {
|
switch (props.template.type) {
|
||||||
case 'bool':
|
case 'bool':
|
||||||
data = <CheckBox changed={handleChanged}
|
data = (
|
||||||
|
<CheckBox
|
||||||
|
changed={handleChanged}
|
||||||
checked={props.value}
|
checked={props.value}
|
||||||
disabled={props.readOnly}
|
disabled={props.readOnly}
|
||||||
autoFocus={props.autoFocus}/>;
|
autoFocus={props.autoFocus}
|
||||||
|
/>
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'double':
|
case 'double':
|
||||||
data = <input min={0.0}
|
data = (
|
||||||
|
<input
|
||||||
|
min={0.0}
|
||||||
autoFocus={props.autoFocus}
|
autoFocus={props.autoFocus}
|
||||||
disabled={props.readOnly}
|
disabled={props.readOnly}
|
||||||
onChange={e=>handleChanged(e)}
|
onChange={(e) => handleChanged(e)}
|
||||||
step={'0.01'}
|
step={'0.01'}
|
||||||
className={'ConfigurationItemInput'}
|
className={'ConfigurationItemInput'}
|
||||||
type={'number'}
|
type={'number'}
|
||||||
value={parseFloat(props.value).toFixed(2)}/>;
|
value={parseFloat(props.value).toFixed(2)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'list':
|
case 'list':
|
||||||
data = <DropDown alt
|
data = (
|
||||||
|
<DropDown
|
||||||
|
alt
|
||||||
auto
|
auto
|
||||||
autoFocus={props.autoFocus}
|
autoFocus={props.autoFocus}
|
||||||
changed={handleChanged}
|
changed={handleChanged}
|
||||||
disabled={props.readOnly}
|
disabled={props.readOnly}
|
||||||
items={props.items}
|
items={props.items}
|
||||||
selected={props.value} />;
|
selected={props.value}
|
||||||
|
/>
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'string':
|
case 'string':
|
||||||
if (props.template.subtype === 'password') {
|
if (props.template.subtype === 'password') {
|
||||||
data = (
|
data = (
|
||||||
<Password autoFocus={props.autoFocus}
|
<Password
|
||||||
changed={s => handleChanged({
|
autoFocus={props.autoFocus}
|
||||||
|
changed={(s) =>
|
||||||
|
handleChanged({
|
||||||
target: {
|
target: {
|
||||||
type: 'password',
|
type: 'password',
|
||||||
value: s,
|
value: s,
|
||||||
},
|
},
|
||||||
})}
|
})
|
||||||
|
}
|
||||||
disabled={props.readOnly}
|
disabled={props.readOnly}
|
||||||
mismatchHandler={() => props.notifyError('Passwords do not match')}
|
mismatchHandler={() => props.notifyError('Passwords do not match')}
|
||||||
value={props.value} />
|
value={props.value}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
data = (
|
data = (
|
||||||
<input onChange={e => handleChanged(e)}
|
<input
|
||||||
|
onChange={(e) => handleChanged(e)}
|
||||||
autoFocus={props.autoFocus}
|
autoFocus={props.autoFocus}
|
||||||
className={'ConfigurationItemInput'}
|
className={'ConfigurationItemInput'}
|
||||||
disabled={props.readOnly}
|
disabled={props.readOnly}
|
||||||
type={'text'}
|
type={'text'}
|
||||||
value={props.value}/>
|
value={props.value}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'uint8':
|
case 'uint8':
|
||||||
data = <input max={255}
|
data = (
|
||||||
|
<input
|
||||||
|
max={255}
|
||||||
min={0}
|
min={0}
|
||||||
autoFocus={props.autoFocus}
|
autoFocus={props.autoFocus}
|
||||||
disabled={props.readOnly}
|
disabled={props.readOnly}
|
||||||
onChange={e=>handleChanged(e)}
|
onChange={(e) => handleChanged(e)}
|
||||||
className={'ConfigurationItemInput'}
|
className={'ConfigurationItemInput'}
|
||||||
type={'number'}
|
type={'number'}
|
||||||
value={props.value}/>;
|
value={props.value}
|
||||||
|
/>
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'uint16':
|
case 'uint16':
|
||||||
data = <input max={65535}
|
data = (
|
||||||
|
<input
|
||||||
|
max={65535}
|
||||||
min={0}
|
min={0}
|
||||||
autoFocus={props.autoFocus}
|
autoFocus={props.autoFocus}
|
||||||
disabled={props.readOnly}
|
disabled={props.readOnly}
|
||||||
onChange={e=>handleChanged(e)}
|
onChange={(e) => handleChanged(e)}
|
||||||
className={'ConfigurationItemInput'}
|
className={'ConfigurationItemInput'}
|
||||||
type={'number'}
|
type={'number'}
|
||||||
value={props.value}/>;
|
value={props.value}
|
||||||
|
/>
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'uint32':
|
case 'uint32':
|
||||||
data = <input max={4294967295}
|
data = (
|
||||||
|
<input
|
||||||
|
max={4294967295}
|
||||||
min={0}
|
min={0}
|
||||||
autoFocus={props.autoFocus}
|
autoFocus={props.autoFocus}
|
||||||
disabled={props.readOnly}
|
disabled={props.readOnly}
|
||||||
onChange={e=>handleChanged(e)}
|
onChange={(e) => handleChanged(e)}
|
||||||
className={'ConfigurationItemInput'}
|
className={'ConfigurationItemInput'}
|
||||||
type={'number'}
|
type={'number'}
|
||||||
value={props.value}/>;
|
value={props.value}
|
||||||
|
/>
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'uint64':
|
case 'uint64':
|
||||||
data = <input max={18446744073709551615}
|
data = (
|
||||||
|
<input
|
||||||
|
max={18446744073709551615}
|
||||||
min={0}
|
min={0}
|
||||||
autoFocus={props.autoFocus}
|
autoFocus={props.autoFocus}
|
||||||
disabled={props.readOnly}
|
disabled={props.readOnly}
|
||||||
onChange={e=>handleChanged(e)}
|
onChange={(e) => handleChanged(e)}
|
||||||
className={'ConfigurationItemInput'}
|
className={'ConfigurationItemInput'}
|
||||||
type={'number'}
|
type={'number'}
|
||||||
value={props.value}/>;
|
value={props.value}
|
||||||
|
/>
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'string_array':
|
case 'string_array':
|
||||||
data = (
|
data = (
|
||||||
<textarea autoFocus={props.autoFocus}
|
<textarea
|
||||||
|
autoFocus={props.autoFocus}
|
||||||
disabled={props.readOnly}
|
disabled={props.readOnly}
|
||||||
rows={4}
|
rows={4}
|
||||||
cols={36}
|
cols={36}
|
||||||
onChange={e=>handleChanged(e)}
|
onChange={(e) => handleChanged(e)}
|
||||||
className={'ConfigurationItemInput'}
|
className={'ConfigurationItemInput'}
|
||||||
value={props.value.join('\n')} />
|
value={props.value.join('\n')}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'password':
|
case 'password':
|
||||||
data = (
|
data = (
|
||||||
<Password autoFocus={props.autoFocus}
|
<Password
|
||||||
changed={s => handleChanged({
|
autoFocus={props.autoFocus}
|
||||||
|
changed={(s) =>
|
||||||
|
handleChanged({
|
||||||
target: {
|
target: {
|
||||||
type: 'password',
|
type: 'password',
|
||||||
value: s,
|
value: s,
|
||||||
},
|
},
|
||||||
})}
|
})
|
||||||
|
}
|
||||||
disabled={props.readOnly}
|
disabled={props.readOnly}
|
||||||
mismatchHandler={() => props.notifyError('Passwords do not match')}
|
mismatchHandler={() => props.notifyError('Passwords do not match')}
|
||||||
value={props.value} />
|
value={props.value}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -175,13 +226,18 @@ export default connect(null, mapDispatchToProps)(props => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={'ConfigurationItem'}>
|
<div className={'ConfigurationItem'}>
|
||||||
<table cellPadding='2'
|
<table cellPadding="2" width="100%">
|
||||||
width='100%'>
|
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
{infoDisplay ?
|
{infoDisplay ? (
|
||||||
<td width='100%' valign={'top'}>{infoDisplay} {props.label}</td> :
|
<td width="100%" valign={'top'}>
|
||||||
<td width='100%' valign={'top'}>{props.label}</td>}
|
{infoDisplay} {props.label}
|
||||||
|
</td>
|
||||||
|
) : (
|
||||||
|
<td width="100%" valign={'top'}>
|
||||||
|
{props.label}
|
||||||
|
</td>
|
||||||
|
)}
|
||||||
<td>{data}</td>
|
<td>{data}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import {Component} from 'react';
|
import { Component } from 'react';
|
||||||
import {getIPCRenderer} from '../../utils';
|
import { getIPCRenderer } from '../../utils.jsx';
|
||||||
|
|
||||||
const ipcRenderer = getIPCRenderer();
|
const ipcRenderer = getIPCRenderer();
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@ export default class IPCContainer extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.handlerList = {};
|
this.handlerList = {};
|
||||||
};
|
}
|
||||||
|
|
||||||
sendRequest = (name, data) => {
|
sendRequest = (name, data) => {
|
||||||
if (ipcRenderer) {
|
if (ipcRenderer) {
|
||||||
@@ -41,5 +41,4 @@ export default class IPCContainer extends Component {
|
|||||||
ipcRenderer.on(name, callback);
|
ipcRenderer.on(name, callback);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
}
|
||||||
};
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import './MountItem.css';
|
import './MountItem.css';
|
||||||
import {connect} from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import DropDown from '../../../components/UI/DropDown/DropDown';
|
import DropDown from '../../../components/UI/DropDown/DropDown';
|
||||||
import Button from '../../../components/UI/Button/Button';
|
import Button from '../../../components/UI/Button/Button';
|
||||||
import Loader from 'react-loader-spinner';
|
import Loader from 'react-loader-spinner';
|
||||||
@@ -11,36 +11,41 @@ import RootElem from '../../../components/UI/RootElem/RootElem';
|
|||||||
import {
|
import {
|
||||||
displayConfiguration,
|
displayConfiguration,
|
||||||
removeMount,
|
removeMount,
|
||||||
setProviderState
|
setProviderState,
|
||||||
} from '../../../redux/actions/mount_actions';
|
} from '../../../redux/actions/mount_actions';
|
||||||
import {
|
import {
|
||||||
displaySkynetExport,
|
displaySkynetExport,
|
||||||
displaySkynetImport,
|
displaySkynetImport,
|
||||||
} from '../../../redux/actions/skynet_actions'
|
} from '../../../redux/actions/skynet_actions';
|
||||||
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
import { faTrashAlt} from '@fortawesome/free-solid-svg-icons';
|
import { faTrashAlt } from '@fortawesome/free-solid-svg-icons';
|
||||||
import CheckBox from '../../../components/UI/CheckBox/CheckBox';
|
import CheckBox from '../../../components/UI/CheckBox/CheckBox';
|
||||||
|
|
||||||
const mapStateToProps = (state, ownProps) => {
|
const mapStateToProps = (state, ownProps) => {
|
||||||
return {
|
return {
|
||||||
MState: state.mounts.MountState[ownProps.provider],
|
MState: state.mounts.MountState[ownProps.provider],
|
||||||
Platform: state.common.Platform,
|
Platform: state.common.Platform,
|
||||||
PState: state.mounts.ProviderState[ownProps.provider]
|
PState: state.mounts.ProviderState[ownProps.provider],
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapDispatchToProps = dispatch => {
|
const mapDispatchToProps = (dispatch) => {
|
||||||
return {
|
return {
|
||||||
displayConfiguration: (provider, remote, s3) => dispatch(displayConfiguration(provider, remote, s3)),
|
displayConfiguration: (provider, remote, s3) =>
|
||||||
displaySkynetExport: display => dispatch(displaySkynetExport(display)),
|
dispatch(displayConfiguration(provider, remote, s3)),
|
||||||
displaySkynetImport: display => dispatch(displaySkynetImport(display)),
|
displaySkynetExport: (display) => dispatch(displaySkynetExport(display)),
|
||||||
removeMount: provider => dispatch(removeMount(provider)),
|
displaySkynetImport: (display) => dispatch(displaySkynetImport(display)),
|
||||||
setProviderState: (provider, state) => dispatch(setProviderState(provider, state)),
|
removeMount: (provider) => dispatch(removeMount(provider)),
|
||||||
}
|
setProviderState: (provider, state) =>
|
||||||
|
dispatch(setProviderState(provider, state)),
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(props => {
|
export default connect(
|
||||||
const handleAutoMountChanged = e => {
|
mapStateToProps,
|
||||||
|
mapDispatchToProps
|
||||||
|
)((props) => {
|
||||||
|
const handleAutoMountChanged = (e) => {
|
||||||
const state = {
|
const state = {
|
||||||
...props.PState,
|
...props.PState,
|
||||||
AutoMount: e.target.checked,
|
AutoMount: e.target.checked,
|
||||||
@@ -48,7 +53,7 @@ export default connect(mapStateToProps, mapDispatchToProps)(props => {
|
|||||||
props.setProviderState(props.provider, state);
|
props.setProviderState(props.provider, state);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleAutoRestartChanged = e => {
|
const handleAutoRestartChanged = (e) => {
|
||||||
const state = {
|
const state = {
|
||||||
...props.PState,
|
...props.PState,
|
||||||
AutoRestart: e.target.checked,
|
AutoRestart: e.target.checked,
|
||||||
@@ -57,18 +62,28 @@ export default connect(mapStateToProps, mapDispatchToProps)(props => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let secondRow = 6;
|
let secondRow = 6;
|
||||||
const pointer = {cursor: props.MState.AllowMount ? 'pointer' : 'no-drop'};
|
const pointer = { cursor: props.MState.AllowMount ? 'pointer' : 'no-drop' };
|
||||||
const configButton = (
|
const configButton = (
|
||||||
<RootElem colSpan={4}
|
<RootElem colSpan={4} rowSpan={6}>
|
||||||
rowSpan={6}>
|
<img
|
||||||
<img alt=''
|
alt=""
|
||||||
height={'16px'}
|
height={'16px'}
|
||||||
onClick={props.MState.AllowMount ? () => props.displayConfiguration(props.provider, props.remote, props.s3) : e => {
|
onClick={
|
||||||
|
props.MState.AllowMount
|
||||||
|
? () =>
|
||||||
|
props.displayConfiguration(
|
||||||
|
props.provider,
|
||||||
|
props.remote,
|
||||||
|
props.s3
|
||||||
|
)
|
||||||
|
: (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}}
|
}
|
||||||
|
}
|
||||||
src={configureImage}
|
src={configureImage}
|
||||||
style={{padding: 0, border: 0, margin: 0, ...pointer}}
|
style={{ padding: 0, border: 0, margin: 0, ...pointer }}
|
||||||
width={'16px'}/>
|
width={'16px'}
|
||||||
|
/>
|
||||||
</RootElem>
|
</RootElem>
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -77,80 +92,119 @@ export default connect(mapStateToProps, mapDispatchToProps)(props => {
|
|||||||
if (props.Platform === 'win32') {
|
if (props.Platform === 'win32') {
|
||||||
inputColumnSpan = 20;
|
inputColumnSpan = 20;
|
||||||
const index = props.MState.DriveLetters.indexOf(props.PState.MountLocation);
|
const index = props.MState.DriveLetters.indexOf(props.PState.MountLocation);
|
||||||
inputControls = <DropDown changed={props.changed}
|
inputControls = (
|
||||||
|
<DropDown
|
||||||
|
changed={props.changed}
|
||||||
colSpan={inputColumnSpan}
|
colSpan={inputColumnSpan}
|
||||||
disabled={!props.MState.AllowMount || props.MState.Mounted}
|
disabled={!props.MState.AllowMount || props.MState.Mounted}
|
||||||
items={props.MState.DriveLetters}
|
items={props.MState.DriveLetters}
|
||||||
row={secondRow}
|
row={secondRow}
|
||||||
rowSpan={7}
|
rowSpan={7}
|
||||||
selected={index >= 0 ? props.PState.MountLocation : ''}/>;
|
selected={index >= 0 ? props.PState.MountLocation : ''}
|
||||||
|
/>
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
inputColumnSpan = 64;
|
inputColumnSpan = 64;
|
||||||
inputControls = [];
|
inputControls = [];
|
||||||
let key = 0;
|
let key = 0;
|
||||||
inputControls.push((
|
inputControls.push(
|
||||||
<RootElem colSpan={inputColumnSpan - 8}
|
<RootElem
|
||||||
|
colSpan={inputColumnSpan - 8}
|
||||||
key={'i' + key++}
|
key={'i' + key++}
|
||||||
row={secondRow}
|
row={secondRow}
|
||||||
rowSpan={7}>
|
rowSpan={7}
|
||||||
<input disabled={!props.MState.AllowMount || props.MState.Mounted}
|
>
|
||||||
|
<input
|
||||||
|
disabled={!props.MState.AllowMount || props.MState.Mounted}
|
||||||
maxLength={4096}
|
maxLength={4096}
|
||||||
onChange={props.changed}
|
onChange={props.changed}
|
||||||
size={4096}
|
size={4096}
|
||||||
className={'MountItemInput'}
|
className={'MountItemInput'}
|
||||||
type={'text'}
|
type={'text'}
|
||||||
value={props.PState.MountLocation}/>
|
value={props.PState.MountLocation}
|
||||||
|
/>
|
||||||
</RootElem>
|
</RootElem>
|
||||||
));
|
);
|
||||||
inputControls.push((
|
inputControls.push(
|
||||||
<Button clicked={()=>props.browseClicked(props.provider, props.PState.MountLocation)}
|
<Button
|
||||||
|
clicked={() =>
|
||||||
|
props.browseClicked(props.provider, props.PState.MountLocation)
|
||||||
|
}
|
||||||
col={inputColumnSpan - 7}
|
col={inputColumnSpan - 7}
|
||||||
colSpan={7}
|
colSpan={7}
|
||||||
disabled={props.MState.Mounted || !props.MState.AllowMount}
|
disabled={props.MState.Mounted || !props.MState.AllowMount}
|
||||||
key={'b' + key++}
|
key={'b' + key++}
|
||||||
row={secondRow}
|
row={secondRow}
|
||||||
rowSpan={7}>...</Button>
|
rowSpan={7}
|
||||||
));
|
>
|
||||||
|
...
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const buttonDisplay = props.MState.AllowMount ?
|
const buttonDisplay = props.MState.AllowMount ? (
|
||||||
(props.MState.Mounted ? 'Unmount' : 'Mount') :
|
props.MState.Mounted ? (
|
||||||
<Loader color={'var(--heading_text_color)'}
|
'Unmount'
|
||||||
|
) : (
|
||||||
|
'Mount'
|
||||||
|
)
|
||||||
|
) : (
|
||||||
|
<Loader
|
||||||
|
color={'var(--heading_text_color)'}
|
||||||
height={19}
|
height={19}
|
||||||
type='Circles'
|
type="Circles"
|
||||||
width={19}/>;
|
width={19}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
const actionsDisplay = (
|
const actionsDisplay = (
|
||||||
<Button
|
<Button
|
||||||
clicked={() => props.clicked(props.provider, props.remote, props.s3, !props.MState.Mounted, props.PState.MountLocation)}
|
clicked={() =>
|
||||||
|
props.clicked(
|
||||||
|
props.provider,
|
||||||
|
props.remote,
|
||||||
|
props.s3,
|
||||||
|
!props.MState.Mounted,
|
||||||
|
props.PState.MountLocation
|
||||||
|
)
|
||||||
|
}
|
||||||
col={inputColumnSpan + 2}
|
col={inputColumnSpan + 2}
|
||||||
colSpan={21}
|
colSpan={21}
|
||||||
disabled={!props.MState.AllowMount}
|
disabled={!props.MState.AllowMount}
|
||||||
row={secondRow}
|
row={secondRow}
|
||||||
rowSpan={7}>
|
rowSpan={7}
|
||||||
|
>
|
||||||
{buttonDisplay}
|
{buttonDisplay}
|
||||||
</Button>);
|
</Button>
|
||||||
|
);
|
||||||
|
|
||||||
const autoMountControl = (
|
const autoMountControl = (
|
||||||
<RootElem col={inputColumnSpan + 24}
|
<RootElem
|
||||||
|
col={inputColumnSpan + 24}
|
||||||
colSpan={28}
|
colSpan={28}
|
||||||
row={secondRow}
|
row={secondRow}
|
||||||
rowSpan={7}>
|
rowSpan={7}
|
||||||
<CheckBox changed={handleAutoMountChanged}
|
>
|
||||||
|
<CheckBox
|
||||||
|
changed={handleAutoMountChanged}
|
||||||
checked={props.PState.AutoMount}
|
checked={props.PState.AutoMount}
|
||||||
label={'Auto-mount'}/>
|
label={'Auto-mount'}
|
||||||
|
/>
|
||||||
</RootElem>
|
</RootElem>
|
||||||
);
|
);
|
||||||
|
|
||||||
const autoRestartControl = (
|
const autoRestartControl = (
|
||||||
<RootElem col={inputColumnSpan + 24 + 28}
|
<RootElem
|
||||||
|
col={inputColumnSpan + 24 + 28}
|
||||||
colSpan={24}
|
colSpan={24}
|
||||||
row={secondRow}
|
row={secondRow}
|
||||||
rowSpan={7}>
|
rowSpan={7}
|
||||||
<CheckBox changed={handleAutoRestartChanged}
|
>
|
||||||
|
<CheckBox
|
||||||
|
changed={handleAutoRestartChanged}
|
||||||
checked={props.PState.AutoRestart}
|
checked={props.PState.AutoRestart}
|
||||||
label={'Restart'}/>
|
label={'Restart'}
|
||||||
|
/>
|
||||||
</RootElem>
|
</RootElem>
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -158,7 +212,7 @@ export default connect(mapStateToProps, mapDispatchToProps)(props => {
|
|||||||
if (props.allowRemove) {
|
if (props.allowRemove) {
|
||||||
const removeDisabled = !props.MState.AllowMount || props.MState.Mounted;
|
const removeDisabled = !props.MState.AllowMount || props.MState.Mounted;
|
||||||
const removeStyle = {
|
const removeStyle = {
|
||||||
cursor: removeDisabled ? 'no-drop' : 'pointer'
|
cursor: removeDisabled ? 'no-drop' : 'pointer',
|
||||||
};
|
};
|
||||||
const handleRemoveMount = () => {
|
const handleRemoveMount = () => {
|
||||||
if (!removeDisabled) {
|
if (!removeDisabled) {
|
||||||
@@ -166,17 +220,18 @@ export default connect(mapStateToProps, mapDispatchToProps)(props => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
removeControl = (
|
removeControl = (
|
||||||
<RootElem col={dimensions=>dimensions.columns - 6}
|
<RootElem
|
||||||
row={secondRow + 3}>
|
col={(dimensions) => dimensions.columns - 6}
|
||||||
<a href={'#'}
|
row={secondRow + 3}
|
||||||
onClick={handleRemoveMount}
|
>
|
||||||
style={removeStyle}>
|
<a href={'#'} onClick={handleRemoveMount} style={removeStyle}>
|
||||||
<FontAwesomeIcon icon={faTrashAlt}/>
|
<FontAwesomeIcon icon={faTrashAlt} />
|
||||||
</a>
|
</a>
|
||||||
</RootElem>);
|
</RootElem>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const isSkynet = (props.provider === 'Skynet');
|
const isSkynet = props.provider === 'Skynet';
|
||||||
return (
|
return (
|
||||||
<div className={'MountItem'}>
|
<div className={'MountItem'}>
|
||||||
<Grid noScroll>
|
<Grid noScroll>
|
||||||
@@ -185,28 +240,49 @@ export default connect(mapStateToProps, mapDispatchToProps)(props => {
|
|||||||
col={configButton ? 6 : 0}
|
col={configButton ? 6 : 0}
|
||||||
rowSpan={5}
|
rowSpan={5}
|
||||||
colSpan={90}
|
colSpan={90}
|
||||||
text={props.remote ? props.provider.substr(6) : props.s3 ? props.provider.substr(2) : isSkynet ? props.provider + ' [EXPERIMENTAL]' : props.provider}
|
text={
|
||||||
|
props.remote
|
||||||
|
? props.provider.substr(6)
|
||||||
|
: props.s3
|
||||||
|
? props.provider.substr(2)
|
||||||
|
: isSkynet
|
||||||
|
? props.provider + ' [EXPERIMENTAL]'
|
||||||
|
: props.provider
|
||||||
|
}
|
||||||
textAlign={'Left'}
|
textAlign={'Left'}
|
||||||
type={'Heading2'}/>
|
type={'Heading2'}
|
||||||
{(isSkynet && (props.MState.Mounted)) ? (
|
/>
|
||||||
<a href={'#'}
|
{isSkynet && props.MState.Mounted ? (
|
||||||
|
<a
|
||||||
|
href={'#'}
|
||||||
col={(configButton ? 24 : 18) + 34}
|
col={(configButton ? 24 : 18) + 34}
|
||||||
onClick={props.MState.AllowMount ? () => props.displaySkynetExport(true) : e => {
|
onClick={
|
||||||
|
props.MState.AllowMount
|
||||||
|
? () => props.displaySkynetExport(true)
|
||||||
|
: (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}}
|
}
|
||||||
|
}
|
||||||
rowSpan={5}
|
rowSpan={5}
|
||||||
style={{...pointer, fontWeight: 'normal'}}>
|
style={{ ...pointer, fontWeight: 'normal' }}
|
||||||
|
>
|
||||||
<u>Export</u>
|
<u>Export</u>
|
||||||
</a>
|
</a>
|
||||||
) : null}
|
) : null}
|
||||||
{(isSkynet && (props.MState.Mounted)) ? (
|
{isSkynet && props.MState.Mounted ? (
|
||||||
<a href={'#'}
|
<a
|
||||||
|
href={'#'}
|
||||||
col={(configButton ? 24 + 13 : 18 + 13) + 34}
|
col={(configButton ? 24 + 13 : 18 + 13) + 34}
|
||||||
onClick={props.MState.AllowMount ? () => props.displaySkynetImport(true) : e => {
|
onClick={
|
||||||
|
props.MState.AllowMount
|
||||||
|
? () => props.displaySkynetImport(true)
|
||||||
|
: (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}}
|
}
|
||||||
|
}
|
||||||
rowSpan={5}
|
rowSpan={5}
|
||||||
style={{...pointer, fontWeight: 'normal'}}>
|
style={{ ...pointer, fontWeight: 'normal' }}
|
||||||
|
>
|
||||||
<u>Import</u>
|
<u>Import</u>
|
||||||
</a>
|
</a>
|
||||||
) : null}
|
) : null}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import React from 'react';
|
|||||||
import AddMount from '../AddMount/AddMount';
|
import AddMount from '../AddMount/AddMount';
|
||||||
import Box from '../../components/UI/Box/Box';
|
import Box from '../../components/UI/Box/Box';
|
||||||
import Button from '../../components/UI/Button/Button';
|
import Button from '../../components/UI/Button/Button';
|
||||||
import {connect} from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import './MountItems.css';
|
import './MountItems.css';
|
||||||
import Modal from '../../components/UI/Modal/Modal';
|
import Modal from '../../components/UI/Modal/Modal';
|
||||||
import MountItem from './MountItem/MountItem';
|
import MountItem from './MountItem/MountItem';
|
||||||
@@ -14,9 +14,9 @@ import {
|
|||||||
setBusy,
|
setBusy,
|
||||||
setMounted,
|
setMounted,
|
||||||
setMountState,
|
setMountState,
|
||||||
setProviderState
|
setProviderState,
|
||||||
} from '../../redux/actions/mount_actions';
|
} from '../../redux/actions/mount_actions';
|
||||||
import {notifyError} from '../../redux/actions/error_actions';
|
import { notifyError } from '../../redux/actions/error_actions';
|
||||||
|
|
||||||
const Constants = require('../../constants');
|
const Constants = require('../../constants');
|
||||||
|
|
||||||
@@ -29,7 +29,7 @@ class MountItems extends IPCContainer {
|
|||||||
RetryItems: {},
|
RetryItems: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
addMountsBusy = provider => {
|
addMountsBusy = (provider) => {
|
||||||
this.props.setMountsBusy(true);
|
this.props.setMountsBusy(true);
|
||||||
this.activeDetections.push(provider);
|
this.activeDetections.push(provider);
|
||||||
};
|
};
|
||||||
@@ -43,22 +43,34 @@ class MountItems extends IPCContainer {
|
|||||||
...this.state.RetryItems,
|
...this.state.RetryItems,
|
||||||
};
|
};
|
||||||
delete retryItems[provider];
|
delete retryItems[provider];
|
||||||
this.setState({
|
this.setState(
|
||||||
|
{
|
||||||
DisplayRetry: Object.keys(retryItems).length > 0,
|
DisplayRetry: Object.keys(retryItems).length > 0,
|
||||||
RetryItems: retryItems,
|
RetryItems: retryItems,
|
||||||
}, () => {
|
},
|
||||||
|
() => {
|
||||||
if (this.state.DisplayRetry) {
|
if (this.state.DisplayRetry) {
|
||||||
this.sendRequest(Constants.IPC_Show_Window);
|
this.sendRequest(Constants.IPC_Show_Window);
|
||||||
}
|
}
|
||||||
stateCallback();
|
stateCallback();
|
||||||
});
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.setRequestHandler(Constants.IPC_Detect_Mount_Reply, this.onDetectMountReply);
|
this.setRequestHandler(
|
||||||
this.setRequestHandler(Constants.IPC_Mount_Drive_Reply, this.onMountDriveReply);
|
Constants.IPC_Detect_Mount_Reply,
|
||||||
this.setRequestHandler(Constants.IPC_Unmount_Drive_Reply, this.onUnmountDriveReply);
|
this.onDetectMountReply
|
||||||
|
);
|
||||||
|
this.setRequestHandler(
|
||||||
|
Constants.IPC_Mount_Drive_Reply,
|
||||||
|
this.onMountDriveReply
|
||||||
|
);
|
||||||
|
this.setRequestHandler(
|
||||||
|
Constants.IPC_Unmount_Drive_Reply,
|
||||||
|
this.onUnmountDriveReply
|
||||||
|
);
|
||||||
this.props.resetMountsState();
|
this.props.resetMountsState();
|
||||||
this.detectMounts();
|
this.detectMounts();
|
||||||
}
|
}
|
||||||
@@ -73,9 +85,9 @@ class MountItems extends IPCContainer {
|
|||||||
this.props.resetMountsState();
|
this.props.resetMountsState();
|
||||||
this.activeDetections = [];
|
this.activeDetections = [];
|
||||||
super.componentWillUnmount();
|
super.componentWillUnmount();
|
||||||
};
|
}
|
||||||
|
|
||||||
detectMount = provider => {
|
detectMount = (provider) => {
|
||||||
this.addMountsBusy(provider);
|
this.addMountsBusy(provider);
|
||||||
|
|
||||||
this.sendRequest(Constants.IPC_Detect_Mount, {
|
this.sendRequest(Constants.IPC_Detect_Mount, {
|
||||||
@@ -86,10 +98,10 @@ class MountItems extends IPCContainer {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
detectMounts = ()=> {
|
detectMounts = () => {
|
||||||
if (!this.state.DisplayRetry) {
|
if (!this.state.DisplayRetry) {
|
||||||
const providerList = this.getProviderList();
|
const providerList = this.getProviderList();
|
||||||
providerList.forEach(provider => {
|
providerList.forEach((provider) => {
|
||||||
this.detectMount(provider);
|
this.detectMount(provider);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -98,7 +110,7 @@ class MountItems extends IPCContainer {
|
|||||||
displayRetryMount = (provider, remote, s3, mountLocation, msg) => {
|
displayRetryMount = (provider, remote, s3, mountLocation, msg) => {
|
||||||
if (!this.state.RetryItems[provider]) {
|
if (!this.state.RetryItems[provider]) {
|
||||||
let retryItems = {
|
let retryItems = {
|
||||||
...this.state.RetryItems
|
...this.state.RetryItems,
|
||||||
};
|
};
|
||||||
retryItems[provider] = {
|
retryItems[provider] = {
|
||||||
RetrySeconds: 10,
|
RetrySeconds: 10,
|
||||||
@@ -110,10 +122,12 @@ class MountItems extends IPCContainer {
|
|||||||
};
|
};
|
||||||
this.props.setMountState(provider, mountState);
|
this.props.setMountState(provider, mountState);
|
||||||
|
|
||||||
this.setState({
|
this.setState(
|
||||||
|
{
|
||||||
DisplayRetry: true,
|
DisplayRetry: true,
|
||||||
RetryItems: retryItems,
|
RetryItems: retryItems,
|
||||||
}, () => {
|
},
|
||||||
|
() => {
|
||||||
this.sendRequest(Constants.IPC_Show_Window);
|
this.sendRequest(Constants.IPC_Show_Window);
|
||||||
this.retryIntervals[provider] = setInterval(() => {
|
this.retryIntervals[provider] = setInterval(() => {
|
||||||
let retryItems = {
|
let retryItems = {
|
||||||
@@ -122,7 +136,13 @@ class MountItems extends IPCContainer {
|
|||||||
const retrySeconds = retryItems[provider].RetrySeconds - 1;
|
const retrySeconds = retryItems[provider].RetrySeconds - 1;
|
||||||
if (retrySeconds === 0) {
|
if (retrySeconds === 0) {
|
||||||
this.cancelRetryMount(provider, () => {
|
this.cancelRetryMount(provider, () => {
|
||||||
this.handleMountUnMount(provider, remote, s3, true, mountLocation);
|
this.handleMountUnMount(
|
||||||
|
provider,
|
||||||
|
remote,
|
||||||
|
s3,
|
||||||
|
true,
|
||||||
|
mountLocation
|
||||||
|
);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
retryItems[provider].RetrySeconds = retrySeconds;
|
retryItems[provider].RetrySeconds = retrySeconds;
|
||||||
@@ -131,7 +151,8 @@ class MountItems extends IPCContainer {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, 1000);
|
}, 1000);
|
||||||
});
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -140,7 +161,7 @@ class MountItems extends IPCContainer {
|
|||||||
Title: provider + ' Mount Location',
|
Title: provider + ' Mount Location',
|
||||||
Location: location,
|
Location: location,
|
||||||
});
|
});
|
||||||
if (location && (location.length > 0)) {
|
if (location && location.length > 0) {
|
||||||
this.handleMountLocationChanged(provider, location);
|
this.handleMountLocationChanged(provider, location);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -154,25 +175,29 @@ class MountItems extends IPCContainer {
|
|||||||
};
|
};
|
||||||
|
|
||||||
handleMountUnMount = (provider, remote, s3, mount, location) => {
|
handleMountUnMount = (provider, remote, s3, mount, location) => {
|
||||||
if (!location || (location.trim().length === 0)) {
|
if (!location || location.trim().length === 0) {
|
||||||
this.props.notifyError('Mount location is not set');
|
this.props.notifyError('Mount location is not set');
|
||||||
} else {
|
} else {
|
||||||
let allowAction = true;
|
let allowAction = true;
|
||||||
if (mount) {
|
if (mount) {
|
||||||
let result = remote || s3 || provider === 'Skynet' ?
|
let result =
|
||||||
{Valid: true, Success: true} :
|
remote || s3 || provider === 'Skynet'
|
||||||
this.sendSyncRequest(Constants.IPC_Check_Daemon_Version, {
|
? { Valid: true, Success: true }
|
||||||
|
: this.sendSyncRequest(Constants.IPC_Check_Daemon_Version, {
|
||||||
Provider: provider,
|
Provider: provider,
|
||||||
Remote: remote,
|
Remote: remote,
|
||||||
S3: s3,
|
S3: s3,
|
||||||
Version: this.props.InstalledVersion
|
Version: this.props.InstalledVersion,
|
||||||
}).data;
|
}).data;
|
||||||
if (result.Success) {
|
if (result.Success) {
|
||||||
if (result.Valid) {
|
if (result.Valid) {
|
||||||
if (this.props.Platform !== 'win32') {
|
if (this.props.Platform !== 'win32') {
|
||||||
result = this.sendSyncRequest(Constants.IPC_Check_Mount_Location, {
|
result = this.sendSyncRequest(
|
||||||
|
Constants.IPC_Check_Mount_Location,
|
||||||
|
{
|
||||||
Location: location,
|
Location: location,
|
||||||
});
|
}
|
||||||
|
);
|
||||||
if (!result.Success) {
|
if (!result.Success) {
|
||||||
allowAction = false;
|
allowAction = false;
|
||||||
this.props.notifyError(result.Error.toString());
|
this.props.notifyError(result.Error.toString());
|
||||||
@@ -180,20 +205,56 @@ class MountItems extends IPCContainer {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
allowAction = false;
|
allowAction = false;
|
||||||
if ((result.Code === new Uint32Array([-1])[0]) || (result.Code === new Uint8Array([-1])[0])) {
|
if (
|
||||||
this.displayRetryMount(provider, remote, s3, location, 'Failed to connect to ' + provider + ' daemon');
|
result.Code === new Uint32Array([-1])[0] ||
|
||||||
} else if ((result.Code === new Uint32Array([-3])[0]) || (result.Code === new Uint8Array([-3])[0])) {
|
result.Code === new Uint8Array([-1])[0]
|
||||||
this.displayRetryMount(provider, remote, s3, location, 'Incompatible ' + provider + ' daemon. Please upgrade ' + provider + '.');
|
) {
|
||||||
|
this.displayRetryMount(
|
||||||
|
provider,
|
||||||
|
remote,
|
||||||
|
s3,
|
||||||
|
location,
|
||||||
|
'Failed to connect to ' + provider + ' daemon'
|
||||||
|
);
|
||||||
|
} else if (
|
||||||
|
result.Code === new Uint32Array([-3])[0] ||
|
||||||
|
result.Code === new Uint8Array([-3])[0]
|
||||||
|
) {
|
||||||
|
this.displayRetryMount(
|
||||||
|
provider,
|
||||||
|
remote,
|
||||||
|
s3,
|
||||||
|
location,
|
||||||
|
'Incompatible ' +
|
||||||
|
provider +
|
||||||
|
' daemon. Please upgrade ' +
|
||||||
|
provider +
|
||||||
|
'.'
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
this.displayRetryMount(provider, remote, s3, location, 'Version check failed: ' + result.Error);
|
this.displayRetryMount(
|
||||||
|
provider,
|
||||||
|
remote,
|
||||||
|
s3,
|
||||||
|
location,
|
||||||
|
'Version check failed: ' + result.Error
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
allowAction = false;
|
allowAction = false;
|
||||||
if (this.props.Platform === 'win32') {
|
if (this.props.Platform === 'win32') {
|
||||||
this.props.notifyError('Failed to launch repertory. Please install Microsoft Visual C++ Redistributable for Visual Studio 2015, 2017 and 2019.');
|
this.props.notifyError(
|
||||||
|
'Failed to launch repertory. Please install Microsoft Visual C++ Redistributable for Visual Studio 2015, 2017 and 2019.'
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
this.displayRetryMount(provider, remote, s3, location, 'Version check failed: ' + result.Error);
|
this.displayRetryMount(
|
||||||
|
provider,
|
||||||
|
remote,
|
||||||
|
s3,
|
||||||
|
location,
|
||||||
|
'Version check failed: ' + result.Error
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -223,11 +284,13 @@ class MountItems extends IPCContainer {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
getProviderList = providersOnly => {
|
getProviderList = (providersOnly) => {
|
||||||
const providerList = Constants.PROVIDER_LIST.filter(i => {
|
const providerList = Constants.PROVIDER_LIST.filter((i) => {
|
||||||
return ((i === 'Skynet') && this.props.skynetSupported) ||
|
return (
|
||||||
((i === 'ScPrime') && this.props.scPrimeSupported) ||
|
(i === 'Skynet' && this.props.skynetSupported) ||
|
||||||
((i === 'Sia') && this.props.siaSupported);
|
(i === 'ScPrime' && this.props.scPrimeSupported) ||
|
||||||
|
(i === 'Sia' && this.props.siaSupported)
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
let remoteList = [];
|
let remoteList = [];
|
||||||
@@ -240,17 +303,12 @@ class MountItems extends IPCContainer {
|
|||||||
s3List = [...this.props.S3Mounts];
|
s3List = [...this.props.S3Mounts];
|
||||||
}
|
}
|
||||||
|
|
||||||
return [
|
return [...providerList, ...remoteList, ...s3List];
|
||||||
...providerList,
|
|
||||||
...remoteList,
|
|
||||||
...s3List,
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
hasActiveMount = () => {
|
hasActiveMount = () => {
|
||||||
for (const provider of Object.keys(this.props.MountState)) {
|
for (const provider of Object.keys(this.props.MountState)) {
|
||||||
if (this.props.MountState[provider].Mounted)
|
if (this.props.MountState[provider].Mounted) return true;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -259,7 +317,11 @@ class MountItems extends IPCContainer {
|
|||||||
onDetectMountReply = (event, arg) => {
|
onDetectMountReply = (event, arg) => {
|
||||||
const provider = arg.data.Provider;
|
const provider = arg.data.Provider;
|
||||||
if (!this.state.RetryItems[provider]) {
|
if (!this.state.RetryItems[provider]) {
|
||||||
if (arg.data.Success && (!arg.data.Active || (arg.data.Location && (arg.data.Location.length > 0)))) {
|
if (
|
||||||
|
arg.data.Success &&
|
||||||
|
(!arg.data.Active ||
|
||||||
|
(arg.data.Location && arg.data.Location.length > 0))
|
||||||
|
) {
|
||||||
const mountState = {
|
const mountState = {
|
||||||
AllowMount: true,
|
AllowMount: true,
|
||||||
DriveLetters: arg.data.DriveLetters,
|
DriveLetters: arg.data.DriveLetters,
|
||||||
@@ -267,7 +329,12 @@ class MountItems extends IPCContainer {
|
|||||||
};
|
};
|
||||||
this.props.setMountState(provider, mountState);
|
this.props.setMountState(provider, mountState);
|
||||||
|
|
||||||
this.updateMountLocation(provider, arg.data.Location, mountState.Mounted, arg.data.DriveLetters);
|
this.updateMountLocation(
|
||||||
|
provider,
|
||||||
|
arg.data.Location,
|
||||||
|
mountState.Mounted,
|
||||||
|
arg.data.DriveLetters
|
||||||
|
);
|
||||||
this.props.setAutoMountProcessed(provider, true);
|
this.props.setAutoMountProcessed(provider, true);
|
||||||
this.removeMountsBusy(provider);
|
this.removeMountsBusy(provider);
|
||||||
} else {
|
} else {
|
||||||
@@ -284,39 +351,63 @@ class MountItems extends IPCContainer {
|
|||||||
};
|
};
|
||||||
|
|
||||||
onUnmountDriveReply = (event, arg) => {
|
onUnmountDriveReply = (event, arg) => {
|
||||||
if (arg && arg.data && !arg.data.Expected && arg.data.Location && this.props.ProviderState[arg.data.Provider].AutoRestart) {
|
if (
|
||||||
this.displayRetryMount(arg.data.Provider, arg.data.Remote, arg.data.Location);
|
arg &&
|
||||||
|
arg.data &&
|
||||||
|
!arg.data.Expected &&
|
||||||
|
arg.data.Location &&
|
||||||
|
this.props.ProviderState[arg.data.Provider].AutoRestart
|
||||||
|
) {
|
||||||
|
this.displayRetryMount(
|
||||||
|
arg.data.Provider,
|
||||||
|
arg.data.Remote,
|
||||||
|
arg.data.Location
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
this.detectMount(arg.data.Provider);
|
this.detectMount(arg.data.Provider);
|
||||||
}
|
}
|
||||||
this.removeMountsBusy(arg.data.Provider);
|
this.removeMountsBusy(arg.data.Provider);
|
||||||
};
|
};
|
||||||
|
|
||||||
removeMountsBusy = provider => {
|
removeMountsBusy = (provider) => {
|
||||||
const idx = this.activeDetections.indexOf(provider);
|
const idx = this.activeDetections.indexOf(provider);
|
||||||
if (idx > -1) {
|
if (idx > -1) {
|
||||||
this.activeDetections.splice(idx, 1);
|
this.activeDetections.splice(idx, 1);
|
||||||
}
|
}
|
||||||
this.props.setMountsBusy((this.activeDetections.length > 0) || this.hasActiveMount());
|
this.props.setMountsBusy(
|
||||||
|
this.activeDetections.length > 0 || this.hasActiveMount()
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
updateMountLocation = (provider, location, mounted, driveLetters) => {
|
updateMountLocation = (provider, location, mounted, driveLetters) => {
|
||||||
const providerState = this.props.ProviderState[provider];
|
const providerState = this.props.ProviderState[provider];
|
||||||
if (location.length === 0) {
|
if (location.length === 0) {
|
||||||
location = (this.props.Platform === 'win32') ?
|
location =
|
||||||
!providerState.MountLocation || providerState.MountLocation.trim().length === 0 ? driveLetters[0] : providerState.MountLocation :
|
this.props.Platform === 'win32'
|
||||||
providerState.MountLocation;
|
? !providerState.MountLocation ||
|
||||||
|
providerState.MountLocation.trim().length === 0
|
||||||
|
? driveLetters[0]
|
||||||
|
: providerState.MountLocation
|
||||||
|
: providerState.MountLocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (location !== providerState.MountLocation) {
|
if (location !== providerState.MountLocation) {
|
||||||
this.handleMountLocationChanged(provider, location);
|
this.handleMountLocationChanged(provider, location);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.props.AutoMountProcessed[provider] &&
|
if (
|
||||||
|
!this.props.AutoMountProcessed[provider] &&
|
||||||
this.props.ProviderState[provider].AutoMount &&
|
this.props.ProviderState[provider].AutoMount &&
|
||||||
!mounted &&
|
!mounted &&
|
||||||
(location.length > 0)) {
|
location.length > 0
|
||||||
this.handleMountUnMount(provider, this.props.RemoteMounts.includes(provider), this.props.S3Mounts.includes(provider), true, location);
|
) {
|
||||||
|
this.handleMountUnMount(
|
||||||
|
provider,
|
||||||
|
this.props.RemoteMounts.includes(provider),
|
||||||
|
this.props.S3Mounts.includes(provider),
|
||||||
|
true,
|
||||||
|
location
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -328,104 +419,162 @@ class MountItems extends IPCContainer {
|
|||||||
for (const provider in this.state.RetryItems) {
|
for (const provider in this.state.RetryItems) {
|
||||||
if (this.state.RetryItems.hasOwnProperty(provider)) {
|
if (this.state.RetryItems.hasOwnProperty(provider)) {
|
||||||
if (this.state.RetryItems[provider].RetryMessage) {
|
if (this.state.RetryItems[provider].RetryMessage) {
|
||||||
retryList.push(<p key={'rl_' + retryList.length}>{this.state.RetryItems[provider].RetryMessage}</p>);
|
retryList.push(
|
||||||
|
<p key={'rl_' + retryList.length}>
|
||||||
|
{this.state.RetryItems[provider].RetryMessage}
|
||||||
|
</p>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
retryList.push(<Button clicked={() => this.cancelRetryMount(provider, () => this.detectMounts())}
|
retryList.push(
|
||||||
key={'rl_' + retryList.length}>Cancel {provider} Remount
|
<Button
|
||||||
({this.state.RetryItems[provider].RetrySeconds}s)</Button>);
|
clicked={() =>
|
||||||
|
this.cancelRetryMount(provider, () => this.detectMounts())
|
||||||
|
}
|
||||||
|
key={'rl_' + retryList.length}
|
||||||
|
>
|
||||||
|
Cancel {provider} Remount (
|
||||||
|
{this.state.RetryItems[provider].RetrySeconds}s)
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
if (++retryCount < Object.keys(this.state.RetryItems).length) {
|
if (++retryCount < Object.keys(this.state.RetryItems).length) {
|
||||||
retryList.push(<div style={{paddingTop: 'var(--default_spacing)'}}
|
retryList.push(
|
||||||
key={'rl_' + retryList.length}/>);
|
<div
|
||||||
|
style={{ paddingTop: 'var(--default_spacing)' }}
|
||||||
|
key={'rl_' + retryList.length}
|
||||||
|
/>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
retryDisplay = (
|
retryDisplay = (
|
||||||
<Modal>
|
<Modal>
|
||||||
<Box dxDark dxStyle={{padding: 'var(--default_spacing)', minWidth: '70vw'}}>
|
<Box
|
||||||
<h1 style={{
|
dxDark
|
||||||
|
dxStyle={{ padding: 'var(--default_spacing)', minWidth: '70vw' }}
|
||||||
|
>
|
||||||
|
<h1
|
||||||
|
style={{
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
paddingBottom: 'var(--default_spacing)',
|
paddingBottom: 'var(--default_spacing)',
|
||||||
color: 'var(--text_color_error)'
|
color: 'var(--text_color_error)',
|
||||||
}}>Mount Failed</h1>
|
}}
|
||||||
|
>
|
||||||
|
Mount Failed
|
||||||
|
</h1>
|
||||||
{retryList}
|
{retryList}
|
||||||
</Box>
|
</Box>
|
||||||
</Modal>
|
</Modal>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let footerItems = [];
|
let footerItems = [];
|
||||||
if (this.props.remoteSupported || this.props.s3Supported) {
|
if (this.props.remoteSupported || this.props.s3Supported) {
|
||||||
footerItems.push(<AddMount remoteSupported={this.props.remoteSupported}
|
footerItems.push(
|
||||||
|
<AddMount
|
||||||
|
remoteSupported={this.props.remoteSupported}
|
||||||
s3Supported={this.props.s3Supported}
|
s3Supported={this.props.s3Supported}
|
||||||
key={'hi_' + footerItems.length}/>);
|
key={'hi_' + footerItems.length}
|
||||||
|
/>
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
footerItems.push(<div key={'hi_' + footerItems.length}
|
footerItems.push(
|
||||||
style={{height: '27px'}}/>);
|
<div key={'hi_' + footerItems.length} style={{ height: '27px' }} />
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let items = [];
|
let items = [];
|
||||||
for (const provider of this.getProviderList(true)) {
|
for (const provider of this.getProviderList(true)) {
|
||||||
items.push((
|
items.push(
|
||||||
<MountItem allowRemove={false}
|
<MountItem
|
||||||
|
allowRemove={false}
|
||||||
browseClicked={this.handleBrowseLocation}
|
browseClicked={this.handleBrowseLocation}
|
||||||
changed={e => this.handleMountLocationChanged(provider, e.target.value)}
|
changed={(e) =>
|
||||||
|
this.handleMountLocationChanged(provider, e.target.value)
|
||||||
|
}
|
||||||
clicked={this.handleMountUnMount}
|
clicked={this.handleMountUnMount}
|
||||||
key={'it_' + items.length}
|
key={'it_' + items.length}
|
||||||
provider={provider}/>
|
provider={provider}
|
||||||
));
|
/>
|
||||||
items.push(<div key={'it_' + items.length}
|
);
|
||||||
style={{paddingTop: 'var(--default_spacing)'}} />)
|
items.push(
|
||||||
|
<div
|
||||||
|
key={'it_' + items.length}
|
||||||
|
style={{ paddingTop: 'var(--default_spacing)' }}
|
||||||
|
/>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.props.remoteSupported) {
|
if (this.props.remoteSupported) {
|
||||||
for (const provider of this.props.RemoteMounts) {
|
for (const provider of this.props.RemoteMounts) {
|
||||||
items.push((
|
items.push(
|
||||||
<MountItem allowRemove={true}
|
<MountItem
|
||||||
|
allowRemove={true}
|
||||||
browseClicked={this.handleBrowseLocation}
|
browseClicked={this.handleBrowseLocation}
|
||||||
changed={e => this.handleMountLocationChanged(provider, e.target.value)}
|
changed={(e) =>
|
||||||
|
this.handleMountLocationChanged(provider, e.target.value)
|
||||||
|
}
|
||||||
clicked={this.handleMountUnMount}
|
clicked={this.handleMountUnMount}
|
||||||
key={'it_' + items.length}
|
key={'it_' + items.length}
|
||||||
provider={provider}
|
provider={provider}
|
||||||
remote/>
|
remote
|
||||||
));
|
/>
|
||||||
items.push(<div key={'it_' + items.length}
|
);
|
||||||
style={{paddingTop: 'var(--default_spacing)'}}/>)
|
items.push(
|
||||||
|
<div
|
||||||
|
key={'it_' + items.length}
|
||||||
|
style={{ paddingTop: 'var(--default_spacing)' }}
|
||||||
|
/>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.props.s3Supported) {
|
if (this.props.s3Supported) {
|
||||||
for (const provider of this.props.S3Mounts) {
|
for (const provider of this.props.S3Mounts) {
|
||||||
items.push((
|
items.push(
|
||||||
<MountItem allowRemove={true}
|
<MountItem
|
||||||
|
allowRemove={true}
|
||||||
browseClicked={this.handleBrowseLocation}
|
browseClicked={this.handleBrowseLocation}
|
||||||
changed={e => this.handleMountLocationChanged(provider, e.target.value)}
|
changed={(e) =>
|
||||||
|
this.handleMountLocationChanged(provider, e.target.value)
|
||||||
|
}
|
||||||
clicked={this.handleMountUnMount}
|
clicked={this.handleMountUnMount}
|
||||||
key={'it_' + items.length}
|
key={'it_' + items.length}
|
||||||
provider={provider}
|
provider={provider}
|
||||||
s3/>
|
s3
|
||||||
));
|
/>
|
||||||
items.push(<div key={'it_' + items.length}
|
);
|
||||||
style={{paddingTop: 'var(--default_spacing)'}}/>)
|
items.push(
|
||||||
|
<div
|
||||||
|
key={'it_' + items.length}
|
||||||
|
style={{ paddingTop: 'var(--default_spacing)' }}
|
||||||
|
/>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
items.splice(items.length - 1, 1);
|
items.splice(items.length - 1, 1);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{margin: 0, padding: 0}}>
|
<div style={{ margin: 0, padding: 0 }}>
|
||||||
{retryDisplay}
|
{retryDisplay}
|
||||||
<div
|
<div
|
||||||
className={this.props.remoteSupported || this.props.s3Supported ? 'MountItemsRemote' : 'MountItems'}>
|
className={
|
||||||
|
this.props.remoteSupported || this.props.s3Supported
|
||||||
|
? 'MountItemsRemote'
|
||||||
|
: 'MountItems'
|
||||||
|
}
|
||||||
|
>
|
||||||
{items}
|
{items}
|
||||||
</div>
|
</div>
|
||||||
<div style={{paddingTop: 'var(--default_spacing)'}}/>
|
<div style={{ paddingTop: 'var(--default_spacing)' }} />
|
||||||
{footerItems}
|
{footerItems}
|
||||||
</div>);
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const mapStateToProps = state => {
|
const mapStateToProps = (state) => {
|
||||||
return {
|
return {
|
||||||
AutoMountProcessed: state.mounts.AutoMountProcessed,
|
AutoMountProcessed: state.mounts.AutoMountProcessed,
|
||||||
InstalledVersion: state.relver.InstalledVersion,
|
InstalledVersion: state.relver.InstalledVersion,
|
||||||
@@ -435,20 +584,25 @@ const mapStateToProps = state => {
|
|||||||
ProviderState: state.mounts.ProviderState,
|
ProviderState: state.mounts.ProviderState,
|
||||||
RemoteMounts: state.mounts.RemoteMounts,
|
RemoteMounts: state.mounts.RemoteMounts,
|
||||||
S3Mounts: state.mounts.S3Mounts,
|
S3Mounts: state.mounts.S3Mounts,
|
||||||
}
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapDispatchToProps = dispatch => {
|
const mapDispatchToProps = (dispatch) => {
|
||||||
return {
|
return {
|
||||||
notifyError: (msg, critical, callback) => dispatch(notifyError(msg, critical, callback)),
|
notifyError: (msg, critical, callback) =>
|
||||||
|
dispatch(notifyError(msg, critical, callback)),
|
||||||
resetMountsState: () => dispatch(resetMountsState()),
|
resetMountsState: () => dispatch(resetMountsState()),
|
||||||
setAllowMount: (provider, allow) => dispatch(setAllowMount(provider, allow)),
|
setAllowMount: (provider, allow) =>
|
||||||
setAutoMountProcessed: (provider, processed) => dispatch(setAutoMountProcessed(provider, processed)),
|
dispatch(setAllowMount(provider, allow)),
|
||||||
|
setAutoMountProcessed: (provider, processed) =>
|
||||||
|
dispatch(setAutoMountProcessed(provider, processed)),
|
||||||
setMounted: (provider, mounted) => dispatch(setMounted(provider, mounted)),
|
setMounted: (provider, mounted) => dispatch(setMounted(provider, mounted)),
|
||||||
setMountsBusy: busy => dispatch(setBusy(busy)),
|
setMountsBusy: (busy) => dispatch(setBusy(busy)),
|
||||||
setMountState: (provider, state) => dispatch(setMountState(provider, state)),
|
setMountState: (provider, state) =>
|
||||||
setProviderState: (provider, state) => dispatch(setProviderState(provider, state)),
|
dispatch(setMountState(provider, state)),
|
||||||
}
|
setProviderState: (provider, state) =>
|
||||||
|
dispatch(setProviderState(provider, state)),
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(MountItems);
|
export default connect(mapStateToProps, mapDispatchToProps)(MountItems);
|
||||||
|
|||||||
@@ -1,44 +1,52 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import './PinnedManager.css';
|
import './PinnedManager.css';
|
||||||
import {connect} from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import IPCContainer from '../IPCContainer/IPCContainer';
|
import IPCContainer from '../IPCContainer/IPCContainer';
|
||||||
import {notifyApplicationBusy} from '../../redux/actions/common_actions';
|
import { notifyApplicationBusy } from '../../redux/actions/common_actions';
|
||||||
import {notifyError, notifyInfo} from '../../redux/actions/error_actions';
|
import { notifyError, notifyInfo } from '../../redux/actions/error_actions';
|
||||||
import Box from '../../components/UI/Box/Box';
|
import Box from '../../components/UI/Box/Box';
|
||||||
import {displayPinnedManager} from '../../redux/actions/pinned_manager_actions';
|
import { displayPinnedManager } from '../../redux/actions/pinned_manager_actions';
|
||||||
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
import {faFolder} from '@fortawesome/free-solid-svg-icons';
|
import { faFolder } from '@fortawesome/free-solid-svg-icons';
|
||||||
import Button from '../../components/UI/Button/Button';
|
import Button from '../../components/UI/Button/Button';
|
||||||
import CheckBox from '../../components/UI/CheckBox/CheckBox';
|
import CheckBox from '../../components/UI/CheckBox/CheckBox';
|
||||||
|
|
||||||
const Constants = require('../../constants');
|
const Constants = require('../../constants');
|
||||||
|
|
||||||
const mapStateToProps = state => {
|
const mapStateToProps = (state) => {
|
||||||
return {
|
return {
|
||||||
DisplayConfiguration: state.mounts.DisplayConfiguration,
|
DisplayConfiguration: state.mounts.DisplayConfiguration,
|
||||||
DisplayRemoteConfiguration: state.mounts.DisplayRemoteConfiguration,
|
DisplayRemoteConfiguration: state.mounts.DisplayRemoteConfiguration,
|
||||||
DisplayS3Configuration: state.mounts.DisplayS3Configuration,
|
DisplayS3Configuration: state.mounts.DisplayS3Configuration,
|
||||||
}
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapDispatchToProps = dispatch => {
|
const mapDispatchToProps = (dispatch) => {
|
||||||
return {
|
return {
|
||||||
displayPinnedManager: display => dispatch(displayPinnedManager(display)),
|
displayPinnedManager: (display) => dispatch(displayPinnedManager(display)),
|
||||||
notifyApplicationBusy: busy => dispatch(notifyApplicationBusy(busy, true)),
|
notifyApplicationBusy: (busy) =>
|
||||||
|
dispatch(notifyApplicationBusy(busy, true)),
|
||||||
notifyError: (msg, cb) => dispatch(notifyError(msg, false, cb)),
|
notifyError: (msg, cb) => dispatch(notifyError(msg, false, cb)),
|
||||||
notifyInfo: (title, msg) => dispatch(notifyInfo(title, msg)),
|
notifyInfo: (title, msg) => dispatch(notifyInfo(title, msg)),
|
||||||
}
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(class extends IPCContainer {
|
export default connect(
|
||||||
|
mapStateToProps,
|
||||||
|
mapDispatchToProps
|
||||||
|
)(
|
||||||
|
class extends IPCContainer {
|
||||||
state = {
|
state = {
|
||||||
active_directory: '/',
|
active_directory: '/',
|
||||||
items: [],
|
items: [],
|
||||||
previous: [],
|
previous: [],
|
||||||
}
|
};
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.setRequestHandler(Constants.IPC_Get_Directory_Items_Reply, this.onGetDirectoryItemsReply);
|
this.setRequestHandler(
|
||||||
|
Constants.IPC_Get_Directory_Items_Reply,
|
||||||
|
this.onGetDirectoryItemsReply
|
||||||
|
);
|
||||||
this.grabDirectoryItems();
|
this.grabDirectoryItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,21 +62,26 @@ export default connect(mapStateToProps, mapDispatchToProps)(class extends IPCCon
|
|||||||
Version: this.props.version,
|
Version: this.props.version,
|
||||||
Path: this.state.active_directory,
|
Path: this.state.active_directory,
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
onGetDirectoryItemsReply = (_, {data}) => {
|
onGetDirectoryItemsReply = (_, { data }) => {
|
||||||
if (data.Success) {
|
if (data.Success) {
|
||||||
const items = data.Items
|
const items = data.Items.filter(
|
||||||
.filter(i => i.path !== '.' && (this.state.active_directory !== '/' || (i.path.substr(0, 1) !== '.')))
|
(i) =>
|
||||||
.map(i => {
|
i.path !== '.' &&
|
||||||
|
(this.state.active_directory !== '/' || i.path.substr(0, 1) !== '.')
|
||||||
|
).map((i) => {
|
||||||
return {
|
return {
|
||||||
...i,
|
...i,
|
||||||
name: i.path === '..' ? i.path : i.path.substr(i.path.lastIndexOf('/') + 1),
|
name:
|
||||||
|
i.path === '..'
|
||||||
|
? i.path
|
||||||
|
: i.path.substr(i.path.lastIndexOf('/') + 1),
|
||||||
meta: {
|
meta: {
|
||||||
...i.meta,
|
...i.meta,
|
||||||
pinned: i.meta.pinned === '1',
|
pinned: i.meta.pinned === '1',
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
});
|
});
|
||||||
this.setState({
|
this.setState({
|
||||||
items,
|
items,
|
||||||
@@ -78,16 +91,17 @@ export default connect(mapStateToProps, mapDispatchToProps)(class extends IPCCon
|
|||||||
this.props.displayPinnedManager(false);
|
this.props.displayPinnedManager(false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
createDirectory = (name, path, idx, total, item_idx) => {
|
createDirectory = (name, path, idx, total, item_idx) => {
|
||||||
const style = {}
|
const style = {};
|
||||||
if (item_idx + 1 !== total) {
|
if (item_idx + 1 !== total) {
|
||||||
style.marginBottom = '4px';
|
style.marginBottom = '4px';
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<div key={'dir_' + idx} style={{...style}}>
|
<div key={'dir_' + idx} style={{ ...style }}>
|
||||||
<Button buttonStyles={{textAlign: 'left'}}
|
<Button
|
||||||
|
buttonStyles={{ textAlign: 'left' }}
|
||||||
clicked={() => {
|
clicked={() => {
|
||||||
const previous = [...this.state.previous];
|
const previous = [...this.state.previous];
|
||||||
if (path === '..') {
|
if (path === '..') {
|
||||||
@@ -95,38 +109,48 @@ export default connect(mapStateToProps, mapDispatchToProps)(class extends IPCCon
|
|||||||
} else {
|
} else {
|
||||||
previous.push(this.state.active_directory);
|
previous.push(this.state.active_directory);
|
||||||
}
|
}
|
||||||
this.setState({
|
this.setState(
|
||||||
|
{
|
||||||
items: [],
|
items: [],
|
||||||
active_directory: path,
|
active_directory: path,
|
||||||
previous,
|
previous,
|
||||||
}, () => {
|
},
|
||||||
|
() => {
|
||||||
this.grabDirectoryItems();
|
this.grabDirectoryItems();
|
||||||
});
|
}
|
||||||
}}>
|
);
|
||||||
<FontAwesomeIcon icon={faFolder}
|
}}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon
|
||||||
|
icon={faFolder}
|
||||||
fixedWidth
|
fixedWidth
|
||||||
color={'var(--heading_text_color)'}
|
color={'var(--heading_text_color)'}
|
||||||
style={{padding: 0, margin: 0}}/>
|
style={{ padding: 0, margin: 0 }}
|
||||||
|
/>
|
||||||
{name}
|
{name}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
createFile = (name, path, pinned, idx, total, item_idx) => {
|
createFile = (name, path, pinned, idx, total, item_idx) => {
|
||||||
const style = {textAlign: 'left'}
|
const style = { textAlign: 'left' };
|
||||||
if (item_idx + 1 !== total) {
|
if (item_idx + 1 !== total) {
|
||||||
style.marginBottom = '2px';
|
style.marginBottom = '2px';
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<div key={'file_' + idx} style={{...style}}>
|
<div key={'file_' + idx} style={{ ...style }}>
|
||||||
<CheckBox checked={pinned}
|
<CheckBox
|
||||||
|
checked={pinned}
|
||||||
changed={() => {
|
changed={() => {
|
||||||
const items = JSON.parse(JSON.stringify(this.state.items));
|
const items = JSON.parse(JSON.stringify(this.state.items));
|
||||||
const pinned = items[item_idx].meta.pinned = !items[item_idx].meta.pinned;
|
const pinned = (items[item_idx].meta.pinned = !items[item_idx]
|
||||||
this.setState({
|
.meta.pinned);
|
||||||
items
|
this.setState(
|
||||||
}, () => {
|
{
|
||||||
|
items,
|
||||||
|
},
|
||||||
|
() => {
|
||||||
this.sendSyncRequest(Constants.IPC_Set_Pinned, {
|
this.sendSyncRequest(Constants.IPC_Set_Pinned, {
|
||||||
Provider: this.props.DisplayConfiguration,
|
Provider: this.props.DisplayConfiguration,
|
||||||
Remote: this.props.DisplayRemoteConfiguration,
|
Remote: this.props.DisplayRemoteConfiguration,
|
||||||
@@ -135,46 +159,69 @@ export default connect(mapStateToProps, mapDispatchToProps)(class extends IPCCon
|
|||||||
Path: path,
|
Path: path,
|
||||||
Pinned: pinned,
|
Pinned: pinned,
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
|
);
|
||||||
}}
|
}}
|
||||||
label={name}/>
|
label={name}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let idx = 0;
|
let idx = 0;
|
||||||
return (
|
return (
|
||||||
<Box dxDark dxStyle={{
|
<Box
|
||||||
|
dxDark
|
||||||
|
dxStyle={{
|
||||||
height: 'calc(100vh - (var(--default_spacing) * 4)',
|
height: 'calc(100vh - (var(--default_spacing) * 4)',
|
||||||
padding: 'var(--default_spacing)',
|
padding: 'var(--default_spacing)',
|
||||||
width: 'calc(100vw - (var(--default_spacing) * 4)'
|
width: 'calc(100vw - (var(--default_spacing) * 4)',
|
||||||
}}>
|
}}
|
||||||
|
>
|
||||||
<div className={'PinnedManager'}>
|
<div className={'PinnedManager'}>
|
||||||
<div className={'PinnedManagerHeading'}>
|
<div className={'PinnedManagerHeading'}>
|
||||||
<div className={'PinnedManagerClose'}>
|
<div className={'PinnedManagerClose'}>
|
||||||
<a href={'#'}
|
<a
|
||||||
|
href={'#'}
|
||||||
onClick={() => this.props.displayPinnedManager(false)}
|
onClick={() => this.props.displayPinnedManager(false)}
|
||||||
style={{cursor: 'pointer', flex: '0'}}>X</a>
|
style={{ cursor: 'pointer', flex: '0' }}
|
||||||
|
>
|
||||||
|
X
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<h1 style={{width: '100%', textAlign: 'center'}}>{'Pinned File Manager'}</h1>
|
<h1 style={{ width: '100%', textAlign: 'center' }}>
|
||||||
|
{'Pinned File Manager'}
|
||||||
|
</h1>
|
||||||
<div className={'PinnedManagerActiveDirectory'}>
|
<div className={'PinnedManagerActiveDirectory'}>
|
||||||
<b> {this.state.active_directory}</b>
|
<b> {this.state.active_directory}</b>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={'PinnedManagerItemsOwner'}>
|
<div className={'PinnedManagerItemsOwner'}>
|
||||||
<div className={'PinnedManagerItems'}>
|
<div className={'PinnedManagerItems'}>
|
||||||
{
|
{this.state.items.map((i, k) => {
|
||||||
this.state.items.map((i, k) => {
|
return i.directory
|
||||||
return i.directory ?
|
? this.createDirectory(
|
||||||
this.createDirectory(i.name, i.path, idx++, this.state.items.length, k) :
|
i.name,
|
||||||
this.createFile(i.name, i.path, i.meta.pinned, idx++, this.state.items.length, k);
|
i.path,
|
||||||
})
|
idx++,
|
||||||
}
|
this.state.items.length,
|
||||||
|
k
|
||||||
|
)
|
||||||
|
: this.createFile(
|
||||||
|
i.name,
|
||||||
|
i.path,
|
||||||
|
i.meta.pinned,
|
||||||
|
idx++,
|
||||||
|
this.state.items.length,
|
||||||
|
k
|
||||||
|
);
|
||||||
|
})}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Box>
|
</Box>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|||||||
@@ -1,43 +1,50 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import './SelectAppPlatform.css';
|
import './SelectAppPlatform.css';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import {connect} from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import * as Constants from '../../constants';
|
import * as Constants from '../../constants';
|
||||||
import Box from '../../components/UI/Box/Box';
|
import Box from '../../components/UI/Box/Box';
|
||||||
import Button from '../../components/UI/Button/Button';
|
import Button from '../../components/UI/Button/Button';
|
||||||
import {
|
import {
|
||||||
downloadItem,
|
downloadItem,
|
||||||
setAllowDownload
|
setAllowDownload,
|
||||||
} from '../../redux/actions/download_actions';
|
} from '../../redux/actions/download_actions';
|
||||||
import DropDown from '../../components/UI/DropDown/DropDown';
|
import DropDown from '../../components/UI/DropDown/DropDown';
|
||||||
import IPCContainer from '../IPCContainer/IPCContainer';
|
import IPCContainer from '../IPCContainer/IPCContainer';
|
||||||
import {notifyError} from '../../redux/actions/error_actions';
|
import { notifyError } from '../../redux/actions/error_actions';
|
||||||
import {setInstallTestActive} from '../../redux/actions/install_actions';
|
import { setInstallTestActive } from '../../redux/actions/install_actions';
|
||||||
|
|
||||||
class SelectAppPlatform extends IPCContainer {
|
class SelectAppPlatform extends IPCContainer {
|
||||||
state = {
|
state = {
|
||||||
Selected: 0,
|
Selected: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
grabLatestRelease = appPlatform => {
|
grabLatestRelease = (appPlatform) => {
|
||||||
const errorHandler = error => {
|
const errorHandler = (error) => {
|
||||||
this.props.notifyError(error);
|
this.props.notifyError(error);
|
||||||
this.props.setInstallTestActive(false);
|
this.props.setInstallTestActive(false);
|
||||||
this.props.setAllowDownload(false);
|
this.props.setAllowDownload(false);
|
||||||
};
|
};
|
||||||
axios
|
axios
|
||||||
.get(Constants.RELEASES_URL)
|
.get(Constants.RELEASES_URL)
|
||||||
.then(response => {
|
.then((response) => {
|
||||||
try {
|
try {
|
||||||
const releases = response.data.Versions.Release[appPlatform];
|
const releases = response.data.Versions.Release[appPlatform];
|
||||||
const latestVersion = releases[releases.length - 1];
|
const latestVersion = releases[releases.length - 1];
|
||||||
const release = response.data.Locations[appPlatform][latestVersion];
|
const release = response.data.Locations[appPlatform][latestVersion];
|
||||||
this.props.downloadItem(latestVersion + '.zip', Constants.INSTALL_TYPES.TestRelease, release.urls, false, latestVersion, appPlatform);
|
this.props.downloadItem(
|
||||||
|
latestVersion + '.zip',
|
||||||
|
Constants.INSTALL_TYPES.TestRelease,
|
||||||
|
release.urls,
|
||||||
|
false,
|
||||||
|
latestVersion,
|
||||||
|
appPlatform
|
||||||
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
errorHandler(error);
|
errorHandler(error);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch((error) => {
|
||||||
errorHandler(error);
|
errorHandler(error);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -45,10 +52,12 @@ class SelectAppPlatform extends IPCContainer {
|
|||||||
handleTestClicked = () => {
|
handleTestClicked = () => {
|
||||||
this.props.setInstallTestActive(true);
|
this.props.setInstallTestActive(true);
|
||||||
this.props.setAllowDownload(true);
|
this.props.setAllowDownload(true);
|
||||||
this.grabLatestRelease(Constants.LINUX_SELECTABLE_PLATFORMS[this.state.Selected])
|
this.grabLatestRelease(
|
||||||
|
Constants.LINUX_SELECTABLE_PLATFORMS[this.state.Selected]
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
handleChanged = e => {
|
handleChanged = (e) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
...this.state,
|
...this.state,
|
||||||
Selected: Constants.LINUX_SELECTABLE_PLATFORMS.indexOf(e.target.value),
|
Selected: Constants.LINUX_SELECTABLE_PLATFORMS.indexOf(e.target.value),
|
||||||
@@ -57,36 +66,48 @@ class SelectAppPlatform extends IPCContainer {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<Box dxDark dxStyle={{padding: 'var(--default_spacing)'}}>
|
<Box dxDark dxStyle={{ padding: 'var(--default_spacing)' }}>
|
||||||
<h1 className={'SAPHeading'}>Select Linux Platform</h1>
|
<h1 className={'SAPHeading'}>Select Linux Platform</h1>
|
||||||
<div className={'SAPContent'}>
|
<div className={'SAPContent'}>
|
||||||
<p>Repertory was unable to detect your Linux distribution. Please select one of the following and click <b>Test</b> to continue:</p>
|
<p>
|
||||||
|
Repertory was unable to detect your Linux distribution. Please
|
||||||
|
select one of the following and click <b>Test</b> to continue:
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className={'SAPActions'}>
|
<div className={'SAPActions'}>
|
||||||
<DropDown changed={this.handleChanged}
|
<DropDown
|
||||||
|
changed={this.handleChanged}
|
||||||
disabled={this.props.InstallTestActive}
|
disabled={this.props.InstallTestActive}
|
||||||
items={Constants.LINUX_SELECTABLE_PLATFORMS}
|
items={Constants.LINUX_SELECTABLE_PLATFORMS}
|
||||||
selected={Constants.LINUX_SELECTABLE_PLATFORMS[this.state.Selected]}/>
|
selected={Constants.LINUX_SELECTABLE_PLATFORMS[this.state.Selected]}
|
||||||
<Button clicked={this.handleTestClicked}
|
/>
|
||||||
disabled={this.props.InstallTestActive}>Test</Button>
|
<Button
|
||||||
|
clicked={this.handleTestClicked}
|
||||||
|
disabled={this.props.InstallTestActive}
|
||||||
|
>
|
||||||
|
Test
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const mapStateToProps = state => {
|
const mapStateToProps = (state) => {
|
||||||
return {
|
return {
|
||||||
InstallTestActive: state.install.InstallTestActive,
|
InstallTestActive: state.install.InstallTestActive,
|
||||||
}
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapDispatchToProps = dispatch => {
|
const mapDispatchToProps = (dispatch) => {
|
||||||
return {
|
return {
|
||||||
downloadItem: (name, type, urls, isWinFSP, testVersion, appPlatform) => dispatch(downloadItem(name, type, urls, isWinFSP, testVersion, appPlatform)),
|
downloadItem: (name, type, urls, isWinFSP, testVersion, appPlatform) =>
|
||||||
notifyError: msg => dispatch(notifyError(msg)),
|
dispatch(
|
||||||
setAllowDownload: allow => dispatch(setAllowDownload(allow)),
|
downloadItem(name, type, urls, isWinFSP, testVersion, appPlatform)
|
||||||
setInstallTestActive: active => dispatch(setInstallTestActive(active)),
|
),
|
||||||
|
notifyError: (msg) => dispatch(notifyError(msg)),
|
||||||
|
setAllowDownload: (allow) => dispatch(setAllowDownload(allow)),
|
||||||
|
setInstallTestActive: (active) => dispatch(setInstallTestActive(active)),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,58 +1,77 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import './SkynetExport.css';
|
import './SkynetExport.css';
|
||||||
import CheckboxTree from 'react-checkbox-tree';
|
import CheckboxTree from 'react-checkbox-tree';
|
||||||
import {connect} from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import IPCContainer from '../IPCContainer/IPCContainer';
|
import IPCContainer from '../IPCContainer/IPCContainer';
|
||||||
import {notifyApplicationBusy} from '../../redux/actions/common_actions';
|
import { notifyApplicationBusy } from '../../redux/actions/common_actions';
|
||||||
import {notifyError, notifyInfo} from '../../redux/actions/error_actions';
|
import { notifyError, notifyInfo } from '../../redux/actions/error_actions';
|
||||||
import Box from '../../components/UI/Box/Box';
|
import Box from '../../components/UI/Box/Box';
|
||||||
import {displaySkynetExport} from '../../redux/actions/skynet_actions';
|
import { displaySkynetExport } from '../../redux/actions/skynet_actions';
|
||||||
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
import {
|
import {
|
||||||
faCheckSquare, faChevronDown,
|
faCheckSquare,
|
||||||
faChevronRight, faFile, faFolder, faFolderOpen,
|
faChevronDown,
|
||||||
faHSquare, faMinusSquare, faPlusSquare,
|
faChevronRight,
|
||||||
faSquare
|
faFile,
|
||||||
|
faFolder,
|
||||||
|
faFolderOpen,
|
||||||
|
faHSquare,
|
||||||
|
faMinusSquare,
|
||||||
|
faPlusSquare,
|
||||||
|
faSquare,
|
||||||
} from '@fortawesome/free-solid-svg-icons';
|
} from '@fortawesome/free-solid-svg-icons';
|
||||||
import Button from '../../components/UI/Button/Button';
|
import Button from '../../components/UI/Button/Button';
|
||||||
|
|
||||||
const Constants = require('../../constants');
|
const Constants = require('../../constants');
|
||||||
|
|
||||||
const mapStateToProps = state => {
|
const mapStateToProps = (state) => {
|
||||||
return {
|
return {
|
||||||
AppBusy: state.common.AppBusy,
|
AppBusy: state.common.AppBusy,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapDispatchToProps = dispatch => {
|
const mapDispatchToProps = (dispatch) => {
|
||||||
return {
|
return {
|
||||||
displaySkynetExport: display => dispatch(displaySkynetExport(display)),
|
displaySkynetExport: (display) => dispatch(displaySkynetExport(display)),
|
||||||
notifyApplicationBusy: busy => dispatch(notifyApplicationBusy(busy, true)),
|
notifyApplicationBusy: (busy) =>
|
||||||
notifyError: msg => dispatch(notifyError(msg)),
|
dispatch(notifyApplicationBusy(busy, true)),
|
||||||
|
notifyError: (msg) => dispatch(notifyError(msg)),
|
||||||
notifyInfo: (title, msg) => dispatch(notifyInfo(title, msg)),
|
notifyInfo: (title, msg) => dispatch(notifyInfo(title, msg)),
|
||||||
}
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(class extends IPCContainer {
|
export default connect(
|
||||||
|
mapStateToProps,
|
||||||
|
mapDispatchToProps
|
||||||
|
)(
|
||||||
|
class extends IPCContainer {
|
||||||
state = {
|
state = {
|
||||||
checked: [],
|
checked: [],
|
||||||
clicked: {},
|
clicked: {},
|
||||||
expanded: [],
|
expanded: [],
|
||||||
nodes: [],
|
nodes: [],
|
||||||
second_stage: false,
|
second_stage: false,
|
||||||
}
|
};
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.setRequestHandler(Constants.IPC_Grab_Skynet_Tree_Reply, this.onGrabSkynetTreeReply);
|
this.setRequestHandler(
|
||||||
this.setRequestHandler(Constants.IPC_Export_Skylinks_Reply, this.onExportSkylinksReply);
|
Constants.IPC_Grab_Skynet_Tree_Reply,
|
||||||
this.sendRequest(Constants.IPC_Grab_Skynet_Tree, {Version: this.props.version});
|
this.onGrabSkynetTreeReply
|
||||||
|
);
|
||||||
|
this.setRequestHandler(
|
||||||
|
Constants.IPC_Export_Skylinks_Reply,
|
||||||
|
this.onExportSkylinksReply
|
||||||
|
);
|
||||||
|
this.sendRequest(Constants.IPC_Grab_Skynet_Tree, {
|
||||||
|
Version: this.props.version,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
super.componentWillUnmount();
|
super.componentWillUnmount();
|
||||||
}
|
}
|
||||||
|
|
||||||
createNodes = items => {
|
createNodes = (items) => {
|
||||||
/*
|
/*
|
||||||
{
|
{
|
||||||
name: '',
|
name: '',
|
||||||
@@ -66,7 +85,12 @@ export default connect(mapStateToProps, mapDispatchToProps)(class extends IPCCon
|
|||||||
const treeItem = {
|
const treeItem = {
|
||||||
label: item.name,
|
label: item.name,
|
||||||
path: item.path,
|
path: item.path,
|
||||||
value: item.name === '/' ? 0 : item.path ? item.path : JSON.stringify(item),
|
value:
|
||||||
|
item.name === '/'
|
||||||
|
? 0
|
||||||
|
: item.path
|
||||||
|
? item.path
|
||||||
|
: JSON.stringify(item),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (item.directory) {
|
if (item.directory) {
|
||||||
@@ -77,7 +101,7 @@ export default connect(mapStateToProps, mapDispatchToProps)(class extends IPCCon
|
|||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
};
|
||||||
|
|
||||||
handleNavigation = () => {
|
handleNavigation = () => {
|
||||||
if (this.state.second_stage) {
|
if (this.state.second_stage) {
|
||||||
@@ -95,25 +119,34 @@ export default connect(mapStateToProps, mapDispatchToProps)(class extends IPCCon
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
onExportSkylinksReply = (_, arg) => {
|
onExportSkylinksReply = (_, arg) => {
|
||||||
this.props.notifyApplicationBusy(false);
|
this.props.notifyApplicationBusy(false);
|
||||||
if (arg.data.Success) {
|
if (arg.data.Success) {
|
||||||
this.setState({
|
this.setState(
|
||||||
|
{
|
||||||
checked: [],
|
checked: [],
|
||||||
clicked: {},
|
clicked: {},
|
||||||
expanded: [],
|
expanded: [],
|
||||||
nodes: [],
|
nodes: [],
|
||||||
second_stage: false,
|
second_stage: false,
|
||||||
}, () => {
|
},
|
||||||
this.props.notifyInfo('Skylink Exports', '!alternate!!copyable!' + JSON.stringify(arg.data.Result.success, null, 2));
|
() => {
|
||||||
this.sendRequest(Constants.IPC_Grab_Skynet_Tree, {Version: this.props.version});
|
this.props.notifyInfo(
|
||||||
|
'Skylink Exports',
|
||||||
|
'!alternate!!copyable!' +
|
||||||
|
JSON.stringify(arg.data.Result.success, null, 2)
|
||||||
|
);
|
||||||
|
this.sendRequest(Constants.IPC_Grab_Skynet_Tree, {
|
||||||
|
Version: this.props.version,
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
this.props.notifyError(arg.data.Error);
|
this.props.notifyError(arg.data.Error);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
onGrabSkynetTreeReply = (_, arg) => {
|
onGrabSkynetTreeReply = (_, arg) => {
|
||||||
if (arg.data.Success) {
|
if (arg.data.Success) {
|
||||||
@@ -123,23 +156,31 @@ export default connect(mapStateToProps, mapDispatchToProps)(class extends IPCCon
|
|||||||
nodes: this.createNodes(arg.data.Result),
|
nodes: this.createNodes(arg.data.Result),
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.setState({
|
this.setState(
|
||||||
|
{
|
||||||
checked: [],
|
checked: [],
|
||||||
expanded: [],
|
expanded: [],
|
||||||
nodes: [],
|
nodes: [],
|
||||||
}, () => {
|
},
|
||||||
|
() => {
|
||||||
this.props.notifyError(arg.data.Error);
|
this.props.notifyError(arg.data.Error);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return this.props.AppBusy ? (<div/>) : (
|
return this.props.AppBusy ? (
|
||||||
<Box dxDark dxStyle={{
|
<div />
|
||||||
|
) : (
|
||||||
|
<Box
|
||||||
|
dxDark
|
||||||
|
dxStyle={{
|
||||||
height: '90vh',
|
height: '90vh',
|
||||||
padding: 'var(--default_spacing)',
|
padding: 'var(--default_spacing)',
|
||||||
width: 'calc(100vw - (var(--default_spacing) * 4)'
|
width: 'calc(100vw - (var(--default_spacing) * 4)',
|
||||||
}}>
|
}}
|
||||||
|
>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
float: 'right',
|
float: 'right',
|
||||||
@@ -147,89 +188,161 @@ export default connect(mapStateToProps, mapDispatchToProps)(class extends IPCCon
|
|||||||
padding: 0,
|
padding: 0,
|
||||||
marginTop: '-4px',
|
marginTop: '-4px',
|
||||||
boxSizing: 'border-box',
|
boxSizing: 'border-box',
|
||||||
display: 'block'
|
display: 'block',
|
||||||
}}>
|
}}
|
||||||
<a href={'#'}
|
>
|
||||||
|
<a
|
||||||
|
href={'#'}
|
||||||
onClick={() => this.props.displaySkynetExport(false)}
|
onClick={() => this.props.displaySkynetExport(false)}
|
||||||
style={{cursor: 'pointer'}}>X</a>
|
style={{ cursor: 'pointer' }}
|
||||||
|
>
|
||||||
|
X
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<h1
|
<h1 className={'SkynetExportHeading'}>
|
||||||
className={'SkynetExportHeading'}>{this.state.second_stage ? 'Verify Exports' : 'Export Files'}</h1>
|
{this.state.second_stage ? 'Verify Exports' : 'Export Files'}
|
||||||
<div className={this.state.second_stage ? 'SkynetExportList' : 'SkynetExportTree'}>
|
</h1>
|
||||||
{
|
<div
|
||||||
this.state.second_stage ?
|
className={
|
||||||
this.state.checked.map(path => {
|
this.state.second_stage ? 'SkynetExportList' : 'SkynetExportTree'
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{this.state.second_stage ? (
|
||||||
|
this.state.checked.map((path) => {
|
||||||
return (
|
return (
|
||||||
<input readOnly
|
<input
|
||||||
|
readOnly
|
||||||
className={'ConfigurationItemInput'}
|
className={'ConfigurationItemInput'}
|
||||||
key={path}
|
key={path}
|
||||||
style={{width: '100%', marginBottom: 'var(--default_spacing)'}}
|
style={{
|
||||||
|
width: '100%',
|
||||||
|
marginBottom: 'var(--default_spacing)',
|
||||||
|
}}
|
||||||
type={'text'}
|
type={'text'}
|
||||||
value={path}/>
|
value={path}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
: (
|
) : (
|
||||||
<CheckboxTree checked={this.state.checked}
|
<CheckboxTree
|
||||||
|
checked={this.state.checked}
|
||||||
expanded={this.state.expanded}
|
expanded={this.state.expanded}
|
||||||
expandOnClick
|
expandOnClick
|
||||||
showExpandAll
|
showExpandAll
|
||||||
icons={{
|
icons={{
|
||||||
check: <FontAwesomeIcon icon={faCheckSquare} fixedWidth
|
check: (
|
||||||
style={{padding: 0, margin: 0}}/>,
|
<FontAwesomeIcon
|
||||||
uncheck: <FontAwesomeIcon icon={faSquare} fixedWidth
|
icon={faCheckSquare}
|
||||||
style={{padding: 0, margin: 0}}/>,
|
fixedWidth
|
||||||
halfCheck: <FontAwesomeIcon icon={faHSquare} fixedWidth
|
style={{ padding: 0, margin: 0 }}
|
||||||
style={{padding: 0, margin: 0}}/>,
|
/>
|
||||||
expandClose: <FontAwesomeIcon icon={faChevronRight} fixedWidth
|
),
|
||||||
style={{padding: 0, margin: 0}}/>,
|
uncheck: (
|
||||||
expandOpen: <FontAwesomeIcon icon={faChevronDown} fixedWidth
|
<FontAwesomeIcon
|
||||||
style={{padding: 0, margin: 0}}/>,
|
icon={faSquare}
|
||||||
expandAll: <FontAwesomeIcon icon={faPlusSquare} fixedWidth
|
fixedWidth
|
||||||
style={{padding: 0, margin: 0}}/>,
|
style={{ padding: 0, margin: 0 }}
|
||||||
collapseAll: <FontAwesomeIcon icon={faMinusSquare} fixedWidth
|
/>
|
||||||
style={{padding: 0, margin: 0}}/>,
|
),
|
||||||
parentClose: <FontAwesomeIcon icon={faFolder}
|
halfCheck: (
|
||||||
|
<FontAwesomeIcon
|
||||||
|
icon={faHSquare}
|
||||||
|
fixedWidth
|
||||||
|
style={{ padding: 0, margin: 0 }}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
expandClose: (
|
||||||
|
<FontAwesomeIcon
|
||||||
|
icon={faChevronRight}
|
||||||
|
fixedWidth
|
||||||
|
style={{ padding: 0, margin: 0 }}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
expandOpen: (
|
||||||
|
<FontAwesomeIcon
|
||||||
|
icon={faChevronDown}
|
||||||
|
fixedWidth
|
||||||
|
style={{ padding: 0, margin: 0 }}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
expandAll: (
|
||||||
|
<FontAwesomeIcon
|
||||||
|
icon={faPlusSquare}
|
||||||
|
fixedWidth
|
||||||
|
style={{ padding: 0, margin: 0 }}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
collapseAll: (
|
||||||
|
<FontAwesomeIcon
|
||||||
|
icon={faMinusSquare}
|
||||||
|
fixedWidth
|
||||||
|
style={{ padding: 0, margin: 0 }}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
parentClose: (
|
||||||
|
<FontAwesomeIcon
|
||||||
|
icon={faFolder}
|
||||||
fixedWidth
|
fixedWidth
|
||||||
color={'var(--heading_text_color)'}
|
color={'var(--heading_text_color)'}
|
||||||
style={{padding: 0, margin: 0}}/>,
|
style={{ padding: 0, margin: 0 }}
|
||||||
parentOpen: <FontAwesomeIcon icon={faFolderOpen}
|
/>
|
||||||
|
),
|
||||||
|
parentOpen: (
|
||||||
|
<FontAwesomeIcon
|
||||||
|
icon={faFolderOpen}
|
||||||
fixedWidth
|
fixedWidth
|
||||||
color={'var(--heading_text_color)'}
|
color={'var(--heading_text_color)'}
|
||||||
style={{padding: 0, margin: 0}}/>,
|
style={{ padding: 0, margin: 0 }}
|
||||||
leaf: <FontAwesomeIcon icon={faFile}
|
/>
|
||||||
|
),
|
||||||
|
leaf: (
|
||||||
|
<FontAwesomeIcon
|
||||||
|
icon={faFile}
|
||||||
fixedWidth
|
fixedWidth
|
||||||
color={'var(--text_color)'}
|
color={'var(--text_color)'}
|
||||||
style={{padding: 0, margin: 0}}/>
|
style={{ padding: 0, margin: 0 }}
|
||||||
|
/>
|
||||||
|
),
|
||||||
}}
|
}}
|
||||||
nodes={this.state.nodes}
|
nodes={this.state.nodes}
|
||||||
onClick={clicked => this.setState({clicked})}
|
onClick={(clicked) => this.setState({ clicked })}
|
||||||
onCheck={checked => this.setState({checked})}
|
onCheck={(checked) => this.setState({ checked })}
|
||||||
onExpand={expanded => this.setState({expanded})}/>
|
onExpand={(expanded) => this.setState({ expanded })}
|
||||||
)
|
/>
|
||||||
}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div style={{display: 'flex', justifyContent: 'flex-end'}}>
|
<div style={{ display: 'flex', justifyContent: 'flex-end' }}>
|
||||||
{
|
{this.state.second_stage ? (
|
||||||
this.state.second_stage ?
|
<Button
|
||||||
<Button buttonStyles={{
|
buttonStyles={{
|
||||||
height: 'auto',
|
height: 'auto',
|
||||||
marginLeft: 'var(--default_spacing)',
|
marginLeft: 'var(--default_spacing)',
|
||||||
marginTop: 'var(--default_spacing)',
|
marginTop: 'var(--default_spacing)',
|
||||||
width: 'auto'
|
width: 'auto',
|
||||||
}} clicked={() => this.setState({
|
|
||||||
second_stage: false,
|
|
||||||
})}>{'Back'}</Button> :
|
|
||||||
null
|
|
||||||
}
|
|
||||||
<Button buttonStyles={{
|
|
||||||
height: 'auto',
|
|
||||||
marginLeft: 'var(--default_spacing)',
|
|
||||||
marginTop: 'var(--default_spacing)',
|
|
||||||
width: 'auto'
|
|
||||||
}}
|
}}
|
||||||
clicked={this.handleNavigation}>{this.state.second_stage ? 'Export' : 'Next'}</Button>
|
clicked={() =>
|
||||||
|
this.setState({
|
||||||
|
second_stage: false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{'Back'}
|
||||||
|
</Button>
|
||||||
|
) : null}
|
||||||
|
<Button
|
||||||
|
buttonStyles={{
|
||||||
|
height: 'auto',
|
||||||
|
marginLeft: 'var(--default_spacing)',
|
||||||
|
marginTop: 'var(--default_spacing)',
|
||||||
|
width: 'auto',
|
||||||
|
}}
|
||||||
|
clicked={this.handleNavigation}
|
||||||
|
>
|
||||||
|
{this.state.second_stage ? 'Export' : 'Next'}
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|||||||
@@ -1,30 +1,36 @@
|
|||||||
import React from 'react'
|
import React from 'react';
|
||||||
import './Import.css'
|
import './Import.css';
|
||||||
|
|
||||||
const Import = ({data}) => {
|
const Import = ({ data }) => {
|
||||||
return (
|
return (
|
||||||
<div className={'ImportOwner'}>
|
<div className={'ImportOwner'}>
|
||||||
<input readOnly
|
<input
|
||||||
|
readOnly
|
||||||
className={'ConfigurationItemInput'}
|
className={'ConfigurationItemInput'}
|
||||||
style={{
|
style={{
|
||||||
maxWidth: 'calc(33.33% - var(--default_spacing)',
|
maxWidth: 'calc(33.33% - var(--default_spacing)',
|
||||||
marginRight: 'var(--default_spacing)'
|
marginRight: 'var(--default_spacing)',
|
||||||
}}
|
}}
|
||||||
type={'text'}
|
type={'text'}
|
||||||
value={data.directory}/>
|
value={data.directory}
|
||||||
<input readOnly
|
/>
|
||||||
|
<input
|
||||||
|
readOnly
|
||||||
className={'ConfigurationItemInput'}
|
className={'ConfigurationItemInput'}
|
||||||
style={{maxWidth: 'calc(33.33% - calc(var(--default_spacing) / 2))'}}
|
style={{ maxWidth: 'calc(33.33% - calc(var(--default_spacing) / 2))' }}
|
||||||
type={'text'}
|
type={'text'}
|
||||||
value={data.skylink}/>
|
value={data.skylink}
|
||||||
<input readOnly
|
/>
|
||||||
|
<input
|
||||||
|
readOnly
|
||||||
className={'ConfigurationItemInput'}
|
className={'ConfigurationItemInput'}
|
||||||
style={{
|
style={{
|
||||||
maxWidth: 'calc(33.33% - calc(var(--default_spacing) / 2))',
|
maxWidth: 'calc(33.33% - calc(var(--default_spacing) / 2))',
|
||||||
marginLeft: 'var(--default_spacing)'
|
marginLeft: 'var(--default_spacing)',
|
||||||
}}
|
}}
|
||||||
type={'text'}
|
type={'text'}
|
||||||
value={data.token}/>
|
value={data.token}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,29 +1,38 @@
|
|||||||
import React from 'react'
|
import React from 'react';
|
||||||
import './ImportList.css'
|
import './ImportList.css';
|
||||||
import Import from './Import/Import'
|
import Import from './Import/Import';
|
||||||
import Text from '../../../components/UI/Text/Text';
|
import Text from '../../../components/UI/Text/Text';
|
||||||
|
|
||||||
const ImportList = ({imports_array}) => {
|
const ImportList = ({ imports_array }) => {
|
||||||
let key = 0;
|
let key = 0;
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className={'ImportListHeader'}>
|
<div className={'ImportListHeader'}>
|
||||||
<Text type={'Heading1'} text={'Directory'}
|
<Text
|
||||||
style={{minWidth: '33.33%', maxWidth: '33.33%'}}/>
|
type={'Heading1'}
|
||||||
<Text type={'Heading1'} text={'Skylink'} style={{minWidth: '33.33%', maxWidth: '33.33%'}}/>
|
text={'Directory'}
|
||||||
<Text type={'Heading1'} text={'Token'} style={{minWidth: '33.33%', maxWidth: '33.33%'}}/>
|
style={{ minWidth: '33.33%', maxWidth: '33.33%' }}
|
||||||
|
/>
|
||||||
|
<Text
|
||||||
|
type={'Heading1'}
|
||||||
|
text={'Skylink'}
|
||||||
|
style={{ minWidth: '33.33%', maxWidth: '33.33%' }}
|
||||||
|
/>
|
||||||
|
<Text
|
||||||
|
type={'Heading1'}
|
||||||
|
text={'Token'}
|
||||||
|
style={{ minWidth: '33.33%', maxWidth: '33.33%' }}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<hr/>
|
<hr />
|
||||||
<div className={'ImportListOwner'}>
|
<div className={'ImportListOwner'}>
|
||||||
{
|
{imports_array.map((data) => {
|
||||||
imports_array.map(data => {
|
|
||||||
return (
|
return (
|
||||||
<div key={'import_' + key++}>
|
<div key={'import_' + key++}>
|
||||||
<Import data={data}/>
|
<Import data={data} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
})
|
})}
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,36 +1,37 @@
|
|||||||
import React from 'react'
|
import React from 'react';
|
||||||
import {connect} from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import './SkynetImport.css'
|
import './SkynetImport.css';
|
||||||
import Box from '../../components/UI/Box/Box';
|
import Box from '../../components/UI/Box/Box';
|
||||||
import Button from '../../components/UI/Button/Button';
|
import Button from '../../components/UI/Button/Button';
|
||||||
import {displaySkynetImport} from '../../redux/actions/skynet_actions';
|
import { displaySkynetImport } from '../../redux/actions/skynet_actions';
|
||||||
import ImportList from './ImportList/ImportList'
|
import ImportList from './ImportList/ImportList';
|
||||||
import IPCContainer from '../IPCContainer/IPCContainer';
|
import IPCContainer from '../IPCContainer/IPCContainer';
|
||||||
import {notifyApplicationBusy} from '../../redux/actions/common_actions';
|
import { notifyApplicationBusy } from '../../redux/actions/common_actions';
|
||||||
import {
|
import { notifyError, notifyInfo } from '../../redux/actions/error_actions';
|
||||||
notifyError,
|
|
||||||
notifyInfo
|
|
||||||
} from '../../redux/actions/error_actions';
|
|
||||||
|
|
||||||
const Constants = require('../../constants');
|
const Constants = require('../../constants');
|
||||||
|
|
||||||
const mapStateToProps = state => {
|
const mapStateToProps = (state) => {
|
||||||
return {
|
return {
|
||||||
AppBusy: state.common.AppBusy,
|
AppBusy: state.common.AppBusy,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapDispatchToProps = dispatch => {
|
const mapDispatchToProps = (dispatch) => {
|
||||||
return {
|
return {
|
||||||
displaySkynetImport: display => dispatch(displaySkynetImport(display)),
|
displaySkynetImport: (display) => dispatch(displaySkynetImport(display)),
|
||||||
notifyApplicationBusy: busy => dispatch(notifyApplicationBusy(busy, true)),
|
notifyApplicationBusy: (busy) =>
|
||||||
notifyError: msg => dispatch(notifyError(msg)),
|
dispatch(notifyApplicationBusy(busy, true)),
|
||||||
|
notifyError: (msg) => dispatch(notifyError(msg)),
|
||||||
notifyInfo: (title, msg) => dispatch(notifyInfo(title, msg)),
|
notifyInfo: (title, msg) => dispatch(notifyInfo(title, msg)),
|
||||||
}
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(class SkynetImport extends IPCContainer {
|
export default connect(
|
||||||
|
mapStateToProps,
|
||||||
|
mapDispatchToProps
|
||||||
|
)(
|
||||||
|
class SkynetImport extends IPCContainer {
|
||||||
state = {
|
state = {
|
||||||
import_text: '',
|
import_text: '',
|
||||||
imports_array: [],
|
imports_array: [],
|
||||||
@@ -38,7 +39,10 @@ export default connect(mapStateToProps, mapDispatchToProps)(class SkynetImport e
|
|||||||
};
|
};
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.setRequestHandler(Constants.IPC_Import_Skylinks_Reply, this.onImportSkylinksReply);
|
this.setRequestHandler(
|
||||||
|
Constants.IPC_Import_Skylinks_Reply,
|
||||||
|
this.onImportSkylinksReply
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
@@ -46,7 +50,8 @@ export default connect(mapStateToProps, mapDispatchToProps)(class SkynetImport e
|
|||||||
}
|
}
|
||||||
|
|
||||||
displaySyntax = () => {
|
displaySyntax = () => {
|
||||||
const msg = '!alternate!To import Skylinks into the root directory, list each Skylink on a new line:\n' +
|
const msg =
|
||||||
|
'!alternate!To import Skylinks into the root directory, list each Skylink on a new line:\n' +
|
||||||
' AACeCiD6WQG6DzDcCdIu3cFPSxMUMoQPx46NYSyijNMKUA\n' +
|
' AACeCiD6WQG6DzDcCdIu3cFPSxMUMoQPx46NYSyijNMKUA\n' +
|
||||||
' AACyjmDGoHqY7mTaxi-rkpnKUJGZK1B4UhrF74Nv6tY6Cg\n' +
|
' AACyjmDGoHqY7mTaxi-rkpnKUJGZK1B4UhrF74Nv6tY6Cg\n' +
|
||||||
'\n' +
|
'\n' +
|
||||||
@@ -71,8 +76,8 @@ export default connect(mapStateToProps, mapDispatchToProps)(class SkynetImport e
|
|||||||
' "token": "My Password"\n' +
|
' "token": "My Password"\n' +
|
||||||
' }\n' +
|
' }\n' +
|
||||||
' ]';
|
' ]';
|
||||||
this.props.notifyInfo('Import Syntax', msg)
|
this.props.notifyInfo('Import Syntax', msg);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleNavigation = () => {
|
handleNavigation = () => {
|
||||||
if (this.state.second_stage) {
|
if (this.state.second_stage) {
|
||||||
@@ -96,7 +101,7 @@ export default connect(mapStateToProps, mapDispatchToProps)(class SkynetImport e
|
|||||||
importsArray = JSON.parse(this.state.import_text.trim());
|
importsArray = JSON.parse(this.state.import_text.trim());
|
||||||
break;
|
break;
|
||||||
} else if (item.indexOf('=') >= 0) {
|
} else if (item.indexOf('=') >= 0) {
|
||||||
const parts = item.split(',')
|
const parts = item.split(',');
|
||||||
let importItem = {
|
let importItem = {
|
||||||
directory: '/',
|
directory: '/',
|
||||||
skylink: '',
|
skylink: '',
|
||||||
@@ -106,7 +111,9 @@ export default connect(mapStateToProps, mapDispatchToProps)(class SkynetImport e
|
|||||||
part = part.trim();
|
part = part.trim();
|
||||||
const pair = part.split('=');
|
const pair = part.split('=');
|
||||||
if (pair.length !== 2) {
|
if (pair.length !== 2) {
|
||||||
throw new Error('Invalid syntax for import: directory="",skylink="",token=""');
|
throw new Error(
|
||||||
|
'Invalid syntax for import: directory="",skylink="",token=""'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
importItem = {
|
importItem = {
|
||||||
...importItem,
|
...importItem,
|
||||||
@@ -114,7 +121,9 @@ export default connect(mapStateToProps, mapDispatchToProps)(class SkynetImport e
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (!importItem.skylink) {
|
if (!importItem.skylink) {
|
||||||
throw new Error('Invalid syntax for import: directory="",skylink="",token=""');
|
throw new Error(
|
||||||
|
'Invalid syntax for import: directory="",skylink="",token=""'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
importsArray.push(importItem);
|
importsArray.push(importItem);
|
||||||
} else if (item.length > 0) {
|
} else if (item.length > 0) {
|
||||||
@@ -136,38 +145,54 @@ export default connect(mapStateToProps, mapDispatchToProps)(class SkynetImport e
|
|||||||
this.props.notifyError(e);
|
this.props.notifyError(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
onImportSkylinksReply = (_, arg) => {
|
onImportSkylinksReply = (_, arg) => {
|
||||||
this.props.notifyApplicationBusy(false);
|
this.props.notifyApplicationBusy(false);
|
||||||
if (arg.data.Success) {
|
if (arg.data.Success) {
|
||||||
const failedImportsArray = this.state.imports_array.filter(i => {
|
const failedImportsArray = this.state.imports_array.filter((i) => {
|
||||||
return arg.data.Result.failed.includes(i.skylink);
|
return arg.data.Result.failed.includes(i.skylink);
|
||||||
});
|
});
|
||||||
const count = this.state.imports_array.length;
|
const count = this.state.imports_array.length;
|
||||||
this.setState({
|
this.setState(
|
||||||
import_text: failedImportsArray.length > 0 ? JSON.stringify(failedImportsArray, null, 2) : '',
|
{
|
||||||
|
import_text:
|
||||||
|
failedImportsArray.length > 0
|
||||||
|
? JSON.stringify(failedImportsArray, null, 2)
|
||||||
|
: '',
|
||||||
imports_array: [],
|
imports_array: [],
|
||||||
second_stage: false,
|
second_stage: false,
|
||||||
}, () => {
|
},
|
||||||
|
() => {
|
||||||
if (failedImportsArray.length > 0) {
|
if (failedImportsArray.length > 0) {
|
||||||
this.props.notifyError(`Failed to import ${failedImportsArray.length} item(s)`);
|
this.props.notifyError(
|
||||||
|
`Failed to import ${failedImportsArray.length} item(s)`
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
this.props.notifyInfo('Import Result', `Successfully imported ${count} item(s)`);
|
this.props.notifyInfo(
|
||||||
|
'Import Result',
|
||||||
|
`Successfully imported ${count} item(s)`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
this.props.notifyError(arg.data.Error);
|
this.props.notifyError(arg.data.Error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return this.props.AppBusy ? (<div/>) : (
|
return this.props.AppBusy ? (
|
||||||
<Box dxDark dxStyle={{
|
<div />
|
||||||
|
) : (
|
||||||
|
<Box
|
||||||
|
dxDark
|
||||||
|
dxStyle={{
|
||||||
height: 'auto',
|
height: 'auto',
|
||||||
padding: 'var(--default_spacing)',
|
padding: 'var(--default_spacing)',
|
||||||
width: 'calc(100vw - (var(--default_spacing) * 4)'
|
width: 'calc(100vw - (var(--default_spacing) * 4)',
|
||||||
}}>
|
}}
|
||||||
|
>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
float: 'right',
|
float: 'right',
|
||||||
@@ -175,54 +200,79 @@ export default connect(mapStateToProps, mapDispatchToProps)(class SkynetImport e
|
|||||||
padding: 0,
|
padding: 0,
|
||||||
marginTop: '-4px',
|
marginTop: '-4px',
|
||||||
boxSizing: 'border-box',
|
boxSizing: 'border-box',
|
||||||
display: 'block'
|
display: 'block',
|
||||||
}}>
|
}}
|
||||||
<a href={'#'}
|
>
|
||||||
|
<a
|
||||||
|
href={'#'}
|
||||||
onClick={() => this.props.displaySkynetImport(false)}
|
onClick={() => this.props.displaySkynetImport(false)}
|
||||||
style={{cursor: 'pointer'}}>X</a>
|
style={{ cursor: 'pointer' }}
|
||||||
|
>
|
||||||
|
X
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<h1
|
<h1 className={'SkynetImportHeading'}>
|
||||||
className={'SkynetImportHeading'}>{this.state.second_stage ? 'Verify Imports' : 'Import List'}</h1>
|
{this.state.second_stage ? 'Verify Imports' : 'Import List'}
|
||||||
{
|
</h1>
|
||||||
this.state.second_stage ? (
|
{this.state.second_stage ? (
|
||||||
<ImportList imports_array={this.state.imports_array}/>
|
<ImportList imports_array={this.state.imports_array} />
|
||||||
) : (
|
) : (
|
||||||
<textarea autoFocus={true}
|
<textarea
|
||||||
|
autoFocus={true}
|
||||||
className={'SkynetImportTextArea'}
|
className={'SkynetImportTextArea'}
|
||||||
onChange={e => this.setState({
|
onChange={(e) =>
|
||||||
|
this.setState({
|
||||||
import_text: e.target.value,
|
import_text: e.target.value,
|
||||||
})}
|
})
|
||||||
value={this.state.import_text}
|
|
||||||
rows={10}/>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
value={this.state.import_text}
|
||||||
|
rows={10}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
<div className={'SkynetImportButtons'}>
|
<div className={'SkynetImportButtons'}>
|
||||||
<Button
|
<Button
|
||||||
buttonStyles={{height: 'auto', marginTop: 'var(--default_spacing)', width: 'auto'}}
|
buttonStyles={{
|
||||||
clicked={this.displaySyntax}>Import Syntax...</Button>
|
|
||||||
<div className={'SkynetActionButtons'}>
|
|
||||||
{
|
|
||||||
this.state.second_stage ?
|
|
||||||
<Button buttonStyles={{
|
|
||||||
height: 'auto',
|
height: 'auto',
|
||||||
marginLeft: 'var(--default_spacing)',
|
|
||||||
marginTop: 'var(--default_spacing)',
|
marginTop: 'var(--default_spacing)',
|
||||||
width: 'auto'
|
width: 'auto',
|
||||||
}} clicked={() => this.setState({
|
|
||||||
second_stage: false,
|
|
||||||
})}>{'Back'}</Button> :
|
|
||||||
null
|
|
||||||
}
|
|
||||||
<Button buttonStyles={{
|
|
||||||
height: 'auto',
|
|
||||||
marginLeft: 'var(--default_spacing)',
|
|
||||||
marginTop: 'var(--default_spacing)',
|
|
||||||
width: 'auto'
|
|
||||||
}}
|
}}
|
||||||
clicked={this.handleNavigation}>{this.state.second_stage ? 'Import' : 'Next'}</Button>
|
clicked={this.displaySyntax}
|
||||||
|
>
|
||||||
|
Import Syntax...
|
||||||
|
</Button>
|
||||||
|
<div className={'SkynetActionButtons'}>
|
||||||
|
{this.state.second_stage ? (
|
||||||
|
<Button
|
||||||
|
buttonStyles={{
|
||||||
|
height: 'auto',
|
||||||
|
marginLeft: 'var(--default_spacing)',
|
||||||
|
marginTop: 'var(--default_spacing)',
|
||||||
|
width: 'auto',
|
||||||
|
}}
|
||||||
|
clicked={() =>
|
||||||
|
this.setState({
|
||||||
|
second_stage: false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{'Back'}
|
||||||
|
</Button>
|
||||||
|
) : null}
|
||||||
|
<Button
|
||||||
|
buttonStyles={{
|
||||||
|
height: 'auto',
|
||||||
|
marginLeft: 'var(--default_spacing)',
|
||||||
|
marginTop: 'var(--default_spacing)',
|
||||||
|
width: 'auto',
|
||||||
|
}}
|
||||||
|
clicked={this.handleNavigation}
|
||||||
|
>
|
||||||
|
{this.state.second_stage ? 'Import' : 'Next'}
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import React, {Component} from 'react';
|
import React, { Component } from 'react';
|
||||||
import './Password.css';
|
import './Password.css';
|
||||||
import {faEye, faEyeSlash} from '@fortawesome/free-solid-svg-icons';
|
import { faEye, faEyeSlash } from '@fortawesome/free-solid-svg-icons';
|
||||||
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
|
|
||||||
export default class Password extends Component {
|
export default class Password extends Component {
|
||||||
state = {
|
state = {
|
||||||
@@ -12,14 +12,14 @@ export default class Password extends Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
if (!this.props.value || (this.props.value.length === 0)) {
|
if (!this.props.value || this.props.value.length === 0) {
|
||||||
this.setState({
|
this.setState({
|
||||||
...this.state,
|
...this.state,
|
||||||
button_text: 'set',
|
button_text: 'set',
|
||||||
password: '',
|
password: '',
|
||||||
password2: '',
|
password2: '',
|
||||||
show_password: false,
|
show_password: false,
|
||||||
})
|
});
|
||||||
} else {
|
} else {
|
||||||
this.setState({
|
this.setState({
|
||||||
...this.state,
|
...this.state,
|
||||||
@@ -27,7 +27,7 @@ export default class Password extends Component {
|
|||||||
password: this.props.value,
|
password: this.props.value,
|
||||||
password2: '',
|
password2: '',
|
||||||
show_password: false,
|
show_password: false,
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,20 +48,26 @@ export default class Password extends Component {
|
|||||||
this.props.changed(this.state.password);
|
this.props.changed(this.state.password);
|
||||||
this.setState({
|
this.setState({
|
||||||
...this.state,
|
...this.state,
|
||||||
button_text: this.state.password && this.state.password.length > 0 ? 'clear' : 'set',
|
button_text:
|
||||||
|
this.state.password && this.state.password.length > 0
|
||||||
|
? 'clear'
|
||||||
|
: 'set',
|
||||||
password2: '',
|
password2: '',
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.setState({
|
this.setState(
|
||||||
|
{
|
||||||
...this.state,
|
...this.state,
|
||||||
button_text: 'set',
|
button_text: 'set',
|
||||||
password: '',
|
password: '',
|
||||||
password2: '',
|
password2: '',
|
||||||
}, () => {
|
},
|
||||||
|
() => {
|
||||||
if (this.props.mismatchHandler) {
|
if (this.props.mismatchHandler) {
|
||||||
this.props.mismatchHandler();
|
this.props.mismatchHandler();
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -79,7 +85,7 @@ export default class Password extends Component {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
handlePasswordChanged = e => {
|
handlePasswordChanged = (e) => {
|
||||||
if (this.state.button_text === 'set') {
|
if (this.state.button_text === 'set') {
|
||||||
this.setState({
|
this.setState({
|
||||||
...this.state,
|
...this.state,
|
||||||
@@ -93,8 +99,11 @@ export default class Password extends Component {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
handlePasswordKeyUp = e => {
|
handlePasswordKeyUp = (e) => {
|
||||||
if ((e.keyCode === 13) && ((this.state.button_text === 'confirm') || (this.state.button_text === 'set'))) {
|
if (
|
||||||
|
e.keyCode === 13 &&
|
||||||
|
(this.state.button_text === 'confirm' || this.state.button_text === 'set')
|
||||||
|
) {
|
||||||
this.handleActionClick();
|
this.handleActionClick();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -108,28 +117,41 @@ export default class Password extends Component {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div className={'PasswordOwner'} style={{...this.props.style}}>
|
<div className={'PasswordOwner'} style={{ ...this.props.style }}>
|
||||||
{
|
{this.props.readOnly ? null : (
|
||||||
this.props.readOnly ? null : <a href={'#'}
|
<a
|
||||||
|
href={'#'}
|
||||||
className={'PasswordLink'}
|
className={'PasswordLink'}
|
||||||
onClick={this.handleActionClick}>
|
onClick={this.handleActionClick}
|
||||||
|
>
|
||||||
<u>{this.state.button_text}</u>
|
<u>{this.state.button_text}</u>
|
||||||
</a>
|
</a>
|
||||||
}
|
)}
|
||||||
<input autoFocus={this.props.autoFocus}
|
<input
|
||||||
|
autoFocus={this.props.autoFocus}
|
||||||
readOnly={this.props.readOnly}
|
readOnly={this.props.readOnly}
|
||||||
className={'PasswordInput'}
|
className={'PasswordInput'}
|
||||||
disabled={this.props.readOnly || (this.state.button_text === 'clear')}
|
disabled={this.props.readOnly || this.state.button_text === 'clear'}
|
||||||
onChange={this.handlePasswordChanged}
|
onChange={this.handlePasswordChanged}
|
||||||
onKeyUp={this.handlePasswordKeyUp}
|
onKeyUp={this.handlePasswordKeyUp}
|
||||||
type={this.state.show_password ? 'text' : 'password'}
|
type={this.state.show_password ? 'text' : 'password'}
|
||||||
value={(this.state.button_text === 'confirm') ? this.state.password2 : this.state.password}/>
|
value={
|
||||||
<a href={'#'}
|
this.state.button_text === 'confirm'
|
||||||
|
? this.state.password2
|
||||||
|
: this.state.password
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<a
|
||||||
|
href={'#'}
|
||||||
className={'PasswordShowHide'}
|
className={'PasswordShowHide'}
|
||||||
onClick={this.handleShowHideClick}>
|
onClick={this.handleShowHideClick}
|
||||||
<FontAwesomeIcon icon={this.state.show_password ? faEye : faEyeSlash} fixedWidth/>
|
>
|
||||||
|
<FontAwesomeIcon
|
||||||
|
icon={this.state.show_password ? faEye : faEyeSlash}
|
||||||
|
fixedWidth
|
||||||
|
/>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|||||||
656
src/helpers.js
656
src/helpers.js
File diff suppressed because it is too large
Load Diff
@@ -8,28 +8,33 @@ test('verify signature success', () => {
|
|||||||
.verifySignature(
|
.verifySignature(
|
||||||
path.resolve('test/test_verify_signature.dat'),
|
path.resolve('test/test_verify_signature.dat'),
|
||||||
path.resolve('test/test_verify_signature.dat.sig'),
|
path.resolve('test/test_verify_signature.dat.sig'),
|
||||||
path.resolve('blockstorage_dev_public.pem'))
|
path.resolve('blockstorage_dev_public.pem')
|
||||||
.then(stdout => {
|
)
|
||||||
|
.then((stdout) => {
|
||||||
expect(stdout).toBeDefined();
|
expect(stdout).toBeDefined();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('verify signature fail', () => {
|
test('verify signature fail', () => {
|
||||||
return expect(helpers
|
return expect(
|
||||||
.verifySignature(
|
helpers.verifySignature(
|
||||||
path.resolve('test/test_verify_signature_fail.dat'),
|
path.resolve('test/test_verify_signature_fail.dat'),
|
||||||
path.resolve('test/test_verify_signature.dat.sig'),
|
path.resolve('test/test_verify_signature.dat.sig'),
|
||||||
path.resolve('blockstorage_dev_public.pem')))
|
path.resolve('blockstorage_dev_public.pem')
|
||||||
.rejects
|
)
|
||||||
.toThrow()
|
).rejects.toThrow();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('create temp signature files', () => {
|
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 b64signature = fs
|
||||||
const data = helpers
|
.readFileSync(path.resolve('test/test_create_signature.sig.b64'), {
|
||||||
.createSignatureFiles(
|
encoding: 'utf8',
|
||||||
|
})
|
||||||
|
.replace(/(\r\n|\n|\r)/gm, '');
|
||||||
|
const data = helpers.createSignatureFiles(
|
||||||
b64signature,
|
b64signature,
|
||||||
Constants.DEV_PUBLIC_KEY);
|
Constants.DEV_PUBLIC_KEY
|
||||||
|
);
|
||||||
expect(data).toBeDefined();
|
expect(data).toBeDefined();
|
||||||
expect(data.PublicKeyFile).toBeDefined();
|
expect(data.PublicKeyFile).toBeDefined();
|
||||||
expect(data.SignatureFile).toBeDefined();
|
expect(data.SignatureFile).toBeDefined();
|
||||||
@@ -37,22 +42,33 @@ test('create temp signature files', () => {
|
|||||||
expect(fs.statSync(data.SignatureFile).isFile()).toBe(true);
|
expect(fs.statSync(data.SignatureFile).isFile()).toBe(true);
|
||||||
expect(fs.statSync(data.PublicKeyFile).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(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.PublicKeyFile);
|
||||||
fs.unlinkSync(data.SignatureFile);
|
fs.unlinkSync(data.SignatureFile);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('verify sha56 success', ()=> {
|
test('verify sha56 success', () => {
|
||||||
const hash = fs.readFileSync('test/test_verify_sha256.dat.sha256', {encoding: 'utf8'});
|
const hash = fs.readFileSync('test/test_verify_sha256.dat.sha256', {
|
||||||
return expect(helpers.verifyHash(path.resolve('test/test_verify_sha256.dat'), hash))
|
encoding: 'utf8',
|
||||||
.resolves.toBe(hash)
|
});
|
||||||
|
return expect(
|
||||||
|
helpers.verifyHash(path.resolve('test/test_verify_sha256.dat'), hash)
|
||||||
|
).resolves.toBe(hash);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('verify sha56 fail', ()=> {
|
test('verify sha56 fail', () => {
|
||||||
const hash = fs.readFileSync('test/test_verify_sha256.dat.sha256', {encoding: 'utf8'});
|
const hash = fs.readFileSync('test/test_verify_sha256.dat.sha256', {
|
||||||
return expect(helpers.verifyHash(path.resolve('test/test_verify_sha256_fail.dat'), hash))
|
encoding: 'utf8',
|
||||||
.rejects.toThrow();
|
});
|
||||||
|
return expect(
|
||||||
|
helpers.verifyHash(path.resolve('test/test_verify_sha256_fail.dat'), hash)
|
||||||
|
).rejects.toThrow();
|
||||||
});
|
});
|
||||||
@@ -35,7 +35,8 @@ a {
|
|||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
html, body {
|
html,
|
||||||
|
body {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
@@ -52,7 +53,9 @@ p {
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1, h2, h3 {
|
h1,
|
||||||
|
h2,
|
||||||
|
h3 {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
@@ -65,7 +68,8 @@ h1 {
|
|||||||
color: var(--heading_text_color);
|
color: var(--heading_text_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
h2, h3 {
|
h2,
|
||||||
|
h3 {
|
||||||
color: var(--heading_other_text_color);
|
color: var(--heading_other_text_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,19 +85,23 @@ p {
|
|||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
.scrollable-content, ::-webkit-scrollbar {
|
.scrollable-content,
|
||||||
|
::-webkit-scrollbar {
|
||||||
width: 8px;
|
width: 8px;
|
||||||
height: 8px;
|
height: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.scrollable-content, ::-webkit-scrollbar * {
|
.scrollable-content,
|
||||||
|
::-webkit-scrollbar * {
|
||||||
background: transparent;
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.scrollable-content, ::-webkit-scrollbar-thumb {
|
.scrollable-content,
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
background: var(--control_background_hover) !important;
|
background: var(--control_background_hover) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.scrollbar-corner, ::-webkit-scrollbar-corner {
|
.scrollbar-corner,
|
||||||
|
::-webkit-scrollbar-corner {
|
||||||
background: transparent;
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
|||||||
20
src/index.js
20
src/index.js
@@ -3,16 +3,16 @@ import 'react-checkbox-tree/lib/react-checkbox-tree.css';
|
|||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import {Provider} from 'react-redux';
|
import { Provider } from 'react-redux';
|
||||||
|
|
||||||
import packageJson from '../package.json';
|
import packageJson from '../package.json';
|
||||||
|
|
||||||
import App from './App.jsx';
|
import App from './App.jsx';
|
||||||
import {setProviderState} from './redux/actions/mount_actions';
|
import { setProviderState } from './redux/actions/mount_actions';
|
||||||
import {setActiveRelease} from './redux/actions/release_version_actions';
|
import { setActiveRelease } from './redux/actions/release_version_actions';
|
||||||
import createAppStore from './redux/store/createAppStore';
|
import createAppStore from './redux/store/createAppStore';
|
||||||
import * as serviceWorker from './serviceWorker';
|
import * as serviceWorker from './serviceWorker';
|
||||||
import {getIPCRenderer} from './utils';
|
import { getIPCRenderer } from './utils.jsx';
|
||||||
|
|
||||||
const Constants = require('./constants');
|
const Constants = require('./constants');
|
||||||
|
|
||||||
@@ -45,16 +45,18 @@ if (ipcRenderer) {
|
|||||||
store.dispatch(setProviderState(provider, state));
|
store.dispatch(setProviderState(provider, state));
|
||||||
}
|
}
|
||||||
store.dispatch(
|
store.dispatch(
|
||||||
setActiveRelease(result.data.Release, result.data.Version));
|
setActiveRelease(result.data.Release, result.data.Version)
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
store = createAppStore(platformInfo, packageJson.version, {});
|
store = createAppStore(platformInfo, packageJson.version, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
ReactDOM.render((
|
ReactDOM.render(
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
<App/>
|
<App />
|
||||||
</Provider>
|
</Provider>,
|
||||||
), document.getElementById('root'));
|
document.getElementById('root')
|
||||||
|
);
|
||||||
serviceWorker.unregister();
|
serviceWorker.unregister();
|
||||||
});
|
});
|
||||||
ipcRenderer.send(Constants.IPC_Get_State);
|
ipcRenderer.send(Constants.IPC_Get_State);
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
|
import { createAction } from '@reduxjs/toolkit';
|
||||||
|
|
||||||
import * as Constants from '../../constants';
|
import * as Constants from '../../constants';
|
||||||
import {createAction} from '@reduxjs/toolkit';
|
import { getIPCRenderer } from '../../utils.jsx';
|
||||||
import {getIPCRenderer} from '../../utils';
|
|
||||||
|
|
||||||
const ipcRenderer = getIPCRenderer();
|
const ipcRenderer = getIPCRenderer();
|
||||||
let yesNoResolvers = [];
|
let yesNoResolvers = [];
|
||||||
|
|
||||||
export const confirmYesNo = title => {
|
export const confirmYesNo = (title) => {
|
||||||
return dispatch => {
|
return (dispatch) => {
|
||||||
return new Promise(resolve => {
|
return new Promise((resolve) => {
|
||||||
dispatch(handleConfirmYesNo(true, title, resolve));
|
dispatch(handleConfirmYesNo(true, title, resolve));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -17,15 +18,12 @@ export const DISPLAY_CONFIRM_YES_NO = 'common/displayConfirmYesNo';
|
|||||||
const displayConfirmYesNo = (show, title) => {
|
const displayConfirmYesNo = (show, title) => {
|
||||||
return {
|
return {
|
||||||
type: DISPLAY_CONFIRM_YES_NO,
|
type: DISPLAY_CONFIRM_YES_NO,
|
||||||
payload: {
|
payload: { show, title },
|
||||||
show,
|
|
||||||
title
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const displaySelectAppPlatform = display => {
|
export const displaySelectAppPlatform = (display) => {
|
||||||
return dispatch => {
|
return (dispatch) => {
|
||||||
if (display) {
|
if (display) {
|
||||||
dispatch(showWindow());
|
dispatch(showWindow());
|
||||||
}
|
}
|
||||||
@@ -34,14 +32,14 @@ export const displaySelectAppPlatform = display => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const hideConfirmYesNo = confirmed => {
|
export const hideConfirmYesNo = (confirmed) => {
|
||||||
return dispatch => {
|
return (dispatch) => {
|
||||||
dispatch(handleConfirmYesNo(false, confirmed));
|
dispatch(handleConfirmYesNo(false, confirmed));
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleConfirmYesNo = (show, titleOrConfirmed, resolve) => {
|
const handleConfirmYesNo = (show, titleOrConfirmed, resolve) => {
|
||||||
return dispatch => {
|
return (dispatch) => {
|
||||||
if (show) {
|
if (show) {
|
||||||
yesNoResolvers.push(resolve);
|
yesNoResolvers.push(resolve);
|
||||||
dispatch(displayConfirmYesNo(show, titleOrConfirmed));
|
dispatch(displayConfirmYesNo(show, titleOrConfirmed));
|
||||||
@@ -57,26 +55,23 @@ export const NOTIFY_APPLICATION_BUSY = 'common/notifyApplicationBusy';
|
|||||||
export const notifyApplicationBusy = (busy, transparent) => {
|
export const notifyApplicationBusy = (busy, transparent) => {
|
||||||
return {
|
return {
|
||||||
type: NOTIFY_APPLICATION_BUSY,
|
type: NOTIFY_APPLICATION_BUSY,
|
||||||
payload: {
|
payload: { busy, transparent },
|
||||||
busy,
|
|
||||||
transparent
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const notifyRebootRequired = createAction('common/notifyRebootRequired');
|
export const notifyRebootRequired = createAction('common/notifyRebootRequired');
|
||||||
|
|
||||||
export const rebootSystem = () => {
|
export const rebootSystem = () => {
|
||||||
return dispatch => {
|
return (dispatch) => {
|
||||||
dispatch(setApplicationReady(false));
|
dispatch(setApplicationReady(false));
|
||||||
if (ipcRenderer) {
|
if (ipcRenderer) {
|
||||||
ipcRenderer.send(Constants.IPC_Reboot_System);
|
ipcRenderer.send(Constants.IPC_Reboot_System);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const saveState = () => {
|
export const saveState = () => {
|
||||||
return (dispatch, getState) => {
|
return (_, getState) => {
|
||||||
const state = getState();
|
const state = getState();
|
||||||
if (state.common.AppReady) {
|
if (state.common.AppReady) {
|
||||||
let currentState = {
|
let currentState = {
|
||||||
@@ -94,9 +89,7 @@ export const saveState = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ipcRenderer) {
|
if (ipcRenderer) {
|
||||||
ipcRenderer.send(Constants.IPC_Save_State, {
|
ipcRenderer.send(Constants.IPC_Save_State, { State: currentState });
|
||||||
State: currentState
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -106,7 +99,7 @@ export const setAllowMount = createAction('common/setAllowMount');
|
|||||||
export const setApplicationReady = createAction('common/setApplicationReady');
|
export const setApplicationReady = createAction('common/setApplicationReady');
|
||||||
|
|
||||||
export const SET_DISPLAY_SELECT_APPPLATFORM = 'common/displaySelectAppPlatform';
|
export const SET_DISPLAY_SELECT_APPPLATFORM = 'common/displaySelectAppPlatform';
|
||||||
export const setDisplaySelectAppPlatform = display => {
|
export const setDisplaySelectAppPlatform = (display) => {
|
||||||
return {
|
return {
|
||||||
type: SET_DISPLAY_SELECT_APPPLATFORM,
|
type: SET_DISPLAY_SELECT_APPPLATFORM,
|
||||||
payload: display,
|
payload: display,
|
||||||
@@ -116,14 +109,14 @@ export const setDisplaySelectAppPlatform = display => {
|
|||||||
export const setLinuxAppPlatform = createAction('common/setLinuxAppPlatform');
|
export const setLinuxAppPlatform = createAction('common/setLinuxAppPlatform');
|
||||||
|
|
||||||
export const setRebootRequired = () => {
|
export const setRebootRequired = () => {
|
||||||
return dispatch => {
|
return (dispatch) => {
|
||||||
dispatch(showWindow());
|
dispatch(showWindow());
|
||||||
dispatch(notifyRebootRequired(true));
|
dispatch(notifyRebootRequired(true));
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const showWindow = () => {
|
export const showWindow = () => {
|
||||||
return dispatch => {
|
return (_) => {
|
||||||
if (ipcRenderer) {
|
if (ipcRenderer) {
|
||||||
ipcRenderer.send(Constants.IPC_Show_Window);
|
ipcRenderer.send(Constants.IPC_Show_Window);
|
||||||
}
|
}
|
||||||
@@ -131,7 +124,7 @@ export const showWindow = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const shutdownApplication = () => {
|
export const shutdownApplication = () => {
|
||||||
return dispatch => {
|
return (dispatch) => {
|
||||||
dispatch(setApplicationReady(false));
|
dispatch(setApplicationReady(false));
|
||||||
if (ipcRenderer) {
|
if (ipcRenderer) {
|
||||||
ipcRenderer.send(Constants.IPC_Shutdown);
|
ipcRenderer.send(Constants.IPC_Shutdown);
|
||||||
|
|||||||
@@ -1,54 +1,72 @@
|
|||||||
|
import { createAction } from '@reduxjs/toolkit';
|
||||||
|
|
||||||
import * as Constants from '../../constants';
|
import * as Constants from '../../constants';
|
||||||
import {createAction} from '@reduxjs/toolkit';
|
import { getIPCRenderer } from '../../utils.jsx';
|
||||||
import {getIPCRenderer} from '../../utils';
|
|
||||||
import {notifyError} from './error_actions';
|
import { notifyError } from './error_actions';
|
||||||
import {
|
import {
|
||||||
installAndTestRelease,
|
installAndTestRelease,
|
||||||
installDependency,
|
installDependency,
|
||||||
installRelease,
|
installRelease,
|
||||||
installUpgrade
|
installUpgrade,
|
||||||
} from './install_actions';
|
} from './install_actions';
|
||||||
|
|
||||||
export const setAllowDownload = createAction('download/setAllowDownload');
|
export const setAllowDownload = createAction('download/setAllowDownload');
|
||||||
|
|
||||||
export const SET_DOWNLOAD_BEGIN = 'download/setDownloadBegin';
|
export const SET_DOWNLOAD_BEGIN = 'download/setDownloadBegin';
|
||||||
export const setDownloadBegin = (name, type, url) => {
|
export const setDownloadBegin = (name, type, url) => {
|
||||||
return {
|
return { type: SET_DOWNLOAD_BEGIN, payload: { name, type, url } };
|
||||||
type: SET_DOWNLOAD_BEGIN,
|
|
||||||
payload: {
|
|
||||||
name,
|
|
||||||
type,
|
|
||||||
url
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const setDownloadEnd = createAction('download/setDownloadEnd');
|
export const setDownloadEnd = createAction('download/setDownloadEnd');
|
||||||
export const setDownloadProgress = createAction('download/setDownloadProgress');
|
export const setDownloadProgress = createAction('download/setDownloadProgress');
|
||||||
|
|
||||||
export const downloadItem = (name, type, urls, isWinFSP, testVersion, appPlatform) => {
|
export const downloadItem = (
|
||||||
|
name,
|
||||||
|
type,
|
||||||
|
urls,
|
||||||
|
isWinFSP,
|
||||||
|
testVersion,
|
||||||
|
appPlatform
|
||||||
|
) => {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
if (!Array.isArray(urls)) {
|
if (!Array.isArray(urls)) {
|
||||||
urls = [urls];
|
urls = [urls];
|
||||||
}
|
}
|
||||||
|
|
||||||
const downloadComplete = result => {
|
const downloadComplete = (result) => {
|
||||||
if (result.Success) {
|
if (result.Success) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case Constants.INSTALL_TYPES.Dependency:
|
case Constants.INSTALL_TYPES.Dependency:
|
||||||
dispatch(installDependency(result.Destination, result.URL, isWinFSP));
|
dispatch(
|
||||||
|
installDependency(result.Destination, result.URL, isWinFSP)
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case Constants.INSTALL_TYPES.Release:
|
case Constants.INSTALL_TYPES.Release:
|
||||||
dispatch(installRelease(result.Destination));
|
dispatch(installRelease(result.Destination));
|
||||||
break;
|
break;
|
||||||
case Constants.INSTALL_TYPES.TestRelease:
|
case Constants.INSTALL_TYPES.TestRelease:
|
||||||
dispatch(installAndTestRelease(result.Destination, testVersion, appPlatform));
|
dispatch(
|
||||||
|
installAndTestRelease(
|
||||||
|
result.Destination,
|
||||||
|
testVersion,
|
||||||
|
appPlatform
|
||||||
|
)
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case Constants.INSTALL_TYPES.Upgrade:
|
case Constants.INSTALL_TYPES.Upgrade:
|
||||||
//const info = this.props.LocationsLookup[this.props.AppPlatform][this.props.VersionLookup[this.props.AppPlatform][0]];
|
// const info =
|
||||||
const sha256 = null;//info.sha256;
|
// this.props.LocationsLookup[this.props.AppPlatform][this.props.VersionLookup[this.props.AppPlatform][0]];
|
||||||
const signature = null;//info.sig;
|
const sha256 = null; // info.sha256;
|
||||||
dispatch(installUpgrade(result.Destination, sha256, signature, !!result.SkipVerification));
|
const signature = null; // info.sig;
|
||||||
|
dispatch(
|
||||||
|
installUpgrade(
|
||||||
|
result.Destination,
|
||||||
|
sha256,
|
||||||
|
signature,
|
||||||
|
!!result.SkipVerification
|
||||||
|
)
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dispatch(notifyError('Unknown download type: ' + type));
|
dispatch(notifyError('Unknown download type: ' + type));
|
||||||
@@ -62,10 +80,13 @@ export const downloadItem = (name, type, urls, isWinFSP, testVersion, appPlatfor
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const downloadAtIndex = index => {
|
const downloadAtIndex = (index) => {
|
||||||
const url = urls[index];
|
const url = urls[index];
|
||||||
const state = getState();
|
const state = getState();
|
||||||
if ((index > 0) || (!state.download.DownloadActive && state.download.AllowDownload)) {
|
if (
|
||||||
|
index > 0 ||
|
||||||
|
(!state.download.DownloadActive && state.download.AllowDownload)
|
||||||
|
) {
|
||||||
const ipcRenderer = getIPCRenderer();
|
const ipcRenderer = getIPCRenderer();
|
||||||
if (ipcRenderer) {
|
if (ipcRenderer) {
|
||||||
dispatch(setDownloadBegin(name, type, url));
|
dispatch(setDownloadBegin(name, type, url));
|
||||||
@@ -75,8 +96,11 @@ export const downloadItem = (name, type, urls, isWinFSP, testVersion, appPlatfor
|
|||||||
};
|
};
|
||||||
|
|
||||||
const downloadFileComplete = (_, arg) => {
|
const downloadFileComplete = (_, arg) => {
|
||||||
ipcRenderer.removeListener(Constants.IPC_Download_File_Progress, downloadFileProgress);
|
ipcRenderer.removeListener(
|
||||||
if (!arg.data.Success && (++index < urls.length)) {
|
Constants.IPC_Download_File_Progress,
|
||||||
|
downloadFileProgress
|
||||||
|
);
|
||||||
|
if (!arg.data.Success && ++index < urls.length) {
|
||||||
downloadAtIndex(index);
|
downloadAtIndex(index);
|
||||||
} else {
|
} else {
|
||||||
downloadComplete(arg.data);
|
downloadComplete(arg.data);
|
||||||
@@ -84,8 +108,14 @@ export const downloadItem = (name, type, urls, isWinFSP, testVersion, appPlatfor
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ipcRenderer.on(Constants.IPC_Download_File_Progress, downloadFileProgress);
|
ipcRenderer.on(
|
||||||
ipcRenderer.once(Constants.IPC_Download_File_Complete, downloadFileComplete);
|
Constants.IPC_Download_File_Progress,
|
||||||
|
downloadFileProgress
|
||||||
|
);
|
||||||
|
ipcRenderer.once(
|
||||||
|
Constants.IPC_Download_File_Complete,
|
||||||
|
downloadFileComplete
|
||||||
|
);
|
||||||
|
|
||||||
ipcRenderer.send(Constants.IPC_Download_File, {
|
ipcRenderer.send(Constants.IPC_Download_File, {
|
||||||
Filename: name,
|
Filename: name,
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
import {
|
import { showWindow, shutdownApplication } from './common_actions';
|
||||||
showWindow,
|
|
||||||
shutdownApplication
|
|
||||||
} from './common_actions';
|
|
||||||
|
|
||||||
let ErrorActions = [];
|
let ErrorActions = [];
|
||||||
|
|
||||||
@@ -36,13 +33,13 @@ export const dismissError = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const dismissInfo = () => {
|
export const dismissInfo = () => {
|
||||||
return dispatch => {
|
return (dispatch) => {
|
||||||
dispatch(clearInfo());
|
dispatch(clearInfo());
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const notifyError = (msg, critical, callback) => {
|
export const notifyError = (msg, critical, callback) => {
|
||||||
return dispatch => {
|
return (dispatch) => {
|
||||||
ErrorActions = [callback, ...ErrorActions];
|
ErrorActions = [callback, ...ErrorActions];
|
||||||
msg = msg ? msg.toString() : 'Unknown Error';
|
msg = msg ? msg.toString() : 'Unknown Error';
|
||||||
dispatch(setErrorInfo(msg, critical));
|
dispatch(setErrorInfo(msg, critical));
|
||||||
@@ -51,7 +48,7 @@ export const notifyError = (msg, critical, callback) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const notifyInfo = (title, msg) => {
|
export const notifyInfo = (title, msg) => {
|
||||||
return dispatch => {
|
return (dispatch) => {
|
||||||
title = title ? title.toString() : 'Information';
|
title = title ? title.toString() : 'Information';
|
||||||
msg = msg ? msg.toString() : '';
|
msg = msg ? msg.toString() : '';
|
||||||
dispatch(setInfo(title, msg));
|
dispatch(setInfo(title, msg));
|
||||||
@@ -60,23 +57,10 @@ export const notifyInfo = (title, msg) => {
|
|||||||
|
|
||||||
export const SET_ERROR_INFO = 'error/setErrorInfo';
|
export const SET_ERROR_INFO = 'error/setErrorInfo';
|
||||||
export const setErrorInfo = (msg, critical) => {
|
export const setErrorInfo = (msg, critical) => {
|
||||||
return {
|
return { type: SET_ERROR_INFO, payload: { msg, critical } };
|
||||||
type: SET_ERROR_INFO,
|
|
||||||
payload: {
|
|
||||||
msg,
|
|
||||||
critical
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
export const SET_INFO = 'error/setInfo';
|
export const SET_INFO = 'error/setInfo';
|
||||||
export const setInfo = (title, msg) => {
|
export const setInfo = (title, msg) => {
|
||||||
return {
|
return { type: SET_INFO, payload: { title, msg } };
|
||||||
type: SET_INFO,
|
|
||||||
payload: {
|
|
||||||
title,
|
|
||||||
msg
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
@@ -1,18 +1,8 @@
|
|||||||
|
import { createAction } from '@reduxjs/toolkit';
|
||||||
|
|
||||||
import * as Constants from '../../constants';
|
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 {
|
import {
|
||||||
confirmYesNo,
|
confirmYesNo,
|
||||||
displaySelectAppPlatform,
|
displaySelectAppPlatform,
|
||||||
@@ -21,18 +11,28 @@ import {
|
|||||||
setLinuxAppPlatform,
|
setLinuxAppPlatform,
|
||||||
setRebootRequired,
|
setRebootRequired,
|
||||||
showWindow,
|
showWindow,
|
||||||
shutdownApplication
|
shutdownApplication,
|
||||||
} from './common_actions';
|
} 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();
|
const ipcRenderer = getIPCRenderer();
|
||||||
|
|
||||||
export const checkInstalled = (dependencies, version) => {
|
export const checkInstalled = (dependencies, version) => {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
const checkInstalledComplete = (event, arg) => {
|
const checkInstalledComplete = (_, arg) => {
|
||||||
const result = arg.data;
|
const result = arg.data;
|
||||||
const updateState = () => {
|
const updateState = () => {
|
||||||
const installedVersion = result.Success && result.Exists ? result.Version : 'none';
|
const installedVersion =
|
||||||
|
result.Success && result.Exists ? result.Version : 'none';
|
||||||
const state = getState();
|
const state = getState();
|
||||||
|
|
||||||
const release = state.relver.Release;
|
const release = state.relver.Release;
|
||||||
@@ -40,7 +40,9 @@ export const checkInstalled = (dependencies, version) => {
|
|||||||
|
|
||||||
let upgradeAvailable = false;
|
let upgradeAvailable = false;
|
||||||
if (installedVersion !== 'none') {
|
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) {
|
if (version === -1) {
|
||||||
version = latestVersion;
|
version = latestVersion;
|
||||||
dispatch(setActiveRelease(release, version));
|
dispatch(setActiveRelease(release, version));
|
||||||
@@ -57,14 +59,18 @@ export const checkInstalled = (dependencies, version) => {
|
|||||||
const autoInstallRelease = getState().install.AutoInstallRelease;
|
const autoInstallRelease = getState().install.AutoInstallRelease;
|
||||||
dispatch(setAutoInstallRelease(false));
|
dispatch(setAutoInstallRelease(false));
|
||||||
|
|
||||||
if (result.Dependencies && (result.Dependencies.length > 0)) {
|
if (result.Dependencies && result.Dependencies.length > 0) {
|
||||||
dispatch(showWindow());
|
dispatch(showWindow());
|
||||||
} else if ((installedVersion === 'none') && autoInstallRelease) {
|
} else if (installedVersion === 'none' && autoInstallRelease) {
|
||||||
dispatch(setAllowMount(false));
|
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 urls = getState().relver.LocationsLookup[versionString].urls;
|
||||||
const fileName = versionString + '.zip';
|
const fileName = versionString + '.zip';
|
||||||
dispatch(downloadItem(fileName, Constants.INSTALL_TYPES.Release, urls));
|
dispatch(
|
||||||
|
downloadItem(fileName, Constants.INSTALL_TYPES.Release, urls)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -75,7 +81,10 @@ export const checkInstalled = (dependencies, version) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ipcRenderer.once(Constants.IPC_Check_Installed_Reply, checkInstalledComplete);
|
ipcRenderer.once(
|
||||||
|
Constants.IPC_Check_Installed_Reply,
|
||||||
|
checkInstalledComplete
|
||||||
|
);
|
||||||
ipcRenderer.send(Constants.IPC_Check_Installed, {
|
ipcRenderer.send(Constants.IPC_Check_Installed, {
|
||||||
Dependencies: dependencies,
|
Dependencies: dependencies,
|
||||||
Version: version,
|
Version: version,
|
||||||
@@ -89,10 +98,14 @@ export const checkVersionInstalled = () => {
|
|||||||
|
|
||||||
dispatch(setAllowDownload(false));
|
dispatch(setAllowDownload(false));
|
||||||
const selectedVersion = getSelectedVersionFromState(state);
|
const selectedVersion = getSelectedVersionFromState(state);
|
||||||
if (selectedVersion && (selectedVersion !== 'unavailable')) {
|
if (selectedVersion && selectedVersion !== 'unavailable') {
|
||||||
let dependencies = [];
|
let dependencies = [];
|
||||||
if (state.relver.LocationsLookup[selectedVersion] && state.relver.LocationsLookup[selectedVersion].dependencies) {
|
if (
|
||||||
dependencies = state.relver.LocationsLookup[selectedVersion].dependencies;
|
state.relver.LocationsLookup[selectedVersion] &&
|
||||||
|
state.relver.LocationsLookup[selectedVersion].dependencies
|
||||||
|
) {
|
||||||
|
dependencies =
|
||||||
|
state.relver.LocationsLookup[selectedVersion].dependencies;
|
||||||
}
|
}
|
||||||
dispatch(checkInstalled(dependencies, selectedVersion));
|
dispatch(checkInstalled(dependencies, selectedVersion));
|
||||||
} else {
|
} else {
|
||||||
@@ -107,9 +120,9 @@ export const installDependency = (source, url, isWinFSP) => {
|
|||||||
if (ipcRenderer && !getState().install.InstallActive) {
|
if (ipcRenderer && !getState().install.InstallActive) {
|
||||||
dispatch(setInstallActive(Constants.INSTALL_TYPES.Dependency));
|
dispatch(setInstallActive(Constants.INSTALL_TYPES.Dependency));
|
||||||
|
|
||||||
const installDependencyComplete = (event, arg) => {
|
const installDependencyComplete = (_, arg) => {
|
||||||
const result = arg.data;
|
const result = arg.data;
|
||||||
const handleCompleted = ()=> {
|
const handleCompleted = () => {
|
||||||
if (result.RebootRequired) {
|
if (result.RebootRequired) {
|
||||||
dispatch(setRebootRequired());
|
dispatch(setRebootRequired());
|
||||||
} else {
|
} else {
|
||||||
@@ -122,13 +135,16 @@ export const installDependency = (source, url, isWinFSP) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (result.Success && source.toLowerCase().endsWith('.dmg')) {
|
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;
|
return d.download === url;
|
||||||
});
|
});
|
||||||
const i = setInterval(()=> {
|
const i = setInterval(() => {
|
||||||
const ret = ipcRenderer.sendSync(Constants.IPC_Check_Dependency_Installed + '_sync', {
|
const ret = ipcRenderer.sendSync(
|
||||||
|
Constants.IPC_Check_Dependency_Installed + '_sync',
|
||||||
|
{
|
||||||
File: dep.file,
|
File: dep.file,
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
if (ret.data.Exists) {
|
if (ret.data.Exists) {
|
||||||
clearInterval(i);
|
clearInterval(i);
|
||||||
@@ -142,7 +158,10 @@ export const installDependency = (source, url, isWinFSP) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ipcRenderer.once(Constants.IPC_Install_Dependency_Reply, installDependencyComplete);
|
ipcRenderer.once(
|
||||||
|
Constants.IPC_Install_Dependency_Reply,
|
||||||
|
installDependencyComplete
|
||||||
|
);
|
||||||
ipcRenderer.send(Constants.IPC_Install_Dependency, {
|
ipcRenderer.send(Constants.IPC_Install_Dependency, {
|
||||||
Source: source,
|
Source: source,
|
||||||
URL: url,
|
URL: url,
|
||||||
@@ -160,7 +179,7 @@ export const installAndTestRelease = (source, version, appPlatform) => {
|
|||||||
FilePath: source,
|
FilePath: source,
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcRenderer.once(Constants.IPC_Test_Release_Reply, (event, arg) => {
|
ipcRenderer.once(Constants.IPC_Test_Release_Reply, (_, arg) => {
|
||||||
if (arg.data.Success) {
|
if (arg.data.Success) {
|
||||||
ipcRenderer.sendSync(Constants.IPC_Set_Linux_AppPlatform, {
|
ipcRenderer.sendSync(Constants.IPC_Set_Linux_AppPlatform, {
|
||||||
AppPlatform: appPlatform,
|
AppPlatform: appPlatform,
|
||||||
@@ -177,10 +196,13 @@ export const installAndTestRelease = (source, version, appPlatform) => {
|
|||||||
});
|
});
|
||||||
ipcRenderer.send(Constants.IPC_Test_Release, {
|
ipcRenderer.send(Constants.IPC_Test_Release, {
|
||||||
Version: version,
|
Version: version,
|
||||||
})
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
ipcRenderer.once(Constants.IPC_Extract_Release_Complete, extractReleaseComplete);
|
ipcRenderer.once(
|
||||||
|
Constants.IPC_Extract_Release_Complete,
|
||||||
|
extractReleaseComplete
|
||||||
|
);
|
||||||
ipcRenderer.send(Constants.IPC_Extract_Release, {
|
ipcRenderer.send(Constants.IPC_Extract_Release, {
|
||||||
Source: source,
|
Source: source,
|
||||||
Version: version,
|
Version: version,
|
||||||
@@ -192,7 +214,10 @@ export const installAndTestRelease = (source, version, appPlatform) => {
|
|||||||
export const installReleaseByVersion = (release, version) => {
|
export const installReleaseByVersion = (release, version) => {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
const install = () => {
|
const install = () => {
|
||||||
if (getState().download.AllowDownload && !getState().download.DownloadActive) {
|
if (
|
||||||
|
getState().download.AllowDownload &&
|
||||||
|
!getState().download.DownloadActive
|
||||||
|
) {
|
||||||
dispatch(setAutoInstallRelease(true));
|
dispatch(setAutoInstallRelease(true));
|
||||||
dispatch(setActiveRelease(release, version));
|
dispatch(setActiveRelease(release, version));
|
||||||
} else {
|
} else {
|
||||||
@@ -202,31 +227,34 @@ export const installReleaseByVersion = (release, version) => {
|
|||||||
|
|
||||||
if (getState().mounts.MountsBusy) {
|
if (getState().mounts.MountsBusy) {
|
||||||
dispatch(confirmYesNo('Unmount all drives?'))
|
dispatch(confirmYesNo('Unmount all drives?'))
|
||||||
.then(confirmed => {
|
.then((confirmed) => {
|
||||||
if (confirmed) {
|
if (confirmed) {
|
||||||
dispatch(unmountAll(install));
|
dispatch(unmountAll(install));
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(error => notifyError(error));
|
.catch((error) => notifyError(error));
|
||||||
} else {
|
} else {
|
||||||
install();
|
install();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const installRelease = source => {
|
export const installRelease = (source) => {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
if (ipcRenderer && !getState().install.InstallActive) {
|
if (ipcRenderer && !getState().install.InstallActive) {
|
||||||
dispatch(setInstallActive(Constants.INSTALL_TYPES.Release));
|
dispatch(setInstallActive(Constants.INSTALL_TYPES.Release));
|
||||||
|
|
||||||
const version = getSelectedVersionFromState(getState());
|
const version = getSelectedVersionFromState(getState());
|
||||||
const extractReleaseComplete = (event, arg) => {
|
const extractReleaseComplete = (_, arg) => {
|
||||||
ipcRenderer.send(Constants.IPC_Delete_File, {
|
ipcRenderer.send(Constants.IPC_Delete_File, {
|
||||||
FilePath: source,
|
FilePath: source,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (arg.data.Success) {
|
if (arg.data.Success) {
|
||||||
localStorage.setItem('previous_releases', localStorage.getItem('releases'));
|
localStorage.setItem(
|
||||||
|
'previous_releases',
|
||||||
|
localStorage.getItem('releases')
|
||||||
|
);
|
||||||
dispatch(setNewReleasesAvailable2([]));
|
dispatch(setNewReleasesAvailable2([]));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,7 +262,10 @@ export const installRelease = source => {
|
|||||||
dispatch(checkVersionInstalled());
|
dispatch(checkVersionInstalled());
|
||||||
};
|
};
|
||||||
|
|
||||||
ipcRenderer.once(Constants.IPC_Extract_Release_Complete, extractReleaseComplete);
|
ipcRenderer.once(
|
||||||
|
Constants.IPC_Extract_Release_Complete,
|
||||||
|
extractReleaseComplete
|
||||||
|
);
|
||||||
ipcRenderer.send(Constants.IPC_Extract_Release, {
|
ipcRenderer.send(Constants.IPC_Extract_Release, {
|
||||||
Source: source,
|
Source: source,
|
||||||
Version: version,
|
Version: version,
|
||||||
@@ -249,23 +280,33 @@ export const installUpgrade = (source, sha256, signature, skipVerification) => {
|
|||||||
dispatch(setInstallActive(Constants.INSTALL_TYPES.Upgrade));
|
dispatch(setInstallActive(Constants.INSTALL_TYPES.Upgrade));
|
||||||
dispatch(setApplicationReady(false));
|
dispatch(setApplicationReady(false));
|
||||||
|
|
||||||
const installUpgradeComplete = (event, arg) => {
|
const installUpgradeComplete = (_, arg) => {
|
||||||
const result = arg.data;
|
const result = arg.data;
|
||||||
if (result.Success) {
|
if (result.Success) {
|
||||||
dispatch(shutdownApplication());
|
dispatch(shutdownApplication());
|
||||||
} else {
|
} else {
|
||||||
dispatch(setApplicationReady(true));
|
dispatch(setApplicationReady(true));
|
||||||
dispatch(setInstallComplete(result));
|
dispatch(setInstallComplete(result));
|
||||||
dispatch(notifyError(result.Error, false, () => {
|
dispatch(
|
||||||
|
notifyError(
|
||||||
|
result.Error,
|
||||||
|
false,
|
||||||
|
() => {
|
||||||
// TODO Prompt to verify
|
// TODO Prompt to verify
|
||||||
if (result.AllowSkipVerification) {
|
if (result.AllowSkipVerification) {
|
||||||
dispatch(installUpgrade(source, sha256, signature, true));
|
dispatch(installUpgrade(source, sha256, signature, true));
|
||||||
}
|
}
|
||||||
}, false));
|
},
|
||||||
|
false
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ipcRenderer.once(Constants.IPC_Install_Upgrade_Reply, installUpgradeComplete);
|
ipcRenderer.once(
|
||||||
|
Constants.IPC_Install_Upgrade_Reply,
|
||||||
|
installUpgradeComplete
|
||||||
|
);
|
||||||
ipcRenderer.send(Constants.IPC_Install_Upgrade, {
|
ipcRenderer.send(Constants.IPC_Install_Upgrade, {
|
||||||
Sha256: sha256,
|
Sha256: sha256,
|
||||||
Signature: signature,
|
Signature: signature,
|
||||||
@@ -276,9 +317,17 @@ export const installUpgrade = (source, sha256, signature, skipVerification) => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const setAutoInstallRelease = createAction('install/setAutoInstallRelease');
|
export const setAutoInstallRelease = createAction(
|
||||||
export const setDismissDependencies = createAction('install/setDismissDependencies');
|
'install/setAutoInstallRelease'
|
||||||
|
);
|
||||||
|
export const setDismissDependencies = createAction(
|
||||||
|
'install/setDismissDependencies'
|
||||||
|
);
|
||||||
export const setInstallActive = createAction('install/setInstallActive');
|
export const setInstallActive = createAction('install/setInstallActive');
|
||||||
export const setInstallTestActive = createAction('install/setInstallTestActive');
|
export const setInstallTestActive = createAction(
|
||||||
|
'install/setInstallTestActive'
|
||||||
|
);
|
||||||
export const setInstallComplete = createAction('install/setInstallComplete');
|
export const setInstallComplete = createAction('install/setInstallComplete');
|
||||||
export const setMissingDependencies = createAction('install/setMissingDependencies');
|
export const setMissingDependencies = createAction(
|
||||||
|
'install/setMissingDependencies'
|
||||||
|
);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import {createAction} from '@reduxjs/toolkit';
|
import {createAction} from '@reduxjs/toolkit';
|
||||||
|
|
||||||
import * as Constants from '../../constants';
|
import * as Constants from '../../constants';
|
||||||
import {getIPCRenderer} from '../../utils';
|
import {getIPCRenderer} from '../../utils.jsx';
|
||||||
|
|
||||||
import {confirmYesNo, saveState} from './common_actions';
|
import {confirmYesNo, saveState} from './common_actions';
|
||||||
import {notifyError} from './error_actions';
|
import {notifyError} from './error_actions';
|
||||||
@@ -23,8 +23,10 @@ export const addRemoteMount = (hostNameOrIp, port, token) => {
|
|||||||
Version: getState().relver.InstalledVersion,
|
Version: getState().relver.InstalledVersion,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
dispatch(
|
dispatch(noti
|
||||||
notifyError('Failed to set \'RemoteToken\': ' + arg.data.Error));
|
'Failed to set \'RemoteToken\': '
|
||||||
|
oken
|
||||||
|
': " + arg.data.Error));
|
||||||
dispatch(setBusy(false));
|
dispatch(setBusy(false));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -43,7 +45,14 @@ export const addRemoteMount = (hostNameOrIp, port, token) => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const addS3Mount = (name, accessKey, secretKey, region, bucketName, url) => {
|
export const addS3Mount = (
|
||||||
|
name,
|
||||||
|
accessKey,
|
||||||
|
secretKey,
|
||||||
|
region,
|
||||||
|
bucketName,
|
||||||
|
url
|
||||||
|
) => {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
const ipcRenderer = getIPCRenderer();
|
const ipcRenderer = getIPCRenderer();
|
||||||
const provider = 'S3' + name;
|
const provider = 'S3' + name;
|
||||||
@@ -60,7 +69,8 @@ export const addS3Mount = (name, accessKey, secretKey, region, bucketName, url)
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
dispatch(
|
dispatch(
|
||||||
notifyError('Failed to create S3 instance: ' + arg.data.Error));
|
notifyError('Failed to create S3 instance: ' + arg.data.Error)
|
||||||
|
);
|
||||||
dispatch(setBusy(false));
|
dispatch(setBusy(false));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -95,11 +105,12 @@ export const displayConfiguration = (provider, remote, s3) => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const removeMount = provider => {
|
export const removeMount = (provider) => {
|
||||||
return dispatch => {
|
return (dispatch) => {
|
||||||
const isRemote = provider.startsWith('Remote');
|
const isRemote = provider.startsWith('Remote');
|
||||||
dispatch(confirmYesNo('Delete [' + provider.substr(isRemote ? 6 : 2) + ']?'))
|
dispatch(
|
||||||
.then(confirmed => {
|
confirmYesNo('Delete [' + provider.substr(isRemote ? 6 : 2) + ']?')
|
||||||
|
).then((confirmed) => {
|
||||||
if (confirmed) {
|
if (confirmed) {
|
||||||
dispatch(removeMount2(provider));
|
dispatch(removeMount2(provider));
|
||||||
}
|
}
|
||||||
@@ -107,8 +118,8 @@ export const removeMount = provider => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const removeMount2 = provider => {
|
const removeMount2 = (provider) => {
|
||||||
return dispatch => {
|
return (dispatch) => {
|
||||||
const ipcRenderer = getIPCRenderer();
|
const ipcRenderer = getIPCRenderer();
|
||||||
ipcRenderer.once(Constants.IPC_Remove_Mount_Reply, (_, arg) => {
|
ipcRenderer.once(Constants.IPC_Remove_Mount_Reply, (_, arg) => {
|
||||||
if (arg.data.Success) {
|
if (arg.data.Success) {
|
||||||
@@ -119,7 +130,7 @@ const removeMount2 = provider => {
|
|||||||
const isRemote = provider.startsWith('Remote');
|
const isRemote = provider.startsWith('Remote');
|
||||||
ipcRenderer.send(Constants.IPC_Remove_Mount, {
|
ipcRenderer.send(Constants.IPC_Remove_Mount, {
|
||||||
Remote: isRemote,
|
Remote: isRemote,
|
||||||
Name: provider.substr(isRemote ? 6 : 2)
|
Name: provider.substr(isRemote ? 6 : 2),
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -128,15 +139,13 @@ export const removeMount3 = createAction('mounts/removeMount3');
|
|||||||
|
|
||||||
export const RESET_MOUNTS_STATE = 'mounts/resetMountsState';
|
export const RESET_MOUNTS_STATE = 'mounts/resetMountsState';
|
||||||
export const 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 SET_ALLOW_MOUNT = 'mounts/setAllowMount';
|
||||||
export const setAllowMount =
|
export const setAllowMount = (provider, allow) => {
|
||||||
(provider,
|
|
||||||
allow) => {
|
|
||||||
return {type: SET_ALLOW_MOUNT, payload: {provider, allow}};
|
return {type: SET_ALLOW_MOUNT, payload: {provider, allow}};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SET_AUTO_MOUNT_PROCESSED = 'mounts/setAutoMountProcessed';
|
export const SET_AUTO_MOUNT_PROCESSED = 'mounts/setAutoMountProcessed';
|
||||||
export const setAutoMountProcessed = (provider, processed) => {
|
export const setAutoMountProcessed = (provider, processed) => {
|
||||||
@@ -146,26 +155,22 @@ export const setAutoMountProcessed = (provider, processed) => {
|
|||||||
export const setBusy = createAction('mounts/setBusy');
|
export const setBusy = createAction('mounts/setBusy');
|
||||||
|
|
||||||
export const SET_MOUNT_STATE = 'mounts/setMountState';
|
export const SET_MOUNT_STATE = 'mounts/setMountState';
|
||||||
export const setMountState =
|
export const setMountState = (provider, state) => {
|
||||||
(provider,
|
|
||||||
state) => {
|
|
||||||
return {type: SET_MOUNT_STATE, payload: {provider, state}};
|
return {type: SET_MOUNT_STATE, payload: {provider, state}};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SET_MOUNTED = 'mounts/setMounted';
|
export const SET_MOUNTED = 'mounts/setMounted';
|
||||||
export const setMounted =
|
export const setMounted = (provider, mounted) => {
|
||||||
(provider,
|
|
||||||
mounted) => {
|
|
||||||
return {type: SET_MOUNTED, payload: {provider, mounted}};
|
return {type: SET_MOUNTED, payload: {provider, mounted}};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SET_PROVIDER_STATE = 'mounts/setProviderState';
|
export const SET_PROVIDER_STATE = 'mounts/setProviderState';
|
||||||
export const setProviderState = (provider, state) => {
|
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 => {
|
export const unmountAll = (completedCallback) => {
|
||||||
return dispatch => {
|
return (dispatch) => {
|
||||||
const ipcRenderer = getIPCRenderer();
|
const ipcRenderer = getIPCRenderer();
|
||||||
const unmountedCallback = () => {
|
const unmountedCallback = () => {
|
||||||
dispatch(resetMountsState());
|
dispatch(resetMountsState());
|
||||||
@@ -173,5 +178,5 @@ export const unmountAll = completedCallback => {
|
|||||||
};
|
};
|
||||||
ipcRenderer.once(Constants.IPC_Unmount_All_Drives_Reply, unmountedCallback);
|
ipcRenderer.once(Constants.IPC_Unmount_All_Drives_Reply, unmountedCallback);
|
||||||
ipcRenderer.send(Constants.IPC_Unmount_All_Drives);
|
ipcRenderer.send(Constants.IPC_Unmount_All_Drives);
|
||||||
}
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import {createAction} from '@reduxjs/toolkit';
|
import { createAction } from '@reduxjs/toolkit';
|
||||||
|
|
||||||
export const displayPinnedManager = createAction('pinned/displayPinnedManager');
|
export const displayPinnedManager = createAction('pinned/displayPinnedManager');
|
||||||
|
|
||||||
|
|||||||
@@ -1,23 +1,26 @@
|
|||||||
|
import { createAction } from '@reduxjs/toolkit';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
|
||||||
import * as Constants from '../../constants';
|
import * as Constants from '../../constants';
|
||||||
import {createAction} from '@reduxjs/toolkit';
|
import {
|
||||||
import {notifyError} from './error_actions';
|
checkNewReleases,
|
||||||
|
getIPCRenderer,
|
||||||
|
getNewReleases,
|
||||||
|
getSelectedVersionFromState,
|
||||||
|
} from '../../utils.jsx';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
saveState,
|
saveState,
|
||||||
setAllowMount,
|
setAllowMount,
|
||||||
setApplicationReady,
|
setApplicationReady,
|
||||||
showWindow
|
showWindow,
|
||||||
} from './common_actions';
|
} from './common_actions';
|
||||||
|
import { notifyError } from './error_actions';
|
||||||
import {
|
import {
|
||||||
checkVersionInstalled,
|
checkVersionInstalled,
|
||||||
setDismissDependencies
|
setDismissDependencies,
|
||||||
} from './install_actions';
|
} from './install_actions';
|
||||||
import {unmountAll} from './mount_actions';
|
import { unmountAll } from './mount_actions';
|
||||||
import {
|
|
||||||
checkNewReleases,
|
|
||||||
getIPCRenderer,
|
|
||||||
getNewReleases, getSelectedVersionFromState
|
|
||||||
} from '../../utils';
|
|
||||||
|
|
||||||
export const CLEAR_UI_UPGRADE = 'relver/clearUIUpgrade';
|
export const CLEAR_UI_UPGRADE = 'relver/clearUIUpgrade';
|
||||||
export const clearUIUpgrade = () => {
|
export const clearUIUpgrade = () => {
|
||||||
@@ -27,12 +30,12 @@ export const clearUIUpgrade = () => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const cleanupOldReleases = versionList => {
|
const cleanupOldReleases = (versionList) => {
|
||||||
return dispatch => {
|
return (_) => {
|
||||||
const ipcRenderer = getIPCRenderer();
|
const ipcRenderer = getIPCRenderer();
|
||||||
if (ipcRenderer) {
|
if (ipcRenderer) {
|
||||||
ipcRenderer.sendSync(Constants.IPC_Cleanup_Releases + '_sync', {
|
ipcRenderer.sendSync(Constants.IPC_Cleanup_Releases + '_sync', {
|
||||||
version_list: versionList
|
version_list: versionList,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -42,24 +45,32 @@ export const detectUIUpgrade = () => {
|
|||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
axios
|
axios
|
||||||
.get(Constants.UI_RELEASES_URL)
|
.get(Constants.UI_RELEASES_URL)
|
||||||
.then(response => {
|
.then((response) => {
|
||||||
const state = getState();
|
const state = getState();
|
||||||
const appPlatform = state.common.AppPlatform;
|
const appPlatform = state.common.AppPlatform;
|
||||||
const version = state.common.Version;
|
const version = state.common.Version;
|
||||||
const data = response.data;
|
const data = response.data;
|
||||||
|
|
||||||
if (data.Versions &&
|
if (
|
||||||
|
data.Versions &&
|
||||||
data.Versions[appPlatform] &&
|
data.Versions[appPlatform] &&
|
||||||
(data.Versions[appPlatform].length > 0) &&
|
data.Versions[appPlatform].length > 0 &&
|
||||||
(data.Versions[appPlatform][0] !== version)) {
|
data.Versions[appPlatform][0] !== version
|
||||||
dispatch(setUIUpgradeData(data.Locations[appPlatform][data.Versions[appPlatform][0]], data.Versions[appPlatform][0]));
|
) {
|
||||||
|
dispatch(
|
||||||
|
setUIUpgradeData(
|
||||||
|
data.Locations[appPlatform][data.Versions[appPlatform][0]],
|
||||||
|
data.Versions[appPlatform][0]
|
||||||
|
)
|
||||||
|
);
|
||||||
if (!state.relver.UpgradeDismissed) {
|
if (!state.relver.UpgradeDismissed) {
|
||||||
dispatch(showWindow());
|
dispatch(showWindow());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
dispatch(clearUIUpgrade());
|
dispatch(clearUIUpgrade());
|
||||||
}
|
}
|
||||||
}).catch(() => {
|
})
|
||||||
|
.catch(() => {
|
||||||
dispatch(clearUIUpgrade());
|
dispatch(clearUIUpgrade());
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -67,30 +78,41 @@ export const detectUIUpgrade = () => {
|
|||||||
|
|
||||||
export const loadReleases = () => {
|
export const loadReleases = () => {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
const dispatchActions = (locationsLookup, versionLookup)=> {
|
const dispatchActions = (locationsLookup, versionLookup) => {
|
||||||
const state = getState().relver;
|
const state = getState().relver;
|
||||||
let release = state.Release;
|
let release = state.Release;
|
||||||
if (release >= Constants.RELEASE_TYPES.length) {
|
if (release >= Constants.RELEASE_TYPES.length) {
|
||||||
release = Constants.DEFAULT_RELEASE;
|
release = Constants.DEFAULT_RELEASE;
|
||||||
}
|
}
|
||||||
|
|
||||||
let latestVersion = versionLookup[Constants.RELEASE_TYPES[release]].length - 1;
|
let latestVersion =
|
||||||
|
versionLookup[Constants.RELEASE_TYPES[release]].length - 1;
|
||||||
let version = state.Version;
|
let version = state.Version;
|
||||||
if (versionLookup[Constants.RELEASE_TYPES[release]][0] === 'unavailable') {
|
if (
|
||||||
|
versionLookup[Constants.RELEASE_TYPES[release]][0] === 'unavailable'
|
||||||
|
) {
|
||||||
release = Constants.DEFAULT_RELEASE;
|
release = Constants.DEFAULT_RELEASE;
|
||||||
version = latestVersion = versionLookup[Constants.RELEASE_TYPES[release]].length - 1
|
version = latestVersion =
|
||||||
} else if ((version === -1) || !versionLookup[Constants.RELEASE_TYPES[release]][version]) {
|
versionLookup[Constants.RELEASE_TYPES[release]].length - 1;
|
||||||
|
} else if (
|
||||||
|
version === -1 ||
|
||||||
|
!versionLookup[Constants.RELEASE_TYPES[release]][version]
|
||||||
|
) {
|
||||||
version = latestVersion;
|
version = latestVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
dispatch(setReleaseData(locationsLookup, versionLookup));
|
dispatch(setReleaseData(locationsLookup, versionLookup));
|
||||||
|
|
||||||
const dispatchActions = (processAllowDismiss = true) => {
|
const dispatchActions = (processAllowDismiss = true) => {
|
||||||
dispatch(setReleaseUpgradeAvailable((version !== latestVersion)));
|
dispatch(setReleaseUpgradeAvailable(version !== latestVersion));
|
||||||
dispatch(setApplicationReady(true));
|
dispatch(setApplicationReady(true));
|
||||||
dispatch(detectUIUpgrade());
|
dispatch(detectUIUpgrade());
|
||||||
if (processAllowDismiss) {
|
if (processAllowDismiss) {
|
||||||
dispatch(setAllowDismissDependencies(versionLookup[Constants.RELEASE_TYPES[release]].length > 1));
|
dispatch(
|
||||||
|
setAllowDismissDependencies(
|
||||||
|
versionLookup[Constants.RELEASE_TYPES[release]].length > 1
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
dispatch(checkVersionInstalled());
|
dispatch(checkVersionInstalled());
|
||||||
|
|
||||||
@@ -98,16 +120,18 @@ export const loadReleases = () => {
|
|||||||
for (const key of Object.keys(locationsLookup)) {
|
for (const key of Object.keys(locationsLookup)) {
|
||||||
versionList.push(key);
|
versionList.push(key);
|
||||||
}
|
}
|
||||||
dispatch(cleanupOldReleases(versionList))
|
dispatch(cleanupOldReleases(versionList));
|
||||||
};
|
};
|
||||||
|
|
||||||
if ((version !== state.Version) || (release !== state.Release)) {
|
if (version !== state.Version || release !== state.Release) {
|
||||||
dispatch(unmountAll(() => {
|
dispatch(
|
||||||
|
unmountAll(() => {
|
||||||
dispatch(setActiveRelease(release, version));
|
dispatch(setActiveRelease(release, version));
|
||||||
dispatchActions(false);
|
dispatchActions(false);
|
||||||
dispatch(showWindow());
|
dispatch(showWindow());
|
||||||
dispatch(saveState());
|
dispatch(saveState());
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
dispatchActions();
|
dispatchActions();
|
||||||
}
|
}
|
||||||
@@ -115,7 +139,7 @@ export const loadReleases = () => {
|
|||||||
|
|
||||||
axios
|
axios
|
||||||
.get(Constants.RELEASES_URL)
|
.get(Constants.RELEASES_URL)
|
||||||
.then(response => {
|
.then((response) => {
|
||||||
const appPlatform = getState().common.AppPlatform;
|
const appPlatform = getState().common.AppPlatform;
|
||||||
const versionLookup = {
|
const versionLookup = {
|
||||||
Release: response.data.Versions.Release[appPlatform],
|
Release: response.data.Versions.Release[appPlatform],
|
||||||
@@ -129,14 +153,21 @@ export const loadReleases = () => {
|
|||||||
|
|
||||||
const storedReleases = localStorage.getItem('releases');
|
const storedReleases = localStorage.getItem('releases');
|
||||||
let newReleases = [];
|
let newReleases = [];
|
||||||
if (storedReleases && (storedReleases.length > 0)) {
|
if (storedReleases && storedReleases.length > 0) {
|
||||||
newReleases = getNewReleases(JSON.parse(storedReleases).VersionLookup, versionLookup, getSelectedVersionFromState(getState()));
|
newReleases = getNewReleases(
|
||||||
|
JSON.parse(storedReleases).VersionLookup,
|
||||||
|
versionLookup,
|
||||||
|
getSelectedVersionFromState(getState())
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
localStorage.setItem('releases', JSON.stringify({
|
localStorage.setItem(
|
||||||
|
'releases',
|
||||||
|
JSON.stringify({
|
||||||
LocationsLookup: locationsLookup,
|
LocationsLookup: locationsLookup,
|
||||||
VersionLookup: versionLookup
|
VersionLookup: versionLookup,
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
dispatchActions(locationsLookup, versionLookup);
|
dispatchActions(locationsLookup, versionLookup);
|
||||||
|
|
||||||
dispatch(setNewReleasesAvailable(newReleases));
|
dispatch(setNewReleasesAvailable(newReleases));
|
||||||
@@ -144,12 +175,17 @@ export const loadReleases = () => {
|
|||||||
dispatch(setNewReleasesAvailable2(newReleases));
|
dispatch(setNewReleasesAvailable2(newReleases));
|
||||||
localStorage.setItem('previous_releases', storedReleases);
|
localStorage.setItem('previous_releases', storedReleases);
|
||||||
dispatch(showWindow());
|
dispatch(showWindow());
|
||||||
} else if ((newReleases = checkNewReleases(getSelectedVersionFromState(getState()))).length > 0) {
|
} else if (
|
||||||
|
(newReleases = checkNewReleases(
|
||||||
|
getSelectedVersionFromState(getState())
|
||||||
|
)).length > 0
|
||||||
|
) {
|
||||||
dispatch(setNewReleasesAvailable2(newReleases));
|
dispatch(setNewReleasesAvailable2(newReleases));
|
||||||
}
|
}
|
||||||
}).catch(error => {
|
})
|
||||||
|
.catch((error) => {
|
||||||
const releases = localStorage.getItem('releases');
|
const releases = localStorage.getItem('releases');
|
||||||
if (releases && (releases.length > 0)) {
|
if (releases && releases.length > 0) {
|
||||||
const obj = JSON.parse(releases);
|
const obj = JSON.parse(releases);
|
||||||
const locationsLookup = obj.LocationsLookup;
|
const locationsLookup = obj.LocationsLookup;
|
||||||
const versionLookup = obj.VersionLookup;
|
const versionLookup = obj.VersionLookup;
|
||||||
@@ -166,10 +202,7 @@ export const NOTIFY_ACTIVE_RELEASE = 'relver/notifyActiveRelease';
|
|||||||
export const notifyActiveRelease = (release, version) => {
|
export const notifyActiveRelease = (release, version) => {
|
||||||
return {
|
return {
|
||||||
type: NOTIFY_ACTIVE_RELEASE,
|
type: NOTIFY_ACTIVE_RELEASE,
|
||||||
payload: {
|
payload: { release: release, version: version },
|
||||||
release: release,
|
|
||||||
version: version
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -183,7 +216,7 @@ export const setActiveRelease = (release, version) => {
|
|||||||
version = -1;
|
version = -1;
|
||||||
}
|
}
|
||||||
const versions = relver.VersionLookup[Constants.RELEASE_TYPES[release]];
|
const versions = relver.VersionLookup[Constants.RELEASE_TYPES[release]];
|
||||||
dispatch(setAllowDismissDependencies(versions && (versions.length > 1)));
|
dispatch(setAllowDismissDependencies(versions && versions.length > 1));
|
||||||
dispatch(setDismissDependencies(false));
|
dispatch(setDismissDependencies(false));
|
||||||
dispatch(notifyActiveRelease(release, version));
|
dispatch(notifyActiveRelease(release, version));
|
||||||
if (common.AppReady) {
|
if (common.AppReady) {
|
||||||
@@ -192,25 +225,35 @@ export const setActiveRelease = (release, version) => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const setAllowDismissDependencies = createAction('relver/setAllowDismissDependencies');
|
export const setAllowDismissDependencies = createAction(
|
||||||
export const setDismissNewReleasesAvailable = createAction('relver/setDismissNewReleasesAvailable');
|
'relver/setAllowDismissDependencies'
|
||||||
|
);
|
||||||
|
export const setDismissNewReleasesAvailable = createAction(
|
||||||
|
'relver/setDismissNewReleasesAvailable'
|
||||||
|
);
|
||||||
export const setDismissUIUpgrade = createAction('relver/setDismissUIUpgrade');
|
export const setDismissUIUpgrade = createAction('relver/setDismissUIUpgrade');
|
||||||
export const setInstalledVersion = createAction('relver/setInstalledVersion');
|
export const setInstalledVersion = createAction('relver/setInstalledVersion');
|
||||||
export const setNewReleasesAvailable = createAction('relver/setNewReleasesAvailable');
|
export const setNewReleasesAvailable = createAction(
|
||||||
export const setNewReleasesAvailable2 = createAction('relver/setNewReleasesAvailable2');
|
'relver/setNewReleasesAvailable'
|
||||||
|
);
|
||||||
|
export const setNewReleasesAvailable2 = createAction(
|
||||||
|
'relver/setNewReleasesAvailable2'
|
||||||
|
);
|
||||||
|
|
||||||
export const SET_RELEASE_DATA = 'relver/setReleaseData';
|
export const SET_RELEASE_DATA = 'relver/setReleaseData';
|
||||||
export const setReleaseData = (locationsLookup, versionLookup)=> {
|
export const setReleaseData = (locationsLookup, versionLookup) => {
|
||||||
return {
|
return {
|
||||||
type: SET_RELEASE_DATA,
|
type: SET_RELEASE_DATA,
|
||||||
payload: {
|
payload: {
|
||||||
locations: locationsLookup,
|
locations: locationsLookup,
|
||||||
versions: versionLookup,
|
versions: versionLookup,
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const setReleaseUpgradeAvailable = createAction('relver/setReleaseUpgradeAvailable');
|
export const setReleaseUpgradeAvailable = createAction(
|
||||||
|
'relver/setReleaseUpgradeAvailable'
|
||||||
|
);
|
||||||
|
|
||||||
export const SET_UI_UPGRADE_DATA = 'relver/setUIUpgradeData';
|
export const SET_UI_UPGRADE_DATA = 'relver/setUIUpgradeData';
|
||||||
export const setUIUpgradeData = (upgradeData, version) => {
|
export const setUIUpgradeData = (upgradeData, version) => {
|
||||||
@@ -219,6 +262,6 @@ export const setUIUpgradeData = (upgradeData, version) => {
|
|||||||
payload: {
|
payload: {
|
||||||
upgrade_data: upgradeData,
|
upgrade_data: upgradeData,
|
||||||
version: version,
|
version: version,
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import {createAction} from '@reduxjs/toolkit';
|
import { createAction } from '@reduxjs/toolkit';
|
||||||
|
|
||||||
export const displaySkynetExport = createAction('skynet/displaySkynetExport');
|
export const displaySkynetExport = createAction('skynet/displaySkynetExport');
|
||||||
export const displaySkynetImport = createAction('skynet/displaySkynetImport');
|
export const displaySkynetImport = createAction('skynet/displaySkynetImport');
|
||||||
|
|||||||
@@ -1,16 +1,18 @@
|
|||||||
import {createReducer} from '@reduxjs/toolkit';
|
import { createReducer } from '@reduxjs/toolkit';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
DISPLAY_CONFIRM_YES_NO,
|
DISPLAY_CONFIRM_YES_NO,
|
||||||
NOTIFY_APPLICATION_BUSY,
|
NOTIFY_APPLICATION_BUSY,
|
||||||
notifyRebootRequired,
|
notifyRebootRequired,
|
||||||
|
SET_DISPLAY_SELECT_APPPLATFORM,
|
||||||
setAllowMount,
|
setAllowMount,
|
||||||
setApplicationReady,
|
setApplicationReady,
|
||||||
setLinuxAppPlatform,
|
setLinuxAppPlatform,
|
||||||
SET_DISPLAY_SELECT_APPPLATFORM
|
|
||||||
} from '../actions/common_actions';
|
} from '../actions/common_actions';
|
||||||
|
|
||||||
export const createCommonReducer = (platformInfo, version) => {
|
export const createCommonReducer = (platformInfo, version) => {
|
||||||
return createReducer({
|
return createReducer(
|
||||||
|
{
|
||||||
AllowMount: false,
|
AllowMount: false,
|
||||||
AppBusy: false,
|
AppBusy: false,
|
||||||
AppBusyTransparent: false,
|
AppBusyTransparent: false,
|
||||||
@@ -22,25 +24,20 @@ export const createCommonReducer = (platformInfo, version) => {
|
|||||||
Platform: platformInfo.Platform,
|
Platform: platformInfo.Platform,
|
||||||
RebootRequired: false,
|
RebootRequired: false,
|
||||||
Version: version,
|
Version: version,
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
[DISPLAY_CONFIRM_YES_NO]: (state, action) => {
|
[DISPLAY_CONFIRM_YES_NO]: (state, action) => {
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
DisplayConfirmYesNo: action.payload.show,
|
DisplayConfirmYesNo: action.payload.show,
|
||||||
ConfirmTitle: action.payload.show ? action.payload.title : null,
|
ConfirmTitle: action.payload.show ? action.payload.title : null,
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
[SET_DISPLAY_SELECT_APPPLATFORM]: (state, action) => {
|
[SET_DISPLAY_SELECT_APPPLATFORM]: (state, action) => {
|
||||||
return {
|
return { ...state, DisplaySelectAppPlatform: action.payload };
|
||||||
...state,
|
|
||||||
DisplaySelectAppPlatform: action.payload,
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
[setAllowMount]: (state, action) => {
|
[setAllowMount]: (state, action) => {
|
||||||
return {
|
return { ...state, AllowMount: action.payload };
|
||||||
...state,
|
|
||||||
AllowMount: action.payload,
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
[setApplicationReady]: (state, action) => {
|
[setApplicationReady]: (state, action) => {
|
||||||
return {
|
return {
|
||||||
@@ -49,10 +46,7 @@ export const createCommonReducer = (platformInfo, version) => {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
[setLinuxAppPlatform]: (state, action) => {
|
[setLinuxAppPlatform]: (state, action) => {
|
||||||
return {
|
return { ...state, AppPlatform: action.payload };
|
||||||
...state,
|
|
||||||
AppPlatform: action.payload,
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
[NOTIFY_APPLICATION_BUSY]: (state, action) => {
|
[NOTIFY_APPLICATION_BUSY]: (state, action) => {
|
||||||
return {
|
return {
|
||||||
@@ -67,5 +61,6 @@ export const createCommonReducer = (platformInfo, version) => {
|
|||||||
RebootRequired: action.payload,
|
RebootRequired: action.payload,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
}
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import {createReducer} from '@reduxjs/toolkit';
|
import { createReducer } from '@reduxjs/toolkit';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
setAllowDownload,
|
|
||||||
SET_DOWNLOAD_BEGIN,
|
SET_DOWNLOAD_BEGIN,
|
||||||
|
setAllowDownload,
|
||||||
setDownloadEnd,
|
setDownloadEnd,
|
||||||
setDownloadProgress
|
setDownloadProgress,
|
||||||
} from '../actions/download_actions';
|
} from '../actions/download_actions';
|
||||||
|
|
||||||
const defaultDownloadState = {
|
const defaultDownloadState = {
|
||||||
@@ -17,10 +18,12 @@ const defaultDownloadState = {
|
|||||||
DownloadType: null,
|
DownloadType: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const downloadReducer = createReducer({
|
export const downloadReducer = createReducer(
|
||||||
|
{
|
||||||
...defaultDownloadState,
|
...defaultDownloadState,
|
||||||
AllowDownload: false,
|
AllowDownload: false,
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
[setAllowDownload]: (state, action) => {
|
[setAllowDownload]: (state, action) => {
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
@@ -35,7 +38,7 @@ export const downloadReducer = createReducer({
|
|||||||
DownloadName: action.payload.name,
|
DownloadName: action.payload.name,
|
||||||
DownloadType: action.payload.type,
|
DownloadType: action.payload.type,
|
||||||
DownloadURL: action.payload.url,
|
DownloadURL: action.payload.url,
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
[setDownloadEnd]: (state, action) => {
|
[setDownloadEnd]: (state, action) => {
|
||||||
return {
|
return {
|
||||||
@@ -45,9 +48,7 @@ export const downloadReducer = createReducer({
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
[setDownloadProgress]: (state, action) => {
|
[setDownloadProgress]: (state, action) => {
|
||||||
return {
|
return { ...state, DownloadProgress: action.payload };
|
||||||
...state,
|
},
|
||||||
DownloadProgress: action.payload,
|
|
||||||
}
|
}
|
||||||
}
|
);
|
||||||
});
|
|
||||||
|
|||||||
@@ -1,33 +1,37 @@
|
|||||||
import {createReducer} from '@reduxjs/toolkit';
|
import { createReducer } from '@reduxjs/toolkit';
|
||||||
import {
|
import {
|
||||||
CLEAR_ERROR,
|
CLEAR_ERROR,
|
||||||
CLEAR_INFO,
|
CLEAR_INFO,
|
||||||
SET_ERROR_INFO,
|
SET_ERROR_INFO,
|
||||||
SET_INFO
|
SET_INFO,
|
||||||
} from '../actions/error_actions';
|
} from '../actions/error_actions';
|
||||||
|
|
||||||
export const errorReducer = createReducer({
|
export const errorReducer = createReducer(
|
||||||
|
{
|
||||||
DisplayError: false,
|
DisplayError: false,
|
||||||
DisplayInfo: false,
|
DisplayInfo: false,
|
||||||
ErrorCritical: false,
|
ErrorCritical: false,
|
||||||
ErrorStack: [],
|
ErrorStack: [],
|
||||||
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) : [];
|
[CLEAR_ERROR]: (state) => {
|
||||||
|
const errorStack =
|
||||||
|
state.ErrorStack.length > 0 ? state.ErrorStack.slice(1) : [];
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
DisplayInfo: (infoStack.length > 0),
|
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,
|
InfoStack: infoStack,
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
[SET_ERROR_INFO]: (state, action) => {
|
[SET_ERROR_INFO]: (state, action) => {
|
||||||
const errorStack = [action.payload.msg, ...state.ErrorStack];
|
const errorStack = [action.payload.msg, ...state.ErrorStack];
|
||||||
@@ -36,17 +40,14 @@ export const errorReducer = createReducer({
|
|||||||
DisplayError: true,
|
DisplayError: true,
|
||||||
ErrorCritical: state.ErrorCritical || action.payload.critical,
|
ErrorCritical: state.ErrorCritical || action.payload.critical,
|
||||||
ErrorStack: errorStack,
|
ErrorStack: errorStack,
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
[SET_INFO]: (state, action) => {
|
[SET_INFO]: (state, action) => {
|
||||||
const infoStack = [{
|
const infoStack = [
|
||||||
title: action.payload.title,
|
{ title: action.payload.title, message: action.payload.msg },
|
||||||
message: action.payload.msg
|
...state.InfoStack,
|
||||||
}, ...state.InfoStack];
|
];
|
||||||
return {
|
return { ...state, DisplayInfo: true, InfoStack: infoStack };
|
||||||
...state,
|
},
|
||||||
DisplayInfo: true,
|
|
||||||
InfoStack: infoStack,
|
|
||||||
}
|
}
|
||||||
}
|
);
|
||||||
});
|
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
import {createReducer} from '@reduxjs/toolkit';
|
import { createReducer } from '@reduxjs/toolkit';
|
||||||
import {
|
import {
|
||||||
setAutoInstallRelease,
|
setAutoInstallRelease,
|
||||||
setDismissDependencies,
|
setDismissDependencies,
|
||||||
setInstallActive,
|
setInstallActive,
|
||||||
setInstallComplete,
|
setInstallComplete,
|
||||||
setInstallTestActive,
|
setInstallTestActive,
|
||||||
setMissingDependencies
|
setMissingDependencies,
|
||||||
} from '../actions/install_actions';
|
} from '../actions/install_actions';
|
||||||
|
|
||||||
export const installReducer = createReducer({
|
export const installReducer = createReducer(
|
||||||
|
{
|
||||||
AutoInstallRelease: false,
|
AutoInstallRelease: false,
|
||||||
DismissDependencies: false,
|
DismissDependencies: false,
|
||||||
InstallActive: false,
|
InstallActive: false,
|
||||||
@@ -16,18 +17,13 @@ export const installReducer = createReducer({
|
|||||||
InstallTestActive: false,
|
InstallTestActive: false,
|
||||||
InstallType: null,
|
InstallType: null,
|
||||||
MissingDependencies: [],
|
MissingDependencies: [],
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
[setAutoInstallRelease]: (state, action) => {
|
[setAutoInstallRelease]: (state, action) => {
|
||||||
return {
|
return { ...state, AutoInstallRelease: action.payload };
|
||||||
...state,
|
|
||||||
AutoInstallRelease: action.payload,
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
[setDismissDependencies]: (state, action) => {
|
[setDismissDependencies]: (state, action) => {
|
||||||
return {
|
return { ...state, DismissDependencies: action.payload };
|
||||||
...state,
|
|
||||||
DismissDependencies: action.payload,
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
[setInstallActive]: (state, action) => {
|
[setInstallActive]: (state, action) => {
|
||||||
return {
|
return {
|
||||||
@@ -43,18 +39,13 @@ export const installReducer = createReducer({
|
|||||||
InstallActive: false,
|
InstallActive: false,
|
||||||
InstallResult: action.payload,
|
InstallResult: action.payload,
|
||||||
InstallType: null,
|
InstallType: null,
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
[setInstallTestActive]: (state, action) => {
|
[setInstallTestActive]: (state, action) => {
|
||||||
return {
|
return { ...state, InstallTestActive: action.payload };
|
||||||
...state,
|
|
||||||
InstallTestActive: action.payload,
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
[setMissingDependencies]: (state, action) => {
|
[setMissingDependencies]: (state, action) => {
|
||||||
return {
|
return { ...state, MissingDependencies: action.payload };
|
||||||
...state,
|
},
|
||||||
MissingDependencies: action.payload,
|
|
||||||
}
|
}
|
||||||
}
|
);
|
||||||
});
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import {createReducer} from '@reduxjs/toolkit';
|
import { createReducer } from '@reduxjs/toolkit';
|
||||||
|
|
||||||
import * as Constants from '../../constants';
|
import * as Constants from '../../constants';
|
||||||
import {
|
import {
|
||||||
@@ -12,49 +12,49 @@ import {
|
|||||||
SET_MOUNT_STATE,
|
SET_MOUNT_STATE,
|
||||||
SET_MOUNTED,
|
SET_MOUNTED,
|
||||||
SET_PROVIDER_STATE,
|
SET_PROVIDER_STATE,
|
||||||
setBusy
|
setBusy,
|
||||||
} from '../actions/mount_actions';
|
} from '../actions/mount_actions';
|
||||||
|
|
||||||
export const createMountReducer = state => {
|
export const createMountReducer = (state) => {
|
||||||
let providerList = [
|
let providerList = [
|
||||||
...Constants.PROVIDER_LIST,
|
...Constants.PROVIDER_LIST,
|
||||||
...(state.RemoteMounts || []),
|
...(state.RemoteMounts || []),
|
||||||
...(state.S3Mounts || []),
|
...(state.S3Mounts || []),
|
||||||
];
|
];
|
||||||
const providerState = providerList
|
const providerState = providerList
|
||||||
.map(provider => {
|
.map((provider) => {
|
||||||
return {
|
return {
|
||||||
[provider]: {
|
[provider]: {
|
||||||
AutoMount: false,
|
AutoMount: false,
|
||||||
AutoRestart: false,
|
AutoRestart: false,
|
||||||
MountLocation: '',
|
MountLocation: '',
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
})
|
})
|
||||||
.reduce((map, obj) => {
|
.reduce((map, obj) => {
|
||||||
return {...map, ...obj}
|
return { ...map, ...obj };
|
||||||
});
|
});
|
||||||
|
|
||||||
const mountState = providerList
|
const mountState = providerList
|
||||||
.map(provider => {
|
.map((provider) => {
|
||||||
return {
|
return {
|
||||||
[provider]: {
|
[provider]: {
|
||||||
AllowMount: false,
|
AllowMount: false,
|
||||||
DriveLetters: [],
|
DriveLetters: [],
|
||||||
Mounted: false,
|
Mounted: false,
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
})
|
})
|
||||||
.reduce((map, obj) => {
|
.reduce((map, obj) => {
|
||||||
return {...map, ...obj}
|
return { ...map, ...obj };
|
||||||
});
|
});
|
||||||
|
|
||||||
const autoMountProcessed =
|
const autoMountProcessed = providerList
|
||||||
providerList.map(provider => {
|
.map((provider) => {
|
||||||
return {[provider]: false,}
|
return { [provider]: false };
|
||||||
})
|
})
|
||||||
.reduce((map, obj) => {
|
.reduce((map, obj) => {
|
||||||
return {...map, ...obj}
|
return { ...map, ...obj };
|
||||||
});
|
});
|
||||||
|
|
||||||
return createReducer(
|
return createReducer(
|
||||||
@@ -71,52 +71,56 @@ export const createMountReducer = state => {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
[addRemoteMount2]: (state, action) => {
|
[addRemoteMount2]: (state, action) => {
|
||||||
let mountState = {...state.MountState};
|
let mountState = { ...state.MountState };
|
||||||
mountState[action.payload] = {
|
mountState[action.payload] = {
|
||||||
AllowMount: false,
|
AllowMount: false,
|
||||||
DriveLetters: [],
|
DriveLetters: [],
|
||||||
Mounted: false,
|
Mounted: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
let providerState = {...state.ProviderState};
|
let providerState = { ...state.ProviderState };
|
||||||
providerState[action.payload] = {
|
providerState[action.payload] = {
|
||||||
AutoMount: false,
|
AutoMount: false,
|
||||||
AutoRestart: false,
|
AutoRestart: false,
|
||||||
MountLocation: '',
|
MountLocation: '',
|
||||||
};
|
};
|
||||||
|
|
||||||
let autoMountProcessed = {...state.AutoMountProcessed};
|
let autoMountProcessed = { ...state.AutoMountProcessed };
|
||||||
autoMountProcessed[action.payload] = true;
|
autoMountProcessed[action.payload] = true;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...state, AutoMountProcessed: autoMountProcessed,
|
...state,
|
||||||
MountState: mountState, ProviderState: providerState,
|
AutoMountProcessed: autoMountProcessed,
|
||||||
|
MountState: mountState,
|
||||||
|
ProviderState: providerState,
|
||||||
RemoteMounts: [...state.RemoteMounts, action.payload],
|
RemoteMounts: [...state.RemoteMounts, action.payload],
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
[addS3Mount2]: (state, action) => {
|
[addS3Mount2]: (state, action) => {
|
||||||
let mountState = {...state.MountState};
|
let mountState = { ...state.MountState };
|
||||||
mountState[action.payload] = {
|
mountState[action.payload] = {
|
||||||
AllowMount: false,
|
AllowMount: false,
|
||||||
DriveLetters: [],
|
DriveLetters: [],
|
||||||
Mounted: false,
|
Mounted: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
let providerState = {...state.ProviderState};
|
let providerState = { ...state.ProviderState };
|
||||||
providerState[action.payload] = {
|
providerState[action.payload] = {
|
||||||
AutoMount: false,
|
AutoMount: false,
|
||||||
AutoRestart: false,
|
AutoRestart: false,
|
||||||
MountLocation: '',
|
MountLocation: '',
|
||||||
};
|
};
|
||||||
|
|
||||||
let autoMountProcessed = {...state.AutoMountProcessed};
|
let autoMountProcessed = { ...state.AutoMountProcessed };
|
||||||
autoMountProcessed[action.payload] = true;
|
autoMountProcessed[action.payload] = true;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...state, AutoMountProcessed: autoMountProcessed,
|
...state,
|
||||||
MountState: mountState, ProviderState: providerState,
|
AutoMountProcessed: autoMountProcessed,
|
||||||
|
MountState: mountState,
|
||||||
|
ProviderState: providerState,
|
||||||
S3Mounts: [...state.S3Mounts, action.payload],
|
S3Mounts: [...state.S3Mounts, action.payload],
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
[DISPLAY_CONFIGURATION]: (state, action) => {
|
[DISPLAY_CONFIGURATION]: (state, action) => {
|
||||||
return {
|
return {
|
||||||
@@ -127,19 +131,19 @@ export const createMountReducer = state => {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
[removeMount3]: (state, action) => {
|
[removeMount3]: (state, action) => {
|
||||||
let mountState = {...state.MountState};
|
let mountState = { ...state.MountState };
|
||||||
delete mountState[action.payload];
|
delete mountState[action.payload];
|
||||||
|
|
||||||
let providerState = {...state.ProviderState};
|
let providerState = { ...state.ProviderState };
|
||||||
delete providerState[action.payload];
|
delete providerState[action.payload];
|
||||||
|
|
||||||
let autoMountProcessed = {...state.AutoMountProcessed};
|
let autoMountProcessed = { ...state.AutoMountProcessed };
|
||||||
delete autoMountProcessed[action.payload];
|
delete autoMountProcessed[action.payload];
|
||||||
|
|
||||||
const remoteMounts =
|
const remoteMounts = state.RemoteMounts.filter(
|
||||||
state.RemoteMounts.filter(i => i !== action.payload);
|
(i) => i !== action.payload
|
||||||
const s3Mounts =
|
);
|
||||||
state.S3Mounts.filter(i => i !== action.payload);
|
const s3Mounts = state.S3Mounts.filter((i) => i !== action.payload);
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
AutoMountProcessed: autoMountProcessed,
|
AutoMountProcessed: autoMountProcessed,
|
||||||
@@ -150,7 +154,7 @@ export const createMountReducer = state => {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
[RESET_MOUNTS_STATE]: (state, action) => {
|
[RESET_MOUNTS_STATE]: (state, action) => {
|
||||||
return {...state, MountsBusy: false, MountState: mountState,}
|
return { ...state, MountsBusy: false, MountState: mountState };
|
||||||
},
|
},
|
||||||
[SET_AUTO_MOUNT_PROCESSED]: (state, action) => {
|
[SET_AUTO_MOUNT_PROCESSED]: (state, action) => {
|
||||||
return {
|
return {
|
||||||
@@ -158,7 +162,7 @@ export const createMountReducer = state => {
|
|||||||
AutoMountProcessed: {
|
AutoMountProcessed: {
|
||||||
...state.AutoMountProcessed,
|
...state.AutoMountProcessed,
|
||||||
[action.payload.provider]: action.payload.processed,
|
[action.payload.provider]: action.payload.processed,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
[SET_ALLOW_MOUNT]: (state, action) => {
|
[SET_ALLOW_MOUNT]: (state, action) => {
|
||||||
@@ -169,14 +173,12 @@ export const createMountReducer = state => {
|
|||||||
[action.payload.provider]: {
|
[action.payload.provider]: {
|
||||||
...state.MountState[action.payload.provider],
|
...state.MountState[action.payload.provider],
|
||||||
AllowMount: action.payload.allow,
|
AllowMount: action.payload.allow,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
[setBusy]:
|
[setBusy]: (state, action) => {
|
||||||
(state,
|
return { ...state, MountsBusy: action.payload };
|
||||||
action) => {
|
|
||||||
return {...state, MountsBusy: action.payload};
|
|
||||||
},
|
},
|
||||||
[SET_MOUNT_STATE]: (state, action) => {
|
[SET_MOUNT_STATE]: (state, action) => {
|
||||||
return {
|
return {
|
||||||
@@ -185,9 +187,9 @@ export const createMountReducer = state => {
|
|||||||
...state.MountState,
|
...state.MountState,
|
||||||
[action.payload.provider]: {
|
[action.payload.provider]: {
|
||||||
...state.MountState[action.payload.provider],
|
...state.MountState[action.payload.provider],
|
||||||
...action.payload.state
|
...action.payload.state,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
[SET_MOUNTED]: (state, action) => {
|
[SET_MOUNTED]: (state, action) => {
|
||||||
@@ -198,8 +200,8 @@ export const createMountReducer = state => {
|
|||||||
[action.payload.provider]: {
|
[action.payload.provider]: {
|
||||||
...state.MountState[action.payload.provider],
|
...state.MountState[action.payload.provider],
|
||||||
Mounted: action.payload.mounted,
|
Mounted: action.payload.mounted,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
[SET_PROVIDER_STATE]: (state, action) => {
|
[SET_PROVIDER_STATE]: (state, action) => {
|
||||||
@@ -209,10 +211,11 @@ export const createMountReducer = state => {
|
|||||||
...state.ProviderState,
|
...state.ProviderState,
|
||||||
[action.payload.provider]: {
|
[action.payload.provider]: {
|
||||||
...state.ProviderState[action.payload.provider],
|
...state.ProviderState[action.payload.provider],
|
||||||
...action.payload.state
|
...action.payload.state,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
};
|
);
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,13 +1,16 @@
|
|||||||
import {createReducer} from '@reduxjs/toolkit';
|
import { createReducer } from '@reduxjs/toolkit';
|
||||||
import {displayPinnedManager} from '../actions/pinned_manager_actions';
|
import { displayPinnedManager } from '../actions/pinned_manager_actions';
|
||||||
|
|
||||||
export const pinnedManagerReducer = createReducer({
|
export const pinnedManagerReducer = createReducer(
|
||||||
|
{
|
||||||
DisplayPinnedManager: false,
|
DisplayPinnedManager: false,
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
[displayPinnedManager]: (state, action) => {
|
[displayPinnedManager]: (state, action) => {
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
DisplayPinnedManager: action.payload,
|
DisplayPinnedManager: action.payload,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
import {createReducer} from '@reduxjs/toolkit';
|
import { createReducer } from '@reduxjs/toolkit';
|
||||||
import * as Actions from '../actions/release_version_actions';
|
|
||||||
import * as Constants from '../../constants';
|
|
||||||
|
|
||||||
const versionLookup = Constants.RELEASE_TYPES.map(k=> {
|
import * as Constants from '../../constants';
|
||||||
return {
|
import * as Actions from '../actions/release_version_actions';
|
||||||
[k]: ['unavailable']
|
|
||||||
};
|
const versionLookup = Constants.RELEASE_TYPES.map((k) => {
|
||||||
|
return { [k]: ['unavailable'] };
|
||||||
}).reduce((map, obj) => {
|
}).reduce((map, obj) => {
|
||||||
return {
|
return {
|
||||||
...map,
|
...map,
|
||||||
@@ -13,7 +12,8 @@ const versionLookup = Constants.RELEASE_TYPES.map(k=> {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
export const releaseVersionReducer = createReducer({
|
export const releaseVersionReducer = createReducer(
|
||||||
|
{
|
||||||
AllowDismissDependencies: false,
|
AllowDismissDependencies: false,
|
||||||
DismissNewReleasesAvailable: true,
|
DismissNewReleasesAvailable: true,
|
||||||
InstalledVersion: 'none',
|
InstalledVersion: 'none',
|
||||||
@@ -28,8 +28,9 @@ export const releaseVersionReducer = createReducer({
|
|||||||
UpgradeDismissed: false,
|
UpgradeDismissed: false,
|
||||||
Version: -1,
|
Version: -1,
|
||||||
VersionLookup: versionLookup,
|
VersionLookup: versionLookup,
|
||||||
}, {
|
},
|
||||||
[Actions.CLEAR_UI_UPGRADE]: state => {
|
{
|
||||||
|
[Actions.CLEAR_UI_UPGRADE]: (state) => {
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
UpgradeAvailable: false,
|
UpgradeAvailable: false,
|
||||||
@@ -42,7 +43,7 @@ export const releaseVersionReducer = createReducer({
|
|||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
Release: action.payload.release,
|
Release: action.payload.release,
|
||||||
Version: action.payload.version
|
Version: action.payload.version,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
[Actions.setAllowDismissDependencies]: (state, action) => {
|
[Actions.setAllowDismissDependencies]: (state, action) => {
|
||||||
@@ -64,10 +65,7 @@ export const releaseVersionReducer = createReducer({
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
[Actions.setInstalledVersion]: (state, action) => {
|
[Actions.setInstalledVersion]: (state, action) => {
|
||||||
return {
|
return { ...state, InstalledVersion: action.payload };
|
||||||
...state,
|
|
||||||
InstalledVersion: action.payload,
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
[Actions.setNewReleasesAvailable]: (state, action) => {
|
[Actions.setNewReleasesAvailable]: (state, action) => {
|
||||||
return {
|
return {
|
||||||
@@ -103,5 +101,6 @@ export const releaseVersionReducer = createReducer({
|
|||||||
UpgradeVersion: action.payload.version,
|
UpgradeVersion: action.payload.version,
|
||||||
UpgradeDismissed: false,
|
UpgradeDismissed: false,
|
||||||
};
|
};
|
||||||
|
},
|
||||||
}
|
}
|
||||||
});
|
);
|
||||||
|
|||||||
@@ -1,20 +1,17 @@
|
|||||||
import {createReducer} from '@reduxjs/toolkit';
|
import { createReducer } from '@reduxjs/toolkit';
|
||||||
import * as Actions from '../actions/skynet_actions';
|
import * as Actions from '../actions/skynet_actions';
|
||||||
|
|
||||||
export const skynetReducer = createReducer({
|
export const skynetReducer = createReducer(
|
||||||
|
{
|
||||||
DisplayExport: false,
|
DisplayExport: false,
|
||||||
DisplayImport: false,
|
DisplayImport: false,
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
[Actions.displaySkynetExport]: (state, action) => {
|
[Actions.displaySkynetExport]: (state, action) => {
|
||||||
return {
|
return { ...state, DisplayExport: action.payload };
|
||||||
...state,
|
|
||||||
DisplayExport: action.payload,
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
[Actions.displaySkynetImport]: (state, action) => {
|
[Actions.displaySkynetImport]: (state, action) => {
|
||||||
return {
|
return { ...state, DisplayImport: action.payload };
|
||||||
...state,
|
|
||||||
DisplayImport: action.payload,
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
import {configureStore, getDefaultMiddleware} from '@reduxjs/toolkit';
|
import { configureStore, getDefaultMiddleware } from '@reduxjs/toolkit';
|
||||||
import {createCommonReducer} from '../reducers/common_reducer';
|
|
||||||
import {downloadReducer} from '../reducers/download_reducer';
|
import { createCommonReducer } from '../reducers/common_reducer';
|
||||||
import {errorReducer} from '../reducers/error_reducer';
|
import { downloadReducer } from '../reducers/download_reducer';
|
||||||
import {installReducer} from '../reducers/install_reducer';
|
import { errorReducer } from '../reducers/error_reducer';
|
||||||
import {createMountReducer} from '../reducers/mount_reducer';
|
import { installReducer } from '../reducers/install_reducer';
|
||||||
import {releaseVersionReducer} from '../reducers/release_version_reducer';
|
import { createMountReducer } from '../reducers/mount_reducer';
|
||||||
import {skynetReducer} from '../reducers/skynet_reducer';
|
import { pinnedManagerReducer } from '../reducers/pinned_manager_reducer';
|
||||||
import {pinnedManagerReducer} from '../reducers/pinned_manager_reducer'
|
import { releaseVersionReducer } from '../reducers/release_version_reducer';
|
||||||
|
import { skynetReducer } from '../reducers/skynet_reducer';
|
||||||
|
|
||||||
export default function createAppStore(platformInfo, version, state) {
|
export default function createAppStore(platformInfo, version, state) {
|
||||||
const reducer = {
|
const reducer = {
|
||||||
@@ -25,6 +26,6 @@ export default function createAppStore(platformInfo, version, state) {
|
|||||||
return configureStore({
|
return configureStore({
|
||||||
reducer,
|
reducer,
|
||||||
middleware,
|
middleware,
|
||||||
devTools: process.env.NODE_ENV !== 'production'
|
devTools: process.env.NODE_ENV !== 'production',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
const Constants = require('../../constants');
|
const Constants = require('../../constants');
|
||||||
|
|
||||||
const addListeners = (ipcMain, {closeApplication, setWindowVisibility}) => {
|
const addListeners = (ipcMain, { closeApplication, setWindowVisibility }) => {
|
||||||
ipcMain.on(Constants.IPC_Shutdown, () => {
|
ipcMain.on(Constants.IPC_Shutdown, () => {
|
||||||
closeApplication();
|
closeApplication();
|
||||||
});
|
});
|
||||||
@@ -9,12 +9,10 @@ const addListeners = (ipcMain, {closeApplication, setWindowVisibility}) => {
|
|||||||
setWindowVisibility(true);
|
setWindowVisibility(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.on(Constants.IPC_Show_Window + '_sync', event => {
|
ipcMain.on(Constants.IPC_Show_Window + '_sync', (event) => {
|
||||||
setWindowVisibility(true);
|
setWindowVisibility(true);
|
||||||
event.returnValue = true;
|
event.returnValue = true;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = { addListeners };
|
||||||
addListeners
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
const Constants = require('../../constants');
|
const Constants = require('../../constants');
|
||||||
const helpers = require('../../helpers');
|
const helpers = require('../../helpers');
|
||||||
|
|
||||||
const addListeners = (ipcMain, {standardIPCReply}) => {
|
const addListeners = (ipcMain, { standardIPCReply }) => {
|
||||||
ipcMain.on(Constants.IPC_Get_Config, (event, data) => {
|
ipcMain.on(Constants.IPC_Get_Config, (event, data) => {
|
||||||
helpers
|
helpers
|
||||||
.getConfig(data.Version, data.Provider, data.Remote, data.S3)
|
.getConfig(data.Version, data.Provider, data.Remote, data.S3)
|
||||||
@@ -11,10 +11,15 @@ const addListeners = (ipcMain, {standardIPCReply}) => {
|
|||||||
Config: data.Data,
|
Config: data.Data,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
standardIPCReply(event, Constants.IPC_Get_Config_Reply, {}, data.Code);
|
standardIPCReply(
|
||||||
|
event,
|
||||||
|
Constants.IPC_Get_Config_Reply,
|
||||||
|
{},
|
||||||
|
data.Code
|
||||||
|
);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch((error) => {
|
||||||
standardIPCReply(event, Constants.IPC_Get_Config_Reply, {}, error);
|
standardIPCReply(event, Constants.IPC_Get_Config_Reply, {}, error);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -27,8 +32,13 @@ const addListeners = (ipcMain, {standardIPCReply}) => {
|
|||||||
Template: data,
|
Template: data,
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch((error) => {
|
||||||
standardIPCReply(event, Constants.IPC_Get_Config_Template_Reply, {}, error);
|
standardIPCReply(
|
||||||
|
event,
|
||||||
|
Constants.IPC_Get_Config_Template_Reply,
|
||||||
|
{},
|
||||||
|
error
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -36,12 +46,24 @@ const addListeners = (ipcMain, {standardIPCReply}) => {
|
|||||||
const setConfigValue = (i) => {
|
const setConfigValue = (i) => {
|
||||||
if (i < data.Items.length) {
|
if (i < data.Items.length) {
|
||||||
helpers
|
helpers
|
||||||
.setConfigValue(data.Items[i].Name, data.Items[i].Value, data.Provider, data.Remote, data.S3, data.Version)
|
.setConfigValue(
|
||||||
|
data.Items[i].Name,
|
||||||
|
data.Items[i].Value,
|
||||||
|
data.Provider,
|
||||||
|
data.Remote,
|
||||||
|
data.S3,
|
||||||
|
data.Version
|
||||||
|
)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
setConfigValue(++i);
|
setConfigValue(++i);
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch((error) => {
|
||||||
standardIPCReply(event, Constants.IPC_Set_Config_Values_Reply, {}, error);
|
standardIPCReply(
|
||||||
|
event,
|
||||||
|
Constants.IPC_Set_Config_Values_Reply,
|
||||||
|
{},
|
||||||
|
error
|
||||||
|
);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
standardIPCReply(event, Constants.IPC_Set_Config_Values_Reply, {});
|
standardIPCReply(event, Constants.IPC_Set_Config_Values_Reply, {});
|
||||||
@@ -51,6 +73,4 @@ const addListeners = (ipcMain, {standardIPCReply}) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = { addListeners };
|
||||||
addListeners
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -1,47 +1,46 @@
|
|||||||
const Constants = require('../../constants');
|
const Constants = require('../../constants');
|
||||||
const helpers = require('../../helpers');
|
const helpers = require('../../helpers');
|
||||||
|
|
||||||
const addListeners = (ipcMain, {standardIPCReply}) => {
|
const addListeners = (ipcMain, { standardIPCReply }) => {
|
||||||
ipcMain.on(Constants.IPC_Check_Daemon_Version, (event, data) => {
|
ipcMain.on(Constants.IPC_Check_Daemon_Version, (event, data) => {
|
||||||
helpers
|
helpers
|
||||||
.checkDaemonVersion(data.Version, data.Provider)
|
.checkDaemonVersion(data.Version, data.Provider)
|
||||||
.then(code => {
|
.then((code) => {
|
||||||
standardIPCReply(event, Constants.IPC_Check_Daemon_Version_Reply, {
|
standardIPCReply(event, Constants.IPC_Check_Daemon_Version_Reply, {
|
||||||
Valid: (code === 0),
|
Valid: code === 0,
|
||||||
Code: code,
|
Code: code,
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(e => {
|
.catch((e) => {
|
||||||
standardIPCReply(event, Constants.IPC_Check_Daemon_Version_Reply, {
|
standardIPCReply(
|
||||||
|
event,
|
||||||
|
Constants.IPC_Check_Daemon_Version_Reply,
|
||||||
|
{
|
||||||
Valid: false,
|
Valid: false,
|
||||||
}, e);
|
},
|
||||||
|
e
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.on(Constants.IPC_Check_Daemon_Version + '_sync', (event, data) => {
|
ipcMain.on(Constants.IPC_Check_Daemon_Version + '_sync', (event, data) => {
|
||||||
helpers
|
helpers
|
||||||
.checkDaemonVersion(data.Version, data.Provider)
|
.checkDaemonVersion(data.Version, data.Provider)
|
||||||
.then(code => {
|
.then((code) => {
|
||||||
event.returnValue = {
|
event.returnValue = {
|
||||||
data: {
|
data: {
|
||||||
Success: true,
|
Success: true,
|
||||||
Valid: (code === 0),
|
Valid: code === 0,
|
||||||
Code: code,
|
Code: code,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
.catch(e => {
|
.catch((e) => {
|
||||||
event.returnValue = {
|
event.returnValue = {
|
||||||
data: {
|
data: { Error: e.toString(), Success: false, Valid: false },
|
||||||
Error: e.toString(),
|
|
||||||
Success: false,
|
|
||||||
Valid: false
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = { addListeners };
|
||||||
addListeners
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ const Constants = require('../../constants');
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const helpers = require('../../helpers');
|
const helpers = require('../../helpers');
|
||||||
|
|
||||||
const addListeners = (ipcMain, {standardIPCReply}) => {
|
const addListeners = (ipcMain, { standardIPCReply }) => {
|
||||||
ipcMain.on(Constants.IPC_Check_Dependency_Installed, (event, data) => {
|
ipcMain.on(Constants.IPC_Check_Dependency_Installed, (event, data) => {
|
||||||
try {
|
try {
|
||||||
const exists = fs.lstatSync(data.File).isFile();
|
const exists = fs.lstatSync(data.File).isFile();
|
||||||
@@ -13,14 +13,16 @@ const addListeners = (ipcMain, {standardIPCReply}) => {
|
|||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
standardIPCReply(event, Constants.IPC_Check_Dependency_Installed_Reply, {
|
standardIPCReply(event, Constants.IPC_Check_Dependency_Installed_Reply, {
|
||||||
data : {
|
data: {
|
||||||
Exists: false,
|
Exists: false,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.on(Constants.IPC_Check_Dependency_Installed + '_sync', (event, data) => {
|
ipcMain.on(
|
||||||
|
Constants.IPC_Check_Dependency_Installed + '_sync',
|
||||||
|
(event, data) => {
|
||||||
try {
|
try {
|
||||||
const ls = fs.lstatSync(data.File);
|
const ls = fs.lstatSync(data.File);
|
||||||
event.returnValue = {
|
event.returnValue = {
|
||||||
@@ -30,12 +32,11 @@ const addListeners = (ipcMain, {standardIPCReply}) => {
|
|||||||
};
|
};
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
event.returnValue = {
|
event.returnValue = {
|
||||||
data: {
|
data: { Exists: false },
|
||||||
Exists: false
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
ipcMain.on(Constants.IPC_Install_Dependency, (event, data) => {
|
ipcMain.on(Constants.IPC_Install_Dependency, (event, data) => {
|
||||||
if (data.Source.toLowerCase().endsWith('.dmg')) {
|
if (data.Source.toLowerCase().endsWith('.dmg')) {
|
||||||
@@ -47,11 +48,16 @@ const addListeners = (ipcMain, {standardIPCReply}) => {
|
|||||||
URL: data.URL,
|
URL: data.URL,
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(error=> {
|
.catch((error) => {
|
||||||
standardIPCReply(event, Constants.IPC_Install_Dependency_Reply, {
|
standardIPCReply(
|
||||||
|
event,
|
||||||
|
Constants.IPC_Install_Dependency_Reply,
|
||||||
|
{
|
||||||
Source: data.Source,
|
Source: data.Source,
|
||||||
URL: data.URL,
|
URL: data.URL,
|
||||||
}, error);
|
},
|
||||||
|
error
|
||||||
|
);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
const execInstall = () => {
|
const execInstall = () => {
|
||||||
@@ -63,17 +69,22 @@ const addListeners = (ipcMain, {standardIPCReply}) => {
|
|||||||
URL: data.URL,
|
URL: data.URL,
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch((error) => {
|
||||||
standardIPCReply(event, Constants.IPC_Install_Dependency_Reply, {
|
standardIPCReply(
|
||||||
|
event,
|
||||||
|
Constants.IPC_Install_Dependency_Reply,
|
||||||
|
{
|
||||||
Source: data.Source,
|
Source: data.Source,
|
||||||
URL: data.URL,
|
URL: data.URL,
|
||||||
}, error);
|
},
|
||||||
|
error
|
||||||
|
);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
if (data.IsWinFSP) {
|
if (data.IsWinFSP) {
|
||||||
helpers
|
helpers
|
||||||
.performWindowsUninstall(Constants.WINFSP_VERSION_NAMES)
|
.performWindowsUninstall(Constants.WINFSP_VERSION_NAMES)
|
||||||
.then(uninstalled => {
|
.then((uninstalled) => {
|
||||||
if (uninstalled) {
|
if (uninstalled) {
|
||||||
standardIPCReply(event, Constants.IPC_Install_Dependency_Reply, {
|
standardIPCReply(event, Constants.IPC_Install_Dependency_Reply, {
|
||||||
RebootRequired: true,
|
RebootRequired: true,
|
||||||
@@ -84,11 +95,16 @@ const addListeners = (ipcMain, {standardIPCReply}) => {
|
|||||||
execInstall();
|
execInstall();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch((error) => {
|
||||||
standardIPCReply(event, Constants.IPC_Install_Dependency_Reply, {
|
standardIPCReply(
|
||||||
|
event,
|
||||||
|
Constants.IPC_Install_Dependency_Reply,
|
||||||
|
{
|
||||||
Source: data.Source,
|
Source: data.Source,
|
||||||
URL: data.URL,
|
URL: data.URL,
|
||||||
}, error);
|
},
|
||||||
|
error
|
||||||
|
);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
execInstall();
|
execInstall();
|
||||||
@@ -97,6 +113,4 @@ const addListeners = (ipcMain, {standardIPCReply}) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = { addListeners };
|
||||||
addListeners
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -2,24 +2,32 @@ const Constants = require('../../constants');
|
|||||||
const helpers = require('../../helpers');
|
const helpers = require('../../helpers');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
|
||||||
const addListeners = (ipcMain, {standardIPCReply}) => {
|
const addListeners = (ipcMain, { standardIPCReply }) => {
|
||||||
ipcMain.on(Constants.IPC_Download_File, (event, data) => {
|
ipcMain.on(Constants.IPC_Download_File, (event, data) => {
|
||||||
const destination = path.join(helpers.getDataDirectory(), data.Filename);
|
const destination = path.join(helpers.getDataDirectory(), data.Filename);
|
||||||
helpers.downloadFile(data.URL, destination, (progress) => {
|
helpers.downloadFile(
|
||||||
|
data.URL,
|
||||||
|
destination,
|
||||||
|
(progress) => {
|
||||||
standardIPCReply(event, Constants.IPC_Download_File_Progress, {
|
standardIPCReply(event, Constants.IPC_Download_File_Progress, {
|
||||||
Destination: destination,
|
Destination: destination,
|
||||||
Progress: progress,
|
Progress: progress,
|
||||||
URL: data.URL,
|
URL: data.URL,
|
||||||
});
|
});
|
||||||
}, error => {
|
},
|
||||||
standardIPCReply(event, Constants.IPC_Download_File_Complete, {
|
(error) => {
|
||||||
|
standardIPCReply(
|
||||||
|
event,
|
||||||
|
Constants.IPC_Download_File_Complete,
|
||||||
|
{
|
||||||
Destination: destination,
|
Destination: destination,
|
||||||
URL: data.URL,
|
URL: data.URL,
|
||||||
}, error);
|
},
|
||||||
});
|
error
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = { addListeners };
|
||||||
addListeners
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -1,19 +1,23 @@
|
|||||||
const Constants = require('../../constants');
|
const Constants = require('../../constants');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
|
|
||||||
const addListeners = (ipcMain, {getMainWindow, dialog}) => {
|
const addListeners = (ipcMain, { getMainWindow, dialog }) => {
|
||||||
ipcMain.on(Constants.IPC_Browse_Directory + '_sync', (event, data) => {
|
ipcMain.on(Constants.IPC_Browse_Directory + '_sync', (event, data) => {
|
||||||
dialog.showOpenDialog(getMainWindow(), {
|
dialog.showOpenDialog(
|
||||||
|
getMainWindow(),
|
||||||
|
{
|
||||||
defaultPath: data.Location,
|
defaultPath: data.Location,
|
||||||
properties: ['openDirectory'],
|
properties: ['openDirectory'],
|
||||||
title: data.Title,
|
title: data.Title,
|
||||||
}, (filePaths) => {
|
},
|
||||||
if (filePaths && (filePaths.length > 0)) {
|
(filePaths) => {
|
||||||
|
if (filePaths && filePaths.length > 0) {
|
||||||
event.returnValue = filePaths[0];
|
event.returnValue = filePaths[0];
|
||||||
} else {
|
} else {
|
||||||
event.returnValue = '';
|
event.returnValue = '';
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.on(Constants.IPC_Delete_File, (event, data) => {
|
ipcMain.on(Constants.IPC_Delete_File, (event, data) => {
|
||||||
@@ -21,11 +25,8 @@ const addListeners = (ipcMain, {getMainWindow, dialog}) => {
|
|||||||
if (fs.existsSync(data.FilePath)) {
|
if (fs.existsSync(data.FilePath)) {
|
||||||
fs.unlinkSync(data.FilePath);
|
fs.unlinkSync(data.FilePath);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {}
|
||||||
}
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = { addListeners };
|
||||||
addListeners
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -10,18 +10,25 @@ let manualMountDetection = {};
|
|||||||
let mountedData = {};
|
let mountedData = {};
|
||||||
let mountedLocations = [];
|
let mountedLocations = [];
|
||||||
|
|
||||||
const clearManualMountDetection = provider => {
|
const clearManualMountDetection = (provider) => {
|
||||||
if (manualMountDetection[provider]) {
|
if (manualMountDetection[provider]) {
|
||||||
clearInterval(manualMountDetection[provider]);
|
clearInterval(manualMountDetection[provider]);
|
||||||
delete manualMountDetection[provider];
|
delete manualMountDetection[provider];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const monitorMount = (sender, provider, providerList, version, pid, location) => {
|
const monitorMount = (
|
||||||
|
sender,
|
||||||
|
provider,
|
||||||
|
providerList,
|
||||||
|
version,
|
||||||
|
pid,
|
||||||
|
location
|
||||||
|
) => {
|
||||||
manualMountDetection[provider] = setInterval(() => {
|
manualMountDetection[provider] = setInterval(() => {
|
||||||
helpers
|
helpers
|
||||||
.detectRepertoryMounts(version, providerList)
|
.detectRepertoryMounts(version, providerList)
|
||||||
.then(result => {
|
.then((result) => {
|
||||||
if (result[provider].PID !== pid) {
|
if (result[provider].PID !== pid) {
|
||||||
if (result[provider].PID === -1) {
|
if (result[provider].PID === -1) {
|
||||||
clearManualMountDetection(provider);
|
clearManualMountDetection(provider);
|
||||||
@@ -32,14 +39,14 @@ const monitorMount = (sender, provider, providerList, version, pid, location) =>
|
|||||||
Provider: provider,
|
Provider: provider,
|
||||||
Error: Error(provider + ' Unmounted').toString(),
|
Error: Error(provider + ' Unmounted').toString(),
|
||||||
Success: false,
|
Success: false,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
pid = result[provider].PID;
|
pid = result[provider].PID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(e => {
|
.catch((e) => {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
});
|
});
|
||||||
}, 6000);
|
}, 6000);
|
||||||
@@ -55,22 +62,27 @@ const unmountAllDrives = () => {
|
|||||||
// Unmount all items
|
// Unmount all items
|
||||||
for (const mountLocation of mountedLocations) {
|
for (const mountLocation of mountedLocations) {
|
||||||
const data = mountedData[mountLocation];
|
const data = mountedData[mountLocation];
|
||||||
helpers.stopMountProcessSync(data.Version, data.Provider, data.Remote, data.S3);
|
helpers.stopMountProcessSync(
|
||||||
|
data.Version,
|
||||||
|
data.Provider,
|
||||||
|
data.Remote,
|
||||||
|
data.S3
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
mountedLocations = [];
|
mountedLocations = [];
|
||||||
mountedData = {};
|
mountedData = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
const addListeners = (ipcMain, {setTrayImage, standardIPCReply}) => {
|
const addListeners = (ipcMain, { setTrayImage, standardIPCReply }) => {
|
||||||
ipcMain.on(Constants.IPC_Check_Mount_Location + '_sync', (event, data) => {
|
ipcMain.on(Constants.IPC_Check_Mount_Location + '_sync', (event, data) => {
|
||||||
let response = {
|
let response = { Success: true, Error: '' };
|
||||||
Success: true,
|
|
||||||
Error: ''
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (fs.existsSync(data.Location) && fs.statSync(data.Location).isDirectory()) {
|
if (
|
||||||
|
fs.existsSync(data.Location) &&
|
||||||
|
fs.statSync(data.Location).isDirectory()
|
||||||
|
) {
|
||||||
if (fs.readdirSync(data.Location).length !== 0) {
|
if (fs.readdirSync(data.Location).length !== 0) {
|
||||||
response.Success = false;
|
response.Success = false;
|
||||||
response.Error = 'Directory not empty: ' + data.Location;
|
response.Error = 'Directory not empty: ' + data.Location;
|
||||||
@@ -106,8 +118,7 @@ const addListeners = (ipcMain, {setTrayImage, standardIPCReply}) => {
|
|||||||
if (Object.keys(locations).length > 0) {
|
if (Object.keys(locations).length > 0) {
|
||||||
for (const provider of providerList) {
|
for (const provider of providerList) {
|
||||||
driveInUse = locations[provider].startsWith(drive);
|
driveInUse = locations[provider].startsWith(drive);
|
||||||
if (driveInUse)
|
if (driveInUse) break;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!driveInUse) {
|
if (!driveInUse) {
|
||||||
@@ -117,17 +128,18 @@ const addListeners = (ipcMain, {setTrayImage, standardIPCReply}) => {
|
|||||||
driveLetters[provider].push(drive);
|
driveLetters[provider].push(drive);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Object.keys(locations).length > 0) {
|
if (Object.keys(locations).length > 0) {
|
||||||
for (const provider of providerList) {
|
for (const provider of providerList) {
|
||||||
if (locations[provider].length > 0) {
|
if (locations[provider].length > 0) {
|
||||||
if (!driveLetters[provider].find((driveLetter) => {
|
if (
|
||||||
|
!driveLetters[provider].find((driveLetter) => {
|
||||||
return driveLetter === locations[provider];
|
return driveLetter === locations[provider];
|
||||||
})) {
|
})
|
||||||
|
) {
|
||||||
driveLetters[provider].push(locations[provider]);
|
driveLetters[provider].push(locations[provider]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -135,17 +147,16 @@ const addListeners = (ipcMain, {setTrayImage, standardIPCReply}) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const setImage = locations => {
|
const setImage = (locations) => {
|
||||||
let driveInUse;
|
let driveInUse;
|
||||||
if (Object.keys(locations).length > 0) {
|
if (Object.keys(locations).length > 0) {
|
||||||
for (const provider of providerList) {
|
for (const provider of providerList) {
|
||||||
driveInUse = locations[provider] && locations[provider].length > 0;
|
driveInUse = locations[provider] && locations[provider].length > 0;
|
||||||
if (driveInUse)
|
if (driveInUse) break;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setTrayImage(driveInUse)
|
setTrayImage(driveInUse);
|
||||||
};
|
};
|
||||||
|
|
||||||
helpers
|
helpers
|
||||||
@@ -154,7 +165,9 @@ const addListeners = (ipcMain, {setTrayImage, standardIPCReply}) => {
|
|||||||
let storageData = {};
|
let storageData = {};
|
||||||
let locations = {};
|
let locations = {};
|
||||||
for (const provider of providerList) {
|
for (const provider of providerList) {
|
||||||
storageData[provider] = results[provider] ? results[provider] : {
|
storageData[provider] = results[provider]
|
||||||
|
? results[provider]
|
||||||
|
: {
|
||||||
Active: false,
|
Active: false,
|
||||||
Location: '',
|
Location: '',
|
||||||
PID: -1,
|
PID: -1,
|
||||||
@@ -164,7 +177,14 @@ const addListeners = (ipcMain, {setTrayImage, standardIPCReply}) => {
|
|||||||
if (storageData[provider].PID !== -1) {
|
if (storageData[provider].PID !== -1) {
|
||||||
expectedUnmount[provider] = false;
|
expectedUnmount[provider] = false;
|
||||||
if (firstMountCheck) {
|
if (firstMountCheck) {
|
||||||
monitorMount(event.sender, provider, providerList, data.Version, storageData[provider].PID, storageData[provider].Location);
|
monitorMount(
|
||||||
|
event.sender,
|
||||||
|
provider,
|
||||||
|
providerList,
|
||||||
|
data.Version,
|
||||||
|
storageData[provider].PID,
|
||||||
|
storageData[provider].Location
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -185,15 +205,20 @@ const addListeners = (ipcMain, {setTrayImage, standardIPCReply}) => {
|
|||||||
Provider: provider,
|
Provider: provider,
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch((error) => {
|
||||||
if (os.platform() === 'win32') {
|
if (os.platform() === 'win32') {
|
||||||
grabDriveLetters({});
|
grabDriveLetters({});
|
||||||
}
|
}
|
||||||
setImage({});
|
setImage({});
|
||||||
standardIPCReply(event, Constants.IPC_Detect_Mount_Reply, {
|
standardIPCReply(
|
||||||
|
event,
|
||||||
|
Constants.IPC_Detect_Mount_Reply,
|
||||||
|
{
|
||||||
DriveLetters: driveLetters[provider],
|
DriveLetters: driveLetters[provider],
|
||||||
Provider: provider,
|
Provider: provider,
|
||||||
}, error);
|
},
|
||||||
|
error
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -216,18 +241,30 @@ const addListeners = (ipcMain, {setTrayImage, standardIPCReply}) => {
|
|||||||
delete mountedData[data.Location];
|
delete mountedData[data.Location];
|
||||||
}
|
}
|
||||||
|
|
||||||
standardIPCReply(event, Constants.IPC_Unmount_Drive_Reply, {
|
standardIPCReply(
|
||||||
|
event,
|
||||||
|
Constants.IPC_Unmount_Drive_Reply,
|
||||||
|
{
|
||||||
Expected: expectedUnmount[data.Provider],
|
Expected: expectedUnmount[data.Provider],
|
||||||
Location: data.Location,
|
Location: data.Location,
|
||||||
Provider: data.Provider,
|
Provider: data.Provider,
|
||||||
Remote: data.Remote,
|
Remote: data.Remote,
|
||||||
S3: data.S3,
|
S3: data.S3,
|
||||||
}, error || Error(data.Provider + ' Unmounted'));
|
},
|
||||||
|
error || Error(data.Provider + ' Unmounted')
|
||||||
|
);
|
||||||
};
|
};
|
||||||
helpers
|
helpers
|
||||||
.executeMount(data.Version, data.Provider, data.Remote, data.S3, data.Location, (error, pid) => {
|
.executeMount(
|
||||||
|
data.Version,
|
||||||
|
data.Provider,
|
||||||
|
data.Remote,
|
||||||
|
data.S3,
|
||||||
|
data.Location,
|
||||||
|
(error, pid) => {
|
||||||
errorHandler(pid, error);
|
errorHandler(pid, error);
|
||||||
})
|
}
|
||||||
|
)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
standardIPCReply(event, Constants.IPC_Mount_Drive_Reply, {
|
standardIPCReply(event, Constants.IPC_Mount_Drive_Reply, {
|
||||||
Provider: data.Provider,
|
Provider: data.Provider,
|
||||||
@@ -235,7 +272,7 @@ const addListeners = (ipcMain, {setTrayImage, standardIPCReply}) => {
|
|||||||
S3: data.S3,
|
S3: data.S3,
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch((error) => {
|
||||||
errorHandler(-1, error);
|
errorHandler(-1, error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -245,17 +282,31 @@ const addListeners = (ipcMain, {setTrayImage, standardIPCReply}) => {
|
|||||||
if (data.Remote) {
|
if (data.Remote) {
|
||||||
data.Name = data.Name.replace(':', '_');
|
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 {
|
try {
|
||||||
helpers.removeDirectoryRecursively(dataDirectory);
|
helpers.removeDirectoryRecursively(dataDirectory);
|
||||||
standardIPCReply(event, Constants.IPC_Remove_Mount_Reply, {DataDirectory: dataDirectory});
|
standardIPCReply(event, Constants.IPC_Remove_Mount_Reply, {
|
||||||
|
DataDirectory: dataDirectory,
|
||||||
|
});
|
||||||
} catch (e) {
|
} 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();
|
unmountAllDrives();
|
||||||
standardIPCReply(event, Constants.IPC_Unmount_All_Drives_Reply);
|
standardIPCReply(event, Constants.IPC_Unmount_All_Drives_Reply);
|
||||||
});
|
});
|
||||||
@@ -266,10 +317,10 @@ const addListeners = (ipcMain, {setTrayImage, standardIPCReply}) => {
|
|||||||
expectedUnmount[data.Provider] = true;
|
expectedUnmount[data.Provider] = true;
|
||||||
helpers
|
helpers
|
||||||
.stopMountProcess(data.Version, data.Provider, data.Remote, data.S3)
|
.stopMountProcess(data.Version, data.Provider, data.Remote, data.S3)
|
||||||
.then(result => {
|
.then((result) => {
|
||||||
console.log(result);
|
console.log(result);
|
||||||
})
|
})
|
||||||
.catch(e => {
|
.catch((e) => {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -277,5 +328,5 @@ const addListeners = (ipcMain, {setTrayImage, standardIPCReply}) => {
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
addListeners,
|
addListeners,
|
||||||
unmountAllDrives
|
unmountAllDrives,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,49 +1,64 @@
|
|||||||
const Constants = require('../../constants');
|
const Constants = require('../../constants');
|
||||||
const helpers = require('../../helpers');
|
const helpers = require('../../helpers');
|
||||||
|
|
||||||
const addListeners = (ipcMain, {standardIPCReply}) => {
|
const addListeners = (ipcMain, { standardIPCReply }) => {
|
||||||
ipcMain.on(Constants.IPC_Get_Directory_Items, (event, data) => {
|
ipcMain.on(Constants.IPC_Get_Directory_Items, (event, data) => {
|
||||||
helpers
|
helpers
|
||||||
.grabDirectoryItems(data.Path, data.Version, data.Provider, data.Remote, data.S3)
|
.grabDirectoryItems(
|
||||||
.then(data => {
|
data.Path,
|
||||||
|
data.Version,
|
||||||
|
data.Provider,
|
||||||
|
data.Remote,
|
||||||
|
data.S3
|
||||||
|
)
|
||||||
|
.then((data) => {
|
||||||
standardIPCReply(event, Constants.IPC_Get_Directory_Items_Reply, {
|
standardIPCReply(event, Constants.IPC_Get_Directory_Items_Reply, {
|
||||||
Items: data.items,
|
Items: data.items,
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(e => {
|
.catch((e) => {
|
||||||
standardIPCReply(event, Constants.IPC_Get_Directory_Items_Reply, {}, e);
|
standardIPCReply(event, Constants.IPC_Get_Directory_Items_Reply, {}, e);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.on(Constants.IPC_Get_Pinned_Files, (event, data) => {
|
ipcMain.on(Constants.IPC_Get_Pinned_Files, (event, data) => {
|
||||||
helpers
|
helpers
|
||||||
.grabDirectoryItems(data.Path, data.Version, data.Provider, data.Remote, data.S3)
|
.grabDirectoryItems(
|
||||||
.then(data => {
|
data.Path,
|
||||||
|
data.Version,
|
||||||
|
data.Provider,
|
||||||
|
data.Remote,
|
||||||
|
data.S3
|
||||||
|
)
|
||||||
|
.then((data) => {
|
||||||
standardIPCReply(event, Constants.IPC_Get_Directory_Items_Reply, {
|
standardIPCReply(event, Constants.IPC_Get_Directory_Items_Reply, {
|
||||||
Items: data.items,
|
Items: data.items,
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(e => {
|
.catch((e) => {
|
||||||
standardIPCReply(event, Constants.IPC_Get_Directory_Items_Reply, {}, 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) => {
|
ipcMain.on(Constants.IPC_Set_Pinned + '_sync', (event, data) => {
|
||||||
helpers
|
helpers
|
||||||
.setPinned(data.Path, data.Pinned, data.Version, data.Provider, data.Remote, data.S3)
|
.setPinned(
|
||||||
.then(success => {
|
data.Path,
|
||||||
|
data.Pinned,
|
||||||
|
data.Version,
|
||||||
|
data.Provider,
|
||||||
|
data.Remote,
|
||||||
|
data.S3
|
||||||
|
)
|
||||||
|
.then((success) => {
|
||||||
event.returnValue = success;
|
event.returnValue = success;
|
||||||
})
|
})
|
||||||
.catch(e => {
|
.catch((e) => {
|
||||||
event.returnValue = false;
|
event.returnValue = false;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = { addListeners };
|
||||||
addListeners
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -10,11 +10,11 @@ const getPlatformOverride = () => {
|
|||||||
return _platformOverride;
|
return _platformOverride;
|
||||||
};
|
};
|
||||||
|
|
||||||
const setPlatformOverride = platformOverride => {
|
const setPlatformOverride = (platformOverride) => {
|
||||||
_platformOverride = platformOverride;
|
_platformOverride = platformOverride;
|
||||||
};
|
};
|
||||||
|
|
||||||
const addListeners = (ipcMain, {detectScript, saveUiSettings}) => {
|
const addListeners = (ipcMain, { detectScript, saveUiSettings }) => {
|
||||||
ipcMain.on(Constants.IPC_Get_Platform, (event) => {
|
ipcMain.on(Constants.IPC_Get_Platform, (event) => {
|
||||||
const sendResponse = (appPlatform, platform) => {
|
const sendResponse = (appPlatform, platform) => {
|
||||||
event.sender.send(Constants.IPC_Get_Platform_Reply, {
|
event.sender.send(Constants.IPC_Get_Platform_Reply, {
|
||||||
@@ -25,7 +25,7 @@ const addListeners = (ipcMain, {detectScript, saveUiSettings}) => {
|
|||||||
|
|
||||||
const platform = os.platform();
|
const platform = os.platform();
|
||||||
if (platform === 'linux') {
|
if (platform === 'linux') {
|
||||||
if (_platformOverride && (_platformOverride.length > 0)) {
|
if (_platformOverride && _platformOverride.length > 0) {
|
||||||
sendResponse(_platformOverride, 'linux');
|
sendResponse(_platformOverride, 'linux');
|
||||||
} else {
|
} else {
|
||||||
const scriptFile = path.join(os.tmpdir(), 'repertory_detect_linux.sh');
|
const scriptFile = path.join(os.tmpdir(), 'repertory_detect_linux.sh');
|
||||||
@@ -33,25 +33,29 @@ const addListeners = (ipcMain, {detectScript, saveUiSettings}) => {
|
|||||||
|
|
||||||
helpers
|
helpers
|
||||||
.executeScript(scriptFile)
|
.executeScript(scriptFile)
|
||||||
.then(data => {
|
.then((data) => {
|
||||||
let appPlatform = data.replace(/(\r\n|\n|\r)/gm, "");
|
let appPlatform = data.replace(/(\r\n|\n|\r)/gm, '');
|
||||||
if (appPlatform === 'unknown') {
|
if (appPlatform === 'unknown') {
|
||||||
helpers
|
helpers.downloadFile(
|
||||||
.downloadFile(Constants.LINUX_DETECT_SCRIPT_URL, scriptFile, null, err => {
|
Constants.LINUX_DETECT_SCRIPT_URL,
|
||||||
|
scriptFile,
|
||||||
|
null,
|
||||||
|
(err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
sendResponse(appPlatform, platform);
|
sendResponse(appPlatform, platform);
|
||||||
} else {
|
} else {
|
||||||
helpers
|
helpers
|
||||||
.executeScript(scriptFile)
|
.executeScript(scriptFile)
|
||||||
.then(data => {
|
.then((data) => {
|
||||||
appPlatform = data.replace(/(\r\n|\n|\r)/gm, "");
|
appPlatform = data.replace(/(\r\n|\n|\r)/gm, '');
|
||||||
sendResponse(appPlatform, platform);
|
sendResponse(appPlatform, platform);
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
sendResponse(appPlatform, platform);
|
sendResponse(appPlatform, platform);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
sendResponse(appPlatform, platform);
|
sendResponse(appPlatform, platform);
|
||||||
}
|
}
|
||||||
@@ -75,5 +79,5 @@ const addListeners = (ipcMain, {detectScript, saveUiSettings}) => {
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
getPlatformOverride,
|
getPlatformOverride,
|
||||||
setPlatformOverride,
|
setPlatformOverride,
|
||||||
addListeners
|
addListeners,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ const os = require('os');
|
|||||||
const path = require('path');
|
const path = require('path');
|
||||||
const unzip = require('unzipper');
|
const unzip = require('unzipper');
|
||||||
|
|
||||||
const addListeners = (ipcMain, {getCleanupReleases, standardIPCReply}) => {
|
const addListeners = (ipcMain, { getCleanupReleases, standardIPCReply }) => {
|
||||||
ipcMain.on(Constants.IPC_Check_Installed, (event, data) => {
|
ipcMain.on(Constants.IPC_Check_Installed, (event, data) => {
|
||||||
const destination = path.join(helpers.getDataDirectory(), data.Version);
|
const destination = path.join(helpers.getDataDirectory(), data.Version);
|
||||||
helpers
|
helpers
|
||||||
@@ -13,19 +13,26 @@ const addListeners = (ipcMain, {getCleanupReleases, standardIPCReply}) => {
|
|||||||
.then((dependencies) => {
|
.then((dependencies) => {
|
||||||
let exists = false;
|
let exists = false;
|
||||||
try {
|
try {
|
||||||
exists = fs.existsSync(destination) && fs.lstatSync(destination).isDirectory();
|
exists =
|
||||||
} catch (e) {
|
fs.existsSync(destination) &&
|
||||||
}
|
fs.lstatSync(destination).isDirectory();
|
||||||
|
} catch (e) {}
|
||||||
standardIPCReply(event, Constants.IPC_Check_Installed_Reply, {
|
standardIPCReply(event, Constants.IPC_Check_Installed_Reply, {
|
||||||
Dependencies: dependencies,
|
Dependencies: dependencies,
|
||||||
Exists: exists,
|
Exists: exists,
|
||||||
Version: data.Version,
|
Version: data.Version,
|
||||||
});
|
});
|
||||||
}).catch(error => {
|
})
|
||||||
standardIPCReply(event, Constants.IPC_Check_Installed_Reply, {
|
.catch((error) => {
|
||||||
|
standardIPCReply(
|
||||||
|
event,
|
||||||
|
Constants.IPC_Check_Installed_Reply,
|
||||||
|
{
|
||||||
Dependencies: [],
|
Dependencies: [],
|
||||||
Version: data.Version,
|
Version: data.Version,
|
||||||
}, error);
|
},
|
||||||
|
error
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -45,31 +52,42 @@ const addListeners = (ipcMain, {getCleanupReleases, standardIPCReply}) => {
|
|||||||
const stream = fs.createReadStream(data.Source);
|
const stream = fs.createReadStream(data.Source);
|
||||||
stream
|
stream
|
||||||
.pipe(unzip.Extract({ path: destination }))
|
.pipe(unzip.Extract({ path: destination }))
|
||||||
.on('error', error => {
|
.on('error', (error) => {
|
||||||
try {
|
try {
|
||||||
helpers.removeDirectoryRecursively(destination);
|
helpers.removeDirectoryRecursively(destination);
|
||||||
} catch (e) {
|
} catch (e) {}
|
||||||
}
|
|
||||||
stream.close();
|
stream.close();
|
||||||
standardIPCReply(event, Constants.IPC_Extract_Release_Complete, {
|
standardIPCReply(
|
||||||
|
event,
|
||||||
|
Constants.IPC_Extract_Release_Complete,
|
||||||
|
{
|
||||||
Source: data.Source,
|
Source: data.Source,
|
||||||
}, error);
|
},
|
||||||
|
error
|
||||||
|
);
|
||||||
})
|
})
|
||||||
.on('finish', () => {
|
.on('finish', () => {
|
||||||
stream.close();
|
stream.close();
|
||||||
if (os.platform() !== 'win32') {
|
if (os.platform() !== 'win32') {
|
||||||
helpers
|
helpers
|
||||||
.executeAndWait("chmod +x \"" + path.join(destination, 'repertory') + "\"")
|
.executeAndWait(
|
||||||
|
'chmod +x "' + path.join(destination, 'repertory') + '"'
|
||||||
|
)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
standardIPCReply(event, Constants.IPC_Extract_Release_Complete, {
|
standardIPCReply(event, Constants.IPC_Extract_Release_Complete, {
|
||||||
Source: data.Source,
|
Source: data.Source,
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch((error) => {
|
||||||
standardIPCReply(event, Constants.IPC_Extract_Release_Complete, {
|
standardIPCReply(
|
||||||
|
event,
|
||||||
|
Constants.IPC_Extract_Release_Complete,
|
||||||
|
{
|
||||||
Source: data.Source,
|
Source: data.Source,
|
||||||
}, error);
|
},
|
||||||
})
|
error
|
||||||
|
);
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
standardIPCReply(event, Constants.IPC_Extract_Release_Complete, {
|
standardIPCReply(event, Constants.IPC_Extract_Release_Complete, {
|
||||||
Source: data.Source,
|
Source: data.Source,
|
||||||
@@ -84,12 +102,10 @@ const addListeners = (ipcMain, {getCleanupReleases, standardIPCReply}) => {
|
|||||||
.then(() => {
|
.then(() => {
|
||||||
standardIPCReply(event, Constants.IPC_Test_Release_Reply, {});
|
standardIPCReply(event, Constants.IPC_Test_Release_Reply, {});
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch((error) => {
|
||||||
standardIPCReply(event, Constants.IPC_Test_Release_Reply, {}, error);
|
standardIPCReply(event, Constants.IPC_Test_Release_Reply, {}, error);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = { addListeners };
|
||||||
addListeners
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
const Constants = require('../../constants');
|
const Constants = require('../../constants');
|
||||||
const helpers = require('../../helpers');
|
const helpers = require('../../helpers');
|
||||||
|
|
||||||
const addListeners = (ipcMain, {standardIPCReply}) => {
|
const addListeners = (ipcMain, { standardIPCReply }) => {
|
||||||
ipcMain.on(Constants.IPC_Export_Skylinks, (event, data) => {
|
ipcMain.on(Constants.IPC_Export_Skylinks, (event, data) => {
|
||||||
helpers
|
helpers
|
||||||
.exportSkylinks(data.Version, data.Paths)
|
.exportSkylinks(data.Version, data.Paths)
|
||||||
.then(result => {
|
.then((result) => {
|
||||||
standardIPCReply(event, Constants.IPC_Export_Skylinks_Reply, {
|
standardIPCReply(event, Constants.IPC_Export_Skylinks_Reply, {
|
||||||
Result: result,
|
Result: result,
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch((error) => {
|
||||||
standardIPCReply(event, Constants.IPC_Export_Skylinks_Reply, {}, error);
|
standardIPCReply(event, Constants.IPC_Export_Skylinks_Reply, {}, error);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -18,30 +18,33 @@ const addListeners = (ipcMain, {standardIPCReply}) => {
|
|||||||
ipcMain.on(Constants.IPC_Grab_Skynet_Tree, (event, data) => {
|
ipcMain.on(Constants.IPC_Grab_Skynet_Tree, (event, data) => {
|
||||||
helpers
|
helpers
|
||||||
.grabSkynetFileTree(data.Version)
|
.grabSkynetFileTree(data.Version)
|
||||||
.then(result => {
|
.then((result) => {
|
||||||
standardIPCReply(event, Constants.IPC_Grab_Skynet_Tree_Reply, {
|
standardIPCReply(event, Constants.IPC_Grab_Skynet_Tree_Reply, {
|
||||||
Result: result,
|
Result: result,
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch((error) => {
|
||||||
standardIPCReply(event, Constants.IPC_Grab_Skynet_Tree_Reply, {}, error);
|
standardIPCReply(
|
||||||
|
event,
|
||||||
|
Constants.IPC_Grab_Skynet_Tree_Reply,
|
||||||
|
{},
|
||||||
|
error
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.on(Constants.IPC_Import_Skylinks, (event, data) => {
|
ipcMain.on(Constants.IPC_Import_Skylinks, (event, data) => {
|
||||||
helpers
|
helpers
|
||||||
.importSkylinks(data.Version, data.JsonArray)
|
.importSkylinks(data.Version, data.JsonArray)
|
||||||
.then(result => {
|
.then((result) => {
|
||||||
standardIPCReply(event, Constants.IPC_Import_Skylinks_Reply, {
|
standardIPCReply(event, Constants.IPC_Import_Skylinks_Reply, {
|
||||||
Result: result,
|
Result: result,
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch((error) => {
|
||||||
standardIPCReply(event, Constants.IPC_Import_Skylinks_Reply, {}, error);
|
standardIPCReply(event, Constants.IPC_Import_Skylinks_Reply, {}, error);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = { addListeners };
|
||||||
addListeners
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -3,18 +3,19 @@ const fs = require('fs');
|
|||||||
const helpers = require('../../helpers');
|
const helpers = require('../../helpers');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
|
||||||
const getDirectories = source => {
|
const getDirectories = (source) => {
|
||||||
try {
|
try {
|
||||||
return fs.readdirSync(source, {withFileTypes: true})
|
return fs
|
||||||
.filter(dirent => dirent.isDirectory())
|
.readdirSync(source, { withFileTypes: true })
|
||||||
.map(dirent => dirent.name);
|
.filter((dirent) => dirent.isDirectory())
|
||||||
|
.map((dirent) => dirent.name);
|
||||||
} catch {
|
} catch {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
const addListeners = ipcMain => {
|
const addListeners = (ipcMain) => {
|
||||||
ipcMain.on(Constants.IPC_Get_State, event => {
|
ipcMain.on(Constants.IPC_Get_State, (event) => {
|
||||||
helpers.mkDirByPathSync(helpers.getDataDirectory());
|
helpers.mkDirByPathSync(helpers.getDataDirectory());
|
||||||
|
|
||||||
let data = {};
|
let data = {};
|
||||||
@@ -32,14 +33,16 @@ const addListeners = ipcMain => {
|
|||||||
AutoMount: false,
|
AutoMount: false,
|
||||||
AutoRestart: true,
|
AutoRestart: true,
|
||||||
MountLocation: '',
|
MountLocation: '',
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data.RemoteMounts = data.RemoteMounts || [];
|
data.RemoteMounts = data.RemoteMounts || [];
|
||||||
data.S3Mounts = data.S3Mounts || [];
|
data.S3Mounts = data.S3Mounts || [];
|
||||||
|
|
||||||
const remoteItems = getDirectories(path.join(helpers.getRepertoryDirectory(), 'remote'));
|
const remoteItems = getDirectories(
|
||||||
|
path.join(helpers.getRepertoryDirectory(), 'remote')
|
||||||
|
);
|
||||||
for (const dir of remoteItems) {
|
for (const dir of remoteItems) {
|
||||||
const name = 'Remote' + dir.replace('_', ':');
|
const name = 'Remote' + dir.replace('_', ':');
|
||||||
if (!data.RemoteMounts || data.RemoteMounts.indexOf(name) === -1) {
|
if (!data.RemoteMounts || data.RemoteMounts.indexOf(name) === -1) {
|
||||||
@@ -52,7 +55,9 @@ const addListeners = ipcMain => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const s3Items = getDirectories(path.join(helpers.getRepertoryDirectory(), 's3'));
|
const s3Items = getDirectories(
|
||||||
|
path.join(helpers.getRepertoryDirectory(), 's3')
|
||||||
|
);
|
||||||
for (const dir of s3Items) {
|
for (const dir of s3Items) {
|
||||||
const name = 'S3' + dir;
|
const name = 'S3' + dir;
|
||||||
if (!data.S3Mounts || data.S3Mounts.indexOf(name) === -1) {
|
if (!data.S3Mounts || data.S3Mounts.indexOf(name) === -1) {
|
||||||
@@ -76,6 +81,4 @@ const addListeners = ipcMain => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = { addListeners };
|
||||||
addListeners
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ const Constants = require('../../constants');
|
|||||||
const os = require('os');
|
const os = require('os');
|
||||||
const helpers = require('../../helpers');
|
const helpers = require('../../helpers');
|
||||||
|
|
||||||
const addListeners = (ipcMain, {closeApplication}) => {
|
const addListeners = (ipcMain, { closeApplication }) => {
|
||||||
ipcMain.on(Constants.IPC_Reboot_System, () => {
|
ipcMain.on(Constants.IPC_Reboot_System, () => {
|
||||||
if (os.platform() === 'win32') {
|
if (os.platform() === 'win32') {
|
||||||
helpers.executeAsync('shutdown.exe', ['/r', '/t', '30']);
|
helpers.executeAsync('shutdown.exe', ['/r', '/t', '30']);
|
||||||
@@ -11,6 +11,4 @@ const addListeners = (ipcMain, {closeApplication}) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = { addListeners };
|
||||||
addListeners
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -3,7 +3,10 @@ const fs = require('fs');
|
|||||||
const helpers = require('../../helpers');
|
const helpers = require('../../helpers');
|
||||||
const os = require('os');
|
const os = require('os');
|
||||||
|
|
||||||
const addListeners = (ipcMain, {setIsInstalling, unmountAllDrives, standardIPCReply}) => {
|
const addListeners = (
|
||||||
|
ipcMain,
|
||||||
|
{ setIsInstalling, unmountAllDrives, standardIPCReply }
|
||||||
|
) => {
|
||||||
ipcMain.on(Constants.IPC_Install_Upgrade, (event, data) => {
|
ipcMain.on(Constants.IPC_Install_Upgrade, (event, data) => {
|
||||||
let allowSkipVerification = true;
|
let allowSkipVerification = true;
|
||||||
|
|
||||||
@@ -19,25 +22,34 @@ const addListeners = (ipcMain, {setIsInstalling, unmountAllDrives, standardIPCRe
|
|||||||
if (tempPub) {
|
if (tempPub) {
|
||||||
fs.unlinkSync(tempPub);
|
fs.unlinkSync(tempPub);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {}
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const errorHandler = err => {
|
const errorHandler = (err) => {
|
||||||
cleanupFiles();
|
cleanupFiles();
|
||||||
setIsInstalling(false);
|
setIsInstalling(false);
|
||||||
standardIPCReply(event, Constants.IPC_Install_Upgrade_Reply, {
|
standardIPCReply(
|
||||||
|
event,
|
||||||
|
Constants.IPC_Install_Upgrade_Reply,
|
||||||
|
{
|
||||||
AllowSkipVerification: allowSkipVerification,
|
AllowSkipVerification: allowSkipVerification,
|
||||||
Source: data.Source,
|
Source: data.Source,
|
||||||
}, err);
|
},
|
||||||
|
err
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO Enable verification in 1.0.4
|
// TODO Enable verification in 1.0.4
|
||||||
const hasSignature = false;//!data.SkipVerification && data.Signature && (data.Signature.length > 0);
|
const hasSignature = false; //! data.SkipVerification && data.Signature
|
||||||
const hasHash = false;//!data.SkipVerification && data.Sha256 && (data.Sha256.length > 0);
|
//! && (data.Signature.length > 0);
|
||||||
|
const hasHash = false; //! data.SkipVerification && data.Sha256 &&
|
||||||
|
//! (data.Sha256.length > 0);
|
||||||
if (hasSignature) {
|
if (hasSignature) {
|
||||||
try {
|
try {
|
||||||
const files = helpers.createSignatureFiles(data.Signature, Constants.DEV_PUBLIC_KEY);
|
const files = helpers.createSignatureFiles(
|
||||||
|
data.Signature,
|
||||||
|
Constants.DEV_PUBLIC_KEY
|
||||||
|
);
|
||||||
tempPub = files.PublicKeyFile;
|
tempPub = files.PublicKeyFile;
|
||||||
tempSig = files.SignatureFile;
|
tempSig = files.SignatureFile;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -72,9 +84,9 @@ const addListeners = (ipcMain, {setIsInstalling, unmountAllDrives, standardIPCRe
|
|||||||
.executeAsync(command, args)
|
.executeAsync(command, args)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
cleanupFiles();
|
cleanupFiles();
|
||||||
standardIPCReply(event, Constants.IPC_Install_Upgrade_Reply)
|
standardIPCReply(event, Constants.IPC_Install_Upgrade_Reply);
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch((error) => {
|
||||||
setIsInstalling(false);
|
setIsInstalling(false);
|
||||||
errorHandler(error);
|
errorHandler(error);
|
||||||
});
|
});
|
||||||
@@ -87,12 +99,14 @@ const addListeners = (ipcMain, {setIsInstalling, unmountAllDrives, standardIPCRe
|
|||||||
executeInstall();
|
executeInstall();
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
errorHandler(Error('Failed to verify installation package signature'));
|
errorHandler(
|
||||||
|
Error('Failed to verify installation package signature')
|
||||||
|
);
|
||||||
});
|
});
|
||||||
} else if (hasHash) {
|
} else if (hasHash) {
|
||||||
helpers
|
helpers
|
||||||
.verifyHash(data.Source, data.Sha256)
|
.verifyHash(data.Source, data.Sha256)
|
||||||
.then(()=> {
|
.then(() => {
|
||||||
executeInstall();
|
executeInstall();
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
@@ -111,6 +125,4 @@ const addListeners = (ipcMain, {setIsInstalling, unmountAllDrives, standardIPCRe
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = { addListeners };
|
||||||
addListeners
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ export function register(config) {
|
|||||||
function registerValidSW(swUrl, config) {
|
function registerValidSW(swUrl, config) {
|
||||||
navigator.serviceWorker
|
navigator.serviceWorker
|
||||||
.register(swUrl)
|
.register(swUrl)
|
||||||
.then(registration => {
|
.then((registration) => {
|
||||||
registration.onupdatefound = () => {
|
registration.onupdatefound = () => {
|
||||||
const installingWorker = registration.installing;
|
const installingWorker = registration.installing;
|
||||||
if (installingWorker == null) {
|
if (installingWorker == null) {
|
||||||
@@ -93,7 +93,7 @@ function registerValidSW(swUrl, config) {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch((error) => {
|
||||||
console.error('Error during service worker registration:', error);
|
console.error('Error during service worker registration:', error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -101,7 +101,7 @@ function registerValidSW(swUrl, config) {
|
|||||||
function checkValidServiceWorker(swUrl, config) {
|
function checkValidServiceWorker(swUrl, config) {
|
||||||
// Check if the service worker can be found. If it can't reload the page.
|
// Check if the service worker can be found. If it can't reload the page.
|
||||||
fetch(swUrl)
|
fetch(swUrl)
|
||||||
.then(response => {
|
.then((response) => {
|
||||||
// Ensure service worker exists, and that we really are getting a JS file.
|
// Ensure service worker exists, and that we really are getting a JS file.
|
||||||
const contentType = response.headers.get('content-type');
|
const contentType = response.headers.get('content-type');
|
||||||
if (
|
if (
|
||||||
@@ -109,7 +109,7 @@ function checkValidServiceWorker(swUrl, config) {
|
|||||||
(contentType != null && contentType.indexOf('javascript') === -1)
|
(contentType != null && contentType.indexOf('javascript') === -1)
|
||||||
) {
|
) {
|
||||||
// No service worker found. Probably a different app. Reload the page.
|
// No service worker found. Probably a different app. Reload the page.
|
||||||
navigator.serviceWorker.ready.then(registration => {
|
navigator.serviceWorker.ready.then((registration) => {
|
||||||
registration.unregister().then(() => {
|
registration.unregister().then(() => {
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
});
|
});
|
||||||
@@ -128,7 +128,7 @@ function checkValidServiceWorker(swUrl, config) {
|
|||||||
|
|
||||||
export function unregister() {
|
export function unregister() {
|
||||||
if ('serviceWorker' in navigator) {
|
if ('serviceWorker' in navigator) {
|
||||||
navigator.serviceWorker.ready.then(registration => {
|
navigator.serviceWorker.ready.then((registration) => {
|
||||||
registration.unregister();
|
registration.unregister();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
106
src/utils.js
106
src/utils.js
@@ -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 ? (<Modal {...modalProps}>{jsx}</Modal>) : 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];
|
|
||||||
};
|
|
||||||
|
|
||||||
134
src/utils.jsx
Normal file
134
src/utils.jsx
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import Modal from './components/UI/Modal/Modal';
|
||||||
|
import * as Constants from './constants';
|
||||||
|
|
||||||
|
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 ? <Modal {...modalProps}>{jsx}</Modal> : 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
|
||||||
|
];
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user