/** * Swipe Navigation for Echo * Swipe left/right to navigate between pages */ (function() { const pages = ['index.html', 'notes.html', 'files.html']; // Get current page index function getCurrentIndex() { const path = window.location.pathname; let filename = path.split('/').pop() || 'index.html'; // Handle /echo/ without filename if (filename === '' || filename === 'echo') filename = 'index.html'; const idx = pages.indexOf(filename); return idx >= 0 ? idx : 0; } // Navigate to page function navigateTo(index) { if (index >= 0 && index < pages.length) { window.location.href = pages[index]; } } // Swipe detection let touchStartX = 0; let touchStartY = 0; let touchEndX = 0; let touchEndY = 0; const minSwipeDistance = 80; const maxVerticalDistance = 100; document.addEventListener('touchstart', function(e) { touchStartX = e.changedTouches[0].screenX; touchStartY = e.changedTouches[0].screenY; }, { passive: true }); document.addEventListener('touchend', function(e) { touchEndX = e.changedTouches[0].screenX; touchEndY = e.changedTouches[0].screenY; handleSwipe(); }, { passive: true }); function handleSwipe() { const deltaX = touchEndX - touchStartX; const deltaY = Math.abs(touchEndY - touchStartY); // Ignore if vertical swipe or too short if (deltaY > maxVerticalDistance) return; if (Math.abs(deltaX) < minSwipeDistance) return; const currentIndex = getCurrentIndex(); if (deltaX > 0) { // Swipe right → previous page navigateTo(currentIndex - 1); } else { // Swipe left → next page navigateTo(currentIndex + 1); } } // Visual indicator (optional dots) function createIndicator() { const indicator = document.createElement('div'); indicator.className = 'swipe-indicator'; indicator.innerHTML = pages.map((_, i) => `` ).join(''); document.body.appendChild(indicator); } // Add indicator styles const style = document.createElement('style'); style.textContent = ` .swipe-indicator { position: fixed; bottom: 24px; left: 50%; transform: translateX(-50%); display: flex; gap: 10px; z-index: 9999; padding: 10px 16px; background: rgba(50, 50, 60, 0.9); border: 1px solid rgba(255, 255, 255, 0.2); border-radius: 24px; backdrop-filter: blur(8px); } .swipe-dot { width: 10px; height: 10px; border-radius: 50%; background: rgba(255, 255, 255, 0.3); border: 1px solid rgba(255, 255, 255, 0.5); transition: all 0.2s; } .swipe-dot.active { background: #3b82f6; border-color: #3b82f6; transform: scale(1.3); box-shadow: 0 0 8px rgba(59, 130, 246, 0.6); } @media (min-width: 769px) { .swipe-indicator { display: none; } } `; document.head.appendChild(style); // Init after DOM ready function init() { if ('ontouchstart' in window || navigator.maxTouchPoints > 0) { createIndicator(); } } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();