From 8d556bbff1bd716c2c42c8002706038f28b55b91 Mon Sep 17 00:00:00 2001
From: Ilion Beyst <ilion.beyst@gmail.com>
Date: Sun, 30 Oct 2022 16:23:18 +0100
Subject: add filtering and infinite scroll to BotMatches

---
 .../src/lib/components/matches/BotMatchList.svelte | 73 ++++++++++++++++++++--
 1 file changed, 69 insertions(+), 4 deletions(-)

(limited to 'web/pw-server/src/lib/components/matches/BotMatchList.svelte')

diff --git a/web/pw-server/src/lib/components/matches/BotMatchList.svelte b/web/pw-server/src/lib/components/matches/BotMatchList.svelte
index 959cd07..4a00909 100644
--- a/web/pw-server/src/lib/components/matches/BotMatchList.svelte
+++ b/web/pw-server/src/lib/components/matches/BotMatchList.svelte
@@ -1,19 +1,84 @@
 <script lang="ts">
-  import type { BotMatch } from "$lib/matches";
+  import { ApiClient } from "$lib/api_client";
+  import { apiMatchtoBotMatch, BotMatch } from "$lib/matches";
+  import { onDestroy, onMount } from "svelte";
   import BotMatchCard from "./BotMatchCard.svelte";
 
-  export let botMatches: BotMatch[];
+  export let botName: string;
+  export let opponentName: string | undefined;
+  export let mapName: string | undefined;
 
-  function match_url(match: object) {
-    return `/matches/${match["id"]}`;
+  let botMatches: BotMatch[] = [];
+  let nextCursor = undefined;
+  let loading = false;
+  let hasMore = true;
+
+  onMount(async () => {
+    window.addEventListener("scroll", onScroll);
+    window.addEventListener("resize", onScroll);
+  });
+
+  onDestroy(() => {
+    window.removeEventListener("scroll", onScroll);
+    window.removeEventListener("resize", onScroll);
+  });
+
+  function onScroll(e: Event) {
+    // const element = e.target as HTMLElement;
+    const element = window.document.body;
+    if (hasMore && element.scrollHeight - window.scrollY - element.clientHeight <= 300) {
+      fetchNextPage();
+    }
+  }
+
+  async function fetchNextPage() {
+    if (loading) {
+      return;
+    }
+    loading = true;
+    const params = { bot: botName, count: "50" };
+    if (opponentName) {
+      params["opponent"] = opponentName;
+    }
+    if (mapName) {
+      params["map"] = mapName;
+    }
+    if (nextCursor) {
+      params["before"] = nextCursor;
+    }
+    const apiClient = new ApiClient();
+    let { matches, has_next } = await apiClient.get("/api/matches", params);
+    if (has_next) {
+      nextCursor = matches[matches.length - 1]["timestamp"];
+    } else {
+      hasMore = false;
+    }
+    botMatches = botMatches.concat(matches.map((m) => apiMatchtoBotMatch(botName, m)));
+    loading = false;
   }
+
+  async function resetList(..._params: any[]) {
+    botMatches = [];
+    nextCursor = undefined;
+    hasMore = true;
+    await fetchNextPage();
+  }
+
+  $: resetList(botName, opponentName, mapName);
 </script>
 
 <div>
   {#each botMatches as botMatch}
     <BotMatchCard {botMatch} />
   {/each}
+  {#if loading}
+    <div class="loading-container">Loading...</div>
+  {/if}
 </div>
 
 <style lang="scss">
+  .loading-container {
+    text-align: center;
+    padding: 16px;
+  }
 </style>
-- 
cgit v1.2.3

