import React from 'react';
import TranslatedComponent from './TranslatedComponent';
import { Languages } from '../i18n/Language';
import { Insurance } from '../shipyard/Constants';
import Link from './Link';
import ActiveLink from './ActiveLink';
import cn from 'classnames';
import { Cogs, CoriolisLogo, Hammer, Help, Rocket, StatsBars } from './SvgIcons';
import { Ships } from 'coriolis-data/dist';
import Persist from '../stores/Persist';
import { toDetailedExport } from '../shipyard/Serializer';
import Ship from '../shipyard/Ship';
import ModalBatchOrbis from './ModalBatchOrbis';
import ModalDeleteAll from './ModalDeleteAll';
import ModalExport from './ModalExport';
import ModalHelp from './ModalHelp';
import ModalImport from './ModalImport';
import Slider from './Slider';
import Announcement from './Announcement';
import { outfitURL } from '../utils/UrlGenerators';
const SIZE_MIN = 0.65;
const SIZE_RANGE = 0.55;
/**
* Normalize percentages to 'clean' values
* @param {Number} val Percentage value
* @return {Number} Normalized value
*/
function normalizePercent(val) {
if (val === '' || isNaN(val)) {
return 0;
}
val = Math.round(val * 1000) / 1000;
return val >= 100 ? 100 : val;
}
/**
* Rounds the value to the nearest quarter (0, 0.25, 0.5, 0.75)
* @param {Number} val Value
* @return {Number} Rounded value
*/
function nearestQtrPct(val) {
return Math.round(val * 4) / 4;
}
/**
* Select all text in a field
* @param {SyntheticEvent} e Event
*/
function selectAll(e) {
e.target.select();
}
/**
* Coriolis App Header section / menus
*/
export default class Header extends TranslatedComponent {
/**
* Constructor
* @param {Object} props React Component properties
* @param {Object} context React Component context
*/
constructor(props, context) {
super(props);
this.shipOrder = Object.keys(Ships).sort();
this._setLanguage = this._setLanguage.bind(this);
this._setInsurance = this._setInsurance.bind(this);
this._setShipDiscount = this._setShipDiscount.bind(this);
this._changeShipDiscount = this._changeShipDiscount.bind(this);
this._kpShipDiscount = this._kpShipDiscount.bind(this);
this._setModuleDiscount = this._setModuleDiscount.bind(this);
this._changeModuleDiscount = this._changeModuleDiscount.bind(this);
this._kpModuleDiscount = this._kpModuleDiscount.bind(this);
this._openShips = this._openMenu.bind(this, 's');
this._openBuilds = this._openMenu.bind(this, 'b');
this._openComp = this._openMenu.bind(this, 'comp');
this._openAnnounce = this._openMenu.bind(this, 'announce');
this._getAnnouncementsMenu = this._getAnnouncementsMenu.bind(this);
this._openSettings = this._openMenu.bind(this, 'settings');
this._showHelp = this._showHelp.bind(this);
this.update = this.update.bind(this);
this.languageOptions = [];
this.insuranceOptions = [];
this.state = {
shipDiscount: normalizePercent(Persist.getShipDiscount() * 100),
moduleDiscount: normalizePercent(Persist.getModuleDiscount() * 100),
};
let translate = context.language.translate;
for (let langCode in Languages) {
this.languageOptions.push();
}
for (let name in Insurance) {
this.insuranceOptions.push();
}
}
/**
* Update insurance level
* @param {SyntheticEvent} e Event
*/
_setInsurance(e) {
Persist.setInsurance(e.target.value);
}
/**
* Update the Module discount
*/
_setModuleDiscount() {
let moduleDiscount = normalizePercent(this.state.moduleDiscount);
this.setState({ moduleDiscount });
Persist.setModuleDiscount(moduleDiscount / 100); // Decimal value is stored
}
/**
* Update the Ship discount
*/
_setShipDiscount() {
let shipDiscount = normalizePercent(this.state.shipDiscount);
this.setState({ shipDiscount });
Persist.setShipDiscount(shipDiscount / 100); // Decimal value is stored
}
/**
* Input handler for the module discount field
* @param {SyntheticEvent} e Event
*/
_changeModuleDiscount(e) {
let moduleDiscount = e.target.value;
if (e.target.value === '' || e.target.value === '-' || e.target.value === '.') {
this.setState({ moduleDiscount });
} else if (!isNaN(moduleDiscount) && Math.round(moduleDiscount) < 100) {
this.setState({ moduleDiscount });
}
}
/**
* Input handler for the ship discount field
* @param {SyntheticEvent} e Event
*/
_changeShipDiscount(e) {
let shipDiscount = e.target.value;
if (e.target.value === '' || e.target.value === '-' || e.target.value === '.') {
this.setState({ shipDiscount });
} else if (!isNaN(shipDiscount) && Math.round(shipDiscount) < 100) {
this.setState({ shipDiscount });
}
}
/**
* Key down/press handler for ship discount field
* @param {SyntheticEvent} e Event
*/
_kpShipDiscount(e) {
let sd = this.state.shipDiscount * 1;
switch (e.keyCode) {
case 38:
e.preventDefault();
this.setState({ shipDiscount: e.shiftKey ? nearestQtrPct(sd + 0.25) : normalizePercent(sd + 1) });
break;
case 40:
e.preventDefault();
this.setState({ shipDiscount: e.shiftKey ? nearestQtrPct(sd - 0.25) : normalizePercent(sd - 1) });
break;
case 13:
e.preventDefault();
e.target.blur();
}
}
/**
* Key down/press handler for module discount field
* @param {SyntheticEvent} e Event
*/
_kpModuleDiscount(e) {
let md = this.state.moduleDiscount * 1;
switch (e.keyCode) {
case 38:
e.preventDefault();
this.setState({ moduleDiscount: e.shiftKey ? nearestQtrPct(md + 0.25) : normalizePercent(md + 1) });
break;
case 40:
e.preventDefault();
this.setState({ moduleDiscount: e.shiftKey ? nearestQtrPct(md - 0.25) : normalizePercent(md - 1) });
break;
case 13:
e.preventDefault();
e.target.blur();
}
}
/**
* Update the current language
* @param {SyntheticEvent} e Event
*/
_setLanguage(e) {
Persist.setLangCode(e.target.value);
}
/**
* Toggle tooltips setting
*/
_toggleTooltips() {
Persist.showTooltips(!Persist.showTooltips());
}
/**
* Toggle module resistances setting
*/
_toggleModuleResistances() {
Persist.showModuleResistances(!Persist.showModuleResistances());
}
/**
* Show delete all modal
* @param {SyntheticEvent} e Event
*/
_showDeleteAll(e) {
e.preventDefault();
this.context.showModal();
};
/**
* Show export modal with backup data
* @param {SyntheticEvent} e Event
*/
_showBackup(e) {
let translate = this.context.language.translate;
e.preventDefault();
this.context.showModal();
};
/**
* Uploads all ship-builds to orbis
* @param {e} e Event
*/
_uploadAllBuildsToOrbis(e) {
e.preventDefault();
const data = Persist.getBuilds();
let postObject = [];
for (const ship in data) {
for (const code in data[ship]) {
const shipModel = ship;
if (!shipModel) {
throw 'No such ship found: "' + ship + '"';
}
const shipTemplate = Ships[shipModel];
const shipPostObject = {};
let shipInstance = new Ship(shipModel, shipTemplate.properties, shipTemplate.slots);
shipInstance.buildWith(null);
shipInstance.buildFrom(data[ship][code]);
shipPostObject.coriolisId = shipInstance.id;
shipPostObject.coriolisShip = shipInstance;
shipPostObject.coriolisShip.url = window.location.origin + outfitURL(shipModel, data[ship][code], code);
shipPostObject.title = code || shipInstance.id;
shipPostObject.description = code || shipInstance.id;
shipPostObject.ShipName = shipInstance.id;
shipPostObject.Ship = shipInstance.id;
postObject.push(shipPostObject);
}
}
console.log(postObject);
this.context.showModal();
}
/**
* Show export modal with detailed export
* @param {SyntheticEvent} e Event
*/
_showDetailedExport(e) {
let translate = this.context.language.translate;
e.preventDefault();
this.context.showModal();
}
/**
* Show help modal
* @param {SyntheticEvent} e Event
*/
_showHelp(e) {
let translate = this.context.language.translate;
e.preventDefault();
this.context.showModal();
}
/**
* Show import modal
* @param {SyntheticEvent} e Event
*/
_showImport(e) {
e.preventDefault();
this.context.showModal();
}
/**
* Update the app scale / size ratio
* @param {number} scale scale Size Ratio
*/
_setTextSize(scale) {
Persist.setSizeRatio((scale * SIZE_RANGE) + SIZE_MIN);
}
/**
* Reset the app scale / size ratio
*/
_resetTextSize() {
Persist.setSizeRatio(1);
}
/**
* Open a menu
* @param {string} menu Menu name
* @param {SyntheticEvent} event Event
*/
_openMenu(menu, event) {
event.stopPropagation();
if (this.props.currentMenu == menu) {
menu = null;
}
this.context.openMenu(menu);
}
/**
* Generate the ships menu
* @return {React.Component} Menu
*/
_getShipsMenu() {
let shipList = [];
for (let s of this.shipOrder) {
shipList.push({Ships[s].properties.name});
}
return (
e.stopPropagation() }>
{shipList}
);
}
/**
* Generate the builds menu
* @return {React.Component} Menu
*/
_getBuildsMenu() {
let builds = Persist.getBuilds();
let buildList = [];
for (let shipId of this.shipOrder) {
if (builds[shipId]) {
let shipBuilds = [];
let buildNameOrder = Object.keys(builds[shipId]).sort();
for (let buildName of buildNameOrder) {
let href = outfitURL(shipId, builds[shipId][buildName], buildName);
shipBuilds.push(
{buildName}
);
}
buildList.push(
{Ships[shipId].properties.name}{shipBuilds}
);
}
}
return (
e.stopPropagation() }>
{buildList}
);
}
/**
* Generate the comparison menu
* @return {React.Component} Menu
*/
_getComparisonsMenu() {
let comparisons;
let translate = this.context.language.translate;
if (Persist.hasComparisons()) {
comparisons = [];
let comps = Object.keys(Persist.getComparisons()).sort();
for (let name of comps) {
comparisons.push({name});
}
} else {
comparisons = {translate('none created')};
}
return (
);
}
/**
* Generate the announcement menu
* @return {React.Component} Menu
*/
_getAnnouncementsMenu() {
let announcements;
let translate = this.context.language.translate;
if (this.props.announcements) {
announcements = [];
for (let announce of this.props.announcements) {
announcements.push();
announcements.push();
}
}
return (
);
}
/**
* Generate the settings menu
* @return {React.Component} Menu
*/
_getSettingsMenu() {
let translate = this.context.language.translate;
let tips = Persist.showTooltips();
let moduleResistances = Persist.showModuleResistances();
return (