From b77bced96d5b4a2f1d7103822a8282ba67737d63 Mon Sep 17 00:00:00 2001 From: Degenoah Date: Mon, 11 Mar 2024 12:46:54 -0600 Subject: [PATCH 1/3] Add null checks in searchUnits() to avoid unit view to stop working. --- src/main.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.ts b/src/main.ts index af3d161..00d7e8b 100644 --- a/src/main.ts +++ b/src/main.ts @@ -954,11 +954,11 @@ class MapViewer { .includes(current_search_string) ) { elem?.classList.add('hide'); - const tooltipClass = elem.getAttribute('aria-describedby'); + const tooltipClass = elem?.getAttribute('aria-describedby'); document.getElementById(tooltipClass)?.classList.add('hide'); } else { elem?.classList.remove('hide'); - const tooltipClass = elem.getAttribute('aria-describedby'); + const tooltipClass = elem?.getAttribute('aria-describedby'); document.getElementById(tooltipClass)?.classList.remove('hide'); } }); From f553c3815313e343bf2a93901297d118b7931957 Mon Sep 17 00:00:00 2001 From: Degenoah Date: Tue, 12 Mar 2024 01:13:09 -0600 Subject: [PATCH 2/3] Rename createToogleLayerButton to createToggleLayerButton. --- src/main.ts | 10 +++++----- src/map.ts | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main.ts b/src/main.ts index 00d7e8b..06da642 100644 --- a/src/main.ts +++ b/src/main.ts @@ -268,7 +268,7 @@ class MapViewer { }; addFortificationsToggle = () => { - const fortificationsToggleButton = mapper.createToogleLayerButton( + const fortificationsToggleButton = mapper.createToggleLayerButton( () => this.toggleFortificationsLayer(), 'Toggle Fortifications', 'fortifications-toggle-button', @@ -278,7 +278,7 @@ class MapViewer { }; addDragonTeethToggle = () => { - const dragonTeethToggleButton = mapper.createToogleLayerButton( + const dragonTeethToggleButton = mapper.createToggleLayerButton( () => this.toggleDragonTeethLayer(), 'Toggle Dragon Teeth', 'dragonteeth-toggle-button', @@ -288,7 +288,7 @@ class MapViewer { }; addUnitsToggle = () => { - const unitsToggleButton = mapper.createToogleLayerButton( + const unitsToggleButton = mapper.createToggleLayerButton( () => this.toggleUnitsLayer(), 'Toggle Units', 'units-toggle-button', @@ -298,7 +298,7 @@ class MapViewer { }; addGeosToggle = () => { - const geosToggleButton = mapper.createToogleLayerButton( + const geosToggleButton = mapper.createToggleLayerButton( () => this.toggleGeosLayer(), 'Toggle Geolocations', 'geolocations-toggle-button', @@ -308,7 +308,7 @@ class MapViewer { }; addUnitLabelToggle = () => { - const unitLabelsToggleButton = mapper.createToogleLayerButton( + const unitLabelsToggleButton = mapper.createToggleLayerButton( () => this.toggleUnitLabels(), 'Toggle Unit Labels permanently on (at zoomlevel >= 11)', 'unitlabels-toggle-button', diff --git a/src/map.ts b/src/map.ts index 818b1c1..009e477 100644 --- a/src/map.ts +++ b/src/map.ts @@ -175,7 +175,7 @@ export const createTimelineToggleButton = ( return toggleButton; }; -export const createToogleLayerButton = ( +export const createToggleLayerButton = ( callback: Function, title: string, cls: string, From 29abd4534c8b1450a5a7bbcee79fe0d6f5142656 Mon Sep 17 00:00:00 2001 From: Degenoah Date: Tue, 12 Mar 2024 02:25:23 -0600 Subject: [PATCH 3/3] duplicate code reduction and other various changes. --- src/helper.ts | 162 ++++++++++++++++++++++---------------------------- src/main.ts | 123 +++++++++++++++++++------------------- src/map.ts | 61 ++++++------------- 3 files changed, 153 insertions(+), 193 deletions(-) diff --git a/src/helper.ts b/src/helper.ts index 1ec70f0..c97c27b 100644 --- a/src/helper.ts +++ b/src/helper.ts @@ -1,4 +1,4 @@ -import { UnitData, UnitMap, GeosData } from './types'; +import { UnitData, UnitPosition, UnitMap, GeosData } from './types'; export const dateKey2dateString = (dateKey: any): string => { const pattern = /(\d{4})(\d{2})(\d{2})/; @@ -46,103 +46,85 @@ export const prepareGeosData = (data: GeosData) => { export const prepareUnitData = (data: UnitData, unit_map: UnitMap) => { const unitCollections: any = []; - const uaUnitFeatures: any = []; - const ruUnitFeatures: any = []; - // ua units - if (Array.isArray(data.ua) && data.ua.length > 0) { - for (let i = 0; i < data.ua.length; i++) { - const unitData = data.ua[i]; - const unitId = unitData[0]; - const unitCoordinates = unitData[1]; - let unitName = 'Unknown'; - let unitSIDC = '30000000000000000000'; // fallback - let unitSIDCText = ''; - if (unit_map.hasOwnProperty(unitId)) { - const aUnitData = unit_map[unitId]; - if (aUnitData.hasOwnProperty('n') && aUnitData.n !== undefined) { - unitName = aUnitData.n; - } - if (aUnitData.hasOwnProperty('sidc') && aUnitData.sidc !== undefined) { - unitSIDC = aUnitData.sidc; - } - if (aUnitData.hasOwnProperty('sidc_custom_text') && aUnitData.sidc_custom_text !== undefined) { - unitSIDCText = aUnitData.sidc_custom_text; + /** + * Helper function for populating `unitCollections` with features. + * @param units A list of units and their positions. + * @param unitSide Shorthand for the unit sides. + */ + const _populateUnitFeatures = ( + units: UnitPosition[], + unitSide: string + ) => { + const unitFeatures: any = []; + + if (Array.isArray(units) && units.length > 0) { + for (let i = 0; i < units.length; i++) { + const unitData = units[i]; + const unitId = unitData[0]; + const unitCoordinates = unitData[1]; + let unitName = 'Unknown'; + let unitSIDC = '30000000000000000000'; // fallback + let unitSIDCText = ''; + + if (unit_map.hasOwnProperty(unitId)) { + const aUnitData = unit_map[unitId]; + + if ( + aUnitData.hasOwnProperty('n') && + aUnitData.n !== undefined + ) { + unitName = aUnitData.n; + } + + if ( + aUnitData.hasOwnProperty('sidc') && + aUnitData.sidc !== undefined + ) { + unitSIDC = aUnitData.sidc; + } + + if ( + aUnitData.hasOwnProperty('sidc_custom_text') && + aUnitData.sidc_custom_text !== undefined + ) { + unitSIDCText = aUnitData.sidc_custom_text; + } } + + unitFeatures.push({ + type: 'Feature', + geometry: { + type: 'Point', + coordinates: unitCoordinates, + }, + properties: { + unitId: unitId, + unitName: unitName, + unitSide: unitSide, + unitSIDC: unitSIDC, + unitSIDCText: unitSIDCText + }, + }); } - uaUnitFeatures.push({ - type: 'Feature', - geometry: { - type: 'Point', - coordinates: unitCoordinates, - }, - properties: { - unitId: unitId, - unitName: unitName, - unitSide: 'ua', - unitSIDC: unitSIDC, - unitSIDCText: unitSIDCText - }, - }); } - } - if (uaUnitFeatures.length > 0) { - const uaFeatureCollection = { - type: 'FeatureCollection', - features: uaUnitFeatures, - }; - unitCollections.push(uaFeatureCollection); - } else { - unitCollections.push(null); - } - // ru inits - if (Array.isArray(data.ru) && data.ru.length > 0) { - for (let i = 0; i < data.ru.length; i++) { - const unitData = data.ru[i]; - const unitId = unitData[0]; - const unitCoordinates = unitData[1]; - let unitName = 'Unknown'; - let unitSIDC = '30000000000000000000'; // fallback - let unitSIDCText = ''; - if (unit_map.hasOwnProperty(unitId)) { - const aUnitData = unit_map[unitId]; - if (aUnitData.hasOwnProperty('n') && aUnitData.n !== undefined) { - unitName = aUnitData.n; - } - if (aUnitData.hasOwnProperty('sidc') && aUnitData.sidc !== undefined) { - unitSIDC = aUnitData.sidc; - } - if (aUnitData.hasOwnProperty('sidc_custom_text') && aUnitData.sidc_custom_text !== undefined) { - unitSIDCText = aUnitData.sidc_custom_text; - } + if (unitFeatures.length > 0) { + const featureCollection = { + type: 'FeatureCollection', + features: unitFeatures, } - ruUnitFeatures.push({ - type: 'Feature', - geometry: { - type: 'Point', - coordinates: unitCoordinates, - }, - properties: { - unitId: unitId, - unitName: unitName, - unitSide: 'ru', - unitSIDC: unitSIDC, - unitSIDCText: unitSIDCText - }, - }); + unitCollections.push(featureCollection); + } else { + console.error('failed to create unit features!!!'); + unitCollections.push(null); } - } - if (ruUnitFeatures.length > 0) { - const ruFeatureCollection = { - type: 'FeatureCollection', - features: ruUnitFeatures, - }; - unitCollections.push(ruFeatureCollection); - } else { - unitCollections.push(null); - } + }; + + // Create unit features. + _populateUnitFeatures(data.ua, 'ua'); + _populateUnitFeatures(data.ru, 'ru'); return unitCollections; }; diff --git a/src/main.ts b/src/main.ts index 06da642..9b45e1e 100644 --- a/src/main.ts +++ b/src/main.ts @@ -80,19 +80,57 @@ class MapViewer { // set date input to correct date this.updateDateInput(); - // add listener + // add listeners this.addTimelineControlListener(); this.addMapZoomListener(); this.addMapMoveListener(); this.addSearchInputListener(); + // // add toggle buttons - this.addTimelineControlToggle(); - this.addFortificationsToggle(); - this.addDragonTeethToggle(); - this.addUnitsToggle(); - this.addGeosToggle(); - this.addUnitLabelToggle(); + // + + this.addToggleButton( + this.toggleTimelineControl, + 'Toggle Timeline Controls', + 'timeline-toggle-button', + this.layer_status.timeline + ); + + this.addToggleButton( + this.toggleFortificationsLayer, + 'Toggle Fortifications', + 'fortifications-toggle-button', + this.layer_status.fortifications + ); + + this.addToggleButton( + this.toggleDragonTeethLayer, + 'Toggle Dragon Teeth', + 'dragonteeth-toggle-button', + this.layer_status.dragon_teeth + ); + + this.addToggleButton( + this.toggleUnitsLayer, + 'Toggle Units', + 'units-toggle-button', + this.layer_status.units + ); + + this.addToggleButton( + this.toggleGeosLayer, + 'Toggle Geolocations', + 'geolocations-toggle-button', + this.layer_status.geos + ); + + this.addToggleButton( + this.toggleUnitLabels, + 'Toggle Unit Labels permanently on (at zoomlevel >= 11)', + 'unitlabels-toggle-button', + this.showPermanentUnitLabels + ); // fetch latest data await this.fetchData(); @@ -259,62 +297,24 @@ class MapViewer { // Toggle Buttons Setup //================================================= - addTimelineControlToggle = () => { - const timelineToggleButton = mapper.createTimelineToggleButton( - () => this.toggleTimelineControl(), - this.layer_status.timeline + /** + * Creates a button for toggling map features. + * @param callbackFn The callback function. + * @param title The button title. + * @param cls The button dom class. + * @param initialStatus The initial state of the button. + */ + addToggleButton = ( + callbackFn: Function, + title: string, + cls: string, + initialStatus: boolean + ) => { + const toggleButton = mapper.createToggleButton( + () => callbackFn(), title, cls, initialStatus ); - timelineToggleButton.addTo(this.map); - }; - addFortificationsToggle = () => { - const fortificationsToggleButton = mapper.createToggleLayerButton( - () => this.toggleFortificationsLayer(), - 'Toggle Fortifications', - 'fortifications-toggle-button', - this.layer_status.fortifications - ); - fortificationsToggleButton.addTo(this.map); - }; - - addDragonTeethToggle = () => { - const dragonTeethToggleButton = mapper.createToggleLayerButton( - () => this.toggleDragonTeethLayer(), - 'Toggle Dragon Teeth', - 'dragonteeth-toggle-button', - this.layer_status.dragon_teeth - ); - dragonTeethToggleButton.addTo(this.map); - }; - - addUnitsToggle = () => { - const unitsToggleButton = mapper.createToggleLayerButton( - () => this.toggleUnitsLayer(), - 'Toggle Units', - 'units-toggle-button', - this.layer_status.units - ); - unitsToggleButton.addTo(this.map); - }; - - addGeosToggle = () => { - const geosToggleButton = mapper.createToggleLayerButton( - () => this.toggleGeosLayer(), - 'Toggle Geolocations', - 'geolocations-toggle-button', - this.layer_status.geos - ); - geosToggleButton.addTo(this.map); - }; - - addUnitLabelToggle = () => { - const unitLabelsToggleButton = mapper.createToggleLayerButton( - () => this.toggleUnitLabels(), - 'Toggle Unit Labels permanently on (at zoomlevel >= 11)', - 'unitlabels-toggle-button', - this.showPermanentUnitLabels - ); - unitLabelsToggleButton.addTo(this.map); + toggleButton.addTo(this.map); }; //================================================= @@ -773,6 +773,7 @@ class MapViewer { //--------------------------------------------------------- createUnitLayers = () => { + /// BUG: Something might be broken here, related to issue #12. if (this.baseData === null) { return; } diff --git a/src/map.ts b/src/map.ts index 009e477..103ad75 100644 --- a/src/map.ts +++ b/src/map.ts @@ -15,16 +15,13 @@ declare module 'leaflet' { } } +/** + * Initializes the leaflet base map. + * @returns The leaflet map. + */ export const initBaseMap = () => { - const lat = 47.5; - const lng = 36.0; - // const lat = 45.94153243267059; // dev - // const lng = 36.56250000000001; // dev - const zoom = 7; // initial zoom level - // const zoom = 10; // dev - - // map center - const mapcenter: any = [lat, lng]; + const initialZoom = 7; + const mapCenter: any = [47.5, 36.0]; // OSM tile layer const cyclosmUrl = @@ -107,8 +104,8 @@ export const initBaseMap = () => { // create base map with OSM layer as default const map = L.map('map', { layers: [cyclosm], - center: mapcenter, - zoom: zoom, + center: mapCenter, + zoom: initialZoom, minZoom: 4, maxZoom: 18, maxBounds: [ @@ -151,52 +148,32 @@ export const initBaseMap = () => { return map; }; -export const createTimelineToggleButton = ( - cb: Function, - initialStatus: boolean -) => { - // toggle button - const toggleButtonControl = L.Control.extend({ - onAdd: function () { - const statusCls = initialStatus ? 'active' : 'inactive'; - const button = L.DomUtil.create( - 'button', - `toggle-button timeline-toggle-button ${statusCls}` - ); - button.title = 'Toggle Timeline Controls'; - L.DomEvent.disableClickPropagation(button); - L.DomEvent.on(button, 'click', function () { - cb(); - }); - return button; - }, - }); - const toggleButton = new toggleButtonControl({ position: 'topright' }); - return toggleButton; -}; - -export const createToggleLayerButton = ( +export const createToggleButton = ( callback: Function, title: string, cls: string, initialStatus: boolean ) => { - // toggle button - const toggleLayerButton = L.Control.extend({ - onAdd: function () { + const toggleButtonControl = L.Control.extend({ + onAdd: () => { const statusCls = initialStatus ? 'active' : 'inactive'; + const button = L.DomUtil.create( 'button', `toggle-button ${cls} ${statusCls}` ); + button.title = title; L.DomEvent.disableClickPropagation(button); - L.DomEvent.on(button, 'click', function () { + + L.DomEvent.on(button, 'click', () => { callback(); }); + return button; - }, + } }); - const toggleButton = new toggleLayerButton({ position: 'topright' }); + + const toggleButton = new toggleButtonControl({ position: 'topright' }); return toggleButton; };