| Philip Zeyliger | e08c7ff | 2025-06-06 13:22:12 -0700 | [diff] [blame] | 1 | // Shared interface detection and auto-switching logic |
| 2 | // Used by both desktop and mobile interfaces |
| 3 | |
| 4 | (function () { |
| 5 | function detectMobile() { |
| 6 | const isMobileScreen = window.innerWidth < 768; |
| 7 | const isTouchDevice = "ontouchstart" in window; |
| 8 | const isMobileUA = |
| 9 | /Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test( |
| 10 | navigator.userAgent, |
| 11 | ); |
| 12 | |
| 13 | return isMobileScreen || (isTouchDevice && isMobileUA); |
| 14 | } |
| 15 | |
| 16 | function detectDesktop() { |
| 17 | const isDesktopScreen = window.innerWidth >= 768; |
| 18 | const isNotTouchDevice = !("ontouchstart" in window); |
| 19 | const isDesktopUA = |
| 20 | !/Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test( |
| 21 | navigator.userAgent, |
| 22 | ); |
| 23 | |
| 24 | return isDesktopScreen && (isNotTouchDevice || isDesktopUA); |
| 25 | } |
| 26 | |
| 27 | function autoRedirectToMobile() { |
| 28 | const urlParams = new URLSearchParams(window.location.search); |
| 29 | const hasDesktopParam = urlParams.has("d"); |
| 30 | |
| 31 | // Respect manual overrides - if ?d is present, stay on desktop |
| 32 | if (hasDesktopParam) return; |
| 33 | |
| 34 | // If mobile is detected and no explicit desktop request |
| 35 | if (detectMobile() && !hasDesktopParam) { |
| 36 | // Add ?m parameter to current URL |
| 37 | const url = new URL(window.location); |
| 38 | url.searchParams.set("m", ""); |
| 39 | // Remove any conflicting parameters |
| 40 | url.searchParams.delete("d"); |
| 41 | window.location.href = url.toString(); |
| 42 | } |
| 43 | } |
| 44 | |
| 45 | function autoRedirectToDesktop() { |
| 46 | const urlParams = new URLSearchParams(window.location.search); |
| 47 | const hasMobileParam = urlParams.has("m"); |
| 48 | |
| 49 | // Respect manual overrides - if ?m is present, stay on mobile |
| 50 | if (hasMobileParam) return; |
| 51 | |
| 52 | // If we detect desktop conditions |
| 53 | if (detectDesktop() && !hasMobileParam) { |
| 54 | // Add ?d parameter to current URL |
| 55 | const url = new URL(window.location); |
| 56 | url.searchParams.set("d", ""); |
| 57 | // Remove any conflicting parameters |
| 58 | url.searchParams.delete("m"); |
| 59 | window.location.href = url.toString(); |
| 60 | } |
| 61 | } |
| 62 | |
| 63 | function runAutoDetection() { |
| 64 | // Determine which detection to run based on current interface |
| 65 | // This is determined by checking if we're serving mobile or desktop HTML |
| 66 | const isMobileInterface = document.querySelector("mobile-shell") !== null; |
| 67 | |
| 68 | if (isMobileInterface) { |
| 69 | autoRedirectToDesktop(); |
| 70 | } else { |
| 71 | autoRedirectToMobile(); |
| 72 | } |
| 73 | } |
| 74 | |
| 75 | // iOS Safari viewport height fix |
| 76 | function fixIOSViewportHeight() { |
| 77 | // Only apply on iOS Safari |
| 78 | const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent); |
| 79 | const isSafari = |
| 80 | /Safari/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent); |
| 81 | |
| 82 | if (isIOS && isSafari) { |
| 83 | // Set CSS custom property with actual viewport height |
| 84 | const vh = window.innerHeight * 0.01; |
| 85 | document.documentElement.style.setProperty("--vh", `${vh}px`); |
| 86 | |
| 87 | // Update on orientation change |
| 88 | window.addEventListener("orientationchange", () => { |
| 89 | setTimeout(() => { |
| 90 | const vh = window.innerHeight * 0.01; |
| 91 | document.documentElement.style.setProperty("--vh", `${vh}px`); |
| 92 | }, 100); |
| 93 | }); |
| 94 | |
| 95 | // Update on resize |
| 96 | window.addEventListener("resize", () => { |
| 97 | const vh = window.innerHeight * 0.01; |
| 98 | document.documentElement.style.setProperty("--vh", `${vh}px`); |
| 99 | }); |
| 100 | } |
| 101 | } |
| 102 | |
| 103 | // Run detection when DOM is ready |
| 104 | if (document.readyState === "loading") { |
| 105 | document.addEventListener("DOMContentLoaded", () => { |
| 106 | runAutoDetection(); |
| 107 | fixIOSViewportHeight(); |
| 108 | }); |
| 109 | } else { |
| 110 | runAutoDetection(); |
| 111 | fixIOSViewportHeight(); |
| 112 | } |
| 113 | })(); |