Continued porting to react, approaching beta

This commit is contained in:
Colin McLeod
2016-01-21 22:06:05 -08:00
parent 653cb30dd9
commit 8227a4e361
86 changed files with 3810 additions and 2030 deletions

View File

@@ -4,7 +4,6 @@ import Page from './Page';
import cn from 'classnames';
import Router from '../Router';
import Persist from '../stores/Persist';
import InterfaceEvents from '../utils/InterfaceEvents';
import { Ships } from 'coriolis-data';
import Ship from '../shipyard/Ship';
import { toDetailedBuild } from '../shipyard/Serializer';
@@ -23,13 +22,26 @@ import Slider from '../components/Slider';
const SPEED_SERIES = ['boost', '4 Pips', '2 Pips', '0 Pips'];
const SPEED_COLORS = ['#0088d2', '#ff8c0d', '#D26D00', '#c06400'];
/**
* The Outfitting Page
*/
export default class OutfittingPage extends Page {
/**
* Constructor
* @param {Object} props React Component properties
* @param {Object} context React Component context
*/
constructor(props, context) {
super(props, context);
this.state = this._initState(context);
}
/**
* [Re]Create initial state from context
* @param {context} context React component context
* @return {Object} New state object
*/
_initState(context) {
let params = context.route.params;
let shipId = params.ship;
@@ -70,12 +82,16 @@ export default class OutfittingPage extends Page {
};
}
/**
* Handle build name change and update state
* @param {SyntheticEvent} event React Event
*/
_buildNameChange(event) {
let stateChanges = {
buildName: event.target.value
}
};
if(Persist.hasBuild(this.state.shipId, stateChanges.buildName)) {
if (Persist.hasBuild(this.state.shipId, stateChanges.buildName)) {
stateChanges.savedCode = Persist.getBuild(this.state.shipId, stateChanges.buildName);
} else {
stateChanges.savedCode = null;
@@ -84,37 +100,55 @@ export default class OutfittingPage extends Page {
this.setState(stateChanges);
}
/**
* Save the current build
*/
_saveBuild() {
let code = this.state.ship.toString();
Persist.saveBuild(this.state.shipId, this.state.buildName, code);
this.setState({ code, savedCode: code});
this.setState({ code, savedCode: code });
}
/**
* Reload build from last save
*/
_reloadBuild() {
this.state.ship.buildFrom(this.state.savedCode);
this._shipUpdated();
}
/**
* Reset build to Stock/Factory defaults
*/
_resetBuild() {
this.state.ship.buildWith(Ships[this.state.shipId].defaults);
this._shipUpdated();
}
/**
* Delete the build
*/
_deleteBuild() {
Persist.deleteBuild(this.state.shipId, this.state.buildName);
Router.go(`/outfit/${this.state.shipId}`);
}
/**
* Serialized and show the export modal
*/
_exportBuild() {
let translate = this.context.language.translate;
let {buildName, ship } = this.state;
InterfaceEvents.showModal(<ModalExport
let { buildName, ship } = this.state;
this.context.showModal(<ModalExport
title={buildName + ' ' + translate('export')}
description={translate('PHRASE_EXPORT_DESC')}
data={toDetailedBuild(buildName, ship, ship.toString())}
/>);
}
/**
* Trigger render on ship model change
*/
_shipUpdated() {
let { shipId, buildName, ship, fuelCapacity } = this.state;
let code = ship.toString();
@@ -127,6 +161,12 @@ export default class OutfittingPage extends Page {
this.setState({ code });
}
/**
* Update the current route based on build
* @param {string} shipId Ship Id
* @param {string} code Serialized ship 'code'
* @param {string} buildName Current build name
*/
_updateRoute(shipId, code, buildName) {
let qStr = '';
@@ -137,6 +177,10 @@ export default class OutfittingPage extends Page {
Router.replace(`/outfit/${shipId}/${code}${qStr}`);
}
/**
* Update current fuel level
* @param {number} fuelLevel Fuel leval 0 - 1
*/
_fuelChange(fuelLevel) {
let ship = this.state.ship;
let fuelCapacity = ship.fuelCapacity;
@@ -150,34 +194,57 @@ export default class OutfittingPage extends Page {
});
}
/**
* Update dimenions from rendered DOM
*/
_updateDimensions() {
this.setState({
chartWidth: findDOMNode(this.refs.chartThird).offsetWidth
});
}
/**
* Update state based on context changes
* @param {Object} nextProps Incoming/Next properties
* @param {Object} nextContext Incoming/Next conext
*/
componentWillReceiveProps(nextProps, nextContext) {
if (this.context.route !== nextContext.route) { // Only reinit state if the route has changed
this.setState(this._initState(nextContext));
}
}
componentWillMount(){
this.resizeListener = InterfaceEvents.addListener('windowResized', this._updateDimensions);
/**
* Add listeners when about to mount
*/
componentWillMount() {
this.resizeListener = this.context.onWindowResize(this._updateDimensions);
}
componentDidMount(){
/**
* Trigger DOM updates on mount
*/
componentDidMount() {
this._updateDimensions();
}
componentWillUnmount(){
/**
* Remove listeners on unmount
*/
componentWillUnmount() {
this.resizeListener.remove();
}
/**
* Render the Page
* @return {React.Component} The page contents
*/
render() {
let { translate, units, formats } = this.context.language;
let { translate, units, formats, termtip } = this.context.language;
let tip = this.context.termtip;
let hide = this.context.tooltip.bind(null, null);
let state = this.state;
let { ship, code, savedCode, buildName, chartWidth } = state;
let { ship, code, savedCode, buildName, chartWidth, fuelCapacity, fuelLevel } = state;
let menu = this.props.currentMenu;
let shipUpdated = this._shipUpdated;
let hStr = ship.getHardpointsString();
@@ -185,25 +252,25 @@ export default class OutfittingPage extends Page {
let iStr = ship.getInternalString();
return (
<div id='outfit' className={'page'} style={{ fontSize: (this.context.sizeRatio * 0.9) + 'em'}}>
<div id='outfit' className={'page'} style={{ fontSize: (this.context.sizeRatio * 0.9) + 'em' }}>
<div id='overview'>
<h1>{ship.name}</h1>
<div id='build'>
<input value={buildName} onChange={this._buildNameChange} placeholder={translate('Enter Name')} maxsize={50} />
<button onClick={this._saveBuild} disabled={!buildName || savedCode && code == savedCode}>
<FloppyDisk className='lg'/><span className='button-lbl'>{translate('save')}</span>
<button onClick={this._saveBuild} disabled={!buildName || savedCode && code == savedCode} onMouseOver={tip.bind(null, 'save')} onMouseOut={hide}>
<FloppyDisk className='lg' />
</button>
<button onClick={this._reloadBuild} disabled={!savedCode || code == savedCode}>
<Reload className='lg'/><span className='button-lbl' >{translate('reload')}</span>
<button onClick={this._reloadBuild} disabled={!savedCode || code == savedCode} onMouseOver={tip.bind(null, 'reload')} onMouseOut={hide}>
<Reload className='lg'/>
</button>
<button className={'danger'} onClick={this._deleteBuild} disabled={!savedCode}>
<button className={'danger'} onClick={this._deleteBuild} disabled={!savedCode} onMouseOver={tip.bind(null, 'delete')} onMouseOut={hide}>
<Bin className='lg'/>
</button>
<button onClick={this._resetBuild} disabled={!code}>
<Switch className='lg'/><span className='button-lbl'>{translate('reset')}</span>
<button onClick={this._resetBuild} disabled={!code} onMouseOver={tip.bind(null, 'reset')} onMouseOut={hide}>
<Switch className='lg'/>
</button>
<button onClick={this._exportBuild} disabled={!buildName}>
<Download className='lg'/><span className='button-lbl'>{translate('export')}</span>
<button onClick={this._exportBuild} disabled={!buildName} onMouseOver={tip.bind(null, 'export')} onMouseOut={hide}>
<Download className='lg'/>
</button>
</div>
</div>
@@ -261,12 +328,12 @@ export default class OutfittingPage extends Page {
</div>
<div className='group half'>
<table style={{ width: '100%', lineHeight: '1em'}}>
<table style={{ width: '100%', lineHeight: '1em' }}>
<tbody >
<tr>
<td style={{ verticalAlign: 'top', padding:0 }}><Fuel className='xl primary-disabled' /></td>
<td><Slider axis={true} onChange={this._fuelChange} axisUnit={translate('T')} percent={state.fuelLevel} max={state.fuelCapacity} /></td>
<td className='primary' style={{ width: '10em', verticalAlign: 'top', fontSize: '0.9em' }}>{formats.f2(state.fuelLevel * ship.fuelCapacity)}{units.T} {formats.pct1(state.fuelLevel)}</td>
<td><Slider axis={true} onChange={this._fuelChange} axisUnit={translate('T')} percent={fuelLevel} max={fuelCapacity} /></td>
<td className='primary' style={{ width: '10em', verticalAlign: 'top', fontSize: '0.9em' }}>{formats.f2(fuelLevel * fuelCapacity)}{units.T} {formats.pct1(fuelLevel)}</td>
</tr>
</tbody>
</table>