From 2c9ca397e444fb4c6be85d4e95b5d2df28e41a02 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Fri, 3 Jan 2025 23:44:20 +0200 Subject: [PATCH] feat(mobile): basic swipe mechanism for sidebar --- .../mobile_widgets/sidebar_container.js | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/src/public/app/widgets/mobile_widgets/sidebar_container.js b/src/public/app/widgets/mobile_widgets/sidebar_container.js index 282a51604..009f6a9d0 100644 --- a/src/public/app/widgets/mobile_widgets/sidebar_container.js +++ b/src/public/app/widgets/mobile_widgets/sidebar_container.js @@ -6,6 +6,7 @@ export default class SidebarContainer extends FlexContainer { super(direction); this.screenName = screenName; + this.currentTranslate = -100; } doRender() { @@ -16,6 +17,63 @@ export default class SidebarContainer extends FlexContainer { screen: "detail" }); }); + + document.addEventListener("touchstart", (e) => this.#onDragStart(e), { + passive: false + }); + document.addEventListener("touchmove", (e) => this.#onDragMove(e)); + document.addEventListener("touchend", (e) => this.#onDragEnd(e)); + } + + #onDragStart(e) { + if (!this.sidebarContainer) { + this.sidebarContainer = document.getElementById("mobile-sidebar-container"); + this.sidebarWrapper = document.getElementById("mobile-sidebar-wrapper"); + } + + const x = e.touches ? e.touches[0].clientX : e.clientX; + + if (x > 30 && this.currentTranslate === -100) { + return; + } + + this.isDragging = true; + this.startX = x; + + this.sidebarContainer.style.zIndex = 1000; + + this.sidebarWrapper.style.transition = "none"; + + e.preventDefault(); + } + + #onDragMove(e) { + if (!this.isDragging) { + return; + } + + const x = e.touches ? e.touches[0].clientX : e.clientX; + const deltaX = x - this.startX; + const width = this.sidebarWrapper.offsetWidth; + const translatePercentage = Math.min(0, Math.max(this.currentTranslate + (deltaX / width) * 100, -100)); + + this.sidebarWrapper.style.transform = `translateX(${translatePercentage}%)`; + } + + #onDragEnd(e) { + if (!this.isDragging) { + return; + } + + const translateX = parseFloat(this.sidebarWrapper.style.transform.match(/-?\d+/)[0]); + const isOpen = translateX > -50; + this.sidebarWrapper.classList.toggle("show", isOpen); + this.sidebarWrapper.style.transform = isOpen ? 'translateX(0)' : 'translateX(-100%)'; + this.currentTranslate = isOpen ? 0 : -100; + + if (!isOpen) { + this.sidebarContainer.style.zIndex = -1000; + } } activeScreenChangedEvent({activeScreen}) {