From 1614fea76a6fc1f4d70ddb14b95e3004c79365ef Mon Sep 17 00:00:00 2001
From: Kit La Touche <kit@transneptune.net>
Date: Mon, 4 Nov 2024 22:31:27 -0500
Subject: Set up framework for testing touch events

This includes a change to tools/run that exposes the dev server on my
local network. This change should not make it into the final form of
this branch.

This is so I can use actual for real touch events on my actual for real
phone, hooked up for remote debugging to my computer so I can see
console events etc.
---
 ui/routes/(app)/+layout.svelte | 35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

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

diff --git a/ui/routes/(app)/+layout.svelte b/ui/routes/(app)/+layout.svelte
index ae3dc6a..acaea53 100644
--- a/ui/routes/(app)/+layout.svelte
+++ b/ui/routes/(app)/+layout.svelte
@@ -25,6 +25,40 @@
     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) {
+  }
+
   onMount(async () => {
     let response = await boot();
     switch (response.status) {
@@ -45,6 +79,7 @@
         break;
     }
     loading = false;
+    setTouchEvents();
   });
 
   onDestroy(async () => {
-- 
cgit v1.2.3


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.
---
 package-lock.json              |  9 +++++-
 package.json                   |  3 +-
 ui/routes/(app)/+layout.svelte | 64 ++++++++++++++++++++----------------------
 3 files changed, 41 insertions(+), 35 deletions(-)

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

diff --git a/package-lock.json b/package-lock.json
index 01b0cce..179731a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,7 +10,8 @@
 			"dependencies": {
 				"axios": "^1.7.7",
 				"dompurify": "^3.1.7",
-				"marked": "^14.1.3"
+				"marked": "^14.1.3",
+				"tinygesture": "^3.0.0"
 			},
 			"devDependencies": {
 				"@skeletonlabs/skeleton": "^2.10.3",
@@ -3372,6 +3373,12 @@
 				"globrex": "^0.1.2"
 			}
 		},
+		"node_modules/tinygesture": {
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/tinygesture/-/tinygesture-3.0.0.tgz",
+			"integrity": "sha512-UawUggtPCHy+N65ULpR/i6VLH8AzB7jWVvTNoXRFTJNh+ub6lP/SJCxzV/Ua7sJbCt9U9I79wKkKk3wbjcLdbQ==",
+			"license": "Apache-2.0"
+		},
 		"node_modules/to-regex-range": {
 			"version": "5.0.1",
 			"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
diff --git a/package.json b/package.json
index c51974c..0b96558 100644
--- a/package.json
+++ b/package.json
@@ -37,6 +37,7 @@
 	"dependencies": {
 		"axios": "^1.7.7",
 		"dompurify": "^3.1.7",
-		"marked": "^14.1.3"
+		"marked": "^14.1.3",
+		"tinygesture": "^3.0.0"
 	}
 }
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

