diff --git a/example/rn-cli.config.js b/example/rn-cli.config.js
index c049b59..faa16fe 100644
--- a/example/rn-cli.config.js
+++ b/example/rn-cli.config.js
@@ -4,8 +4,10 @@ const path = require('path');
const glob = require('glob-to-regexp');
const blacklist = require('metro/src/blacklist');
const pak = require('../package.json');
+const pak2 = require('./package.json');
const dependencies = Object.keys(pak.dependencies);
+const localDependencies = Object.keys(pak2.dependencies);
const peerDependencies = Object.keys(pak.peerDependencies);
module.exports = {
@@ -13,7 +15,7 @@ module.exports = {
return [__dirname, path.resolve(__dirname, '..')];
},
getProvidesModuleNodeModules() {
- return [...dependencies, ...peerDependencies];
+ return [...dependencies, ...localDependencies, ...peerDependencies];
},
getBlacklistRE() {
return blacklist([glob(`${path.resolve(__dirname, '..')}/node_modules/*`)]);
diff --git a/package.json b/package.json
index a7ced87..4a2e7b5 100644
--- a/package.json
+++ b/package.json
@@ -10,7 +10,6 @@
"test": "jest",
"lint": "eslint .",
"format": "eslint . --fix",
- "precommit": "yarn lint && yarn test",
"build": "babel --no-babelrc --plugins=syntax-jsx,syntax-class-properties,syntax-object-rest-spread,transform-flow-strip-types src --copy-files --out-dir dist --ignore '**/__tests__/**'",
"prepare": "yarn build"
},
@@ -58,6 +57,8 @@
"react": "*",
"react-native": "*",
"react-native-screens": "^1.0.0 || ^1.0.0-alpha",
+ "react-native-gesture-handler": "^1.0.0",
+ "react-native-reanimated": "^1.0.0 || ^1.0.0-alpha",
"react-navigation": ">=2.0 || ^2.0.0-beta"
},
"jest": {
diff --git a/src/views/Header/Header.js b/src/views/Header/Header.js
index 189b711..e93dc79 100644
--- a/src/views/Header/Header.js
+++ b/src/views/Header/Header.js
@@ -523,7 +523,6 @@ class Header extends React.PureComponent {
});
const scenesProps = Object.values(scenesByIndex).map(scene => ({
position: this.props.position,
- progress: this.props.progress,
scene,
}));
appBar = scenesProps.map(this._renderHeader, this);
@@ -531,7 +530,6 @@ class Header extends React.PureComponent {
} else {
const headerProps = {
position: new Animated.Value(this.props.scene.index),
- progress: new Animated.Value(0),
scene: this.props.scene,
};
diff --git a/src/views/StackView/StackViewLayout.js b/src/views/StackView/StackViewLayout.js
index 6838d4a..77ea95f 100644
--- a/src/views/StackView/StackViewLayout.js
+++ b/src/views/StackView/StackViewLayout.js
@@ -19,6 +19,7 @@ import {
NavigationProvider,
} from 'react-navigation';
import { ScreenContainer } from 'react-native-screens';
+import { PanGestureHandler } from 'react-native-gesture-handler';
import Card from './StackViewCard';
import Header from '../Header/Header';
@@ -252,188 +253,6 @@ class StackViewLayout extends React.Component {
}
}
- _panResponder = PanResponder.create({
- onPanResponderTerminate: () => {
- const { navigation } = this.props.transitionProps;
- const { index } = navigation.state;
- this._isResponding = false;
- this._reset(index, 0);
- this.props.onGestureCanceled && this.props.onGestureCanceled();
- },
- onPanResponderGrant: () => {
- const {
- transitionProps: { navigation, position, scene },
- } = this.props;
- const { index } = navigation.state;
-
- if (index !== scene.index) {
- return false;
- }
-
- position.stopAnimation(value => {
- this._isResponding = true;
- this._gestureStartValue = value;
- });
- this.props.onGestureBegin && this.props.onGestureBegin();
- },
- onMoveShouldSetPanResponder: (event, gesture) => {
- const {
- transitionProps: { navigation, layout, scene },
- mode,
- } = this.props;
- const { index } = navigation.state;
- const isVertical = mode === 'modal';
- const { options } = scene.descriptor;
- const gestureDirection = options.gestureDirection;
-
- const gestureDirectionInverted =
- typeof gestureDirection === 'string'
- ? gestureDirection === 'inverted'
- : I18nManager.isRTL;
-
- if (index !== scene.index) {
- return false;
- }
-
- const immediateIndex =
- this._immediateIndex == null ? index : this._immediateIndex;
- const currentDragDistance = gesture[isVertical ? 'dy' : 'dx'];
- const currentDragPosition =
- event.nativeEvent[isVertical ? 'pageY' : 'pageX'];
- const axisLength = isVertical
- ? layout.height.__getValue()
- : layout.width.__getValue();
- const axisHasBeenMeasured = !!axisLength;
-
- // Measure the distance from the touch to the edge of the screen
- const screenEdgeDistance = gestureDirectionInverted
- ? axisLength - (currentDragPosition - currentDragDistance)
- : currentDragPosition - currentDragDistance;
- // Compare to the gesture distance relavant to card or modal
-
- const {
- gestureResponseDistance: userGestureResponseDistance = {},
- } = options;
- const gestureResponseDistance = isVertical
- ? userGestureResponseDistance.vertical ||
- GESTURE_RESPONSE_DISTANCE_VERTICAL
- : userGestureResponseDistance.horizontal ||
- GESTURE_RESPONSE_DISTANCE_HORIZONTAL;
- // GESTURE_RESPONSE_DISTANCE is about 25 or 30. Or 135 for modals
- if (screenEdgeDistance > gestureResponseDistance) {
- // Reject touches that started in the middle of the screen
- return false;
- }
-
- const hasDraggedEnough =
- Math.abs(currentDragDistance) > RESPOND_THRESHOLD;
-
- const isOnFirstCard = immediateIndex === 0;
- const shouldSetResponder =
- hasDraggedEnough && axisHasBeenMeasured && !isOnFirstCard;
- return shouldSetResponder;
- },
- onPanResponderMove: (event, gesture) => {
- const {
- transitionProps: { navigation, position, layout, scene },
- mode,
- } = this.props;
- const { index } = navigation.state;
- const isVertical = mode === 'modal';
- const { options } = scene.descriptor;
- const gestureDirection = options.gestureDirection;
-
- const gestureDirectionInverted =
- typeof gestureDirection === 'string'
- ? gestureDirection === 'inverted'
- : I18nManager.isRTL;
-
- // Handle the moving touches for our granted responder
- const startValue = this._gestureStartValue;
- const axis = isVertical ? 'dy' : 'dx';
- const axisDistance = isVertical
- ? layout.height.__getValue()
- : layout.width.__getValue();
- const currentValue =
- axis === 'dx' && gestureDirectionInverted
- ? startValue + gesture[axis] / axisDistance
- : startValue - gesture[axis] / axisDistance;
- const value = clamp(index - 1, currentValue, index);
- position.setValue(value);
- },
- onPanResponderTerminationRequest: () =>
- // Returning false will prevent other views from becoming responder while
- // the navigation view is the responder (mid-gesture)
- false,
- onPanResponderRelease: (event, gesture) => {
- const {
- transitionProps: { navigation, position, layout, scene },
- mode,
- } = this.props;
- const { index } = navigation.state;
- const isVertical = mode === 'modal';
- const { options } = scene.descriptor;
- const gestureDirection = options.gestureDirection;
-
- const gestureDirectionInverted =
- typeof gestureDirection === 'string'
- ? gestureDirection === 'inverted'
- : I18nManager.isRTL;
-
- if (!this._isResponding) {
- return;
- }
- this._isResponding = false;
-
- const immediateIndex =
- this._immediateIndex == null ? index : this._immediateIndex;
-
- // Calculate animate duration according to gesture speed and moved distance
- const axisDistance = isVertical
- ? layout.height.__getValue()
- : layout.width.__getValue();
- const movementDirection = gestureDirectionInverted ? -1 : 1;
- const movedDistance =
- movementDirection * gesture[isVertical ? 'dy' : 'dx'];
- const gestureVelocity =
- movementDirection * gesture[isVertical ? 'vy' : 'vx'];
- const defaultVelocity = axisDistance / ANIMATION_DURATION;
- const velocity = Math.max(Math.abs(gestureVelocity), defaultVelocity);
- const resetDuration = gestureDirectionInverted
- ? (axisDistance - movedDistance) / velocity
- : movedDistance / velocity;
- const goBackDuration = gestureDirectionInverted
- ? movedDistance / velocity
- : (axisDistance - movedDistance) / velocity;
-
- // To asyncronously get the current animated value, we need to run stopAnimation:
- position.stopAnimation(value => {
- // If the speed of the gesture release is significant, use that as the indication
- // of intent
- if (gestureVelocity < -0.5) {
- this.props.onGestureCanceled && this.props.onGestureCanceled();
- this._reset(immediateIndex, resetDuration);
- return;
- }
- if (gestureVelocity > 0.5) {
- this.props.onGestureFinish && this.props.onGestureFinish();
- this._goBack(immediateIndex, goBackDuration);
- return;
- }
-
- // Then filter based on the distance the screen was moved. Over a third of the way swiped,
- // and the back will happen.
- if (value <= index - POSITION_THRESHOLD) {
- this.props.onGestureFinish && this.props.onGestureFinish();
- this._goBack(immediateIndex, goBackDuration);
- } else {
- this.props.onGestureCanceled && this.props.onGestureCanceled();
- this._reset(immediateIndex, resetDuration);
- }
- });
- },
- });
-
_onFloatingHeaderLayout = e => {
this.setState({ floatingHeaderHeight: e.nativeEvent.layout.height });
};
@@ -464,24 +283,62 @@ class StackViewLayout extends React.Component {
? options.gesturesEnabled
: Platform.OS === 'ios';
- const responder = !gesturesEnabled ? null : this._panResponder;
-
- const handlers = gesturesEnabled ? responder.panHandlers : {};
const containerStyle = [
styles.container,
this._getTransitionConfig().containerStyle,
];
return (
-
-
- {scenes.map(s => this._renderCard(s))}
-
- {floatingHeader}
-
+
+
+
+ {scenes.map(s => this._renderCard(s))}
+
+ {floatingHeader}
+
+
);
}
+ _handlePanGestureEvent = ({ nativeEvent }) => {
+ // const startValue = this._gestureStartValue;
+ // const axis = isVertical ? 'dy' : 'dx';
+ // const axisDistance = isVertical
+ // ? layout.height.__getValue()
+ // : layout.width.__getValue();
+ // const currentValue =
+ // axis === 'dx' && gestureDirectionInverted
+ // ? startValue + gesture[axis] / axisDistance
+ // : startValue - gesture[axis] / axisDistance;
+ // const value = clamp(index - 1, currentValue, index);
+ // position.setValue(value);
+
+
+ // Without using Reanimated it's not possible to do all of the following
+ // stuff with native driver.
+ const {
+ transitionProps: { navigation, position, layout, scene },
+ mode,
+ } = this.props;
+ const { index } = navigation.state;
+ const distance = layout.width.__getValue();
+ const translation = nativeEvent.translationX;
+ const currentValue = 1 - translation / distance;
+ const value = clamp(index - 1, currentValue, index);
+ console.log({ distance, translation, currentValue })
+ position.setValue(value);
+ }
+
+ _handlePanGestureStateChange = ({ nativeEvent }) => {
+ const { oldState, state } = nativeEvent;
+ // console.log({ nativeEvent })
+ }
+
_getHeaderMode() {
if (this.props.headerMode) {
return this.props.headerMode;
diff --git a/src/views/Transitioner.js b/src/views/Transitioner.js
index 9437215..3bbfc0c 100644
--- a/src/views/Transitioner.js
+++ b/src/views/Transitioner.js
@@ -28,7 +28,6 @@ class Transitioner extends React.Component {
this.state = {
layout,
position: new Animated.Value(this.props.navigation.state.index),
- progress: new Animated.Value(1),
scenes: NavigationScenesReducer(
[],
this.props.navigation.state,
@@ -90,9 +89,7 @@ class Transitioner extends React.Component {
scenes: nextScenes,
};
- const { position, progress } = nextState;
-
- progress.setValue(0);
+ const { position } = nextState;
this._prevTransitionProps = this._transitionProps;
this._transitionProps = buildTransitionProps(nextProps, nextState);
@@ -108,7 +105,6 @@ class Transitioner extends React.Component {
if (result instanceof Promise) {
await result;
}
- progress.setValue(1);
position.setValue(toValue);
this._onTransitionEnd();
});
@@ -137,10 +133,6 @@ class Transitioner extends React.Component {
const animations =
indexHasChanged && positionHasChanged
? [
- timing(progress, {
- ...transitionSpec,
- toValue: 1,
- }),
timing(position, {
...transitionSpec,
toValue: nextProps.navigation.state.index,
@@ -245,7 +237,7 @@ class Transitioner extends React.Component {
function buildTransitionProps(props, state) {
const { navigation } = props;
- const { layout, position, progress, scenes } = state;
+ const { layout, position, scenes } = state;
const scene = scenes.find(isSceneActive);
@@ -255,7 +247,6 @@ function buildTransitionProps(props, state) {
layout,
navigation,
position,
- progress,
scenes,
scene,
index: scene.index,