diff --git a/public/electron.js b/public/electron.js index 3d6f029..fa5279b 100644 --- a/public/electron.js +++ b/public/electron.js @@ -35,6 +35,7 @@ const FilesystemIPC = require('../src/renderer/ipc/FilesystemIPC'); const MountsIPC = require('../src/renderer/ipc/MountsIPC'); const PlatformIPC = require('../src/renderer/ipc/PlatformIPC'); const ReleaseIPC = require('../src/renderer/ipc/ReleaseIPC'); +const SkynetIPC = require('../src/renderer/ipc/SkynetIPC'); const StateIPC = require('../src/renderer/ipc/StateIPC'); const SystemIPC = require('../src/renderer/ipc/SystemIPC'); const UpgradeIPC = require('../src/renderer/ipc/UpgradeIPC'); @@ -331,6 +332,7 @@ FilesystemIPC.addListeners(ipcMain, AppFunctions); MountsIPC.addListeners(ipcMain, AppFunctions); PlatformIPC.addListeners(ipcMain, AppFunctions); ReleaseIPC.addListeners(ipcMain, AppFunctions); +SkynetIPC.addListeners(ipcMain, AppFunctions); StateIPC.addListeners(ipcMain, AppFunctions); SystemIPC.addListeners(ipcMain, AppFunctions); UpgradeIPC.addListeners(ipcMain, AppFunctions); diff --git a/src/App.js b/src/App.js index ab9bae1..f225109 100644 --- a/src/App.js +++ b/src/App.js @@ -174,7 +174,7 @@ class App extends IPCContainer { const selectAppPlatformDisplay = createModalConditionally(this.props.DisplaySelectAppPlatform, ); const upgradeDisplay = createModalConditionally(showUpgrade, ); - const importDisplay = createModalConditionally(showSkynetImport, ); + const importDisplay = createModalConditionally(showSkynetImport, ); let mainContent = []; if (this.props.DisplaySelectAppPlatform || !this.props.AppReady) { diff --git a/src/constants.js b/src/constants.js index bc98f67..70a24a8 100644 --- a/src/constants.js +++ b/src/constants.js @@ -114,6 +114,9 @@ exports.IPC_Get_Platform_Reply = 'get_platform_reply'; exports.IPC_Get_State = 'get_state'; exports.IPC_Get_State_Reply = 'get_state_reply'; +exports.IPC_Import_Skylinks = 'import_skylinks'; +exports.IPC_Import_Skylinks_Reply = 'import_skylinks_reply'; + exports.IPC_Install_Dependency = 'install_dependency'; exports.IPC_Install_Dependency_Reply = 'install_dependency_reply'; diff --git a/src/containers/MountItems/MountItem/MountItem.js b/src/containers/MountItems/MountItem/MountItem.js index 51b7443..3f2d172 100644 --- a/src/containers/MountItems/MountItem/MountItem.js +++ b/src/containers/MountItems/MountItem/MountItem.js @@ -182,7 +182,7 @@ export default connect(mapStateToProps, mapDispatchToProps)(props => { rowSpan={5} text={props.remote ? props.provider.substr(6) : props.provider} type={'Heading2'}/> - {(props.provider === 'Skynet') ? ( + {((props.provider === 'Skynet') && (props.MState.Mounted)) ? ( props.displaySkynetExport(true) : e => {e.preventDefault();}} @@ -191,7 +191,7 @@ export default connect(mapStateToProps, mapDispatchToProps)(props => { Export ) : null} - {(props.provider === 'Skynet') ? ( + {((props.provider === 'Skynet') && (props.MState.Mounted)) ? ( props.displaySkynetImport(true) : e => {e.preventDefault();}} diff --git a/src/containers/SkynetImport/SkynetImport.js b/src/containers/SkynetImport/SkynetImport.js index de11dd1..3d7ebfb 100644 --- a/src/containers/SkynetImport/SkynetImport.js +++ b/src/containers/SkynetImport/SkynetImport.js @@ -4,7 +4,9 @@ import {connect} from 'react-redux'; import './SkynetImport.css' import Box from '../../components/UI/Box/Box'; import Button from '../../components/UI/Button/Button'; -import {displaySkynetImport} from '../../redux/actions/skynet_actions'; +import { + displaySkynetImport, importSkylinks +} from '../../redux/actions/skynet_actions'; import { notifyError, notifyInfo @@ -15,6 +17,7 @@ const mapDispatchToProps = dispatch => { displaySkynetImport: display => dispatch(displaySkynetImport(display)), notifyInfo: msg => dispatch(notifyInfo('Import Syntax', msg)), notifyError: msg => dispatch(notifyError(msg)), + importSkylinks: (version, jsonArray) => dispatch(importSkylinks(version, jsonArray)), } }; @@ -55,12 +58,12 @@ export default connect(null, mapDispatchToProps)(class extends Component { processNext = () => { const items = this.state.import_list.split('\n'); - let jsonItems = []; + let importsArray = []; try { for (let item of items) { item = item.trim(); if (item.startsWith('[')) { - jsonItems = JSON.parse(this.state.import_list.trim()); + importsArray = JSON.parse(this.state.import_list.trim()); break; } else if (item.indexOf('=') >= 0) { const parts = item.split(',') @@ -83,19 +86,19 @@ export default connect(null, mapDispatchToProps)(class extends Component { if (!importItem.skylink) { throw new Error('Invalid syntax for import: directory="",skylink="",token=""'); } - jsonItems.push(importItem); + importsArray.push(importItem); } else if (item.length > 0) { - jsonItems.push({ + importsArray.push({ directory: '/', skylink: item, }); } } - if (jsonItems.length === 0) { + if (importsArray.length === 0) { throw new Error('Nothing to import'); } - console.log(jsonItems); + this.props.importSkylinks(this.props.version, importsArray); } catch (e) { this.props.notifyError(e); } diff --git a/src/helpers.js b/src/helpers.js index 6067944..4d0c4f6 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -683,6 +683,48 @@ module.exports.getMissingDependencies = dependencies => { }); }; +module.exports.importSkylinks = (version, jsonArray) => { + return new Promise((resolve, reject) => { + const repertoryExec = _getRepertoryExec(version); + const processOptions = { + cwd: repertoryExec.working, + detached: true, + shell: false, + windowsHide: true, + }; + + const args = _getDefaultRepertoryArgs('Skynet'); + args.push('-ij'); + args.push(JSON.stringify(jsonArray)); + + let result = ''; + const process = new spawn(repertoryExec.cmd, args, processOptions); + + process.on('error', (err) => { + reject(err); + }); + + process.stdout.on('data', (d)=> { + result += d; + }); + + process.stderr.on('data', (d)=> { + result += d; + }); + + process.on('exit', code => { + if (code === 0) { + result = result.substr(result.indexOf('{')); + resolve(JSON.parse(result)); + } else { + reject(new Error('Failed to import: ' + code + ':' + result)); + } + }); + + process.unref(); + }); +}; + //https://stackoverflow.com/questions/31645738/how-to-create-full-path-with-nodes-fs-mkdirsync module.exports.mkDirByPathSync = (targetDir, { isRelativeToScript = false } = {}) => { const sep = path.sep; diff --git a/src/redux/actions/skynet_actions.js b/src/redux/actions/skynet_actions.js index efeac8b..c3b22e8 100644 --- a/src/redux/actions/skynet_actions.js +++ b/src/redux/actions/skynet_actions.js @@ -1,5 +1,27 @@ import {createAction} from '@reduxjs/toolkit'; - +import {getIPCRenderer} from '../../utils'; +import * as Constants from '../../constants'; +import {notifyError} from './error_actions'; export const displaySkynetExport = createAction('skynet/displaySkynetExport'); export const displaySkynetImport = createAction('skynet/displaySkynetImport'); + +export const importSkylinks = (version, jsonArray) => { + return dispatch => { + const ipcRenderer = getIPCRenderer(); + if (ipcRenderer) { + ipcRenderer.once(Constants.IPC_Import_Skylinks_Reply, (_, arg) => { + if (arg.data.Success) { + + } else { + dispatch(notifyError(arg.data.Error)); + } + }); + + ipcRenderer.send(Constants.IPC_Import_Skylinks, { + Version: version, + JsonArray: jsonArray, + }); + } + }; +}; diff --git a/src/renderer/ipc/SkynetIPC.js b/src/renderer/ipc/SkynetIPC.js new file mode 100644 index 0000000..fd3d1bf --- /dev/null +++ b/src/renderer/ipc/SkynetIPC.js @@ -0,0 +1,21 @@ +const Constants = require('../../constants'); +const helpers = require('../../helpers'); + +const addListeners = (ipcMain, {standardIPCReply}) => { + ipcMain.on(Constants.IPC_Import_Skylinks, (event, data) => { + helpers + .importSkylinks(data.Version, data.JsonArray) + .then(result => { + standardIPCReply(event, Constants.IPC_Import_Skylinks_Reply, { + Result: result, + }); + }) + .catch(error => { + standardIPCReply(event, Constants.IPC_Import_Skylinks_Reply, {}, error); + }); + }); +}; + +module.exports = { + addListeners +};