forked from Expensify/App
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
reverted back the swipeableview, move events with web-based carousel
- Loading branch information
1 parent
5b303d0
commit 0cd79cc
Showing
6 changed files
with
191 additions
and
156 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
import React from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import {Pressable} from 'react-native'; | ||
import canUseTouchScreen from '../../libs/canUseTouchscreen'; | ||
|
||
const propTypes = { | ||
/** handles onPress events with a callback */ | ||
onPress: PropTypes.func, | ||
|
||
/** can handle the cycling of attachments */ | ||
onCycleThroughAttachments: PropTypes.func, | ||
|
||
/** can be set to provide styles */ | ||
styles: PropTypes.arrayOf(PropTypes.shape({})), | ||
|
||
/** Children to render. */ | ||
children: PropTypes.oneOfType([ | ||
PropTypes.func, | ||
PropTypes.node, | ||
]).isRequired, | ||
}; | ||
|
||
const defaultProps = { | ||
styles: [], | ||
onPress: () => {}, | ||
onCycleThroughAttachments: () => {}, | ||
}; | ||
|
||
class Carousel extends React.Component { | ||
constructor(props) { | ||
super(props); | ||
|
||
this.canUseTouchScreen = canUseTouchScreen(); | ||
this.handleKeyPress = this.handleKeyPress.bind(this); | ||
} | ||
|
||
componentDidMount() { | ||
if (this.canUseTouchScreen) { | ||
return; | ||
} | ||
document.addEventListener('keydown', this.handleKeyPress); | ||
} | ||
|
||
componentWillUnmount() { | ||
if (this.canUseTouchScreen) { | ||
return; | ||
} | ||
document.removeEventListener('keydown', this.handleKeyPress); | ||
} | ||
|
||
/** | ||
* Listens for keyboard shortcuts and applies the action | ||
* | ||
* @param {Object} e | ||
*/ | ||
handleKeyPress(e) { | ||
if (e.key === 'ArrowLeft') { | ||
this.props.onCycleThroughAttachments(-1); | ||
} | ||
if (e.key === 'ArrowRight') { | ||
this.props.onCycleThroughAttachments(1); | ||
} | ||
} | ||
|
||
render() { | ||
return ( | ||
<Pressable style={this.props.styles} onPress={this.props.onPress}> | ||
{this.props.children} | ||
</Pressable> | ||
); | ||
} | ||
} | ||
|
||
Carousel.propTypes = propTypes; | ||
Carousel.defaultProps = defaultProps; | ||
|
||
export default Carousel; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
import React, {Component} from 'react'; | ||
import {PanResponder, Dimensions, Animated} from 'react-native'; | ||
import PropTypes from 'prop-types'; | ||
|
||
import styles from '../../styles/styles'; | ||
import CONST from '../../CONST'; | ||
|
||
const propTypes = { | ||
children: PropTypes.element.isRequired, | ||
|
||
/** Callback to fire when swiping left or right */ | ||
onSwipe: PropTypes.func, | ||
|
||
/** Callback to handle a press event because PanResponder will intercept all gestures */ | ||
onPress: PropTypes.func, | ||
|
||
/** These help to prevent a swipe animation when at either end */ | ||
canSwipeLeft: PropTypes.bool, | ||
canSwipeRight: PropTypes.bool, | ||
}; | ||
|
||
const defaultProps = { | ||
onSwipe: () => {}, | ||
onPress: () => {}, | ||
canSwipeLeft: false, | ||
canSwipeRight: false, | ||
}; | ||
|
||
class Carousel extends Component { | ||
constructor(props) { | ||
super(props); | ||
this.pan = new Animated.Value(0); | ||
|
||
this.panResponder = PanResponder.create({ | ||
onMoveShouldSetPanResponderCapture: (_event, gestureState) => { | ||
if (gestureState.dy < CONST.COMPOSER_MAX_HEIGHT) { return; } | ||
return true; | ||
}, | ||
|
||
onStartShouldSetPanResponder: () => true, | ||
onPanResponderMove: (event, gestureState) => Animated.event([null, { | ||
dx: this.pan, | ||
}], {useNativeDriver: false})(event, gestureState), | ||
|
||
onPanResponderRelease: (event, gestureState) => { | ||
// For swiping through images, I needed to catch a single press to hide the arrows | ||
if (gestureState.dx === 0 && gestureState.dy === 0) { | ||
return this.props.onPress(); | ||
} | ||
|
||
const deltaSlide = gestureState.dx > 0 ? -1 : 1; | ||
if (Math.abs(gestureState.vx) < 1.6 || (deltaSlide === -1 && !this.props.canSwipeLeft) || (deltaSlide === 1 && !this.props.canSwipeRight)) { | ||
return Animated.spring(this.pan, {useNativeDriver: false, toValue: 0}).start(); | ||
} | ||
|
||
const width = Dimensions.get('window').width; | ||
const slideLength = deltaSlide * (width * (3 / 4)); | ||
Animated.timing(this.pan, {useNativeDriver: false, duration: 100, toValue: -slideLength}).start(({finished}) => { | ||
if (!finished) { | ||
return; | ||
} | ||
this.props.onSwipe(deltaSlide); | ||
this.pan.setValue(slideLength); | ||
Animated.timing(this.pan, {useNativeDriver: false, duration: 100, toValue: 0}).start(); | ||
}); | ||
}, | ||
}); | ||
} | ||
|
||
render() { | ||
return ( | ||
<Animated.View | ||
style={[ | ||
styles.w100, | ||
styles.h100, | ||
{transform: [{translateX: this.pan}]}, | ||
]} | ||
// eslint-disable-next-line react/jsx-props-no-spreading | ||
{...this.panResponder.panHandlers} | ||
> | ||
{this.props.children} | ||
</Animated.View> | ||
); | ||
} | ||
} | ||
|
||
Carousel.propTypes = propTypes; | ||
Carousel.defaultProps = defaultProps; | ||
|
||
export default Carousel; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,36 +1,3 @@ | ||
import React from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import {Pressable} from 'react-native'; | ||
export default ({children}) => children; | ||
|
||
const propTypes = { | ||
/** this could be set to provide events */ | ||
onPress: PropTypes.func, | ||
|
||
/** can be set to provide styles */ | ||
styles: PropTypes.arrayOf(PropTypes.shape({})), | ||
|
||
/** Children to render. */ | ||
children: PropTypes.oneOfType([ | ||
PropTypes.func, | ||
PropTypes.node, | ||
]).isRequired, | ||
}; | ||
|
||
const defaultProps = { | ||
onPress: () => {}, | ||
styles: [], | ||
}; | ||
|
||
// Swipeable View is available just on Android/iOS for now. Still need to utilize events | ||
function SwipeableView(props) { | ||
return ( | ||
<Pressable style={props.styles} onPress={props.onPress}> | ||
{props.children} | ||
</Pressable> | ||
); | ||
} | ||
|
||
SwipeableView.propTypes = propTypes; | ||
SwipeableView.defaultProps = defaultProps; | ||
|
||
export default SwipeableView; | ||
// Swipeable View is available just on Android/iOS for now. |
Oops, something went wrong.