UNPKG

@nghinv/react-native-app-tour

Version:
132 lines (119 loc) 3.59 kB
/** * Created by nghinv on Wed Jun 23 2021 * Copyright (c) 2021 nghinv@lumi.biz */ import React, { forwardRef, useImperativeHandle, useState, useContext, useCallback, useRef, useEffect } from 'react'; import equals from 'react-fast-compare'; import { Keyboard, Modal, BackHandler } from 'react-native'; import { useSharedValue, withTiming, runOnJS } from 'react-native-reanimated'; import { AppTourContext } from './AppTourContext'; import { useEvent } from './hook'; import MashView from './MashView'; import { timingConfig } from './math'; function AppTourView(_, ref) { const [visible, setVisible] = useState(false); const { nodes, scenes, sceneIndex, options } = useContext(AppTourContext); const { emitEvent } = useEvent(); const progress = useSharedValue(0); const currentStep = useSharedValue(0); const backHandler = useRef(); const handleBackButton = () => { if (options !== null && options !== void 0 && options.backAndroidToSkip) { onStop(); } return true; }; const open = useCallback(step => { var _scenes$sceneIndex; Keyboard.dismiss(); backHandler.current = BackHandler.addEventListener('hardwareBackPress', handleBackButton); if (((_scenes$sceneIndex = scenes[sceneIndex]) === null || _scenes$sceneIndex === void 0 ? void 0 : _scenes$sceneIndex.length) > 0) { setVisible(true); currentStep.value = step !== null && step !== void 0 ? step : 0; progress.value = withTiming(1, timingConfig); const scene = scenes[sceneIndex][currentStep.value]; emitEvent('AppTourEvent', { name: 'onStart', step: currentStep.value, node: nodes.value.find(n => n.id === scene.id), scene }); } }, [sceneIndex, scenes, backHandler]); const onStop = useCallback(callback => { if (backHandler.current) { backHandler.current.remove(); } progress.value = withTiming(0, timingConfig, () => { runOnJS(setVisible)(false); if (callback) { runOnJS(callback)(); } }); }, [backHandler]); useEffect(() => { return () => { if (backHandler.current) { backHandler.current.remove(); } }; }, [backHandler]); useImperativeHandle(ref, () => ({ nextStep: () => { const nextValue = currentStep.value + 1; const sceneLength = scenes[sceneIndex].length; if (nextValue <= sceneLength - 1) { currentStep.value = nextValue; } else { onStop(); } }, preStep: () => { const preValue = currentStep.value - 1; if (preValue >= 0) { currentStep.value = preValue; } else { onStop(); } }, stop: cb => { onStop(cb); }, start: step => { open(step); }, currentStep: () => { return currentStep.value; } })); if (!visible) return null; if (options !== null && options !== void 0 && options.nativeModal) { return /*#__PURE__*/React.createElement(Modal, { visible: visible, transparent: true, animationType: "none" }, /*#__PURE__*/React.createElement(MashView, { onStop: onStop, open: open, progress: progress, currentStep: currentStep, scene: scenes[sceneIndex] })); } return /*#__PURE__*/React.createElement(MashView, { onStop: onStop, open: open, progress: progress, currentStep: currentStep, scene: scenes[sceneIndex] }); } export default /*#__PURE__*/React.memo( /*#__PURE__*/forwardRef(AppTourView), equals); //# sourceMappingURL=AppTourView.js.map