File size: 1,046 Bytes
b87bd2d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
"use client";

import { useEffect, useState } from "react";

/**
 * True on coarse-pointer (touch) devices β€” phones and tablets.
 *
 * #3 mobile: SPACE-centric voice copy ("hold SPACE to talk") reads as
 * "voice is broken" on a phone, which has no spacebar (tap-to-talk DOES
 * work via the mic button's onClick + VAD auto-stop). Components use this
 * to swap to touch-correct copy / hide desktop-only affordances.
 *
 * SSR-safe: returns false during the static-export render and the first
 * client paint, then resolves after mount. `(pointer: coarse)` also
 * covers tablets, unlike a width breakpoint.
 */
export function useIsTouch(): boolean {
  const [isTouch, setIsTouch] = useState(false);
  useEffect(() => {
    if (typeof window === "undefined" || !window.matchMedia) return;
    const mq = window.matchMedia("(pointer: coarse)");
    const update = () => setIsTouch(mq.matches);
    update();
    mq.addEventListener?.("change", update);
    return () => mq.removeEventListener?.("change", update);
  }, []);
  return isTouch;
}