diff --git a/src/hud/index.ts b/src/hud/index.ts
index 16aaaae..c39d9be 100644
--- a/src/hud/index.ts
+++ b/src/hud/index.ts
@@ -23,12 +23,15 @@ function showAttribution (visible: true) {
if (attributionElem) {
if (visible) {
const satelliteStore = viewer.getSatelliteStore();
- if (satelliteStore && satelliteStore.getAttribution()) {
- const attribution = satelliteStore.getAttribution() || {};
+ if (satelliteStore?.getAttribution()) {
+ const attribution = satelliteStore.getAttribution();
const updatedDate = satelliteStore.getUpdatedDate();
- attributionElem.innerHTML = `Orbital object data from ${attribution.name} (updated ${updatedDate})`;
+
+ if (attribution) {
+ attributionElem.innerHTML = `Orbital object data from ${attribution.name} (updated ${updatedDate})`;
+ attributionElem.classList.remove('hidden');
+ }
}
- attributionElem.classList.remove('hidden');
} else {
attributionElem.classList.add('hidden');
}
@@ -274,12 +277,12 @@ function getSupportedEvents () {
}
function initMenus () {
- const elements = document.querySelectorAll('.menu-item');
- for (let i = 0; i < elements.length; i++) {
- const element = elements[i] as HTMLElement;
+ const elements = Array.from(document.querySelectorAll('.menu-item'));
+
+ for (const element of elements) {
element.addEventListener('click', () => {
- const action = element.dataset.action;
- if (action && action.startsWith('open:')) {
+ const action = (element as HTMLElement).dataset.action;
+ if (action?.startsWith('open:')) {
const parts = action.split(':');
windowManager.openWindow(parts[1]);
}
diff --git a/src/utils/logger.ts b/src/utils/logger.ts
index 14ab4c9..f38a015 100644
--- a/src/utils/logger.ts
+++ b/src/utils/logger.ts
@@ -3,7 +3,12 @@
const defaultLogLevel = 'debug';
const logLevels = ['error', 'warn', 'info', 'debug'];
-let allOutputs: Record = {};
+let allOutputs = {
+ error: (..._args: any) => {},
+ warn: (..._args: any) => {},
+ info: (..._args: any) => {},
+ debug: (..._args: any) => {}
+};
let globalLogger = new Proxy({
logLevel: defaultLogLevel,
enabledOutputs: {} as Record,
@@ -41,8 +46,8 @@ function init () {
const enabledOutputs = scope.enabledOutputs;
- for (let i = 0; i < logLevels.length; i++) {
- enabledOutputs[logLevels[i]] = true;
+ for (const logLevel of logLevels) {
+ enabledOutputs[logLevel] = true;
}
allOutputs = {
diff --git a/src/viewer/Earth.ts b/src/viewer/Earth.ts
index 851e9ac..0ba6c3f 100644
--- a/src/viewer/Earth.ts
+++ b/src/viewer/Earth.ts
@@ -2,6 +2,7 @@ import { ShaderMaterial, UniformsUtils, Texture } from 'three';
import { Color, TextureLoader, MeshPhongMaterial, SphereGeometry, Mesh, Group, BackSide, AdditiveBlending } from '../utils/three';
import SceneComponent from './interfaces/SceneComponent';
import SatelliteOrbitScene from './SatelliteOrbitScene';
+import { ViewerContext } from './interfaces/ViewerContext';
class Earth implements SceneComponent {
baseUrl = '';
@@ -91,7 +92,7 @@ class Earth implements SceneComponent {
group.add(mesh);
}
- async init (scene: SatelliteOrbitScene, context: Record) {
+ async init (scene: SatelliteOrbitScene, context: ViewerContext) {
if (context.config) {
this.baseUrl = context.config.baseUrl;
}
@@ -122,7 +123,9 @@ class Earth implements SceneComponent {
this.group.add(this.sphere);
if (this.addClouds) {
- this.initClouds(scene, this.group);
+ this.initClouds(scene, this.group).catch(error => {
+ console.error('Error loading clouds', error);
+ });
}
if (this.addAtmosphere) {
diff --git a/src/viewer/Orbits.ts b/src/viewer/Orbits.ts
index fa1dd31..10812be 100644
--- a/src/viewer/Orbits.ts
+++ b/src/viewer/Orbits.ts
@@ -7,6 +7,7 @@ import SatelliteOrbitScene from './SatelliteOrbitScene';
import logger from '../utils/logger';
import SatelliteGroups from './SatelliteGroups';
import SelectableSatellite from './interfaces/SelectableSatellite';
+import { ViewerContext } from './interfaces/ViewerContext';
class Orbits implements SceneComponent, SelectableSatellite {
config: Record = {};
@@ -221,12 +222,12 @@ class Orbits implements SceneComponent, SelectableSatellite {
// calculate tracks
if (this.satelliteGroup) {
const satellites = this.satelliteGroup.sats;
- const satelliteIds = satellites.map((entry: Record) => entry.satId as number);
+ const satelliteIds = satellites.map((entry) => entry.satId as number);
this.calculateOrbits(satelliteIds);
}
}
- init (scene: SatelliteOrbitScene, context: Record) {
+ init (scene: SatelliteOrbitScene, context: ViewerContext) {
this.config = context.config;
this.scene = scene;
this.orbitWorker = new OrbitCalculationWorker();
diff --git a/src/viewer/SatelliteGroups.ts b/src/viewer/SatelliteGroups.ts
index b8b9656..2a0c86c 100644
--- a/src/viewer/SatelliteGroups.ts
+++ b/src/viewer/SatelliteGroups.ts
@@ -1,6 +1,7 @@
import SatGroup from './SatelliteGroup';
import logger from '../utils/logger';
import SatelliteStore from './SatelliteStore';
+import type SatelliteGroup from './SatelliteGroup';
class SatelliteGroups {
groups: Record = {};
@@ -8,7 +9,7 @@ class SatelliteGroups {
sats: any[] = [];
satelliteStore: SatelliteStore;
- constructor (satelliteGroups: Record[], satelliteStore: SatelliteStore) {
+ constructor (satelliteGroups: SatelliteGroup[], satelliteStore: SatelliteStore) {
if (!satelliteStore) {
throw new Error('satelliteStore is required');
}
@@ -26,13 +27,12 @@ class SatelliteGroups {
this.selectedGroup = group;
if (!group) {
this.clearSelect();
- return;
}
}
forEach (callback: (satId: number) => void) {
- for (let i = 0; i < this.sats.length; i++) {
- callback(this.sats[i].satId);
+ for (const sat of this.sats) {
+ callback(sat.satId);
}
}
@@ -54,21 +54,21 @@ class SatelliteGroups {
reloadGroups () {
const keys = Object.keys(this.groups);
- for (let i = 0; i < keys.length; i++) {
- this.groups[keys[i]].reload();
+ for (const key of keys) {
+ this.groups[key].reload();
}
}
- resetConfig (satelliteGroups: Record[]) {
+ resetConfig (satelliteGroups: SatelliteGroup[]) {
const groupConfigs = satelliteGroups;
- for (let i = 0; i < groupConfigs.length; i++) {
- logger.debug(`registering satellite group ${groupConfigs[i].name} (id: ${groupConfigs[i].id})`);
- this.groups[groupConfigs[i].id.toLowerCase()] = new SatGroup(
- groupConfigs[i].id.toLowerCase(),
- groupConfigs[i].name,
- groupConfigs[i].groupType,
- groupConfigs[i].data,
- this.satelliteStore as SatelliteStore
+ for (const groupConfig of groupConfigs) {
+ logger.debug(`registering satellite group ${groupConfig.name} (id: ${groupConfig.id})`);
+ this.groups[groupConfig.id.toLowerCase()] = new SatGroup(
+ groupConfig.id.toLowerCase(),
+ groupConfig.name,
+ groupConfig.groupType,
+ groupConfig.data,
+ this.satelliteStore
);
}
}
diff --git a/src/viewer/SatelliteStore.ts b/src/viewer/SatelliteStore.ts
index 33663fc..ac623b9 100644
--- a/src/viewer/SatelliteStore.ts
+++ b/src/viewer/SatelliteStore.ts
@@ -11,7 +11,10 @@ class SatelliteStore {
tleUrl = `${config.baseUrl}/data/attributed-TLE.json`;
eventManager: EventManager;
satData: SatelliteObject[] = [];
- attribution?: Record;
+ attribution?: {
+ name: string;
+ url: string;
+ };
updateDate?: Date;
satelliteVelocities: Float32Array = new Float32Array();
satellitePositions: Float32Array = new Float32Array();
@@ -65,7 +68,10 @@ class SatelliteStore {
}
}
- getAttribution (): Record | undefined {
+ getAttribution (): {
+ name: string;
+ url: string;
+ } | undefined {
return this.attribution;
}
diff --git a/src/viewer/Satellites.ts b/src/viewer/Satellites.ts
index c6336b2..8366687 100644
--- a/src/viewer/Satellites.ts
+++ b/src/viewer/Satellites.ts
@@ -21,6 +21,8 @@ import DefaultColorScheme from './color-schemes/DefaultColorScheme';
import SelectableSatellite from './interfaces/SelectableSatellite';
import ShaderStore from './ShaderStore';
import GroupColorScheme from './color-schemes/GroupColorScheme';
+import { SatelliteObject } from './interfaces/SatelliteObject';
+import { ViewerContext } from './interfaces/ViewerContext';
class Satellites implements SceneComponent, SelectableSatellite {
baseUrl = '';
@@ -94,7 +96,7 @@ class Satellites implements SceneComponent, SelectableSatellite {
/**
* update point colours
*/
- private updateSatellitesMaterial (satCount: number, satellites: Record[]) {
+ private updateSatellitesMaterial (satCount: number, satellites: SatelliteObject[]) {
if (this.geometry?.attributes.color && this.currentColorScheme && this.satelliteStore) {
// Adjust if the satellite count adjusts
if (this.satelliteColors.length === 0 || (satCount * 4 !== this.satelliteColors.length)) {
@@ -332,7 +334,7 @@ class Satellites implements SceneComponent, SelectableSatellite {
}));
}
- async init (scene: SatelliteOrbitScene, context: Record) {
+ async init (scene: SatelliteOrbitScene, context: ViewerContext) {
this.satelliteStore = context.satelliteStore;
this.shaderStore = context.shaderStore;
this.scene = scene;
diff --git a/src/viewer/Universe.ts b/src/viewer/Universe.ts
index 1cfe126..4c79d33 100644
--- a/src/viewer/Universe.ts
+++ b/src/viewer/Universe.ts
@@ -1,9 +1,10 @@
+import { ViewerContext } from './interfaces/ViewerContext';
import { TextureLoader } from '../utils/three';
import SceneComponent from './interfaces/SceneComponent';
import SatelliteOrbitScene from './SatelliteOrbitScene';
class Universe implements SceneComponent {
- init (scene: SatelliteOrbitScene, context: Record) {
+ init (scene: SatelliteOrbitScene, context: ViewerContext) {
const baseUrl = context.config.baseUrl;
const texture = new TextureLoader().load(`${baseUrl}textures/example_render.jpg`);
diff --git a/src/viewer/color-schemes/ColorScheme.ts b/src/viewer/color-schemes/ColorScheme.ts
index 671be38..0ffcb7f 100644
--- a/src/viewer/color-schemes/ColorScheme.ts
+++ b/src/viewer/color-schemes/ColorScheme.ts
@@ -1,15 +1,16 @@
import SatelliteGroup from '../SatelliteGroup';
+import { SatelliteObject } from '../interfaces/SatelliteObject';
class ColorScheme {
name: string;
- colorizer: (satellite: Record, group?: SatelliteGroup) => { color: number[], pickable: boolean };
+ colorizer: (satellite: SatelliteObject, group?: SatelliteGroup) => { color: number[], pickable: boolean };
- constructor (name: string, colorizer: (satellite: Record) => { color: number[], pickable: boolean }) {
+ constructor (name: string, colorizer: (satellite: SatelliteObject) => { color: number[], pickable: boolean }) {
this.name = name;
this.colorizer = colorizer;
}
- getSatelliteColor (satellite: Record, group?: SatelliteGroup): { color: number[], pickable: boolean } {
+ getSatelliteColor (satellite: SatelliteObject, group?: SatelliteGroup): { color: number[], pickable: boolean } {
return this.colorizer(satellite, group);
}
}
diff --git a/src/viewer/color-schemes/DefaultColorScheme.ts b/src/viewer/color-schemes/DefaultColorScheme.ts
index 64c0e3d..97289cc 100644
--- a/src/viewer/color-schemes/DefaultColorScheme.ts
+++ b/src/viewer/color-schemes/DefaultColorScheme.ts
@@ -1,8 +1,9 @@
+import { SatelliteObject } from '../interfaces/SatelliteObject';
import ColorScheme from './ColorScheme';
class DefaultColorScheme extends ColorScheme {
constructor () {
- super ('Default color scheme', (satellite: Record) => {
+ super ('Default color scheme', (satellite: SatelliteObject) => {
let color = [1.0, 1.0, 0.0, 1.0];
let pickable = false;
diff --git a/src/viewer/color-schemes/GroupColorScheme.ts b/src/viewer/color-schemes/GroupColorScheme.ts
index 3a46d5b..45585e7 100644
--- a/src/viewer/color-schemes/GroupColorScheme.ts
+++ b/src/viewer/color-schemes/GroupColorScheme.ts
@@ -1,11 +1,12 @@
import SatelliteGroup from '@satellite-viewer/SatelliteGroup';
import ColorScheme from './ColorScheme';
+import { SatelliteObject } from '../interfaces/SatelliteObject';
class GroupColorScheme extends ColorScheme {
constructor () {
- super ('Group color scheme', (satellite: Record, group?: SatelliteGroup) => {
+ super ('Group color scheme', (satellite: SatelliteObject, group?: SatelliteGroup) => {
if (satellite) {
- if (group && group.hasSat(satellite.id)) {
+ if (group?.hasSat(satellite.id)) {
return {
color: [1.0, 0.2, 0.0, 1.0],
pickable: true
diff --git a/src/viewer/index.ts b/src/viewer/index.ts
index 71106e2..577a820 100644
--- a/src/viewer/index.ts
+++ b/src/viewer/index.ts
@@ -16,6 +16,8 @@ import SatelliteGroup from './SatelliteGroup';
import ShaderStore from './ShaderStore';
import logger from '@/utils/logger';
import { ArrowHelper, Raycaster, Vector2, Vector3 } from 'three';
+import { SatelliteObject } from './interfaces/SatelliteObject';
+import { ViewerContext } from './interfaces/ViewerContext';
class Viewer {
config: Record = {
@@ -28,7 +30,12 @@ class Viewer {
camera?: PerspectiveCamera;
controls?: OrbitControls;
renderer?: WebGLRenderer;
- context: Record = {};
+ context: ViewerContext = {
+ satelliteGroups: null as unknown as SatelliteGroups,
+ config: null as unknown as Record,
+ satelliteStore: null as unknown as SatelliteStore,
+ shaderStore: null as unknown as ShaderStore
+ };
satelliteGroups?: SatelliteGroups;
satelliteStore?: SatelliteStore;
shaderStore?: ShaderStore;
@@ -82,7 +89,7 @@ class Viewer {
}
}
- private onSatDataLoaded (satData: Record) {
+ private onSatDataLoaded (satData: SatelliteObject[]) {
this.eventManager.fireEvent('satdataloaded', satData);
this.ready = true;
}
@@ -404,7 +411,7 @@ class Viewer {
this.satellites?.setSatelliteGroup(satelliteGroup);
}
- getSelectedSatellite (): Record | undefined {
+ getSelectedSatellite (): SatelliteObject | undefined {
if (this.satelliteStore) {
return this.satelliteStore.getSatellite(this.selectedSatelliteIdx);
}
diff --git a/src/viewer/interfaces/SceneComponent.ts b/src/viewer/interfaces/SceneComponent.ts
index 399ae68..465b1bc 100644
--- a/src/viewer/interfaces/SceneComponent.ts
+++ b/src/viewer/interfaces/SceneComponent.ts
@@ -1,7 +1,8 @@
+import { ViewerContext } from './ViewerContext';
import SatelliteOrbitScene from '../SatelliteOrbitScene';
interface SceneComponent {
- init (scene: SatelliteOrbitScene, context: Record): void | Promise;
+ init (scene: SatelliteOrbitScene, context: ViewerContext): void | Promise;
update (scene?: SatelliteOrbitScene): void;
}
diff --git a/src/viewer/interfaces/ViewerContext.ts b/src/viewer/interfaces/ViewerContext.ts
new file mode 100644
index 0000000..ea3c3d1
--- /dev/null
+++ b/src/viewer/interfaces/ViewerContext.ts
@@ -0,0 +1,11 @@
+import type SatelliteGroups from '../SatelliteGroups';
+import type SatelliteStore from '../SatelliteStore';
+import type ShaderStore from '../ShaderStore';
+
+
+export interface ViewerContext {
+ satelliteGroups: SatelliteGroups;
+ config: Record;
+ satelliteStore: SatelliteStore;
+ shaderStore: ShaderStore;
+}