/** * TASKMATE - Mobile Swipe Enhancement * ==================================== * Neue Swipe-Funktionalität für bessere mobile Navigation */ export function enhanceMobileSwipe(mobileManager) { const SWIPE_THRESHOLD = 50; const SWIPE_VELOCITY = 0.3; // State für Column-Navigation let currentColumnIndex = 0; let columnCount = 0; let isColumnSwipeEnabled = false; // Column indicator elements let columnIndicator = null; /** * Initialize column swipe for board view */ function initColumnSwipe() { const boardContainer = document.querySelector('.board-container'); if (!boardContainer || mobileManager.currentView !== 'board') return; // Create column indicator if (!columnIndicator) { columnIndicator = document.createElement('div'); columnIndicator.className = 'mobile-column-indicator'; columnIndicator.innerHTML = `
`; document.querySelector('.view-board')?.appendChild(columnIndicator); } updateColumnInfo(); showCurrentColumn(); } /** * Update column information */ function updateColumnInfo() { const columns = document.querySelectorAll('.column'); columnCount = columns.length; // Update dots const dotsContainer = columnIndicator?.querySelector('.column-dots'); if (dotsContainer) { dotsContainer.innerHTML = Array.from({ length: columnCount }, (_, i) => `` ).join(''); } // Update column name const nameContainer = columnIndicator?.querySelector('.column-name'); if (nameContainer && columns[currentColumnIndex]) { const columnTitle = columns[currentColumnIndex].querySelector('.column-title')?.textContent || ''; nameContainer.textContent = columnTitle; } } /** * Show specific column (hide others) */ function showCurrentColumn() { const columns = document.querySelectorAll('.column'); const boardContainer = document.querySelector('.board-container'); columns.forEach((col, index) => { if (index === currentColumnIndex) { col.style.display = 'flex'; col.classList.add('mobile-active'); } else { col.style.display = 'none'; col.classList.remove('mobile-active'); } }); // Update add column button const addColumnBtn = document.querySelector('.btn-add-column'); if (addColumnBtn) { addColumnBtn.style.display = currentColumnIndex === columnCount - 1 ? 'flex' : 'none'; } updateColumnInfo(); } /** * Navigate to specific column */ function navigateToColumn(index) { if (index < 0 || index >= columnCount) return; currentColumnIndex = index; showCurrentColumn(); // Haptic feedback if (navigator.vibrate) { navigator.vibrate(10); } } /** * Enhanced board swipe handler */ mobileManager.handleBoardSwipeEnd = function() { if (!this.isSwiping || this.swipeDirection !== 'horizontal' || this.swipeTarget !== 'board') { this.resetSwipe(); return; } const deltaX = this.touchCurrentX - this.touchStartX; const deltaTime = Date.now() - this.touchStartTime; const velocity = Math.abs(deltaX) / deltaTime; const isValidSwipe = Math.abs(deltaX) > SWIPE_THRESHOLD || velocity > SWIPE_VELOCITY; if (isValidSwipe && isColumnSwipeEnabled) { if (deltaX > 0 && currentColumnIndex > 0) { // Swipe right - previous column navigateToColumn(currentColumnIndex - 1); } else if (deltaX < 0 && currentColumnIndex < columnCount - 1) { // Swipe left - next column navigateToColumn(currentColumnIndex + 1); } } this.resetSwipe(); }; /** * View hint for header swipes */ let viewHint = null; function showViewSwipeHint(viewName, direction) { if (!viewHint) { viewHint = document.createElement('div'); viewHint.className = 'mobile-view-hint'; document.body.appendChild(viewHint); } viewHint.textContent = getViewDisplayName(viewName); viewHint.classList.add('visible', direction); } function hideViewSwipeHint() { if (viewHint) { viewHint.classList.remove('visible', 'left', 'right'); } } function getViewDisplayName(view) { const names = { 'board': 'Board', 'list': 'Liste', 'calendar': 'Kalender', 'proposals': 'Genehmigungen', 'gitea': 'Gitea', 'knowledge': 'Wissen' }; return names[view] || view; } /** * Enhanced header swipe handler */ mobileManager.handleHeaderSwipeMove = function(e) { if (!this.isMobile || this.touchStartX === 0 || this.swipeTarget !== 'header') return; const touch = e.touches[0]; this.touchCurrentX = touch.clientX; this.touchCurrentY = touch.clientY; const deltaX = this.touchCurrentX - this.touchStartX; const deltaY = this.touchCurrentY - this.touchStartY; // Determine direction if (!this.swipeDirection && (Math.abs(deltaX) > 10 || Math.abs(deltaY) > 10)) { if (Math.abs(deltaX) > Math.abs(deltaY) * 1.5) { this.swipeDirection = 'horizontal'; this.isSwiping = true; } else { this.swipeDirection = 'vertical'; this.resetSwipe(); return; } } if (this.swipeDirection !== 'horizontal') return; e.preventDefault(); // Show view hints const currentIndex = this.viewOrder.indexOf(this.currentView); if (deltaX > SWIPE_THRESHOLD && currentIndex > 0) { showViewSwipeHint(this.viewOrder[currentIndex - 1], 'left'); } else if (deltaX < -SWIPE_THRESHOLD && currentIndex < this.viewOrder.length - 1) { showViewSwipeHint(this.viewOrder[currentIndex + 1], 'right'); } else { hideViewSwipeHint(); } }; mobileManager.handleHeaderSwipeEnd = function() { if (!this.isSwiping || this.swipeDirection !== 'horizontal' || this.swipeTarget !== 'header') { this.resetSwipe(); hideViewSwipeHint(); return; } const deltaX = this.touchCurrentX - this.touchStartX; const deltaTime = Date.now() - this.touchStartTime; const velocity = Math.abs(deltaX) / deltaTime; const isValidSwipe = Math.abs(deltaX) > SWIPE_THRESHOLD || velocity > SWIPE_VELOCITY; if (isValidSwipe) { const currentIndex = this.viewOrder.indexOf(this.currentView); if (deltaX > 0 && currentIndex > 0) { // Swipe right - previous view this.switchView(this.viewOrder[currentIndex - 1]); } else if (deltaX < 0 && currentIndex < this.viewOrder.length - 1) { // Swipe left - next view this.switchView(this.viewOrder[currentIndex + 1]); } } hideViewSwipeHint(); this.resetSwipe(); }; // Listen for view changes document.addEventListener('view:changed', (e) => { if (e.detail?.view === 'board' && mobileManager.isMobile) { isColumnSwipeEnabled = true; setTimeout(initColumnSwipe, 100); } else { isColumnSwipeEnabled = false; if (columnIndicator) { columnIndicator.style.display = 'none'; } } }); // Listen for column updates document.addEventListener('columns:updated', () => { if (isColumnSwipeEnabled) { updateColumnInfo(); showCurrentColumn(); } }); // Update on resize window.addEventListener('resize', () => { if (mobileManager.isMobile && mobileManager.currentView === 'board') { if (!isColumnSwipeEnabled) { isColumnSwipeEnabled = true; initColumnSwipe(); } } else { isColumnSwipeEnabled = false; // Show all columns on desktop document.querySelectorAll('.column').forEach(col => { col.style.display = ''; col.classList.remove('mobile-active'); }); if (columnIndicator) { columnIndicator.style.display = 'none'; } } }); }