338 lines
11 KiB
JavaScript
338 lines
11 KiB
JavaScript
import React from 'react';
|
|
import Box from '../../components/UI/Box/Box';
|
|
import Button from '../../components/UI/Button/Button';
|
|
import {connect} from 'react-redux';
|
|
import './MountItems.css';
|
|
import Modal from '../../components/UI/Modal/Modal';
|
|
import MountItem from '../../components/MountItem/MountItem';
|
|
import IPCContainer from '../IPCContainer/IPCContainer';
|
|
import {
|
|
setAllowMount,
|
|
setAutoMountProcessed,
|
|
setBusy,
|
|
setMounted,
|
|
setMountState,
|
|
setProviderState
|
|
} from '../../redux/actions/mount_actions';
|
|
import {notifyError} from '../../redux/actions/error_actions';
|
|
|
|
const Constants = require('../../constants');
|
|
|
|
class MountItems extends IPCContainer {
|
|
constructor(props) {
|
|
super(props);
|
|
|
|
this.setRequestHandler(Constants.IPC_Detect_Mounts_Reply, this.onDetectMountsReply);
|
|
this.setRequestHandler(Constants.IPC_Mount_Drive_Reply, this.onMountDriveReply);
|
|
this.setRequestHandler(Constants.IPC_Unmount_Drive_Reply, this.onUnmountDriveReply);
|
|
}
|
|
|
|
retryIntervals = {};
|
|
|
|
state = {
|
|
DisplayRetry: false,
|
|
RetryItems: {},
|
|
};
|
|
|
|
cancelRetryMount = (provider, stateCallback) => {
|
|
clearInterval(this.retryIntervals[provider]);
|
|
delete this.retryIntervals[provider];
|
|
|
|
if (stateCallback) {
|
|
let retryItems = {
|
|
...this.state.RetryItems,
|
|
};
|
|
delete retryItems[provider];
|
|
this.setState({
|
|
DisplayRetry: Object.keys(retryItems).length > 0,
|
|
RetryItems: retryItems,
|
|
}, () => {
|
|
if (this.state.DisplayRetry) {
|
|
this.sendRequest(Constants.IPC_Show_Window);
|
|
}
|
|
stateCallback();
|
|
});
|
|
}
|
|
};
|
|
|
|
componentDidMount() {
|
|
this.detectMounts();
|
|
}
|
|
|
|
componentWillUnmount() {
|
|
for (const provider in this.state.RetryItems) {
|
|
if (this.state.RetryItems.hasOwnProperty(provider)) {
|
|
this.cancelRetryMount(provider);
|
|
}
|
|
}
|
|
|
|
super.componentWillUnmount();
|
|
};
|
|
|
|
detectMounts = ()=> {
|
|
if (!this.state.DisplayRetry) {
|
|
this.props.setMountsBusy(true);
|
|
this.sendRequest(Constants.IPC_Detect_Mounts, {
|
|
Version: this.props.InstalledVersion,
|
|
});
|
|
}
|
|
};
|
|
|
|
displayRetryMount = (provider, mountLocation, msg) => {
|
|
if (!this.state.RetryItems[provider]) {
|
|
let retryItems = {
|
|
...this.state.RetryItems
|
|
};
|
|
retryItems[provider] = {
|
|
RetrySeconds: 10,
|
|
RetryMessage: msg ? msg.toString() : null,
|
|
};
|
|
const mountState = {
|
|
AllowMount: false,
|
|
Mounted: false,
|
|
};
|
|
this.props.setMountState(provider, mountState);
|
|
|
|
this.setState({
|
|
DisplayRetry: true,
|
|
RetryItems: retryItems,
|
|
}, () => {
|
|
this.sendRequest(Constants.IPC_Show_Window);
|
|
this.retryIntervals[provider] = setInterval(() => {
|
|
let retryItems = {
|
|
...this.state.RetryItems,
|
|
};
|
|
const retrySeconds = retryItems[provider].RetrySeconds - 1;
|
|
if (retrySeconds === 0) {
|
|
this.cancelRetryMount(provider, () => {
|
|
this.handleMountUnMount(provider, true, mountLocation);
|
|
});
|
|
} else {
|
|
retryItems[provider].RetrySeconds = retrySeconds;
|
|
this.setState({
|
|
RetryItems: retryItems,
|
|
});
|
|
}
|
|
}, 1000);
|
|
});
|
|
}
|
|
};
|
|
|
|
handleBrowseLocation = (provider, location) => {
|
|
location = this.sendSyncRequest(Constants.IPC_Browse_Directory, {
|
|
Title: provider + ' Mount Location',
|
|
Location: location,
|
|
});
|
|
if (location && (location.length > 0)) {
|
|
this.handleMountLocationChanged(provider, location);
|
|
}
|
|
};
|
|
|
|
handleMountLocationChanged = (provider, value) => {
|
|
const location = (this.props.Platform === 'win32') ?
|
|
this.props.MountState[provider].DriveLetters[value] :
|
|
value;
|
|
|
|
const state = {
|
|
...this.props.ProviderState[provider],
|
|
MountLocation: location,
|
|
};
|
|
this.props.setProviderState(provider, state);
|
|
};
|
|
|
|
handleMountUnMount = (provider, mount, location) => {
|
|
if (!location || (location.trim().length === 0)) {
|
|
this.props.notifyError('Mount location is not set');
|
|
} else {
|
|
let allowAction = true;
|
|
if (mount) {
|
|
let result = this.sendSyncRequest(Constants.IPC_Check_Daemon_Version, {
|
|
Provider: provider,
|
|
Version: this.props.InstalledVersion
|
|
}).data;
|
|
if (result.Success) {
|
|
if (result.Valid) {
|
|
if (this.props.Platform !== 'win32') {
|
|
result = this.sendSyncRequest(Constants.IPC_Check_Mount_Location, {
|
|
Location: location,
|
|
});
|
|
if (!result.Success) {
|
|
allowAction = false;
|
|
this.props.notifyError(result.Error.toString());
|
|
}
|
|
}
|
|
} else {
|
|
allowAction = false;
|
|
if ((result.Code === new Uint32Array([-1])[0]) || (result.Code === new Uint8Array([-1])[0])) {
|
|
this.displayRetryMount(provider, location, 'Failed to connect to ' + provider + ' daemon');
|
|
} else if ((result.Code === new Uint32Array([-3])[0]) || (result.Code === new Uint8Array([-3])[0])) {
|
|
this.displayRetryMount(provider, location, 'Incompatible ' + provider + ' daemon. Please upgrade ' + provider);
|
|
} else {
|
|
this.displayRetryMount(provider, location, 'Version check failed: ' + result.Error);
|
|
}
|
|
}
|
|
} else {
|
|
allowAction = false;
|
|
this.displayRetryMount(provider, location, 'Version check failed: ' + result.Error);
|
|
}
|
|
}
|
|
|
|
if (allowAction) {
|
|
this.props.setMountsBusy(true);
|
|
this.props.setAllowMount(provider, false);
|
|
|
|
if (mount) {
|
|
this.sendRequest(Constants.IPC_Mount_Drive, {
|
|
Location: location,
|
|
NoConsoleSupported: this.props.noConsoleSupported,
|
|
Provider: provider,
|
|
Version: this.props.InstalledVersion,
|
|
});
|
|
} else {
|
|
this.sendRequest(Constants.IPC_Unmount_Drive, {
|
|
Location: location,
|
|
Provider: provider,
|
|
Version: this.props.InstalledVersion,
|
|
});
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
onDetectMountsReply = (event, arg) => {
|
|
if (!this.state.DisplayRetry && arg.data.Success) {
|
|
let mountsBusy = false;
|
|
let mountStates = {};
|
|
for (const provider of Constants.PROVIDER_LIST) {
|
|
const mountState = {
|
|
AllowMount: true,
|
|
DriveLetters: (arg.data.DriveLetters[provider]),
|
|
Mounted: (arg.data.Locations[provider].length > 0),
|
|
};
|
|
this.props.setMountState(provider, mountState);
|
|
mountsBusy = mountsBusy || mountState.Mounted;
|
|
mountStates[provider] = mountState;
|
|
}
|
|
this.props.setMountsBusy(mountsBusy);
|
|
|
|
const updateMountLocation = (data, provider) => {
|
|
const providerState = this.props.ProviderState[provider];
|
|
let location = data.Locations[provider];
|
|
if (location.length === 0) {
|
|
location = (this.props.Platform === 'win32') ?
|
|
providerState.MountLocation || data.DriveLetters[provider][0] :
|
|
providerState.MountLocation;
|
|
}
|
|
|
|
if (location !== providerState.MountLocation) {
|
|
this.handleMountLocationChanged(provider, location);
|
|
}
|
|
|
|
if (!this.props.AutoMountProcessed &&
|
|
this.props.ProviderState[provider].AutoMount &&
|
|
!mountStates[provider].Mounted &&
|
|
(location.length > 0)) {
|
|
this.handleMountUnMount(provider, true, location);
|
|
}
|
|
};
|
|
|
|
for (const provider of Constants.PROVIDER_LIST) {
|
|
updateMountLocation(arg.data, provider);
|
|
}
|
|
|
|
this.props.setAutoMountProcessed(true);
|
|
} else {
|
|
this.props.notifyError(arg.data.Error);
|
|
}
|
|
};
|
|
|
|
onMountDriveReply = (event, arg) => {
|
|
this.props.setMounted(arg.data.Provider, arg.data.Success);
|
|
this.detectMounts();
|
|
};
|
|
|
|
onUnmountDriveReply = (event, arg) => {
|
|
if (arg && arg.data && !arg.data.Expected && arg.data.Location && this.props.ProviderState[arg.data.Provider].AutoRestart) {
|
|
this.displayRetryMount(arg.data.Provider, arg.data.Location);
|
|
} else {
|
|
this.detectMounts();
|
|
}
|
|
};
|
|
|
|
render() {
|
|
let retryDisplay;
|
|
if (this.state.DisplayRetry) {
|
|
let retryList = [];
|
|
let retryListCount = 0;
|
|
for (const provider in this.state.RetryItems) {
|
|
if (this.state.RetryItems.hasOwnProperty(provider)) {
|
|
retryListCount++;
|
|
if (this.state.RetryItems[provider].RetryMessage) {
|
|
retryList.push(<p key={'p' + retryListCount}>{this.state.RetryItems[provider].RetryMessage}</p>);
|
|
}
|
|
retryList.push(<Button
|
|
clicked={()=>this.cancelRetryMount(provider, ()=> this.detectMounts())}
|
|
key={'b' + retryListCount}>Cancel {provider} Remount ({this.state.RetryItems[provider].RetrySeconds}s)</Button>);
|
|
if (retryListCount < Object.keys(this.state.RetryItems).length) {
|
|
retryList.push(<div style={{paddingTop: '8px'}} key={'d' + retryListCount}/>);
|
|
}
|
|
}
|
|
}
|
|
|
|
retryDisplay = (
|
|
<Modal>
|
|
<Box dxDark dxStyle={{padding: '8px', minWidth: '70vw'}}>
|
|
<h1 style={{textAlign: 'center', paddingBottom: '8px', color: 'var(--text_color_error)'}}>Mount Failed</h1>
|
|
{retryList}
|
|
</Box>
|
|
</Modal>
|
|
)
|
|
}
|
|
|
|
let items = [];
|
|
for (const provider of Constants.PROVIDER_LIST) {
|
|
items.push((
|
|
<MountItem allowConfig={this.props.allowConfig}
|
|
browseClicked={this.handleBrowseLocation}
|
|
changed={e => this.handleMountLocationChanged(provider, e.target.value)}
|
|
clicked={this.handleMountUnMount}
|
|
key={'mi_' + items.length}
|
|
provider={provider}/>
|
|
));
|
|
if (items.length !== this.state.length) {
|
|
items.push(<div key={'di_' + items.length}
|
|
style={{paddingTop: '12px'}} />)
|
|
}
|
|
}
|
|
|
|
return (
|
|
<div className={'MountItems'}>
|
|
{retryDisplay}
|
|
{items}
|
|
</div>);
|
|
}
|
|
}
|
|
|
|
const mapStateToProps = state => {
|
|
return {
|
|
AutoMountProcessed: state.mounts.AutoMountProcessed,
|
|
InstalledVersion: state.relver.InstalledVersion,
|
|
MountState: state.mounts.MountState,
|
|
Platform: state.common.Platform,
|
|
ProviderState: state.mounts.ProviderState,
|
|
}
|
|
};
|
|
|
|
const mapDispatchToProps = dispatch => {
|
|
return {
|
|
notifyError: (msg, critical, callback) => dispatch(notifyError(msg, critical, callback)),
|
|
setAllowMount: (provider, allow) => dispatch(setAllowMount(provider, allow)),
|
|
setAutoMountProcessed: processed => dispatch(setAutoMountProcessed(processed)),
|
|
setMounted: (provider, mounted) => dispatch(setMounted(provider, mounted)),
|
|
setMountsBusy: busy => dispatch(setBusy(busy)),
|
|
setMountState: (provider, state) => dispatch(setMountState(provider, state)),
|
|
setProviderState: (provider, state) => dispatch(setProviderState(provider, state)),
|
|
}
|
|
};
|
|
|
|
export default connect(mapStateToProps, mapDispatchToProps)(MountItems); |