27 lines
981 B
TypeScript
27 lines
981 B
TypeScript
/**
|
|||
|
|
* [Gitea #125] Tiny vibration ticks for touch feedback. Android Chrome/PWA
|
||
|
|
* only — iOS has no web vibration API — and nothing at all when the user
|
||
|
|
* prefers reduced motion. Every call is a cheap no-op elsewhere.
|
||
|
|
*/
|
||
|
|
export type HapticKind = 'ptt-on' | 'ptt-off' | 'reaction';
|
||
|
|
|
||
|
|
const PATTERN: Record<HapticKind, number> = { 'ptt-on': 10, 'ptt-off': 10, reaction: 8 };
|
||
|
|
|
||
|
|
export const hapticsSupported = (): boolean =>
|
||
|
|
typeof navigator !== 'undefined' && typeof navigator.vibrate === 'function';
|
||
|
|
|
||
|
|
const reducedMotion = (): boolean =>
|
||
|
|
typeof window !== 'undefined' &&
|
||
|
|
typeof window.matchMedia === 'function' &&
|
||
|
|
window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
||
|
|
|
||
|
|
/** Fire a tick; returns whether one was requested. */
|
||
|
|
export function tick(kind: HapticKind, enabled = true): boolean {
|
||
|
|
if (!enabled || !hapticsSupported() || reducedMotion()) return false;
|
||
|
|
try {
|
||
|
|
return navigator.vibrate(PATTERN[kind]) === true;
|
||
|
|
} catch {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
}
|