/** * Responsive Modal Navigation * * Provides smart navigation that uses modals on desktop (>1024px) * and full page navigation on mobile (<=1024px) for better UX. * * Usage: * Instead of using hx-get directly on elements, use: * onclick="navigateResponsive(event, '/page/url', '/modal/url')" */ // Breakpoint for mobile vs desktop (matches CSS @media query) const MOBILE_BREAKPOINT = 1024; /** * Check if current viewport is mobile size */ function isMobile() { return window.innerWidth <= MOBILE_BREAKPOINT; } /** * Navigate responsively based on screen size * * @param {Event} event - Click event (will be prevented) * @param {string} pageUrl - Full page URL for mobile * @param {string} modalUrl - Modal content URL for desktop (HTMX) */ function navigateResponsive(event, pageUrl, modalUrl) { event.preventDefault(); event.stopPropagation(); if (isMobile()) { // Mobile: Navigate to full page window.location.href = pageUrl; } else { // Desktop: Load modal via HTMX const target = event.currentTarget; // Trigger HTMX request programmatically htmx.ajax('GET', modalUrl, { target: '#modal-container', swap: 'innerHTML' }); } } /** * Setup responsive navigation for NPC items * Call this after NPCs are loaded */ function setupNPCResponsiveNav(sessionId) { document.querySelectorAll('.npc-item').forEach(item => { const npcId = item.getAttribute('data-npc-id'); if (!npcId) return; const pageUrl = `/game/session/${sessionId}/npc/${npcId}`; const modalUrl = `/game/session/${sessionId}/npc/${npcId}/chat`; // Remove HTMX attributes and add responsive navigation item.removeAttribute('hx-get'); item.removeAttribute('hx-target'); item.removeAttribute('hx-swap'); item.style.cursor = 'pointer'; item.onclick = (e) => navigateResponsive(e, pageUrl, modalUrl); }); } /** * Handle window resize to adapt navigation behavior * Debounced to avoid excessive calls */ let resizeTimeout; window.addEventListener('resize', () => { clearTimeout(resizeTimeout); resizeTimeout = setTimeout(() => { // Re-setup navigation if needed console.log('Viewport resized:', isMobile() ? 'Mobile' : 'Desktop'); }, 250); });