diff --git a/src/components/InfoDetails/InfoDetails.js b/src/components/InfoDetails/InfoDetails.js
index 0678c2a..aaf52fc 100644
--- a/src/components/InfoDetails/InfoDetails.js
+++ b/src/components/InfoDetails/InfoDetails.js
@@ -20,16 +20,46 @@ const mapDispatchToProps = dispatch => {
export default connect(mapStateToProps, mapDispatchToProps)(props => {
let msg = props.InfoMessage.message;
const classes = ['InfoDetailsContent'];
- if (props.InfoMessage.message.startsWith('!alternate!')) {
- classes.push('Alternate');
- msg = props.InfoMessage.message.substr('!alternate!'.length)
+
+ let changed = true;
+ let copyable = false;
+ while (changed) {
+ changed = false;
+ if (msg.startsWith('!alternate!')) {
+ classes.push('Alternate');
+ msg = msg.substr('!alternate!'.length);
+ changed = true;
+ }
+ if (msg.startsWith('!copyable!')) {
+ classes.push('Copyable');
+ msg = msg.substr('!copyable!'.length);
+ copyable = changed = true;
+ }
}
+ const scrollToTop = textArea => {
+ if (!textArea.firstClick) {
+ textArea.firstClick = true;
+ textArea.scrollTop = 0;
+ textArea.setSelectionRange(0, 0);
+ }
+ };
+
return (
{props.InfoMessage.title}
-
{msg}
+ {
+ copyable ? (
+
diff --git a/src/containers/SkynetExport/SkynetExport.js b/src/containers/SkynetExport/SkynetExport.js
index db85ba8..f86a423 100644
--- a/src/containers/SkynetExport/SkynetExport.js
+++ b/src/containers/SkynetExport/SkynetExport.js
@@ -4,7 +4,7 @@ import CheckboxTree from 'react-checkbox-tree';
import {connect} from 'react-redux';
import IPCContainer from '../IPCContainer/IPCContainer';
import {notifyApplicationBusy} from '../../redux/actions/common_actions';
-import {notifyError} from '../../redux/actions/error_actions';
+import {notifyError, notifyInfo} from '../../redux/actions/error_actions';
import Box from '../../components/UI/Box/Box';
import {displaySkynetExport} from '../../redux/actions/skynet_actions';
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
@@ -29,6 +29,7 @@ const mapDispatchToProps = dispatch => {
displaySkynetExport: display => dispatch(displaySkynetExport(display)),
notifyApplicationBusy: busy => dispatch(notifyApplicationBusy(busy, true)),
notifyError: msg => dispatch(notifyError(msg)),
+ notifyInfo: (title, msg) => dispatch(notifyInfo(title, msg)),
}
};
@@ -65,7 +66,7 @@ export default connect(mapStateToProps, mapDispatchToProps)(class extends IPCCon
const treeItem = {
label: item.name,
path: item.path,
- value: item.name === '/' ? 0 : JSON.stringify(item),
+ value: item.name === '/' ? 0 : item.path ? item.path : JSON.stringify(item),
};
if (item.directory) {
@@ -80,7 +81,11 @@ export default connect(mapStateToProps, mapDispatchToProps)(class extends IPCCon
handleNavigation = () => {
if (this.state.second_stage) {
-
+ this.props.notifyApplicationBusy(true);
+ this.sendRequest(Constants.IPC_Export_Skylinks, {
+ Version: this.props.version,
+ Paths: this.state.checked,
+ });
} else {
if (this.state.checked.length === 0) {
this.props.notifyError('No files have been checked');
@@ -93,6 +98,21 @@ export default connect(mapStateToProps, mapDispatchToProps)(class extends IPCCon
}
onExportSkylinksReply = (_, arg) => {
+ this.props.notifyApplicationBusy(false);
+ if (arg.data.Success) {
+ this.setState({
+ checked: [],
+ clicked: {},
+ expanded: [],
+ nodes: [],
+ 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});
+ });
+ } else {
+ this.props.notifyError(arg.data.Error);
+ }
}
onGrabSkynetTreeReply = (_, arg) => {
@@ -133,47 +153,59 @@ export default connect(mapStateToProps, mapDispatchToProps)(class extends IPCCon
onClick={() => this.props.displaySkynetExport(false)}
style={{cursor: 'pointer'}}>X
-
{'Export Files'}
+ {this.state.second_stage ? 'Verify Exports' : 'Export Files'}
{
- this.state.second_stage ? (
) : (
-
,
- uncheck:
{
+ return (
+
+ );
+ })
+ : (
+ ,
- halfCheck: ,
- expandClose: ,
- expandOpen: ,
- expandAll: ,
- collapseAll: ,
+ expandOpen: ,
+ expandAll: ,
- parentClose: ,
- parentOpen: ,
- leaf:
- }}
- nodes={this.state.nodes}
- onClick={clicked => this.setState({clicked})}
- onCheck={checked => this.setState({checked})}
- onExpand={expanded => this.setState({expanded})}/>
- )
+ collapseAll: ,
+ parentClose: ,
+ parentOpen: ,
+ leaf:
+ }}
+ nodes={this.state.nodes}
+ onClick={clicked => this.setState({clicked})}
+ onCheck={checked => this.setState({checked})}
+ onExpand={expanded => this.setState({expanded})}/>
+ )
}
diff --git a/src/helpers.js b/src/helpers.js
index 817d6d9..b8e655b 100644
--- a/src/helpers.js
+++ b/src/helpers.js
@@ -597,6 +597,48 @@ module.exports.executeMount = (version, provider, remote, location, exitCallback
module.exports.exportAllSkylinks = _exportAllSkylinks;
+module.exports.exportSkylinks = (version, paths) => {
+ 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('-ex');
+ args.push(paths.join(','));
+
+ 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();
+ });
+};
+
module.exports.getConfig = (version, provider, remote) => {
return new Promise((resolve, reject) => {
const repertoryExec = _getRepertoryExec(version);
diff --git a/src/renderer/ipc/SkynetIPC.js b/src/renderer/ipc/SkynetIPC.js
index 7701a1c..f8e115a 100644
--- a/src/renderer/ipc/SkynetIPC.js
+++ b/src/renderer/ipc/SkynetIPC.js
@@ -2,16 +2,16 @@ const Constants = require('../../constants');
const helpers = require('../../helpers');
const addListeners = (ipcMain, {standardIPCReply}) => {
- ipcMain.on(Constants.IPC_Import_Skylinks, (event, data) => {
+ ipcMain.on(Constants.IPC_Export_Skylinks, (event, data) => {
helpers
- .importSkylinks(data.Version, data.JsonArray)
+ .exportSkylinks(data.Version, data.Paths)
.then(result => {
- standardIPCReply(event, Constants.IPC_Import_Skylinks_Reply, {
+ standardIPCReply(event, Constants.IPC_Export_Skylinks_Reply, {
Result: result,
});
})
.catch(error => {
- standardIPCReply(event, Constants.IPC_Import_Skylinks_Reply, {}, error);
+ standardIPCReply(event, Constants.IPC_Export_Skylinks_Reply, {}, error);
});
});
@@ -27,6 +27,19 @@ const addListeners = (ipcMain, {standardIPCReply}) => {
standardIPCReply(event, Constants.IPC_Grab_Skynet_Tree_Reply, {}, error);
});
});
+
+ 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 = {