UNPKG

@revrag-ai/embed-react-native

Version:

A powerful React Native library for integrating AI-powered voice agents into mobile applications. Features real-time voice communication, intelligent speech processing, customizable UI components, and comprehensive event handling for building conversation

181 lines (171 loc) 5.51 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.usePopupAnimatedStyles = exports.useButtonAnimations = exports.useButtonAnimatedStyles = exports.useBreathingAnimation = exports.useAnimationValues = exports.createPanGesture = exports.Animated = void 0; var _react = require("react"); var _reactNativeGestureHandler = require("react-native-gesture-handler"); var _reanimatedHelper = require("../utils/reanimated.helper.js"); var _EmbedButtonHelpers = require("./EmbedButton.helpers.js"); /** * @file EmbedButton.animations.ts * @description Animation logic and hooks for the EmbedButton component */ // Get reanimated API with fallbacks const { useSharedValue, useAnimatedStyle, withTiming, withSpring, withRepeat, withSequence, runOnJS, Easing, Animated, isAvailable: isReanimatedAvailable } = (0, _reanimatedHelper.getReanimatedAPI)(); // Show warning if reanimated is not available exports.Animated = Animated; if (!isReanimatedAvailable) { (0, _reanimatedHelper.showReanimatedSetupError)(); } // Export the Animated component for use in the main component // ==================== ANIMATION VALUES HOOK ==================== /** * Hook to initialize and manage all animation shared values */ const useAnimationValues = () => { const isPressed = useSharedValue(false); const offset = useSharedValue({ x: 0, y: 0 }); const start = useSharedValue({ x: 0, y: 0 }); const menuAnimation = useSharedValue(0); const buttonWidth = useSharedValue(_EmbedButtonHelpers.BUTTON_DIMENSIONS.WIDTH); const buttonScale = useSharedValue(1); return { isPressed, offset, start, menuAnimation, buttonWidth, buttonScale }; }; // ==================== BUTTON ANIMATIONS ==================== /** * Hook to handle button expand/collapse animations */ exports.useAnimationValues = useAnimationValues; const useButtonAnimations = (isOpen, menuAnimation, buttonWidth) => { (0, _react.useEffect)(() => { menuAnimation.value = withTiming(isOpen ? 0.8 : 0, { duration: 300 }); buttonWidth.value = withTiming(isOpen ? _EmbedButtonHelpers.BUTTON_DIMENSIONS.EXPANDED_WIDTH : _EmbedButtonHelpers.BUTTON_DIMENSIONS.WIDTH); }, [isOpen, menuAnimation, buttonWidth]); }; // ==================== BREATHING ANIMATION ==================== /** * Hook to handle breathing animation when auto-popup is shown */ exports.useButtonAnimations = useButtonAnimations; const useBreathingAnimation = (isOpen, isAutoOpen, buttonScale) => { (0, _react.useEffect)(() => { if (!isOpen && isAutoOpen) { // Start breathing animation buttonScale.value = withRepeat(withSequence(withTiming(1.1, { duration: 1500, easing: Easing.inOut(Easing.ease) }), withTiming(1, { duration: 1500, easing: Easing.inOut(Easing.ease) })), -1, // Infinite repeat false); } else { // Reset animation buttonScale.value = withTiming(1, { duration: 300 }); } }, [buttonScale, isAutoOpen, isOpen]); }; // ==================== ANIMATED STYLES ==================== /** * Hook to create animated styles for the button */ exports.useBreathingAnimation = useBreathingAnimation; const useButtonAnimatedStyles = (isOpen, offset, buttonWidth, isPressed, buttonScale) => { return useAnimatedStyle(() => { const maxX = (0, _EmbedButtonHelpers.calculateMaxX)(isOpen); const clampedX = (0, _EmbedButtonHelpers.clamp)(offset.value.x, -maxX, 0); return { width: buttonWidth.value, height: _EmbedButtonHelpers.BUTTON_DIMENSIONS.HEIGHT, transform: [{ translateX: clampedX }, { translateY: offset.value.y }, { scale: withSpring(isPressed.value ? 0.95 : buttonScale.value) }], justifyContent: isOpen ? 'space-between' : 'flex-start', overflow: 'hidden' }; }); }; /** * Hook to create animated styles for the popup text */ exports.useButtonAnimatedStyles = useButtonAnimatedStyles; const usePopupAnimatedStyles = (offset, isPressed) => { return useAnimatedStyle(() => { const maxX = _EmbedButtonHelpers.SCREEN_WIDTH; const clampedX = (0, _EmbedButtonHelpers.clamp)(offset.value.x, -maxX, 0); return { transform: [{ translateX: clampedX }, { translateY: offset.value.y }, { scale: withSpring(isPressed.value ? 1 : 1) }] }; }); }; // ==================== GESTURE HANDLER ==================== /** * Create pan gesture for drag functionality */ exports.usePopupAnimatedStyles = usePopupAnimatedStyles; const createPanGesture = (isPressed, offset, start, isOpen, setIsAutoOpen) => { return _reactNativeGestureHandler.Gesture.Pan().onBegin(() => { isPressed.value = true; if (setIsAutoOpen) { runOnJS(setIsAutoOpen)(false); } }).onUpdate(e => { const maxX = (0, _EmbedButtonHelpers.calculateMaxX)(isOpen); const maxY = (0, _EmbedButtonHelpers.calculateMaxY)(); const newX = (0, _EmbedButtonHelpers.clamp)(e.translationX + start.value.x, -maxX, 0); const newY = (0, _EmbedButtonHelpers.clamp)(e.translationY + start.value.y, -maxY, 0); offset.value = { x: newX, y: newY }; }).onEnd(() => { start.value = { x: offset.value.x, y: offset.value.y }; }).onFinalize(() => { isPressed.value = false; }); }; exports.createPanGesture = createPanGesture; //# sourceMappingURL=EmbedButton.animations.js.map