Live video on the AT Protocol
at eli/multistream-fixes 89 lines 2.4 kB view raw
1import { useEffect, useState } from "react"; 2import { Platform } from "react-native"; 3 4export interface PointerDevice { 5 hasHover: boolean; 6 hasFinePointer: boolean; 7 isMouseDriven: boolean; 8 isTouchDriven: boolean; 9} 10 11/** 12 * Hook to detect if the device is primarily mouse-driven vs touch-driven 13 * Uses CSS media queries to detect hover and pointer capabilities 14 */ 15export function usePointerDevice(): PointerDevice { 16 const [pointerDevice, setPointerDevice] = useState<PointerDevice>(() => { 17 // Default values for non-web platforms 18 if (Platform.OS !== "web") { 19 return { 20 hasHover: false, 21 hasFinePointer: false, 22 isMouseDriven: false, 23 isTouchDriven: true, 24 }; 25 } 26 27 // Initial web detection 28 if (typeof window !== "undefined" && window.matchMedia) { 29 const hasHover = window.matchMedia("(hover: hover)").matches; 30 const hasFinePointer = window.matchMedia("(pointer: fine)").matches; 31 32 return { 33 hasHover, 34 hasFinePointer, 35 isMouseDriven: hasHover && hasFinePointer, 36 isTouchDriven: !hasHover || !hasFinePointer, 37 }; 38 } 39 40 // Fallback for SSR or environments without matchMedia 41 return { 42 hasHover: false, 43 hasFinePointer: false, 44 isMouseDriven: false, 45 isTouchDriven: true, 46 }; 47 }); 48 49 useEffect(() => { 50 // Only run on web platforms 51 if ( 52 Platform.OS !== "web" || 53 typeof window === "undefined" || 54 !window.matchMedia 55 ) { 56 return; 57 } 58 59 const hoverQuery = window.matchMedia("(hover: hover)"); 60 const pointerQuery = window.matchMedia("(pointer: fine)"); 61 62 const updatePointerDevice = () => { 63 const hasHover = hoverQuery.matches; 64 const hasFinePointer = pointerQuery.matches; 65 66 setPointerDevice({ 67 hasHover, 68 hasFinePointer, 69 isMouseDriven: hasHover && hasFinePointer, 70 isTouchDriven: !hasHover || !hasFinePointer, 71 }); 72 }; 73 74 // Set up listeners for media query changes 75 hoverQuery.addEventListener("change", updatePointerDevice); 76 pointerQuery.addEventListener("change", updatePointerDevice); 77 78 // Initial update 79 updatePointerDevice(); 80 81 // Cleanup 82 return () => { 83 hoverQuery.removeEventListener("change", updatePointerDevice); 84 pointerQuery.removeEventListener("change", updatePointerDevice); 85 }; 86 }, []); 87 88 return pointerDevice; 89}