)
const confirmDisplay = createModalConditionally(this.props.DisplayConfirmYesNo, );
const dependencyDisplay = createModalConditionally(showDependencies,
, false, this.props.InstallActive);
diff --git a/src/constants.js b/src/constants.js
index f66ba3e..8c45161 100644
--- a/src/constants.js
+++ b/src/constants.js
@@ -122,6 +122,15 @@ exports.IPC_Get_Config_Reply = 'get_config_reply';
exports.IPC_Get_Config_Template = 'get_config_template';
exports.IPC_Get_Config_Template_Reply = 'get_config_template_reply';
+exports.IPC_Get_Directory_Items = 'get_directory_items';
+exports.IPC_Get_Directory_Items_Reply = 'get_directory_items_reply';
+
+exports.IPC_Get_Pinned_Files = 'get_pinned_files';
+exports.IPC_Get_Pinned_Files_Reply = 'get_pinned_files_reply';
+
+exports.IPC_Get_Pinned_Files_Status = 'get_pinned_files_status';
+exports.IPC_Get_Pinned_Files_Status_Reply = 'get_pinned_files_status_reply';
+
exports.IPC_Get_Platform = 'get_platform';
exports.IPC_Get_Platform_Reply = 'get_platform_reply';
@@ -150,6 +159,8 @@ exports.IPC_Reboot_System = 'reboot_system';
exports.IPC_Save_State = 'save_state';
+exports.IPC_Set_Pinned = 'set_pinned';
+
exports.IPC_Show_Window = 'show_window';
exports.IPC_Set_Config_Values = 'set_config_values';
diff --git a/src/containers/PinnedManager/PinnedManager.css b/src/containers/PinnedManager/PinnedManager.css
index e69de29..8ef8396 100644
--- a/src/containers/PinnedManager/PinnedManager.css
+++ b/src/containers/PinnedManager/PinnedManager.css
@@ -0,0 +1,17 @@
+.PinnedManagerActiveDirectory {
+ margin-top: var(--default_spacing);
+ margin-bottom: var(--default_spacing);
+ padding: 2px;
+ width: calc(100% - 4px);
+ text-align: left;
+ border-radius: var(--border_radius);
+ background: var(--control_background);
+}
+
+.PinnedManagerItems {
+ padding: var(--default_spacing);
+ overflow-x: auto;
+ overflow-y: auto;
+ border-radius: var(--border_radius);
+ background: var(--control_background);
+}
diff --git a/src/containers/PinnedManager/PinnedManager.js b/src/containers/PinnedManager/PinnedManager.js
index 90491e4..27138d1 100644
--- a/src/containers/PinnedManager/PinnedManager.js
+++ b/src/containers/PinnedManager/PinnedManager.js
@@ -7,13 +7,19 @@ import {notifyError, notifyInfo} from '../../redux/actions/error_actions';
import Box from '../../components/UI/Box/Box';
import {displayPinnedManager} from '../../redux/actions/pinned_manager_actions';
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
-import {
- faCheckSquare, faChevronDown,
- faChevronRight, faFile, faFolder, faFolderOpen,
- faHSquare, faMinusSquare, faPlusSquare,
- faSquare
-} from '@fortawesome/free-solid-svg-icons';
+import {faFolder} from '@fortawesome/free-solid-svg-icons';
import Button from '../../components/UI/Button/Button';
+import CheckBox from '../../components/UI/CheckBox/CheckBox';
+
+const Constants = require('../../constants');
+
+const mapStateToProps = state => {
+ return {
+ DisplayConfiguration: state.mounts.DisplayConfiguration,
+ DisplayRemoteConfiguration: state.mounts.DisplayRemoteConfiguration,
+ DisplayS3Configuration: state.mounts.DisplayS3Configuration,
+ }
+};
const mapDispatchToProps = dispatch => {
return {
@@ -24,20 +30,115 @@ const mapDispatchToProps = dispatch => {
}
};
-export default connect(null, mapDispatchToProps)(class extends IPCContainer {
+export default connect(mapStateToProps, mapDispatchToProps)(class extends IPCContainer {
state = {
active_directory: '/',
items: [],
+ previous_directory: '',
}
componentDidMount() {
+ this.setRequestHandler(Constants.IPC_Get_Directory_Items_Reply, this.onGetDirectoryItemsReply);
+ this.grabDirectoryItems();
}
componentWillUnmount() {
super.componentWillUnmount();
}
+ grabDirectoryItems = () => {
+ this.sendRequest(Constants.IPC_Get_Directory_Items, {
+ Provider: this.props.DisplayConfiguration,
+ Remote: this.props.DisplayRemoteConfiguration,
+ S3: this.props.DisplayS3Configuration,
+ Version: this.props.version,
+ Path: this.state.active_directory,
+ });
+ }
+
+ onGetDirectoryItemsReply = (_, {data}) => {
+ if (data.Success) {
+ const items = data.Items
+ .filter(i => i.path !== '.' && (this.state.active_directory !== '/' || (i.path.substr(0, 1) !== '.')))
+ .map(i => {
+ return {
+ ...i,
+ name: i.path === '..' ? i.path : '\'' + i.path.substr(i.path.lastIndexOf('/') + 1) + '\'',
+ meta: {
+ ...i.meta,
+ pinned: i.meta.pinned === '1',
+ }
+ }
+ });
+ this.setState({
+ items,
+ });
+ } else {
+ this.props.notifyError(data.Error, false, () => {
+ this.props.displayPinnedManager(false);
+ });
+ }
+ }
+
+ createDirectory = (name, path, idx, total, item_idx) => {
+ const style = {}
+ if (item_idx + 1 !== total) {
+ style.marginBottom = '4px';
+ }
+ return (
+
+
+
+ );
+ }
+
+ createFile = (name, pinned, idx, total, item_idx) => {
+ const style = {textAlign: 'left'}
+ if (item_idx + 1 !== total) {
+ style.marginBottom = '2px';
+ }
+ return (
+
+ {
+ const items = JSON.parse(JSON.stringify(this.state.items));
+ items[item_idx].meta.pinned = !items[item_idx].meta.pinned;
+ this.setState({
+ items
+ }, () => {
+ this.sendSyncRequest(Constants.IPC_Set_Pinned, {
+ Provider: this.props.DisplayConfiguration,
+ Remote: this.props.DisplayRemoteConfiguration,
+ S3: this.props.DisplayS3Configuration,
+ Version: this.props.version,
+ Path: items[item_idx].path,
+ Pinned: items[item_idx].meta.pinned,
+ });
+ });
+ }}
+ label={name}/>
+
+ );
+ }
+
render() {
+ let idx = 0;
return (
X
{'Pinned File Manager'}
+ {this.state.active_directory}
-
+ {
+ this.state.items.map((i, k) => {
+ return i.directory ?
+ this.createDirectory(i.name, i.path, idx++, this.state.items.length, k) :
+ this.createFile(i.name, i.meta.pinned, idx++, this.state.items.length, k);
+ })
+ }
)
diff --git a/src/helpers.js b/src/helpers.js
index 5068396..95f658e 100644
--- a/src/helpers.js
+++ b/src/helpers.js
@@ -840,6 +840,89 @@ module.exports.grabSkynetFileTree = version => {
});
};
+module.exports.grabDirectoryItems = (path, version, provider, remote, s3) => {
+ return new Promise((resolve, reject) => {
+ const repertoryExec = _getRepertoryExec(version);
+ const processOptions = {
+ cwd: repertoryExec.working,
+ detached: true,
+ shell: false,
+ windowsHide: true,
+ };
+
+ const args = _getDefaultRepertoryArgs(provider, remote, s3);
+ args.push('-gdi');
+ args.push(path);
+
+ 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.setPinned = (path, pinned, version, provider, remote, s3) => {
+ return new Promise((resolve, reject) => {
+ const repertoryExec = _getRepertoryExec(version);
+ const processOptions = {
+ cwd: repertoryExec.working,
+ detached: true,
+ shell: false,
+ windowsHide: true,
+ };
+
+ const args = _getDefaultRepertoryArgs(provider, remote, s3);
+ args.push(pinned ? '-pf' : '-uf');
+ args.push(path);
+
+ 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) {
+ resolve(JSON.parse(result).success);
+ } else {
+ reject(new Error('Failed to import: ' + code + ':' + result));
+ }
+ });
+
+ process.unref();
+ });
+};
+
module.exports.importSkylinks = (version, jsonArray) => {
return new Promise((resolve, reject) => {
const repertoryExec = _getRepertoryExec(version);
diff --git a/src/renderer/ipc/PinnedIPC.js b/src/renderer/ipc/PinnedIPC.js
new file mode 100644
index 0000000..2cc26d7
--- /dev/null
+++ b/src/renderer/ipc/PinnedIPC.js
@@ -0,0 +1,49 @@
+const Constants = require('../../constants');
+const helpers = require('../../helpers');
+
+const addListeners = (ipcMain, {standardIPCReply}) => {
+ ipcMain.on(Constants.IPC_Get_Directory_Items, (event, data) => {
+ helpers
+ .grabDirectoryItems(data.Path, data.Version, data.Provider, data.Remote, data.S3)
+ .then(data => {
+ standardIPCReply(event, Constants.IPC_Get_Directory_Items_Reply, {
+ Items: data.items,
+ });
+ })
+ .catch(e => {
+ standardIPCReply(event, Constants.IPC_Get_Directory_Items_Reply, {}, e);
+ });
+ });
+
+ ipcMain.on(Constants.IPC_Get_Pinned_Files, (event, data) => {
+ helpers
+ .grabDirectoryItems(data.Path, data.Version, data.Provider, data.Remote, data.S3)
+ .then(data => {
+ standardIPCReply(event, Constants.IPC_Get_Directory_Items_Reply, {
+ Items: data.items,
+ });
+ })
+ .catch(e => {
+ standardIPCReply(event, Constants.IPC_Get_Directory_Items_Reply, {}, e);
+ });
+ });
+
+ ipcMain.on(Constants.IPC_Get_Pinned_Files_Status, (event, data) => {
+
+ });
+
+ ipcMain.on(Constants.IPC_Set_Pinned + '_sync', (event, data) => {
+ helpers
+ .setPinned(data.Path, data.Pinned, data.Version, data.Provider, data.Remote, data.S3)
+ .then(success => {
+ event.returnValue = success;
+ })
+ .catch(e => {
+ event.returnValue = false;
+ });
+ });
+};
+
+module.exports = {
+ addListeners
+};