UNPKG

@trycourier/courier-react-native

Version:

Inbox, Push Notifications, and Preferences for React Native

76 lines (75 loc) 3.23 kB
import React, { useState, useEffect, useMemo, createContext, useContext } from 'react'; import { View, StyleSheet, Animated, Easing } from 'react-native'; const PokeContext = createContext(undefined); export const usePoke = () => { const context = useContext(PokeContext); if (!context) { throw new Error('usePoke must be used within a PokeProvider'); } return context; }; export const Poke = ({ children, initialEnabled = true, initialIndicatorStyle, initialTouchTimeout = 150, }) => { const [enabled, setEnabled] = useState(initialEnabled); const [indicatorStyle, setIndicatorStyle] = useState(initialIndicatorStyle || {}); const [touchTimeout, setTouchTimeout] = useState(initialTouchTimeout); const contextValue = useMemo(() => ({ setEnabled, setIndicatorStyle, setTouchTimeout, }), []); return (React.createElement(PokeContext.Provider, { value: contextValue }, React.createElement(TouchIndicator, { enabled: enabled, indicatorStyle: indicatorStyle, touchTimeout: touchTimeout }, children))); }; const TouchIndicator = ({ children, indicatorStyle, enabled, touchTimeout }) => { const [latestTouch, setLatestTouch] = useState(null); const indicatorSize = indicatorStyle?.size || 50; const indicatorColor = indicatorStyle?.color || 'rgba(0, 122, 255, 0.4)'; // Default blue color useEffect(() => { if (latestTouch) { const timer = setTimeout(() => { setLatestTouch(null); }, touchTimeout); return () => clearTimeout(timer); } return () => { }; // Add this line }, [latestTouch, touchTimeout]); const handleTouch = (event) => { if (!enabled) return; const touch = event.nativeEvent.touches[0]; // Get only the latest touch if (touch) { const newTouch = { id: `${touch.identifier}-${Date.now()}`, x: touch.pageX, y: touch.pageY, timestamp: Date.now(), animation: new Animated.Value(1), }; Animated.timing(newTouch.animation, { toValue: 0, duration: touchTimeout, useNativeDriver: true, easing: Easing.out(Easing.cubic), }).start(); setLatestTouch(newTouch); } }; const touchIndicatorStyle = useMemo(() => ({ position: 'absolute', width: indicatorSize, height: indicatorSize, borderRadius: indicatorSize / 2, backgroundColor: indicatorColor, zIndex: 9999, }), [indicatorSize, indicatorColor]); return (React.createElement(View, { style: StyleSheet.absoluteFill, onTouchStart: handleTouch, onTouchMove: handleTouch, onTouchEnd: handleTouch }, children, enabled && latestTouch && (React.createElement(Animated.View, { key: latestTouch.id, style: [ touchIndicatorStyle, { left: latestTouch.x - indicatorSize / 2, top: latestTouch.y - indicatorSize / 2, opacity: latestTouch.animation, }, ] })))); };