diff options
Diffstat (limited to 'web/pw-server/src/routes/index.svelte')
-rw-r--r-- | web/pw-server/src/routes/index.svelte | 277 |
1 files changed, 0 insertions, 277 deletions
diff --git a/web/pw-server/src/routes/index.svelte b/web/pw-server/src/routes/index.svelte index 85c2454..e69de29 100644 --- a/web/pw-server/src/routes/index.svelte +++ b/web/pw-server/src/routes/index.svelte @@ -1,277 +0,0 @@ -<script lang="ts"> - import Visualizer from "$lib/components/Visualizer.svelte"; - import EditorView from "$lib/components/EditorView.svelte"; - import { onMount } from "svelte"; - - import { DateTime } from "luxon"; - - import type { Ace } from "ace-builds"; - import ace from "ace-builds/src-noconflict/ace?client"; - import * as AcePythonMode from "ace-builds/src-noconflict/mode-python?client"; - import { getBotCode, saveBotCode, hasBotCode } from "$lib/bot_code"; - import { debounce } from "$lib/utils"; - import SubmitPane from "$lib/components/SubmitPane.svelte"; - import OutputPane from "$lib/components/OutputPane.svelte"; - import RulesView from "$lib/components/RulesView.svelte"; - import Leaderboard from "$lib/components/Leaderboard.svelte"; - - enum ViewMode { - Editor, - MatchVisualizer, - Rules, - Leaderboard, - } - - let matches = []; - - let viewMode = ViewMode.Editor; - let selectedMatchId: string | undefined = undefined; - let selectedMatchLog: string | undefined = undefined; - - let editSession: Ace.EditSession; - - onMount(() => { - if (!hasBotCode()) { - viewMode = ViewMode.Rules; - } - init_editor(); - }); - - function init_editor() { - editSession = new ace.EditSession(getBotCode()); - editSession.setMode(new AcePythonMode.Mode()); - - const saveCode = () => { - const code = editSession.getDocument().getValue(); - saveBotCode(code); - }; - - // cast to any because the type annotations are wrong here - (editSession as any).on("change", debounce(saveCode, 2000)); - } - - async function onMatchCreated(e: CustomEvent) { - const matchData = e.detail["match"]; - matches.unshift(matchData); - matches = matches; - await selectMatch(matchData["id"]); - } - - async function selectMatch(matchId: string) { - selectedMatchId = matchId; - selectedMatchLog = null; - fetchSelectedMatchLog(matchId); - - viewMode = ViewMode.MatchVisualizer; - } - - async function fetchSelectedMatchLog(matchId: string) { - if (matchId !== selectedMatchId) { - return; - } - - let matchLog = await getMatchLog(matchId); - - if (matchLog) { - selectedMatchLog = matchLog; - } else { - // try again in 1 second - setTimeout(fetchSelectedMatchLog, 1000, matchId); - } - } - - async function getMatchData(matchId: string) { - let response = await fetch(`/api/matches/${matchId}`, { - headers: { - "Content-Type": "application/json", - }, - }); - - if (!response.ok) { - throw Error(response.statusText); - } - - let matchData = await response.json(); - return matchData; - } - - async function getMatchLog(matchId: string) { - const matchData = await getMatchData(matchId); - console.log(matchData); - if (matchData["state"] !== "Finished") { - // log is not available yet - return null; - } - - const res = await fetch(`/api/matches/${matchId}/log`, { - headers: { - "Content-Type": "application/json", - }, - }); - - let log = await res.text(); - return log; - } - - function setViewMode(viewMode_: ViewMode) { - selectedMatchId = undefined; - selectedMatchLog = undefined; - viewMode = viewMode_; - } - - function selectRules() { - selectedMatchId = undefined; - selectedMatchLog = undefined; - viewMode = ViewMode.Rules; - } - - function formatMatchTimestamp(timestampString: string): string { - let timestamp = DateTime.fromISO(timestampString, { zone: "utc" }).toLocal(); - if (timestamp.startOf("day").equals(DateTime.now().startOf("day"))) { - return timestamp.toFormat("HH:mm"); - } else { - return timestamp.toFormat("dd/MM"); - } - } - - $: selectedMatch = matches.find((m) => m["id"] === selectedMatchId); -</script> - -<div class="container"> - <div class="sidebar-left"> - <div - class="editor-button sidebar-item" - class:selected={viewMode === ViewMode.Editor} - on:click={() => setViewMode(ViewMode.Editor)} - > - Editor - </div> - <div - class="rules-button sidebar-item" - class:selected={viewMode === ViewMode.Rules} - on:click={() => setViewMode(ViewMode.Rules)} - > - Rules - </div> - <div - class="sidebar-item" - class:selected={viewMode === ViewMode.Leaderboard} - on:click={() => setViewMode(ViewMode.Leaderboard)} - > - Leaderboard - </div> - <div class="sidebar-header">match history</div> - <ul class="match-list"> - {#each matches as match} - <li - class="match-card sidebar-item" - on:click={() => selectMatch(match.id)} - class:selected={match.id === selectedMatchId} - > - <span class="match-timestamp">{formatMatchTimestamp(match.timestamp)}</span> - <!-- hex is hardcoded for now, don't show map name --> - <!-- <span class="match-mapname">hex</span> --> - <!-- ugly temporary hardcode --> - <span class="match-opponent">{match["players"][1]["bot_name"]}</span> - </li> - {/each} - </ul> - </div> - <div class="editor-container"> - {#if viewMode === ViewMode.MatchVisualizer} - <Visualizer matchData={selectedMatch} matchLog={selectedMatchLog} /> - {:else if viewMode === ViewMode.Editor} - <EditorView {editSession} /> - {:else if viewMode === ViewMode.Rules} - <RulesView /> - {:else if viewMode === ViewMode.Leaderboard} - <Leaderboard /> - {/if} - </div> - <div class="sidebar-right"> - {#if viewMode === ViewMode.MatchVisualizer} - <OutputPane matchLog={selectedMatchLog} /> - {:else if viewMode === ViewMode.Editor} - <SubmitPane {editSession} on:matchCreated={onMatchCreated} /> - {/if} - </div> -</div> - -<style lang="scss"> - @import "src/styles/variables.scss"; - - .container { - display: flex; - flex-grow: 1; - min-height: 0; - } - - .sidebar-left { - width: 240px; - background-color: $bg-color; - display: flex; - flex-direction: column; - } - .sidebar-right { - width: 400px; - background-color: white; - border-left: 1px solid; - padding: 0; - display: flex; - overflow: hidden; - } - .editor-container { - flex-grow: 1; - flex-shrink: 1; - overflow: hidden; - background-color: white; - } - - .editor-container { - height: 100%; - } - - .sidebar-item { - color: #eee; - padding: 15px; - } - - .sidebar-item:hover { - background-color: #333; - } - - .sidebar-item.selected { - background-color: #333; - } - - .match-list { - list-style: none; - color: #eee; - padding-top: 15px; - overflow-y: scroll; - padding-left: 0px; - } - - .match-card { - padding: 10px 15px; - font-size: 11pt; - } - - .match-timestamp { - color: #ccc; - } - - .match-opponent { - padding: 0 0.5em; - } - - .sidebar-header { - margin-top: 2em; - text-transform: uppercase; - font-weight: 600; - color: rgba(255, 255, 255, 0.7); - font-size: 14px; - font-family: "Open Sans", sans-serif; - padding-left: 14px; - } -</style> |