UNPKG

@cometchat/chat-uikit-react-native

Version:

Ready-to-use Chat UI Components for React Native

163 lines 5.91 kB
import React from "react"; import ReactNativeZoomableView from "./ReactNativeZoomableView"; export const swipeDirections = { SWIPE_UP: "SWIPE_UP", SWIPE_DOWN: "SWIPE_DOWN", SWIPE_LEFT: "SWIPE_LEFT", SWIPE_RIGHT: "SWIPE_RIGHT", }; class ReactNativeZoomableViewWithGestures extends React.Component { zoomableViewRef; constructor(props) { super(props); this.zoomableViewRef = React.createRef(); } _onShiftingEnd = (e, gestureState, zoomableViewState) => { if (this.props.onShiftingEnd) { this.props.onShiftingEnd(e, gestureState, zoomableViewState); } if (!this._couldCallSwipeEvent(zoomableViewState)) { return; } const swipeDirection = this._getSwipeDirection(gestureState); this._triggerSwipeHandlers(swipeDirection, gestureState); }; /** * Checks if current config options make it possible to process a swipe or if is not necessary * * @returns {*} * @private */ _couldCallSwipeEvent(zoomableViewState) { const { onSwipe, onSwipeUp, onSwipeDown, onSwipeLeft, onSwipeRight, swipeMaxZoom, swipeMinZoom, } = this.props; if (swipeMaxZoom && zoomableViewState.zoomLevel > swipeMaxZoom) { return false; } if (swipeMinZoom && zoomableViewState.zoomLevel < swipeMinZoom) { return false; } return onSwipe || onSwipeUp || onSwipeDown || onSwipeLeft || onSwipeRight; } /** * Checks the swipe and validates whether we should process it or not * * @param gestureState * @returns {*|boolean} * * @private */ _validateSwipe(gestureState) { const { onSwipeUp, onSwipeDown, onSwipeLeft, onSwipeRight } = this.props; const swipeDirection = this._getSwipeDirection(gestureState); const { SWIPE_LEFT, SWIPE_RIGHT, SWIPE_UP, SWIPE_DOWN } = swipeDirections; return ((onSwipeUp && swipeDirection === SWIPE_UP) || (onSwipeDown && swipeDirection === SWIPE_DOWN) || (onSwipeLeft && swipeDirection === SWIPE_LEFT) || (onSwipeRight && swipeDirection === SWIPE_RIGHT)); } /** * Triggers the correct directional callback * * @param swipeDirection * @param gestureState * @private */ _triggerSwipeHandlers(swipeDirection, gestureState) { const { onSwipe, onSwipeUp, onSwipeDown, onSwipeLeft, onSwipeRight } = this.props; const { SWIPE_LEFT, SWIPE_RIGHT, SWIPE_UP, SWIPE_DOWN } = swipeDirections; // trigger the general onswipe callback if (onSwipe) { onSwipe(swipeDirection, gestureState); } // trigger the direction specific swipe callback switch (swipeDirection) { case SWIPE_LEFT: onSwipeLeft && onSwipeLeft(gestureState); break; case SWIPE_RIGHT: onSwipeRight && onSwipeRight(gestureState); break; case SWIPE_UP: onSwipeUp && onSwipeUp(gestureState); break; case SWIPE_DOWN: onSwipeDown && onSwipeDown(gestureState); break; } } /** * Calculates what direction the user swiped * * @param gestureState * @returns {*} * @private */ _getSwipeDirection(gestureState) { const { swipeLengthThreshold } = this.props; const { SWIPE_LEFT, SWIPE_RIGHT, SWIPE_UP, SWIPE_DOWN } = swipeDirections; const { dx, dy } = gestureState; if (!swipeLengthThreshold) { return null; } if (this._isValidHorizontalSwipe(gestureState)) { if (Math.abs(dx) > swipeLengthThreshold) { return dx > 0 ? SWIPE_RIGHT : SWIPE_LEFT; } } else if (this._isValidVerticalSwipe(gestureState)) { if (Math.abs(dy) > swipeLengthThreshold) { return dy > 0 ? SWIPE_DOWN : SWIPE_UP; } } return null; } /** * Checks, whether the swipe was done in a horizontal fashion, respecting swipeVelocityThreshold limits * * @param gestureState * @returns {*} * * @private */ _isValidHorizontalSwipe(gestureState) { const { vx, dy } = gestureState; const { swipeVelocityThreshold, swipeDirectionalThreshold } = this.props; return this._isValidSwipe(vx, swipeVelocityThreshold, dy, swipeDirectionalThreshold); } /** * Checks, whether the swipe was done in a vertical fashion, respecting swipeVelocityThreshold limits * * @param gestureState * @returns {*} * * @private */ _isValidVerticalSwipe(gestureState) { const { vy, dx } = gestureState; const { swipeVelocityThreshold, swipeDirectionalThreshold } = this.props; return this._isValidSwipe(vy, swipeVelocityThreshold, dx, swipeDirectionalThreshold); } /** * Checks the sipw against velocity and directional offset to make sure it only gets activated, when we actually need it * * @param velocity * @param swipeVelocityThreshold * @param directionalOffset * @param swipeDirectionalThreshold * * @returns {boolean} * * @private */ _isValidSwipe(velocity, swipeVelocityThreshold, directionalOffset, swipeDirectionalThreshold) { return (Math.abs(velocity) > swipeVelocityThreshold && Math.abs(directionalOffset) < swipeDirectionalThreshold); } render() { return (<ReactNativeZoomableView {...this.props} ref={(ref) => { this.zoomableViewRef.current = ref; }} onShiftingEnd={this._onShiftingEnd}/>); } } export default ReactNativeZoomableViewWithGestures; //# sourceMappingURL=ReactNativeZoomableViewWithGestures.js.map