diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0c993bc..f509f72 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,7 @@
## 1.3.4
- \#55: Enable 'Activate' release instead of 'Install' in notification pop-up
+- Ability to export Skylink's to json file
## 1.3.3
diff --git a/src/components/InfoDetails/InfoDetails.css b/src/components/InfoDetails/InfoDetails.css
index 2dc812e..c4ec0ef 100644
--- a/src/components/InfoDetails/InfoDetails.css
+++ b/src/components/InfoDetails/InfoDetails.css
@@ -17,3 +17,9 @@
white-space: pre;
hyphens: none;
}
+
+.InfoButtonOwner {
+ display: flex;
+ flex-direction: row;
+ justify-content: flex-end;
+}
diff --git a/src/components/InfoDetails/InfoDetails.js b/src/components/InfoDetails/InfoDetails.js
index 980a427..da94625 100644
--- a/src/components/InfoDetails/InfoDetails.js
+++ b/src/components/InfoDetails/InfoDetails.js
@@ -1,9 +1,10 @@
import React from 'react';
-import { dismissInfo } from '../../redux/actions/error_actions';
+import { dismissInfo, notifyError } from '../../redux/actions/error_actions';
import { connect } from 'react-redux';
import Box from '../UI/Box/Box';
import Button from '../UI/Button/Button';
import './InfoDetails.css';
+import { promptLocationAndSaveFile } from '../../utils';
const mapStateToProps = (state) => {
return {
@@ -14,6 +15,7 @@ const mapStateToProps = (state) => {
const mapDispatchToProps = (dispatch) => {
return {
+ notifyError: (msg) => dispatch(notifyError(msg)),
dismissInfo: () => dispatch(dismissInfo()),
};
};
@@ -65,7 +67,30 @@ export default connect(
{msg}
)}
-
+ {props.InfoMessage.saveToFile ? (
+
+
+
+
+ ) : (
+
+ )}
);
});
diff --git a/src/constants.js b/src/constants.js
index 397c3ba..4db3261 100644
--- a/src/constants.js
+++ b/src/constants.js
@@ -110,6 +110,8 @@ exports.INSTALL_TYPES = {
exports.IPC_Browse_Directory = 'browse_directory';
+exports.IPC_Browse_File = 'browse_file';
+
exports.IPC_Check_Daemon_Version = 'check_daemon_version';
exports.IPC_Check_Daemon_Version_Reply = 'check_daemon_version_reply';
@@ -179,6 +181,7 @@ exports.IPC_Remove_Mount_Reply = 'remove_mount_reply';
exports.IPC_Reboot_System = 'reboot_system';
+exports.IPC_Save_File = 'save_file';
exports.IPC_Save_State = 'save_state';
exports.IPC_Set_Pinned = 'set_pinned';
diff --git a/src/containers/SkynetExport/SkynetExport.js b/src/containers/SkynetExport/SkynetExport.js
index 33214f2..8512b97 100644
--- a/src/containers/SkynetExport/SkynetExport.js
+++ b/src/containers/SkynetExport/SkynetExport.js
@@ -36,7 +36,8 @@ const mapDispatchToProps = (dispatch) => {
notifyApplicationBusy: (busy) =>
dispatch(notifyApplicationBusy(busy, true)),
notifyError: (msg) => dispatch(notifyError(msg)),
- notifyInfo: (title, msg) => dispatch(notifyInfo(title, msg)),
+ notifyInfo: (title, msg) =>
+ dispatch(notifyInfo(title, msg, true, 'skynet_export', 'json')),
};
};
diff --git a/src/redux/actions/error_actions.js b/src/redux/actions/error_actions.js
index 3aa28f7..3ff7316 100644
--- a/src/redux/actions/error_actions.js
+++ b/src/redux/actions/error_actions.js
@@ -47,11 +47,11 @@ export const notifyError = (msg, critical, callback) => {
};
};
-export const notifyInfo = (title, msg) => {
+export const notifyInfo = (title, msg, saveToFile, fileName, extension) => {
return (dispatch) => {
title = title ? title.toString() : 'Information';
msg = msg ? msg.toString() : '';
- dispatch(setInfo(title, msg));
+ dispatch(setInfo(title, msg, saveToFile, fileName, extension));
};
};
@@ -61,6 +61,9 @@ export const setErrorInfo = (msg, critical) => {
};
export const SET_INFO = 'error/setInfo';
-export const setInfo = (title, msg) => {
- return { type: SET_INFO, payload: { title, msg } };
+export const setInfo = (title, msg, saveToFile, fileName, extension) => {
+ return {
+ type: SET_INFO,
+ payload: { title, msg, saveToFile, fileName, extension },
+ };
};
diff --git a/src/redux/reducers/error_reducer.js b/src/redux/reducers/error_reducer.js
index e64f198..180ea64 100644
--- a/src/redux/reducers/error_reducer.js
+++ b/src/redux/reducers/error_reducer.js
@@ -44,7 +44,13 @@ export const errorReducer = createReducer(
},
[SET_INFO]: (state, action) => {
const infoStack = [
- { title: action.payload.title, message: action.payload.msg },
+ {
+ title: action.payload.title,
+ message: action.payload.msg,
+ saveToFile: action.payload.saveToFile,
+ fileName: action.payload.fileName,
+ extension: action.payload.extension,
+ },
...state.InfoStack,
];
return { ...state, DisplayInfo: true, InfoStack: infoStack };
diff --git a/src/renderer/ipc/FilesystemIPC.js b/src/renderer/ipc/FilesystemIPC.js
index bc16108..ff5b1b0 100644
--- a/src/renderer/ipc/FilesystemIPC.js
+++ b/src/renderer/ipc/FilesystemIPC.js
@@ -20,13 +20,40 @@ const addListeners = (ipcMain, { getMainWindow, dialog }) => {
);
});
- ipcMain.on(Constants.IPC_Delete_File, (event, data) => {
+ ipcMain.on(Constants.IPC_Delete_File, (_, data) => {
try {
if (fs.existsSync(data.FilePath)) {
fs.unlinkSync(data.FilePath);
}
} catch (e) {}
});
+
+ ipcMain.on(Constants.IPC_Browse_File + '_sync', (event, data) => {
+ dialog.showSaveDialog(
+ getMainWindow(),
+ {
+ defaultPath: data.Location,
+ properties: ['createDirectory', 'showOverwriteConfirmation'],
+ title: data.Title,
+ },
+ (filePath) => {
+ if (filePath && filePath.length > 0) {
+ event.returnValue = filePath;
+ } else {
+ event.returnValue = '';
+ }
+ }
+ );
+ });
+
+ ipcMain.on(Constants.IPC_Save_File + '_sync', (event, data) => {
+ try {
+ fs.writeFileSync(data.Location, data.Data, 'utf8');
+ event.returnValue = { success: true };
+ } catch (err) {
+ event.returnValue = { success: false, error: err.toString() };
+ }
+ });
};
module.exports = { addListeners };
diff --git a/src/renderer/ipc/StateIPC.js b/src/renderer/ipc/StateIPC.js
index cb6a5c7..ef26170 100644
--- a/src/renderer/ipc/StateIPC.js
+++ b/src/renderer/ipc/StateIPC.js
@@ -74,7 +74,7 @@ const addListeners = (ipcMain) => {
});
});
- ipcMain.on(Constants.IPC_Save_State, (event, data) => {
+ ipcMain.on(Constants.IPC_Save_State, (_, data) => {
helpers.mkDirByPathSync(helpers.getDataDirectory());
const configFile = path.join(helpers.getDataDirectory(), 'settings.json');
fs.writeFileSync(configFile, JSON.stringify(data.State), 'utf8');
diff --git a/src/utils.jsx b/src/utils.jsx
index a0fd161..59c905c 100644
--- a/src/utils.jsx
+++ b/src/utils.jsx
@@ -132,3 +132,17 @@ export const getSelectedVersionFromState = (state) => {
state.relver.Version
];
};
+
+export const promptLocationAndSaveFile = (fileName, data, notifyError) => {
+ const location = ipcRenderer.sendSync(Constants.IPC_Browse_File + '_sync', {Location: fileName, Title: 'Save File'});
+ if (location && location.length > 0) {
+ const ret = ipcRenderer.sendSync(Constants.IPC_Save_File + '_sync', {Location: location, Title: 'Save File', Data: data});
+ if (ret.success) {
+ return true;
+ }
+
+ notifyError(ret.error);
+ }
+
+ return false;
+};