WIP PWA for Grain next.grain.social
at main 49 lines 1.2 kB view raw
1/** 2 * Haptic feedback utility for PWA 3 * - iOS 18+: Uses checkbox switch element hack 4 * - Android: Uses Vibration API 5 * - Other: Silently does nothing 6 */ 7 8// Platform detection 9const isIOS = /iPhone|iPad/.test(navigator.userAgent); 10const hasVibrate = 'vibrate' in navigator; 11 12// Lazy-initialized hidden elements for iOS 13let checkbox = null; 14let label = null; 15 16function ensureElements() { 17 if (checkbox) return; 18 19 checkbox = document.createElement('input'); 20 checkbox.type = 'checkbox'; 21 checkbox.setAttribute('switch', ''); 22 checkbox.id = 'haptic-trigger'; 23 checkbox.style.cssText = 'position:fixed;left:-9999px;opacity:0;pointer-events:none;'; 24 25 label = document.createElement('label'); 26 label.htmlFor = 'haptic-trigger'; 27 label.style.cssText = 'position:fixed;left:-9999px;opacity:0;pointer-events:none;'; 28 29 document.body.append(checkbox, label); 30} 31 32/** 33 * Trigger a light haptic tap 34 */ 35export function trigger() { 36 if (isIOS) { 37 ensureElements(); 38 label.click(); 39 } else if (hasVibrate) { 40 navigator.vibrate(10); 41 } 42} 43 44/** 45 * Check if haptics are supported on this device 46 */ 47export function isSupported() { 48 return isIOS || hasVibrate; 49}