#48: Support pinning files to cache [partial]
This commit is contained in:
@@ -33,6 +33,7 @@ const DependencyIPC = require('../src/renderer/ipc/DependencyIPC');
|
|||||||
const DownloadIPC = require('../src/renderer/ipc/DownloadIPC');
|
const DownloadIPC = require('../src/renderer/ipc/DownloadIPC');
|
||||||
const FilesystemIPC = require('../src/renderer/ipc/FilesystemIPC');
|
const FilesystemIPC = require('../src/renderer/ipc/FilesystemIPC');
|
||||||
const MountsIPC = require('../src/renderer/ipc/MountsIPC');
|
const MountsIPC = require('../src/renderer/ipc/MountsIPC');
|
||||||
|
const PinnedIPC = require('../src/renderer/ipc/PinnedIPC');
|
||||||
const PlatformIPC = require('../src/renderer/ipc/PlatformIPC');
|
const PlatformIPC = require('../src/renderer/ipc/PlatformIPC');
|
||||||
const ReleaseIPC = require('../src/renderer/ipc/ReleaseIPC');
|
const ReleaseIPC = require('../src/renderer/ipc/ReleaseIPC');
|
||||||
const SkynetIPC = require('../src/renderer/ipc/SkynetIPC');
|
const SkynetIPC = require('../src/renderer/ipc/SkynetIPC');
|
||||||
@@ -330,6 +331,7 @@ DependencyIPC.addListeners(ipcMain, AppFunctions);
|
|||||||
DownloadIPC.addListeners(ipcMain, AppFunctions);
|
DownloadIPC.addListeners(ipcMain, AppFunctions);
|
||||||
FilesystemIPC.addListeners(ipcMain, AppFunctions);
|
FilesystemIPC.addListeners(ipcMain, AppFunctions);
|
||||||
MountsIPC.addListeners(ipcMain, AppFunctions);
|
MountsIPC.addListeners(ipcMain, AppFunctions);
|
||||||
|
PinnedIPC.addListeners(ipcMain, AppFunctions);
|
||||||
PlatformIPC.addListeners(ipcMain, AppFunctions);
|
PlatformIPC.addListeners(ipcMain, AppFunctions);
|
||||||
ReleaseIPC.addListeners(ipcMain, AppFunctions);
|
ReleaseIPC.addListeners(ipcMain, AppFunctions);
|
||||||
SkynetIPC.addListeners(ipcMain, AppFunctions);
|
SkynetIPC.addListeners(ipcMain, AppFunctions);
|
||||||
|
|||||||
@@ -181,7 +181,8 @@ class App extends IPCContainer {
|
|||||||
version={selectedVersion}
|
version={selectedVersion}
|
||||||
s3Supported={s3Supported}
|
s3Supported={s3Supported}
|
||||||
remoteSupported={remoteSupported}/>);
|
remoteSupported={remoteSupported}/>);
|
||||||
const pinnedManagerDisplay = createModalConditionally(showPinnedManager, <PinnedManager/>)
|
const pinnedManagerDisplay = createModalConditionally(showPinnedManager, <PinnedManager
|
||||||
|
version={selectedVersion}/>)
|
||||||
const confirmDisplay = createModalConditionally(this.props.DisplayConfirmYesNo, <YesNo/>);
|
const confirmDisplay = createModalConditionally(this.props.DisplayConfirmYesNo, <YesNo/>);
|
||||||
const dependencyDisplay = createModalConditionally(showDependencies,
|
const dependencyDisplay = createModalConditionally(showDependencies,
|
||||||
<DependencyList/>, false, this.props.InstallActive);
|
<DependencyList/>, false, this.props.InstallActive);
|
||||||
|
|||||||
@@ -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 = 'get_config_template';
|
||||||
exports.IPC_Get_Config_Template_Reply = 'get_config_template_reply';
|
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 = 'get_platform';
|
||||||
exports.IPC_Get_Platform_Reply = 'get_platform_reply';
|
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_Save_State = 'save_state';
|
||||||
|
|
||||||
|
exports.IPC_Set_Pinned = 'set_pinned';
|
||||||
|
|
||||||
exports.IPC_Show_Window = 'show_window';
|
exports.IPC_Show_Window = 'show_window';
|
||||||
|
|
||||||
exports.IPC_Set_Config_Values = 'set_config_values';
|
exports.IPC_Set_Config_Values = 'set_config_values';
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
|||||||
@@ -7,13 +7,19 @@ import {notifyError, notifyInfo} from '../../redux/actions/error_actions';
|
|||||||
import Box from '../../components/UI/Box/Box';
|
import Box from '../../components/UI/Box/Box';
|
||||||
import {displayPinnedManager} from '../../redux/actions/pinned_manager_actions';
|
import {displayPinnedManager} from '../../redux/actions/pinned_manager_actions';
|
||||||
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
|
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
|
||||||
import {
|
import {faFolder} from '@fortawesome/free-solid-svg-icons';
|
||||||
faCheckSquare, faChevronDown,
|
|
||||||
faChevronRight, faFile, faFolder, faFolderOpen,
|
|
||||||
faHSquare, faMinusSquare, faPlusSquare,
|
|
||||||
faSquare
|
|
||||||
} from '@fortawesome/free-solid-svg-icons';
|
|
||||||
import Button from '../../components/UI/Button/Button';
|
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 => {
|
const mapDispatchToProps = dispatch => {
|
||||||
return {
|
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 = {
|
state = {
|
||||||
active_directory: '/',
|
active_directory: '/',
|
||||||
items: [],
|
items: [],
|
||||||
|
previous_directory: '',
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
this.setRequestHandler(Constants.IPC_Get_Directory_Items_Reply, this.onGetDirectoryItemsReply);
|
||||||
|
this.grabDirectoryItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
super.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 (
|
||||||
|
<div key={'dir_' + idx} style={{...style}}>
|
||||||
|
<Button buttonStyles={{textAlign: 'left'}}
|
||||||
|
clicked={() => {
|
||||||
|
const current_path = path === '..' ? '' : this.state.active_directory;
|
||||||
|
this.setState({
|
||||||
|
items: [],
|
||||||
|
active_directory: path === '..' ? this.state.previous_directory : path,
|
||||||
|
previous_directory: current_path,
|
||||||
|
}, () => {
|
||||||
|
this.grabDirectoryItems();
|
||||||
|
});
|
||||||
|
}}>
|
||||||
|
<FontAwesomeIcon icon={faFolder}
|
||||||
|
fixedWidth
|
||||||
|
color={'var(--heading_text_color)'}
|
||||||
|
style={{padding: 0, margin: 0}}/>
|
||||||
|
{name}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
createFile = (name, pinned, idx, total, item_idx) => {
|
||||||
|
const style = {textAlign: 'left'}
|
||||||
|
if (item_idx + 1 !== total) {
|
||||||
|
style.marginBottom = '2px';
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<div key={'file_' + idx} style={{...style}}>
|
||||||
|
<CheckBox checked={pinned}
|
||||||
|
changed={() => {
|
||||||
|
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}/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
let idx = 0;
|
||||||
return (
|
return (
|
||||||
<Box dxDark dxStyle={{
|
<Box dxDark dxStyle={{
|
||||||
height: 'calc(100vh - (var(--default_spacing) * 4)',
|
height: 'calc(100vh - (var(--default_spacing) * 4)',
|
||||||
@@ -58,8 +159,15 @@ export default connect(null, mapDispatchToProps)(class extends IPCContainer {
|
|||||||
style={{cursor: 'pointer'}}>X</a>
|
style={{cursor: 'pointer'}}>X</a>
|
||||||
</div>
|
</div>
|
||||||
<h1 style={{width: '100%', textAlign: 'center'}}>{'Pinned File Manager'}</h1>
|
<h1 style={{width: '100%', textAlign: 'center'}}>{'Pinned File Manager'}</h1>
|
||||||
|
<h2 className={'PinnedManagerActiveDirectory'}>{this.state.active_directory}</h2>
|
||||||
<div className={'PinnedManagerItems'}>
|
<div className={'PinnedManagerItems'}>
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
})
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</Box>
|
</Box>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -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) => {
|
module.exports.importSkylinks = (version, jsonArray) => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const repertoryExec = _getRepertoryExec(version);
|
const repertoryExec = _getRepertoryExec(version);
|
||||||
|
|||||||
49
src/renderer/ipc/PinnedIPC.js
Normal file
49
src/renderer/ipc/PinnedIPC.js
Normal file
@@ -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
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user