From 38bb2855b6447685dec79269cc853a63682a7de5 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Tue, 16 Jun 2020 11:26:09 -0500 Subject: [PATCH] Partial import processing --- src/App.js | 8 +- .../ApplicationBusy/ApplicationBusy.js | 21 +++ src/components/UI/Loading/Loading.js | 4 +- src/components/UI/Modal/Modal.css | 4 + src/components/UI/Modal/Modal.js | 4 + src/containers/SkynetImport/Format/Format.css | 0 src/containers/SkynetImport/Format/Format.js | 0 src/containers/SkynetImport/SkynetImport.js | 170 ++++++++++++------ src/redux/actions/common_actions.js | 11 ++ src/redux/actions/skynet_actions.js | 23 --- src/redux/reducers/common_reducer.js | 10 ++ src/utils.js | 4 +- 12 files changed, 172 insertions(+), 87 deletions(-) create mode 100644 src/components/ApplicationBusy/ApplicationBusy.js delete mode 100644 src/containers/SkynetImport/Format/Format.css delete mode 100644 src/containers/SkynetImport/Format/Format.js diff --git a/src/App.js b/src/App.js index f225109..59037f4 100644 --- a/src/App.js +++ b/src/App.js @@ -35,6 +35,7 @@ import YesNo from './components/YesNo/YesNo'; import {createModalConditionally} from './utils'; import SkynetImport from './containers/SkynetImport/SkynetImport'; import {displaySkynetImport} from './redux/actions/skynet_actions'; +import ApplicationBusy from './components/ApplicationBusy/ApplicationBusy'; const Constants = require('./constants'); const Scheduler = require('node-schedule'); @@ -175,6 +176,8 @@ class App extends IPCContainer { ); const upgradeDisplay = createModalConditionally(showUpgrade, ); const importDisplay = createModalConditionally(showSkynetImport, ); + const appBusyDisplay = createModalConditionally(this.props.AppBusy, + , false, true, this.props.AppBusyTransparent); let mainContent = []; if (this.props.DisplaySelectAppPlatform || !this.props.AppReady) { @@ -206,7 +209,7 @@ class App extends IPCContainer { )); } else if (selectedVersion !== 'unavailable') { mainContent.push(( - @@ -252,6 +255,7 @@ class App extends IPCContainer { {confirmDisplay} {downloadDisplay} {rebootDisplay} + {appBusyDisplay} {errorDisplay} ); @@ -263,6 +267,8 @@ const mapStateToProps = state => { AllowDownload: state.download.AllowDownload, AllowMount: state.common.AllowMount, AppPlatform: state.common.AppPlatform, + AppBusy: state.common.AppBusy, + AppBusyTransparent: state.common.AppBusyTransparent, AppReady: state.common.AppReady, DismissDependencies: state.install.DismissDependencies, DisplayConfiguration: state.mounts.DisplayConfiguration, diff --git a/src/components/ApplicationBusy/ApplicationBusy.js b/src/components/ApplicationBusy/ApplicationBusy.js new file mode 100644 index 0000000..dc28d08 --- /dev/null +++ b/src/components/ApplicationBusy/ApplicationBusy.js @@ -0,0 +1,21 @@ +import React from 'react'; +import Box from '../UI/Box/Box'; +import Loader from 'react-loader-spinner'; +import Text from '../UI/Text/Text'; + +export default ({title}) => { + return ( + + +
+ +
+
+ ); +} diff --git a/src/components/UI/Loading/Loading.js b/src/components/UI/Loading/Loading.js index 83c68d1..b627439 100644 --- a/src/components/UI/Loading/Loading.js +++ b/src/components/UI/Loading/Loading.js @@ -2,7 +2,7 @@ import React from 'react'; import './Loading.css' import Loader from 'react-loader-spinner'; -export default props => { +export default () => { return (
@@ -13,4 +13,4 @@ export default props => { type='ThreeDots'/>
); -}; \ No newline at end of file +}; diff --git a/src/components/UI/Modal/Modal.css b/src/components/UI/Modal/Modal.css index 8f5a498..c84ae71 100644 --- a/src/components/UI/Modal/Modal.css +++ b/src/components/UI/Modal/Modal.css @@ -8,6 +8,10 @@ z-index: 2000; } +.Modal.Transparent { + background-color: rgba(0, 0, 0, 0); +} + .ModalContent { position: fixed; width: auto; diff --git a/src/components/UI/Modal/Modal.js b/src/components/UI/Modal/Modal.js index 24646d8..5065aac 100644 --- a/src/components/UI/Modal/Modal.js +++ b/src/components/UI/Modal/Modal.js @@ -13,6 +13,10 @@ export default props => { contentStyles.push('ModalCritical'); } + if (props.transparent) { + modalStyles.push('Transparent'); + } + return (
{ + return { + AppBusy: state.common.AppBusy, + }; +}; const mapDispatchToProps = dispatch => { return { displaySkynetImport: display => dispatch(displaySkynetImport(display)), - notifyInfo: msg => dispatch(notifyInfo('Import Syntax', msg)), + notifyApplicationBusy: busy => dispatch(notifyApplicationBusy(busy, true)), notifyError: msg => dispatch(notifyError(msg)), - importSkylinks: (version, jsonArray) => dispatch(importSkylinks(version, jsonArray)), + notifyInfo: msg => dispatch(notifyInfo('Import Syntax', msg)), } }; -export default connect(null, mapDispatchToProps)(class extends Component { +export default connect(mapStateToProps, mapDispatchToProps)(class extends IPCContainer { state = { - import_list: '', + import_text: '', + imports_array: [], + second_stage: false, }; + componentDidMount() { + this.setRequestHandler(Constants.IPC_Import_Skylinks_Reply, this.onImportSkylinksReply); + } + + componentWillUnmount() { + super.componentWillUnmount(); + } + displaySyntax = () => { const msg = '!alternate!To import Skylinks into the root directory, list each Skylink on a new line:\n' + ' AACeCiD6WQG6DzDcCdIu3cFPSxMUMoQPx46NYSyijNMKUA\n' + ' AACyjmDGoHqY7mTaxi-rkpnKUJGZK1B4UhrF74Nv6tY6Cg\n' + '\n' + - 'To import Skylinks to new or existing directories, use the following syntax:\n' + + 'To import Skylinks into new or existing directories, use the following syntax:\n' + ' directory="/my/sub/dir",skylink="AACeCiD6WQG6DzDcCdIu3cFPSxMUMoQPx46NYSyijNMKUA"\n' + ' directory="/my/sub/dir2",skylink="AACyjmDGoHqY7mTaxi-rkpnKUJGZK1B4UhrF74Nv6tY6Cg"\n' + '\n' + @@ -40,7 +57,7 @@ export default connect(null, mapDispatchToProps)(class extends Component { ' directory="/my/sub/dir",skylink="AACeCiD6WQG6DzDcCdIu3cFPSxMUMoQPx46NYSyijNMKUA",token="My Password"\n' + ' directory="/my/sub/dir",skylink="AACyjmDGoHqY7mTaxi-rkpnKUJGZK1B4UhrF74Nv6tY6Cg",token="My Password"\n' + '\n' + - 'To import JSON Skylinks, use the following syntax:\n' + + 'To import Skylinks using JSON syntax:\n' + ' [\n' + ' {\n' + ' "directory": "/",\n' + @@ -56,56 +73,87 @@ export default connect(null, mapDispatchToProps)(class extends Component { this.props.notifyInfo(msg) } + onImportSkylinksReply = (_, arg) => { + this.props.notifyApplicationBusy(false); + if (arg.data.Success) { + console.log(arg.data.Result); + this.setState({ + import_text: '', + imports_array: [], + second_stage: false, + }); + } else { + this.props.notifyError(arg.data.Error); + } + }; + processNext = () => { - const items = this.state.import_list.split('\n'); - let importsArray = []; - try { - for (let item of items) { - item = item.trim(); - if (item.startsWith('[')) { - importsArray = JSON.parse(this.state.import_list.trim()); - break; - } else if (item.indexOf('=') >= 0) { - const parts = item.split(',') - let importItem = { - directory: '/', - skylink: '', - token: '', - }; - for (let part of parts) { - part = part.trim(); - const pair = part.split('='); - if (pair.length !== 2) { + if (this.state.second_stage) { + try { + this.props.notifyApplicationBusy(true); + this.sendRequest(Constants.IPC_Import_Skylinks, { + Version: this.props.version, + JsonArray: this.state.imports_array, + }); + } catch (e) { + this.props.notifyApplicationBusy(false); + this.props.notifyError(e); + } + } else { + const items = this.state.import_text.split('\n'); + let importsArray = []; + try { + for (let item of items) { + item = item.trim(); + if (item.startsWith('[')) { + importsArray = JSON.parse(this.state.import_text.trim()); + break; + } else if (item.indexOf('=') >= 0) { + const parts = item.split(',') + let importItem = { + directory: '/', + skylink: '', + token: '', + }; + for (let part of parts) { + part = part.trim(); + const pair = part.split('='); + if (pair.length !== 2) { + throw new Error('Invalid syntax for import: directory="",skylink="",token=""'); + } + importItem = { + ...importItem, + [pair[0].trim()]: pair[1].trim().replace(/"/g, ''), + }; + } + if (!importItem.skylink) { throw new Error('Invalid syntax for import: directory="",skylink="",token=""'); } - importItem = { - ...importItem, - [pair[0].trim()]: pair[1].trim().replace(/"/g, ''), - }; + importsArray.push(importItem); + } else if (item.length > 0) { + importsArray.push({ + directory: '/', + skylink: item, + }); } - if (!importItem.skylink) { - throw new Error('Invalid syntax for import: directory="",skylink="",token=""'); - } - importsArray.push(importItem); - } else if (item.length > 0) { - importsArray.push({ - directory: '/', - skylink: item, - }); } - } - if (importsArray.length === 0) { - throw new Error('Nothing to import'); + if (importsArray.length === 0) { + throw new Error('Nothing to import'); + } + this.setState({ + imports_array: importsArray, + second_stage: true, + }); + } catch (e) { + this.props.notifyError(e); } - this.props.importSkylinks(this.props.version, importsArray); - } catch (e) { - this.props.notifyError(e); } } render() { - return ( + // + return this.props.AppBusy ? (
) : ( X

Import List

-