|
|
@@ -0,0 +1,77 @@
|
|
|
+import {cachedFetchJSON} from './cache';
|
|
|
+
|
|
|
+const renderTarget = document.querySelector('#gov')!;
|
|
|
+const planetInput = document.querySelector('#planet') as HTMLInputElement;
|
|
|
+const popSelect = document.querySelector('#pop') as HTMLSelectElement;
|
|
|
+
|
|
|
+function serializeToHash(planet: string, pop: Pop): void {
|
|
|
+ const params = new URLSearchParams({'planet': planet, 'pop': pop});
|
|
|
+ document.location.hash = params.toString();
|
|
|
+}
|
|
|
+
|
|
|
+function deserializeFromHash(): {planet: string, pop: Pop} | null {
|
|
|
+ const params = new URLSearchParams(document.location.hash.substring(1));
|
|
|
+ const planet = params.get('planet');
|
|
|
+ const pop = params.get('pop');
|
|
|
+ if (planet && pop && ['pio', 'set', 'tec', 'eng', 'sci'].includes(pop)) {
|
|
|
+ planetInput.value = planet;
|
|
|
+ popSelect.value = pop;
|
|
|
+ return {planet, pop: pop as Pop};
|
|
|
+ } else
|
|
|
+ return null;
|
|
|
+}
|
|
|
+
|
|
|
+document.querySelector('form')!.addEventListener('submit', async (event) => {
|
|
|
+ event.preventDefault();
|
|
|
+ const planet = planetInput.value;
|
|
|
+ const pop = popSelect.value as Pop;
|
|
|
+ if (planet && pop) {
|
|
|
+ await render(planet, pop);
|
|
|
+ serializeToHash(planet, pop);
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+{
|
|
|
+ const deserialized = deserializeFromHash();
|
|
|
+ if (deserialized)
|
|
|
+ void render(deserialized.planet, deserialized.pop);
|
|
|
+}
|
|
|
+
|
|
|
+async function render(planetName: string, pop: Pop) {
|
|
|
+ const loader = document.querySelector('#loader') as HTMLElement;
|
|
|
+ loader.style.display = 'block';
|
|
|
+ renderTarget.innerHTML = '';
|
|
|
+
|
|
|
+ const planet: Planet = await cachedFetchJSON(
|
|
|
+ `https://api.fnar.net/planet/${encodeURIComponent(planetName)}?include_population_reports=true`);
|
|
|
+ let lastPOPR = null;
|
|
|
+ for (const report of planet.PopulationReports) {
|
|
|
+ if (!lastPOPR || report.SimulationPeriod > lastPOPR.SimulationPeriod)
|
|
|
+ lastPOPR = report;
|
|
|
+ }
|
|
|
+ if (lastPOPR === null) {
|
|
|
+ renderTarget.textContent = `no POPR for ${planetName}`;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const lastPOPRts = Math.floor(new Date(lastPOPR.ReportTimestamp).getTime() / 1000);
|
|
|
+ const nextPOPRts = lastPOPRts + 7 * 24 * 60 * 60;
|
|
|
+ renderTarget.innerHTML = `last POPR: ${lastPOPRts}<br>next POPR: ${nextPOPRts}`;
|
|
|
+
|
|
|
+ loader.style.display = 'none';
|
|
|
+}
|
|
|
+
|
|
|
+type Pop = 'pio' | 'set' | 'tec' | 'eng' | 'sci';
|
|
|
+
|
|
|
+interface Planet {
|
|
|
+ PopulationReports: POPR[]
|
|
|
+}
|
|
|
+
|
|
|
+interface POPR {
|
|
|
+ SimulationPeriod: number;
|
|
|
+ ReportTimestamp: string;
|
|
|
+ NextPopulationPioneer: number;
|
|
|
+ NextPopulationSettler: number;
|
|
|
+ NextPopulationTechnician: number;
|
|
|
+ NextPopulationEngineer: number;
|
|
|
+ NextPopulationScientist: number;
|
|
|
+}
|