gov.ts 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. import {cachedFetchJSON} from './cache';
  2. const renderTarget = document.querySelector('#gov')!;
  3. const planetInput = document.querySelector('#planet') as HTMLInputElement;
  4. const popSelect = document.querySelector('#pop') as HTMLSelectElement;
  5. function serializeToHash(planet: string, pop: Pop): void {
  6. const params = new URLSearchParams({'planet': planet, 'pop': pop});
  7. document.location.hash = params.toString();
  8. }
  9. function deserializeFromHash(): {planet: string, pop: Pop} | null {
  10. const params = new URLSearchParams(document.location.hash.substring(1));
  11. const planet = params.get('planet');
  12. const pop = params.get('pop');
  13. if (planet && pop && ['pio', 'set', 'tec', 'eng', 'sci'].includes(pop)) {
  14. planetInput.value = planet;
  15. popSelect.value = pop;
  16. return {planet, pop: pop as Pop};
  17. } else
  18. return null;
  19. }
  20. document.querySelector('form')!.addEventListener('submit', async (event) => {
  21. event.preventDefault();
  22. const planet = planetInput.value;
  23. const pop = popSelect.value as Pop;
  24. if (planet && pop) {
  25. await render(planet, pop);
  26. serializeToHash(planet, pop);
  27. }
  28. });
  29. {
  30. const deserialized = deserializeFromHash();
  31. if (deserialized)
  32. void render(deserialized.planet, deserialized.pop);
  33. }
  34. async function render(planetName: string, pop: Pop) {
  35. const loader = document.querySelector('#loader') as HTMLElement;
  36. loader.style.display = 'block';
  37. renderTarget.innerHTML = '';
  38. const planet: Planet = await cachedFetchJSON(
  39. `https://api.fnar.net/planet/${encodeURIComponent(planetName)}?include_population_reports=true`);
  40. let lastPOPR = null;
  41. for (const report of planet.PopulationReports) {
  42. if (!lastPOPR || report.SimulationPeriod > lastPOPR.SimulationPeriod)
  43. lastPOPR = report;
  44. }
  45. if (lastPOPR === null) {
  46. renderTarget.textContent = `no POPR for ${planetName}`;
  47. return;
  48. }
  49. const lastPOPRts = Math.floor(new Date(lastPOPR.ReportTimestamp).getTime() / 1000);
  50. const nextPOPRts = lastPOPRts + 7 * 24 * 60 * 60;
  51. renderTarget.innerHTML = `last POPR: ${lastPOPRts}<br>next POPR: ${nextPOPRts}`;
  52. loader.style.display = 'none';
  53. }
  54. type Pop = 'pio' | 'set' | 'tec' | 'eng' | 'sci';
  55. interface Planet {
  56. PopulationReports: POPR[]
  57. }
  58. interface POPR {
  59. SimulationPeriod: number;
  60. ReportTimestamp: string;
  61. NextPopulationPioneer: number;
  62. NextPopulationSettler: number;
  63. NextPopulationTechnician: number;
  64. NextPopulationEngineer: number;
  65. NextPopulationScientist: number;
  66. }