aboutsummaryrefslogtreecommitdiff
path: root/web
diff options
context:
space:
mode:
Diffstat (limited to 'web')
-rw-r--r--web/pw-server/src/lib/components/OutputPane.svelte2
-rw-r--r--web/pw-server/src/lib/components/PlayerLog.svelte153
-rw-r--r--web/pw-server/src/lib/components/log_viewer/LogTurn.svelte160
-rw-r--r--web/pw-server/src/lib/components/log_viewer/PlayerLog.svelte39
-rw-r--r--web/pw-server/src/routes/matches/[match_id].svelte2
-rw-r--r--web/pw-visualizer/src/index.ts21
6 files changed, 211 insertions, 166 deletions
diff --git a/web/pw-server/src/lib/components/OutputPane.svelte b/web/pw-server/src/lib/components/OutputPane.svelte
index 68c5c3b..65ae507 100644
--- a/web/pw-server/src/lib/components/OutputPane.svelte
+++ b/web/pw-server/src/lib/components/OutputPane.svelte
@@ -1,5 +1,5 @@
<script lang="ts">
- import PlayerLog from "./PlayerLog.svelte";
+ import PlayerLog from "./log_viewer/PlayerLog.svelte";
export let matchLog: string;
</script>
diff --git a/web/pw-server/src/lib/components/PlayerLog.svelte b/web/pw-server/src/lib/components/PlayerLog.svelte
deleted file mode 100644
index 60097d8..0000000
--- a/web/pw-server/src/lib/components/PlayerLog.svelte
+++ /dev/null
@@ -1,153 +0,0 @@
-<script lang="ts">
- import { parsePlayerLog, PlayerLog } from "$lib/log_parser";
-
- export let matchLog: string;
- export let playerId: number;
- export let showStdErr: boolean = true;
-
- let playerLog: PlayerLog;
-
- let showRawStderr = false;
-
- const PLURAL_MAP = {
- dispatch: "dispatches",
- ship: "ships",
- };
-
- function pluralize(num: number, word: string): string {
- if (num == 1) {
- return `1 ${word}`;
- } else {
- return `${num} ${PLURAL_MAP[word]}`;
- }
- }
-
- $: if (matchLog) {
- playerLog = parsePlayerLog(playerId, matchLog);
- } else {
- playerLog = [];
- }
-</script>
-
-<div class="output">
- {#if showRawStderr}
- <div class="output-text stderr-text">
- {playerLog.flatMap((turn) => turn.stderr).join("\n")}
- </div>
- {:else}
- <div class="output-text">
- {#each playerLog as logTurn, i}
- <div class="turn">
- <div class="turn-header">
- <span class="turn-header-text">Turn {i}</span>
- {#if logTurn.action?.type === "dispatches"}
- {pluralize(logTurn.action.dispatches.length, "dispatch")}
- {:else if logTurn.action?.type === "timeout"}
- <span class="turn-error">timeout</span>
- {:else if logTurn.action?.type === "bad_command"}
- <span class="turn-error">invalid command</span>
- {/if}
- </div>
- {#if logTurn.action?.type === "dispatches"}
- <div class="dispatches-container">
- {#each logTurn.action.dispatches as dispatch}
- <div class="dispatch">
- <div class="dispatch-text">
- {pluralize(dispatch.ship_count, "ship")} from {dispatch.origin} to {dispatch.destination}
- </div>
- {#if dispatch.error}
- <span class="dispatch-error">{dispatch.error}</span>
- {/if}
- </div>
- {/each}
- </div>
- {:else if logTurn.action?.type === "bad_command"}
- <div class="bad-command-container">
- <div class="bad-command-text">{logTurn.action.command}</div>
- <div class="bad-command-error">Parse error: {logTurn.action.error}</div>
- </div>
- {/if}
- {#if showStdErr && logTurn.stderr.length > 0}
- <div class="stderr-header">stderr</div>
- <div class="stderr-text-box">
- {#each logTurn.stderr as stdErrMsg}
- <div class="stderr-text">{stdErrMsg}</div>
- {/each}
- </div>
- {/if}
- </div>
- {/each}
- </div>
- {/if}
-</div>
-
-<style lang="scss">
- .output {
- background-color: rgb(41, 41, 41);
- }
-
- .turn {
- margin: 16px 4px;
- }
-
- .output-text {
- color: #ccc;
- }
-
- .turn-header {
- display: flex;
- justify-content: space-between;
- }
-
- .turn-header-text {
- color: #eee;
- font-size: 14px;
- font-weight: 600;
- text-transform: uppercase;
- }
-
- .turn-error {
- color: red;
- }
-
- .dispatch {
- display: flex;
- justify-content: space-between;
- }
-
- .dispatch-error {
- color: red;
- }
-
- .bad-command-container {
- border-left: 1px solid red;
- margin-left: 4px;
- padding-left: 8px;
- }
-
- .bad-command-text {
- font-family: "Consolas", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace;
- padding-bottom: 4px;
- }
-
- .bad-command-error {
- color: whitesmoke;
- }
-
- .stderr-text {
- // font-family: monospace;
- font-family: "Consolas", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace;
- white-space: pre-wrap;
- }
-
- .stderr-header {
- color: #eee;
- padding-top: 4px;
- }
-
- .stderr-text-box {
- border-left: 1px solid #ccc;
- margin-left: 4px;
- padding-left: 8px;
- }
-</style>
diff --git a/web/pw-server/src/lib/components/log_viewer/LogTurn.svelte b/web/pw-server/src/lib/components/log_viewer/LogTurn.svelte
index e69de29..80367f4 100644
--- a/web/pw-server/src/lib/components/log_viewer/LogTurn.svelte
+++ b/web/pw-server/src/lib/components/log_viewer/LogTurn.svelte
@@ -0,0 +1,160 @@
+<script lang="ts">
+ import type { PlayerLogTurn } from "$lib/log_parser";
+ import Fa from "svelte-fa";
+ import { faAngleRight, faAngleDown } from "@fortawesome/free-solid-svg-icons";
+
+ export let turnNum: number;
+ export let logTurn: PlayerLogTurn;
+ let expanded = false;
+
+ const PLURAL_MAP = {
+ dispatch: "dispatches",
+ ship: "ships",
+ };
+
+ function pluralize(num: number, word: string): string {
+ if (num == 1) {
+ return `1 ${word}`;
+ } else {
+ return `${num} ${PLURAL_MAP[word]}`;
+ }
+ }
+
+ function toggleExpand() {
+ expanded = !expanded;
+ }
+</script>
+
+<div class="turn">
+ <div class="turn-header" on:click={toggleExpand}>
+ <span>
+ <span class="turn-header-icon">
+ {#if expanded}
+ <Fa icon={faAngleDown} />
+ {:else}
+ <Fa icon={faAngleRight} />
+ {/if}
+ </span>
+ <span class="turn-header-text">
+ Turn {turnNum}
+ </span>
+ </span>
+ {#if logTurn.action?.type === "dispatches"}
+ {pluralize(logTurn.action.dispatches.length, "dispatch")}
+ {:else if logTurn.action?.type === "timeout"}
+ <span class="turn-error">timeout</span>
+ {:else if logTurn.action?.type === "bad_command"}
+ <span class="turn-error">invalid command</span>
+ {/if}
+ </div>
+ {#if expanded}
+ <div class="turn-content">
+ {#if logTurn.action?.type === "dispatches"}
+ <div class="dispatches-container">
+ {#each logTurn.action.dispatches as dispatch}
+ <div class="dispatch">
+ <div class="dispatch-text">
+ {pluralize(dispatch.ship_count, "ship")} from {dispatch.origin} to {dispatch.destination}
+ </div>
+ {#if dispatch.error}
+ <span class="dispatch-error">{dispatch.error}</span>
+ {/if}
+ </div>
+ {/each}
+ </div>
+ {:else if logTurn.action?.type === "bad_command"}
+ <div class="bad-command-container">
+ <div class="bad-command-text">{logTurn.action.command}</div>
+ <div class="bad-command-error">Parse error: {logTurn.action.error}</div>
+ </div>
+ {/if}
+ {#if logTurn.stderr.length > 0}
+ <div class="stderr-header">stderr</div>
+ <div class="stderr-text-box">
+ {#each logTurn.stderr as stdErrMsg}
+ <div class="stderr-text">{stdErrMsg}</div>
+ {/each}
+ </div>
+ {/if}
+ </div>
+ {/if}
+</div>
+
+<style lang="scss">
+ .turn {
+ // padding: 4px 2px;
+ color: #ccc;
+ }
+
+ .turn-header-icon {
+ // padding-right: 0.2em;
+ display: inline-block;
+ width: 1em;
+ }
+
+ .turn-header {
+ display: flex;
+ justify-content: space-between;
+ }
+
+ .turn-header:hover {
+ cursor: pointer;
+ background-color: #333;
+ }
+
+ .turn-header-text {
+ color: #eee;
+ font-size: 14px;
+ font-weight: 600;
+ text-transform: uppercase;
+ }
+
+ .turn-content {
+ margin-bottom: 12px;
+ }
+
+ .turn-error {
+ color: red;
+ }
+
+ .dispatch {
+ display: flex;
+ justify-content: space-between;
+ }
+
+ .dispatch-error {
+ color: red;
+ }
+
+ .bad-command-container {
+ border-left: 1px solid red;
+ margin-left: 4px;
+ padding-left: 8px;
+ }
+
+ .bad-command-text {
+ font-family: "Consolas", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace;
+ padding-bottom: 4px;
+ }
+
+ .bad-command-error {
+ color: whitesmoke;
+ }
+
+ .stderr-text {
+ // font-family: monospace;
+ font-family: "Consolas", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace;
+ white-space: pre-wrap;
+ }
+
+ .stderr-header {
+ color: #eee;
+ padding-top: 4px;
+ }
+
+ .stderr-text-box {
+ border-left: 1px solid #ccc;
+ margin-left: 4px;
+ padding-left: 8px;
+ }
+</style>
diff --git a/web/pw-server/src/lib/components/log_viewer/PlayerLog.svelte b/web/pw-server/src/lib/components/log_viewer/PlayerLog.svelte
new file mode 100644
index 0000000..450fdf2
--- /dev/null
+++ b/web/pw-server/src/lib/components/log_viewer/PlayerLog.svelte
@@ -0,0 +1,39 @@
+<script lang="ts">
+ import { parsePlayerLog, PlayerLog } from "$lib/log_parser";
+ import LogTurn from "./LogTurn.svelte";
+
+ export let matchLog: string;
+ export let playerId: number;
+
+ let playerLog: PlayerLog;
+ let showRawStderr = false;
+
+ $: if (matchLog) {
+ playerLog = parsePlayerLog(playerId, matchLog);
+ } else {
+ playerLog = [];
+ }
+</script>
+
+<div class="output">
+ {#if showRawStderr}
+ <div class="output-text stderr-text">
+ {playerLog.flatMap((turn) => turn.stderr).join("\n")}
+ </div>
+ {:else}
+ <!-- The log should be rerendered when playerId changes -->
+ {#key playerId}
+ <div class="log-contents">
+ {#each playerLog as logTurn, turnNum}
+ <LogTurn {logTurn} {turnNum} />
+ {/each}
+ </div>
+ {/key}
+ {/if}
+</div>
+
+<style lang="scss">
+ .output {
+ background-color: rgb(41, 41, 41);
+ }
+</style>
diff --git a/web/pw-server/src/routes/matches/[match_id].svelte b/web/pw-server/src/routes/matches/[match_id].svelte
index 653b3bf..1d5e072 100644
--- a/web/pw-server/src/routes/matches/[match_id].svelte
+++ b/web/pw-server/src/routes/matches/[match_id].svelte
@@ -22,7 +22,7 @@
<script lang="ts">
import { onMount } from "svelte";
import Visualizer from "$lib/components/Visualizer.svelte";
- import PlayerLog from "$lib/components/PlayerLog.svelte";
+ import PlayerLog from "$lib/components/log_viewer/PlayerLog.svelte";
import Select from "svelte-select";
import { PLAYER_COLORS } from "$lib/constants";
import { currentUser } from "$lib/stores/current_user";
diff --git a/web/pw-visualizer/src/index.ts b/web/pw-visualizer/src/index.ts
index 74b2319..8159134 100644
--- a/web/pw-visualizer/src/index.ts
+++ b/web/pw-visualizer/src/index.ts
@@ -51,6 +51,15 @@ export function set_loading(loading: boolean) {
}
}
+// this function should be called after resizes happen
+function do_resize() {
+ resizeCanvasToDisplaySize(CANVAS);
+
+ if (game_instance) {
+ game_instance.on_resize();
+ }
+}
+
function clamp(min: number, max: number, value: number): number {
if (value < min) {
return min;
@@ -103,17 +112,7 @@ export function init() {
GL.enable(GL.BLEND);
GL.blendFunc(GL.SRC_ALPHA, GL.ONE_MINUS_SRC_ALPHA);
- window.addEventListener(
- "resize",
- function () {
- resizeCanvasToDisplaySize(CANVAS);
-
- if (game_instance) {
- game_instance.on_resize();
- }
- },
- { capture: false, passive: true }
- );
+ new ResizeObserver(do_resize).observe(ELEMENTS["canvas"]);
ELEMENTS["turnSlider"].oninput = function () {
if (game_instance) {