Skip to content

Commit

Permalink
Remove swipe logic
Browse files Browse the repository at this point in the history
  • Loading branch information
wilsonpage committed Nov 24, 2016
1 parent a86faf6 commit 334d250
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 216 deletions.
3 changes: 1 addition & 2 deletions config.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
{
"flags": {
"injectTestUrls": false,
"itemsExpandable": true,
"itemsSwipable": false
"itemsExpandable": true
},

"userFlags": {
Expand Down
202 changes: 7 additions & 195 deletions lib/views/list/list-item.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,30 +15,13 @@ const React = require('react');
*/

const {
PanResponder,
TouchableOpacity,
StyleSheet,
Animated,
Image,
Text,
View,
} = require('react-native');

/**
* Margin either size of the list item.
*
* @type {Number}
*/
const MARGIN_HORIZONTAL = 11;

/**
* Swipe velocity must exceed this
* speed for list-items to swipe away,
* else they spring back.
*
* @type {Number}
*/
const SWIPE_VELOCITY_THRESHOLD = 0.8;

/**
* The ListItem class
*
Expand All @@ -48,20 +31,7 @@ const SWIPE_VELOCITY_THRESHOLD = 0.8;
class ListItem extends React.Component {
constructor(props) {
super(props);

var pan = new Animated.ValueXY();
var opacity = pan.x.interpolate({
inputRange: [-200, 0, 200],
outputRange: [0.5, 1, 0.5],
});

this.state = {
pan: pan,
opacity: opacity,
};

this.panHandlers = this.createPanHandlers();
this.tapHandlers = this.createTapHandlers();
this.onPress = this.onPress.bind(this);
debug('created');
}

Expand All @@ -75,25 +45,18 @@ class ListItem extends React.Component {
render() {
var item = this.props.item.value;
debug('render', item);
var opacity = this.state.opacity;
var pan = this.state.pan;
var translateX = pan.x;
var style = [
styles.root,
this.props.style,
{
transform: [{ translateX }],
opacity,
},
];

return (
<Animated.View
{...this.panHandlers}
<TouchableOpacity
style={style}
onLayout={this.onLayout.bind(this)}>
onPress={this.onPress}
>
{this.renderContent(item)}
</Animated.View>
</TouchableOpacity>
);
}

Expand All @@ -107,7 +70,6 @@ class ListItem extends React.Component {

return (
<View
{...this.tapHandlers}
style={styles.content}
testId="inner">
{this.renderBackground(item)}
Expand Down Expand Up @@ -174,168 +136,18 @@ class ListItem extends React.Component {
</View>;
}

createTapHandlers() {
debug('create tap handlers');
var self = this;

return {

// Static tiles should always have
// the repsonder set so that they
// can respond to taps. For embed
// tiles we don't want to set the
// responder when expanded as it can
// interfere with webview touch events.
onStartShouldSetResponder() {
return true;
},

onResponderGrant() {
self.tapStart = Date.now();
debug('on responser grant');
},

onResponderRelease() {
var time = Date.now() - self.tapStart;
var tapped = time < 250;
debug('on responser release', time, tapped);
if (tapped) self.onTapped();
self.tapStart = null;
},

onResponderTerminationRequest() { return true; },
onResponderTerminate() { self.tapStart = null; },
};
}

createPanHandlers() {
debug('create pan handlers');
return PanResponder.create({
onMoveShouldSetPanResponder: this.onMoveShouldSetPanResponder.bind(this),
onPanResponderGrant: this.onPanResponderGrant.bind(this),
onPanResponderMove: Animated.event([
null, { dx: this.state.pan.x, dy: this.state.pan.y },
]),

onPanResponderRelease: this.onPanResponderRelease.bind(this),
onPanResponderTerminate: this.onPanResponderTerminate.bind(this),
onPanResponderTerminationRequest: () => {
debug('pan responder terminate?');
},
onShouldBlockNativeResponder: () => true,
}).panHandlers;
}

onMoveShouldSetPanResponder(e, { dx, dy }) {
debug('panresponder move should set?', dx, dy);
if (!this.props.swipable) return false;
var isPan = Math.abs(dx) > 6;
var isScroll = Math.abs(dy) > 5;
debug('pan: %s, scroll: %s', isPan, isScroll);
return isPan && !isScroll;
}

onPanResponderGrant() {
debug('panresponder move');
this.dragging = true;
this.props.onGestureStart();
}

onPanResponderRelease(e, gesture) {
debug('panresponser release');
this.onGestureEnd(e, gesture);
}

onPanResponderTerminate(e, gesture) {
debug('panresponder terminate');
this.onGestureEnd(e, gesture);
}

onGestureEnd(e, {vx}) {
var exceededThreshold = Math.abs(vx) > SWIPE_VELOCITY_THRESHOLD;
debug('gesture end', vx, exceededThreshold);
this.dragging = false;

// fast swipes fling the tile away
if (exceededThreshold) this.swipeAway(vx);
else this.snapBack();


// indicate to the list view that
// it can become scrollable again
if (this.props.onGestureEnd) this.props.onGestureEnd();

}

onLayout({nativeEvent:{layout}}) {
debug('on layout');
this.height = layout.height;
this.width = layout.width;
}

onTapped() {
debug('on tapped');
onPress() {
this.props.onPress(this.props.item.id);
}

snapBack() {
return new Promise(resolve => {
Animated.spring(this.state.pan, {
toValue: { x: 0, y: 0 },
friction: 7,
}).start(resolve);
});
}

swipeAway(vx) {
var min = 2;
var max = 5;
var velocity = vx >= 0
? clamp(vx, min, max)
: clamp(vx * -1, min, max) * -1;

debug('swiping away ...', vx, velocity);
Animated.decay(this.state.pan, {
velocity: { x: velocity, y: 0 },
deceleration: 0.9999,
}).start();

// callback once the tile has left the viewport
var listener = this.state.pan.addListener(({ x }) => {
if (Math.abs(x) < (this.width + MARGIN_HORIZONTAL)) return;
debug('swiped away', x, velocity);
this.state.pan.removeListener(listener);
this.state.pan.stopAnimation();
this.props.onSwiped(this);
});
}
}

ListItem.propTypes = {
item: React.PropTypes.object,
showDistance: React.PropTypes.bool,
onLongPress: React.PropTypes.func,
onGestureStart: React.PropTypes.func,
onGestureEnd: React.PropTypes.func,
onSwiped: React.PropTypes.func,
onPress: React.PropTypes.func,
swipable: React.PropTypes.bool,
style: View.propTypes.style,
};

/**
* Clamp a number between a
* given min/max range.
*
* @param {Number} value
* @param {Number} min
* @param {Number} max
* @return {Number}
*/
function clamp(value, min, max) {
return Math.max(Math.min(value, max), min);
}

/**
* Exports
*/
Expand Down
21 changes: 2 additions & 19 deletions lib/views/list/list.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* Dependencies
*/

import { theme } from '../../../config';
import ListItem from './list-item';
import Debug from '../../debug';
import React from 'react';
Expand All @@ -17,11 +18,6 @@ import {
LayoutAnimation,
} from 'react-native';

import {
theme,
flags,
} from '../../../config';

const debug = Debug('ListView');

class ListView extends React.Component {
Expand Down Expand Up @@ -103,13 +99,8 @@ class ListView extends React.Component {
return <ListItem
key={item.id}
item={item}
swipable={flags.itemsSwipable}
showDistance={this.props.showDistance}
onLongPress={this.onItemLongPress}
onGestureStart={this.onItemGestureStart.bind(this)}
onGestureEnd={this.onItemGestureEnd.bind(this)}
onSwiped={this.onItemSwiped.bind(this)}
onPress={this.props.onItemPress.bind(this)}
onPress={this.props.onItemPress}
/>;
});
}
Expand Down Expand Up @@ -150,13 +141,6 @@ class ListView extends React.Component {
this.setState({ scrollable: true });
}

onItemSwiped(item) {
debug('on item swiped');
var newMaxScrollY = this.getMaxScrollY() - item.height;
this.prepareForNewMaxScrollY(newMaxScrollY);
this.props.onItemSwiped(item.props.item);
}

onItemsChange() {
this.doLayoutAnimation();
}
Expand Down Expand Up @@ -218,7 +202,6 @@ ListView.propTypes = {
sortByDistance: React.PropTypes.bool,
showDistance: React.PropTypes.bool,
onRefresh: React.PropTypes.func,
onItemSwiped: React.PropTypes.func,
onItemPress: React.PropTypes.func,
contentOffsetY: React.PropTypes.number,
};
Expand Down

0 comments on commit 334d250

Please sign in to comment.