From 0be2370e0d332b5b8ae2548f6ffdd7869d441ab8 Mon Sep 17 00:00:00 2001
From: Kit La Touche <kit@transneptune.net>
Date: Mon, 18 Nov 2024 22:20:08 -0500
Subject: Add Tinygesture for swipe events

Hide and show channel menu thus. It doesn't gradually pull it out, which
is less than ideal, but it's good enough for now.
---
 ui/routes/(app)/+layout.svelte | 64 ++++++++++++++++++++----------------------
 1 file changed, 31 insertions(+), 33 deletions(-)

(limited to 'ui/routes/(app)/+layout.svelte')

diff --git a/ui/routes/(app)/+layout.svelte b/ui/routes/(app)/+layout.svelte
index 84c71ec..406d85a 100644
--- a/ui/routes/(app)/+layout.svelte
+++ b/ui/routes/(app)/+layout.svelte
@@ -1,7 +1,9 @@
 <script>
   import { page } from '$app/stores';
   import { goto } from '$app/navigation';
+  import { browser } from '$app/environment';
   import { onMount, onDestroy, getContext } from 'svelte';
+  import TinyGesture from 'tinygesture';
 
   import { boot, subscribeToEvents } from '$lib/apiServer';
   import { currentUser, logins, channelsList, messages } from '$lib/store';
@@ -10,6 +12,7 @@
   import CreateChannelForm from '$lib/components/CreateChannelForm.svelte';
 
   let events = null;
+  let gesture = null;
 
   let pageContext = getContext('page');
   let { children } = $props();
@@ -26,38 +29,18 @@
     messages.update((value) => value.setMessages(boot.messages));
   }
 
-  function setTouchEvents() {
-      document.addEventListener("touchstart", processTouchStart);
-      document.addEventListener("touchmove", processTouchMove);
-      document.addEventListener("touchcancel", processTouchCancel);
-      document.addEventListener("touchend", processTouchEnd);
-  }
-
-  function processTouchStart(ev) {
-      ev.preventDefault();
-      switch (ev.touches.length) {
-          case 1:
-              console.log("touch: single");
-              break;
-          case 2:
-              console.log("touch: double");
-              break;
-          case 3:
-              console.log("touch: triple");
-              break;
-          default:
-              console.log("touch: unsupported");
-              break;
-      }
-  }
-
-  function processTouchMove(ev) {
-  }
-
-  function processTouchCancel(ev) {
-  }
-
-  function processTouchEnd(ev) {
+  function setUpGestures() {
+    if (!browser) {
+      // Meaningless if we're not in a browser, so...
+      return;
+    }
+    gesture = new TinyGesture(window);
+    gesture.on('swiperight', (event) => {
+      pageContext.showMenu = true;
+    });
+    gesture.on('swipeleft', (event) => {
+      pageContext.showMenu = false;
+    });
   }
 
   onMount(async () => {
@@ -79,14 +62,18 @@
         // TODO: display error.
         break;
     }
+    setUpGestures();
+
     loading = false;
-    setTouchEvents();
   });
 
   onDestroy(async () => {
     if (events !== null) {
       events.close();
     }
+    if (gesture !== null) {
+        gesture.destroy();
+    }
   });
 </script>
 
@@ -113,12 +100,23 @@
 {/if}
 
 <style>
+  /* Just some global CSS variables, don't mind them.
+   */
   :root {
     --app-bar-height: 68px;
     --input-row-height: 2rem;
     --interface-padding: 16px;
   }
 
+  /* This should help minimize swipe-to-go-back behaviour, enabling our
+   * swipe-to-reveal-channel-menu behaviour. It won't work in all cases; in iOS
+   * Safari, when swiping from the screen edge, the OS gets th event and
+   * handles it before the browser does.
+   */
+  html, body {
+      overscroll-behavior-x: none;
+  }
+
   #interface {
     margin: unset;
     display: grid;
-- 
cgit v1.2.3

