WIP PWA for Grain
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: add haptics utility for iOS 18+ and Android

+49
+49
src/utils/haptics.js
··· 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 9 + const isIOS = /iPhone|iPad/.test(navigator.userAgent); 10 + const hasVibrate = 'vibrate' in navigator; 11 + 12 + // Lazy-initialized hidden elements for iOS 13 + let checkbox = null; 14 + let label = null; 15 + 16 + function 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 + */ 35 + export 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 + */ 47 + export function isSupported() { 48 + return isIOS || hasVibrate; 49 + }