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; +};