From 864e40e25d1bc4a1d7eab4666f6e5303e5d082ce Mon Sep 17 00:00:00 2001 From: ervin Date: Fri, 2 Jan 2026 20:02:45 +0100 Subject: [PATCH] menu --- .ottotime | 3 +- components/AppMenu.vue | 231 +++++++++++++++++++++++++++++++--------- components/RentStep.vue | 2 +- 3 files changed, 184 insertions(+), 52 deletions(-) diff --git a/.ottotime b/.ottotime index 6a3f18c..5f6de5d 100644 --- a/.ottotime +++ b/.ottotime @@ -76,4 +76,5 @@ 1767345728- 93:01 1767373107- 6:35 1767376587- 12:56 -1767377746- 5:52 +1767377746- 15:56 +1767379098- 24:00 diff --git a/components/AppMenu.vue b/components/AppMenu.vue index 189d6b6..a75f988 100644 --- a/components/AppMenu.vue +++ b/components/AppMenu.vue @@ -10,32 +10,44 @@
- - -
- Adataim - - {{ p.label }} - - - Kijelentketés -
-
+
+ - +
{{ props.title }} @@ -65,59 +77,178 @@ const auth = useAuthStore() const config = useMyConfigStore() const token = useCookie('_auth') -const menuShow = ref(false) const router = useRouter() -const isHome = computed(()=>{ - return (route.fullPath === '/') +const isHome = computed(() => { + return (route.fullPath === '/') }) -// Swipe gesture handling -const touchStartX = ref(0) -const touchEndX = ref(0) -const minSwipeDistance = 50 +// Drawer constants +const DRAWER_WIDTH = 288 +const SWIPE_THRESHOLD = 80 +const EDGE_ZONE = 40 + +// Simple state +const drawerRef = ref(null) +const isOpen = ref(false) +const isDragging = ref(false) +const dragOffset = ref(0) // 0 = fully open position, DRAWER_WIDTH = fully closed +const menuHistoryPushed = ref(false) + +// Touch tracking +let touchStartX = 0 +let touchStartY = 0 +let startedFromEdge = false +let isHorizontalSwipe: boolean | null = null + +// Computed translate value +const translateX = computed(() => { + if (isDragging.value) { + return Math.max(0, Math.min(DRAWER_WIDTH, dragOffset.value)) + } + return isOpen.value ? 0 : DRAWER_WIDTH +}) + +// Backdrop opacity based on position +const backdropOpacity = computed(() => { + const openness = 1 - (translateX.value / DRAWER_WIDTH) + return openness * 0.5 +}) + +// Dynamic classes +const drawerClass = computed(() => ({ + 'transition-transform duration-300 ease-out': !isDragging.value, + 'pointer-events-none': !isOpen.value && !isDragging.value +})) + +const backdropClass = computed(() => ({ + 'transition-opacity duration-300': !isDragging.value, + 'pointer-events-none': backdropOpacity.value <= 0 +})) + +function openMenu() { + isOpen.value = true + if (!menuHistoryPushed.value) { + window.history.pushState({ menuOpen: true }, '') + menuHistoryPushed.value = true + } +} + +function closeMenu() { + isOpen.value = false + if (menuHistoryPushed.value) { + menuHistoryPushed.value = false + window.history.back() + } +} + +function closeMenuWithoutHistory() { + isOpen.value = false + menuHistoryPushed.value = false +} + +function handlePopState() { + if (isOpen.value) { + closeMenuWithoutHistory() + } +} function handleTouchStart(e: TouchEvent) { - touchStartX.value = e.touches[0].clientX -} + const touch = e.touches[0] + touchStartX = touch.clientX + touchStartY = touch.clientY + isHorizontalSwipe = null -function handleTouchEnd(e: TouchEvent) { - touchEndX.value = e.changedTouches[0].clientX - handleSwipe() -} - -function handleSwipe() { - const swipeDistance = touchEndX.value - touchStartX.value const screenWidth = window.innerWidth + startedFromEdge = touchStartX > screenWidth - EDGE_ZONE - // Swipe left (from right edge) -> open menu - if (swipeDistance < -minSwipeDistance && touchStartX.value > screenWidth - 50) { - if (props.menu) { - menuShow.value = true + if (isOpen.value) { + dragOffset.value = 0 + } else if (startedFromEdge) { + dragOffset.value = DRAWER_WIDTH + } +} + +function handleTouchMove(e: TouchEvent) { + if (!isOpen.value && !startedFromEdge) return + + const touch = e.touches[0] + const deltaX = touch.clientX - touchStartX + const deltaY = touch.clientY - touchStartY + + // Determine swipe direction on first significant movement + if (isHorizontalSwipe === null && (Math.abs(deltaX) > 10 || Math.abs(deltaY) > 10)) { + isHorizontalSwipe = Math.abs(deltaX) > Math.abs(deltaY) + } + + if (!isHorizontalSwipe) return + + // Start dragging + if (!isDragging.value) { + if (isOpen.value && deltaX > 0) { + isDragging.value = true + } else if (startedFromEdge && deltaX < 0) { + isDragging.value = true } } - // Swipe right -> close menu (if open) - if (swipeDistance > minSwipeDistance && menuShow.value) { - menuShow.value = false + if (isDragging.value) { + if (isOpen.value) { + // Dragging to close: deltaX > 0 means moving right + dragOffset.value = Math.max(0, deltaX) + } else { + // Dragging to open: deltaX < 0 means moving left + dragOffset.value = DRAWER_WIDTH + deltaX + } } } +function handleTouchEnd() { + if (!isDragging.value) { + startedFromEdge = false + isHorizontalSwipe = null + return + } + + const currentOffset = dragOffset.value + + if (isOpen.value) { + // Was open - check if should close + if (currentOffset > SWIPE_THRESHOLD) { + closeMenu() + } + } else { + // Was closed - check if should open + if (currentOffset < DRAWER_WIDTH - SWIPE_THRESHOLD) { + openMenu() + } + } + + // Reset + isDragging.value = false + startedFromEdge = false + isHorizontalSwipe = null +} + onMounted(() => { document.addEventListener('touchstart', handleTouchStart, { passive: true }) + document.addEventListener('touchmove', handleTouchMove, { passive: true }) document.addEventListener('touchend', handleTouchEnd, { passive: true }) + window.addEventListener('popstate', handlePopState) }) onUnmounted(() => { document.removeEventListener('touchstart', handleTouchStart) + document.removeEventListener('touchmove', handleTouchMove) document.removeEventListener('touchend', handleTouchEnd) + window.removeEventListener('popstate', handlePopState) }) -function logOut(){ - token.value = null - auth.user = null - router.push({path:'/login'}) +function logOut() { + token.value = null + auth.user = null + router.push({ path: '/login' }) } - \ No newline at end of file + diff --git a/components/RentStep.vue b/components/RentStep.vue index 6af0620..9c3b73e 100644 --- a/components/RentStep.vue +++ b/components/RentStep.vue @@ -1,5 +1,5 @@