Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove swipe logic #376

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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