aboutsummaryrefslogtreecommitdiff
path: root/web/pw-frontend/src/lib/MatchBrowser.svelte
diff options
context:
space:
mode:
Diffstat (limited to 'web/pw-frontend/src/lib/MatchBrowser.svelte')
-rw-r--r--web/pw-frontend/src/lib/MatchBrowser.svelte140
1 files changed, 140 insertions, 0 deletions
diff --git a/web/pw-frontend/src/lib/MatchBrowser.svelte b/web/pw-frontend/src/lib/MatchBrowser.svelte
new file mode 100644
index 0000000..aeb45be
--- /dev/null
+++ b/web/pw-frontend/src/lib/MatchBrowser.svelte
@@ -0,0 +1,140 @@
+<script lang="ts">
+ import { onMount } from "svelte";
+ import Visualizer from "./Visualizer.svelte";
+ import moment from "moment";
+
+ const PLAYER_COLORS = [
+ "#FF8000",
+ "#0080FF",
+ "#FF6693",
+ "#3FCB55",
+ "#CBC33F",
+ "#CF40E9",
+ "#FF3F0D",
+ "#1BEEF0",
+ "#0DC5FF",
+ ];
+
+ let matches = [];
+ let selectedMatch = null;
+ let selectedMatchLog = null;
+
+ onMount(() => {
+ fetch("/api/matches")
+ .then((response) => response.json())
+ .then((m) => (matches = m));
+ });
+
+ function selectMatch(matchName) {
+ selectedMatch = matchName;
+ selectedMatchLog = null;
+ fetch(`/api/matches/${matchName}`)
+ .then((resp) => resp.text())
+ .then((log) => {
+ selectedMatchLog = log;
+ });
+ }
+
+ function showTimestamp(dateStr: string): string {
+ let t = moment(dateStr);
+ if (t.day() == moment().day()) {
+ return moment(dateStr).format("HH:mm");
+ } else {
+ return moment(dateStr).format("DD/MM");
+ }
+ }
+
+ function playerColor(player_num: number): string {
+ return PLAYER_COLORS[player_num % PLAYER_COLORS.length];
+ }
+</script>
+
+<div class="container">
+ <div class="sidebar">
+ <div class="sidebar-header" />
+ <ul class="match-list">
+ {#each matches as match (match.name)}
+ <li
+ on:click={() => selectMatch(match.name)}
+ class:selected={selectedMatch === match.name}
+ class="match-card"
+ >
+ <div class="match-name">{match.name}</div>
+ <span class="match-timestamp">{showTimestamp(match.timestamp)}</span>
+ <span class="match-mapname">{match.map_name}</span>
+ <ul class="match-player-list">
+ {#each match.players as player, ix}
+ <li class="match-player" style="color: {playerColor(ix)}">
+ {player.name}
+ </li>
+ {/each}
+ </ul>
+ </li>
+ {/each}
+ </ul>
+ </div>
+ <Visualizer matchLog={selectedMatchLog} />
+</div>
+
+<style scoped>
+ .container {
+ display: flex;
+ width: 100vw;
+ height: 100vh;
+ overflow-y: hidden;
+ background-color: rgb(41, 41, 41);
+ }
+
+ .sidebar {
+ width: 20%;
+ width: 350px;
+ color: #eee;
+ overflow: hidden;
+ overflow-y: scroll;
+ height: 100%;
+ }
+
+ .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;
+ }
+
+ .match-list {
+ list-style: none;
+ padding: 0;
+ }
+
+ .match-card {
+ padding: 0.5em;
+ padding-left: 14px;
+ }
+
+ .match-card.selected {
+ background-color: #333;
+ }
+
+ .match-card:hover {
+ background-color: #333;
+ }
+
+ .match-timestamp {
+ color: #ccc;
+ }
+
+ .match-mapname {
+ padding: 0 0.5em;
+ color: #ccc;
+ }
+
+ .match-player-list {
+ list-style: none;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ padding-left: 18px;
+ }
+</style>