From 678adfbda486d79b8006fc8dfe6fa4d60ab721a9 Mon Sep 17 00:00:00 2001
From: dumbmoron <log@riseup.net>
Date: Tue, 16 Jul 2024 17:25:21 +0000
Subject: [PATCH] web/updates: proper navigation buttons, refactor internal nav
 logic

---
 web/src/routes/updates/+page.svelte | 122 +++++++++++++++++++++++-----
 1 file changed, 102 insertions(+), 20 deletions(-)

diff --git a/web/src/routes/updates/+page.svelte b/web/src/routes/updates/+page.svelte
index 79e70b5d..d2dd5496 100644
--- a/web/src/routes/updates/+page.svelte
+++ b/web/src/routes/updates/+page.svelte
@@ -1,15 +1,19 @@
 <script lang="ts">
-    import { onMount } from 'svelte';
-    import type { ChangelogImport } from '$lib/types/changelogs';
     import { t } from '$lib/i18n/translations';
     import { page } from '$app/stores';
+
     import { getAllChangelogs } from '$lib/changelogs';
+    import type { ChangelogImport } from '$lib/types/changelogs';
+
+    import IconChevronLeft from '@tabler/icons-svelte/IconChevronLeft.svelte';
+    import IconChevronRight from '@tabler/icons-svelte/IconChevronRight.svelte';
 
     const changelogs = getAllChangelogs();
     const versions = Object.keys(changelogs);
 
     let changelog: ChangelogImport & { version: string } | undefined;
-    let currentIndex = -1;
+    let currentIndex = 0;
+
     {
         const hash = $page.url.hash.replace("#", "");
         const versionIndex = versions.indexOf(hash);
@@ -33,25 +37,72 @@
         window.location.hash = version;
     }
 
-    const nextChangelog = async () => {
-        ++currentIndex;
-        await loadChangelog();
+    const loadNext = () => {
+        if (currentIndex < versions.length - 1)
+            ++currentIndex;
     }
 
-    onMount(async () => {
-        if (versions.length > 0) {
-            await nextChangelog()
-        } else {
-            // TODO: handle if no changelogs are present
-            // (can this happen? maybe)
-        }
-    });
+    const loadPrev = () => {
+        if (currentIndex > 0)
+            --currentIndex;
+    }
+
+    const preloadNext = () => {
+        if (!next) return;
+        changelogs[next]().catch(() => {});
+    }
+
+    $: prev = versions[currentIndex - 1];
+    $: next = versions[currentIndex + 1];
+    $: currentIndex, loadChangelog();
 </script>
 
 <style>
     .news {
-        max-width: 768px;
-        margin: 0 auto;
+        display: flex;
+        width: 100%;
+        flex-direction: row;
+        justify-content: space-evenly;
+    }
+
+    .button-wrapper-desktop {
+        display: flex;
+        justify-content: center;
+    }
+
+    .button-wrapper-desktop button {
+        position: absolute;
+        top: 50%;
+        background-color: transparent;
+        display: flex;
+        border: none;
+    }
+
+    .changelog-wrapper {
+        max-width: 768pt;
+    }
+
+    button[disabled] {
+        opacity: 0.5;
+        cursor: default;
+    }
+
+    .button-wrapper-mobile {
+        display: none;
+    }
+
+    @media only screen and (max-width: 992pt) {
+        .button-wrapper-mobile {
+            display: flex;
+            padding-bottom: 1rem;
+            margin-left: 1rem;
+            margin-right: 1rem;
+            justify-content: space-between;
+        }
+
+        .button-wrapper-desktop {
+            display: none;
+        }
     }
 </style>
 
@@ -63,9 +114,40 @@
 
 <div class="news">
     {#if changelog}
-        <svelte:component this={changelog.default} version={changelog.version} />
-    {/if}
-    {#if versions[currentIndex + 1]}
-        <button on:click={nextChangelog}>next</button>
+        <div class="button-wrapper-desktop">
+            <button on:click={loadPrev} disabled={!prev}>
+                <IconChevronLeft />
+                { prev || '' }
+            </button>
+        </div>
+        <div class="changelog-wrapper">
+                <svelte:component this={changelog.default} version={changelog.version} />
+                <div class="button-wrapper-mobile">
+                    <button on:click={loadPrev} disabled={!prev}>
+                        <IconChevronLeft />
+                        { prev || '' }
+                    </button>
+                    <button
+                        on:click={loadNext}
+                        on:focus={preloadNext}
+                        on:mousemove={preloadNext}
+                        disabled={!next}
+                    >
+                        { next || '' }
+                    <IconChevronRight />
+                </button>
+                </div>
+        </div>
+        <div class="button-wrapper-desktop">
+            <button
+                on:click={loadNext}
+                on:focus={preloadNext}
+                on:mousemove={preloadNext}
+                disabled={!next}
+            >
+                { next || '' }
+                <IconChevronRight />
+            </button>
+        </div>
     {/if}
 </div>
\ No newline at end of file