Linux / OS X changes
This commit is contained in:
119
electron.js
119
electron.js
@@ -17,10 +17,15 @@ const AutoLaunch = require('auto-launch');
|
|||||||
let mainContextWindow;
|
let mainContextWindow;
|
||||||
let mainWindow;
|
let mainWindow;
|
||||||
let mainWindowTray;
|
let mainWindowTray;
|
||||||
let mountedPIDs = [];
|
let mountedPIDs = {};
|
||||||
|
let mountedLocations = [];
|
||||||
let expectedUnmount = {};
|
let expectedUnmount = {};
|
||||||
let launchHidden = false;
|
let launchHidden = false;
|
||||||
|
|
||||||
|
function closeApplication() {
|
||||||
|
app.quit();
|
||||||
|
}
|
||||||
|
|
||||||
function createWindow() {
|
function createWindow() {
|
||||||
loadUiSettings();
|
loadUiSettings();
|
||||||
|
|
||||||
@@ -50,7 +55,15 @@ function createWindow() {
|
|||||||
// Dereference the window object, usually you would store windows
|
// Dereference the window object, usually you would store windows
|
||||||
// in an array if your app supports multi windows, this is the time
|
// in an array if your app supports multi windows, this is the time
|
||||||
// when you should delete the corresponding element.
|
// when you should delete the corresponding element.
|
||||||
mainWindow = null
|
mainWindow = null;
|
||||||
|
|
||||||
|
// Unmount all items
|
||||||
|
console.log(mountedLocations);
|
||||||
|
for (const i in mountedLocations) {
|
||||||
|
helpers.stopMountProcess(mountedPIDs[mountedLocations[i]], mountedLocations[i]);
|
||||||
|
}
|
||||||
|
mountedLocations = [];
|
||||||
|
mountedPIDs = {};
|
||||||
});
|
});
|
||||||
|
|
||||||
if ((os.platform() === 'win32') || (os.platform() === 'linux')) {
|
if ((os.platform() === 'win32') || (os.platform() === 'linux')) {
|
||||||
@@ -103,7 +116,7 @@ function createWindow() {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Exit', click(item) {
|
label: 'Exit', click(item) {
|
||||||
app.quit();
|
closeApplication();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
@@ -118,14 +131,14 @@ function createWindow() {
|
|||||||
mainWindowTray.setContextMenu(mainContextWindow)
|
mainWindowTray.setContextMenu(mainContextWindow)
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
app.quit();
|
closeApplication();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const instanceLock = app.requestSingleInstanceLock();
|
const instanceLock = app.requestSingleInstanceLock();
|
||||||
if (!instanceLock) {
|
if (!instanceLock) {
|
||||||
app.quit()
|
closeApplication();
|
||||||
} else {
|
} else {
|
||||||
app.on('second-instance', () => {
|
app.on('second-instance', () => {
|
||||||
if (mainWindow) {
|
if (mainWindow) {
|
||||||
@@ -146,7 +159,7 @@ if (!instanceLock) {
|
|||||||
// On OS X it is common for applications and their menu bar
|
// On OS X it is common for applications and their menu bar
|
||||||
// to stay active until the user quits explicitly with Cmd + Q
|
// to stay active until the user quits explicitly with Cmd + Q
|
||||||
if (process.platform !== 'darwin') {
|
if (process.platform !== 'darwin') {
|
||||||
app.quit()
|
closeApplication();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -181,13 +194,15 @@ const saveUiSettings = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const standardIPCReply = (event, channel, data, error) => {
|
const standardIPCReply = (event, channel, data, error) => {
|
||||||
event.sender.send(channel, {
|
if (mainWindow) {
|
||||||
data: {
|
event.sender.send(channel, {
|
||||||
...data,
|
data: {
|
||||||
Error: error,
|
...data,
|
||||||
Success: !error,
|
Error: error,
|
||||||
}
|
Success: !error,
|
||||||
});
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ipcMain.on(Constants.IPC_Check_Dependency_Installed, (event, data) => {
|
ipcMain.on(Constants.IPC_Check_Dependency_Installed, (event, data) => {
|
||||||
@@ -237,11 +252,10 @@ ipcMain.on(Constants.IPC_Delete_File, (event, data) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.on(Constants.IPC_Detect_Mounts, (event, data) => {
|
ipcMain.on(Constants.IPC_Detect_Mounts, (event, data) => {
|
||||||
let driveLetters = {
|
let driveLetters = {};
|
||||||
Hyperspace: [],
|
for (const provider of Constants.PROVIDER_LIST) {
|
||||||
Sia: [],
|
driveLetters[provider] = [];
|
||||||
SiaPrime: [],
|
}
|
||||||
};
|
|
||||||
|
|
||||||
const grabDriveLetters = (hsLocation, siaLocation, siaPrimeLocation) => {
|
const grabDriveLetters = (hsLocation, siaLocation, siaPrimeLocation) => {
|
||||||
for (let i = 'c'.charCodeAt(0); i <= 'z'.charCodeAt(0); i++) {
|
for (let i = 'c'.charCodeAt(0); i <= 'z'.charCodeAt(0); i++) {
|
||||||
@@ -503,30 +517,42 @@ ipcMain.on(Constants.IPC_Install_Upgrade, (event, data) => {
|
|||||||
ipcMain.on(Constants.IPC_Mount_Drive, (event, data) => {
|
ipcMain.on(Constants.IPC_Mount_Drive, (event, data) => {
|
||||||
expectedUnmount[data.StorageType] = false;
|
expectedUnmount[data.StorageType] = false;
|
||||||
const dataDirectory = helpers.resolvePath(data.Directory);
|
const dataDirectory = helpers.resolvePath(data.Directory);
|
||||||
const errorHandler = (pid, error) => {
|
|
||||||
mountedPIDs.splice(mountedPIDs.indexOf(pid), 1);
|
if (mountedLocations.indexOf(data.Location) !== -1) {
|
||||||
standardIPCReply(event, Constants.IPC_Unmount_Drive_Reply, {
|
console.log(data.StorageType + ' already mounted: ' + data.Location);
|
||||||
Expected: expectedUnmount[data.StorageType],
|
} else {
|
||||||
Location: data.Location,
|
mountedLocations.push(data.Location);
|
||||||
PID: -1,
|
mountedPIDs[data.Location] = -1;
|
||||||
StorageType: data.StorageType,
|
const errorHandler = (pid, error) => {
|
||||||
}, error || Error(data.StorageType + ' Unmounted'));
|
if (mountedLocations.indexOf(data.Location) !== -1) {
|
||||||
};
|
mountedLocations.splice(mountedLocations.indexOf(data.Location), 1);
|
||||||
helpers.executeMount(dataDirectory, data.Version, data.StorageType, data.Location, (error, pid) => {
|
delete mountedPIDs[data.Location];
|
||||||
errorHandler(pid, error);
|
}
|
||||||
})
|
|
||||||
.then(pid => {
|
standardIPCReply(event, Constants.IPC_Unmount_Drive_Reply, {
|
||||||
if (pid !== -1) {
|
Expected: expectedUnmount[data.StorageType],
|
||||||
mountedPIDs.push(pid);
|
Location: data.Location,
|
||||||
}
|
PID: -1,
|
||||||
standardIPCReply(event, Constants.IPC_Mount_Drive_Reply, {
|
StorageType: data.StorageType,
|
||||||
PID: pid,
|
}, error || Error(data.StorageType + ' Unmounted'));
|
||||||
StorageType: data.StorageType,
|
};
|
||||||
});
|
helpers
|
||||||
})
|
.executeMount(dataDirectory, data.Version, data.StorageType, data.Location, data.NoConsoleSupported, (error, pid) => {
|
||||||
.catch(error => {
|
errorHandler(pid, error);
|
||||||
errorHandler(-1, error);
|
})
|
||||||
});
|
.then(pid => {
|
||||||
|
if (pid !== -1) {
|
||||||
|
mountedPIDs[data.Location] = pid;
|
||||||
|
}
|
||||||
|
standardIPCReply(event, Constants.IPC_Mount_Drive_Reply, {
|
||||||
|
PID: pid,
|
||||||
|
StorageType: data.StorageType,
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
errorHandler(-1, error);
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.on(Constants.IPC_Save_State, (event, data) => {
|
ipcMain.on(Constants.IPC_Save_State, (event, data) => {
|
||||||
@@ -556,17 +582,14 @@ ipcMain.on(Constants.IPC_Set_Config_Values, (event, data) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.on(Constants.IPC_Shutdown, () => {
|
ipcMain.on(Constants.IPC_Shutdown, () => {
|
||||||
app.quit();
|
closeApplication();
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.on(Constants.IPC_Unmount_Drive, (event, data) => {
|
ipcMain.on(Constants.IPC_Unmount_Drive, (event, data) => {
|
||||||
expectedUnmount[data.StorageType] = true;
|
expectedUnmount[data.StorageType] = true;
|
||||||
helpers
|
helpers
|
||||||
.stopProcessByPID(data.PID)
|
.stopMountProcess(data.PID, data.Location)
|
||||||
.then((pid)=> {
|
.then(()=> {
|
||||||
if (mountedPIDs.indexOf(pid) === -1) {
|
|
||||||
event.sender.send(Constants.IPC_Unmount_Drive_Reply);
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
|
|||||||
81
helpers.js
81
helpers.js
@@ -4,6 +4,7 @@ const os = require('os');
|
|||||||
const axios = require('axios');
|
const axios = require('axios');
|
||||||
const exec = require('child_process').exec;
|
const exec = require('child_process').exec;
|
||||||
const spawn = require('child_process').spawn;
|
const spawn = require('child_process').spawn;
|
||||||
|
const Constants = require('./src/constants');
|
||||||
|
|
||||||
const tryParse = (j, def) => {
|
const tryParse = (j, def) => {
|
||||||
try {
|
try {
|
||||||
@@ -37,23 +38,15 @@ module.exports.detectRepertoryMounts = (directory, version) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
process.on('exit', () => {
|
process.on('exit', () => {
|
||||||
resolve(tryParse(result, {
|
let defaultData = {};
|
||||||
Hyperspace: {
|
for (const provider of Constants.PROVIDER_LIST) {
|
||||||
|
defaultData[provider] = {
|
||||||
Active: false,
|
Active: false,
|
||||||
Location: '',
|
Location: '',
|
||||||
PID: -1,
|
PID: -1,
|
||||||
},
|
};
|
||||||
Sia: {
|
}
|
||||||
Active: false,
|
resolve(tryParse(result, defaultData));
|
||||||
Location: '',
|
|
||||||
PID: -1,
|
|
||||||
},
|
|
||||||
SiaPrime: {
|
|
||||||
Active: false,
|
|
||||||
Location: '',
|
|
||||||
PID: -1,
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
});
|
});
|
||||||
process.unref();
|
process.unref();
|
||||||
});
|
});
|
||||||
@@ -163,29 +156,33 @@ module.exports.executeAsync = (command, args=[]) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.executeMount = (directory, version, storageType, location, exitCallback) => {
|
module.exports.executeMount = (directory, version, storageType, location, noConsoleSupported, exitCallback) => {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
const processOptions = {
|
const processOptions = {
|
||||||
detached: true,
|
detached: os.platform() === 'win32',
|
||||||
shell: true,
|
shell: true,
|
||||||
|
stdio: 'ignore',
|
||||||
};
|
};
|
||||||
|
|
||||||
const command = path.join(directory, version, (os.platform() === 'win32') ? 'repertory.exe' : 'repertory');
|
const command = path.join(directory, version, (os.platform() === 'win32') ? 'repertory.exe' : 'repertory');
|
||||||
const args = [];
|
const args = [];
|
||||||
if (storageType.toLowerCase() === 'hyperspace') {
|
if (Constants.PROVIDER_ARG[storageType.toLowerCase()].length > 0) {
|
||||||
args.push('-hs');
|
args.push(Constants.PROVIDER_ARG[storageType.toLowerCase()]);
|
||||||
} else if (storageType.toLowerCase() === 'siaprime') {
|
|
||||||
args.push('-sp');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((os.platform() === 'linux') || (os.platform() === 'darwin')) {
|
if ((os.platform() === 'linux') || (os.platform() === 'darwin')) {
|
||||||
args.push('-o');
|
args.push('-o');
|
||||||
args.push('big_writes');
|
args.push('big_writes');
|
||||||
|
args.push('-f');
|
||||||
|
if (noConsoleSupported) {
|
||||||
|
args.push('-nc');
|
||||||
|
}
|
||||||
} else if (os.platform() === 'win32') {
|
} else if (os.platform() === 'win32') {
|
||||||
args.push('-hidden');
|
args.push('-hidden');
|
||||||
}
|
}
|
||||||
args.push(location);
|
args.push(location);
|
||||||
|
|
||||||
const process = new spawn(command, args, processOptions);
|
let process = new spawn(command, args, processOptions);
|
||||||
const pid = process.pid;
|
const pid = process.pid;
|
||||||
|
|
||||||
const timeout = setTimeout(() => {
|
const timeout = setTimeout(() => {
|
||||||
@@ -196,11 +193,15 @@ module.exports.executeMount = (directory, version, storageType, location, exitCa
|
|||||||
clearTimeout(timeout);
|
clearTimeout(timeout);
|
||||||
exitCallback(err, pid);
|
exitCallback(err, pid);
|
||||||
});
|
});
|
||||||
|
|
||||||
process.on('exit', (code) => {
|
process.on('exit', (code) => {
|
||||||
clearTimeout(timeout);
|
clearTimeout(timeout);
|
||||||
exitCallback(code, pid);
|
exitCallback(code, pid);
|
||||||
});
|
});
|
||||||
process.unref();
|
|
||||||
|
if (os.platform() === 'win32') {
|
||||||
|
process.unref();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -215,10 +216,8 @@ module.exports.getConfig = (directory, version, storageType) => {
|
|||||||
const command = path.join(directory, version, (os.platform() === 'win32') ? 'repertory.exe' : 'repertory');
|
const command = path.join(directory, version, (os.platform() === 'win32') ? 'repertory.exe' : 'repertory');
|
||||||
const args = [];
|
const args = [];
|
||||||
args.push('-dc');
|
args.push('-dc');
|
||||||
if (storageType.toLowerCase() === 'hyperspace') {
|
if (Constants.PROVIDER_ARG[storageType.toLowerCase()].length > 0) {
|
||||||
args.push('-hs');
|
args.push(Constants.PROVIDER_ARG[storageType.toLowerCase()]);
|
||||||
} else if (storageType.toLowerCase() === 'siaprime') {
|
|
||||||
args.push('-sp');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const process = new spawn(command, args, processOptions);
|
const process = new spawn(command, args, processOptions);
|
||||||
@@ -263,10 +262,8 @@ module.exports.getConfigTemplate = (directory, version, storageType) => {
|
|||||||
const command = path.join(directory, version, (os.platform() === 'win32') ? 'repertory.exe' : 'repertory');
|
const command = path.join(directory, version, (os.platform() === 'win32') ? 'repertory.exe' : 'repertory');
|
||||||
const args = [];
|
const args = [];
|
||||||
args.push('-gt');
|
args.push('-gt');
|
||||||
if (storageType.toLowerCase() === 'hyperspace') {
|
if (Constants.PROVIDER_ARG[storageType.toLowerCase()].length > 0) {
|
||||||
args.push('-hs');
|
args.push(Constants.PROVIDER_ARG[storageType.toLowerCase()]);
|
||||||
} else if (storageType.toLowerCase() === 'siaprime') {
|
|
||||||
args.push('-sp');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const process = new spawn(command, args, processOptions);
|
const process = new spawn(command, args, processOptions);
|
||||||
@@ -428,10 +425,8 @@ module.exports.setConfigValue = (name, value, directory, storageType, version) =
|
|||||||
args.push('-set');
|
args.push('-set');
|
||||||
args.push(name);
|
args.push(name);
|
||||||
args.push(value);
|
args.push(value);
|
||||||
if (storageType.toLowerCase() === 'hyperspace') {
|
if (Constants.PROVIDER_ARG[storageType.toLowerCase()].length > 0) {
|
||||||
args.push('-hs');
|
args.push(Constants.PROVIDER_ARG[storageType.toLowerCase()]);
|
||||||
} else if (storageType.toLowerCase() === 'siaprime') {
|
|
||||||
args.push('-sp');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const process = new spawn(command, args, processOptions);
|
const process = new spawn(command, args, processOptions);
|
||||||
@@ -448,23 +443,31 @@ module.exports.setConfigValue = (name, value, directory, storageType, version) =
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.stopProcessByPID = pid => {
|
module.exports.stopMountProcess = (pid, location) => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const processOptions = {
|
const processOptions = {
|
||||||
detached: true,
|
detached: true,
|
||||||
shell: false,
|
shell: true,
|
||||||
windowsHide: true,
|
windowsHide: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
const command = (os.platform() === 'win32') ? 'taskkill.exe' : 'kill';
|
let procName = 'kill';
|
||||||
|
if (location && location.length > 0) {
|
||||||
|
procName = 'fusermount';
|
||||||
|
}
|
||||||
|
const command = (os.platform() === 'win32') ? 'taskkill.exe' : procName;
|
||||||
const args = [];
|
const args = [];
|
||||||
if (os.platform() === 'win32') {
|
if (os.platform() === 'win32') {
|
||||||
args.push('/PID');
|
args.push('/PID');
|
||||||
}
|
}
|
||||||
args.push(pid);
|
if (procName === 'fusermount') {
|
||||||
|
args.push('-u');
|
||||||
|
args.push(location);
|
||||||
|
} else {
|
||||||
|
args.push(pid);
|
||||||
|
}
|
||||||
|
|
||||||
const process = new spawn(command, args, processOptions);
|
const process = new spawn(command, args, processOptions);
|
||||||
|
|
||||||
process.on('error', (err) => {
|
process.on('error', (err) => {
|
||||||
reject(err);
|
reject(err);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -588,7 +588,10 @@ class App extends Component {
|
|||||||
this.state.LocationsLookup[selectedVersion].config_support;
|
this.state.LocationsLookup[selectedVersion].config_support;
|
||||||
|
|
||||||
const allowSiaPrime = this.state.LocationsLookup[selectedVersion] &&
|
const allowSiaPrime = this.state.LocationsLookup[selectedVersion] &&
|
||||||
this.state.LocationsLookup[selectedVersion].siaprime_support;
|
this.state.LocationsLookup[selectedVersion].siaprime_support;
|
||||||
|
|
||||||
|
const noConsoleSupported = this.state.LocationsLookup[selectedVersion] &&
|
||||||
|
this.state.LocationsLookup[selectedVersion].no_console_supported;
|
||||||
|
|
||||||
const showDependencies = missingDependencies &&
|
const showDependencies = missingDependencies &&
|
||||||
!this.state.DownloadActive;
|
!this.state.DownloadActive;
|
||||||
@@ -691,6 +694,7 @@ class App extends Component {
|
|||||||
<MountItems {...providerProps}
|
<MountItems {...providerProps}
|
||||||
allowConfig={allowConfig}
|
allowConfig={allowConfig}
|
||||||
allowSiaPrime={allowSiaPrime}
|
allowSiaPrime={allowSiaPrime}
|
||||||
|
noConsoleSupported={noConsoleSupported}
|
||||||
autoMountChanged={this.handleAutoMountChanged}
|
autoMountChanged={this.handleAutoMountChanged}
|
||||||
autoMountProcessed={this.notifyAutoMountProcessed}
|
autoMountProcessed={this.notifyAutoMountProcessed}
|
||||||
autoRestartChanged={this.handleAutoRestartChanged}
|
autoRestartChanged={this.handleAutoRestartChanged}
|
||||||
|
|||||||
@@ -15,6 +15,12 @@ exports.PROVIDER_LIST = [
|
|||||||
'SiaPrime'
|
'SiaPrime'
|
||||||
];
|
];
|
||||||
|
|
||||||
|
exports.PROVIDER_ARG = {
|
||||||
|
hyperspace: '-hs',
|
||||||
|
sia: '',
|
||||||
|
siaprime: '-sp'
|
||||||
|
};
|
||||||
|
|
||||||
exports.IPC_Check_Dependency_Installed = 'check_dependency_installed';
|
exports.IPC_Check_Dependency_Installed = 'check_dependency_installed';
|
||||||
exports.IPC_Check_Dependency_Installed_Reply = 'check_dependency_installed';
|
exports.IPC_Check_Dependency_Installed_Reply = 'check_dependency_installed';
|
||||||
|
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ class MountItems extends Component {
|
|||||||
ipcRenderer.send(Constants.IPC_Mount_Drive, {
|
ipcRenderer.send(Constants.IPC_Mount_Drive, {
|
||||||
Directory: this.props.directory,
|
Directory: this.props.directory,
|
||||||
Location: location,
|
Location: location,
|
||||||
|
NoConsoleSupported: this.props.noConsoleSupported,
|
||||||
StorageType: storageType,
|
StorageType: storageType,
|
||||||
Version: this.props.version,
|
Version: this.props.version,
|
||||||
});
|
});
|
||||||
@@ -145,7 +146,7 @@ class MountItems extends Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
onUnmountDriveReply = (event, arg) => {
|
onUnmountDriveReply = (event, arg) => {
|
||||||
if ((this.props.platform === 'win32') && arg && arg.data && !arg.data.Expected && arg.data.Location && this.props[arg.data.StorageType.toLowerCase()].AutoRestart) {
|
if (arg && arg.data && !arg.data.Expected && arg.data.Location && this.props[arg.data.StorageType.toLowerCase()].AutoRestart) {
|
||||||
this.handleMountUnMount(arg.data.StorageType, true, arg.data.Location)
|
this.handleMountUnMount(arg.data.StorageType, true, arg.data.Location)
|
||||||
} else {
|
} else {
|
||||||
this.detectMounts();
|
this.detectMounts();
|
||||||
|
|||||||
Reference in New Issue
Block a user