diff --git a/src/app/pages/ComparisonPage.jsx b/src/app/pages/ComparisonPage.jsx
deleted file mode 100644
index 9aacce4d..00000000
--- a/src/app/pages/ComparisonPage.jsx
+++ /dev/null
@@ -1,626 +0,0 @@
-import React from 'react';
-import Page from './Page';
-import Router from '../Router';
-import cn from 'classnames';
-import { Ships } from 'coriolis-data/dist';
-import { fromComparison, toComparison } from '../shipyard/Serializer';
-import Persist from '../stores/Persist';
-import { SizeMap, ShipFacets } from '../shipyard/Constants';
-import ComparisonTable from '../components/ComparisonTable';
-import BarChart from '../components/BarChart';
-import ModalCompare from '../components/ModalCompare';
-import ModalExport from '../components/ModalExport';
-import ModalPermalink from '../components/ModalPermalink';
-import ModalImport from '../components/ModalImport';
-import {
- FloppyDisk,
- Bin,
- Download,
- Embed,
- Rocket,
- LinkIcon
-} from '../components/SvgIcons';
-import ShortenUrl from '../utils/ShortenUrl';
-import { comparisonBBCode } from '../utils/BBCode';
-const browser = require('detect-browser');
-
-/**
- * Creates a comparator based on the specified predicate
- * @param {string} predicate Predicate / propterty name
- * @return {Function} Comparator
- */
-function sortBy(predicate) {
- return (a, b) => {
- if (a[predicate] === b[predicate]) {
- if (a.name == b.name) {
- a.buildName.toLowerCase() > b.buildName.toLowerCase() ? 1 : -1;
- }
- return a.name.toLowerCase() > b.name.toLowerCase() ? 1 : -1;
- }
- if (typeof a[predicate] == 'string') {
- return a[predicate].toLowerCase() > b[predicate].toLowerCase() ? 1 : -1;
- }
- return a[predicate] > b[predicate] ? 1 : -1;
- };
-}
-
-/**
- * Comparison Page
- */
-export default class ComparisonPage extends Page {
- /**
- * Constructor
- * @param {Object} props React Component properties
- * @param {Object} context React Component context
- */
- constructor(props, context) {
- super(props, context);
- this._sortShips = this._sortShips.bind(this);
- this._buildsSelected = this._buildsSelected.bind(this);
- this._updateDiscounts = this._updateDiscounts.bind(this);
- 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 defaultFacets = [13, 12, 11, 9, 6, 4, 1, 3, 2]; // Reverse order of Armour, Shields, Speed, Jump Range, Cargo Capacity, Cost, DPS, EPS, HPS
- let params = context.route.params;
- let code = params.code;
- let name = params.name ? decodeURIComponent(params.name) : null;
- let newName = '';
- let compareMode = !code;
- let builds = [];
- let saved = false;
- let predicate = 'name';
- let desc = false;
- let importObj = {};
-
- if (compareMode) {
- if (name == 'all') {
- let allBuilds = Persist.getBuilds();
- newName = name;
- for (let shipId in allBuilds) {
- for (let buildName in allBuilds[shipId]) {
- if (buildName && allBuilds[shipId][buildName]) {
- builds.push(
- this._createBuild(
- shipId,
- buildName,
- allBuilds[shipId][buildName]
- )
- );
- }
- }
- }
- } else {
- let comparisonData = Persist.getComparison(name);
- if (comparisonData) {
- defaultFacets = comparisonData.facets;
- comparisonData.builds.forEach(b =>
- builds.push(this._createBuild(b.shipId, b.buildName))
- );
- saved = true;
- newName = name;
- }
- }
- } else {
- try {
- let comparisonData = toComparison(code);
- defaultFacets = comparisonData.f;
- newName = name = comparisonData.n;
- predicate = comparisonData.p;
- desc = comparisonData.d;
- comparisonData.b.forEach(build => {
- builds.push(this._createBuild(build.s, build.n, build.c));
- if (!importObj[build.s]) {
- importObj[build.s] = {};
- }
- importObj[build.s][build.n] = build.c;
- });
- } catch (e) {
- throw { type: 'bad-comparison', message: e.message, details: e };
- }
- }
-
- let facets = [];
- let selectedLength = defaultFacets.length;
- let selectedFacets = new Array(selectedLength);
-
- for (let i = 0; i < ShipFacets.length; i++) {
- let facet = Object.assign({}, ShipFacets[i]);
- let defaultIndex = defaultFacets.indexOf(facet.i);
- if (defaultIndex == -1) {
- facets.push(facet);
- } else {
- facet.active = true;
- selectedFacets[selectedLength - defaultIndex - 1] = facet;
- }
- }
-
- facets = selectedFacets.concat(facets);
- builds.sort(sortBy(predicate));
-
- return {
- title: 'Coriolis EDCD Edition - Compare',
- predicate,
- desc,
- facets,
- builds,
- compareMode,
- code,
- name,
- newName,
- saved,
- importObj
- };
- }
- /**
- * Create a Ship instance / build
- * @param {string} id Ship Id
- * @param {name} name Build name
- * @param {string} code Optional - Serialized ship code
- * @return {Object} Ship instance with build name
- */
- _createBuild(id, name, code) {
- code = code ? code : Persist.getBuild(id, name); // Retrieve build code if not passed
-
- if (!code) {
- // No build found
- return;
- }
-
- let data = Ships[id]; // Get ship properties
- let b = new Ship(id, data.properties, data.slots); // Create a new Ship instance
- b.buildFrom(code); // Populate components from code
- b.buildName = name;
- b.applyDiscounts(Persist.getShipDiscount(), Persist.getModuleDiscount());
- return b;
- }
-
- /**
- * Update state with the specified sort predicates
- * @param {String} predicate Sort predicate - property name
- */
- _sortShips(predicate) {
- let { builds, desc } = this.state;
- if (this.state.predicate == predicate) {
- desc = !desc;
- }
-
- builds.sort(sortBy(predicate));
-
- if (desc) {
- builds.reverse();
- }
-
- this.setState({ predicate, desc });
- }
-
- /**
- * Show selected builds modal
- */
- _selectBuilds() {
- this.context.showModal(
-
- );
- }
-
- /**
- * Update selected builds with new list
- * @param {Array} newBuilds List of new builds
- */
- _buildsSelected(newBuilds) {
- this.context.hideModal();
- let builds = [];
-
- for (let b of newBuilds) {
- builds.push(this._createBuild(b.id, b.buildName));
- }
-
- this.setState({ builds, saved: false });
- }
-
- /**
- * Toggle facet display
- * @param {string} facet Facet / Ship Property
- */
- _toggleFacet(facet) {
- facet.active = !facet.active;
- this.setState({ facets: [].concat(this.state.facets), saved: false });
- }
-
- /**
- * Handle facet drag
- * @param {Event} e Drag Event
- */
- _facetDrag(e) {
- this.nodeAfter = false;
- this.dragged = e.currentTarget;
- let placeholder = (this.placeholder = document.createElement('li'));
- placeholder.style.width = Math.round(this.dragged.offsetWidth) + 'px';
- placeholder.className = 'facet-placeholder';
- if (!browser || (browser.name !== 'edge' && browser.name !== 'ie')) {
- e.dataTransfer.effectAllowed = 'move';
- e.dataTransfer.setData('text/html', e.currentTarget);
- }
- }
-
- /**
- * Handle facet drop
- * @param {Event} e Drop Event
- */
- _facetDrop(e) {
- this.dragged.parentNode.removeChild(this.placeholder);
- let facets = this.state.facets;
- let frm = Number(this.dragged.dataset.i);
- let to = Number(this.over.dataset.i);
-
- if (frm < to) {
- to--;
- }
- if (this.nodeAfter) {
- to++;
- }
-
- facets.splice(to, 0, facets.splice(frm, 1)[0]);
- this.dragged.style.display = null;
- this.setState({ facets: [].concat(facets), saved: false });
- }
-
- /**
- * Handle facet drag over
- * @param {Event} e Drag over Event
- */
- _facetDragOver(e) {
- e.preventDefault();
-
- if (e.target.className == 'facet-placeholder') {
- return;
- } else if (e.target != e.currentTarget) {
- this.over = e.target;
- this.dragged.style.display = 'none';
- let relX = e.clientX - this.over.getBoundingClientRect().left;
- let width = this.over.offsetWidth / 2;
- let parent = e.target.parentNode;
-
- if (parent == e.currentTarget) {
- if (relX > width && this.dragged != e.target) {
- this.nodeAfter = true;
- parent.insertBefore(this.placeholder, e.target.nextElementSibling);
- } else {
- this.nodeAfter = false;
- parent.insertBefore(this.placeholder, e.target);
- }
- }
- }
- }
- /**
- * Handle name change and update state
- * @param {SyntheticEvent} e Event
- */
- _onNameChange(e) {
- this.setState({ newName: e.target.value, saved: false });
- }
-
- /**
- * Delete the current comparison
- */
- _delete() {
- Persist.deleteComparison(this.state.name);
- Router.go('/compare');
- }
-
- /**
- * Import the comparison builds
- */
- _import() {
- let builds = {};
-
- for (let ship of this.state.builds) {
- if (!builds[ship.id]) {
- builds[ship.id] = {};
- }
- builds[ship.id][ship.buildName] = ship.toString();
- }
-
- this.context.showModal(
);
- }
-
- /**
- * Save the current comparison
- */
- _save() {
- let { newName, builds, facets } = this.state;
- let selectedFacets = [];
-
- facets.forEach(f => {
- if (f.active) {
- selectedFacets.unshift(f.i);
- }
- });
-
- Persist.saveComparison(newName, builds, selectedFacets);
- Router.replace(`/compare/${encodeURIComponent(this.state.newName)}`);
- this.setState({ name: newName, saved: true });
- }
-
- /**
- * Serialize and generate a long URL for the current comparison
- * @return {string} URL for serialized comparison
- */
- _buildUrl() {
- let { facets, builds, name, predicate, desc } = this.state;
- let selectedFacets = [];
-
- for (let f of facets) {
- if (f.active) {
- selectedFacets.unshift(f.i);
- }
- }
-
- let code = fromComparison(name, builds, selectedFacets, predicate, desc);
- let loc = window.location;
- return (
- loc.protocol +
- '//' +
- loc.host +
- '/comparison?code=' +
- encodeURIComponent(code)
- );
- }
-
- /**
- * Generates the long permalink URL
- */
- _genPermalink() {
- this.context.showModal(
);
- }
-
- /**
- * Generate E:D Forum BBCode and show in the export modal
- */
- _genBBcode() {
- let { translate, formats } = this.context.language;
- let { facets, builds } = this.state;
-
- let generator = callback => {
- let url = this._buildUrl();
- ShortenUrl(
- url,
- shortenedUrl =>
- callback(
- comparisonBBCode(translate, formats, facets, builds, shortenedUrl)
- ),
- error =>
- callback(comparisonBBCode(translate, formats, facets, builds, url))
- );
- };
-
- this.context.showModal(
-
- );
- }
-
- /**
- * Update dimenions from rendered DOM
- */
- _updateDimensions() {
- this.setState({
- chartWidth: this.chartRef.offsetWidth
- });
- }
-
- /**
- * Update all ship costs on disount change
- */
- _updateDiscounts() {
- let shipDiscount = Persist.getShipDiscount();
- let moduleDiscount = Persist.getModuleDiscount();
- let builds = [];
-
- for (let b of this.state.builds) {
- builds.push(b.applyDiscounts(shipDiscount, moduleDiscount));
- }
-
- this.setState({ builds });
- }
-
- /**
- * 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));
- }
- }
-
- /**
- * Add listeners when about to mount
- */
- componentWillMount() {
- this.resizeListener = this.context.onWindowResize(this._updateDimensions);
- this.persistListener = Persist.addListener(
- 'discounts',
- this._updateDiscounts
- );
- }
-
- /**
- * Trigger DOM updates on mount
- */
- componentDidMount() {
- this._updateDimensions();
- }
-
- /**
- * Remove listeners on unmount
- */
- componentWillUnmount() {
- this.resizeListener.remove();
- this.persistListener.remove();
- }
-
- /**
- * Render the Page
- * @return {React.Component} The page contents
- */
- renderPage() {
- let translate = this.context.language.translate;
- let compareHeader;
- let {
- newName,
- name,
- saved,
- builds,
- facets,
- predicate,
- desc,
- chartWidth
- } = this.state;
-
- if (this.state.compareMode) {
- compareHeader = (
-
- | {translate('comparison')} |
-
-
-
-
-
-
-
- |
-
- );
- } else {
- compareHeader = (
-
- | {translate('comparison')} |
-
- {name}
-
- |
-
- );
- }
-
- return (
-
-
-
- {compareHeader}
-
- | {translate('compare')} |
-
-
- {facets.map((f, i) => (
- -
- {'↔ ' + translate(f.title)}
-
- ))}
-
- |
-
-
-
-
-
-
- {!builds.length ? (
-
(this.chartRef = node)}>
- {translate('PHRASE_NO_BUILDS')}
-
- ) : (
- facets.filter(f => f.active).map((f, i) => (
-
(this.chartRef = node) : null}
- >
-
- {translate(f.title)}
-
-
-
- ))
- )}
-
- );
- }
-}
diff --git a/src/app/stores/Persist.js b/src/app/stores/Persist.js
index d0be7ef9..eb0eeb0a 100644
--- a/src/app/stores/Persist.js
+++ b/src/app/stores/Persist.js
@@ -2,7 +2,6 @@ import { EventEmitter } from 'fbemitter';
import { Insurance } from '../shipyard/Constants';
const LS_KEY_BUILDS = 'builds';
-const LS_KEY_COMPARISONS = 'comparisons';
const LS_KEY_LANG = 'NG_TRANSLATE_LANG_KEY';
const LS_KEY_COST_TAB = 'costTab';
const LS_KEY_CMDR_NAME = 'cmdrName';
@@ -93,7 +92,6 @@ export class Persist extends EventEmitter {
let shipDiscount = _get(LS_KEY_SHIP_DISCOUNT);
let moduleDiscount = _get(LS_KEY_MOD_DISCOUNT);
let buildJson = _get(LS_KEY_BUILDS);
- let comparisonJson = _get(LS_KEY_COMPARISONS);
this.orbisCreds = _get(LS_KEY_ORBIS) || { email: '', password: '' };
this.onStorageChange = this.onStorageChange.bind(this);
@@ -102,7 +100,6 @@ export class Persist extends EventEmitter {
this.shipDiscount = !isNaN(shipDiscount) && shipDiscount < 1 ? shipDiscount * 1 : 0;
this.moduleDiscount = !isNaN(moduleDiscount) && moduleDiscount < 1 ? moduleDiscount * 1 : 0;
this.builds = buildJson && typeof buildJson == 'object' ? buildJson : {};
- this.comparisons = comparisonJson && typeof comparisonJson == 'object' ? comparisonJson : {};
this.costTab = _getString(LS_KEY_COST_TAB);
this.outfittingTab = _getString(LS_KEY_OUTFITTING_TAB);
this.state = _get(LS_KEY_STATE);
@@ -137,10 +134,6 @@ export class Persist extends EventEmitter {
this.builds = newValue ? JSON.parse(newValue) : {};
this.emit('builds');
break;
- case LS_KEY_COMPARISONS:
- this.comparisons = newValue ? JSON.parse(newValue) : {};
- this.emit('comparisons');
- break;
case LS_KEY_LANG:
this.langCode = newValue;
this.emit('language', newValue);
@@ -334,97 +327,16 @@ export class Persist extends EventEmitter {
delete this.builds[shipId];
}
_put(LS_KEY_BUILDS, this.builds);
- // Check if the build was used in existing comparisons
- let comps = this.comparisons;
- for (let c in comps) {
- for (let i = 0; i < comps[c].builds.length; i++) { // For all builds in the current comparison
- if (comps[c].builds[i].shipId == shipId && comps[c].builds[i].buildName == name) {
- comps[c].builds.splice(i, 1);
- break; // A build is unique per comparison
- }
- }
- }
- _put(LS_KEY_COMPARISONS, this.comparisons);
this.emit('builds');
}
}
/**
- * Persist a comparison in localstorage.
- *
- * @param {String} name The name of the comparison
- * @param {array} builds Array of builds
- * @param {array} facets Array of facet indices
- */
- saveComparison(name, builds, facets) {
- if (!this.comparisons[name]) {
- this.comparisons[name] = {};
- }
- this.comparisons[name] = {
- facets,
- builds: builds.map(b => { return { shipId: b.id || b.shipId, buildName: b.buildName }; })
- };
- _put(LS_KEY_COMPARISONS, this.comparisons);
- this.emit('comparisons');
- }
-
- /**
- * Get a comparison
- * @param {String} name Comparison name
- * @return {Object} Object containing array of facets and ship id + build names
- */
- getComparison(name) {
- if (this.comparisons[name]) {
- return this.comparisons[name];
- }
- return null;
- }
-
- /**
- * Get all saved comparisons
- * @return {Object} All comparisons
- */
- getComparisons() {
- return this.comparisons;
- }
-
- /**
- * Check if a comparison has been saved
- * @param {String} name Comparison name
- * @return {Boolean} True if a comparison has been saved
- */
- hasComparison(name) {
- return !!this.comparisons[name];
- }
-
- /**
- * Check if any comparisons have been saved
- * @return {Boolean} True if any comparisons have been saved
- */
- hasComparisons() {
- return Object.keys(this.comparisons).length > 0;
- }
-
- /**
- * Removes the comparison from localstorage.
- * @param {String} name Comparison name
- */
- deleteComparison(name) {
- if (this.comparisons[name]) {
- delete this.comparisons[name];
- _put(LS_KEY_COMPARISONS, this.comparisons);
- this.emit('comparisons');
- }
- }
-
- /**
- * Delete all builds and comparisons from localStorage
+ * Delete all builds from localStorage
*/
deleteAll() {
this.builds = {};
- this.comparisons = {};
_put(LS_KEY_BUILDS, {});
- _put(LS_KEY_COMPARISONS, {});
this.emit('deletedAll');
}
@@ -435,7 +347,6 @@ export class Persist extends EventEmitter {
getAll() {
let data = {};
data[LS_KEY_BUILDS] = this.getBuilds();
- data[LS_KEY_COMPARISONS] = this.getComparisons();
data[LS_KEY_INSURANCE] = this.getInsurance();
data[LS_KEY_SHIP_DISCOUNT] = this.shipDiscount;
data[LS_KEY_MOD_DISCOUNT] = this.moduleDiscount;