mirror of
https://github.com/EDCD/coriolis.git
synced 2025-12-10 07:05:35 +00:00
Continued porting to react, approaching beta
This commit is contained in:
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user