diff --git a/apps/matrix/apps/web/src/routes/(app)/chat/[roomId]/+page.svelte b/apps/matrix/apps/web/src/routes/(app)/chat/[roomId]/+page.svelte index 550b5fb2f..8a5daff5c 100644 --- a/apps/matrix/apps/web/src/routes/(app)/chat/[roomId]/+page.svelte +++ b/apps/matrix/apps/web/src/routes/(app)/chat/[roomId]/+page.svelte @@ -14,6 +14,14 @@ let activeCall = $derived(matrixStore.activeCall); let incomingCall = $derived(matrixStore.incomingCall); + // Swipe-back gesture state + let touchStartX = 0; + let touchStartY = 0; + let isSwiping = $state(false); + let swipeProgress = $state(0); + const SWIPE_THRESHOLD = 100; // px to trigger back navigation + const EDGE_ZONE = 30; // px from left edge to start swipe + let showRoomSettings = $state(false); let showSearch = $state(false); let showForward = $state(false); @@ -69,7 +77,66 @@ }); function handleBack() { - goto('/chat'); + // Use history.back() if we came from the chat list, otherwise goto + if (browser && window.history.length > 1) { + window.history.back(); + } else { + goto('/chat'); + } + } + + // Touch event handlers for swipe-back gesture + function handleTouchStart(e: TouchEvent) { + const touch = e.touches[0]; + // Only start swipe if touch begins in the left edge zone + if (touch.clientX <= EDGE_ZONE) { + touchStartX = touch.clientX; + touchStartY = touch.clientY; + isSwiping = true; + swipeProgress = 0; + } + } + + function handleTouchMove(e: TouchEvent) { + if (!isSwiping) return; + + const touch = e.touches[0]; + const deltaX = touch.clientX - touchStartX; + const deltaY = Math.abs(touch.clientY - touchStartY); + + // Cancel if vertical movement is greater than horizontal (scrolling) + if (deltaY > Math.abs(deltaX)) { + isSwiping = false; + swipeProgress = 0; + return; + } + + // Only track right swipe + if (deltaX > 0) { + swipeProgress = Math.min(deltaX / SWIPE_THRESHOLD, 1); + // Prevent default to avoid scroll interference + if (deltaX > 10) { + e.preventDefault(); + } + } + } + + function handleTouchEnd() { + if (!isSwiping) return; + + // Navigate back if swipe threshold reached + if (swipeProgress >= 1) { + handleBack(); + } + + // Reset state + isSwiping = false; + swipeProgress = 0; + } + + function handleTouchCancel() { + isSwiping = false; + swipeProgress = 0; } function handleReply(message: SimpleMessage) { @@ -114,7 +181,39 @@ -
+ +
+ + {#if isSwiping && swipeProgress > 0} +
+
+
+ + + +
+
+ {/if} {#if matrixStore.currentRoom}