Kaynağa Gözat

gov: show POPR timestamp

raylu 2 hafta önce
ebeveyn
işleme
aa3b1407a8
6 değiştirilmiş dosya ile 120 ekleme ve 1 silme
  1. 1 0
      .gitignore
  2. 1 0
      bun.lock
  3. 1 1
      package.json
  4. 77 0
      ts/gov.ts
  5. 31 0
      www/gov.html
  6. 9 0
      www/style.css

+ 1 - 0
.gitignore

@@ -4,6 +4,7 @@ config.toml
 node_modules/
 node_modules/
 uv.lock
 uv.lock
 www/buy.js*
 www/buy.js*
+www/gov.js*
 www/ledger.js*
 www/ledger.js*
 www/mat.js*
 www/mat.js*
 www/production.js*
 www/production.js*

+ 1 - 0
bun.lock

@@ -1,5 +1,6 @@
 {
 {
   "lockfileVersion": 1,
   "lockfileVersion": 1,
+  "configVersion": 0,
   "workspaces": {
   "workspaces": {
     "": {
     "": {
       "name": "prun-calc",
       "name": "prun-calc",

+ 1 - 1
package.json

@@ -2,7 +2,7 @@
 	"name": "prun-calc",
 	"name": "prun-calc",
 	"version": "0",
 	"version": "0",
 	"scripts": {
 	"scripts": {
-		"build": "bun build ts/buy.ts ts/ledger.ts ts/mat.ts ts/production.ts ts/roi.ts --outdir www --target browser --sourcemap=external",
+		"build": "bun build ts/buy.ts ts/gov.ts ts/ledger.ts ts/mat.ts ts/production.ts ts/roi.ts --outdir www --target browser --sourcemap=external",
 		"typecheck": "tsgo --noEmit",
 		"typecheck": "tsgo --noEmit",
 		"serve": "python3 -m http.server -d www 8000"
 		"serve": "python3 -m http.server -d www 8000"
 	},
 	},

+ 77 - 0
ts/gov.ts

@@ -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;
+}

+ 31 - 0
www/gov.html

@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta charset="UTF-8">
+	<title>PrUn gov</title>
+	<link rel="stylesheet" type="text/css" href="style.css">
+	<link rel="icon" href="https://www.raylu.net/hammer-man.svg" />
+	<meta name="viewport" content="width=device-width, initial-scale=1">
+	<meta name="theme-color" content="#222">
+</head>
+<body>
+	<a href="/">← back</a>
+	<main class="gov">
+		<form>
+			planet: <input type="text" id="planet"><br>
+			<select id="pop">
+				<option value="pio">pioneers</option>
+				<option value="set">settlers</option>
+				<option value="tec">technicians</option>
+				<option value="eng">engineers</option>
+				<option value="sci">scientists</option>
+			</select>
+			<input type="submit" value="run">
+		</form>
+		<section id="loader"></section>
+		<div id="gov"></div>
+	</main>
+	<div id="popover" popover="hint"></div>
+	<script src="gov.js"></script>
+</body>
+</html>

+ 9 - 0
www/style.css

@@ -105,6 +105,15 @@ main.buy {
 	}
 	}
 }
 }
 
 
+main.gov {
+	form input#planet {
+		margin-bottom: 1em;
+	}
+	div#gov {
+		margin-top: 2em;
+	}
+}
+
 main.mat {
 main.mat {
 	width: 90%;
 	width: 90%;
 	min-width: 500px;
 	min-width: 500px;