@trycourier/courier-react-native
Version:
Inbox, Push Notifications, and Preferences for React Native
76 lines (75 loc) • 3.23 kB
JavaScript
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,
},
] }))));
};