Skip to content

Commit

Permalink
Merge pull request #18 from degica/task/keyboard-drag-handle
Browse files Browse the repository at this point in the history
keyboard/ react animation and drag behaviour changes
  • Loading branch information
kasunprabath98 authored Jun 11, 2024
2 parents 6fd66c3 + 07b57cf commit a085725
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 82 deletions.
9 changes: 3 additions & 6 deletions example/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,13 @@ import React from 'react';
import {KomojuSDK} from 'react-native-komoju';
import {PUBLIC_KEY} from '@env';

import {GestureHandlerRootView} from 'react-native-gesture-handler';
import PaymentScreen from './PaymentScreen';

function App(): React.JSX.Element {
return (
<GestureHandlerRootView>
<KomojuSDK.KomojuProvider urlScheme="" publicKey={PUBLIC_KEY}>
<PaymentScreen />
</KomojuSDK.KomojuProvider>
</GestureHandlerRootView>
<KomojuSDK.KomojuProvider urlScheme="" publicKey={PUBLIC_KEY}>
<PaymentScreen />
</KomojuSDK.KomojuProvider>
);
}

Expand Down
1 change: 1 addition & 0 deletions example/PaymentScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ const styles = StyleSheet.create({
flexDirection: 'row',
justifyContent: 'space-between',
minHeight: 100,
zIndex: -100,
},
currencyRow: {
flexDirection: 'row',
Expand Down
1 change: 0 additions & 1 deletion payment_sdk/src/components/PaymentSheet.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React, { useRef, forwardRef, useImperativeHandle } from "react";
import { GestureHandlerRootView } from "react-native-gesture-handler";
import { StyleSheet } from "react-native";

import Sheet, { SheetRefProps } from "./Sheet";
Expand Down
3 changes: 1 addition & 2 deletions payment_sdk/src/components/PillContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React from "react";
import { StyleSheet, View } from "react-native";
import { StyleSheet, View, FlatList } from "react-native";
import Pill from "./Pill";
import { FlatList } from "react-native-gesture-handler";
import { PaymentType } from "../util/types";

type Props = {
Expand Down
149 changes: 79 additions & 70 deletions payment_sdk/src/components/Sheet.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import React, {
useCallback,
useImperativeHandle,
ForwardRefRenderFunction,
forwardRef,
useContext,
useRef,
useEffect,
ForwardRefRenderFunction,
} from "react";
import {
Dimensions,
Expand All @@ -11,15 +14,9 @@ import {
Text,
TouchableOpacity,
View,
Animated as RNAnimated,
PanResponder,
} from "react-native";
import { Gesture, GestureDetector } from "react-native-gesture-handler";
import Animated, {
useAnimatedProps,
useAnimatedStyle,
useSharedValue,
withSpring,
withTiming,
} from "react-native-reanimated";
import ResponseScreen from "./ResponseScreen";
import { Actions, DispatchContext, StateContext } from "../state";
import SheetContent from "./SheetContent";
Expand Down Expand Up @@ -47,21 +44,46 @@ const Sheet: ForwardRefRenderFunction<SheetRefProps, SheetProps> = (
{ children, swipeClose },
ref
) => {
const translateY = useRef(new RNAnimated.Value(0)).current;
const active = useRef(new RNAnimated.Value(0)).current;
const context = useRef(new RNAnimated.Value(0)).current;

const activeState = useRef(false);
const translateYState = useRef(0);
const contextState = useRef(0);

const { paymentState } = useContext(StateContext);
const dispatch = useContext(DispatchContext);

const translateY = useSharedValue(0);
const active = useSharedValue(false);
useEffect(() => {
const yListener = translateY.addListener(({ value }) => {
translateYState.current = value;
});
const activeListener = active.addListener(({ value }) => {
activeState.current = value === 1;
});
const contextID = context.addListener(({ value }) => {
contextState.current = value;
});
return () => {
translateY.removeListener(yListener);
active.removeListener(activeListener);
context.removeListener(contextID);
};
}, []);

const scrollTo = useCallback((destination: number) => {
"worklet";
active.value = destination !== 0;

translateY.value = withSpring(destination, { damping: 50 });
active.setValue(destination !== 0 ? 1 : 0);
RNAnimated.spring(translateY, {
toValue: destination,
friction: 10,
tension: 10,
useNativeDriver: true,
}).start();
}, []);

const isActive = useCallback(() => {
return active.value;
return activeState.current;
}, []);

useImperativeHandle(
Expand All @@ -79,40 +101,25 @@ const Sheet: ForwardRefRenderFunction<SheetRefProps, SheetProps> = (
[scrollTo, isActive]
);

const context = useSharedValue({ y: 0 });
const gesture = Gesture.Pan()
.onStart(() => {
context.value = { y: translateY.value };
})
.onUpdate((event) => {
translateY.value = event.translationY + context.value.y;
translateY.value = Math.max(translateY.value, MAX_TRANSLATE_Y + 50);
const panResponder = useRef(
PanResponder.create({
onStartShouldSetPanResponder: () => true,
onPanResponderGrant: () => {
context.setValue(translateYState.current);
},
onPanResponderMove: (event, gestureState) => {
const totalYMovement = gestureState.dy + contextState.current;
translateY.setValue(Math.max(totalYMovement, MAX_TRANSLATE_Y + 50));
},
onPanResponderRelease: () => {
if (translateYState.current > -SCREEN_HEIGHT / 1.5) {
scrollTo(0);
} else if (translateYState.current < -SCREEN_HEIGHT / 1.5) {
scrollTo(MAX_TRANSLATE_Y + 50);
}
},
})
.onEnd(() => {
if (translateY.value > -SCREEN_HEIGHT / 1) {
scrollTo(0);
} else if (translateY.value < -SCREEN_HEIGHT / 1.5) {
scrollTo(MAX_TRANSLATE_Y);
}
});

const rSheetStyle = useAnimatedStyle(() => {
return {
transform: [{ translateY: translateY.value }],
};
});

const rBackdropStyle = useAnimatedStyle(() => {
return {
opacity: withTiming(active.value ? 1 : 0),
};
}, []);

const rBackdropProps = useAnimatedProps(() => {
return {
pointerEvents: active.value ? "auto" : "none",
} as any;
}, []);
).current;

const getCtaText = () => {
switch (paymentState) {
Expand Down Expand Up @@ -141,29 +148,31 @@ const Sheet: ForwardRefRenderFunction<SheetRefProps, SheetProps> = (

return (
<>
<Animated.View
<RNAnimated.View
onTouchStart={() => {
swipeClose ? scrollTo(0) : null;
if (swipeClose) scrollTo(0);
}}
animatedProps={rBackdropProps}
style={[styles.backDrop, rBackdropStyle]}
pointerEvents="none"
style={[styles.backDrop, { opacity: active }]}
/>
<Animated.View style={[styles.bottomSheetContainer, rSheetStyle]}>
<GestureDetector gesture={gesture}>
<Animated.View>
<View style={styles.line}>
{!paymentState ? (
<Text style={styles.headerLabel}>Payment Options</Text>
) : null}
<TouchableOpacity
style={styles.crossBtn}
onPress={() => scrollTo(0)}
>
<Image source={closeIcon} />
</TouchableOpacity>
</View>
</Animated.View>
</GestureDetector>
<RNAnimated.View
style={[
styles.bottomSheetContainer,
{ transform: [{ translateY: translateY }] },
]}
{...panResponder.panHandlers}
>
<View>
<View style={styles.line}>
<Text style={styles.headerLabel}>Payment Options</Text>
<TouchableOpacity
style={styles.crossBtn}
onPress={() => scrollTo(0)}
>
<Image source={require("../assets/images/close.png")} />
</TouchableOpacity>
</View>
</View>
{paymentState ? (
<ResponseScreen
status={paymentState}
Expand All @@ -173,7 +182,7 @@ const Sheet: ForwardRefRenderFunction<SheetRefProps, SheetProps> = (
) : (
<SheetContent />
)}
</Animated.View>
</RNAnimated.View>
</>
);
};
Expand Down
24 changes: 21 additions & 3 deletions payment_sdk/src/components/SheetContent.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useContext } from "react";
import { ScrollView } from "react-native";
import React, { useContext, useEffect, useState } from "react";
import { Keyboard, ScrollView } from "react-native";

import PillContainer from "./PillContainer";
import WebView from "./WebView";
Expand All @@ -13,6 +13,24 @@ import { PaymentType } from "../util/types";
const SheetContent = () => {
const { paymentType, webViewData, loading } = useContext(StateContext);
const dispatch = useContext(DispatchContext);
const [keyboardHeight, setKeyboardHeight] = useState(0);

useEffect(() => {
const keyboardDidShowListener = Keyboard.addListener(
'keyboardDidShow',
(e) => setKeyboardHeight(e.endCoordinates.height)
);

const keyboardDidHideListener = Keyboard.addListener(
'keyboardDidHide',
() => setKeyboardHeight(0)
);

return () => {
keyboardDidShowListener.remove();
keyboardDidHideListener.remove();
};
}, []);

const handlePillSelect = (type: PaymentType) => {
dispatch({ type: Actions.SET_PAYMENT_OPTION, payload: type });
Expand All @@ -30,7 +48,7 @@ const SheetContent = () => {

return (
<>
<ScrollView>
<ScrollView contentContainerStyle={{paddingBottom: keyboardHeight}}>
<PillContainer onSelect={handlePillSelect} selectedItem={paymentType} />
{paymentType === PaymentType.CREDIT && <CardSection />}
{paymentType === PaymentType.PAY_PAY && <PayPaySection />}
Expand Down

0 comments on commit a085725

Please sign in to comment.