Initial commit

This commit is contained in:
Scott E. Graves
2018-09-25 12:30:15 -05:00
commit a778b6dd25
52 changed files with 3450 additions and 0 deletions

564
src/App.js Normal file
View File

@@ -0,0 +1,564 @@
import React, {Component} from 'react';
import CSSModules from 'react-css-modules';
import styles from './App.css';
import Box from './components/UI/Box/Box';
import DropDown from './components/UI/DropDown/DropDown';
import * as Constants from './constants';
import axios from 'axios';
import MountItems from './containers/MountItems/MountItems';
import DependencyList from './components/DependencyList/DependencyList';
import Button from './components/UI/Button/Button';
import Modal from './components/UI/Modal/Modal';
import DownloadProgress from './components/DownloadProgress/DownloadProgress';
import UpgradeUI from './components/UpgradeUI/UpgradeUI';
import UpgradeIcon from './components/UpgradeIcon/UpgradeIcon';
const Scheduler = require('node-schedule');
let ipcRenderer = null;
if (!process.versions.hasOwnProperty('electron')) {
ipcRenderer = ((window && window.require) ? window.require('electron').ipcRenderer : null);
}
class App extends Component {
constructor(props) {
super(props);
if (ipcRenderer) {
ipcRenderer.on('get_platform_reply', (event, arg) => {
this.setState({
Platform: arg.data,
});
ipcRenderer.send('get_state', Constants.DATA_LOCATIONS[arg.data]);
});
ipcRenderer.on('get_state_reply', (event, arg) => {
if (arg.data) {
if (arg.data.Hyperspace.AutoMount === undefined) {
arg.data.Hyperspace['AutoMount'] = false;
}
if (arg.data.Sia.AutoMount === undefined) {
arg.data.Sia['AutoMount'] = false;
}
this.setState({
Hyperspace: arg.data.Hyperspace,
Release: arg.data.Release,
Sia: arg.data.Sia,
Version: arg.data.Version,
});
}
this.grabReleases();
});
ipcRenderer.on('grab_releases_reply', ()=> {
axios.get(Constants.RELEASES_URL)
.then(response => {
const versionLookup = {
Alpha: response.data.Versions.Alpha[this.state.Platform],
Beta: response.data.Versions.Beta[this.state.Platform],
RC: response.data.Versions.RC[this.state.Platform],
Release: response.data.Versions.Release[this.state.Platform],
};
const locationsLookup = {
...response.data.Locations[this.state.Platform],
};
this.setState({
AllowOptions: true,
LocationsLookup: locationsLookup,
VersionLookup: versionLookup,
});
this.checkVersionInstalled(this.state.Release, this.state.Version, versionLookup);
}).catch(error => {
console.log(error);
});
});
ipcRenderer.on('grab_ui_releases_reply', ()=> {
axios.get(Constants.UI_RELEASES_URL)
.then(response => {
const data = response.data;
if (data.Versions &&
data.Versions[this.state.Platform] &&
(data.Versions[this.state.Platform].length > 0) &&
(data.Versions[this.state.Platform][0] !== this.props.version)) {
this.setState({
UpgradeAvailable: true,
UpgradeDismissed: false,
UpgradeData: data.Locations[this.state.Platform][data.Versions[this.state.Platform][0]],
});
}
}).catch(error => {
console.log(error);
});
});
ipcRenderer.on('download_file_progress', (event, arg) => {
this.setState({
DownloadProgress: arg.data.Progress,
});
});
ipcRenderer.on('download_file_complete', (event, arg) => {
if (this.state.DownloadingRelease) {
if (arg.data.Success) {
const selectedVersion = this.state.VersionLookup[this.state.ReleaseTypes[this.state.Release]][this.state.Version];
ipcRenderer.send('extract_release', {
Directory: Constants.DATA_LOCATIONS[this.state.Platform],
Source: arg.data.Destination,
Version: selectedVersion,
});
}
this.setState({
DownloadActive: false,
DownloadProgress: 0.0,
DownloadingRelease: false,
ExtractActive: arg.data.Success,
DownloadName: '',
});
} else if (this.state.DownloadingDependency) {
if (arg.data.Success) {
ipcRenderer.send('install_dependency', {
Source: arg.data.Destination,
});
}
this.setState({
DownloadActive: false,
DownloadProgress: 0.0,
DownloadingDependency: arg.data.Success,
DownloadName: '',
});
} else if (this.state.DownloadingUpgrade) {
if (arg.data.Success) {
ipcRenderer.send('install_upgrade', {
Source: arg.data.Destination,
});
} else {
this.setState({
DownloadActive: false,
DownloadProgress: 0.0,
DownloadingUpgrade: false,
DownloadName: '',
});
}
} else {
this.setState({
DownloadActive: false,
DownloadProgress: 0.0,
DownloadName: '',
});
}
});
ipcRenderer.on('extract_release_complete', (event, arg) => {
ipcRenderer.send('delete_file', {
FilePath: arg.data.Source,
});
this.setState({
ExtractActive: false,
});
this.checkVersionInstalled(this.state.Release, this.state.Version);
});
ipcRenderer.on('check_installed_reply', (event, arg) => {
this.setState({
AllowDownload: true,
DownloadingDependency: false,
MissingDependencies: arg.data.Dependencies,
RepertoryVersion: arg.data.Success && arg.data.Exists ? arg.data.Version : 'none',
});
});
ipcRenderer.on('install_dependency_reply', (event, arg) => {
ipcRenderer.send('delete_file', {
FilePath: arg.data.Source,
});
this.checkVersionInstalled(this.state.Release, this.state.Version);
});
ipcRenderer.on('install_upgrade_reply', (event, arg) => {
ipcRenderer.sendSync('delete_file', {
FilePath: arg.data.Source,
});
this.setState({
DownloadActive: false,
DownloadProgress: 0.0,
DownloadName: '',
});
});
ipcRenderer.send('get_platform');
Scheduler.scheduleJob('23 11 * * *', this.updateCheckScheduledJob);
}
}
state = {
AllowOptions: false,
AllowDownload: false,
AutoMountChecked: false,
DownloadActive: false,
DownloadProgress: 0.0,
DownloadingDependency: false,
DownloadName: '',
DownloadingRelease: false,
DownloadingUpgrade: false,
ExtractActive: false,
Hyperspace: {
AutoMount: false,
MountLocation: '',
},
LocationsLookup: {},
MissingDependencies: [],
Platform: 'unknown',
Release: 3,
ReleaseTypes: [
'Release',
'RC',
'Beta',
'Alpha',
],
RepertoryVersion: 'none',
Sia: {
AutoMount: false,
MountLocation: '',
},
UpgradeAvailable: false,
UpgradeData: {},
UpgradeDismissed: false,
Version: 0,
VersionLookup: {
Alpha: [
'unavailable'
],
Beta: [
'unavailable'
],
RC: [
'unavailable'
],
Release: [
'unavailable'
],
}
};
checkVersionInstalled = (release, version, versionLookup) => {
if (!versionLookup) {
versionLookup = this.state.VersionLookup;
}
const selectedVersion = versionLookup[this.state.ReleaseTypes[release]][version];
this.setState({
AllowDownload: false,
});
if (ipcRenderer) {
let dependencies = [];
if (this.state.LocationsLookup[selectedVersion] && this.state.LocationsLookup[selectedVersion].dependencies) {
dependencies = this.state.LocationsLookup[selectedVersion].dependencies;
}
ipcRenderer.send('check_installed', {
Dependencies: dependencies,
Directory: Constants.DATA_LOCATIONS[this.state.Platform],
Version: selectedVersion,
});
}
};
grabReleases = () => {
if (this.state.Platform !== 'unknown') {
if (ipcRenderer) {
ipcRenderer.send('grab_releases');
ipcRenderer.send('grab_ui_releases');
}
}
};
handleAutoMountChanged = (storageType, e) => {
let sia = {
...this.state.Sia
};
let hyperspace = {
...this.state.Hyperspace
};
if (storageType === 'Hyperspace') {
hyperspace.AutoMount = e.target.checked;
this.setState({
Hyperspace: hyperspace,
});
} else if (storageType === 'Sia') {
sia.AutoMount = e.target.checked;
this.setState({
Sia: sia,
});
}
this.saveState(this.state.Release, this.state.Version, sia, hyperspace);
};
handleDependencyDownload = (url) => {
if (ipcRenderer) {
const items = url.split('/');
const fileName = items[items.length - 1];
this.setState({
DownloadActive: true,
DownloadingDependency: true,
DownloadName: fileName,
});
ipcRenderer.send('download_file', {
Directory: Constants.DATA_LOCATIONS[this.state.Platform],
Filename: fileName,
URL: url,
});
}
};
handleMountLocationChanged = (storageType, location) => {
const state = {
...this.state[storageType],
MountLocation: location,
};
this.setState({
[storageType]: state,
});
const hyperspace = (storageType === 'Hyperspace') ? state : {
...this.state.Hyperspace,
};
const sia = storageType === 'Sia' ? state : {
...this.state.Sia,
};
this.saveState(this.state.Release, this.state.Version, sia, hyperspace);
};
handleReleaseChanged = (e) => {
const val = parseInt(e.target.value, 10);
this.setState({
Release: val,
Version: 0
});
this.saveState(val, 0, this.state.Sia, this.state.Hyperspace);
this.checkVersionInstalled(val, 0);
};
handleReleaseDownload = () => {
const selectedVersion = this.state.VersionLookup[this.state.ReleaseTypes[this.state.Release]][this.state.Version];
const fileName = selectedVersion + '.zip';
if (ipcRenderer) {
this.setState({
DownloadActive: true,
DownloadingRelease: true,
DownloadName: fileName,
});
ipcRenderer.send('download_file', {
Directory: Constants.DATA_LOCATIONS[this.state.Platform],
Filename: fileName,
URL: this.state.LocationsLookup[selectedVersion].urls[0],
});
}
};
handleUIDownload = () => {
if (ipcRenderer) {
this.setState({
DownloadActive: true,
DownloadingUpgrade: true,
DownloadName: 'UI Upgrade',
});
ipcRenderer.send('download_file', {
Directory: Constants.DATA_LOCATIONS[this.state.Platform],
Filename: this.state.Platform === 'win32' ? 'upgrade.exe' : 'upgrade',
URL: this.state.UpgradeData.urls[0],
});
} else {
this.setState({UpgradeDismissed: true});
}
};
handleVersionChanged = (e) => {
const val = parseInt(e.target.value, 10);
this.setState({
Version: val
});
this.saveState(this.state.Release, val, this.state.Sia, this.state.Hyperspace);
this.checkVersionInstalled(this.state.Release, val);
};
notifyAutoMountProcessed = () => {
this.setState({AutoMountChecked: true});
};
saveState = (release, version, sia, hyperspace)=> {
if (ipcRenderer) {
ipcRenderer.send('save_state', {
Directory: Constants.DATA_LOCATIONS[this.state.Platform],
State: {
Hyperspace: hyperspace,
Release: release,
Sia: sia,
Version: version,
}
});
}
};
updateCheckScheduledJob = () => {
if (this.state.Platform !== 'unknown') {
if (ipcRenderer) {
ipcRenderer.send('grab_ui_releases');
}
}
};
render() {
const selectedVersion = this.state.VersionLookup[this.state.ReleaseTypes[this.state.Release]][this.state.Version];
const downloadEnabled = this.state.AllowDownload &&
!this.state.DownloadActive &&
(((selectedVersion !== 'unavailable') && (selectedVersion !== this.state.RepertoryVersion)));
const allowMount = this.state.RepertoryVersion !== 'none';
const missingDependencies = (this.state.MissingDependencies.length > 0);
let mountDisplay = null;
if (allowMount) {
mountDisplay = <MountItems platform={this.state.Platform}
sia={this.state.Sia}
hyperspace={this.state.Hyperspace}
changed={this.handleMountLocationChanged}
processAutoMount={!this.state.AutoMountChecked}
autoMountProcessed={this.notifyAutoMountProcessed}
autoMountChanged={this.handleAutoMountChanged}
version={this.state.RepertoryVersion}
directory={Constants.DATA_LOCATIONS[this.state.Platform]}
disabled={!allowMount}/>;
}
let dependencyDisplay = null;
if (missingDependencies && !this.state.DownloadActive) {
dependencyDisplay = (
<Modal>
<DependencyList allowDownload={!this.state.DownloadingDependency}
dependencies={this.state.MissingDependencies}
onDownload={this.handleDependencyDownload}/>
}
</Modal>
)
}
let downloadDisplay = null;
if (this.state.DownloadActive) {
downloadDisplay = (
<Modal>
<DownloadProgress progress={this.state.DownloadProgress}
display={this.state.DownloadName}/>
</Modal>);
}
let releaseDisplay = null;
if (this.state.ExtractActive) {
releaseDisplay = <h3 style={{textAlign: 'center'}}>{'Activating <' + selectedVersion + '>'}</h3>
} else {
releaseDisplay = <Button disabled={!downloadEnabled}
clicked={this.handleReleaseDownload}>Install</Button>;
}
let upgradeDisplay = null;
if (!missingDependencies &&
!this.state.DownloadActive &&
this.state.UpgradeAvailable &&
!this.state.UpgradeDismissed) {
upgradeDisplay = (
<Modal>
<UpgradeUI upgrade={this.handleUIDownload}
cancel={()=>this.setState({UpgradeDismissed: true})}/>
</Modal>
);
}
let options = null;
if (this.state.AllowOptions) {
options = (
<table width='100%' cellPadding='2'>
<tbody>
<tr>
<td width='33%'>
<h2>Release</h2>
</td>
<td width='33%'>
<h2>Version</h2>
</td>
<td width='33%'>
<h2>Installed</h2>
</td>
</tr>
<tr>
<td>
<DropDown disabled={this.state.DownloadActive || this.state.ExtractActive}
items={this.state.ReleaseTypes}
selected={this.state.Release}
changed={this.handleReleaseChanged}/>
</td>
<td>
<DropDown disabled={this.state.DownloadActive || this.state.ExtractActive}
items={this.state.VersionLookup[this.state.ReleaseTypes[this.state.Release]]}
selected={this.state.Version}
changed={this.handleVersionChanged}/>
</td>
<td>
{this.state.RepertoryVersion}
</td>
</tr>
<tr>
<td colSpan={3}>
{releaseDisplay}
</td>
</tr>
<tr>
<td colSpan={3}>
{mountDisplay}
</td>
</tr>
</tbody>
</table>);
}
return (
<div styleName='App'>
{dependencyDisplay}
{upgradeDisplay}
{downloadDisplay}
<Box dxDark dxStyle={{'height': 'auto', 'padding': '2px'}}>
<table cellPadding={0} cellSpacing={0} style={{margin: 0, padding: 0}}>
<tbody style={{margin: 0, padding: 0}}>
<tr style={{margin: 0, padding: 0}}>
<td width='33%' style={{margin: 0, padding: 0}}/>
<td width='33%' style={{margin: 0, padding: 0}}>
<h1 style={{'textAlign': 'center'}}>{'Repertory UI v' + this.props.version}</h1>
</td>
<td width='33%' style={{margin: 0, padding: 0}} align='right' valign='middle'>
<UpgradeIcon
available={this.state.UpgradeAvailable}
clicked={()=>this.setState({UpgradeDismissed: false})}/>
</td>
</tr>
</tbody>
</table>
</Box>
<Box dxStyle={{'padding': '4px', 'marginTop': '10px'}}>
{options}
</Box>
</div>
);
}
}
export default CSSModules(App, styles, {allowMultiple: true});