import { FlatList, Image, Pressable, Dimensions, StyleSheet, Text, View, useWindowDimensions, ScrollView, StatusBar, Alert } from 'react-native'
import React, { useEffect, useState } from 'react'
import Styles from '../../Styles/GlobalCss/Styles'
import Icon from 'react-native-vector-icons/FontAwesome'
import Icons from 'react-native-vector-icons/FontAwesome5'
import Color from '../../assets/color'
import size from '../../assets/size'
import WebApi from '../../Utils/WebApi'
import Header from '../../Components/Header'
import MapView, { Marker, PROVIDER_GOOGLE } from 'react-native-maps';
import { TextInput } from '../../Components'
import {
GestureHandlerRootView,
PanGestureHandler,
TouchableOpacity,
} from 'react-native-gesture-handler';
import Animated, {
useAnimatedGestureHandler,
useAnimatedStyle,
useSharedValue,
withSpring,
WithSpringConfig,
} from 'react-native-reanimated';
// type SheetPositions = 'minimised' | 'maximised' | 'expanded';
const window = Dimensions.get('window');
const screen = Dimensions.get('screen');
const NAV_HEIGHT = 48;
const Sheet = (props) => {
const [dimensions, setDimensions] = useState({ window, screen });
const { width, height } = useWindowDimensions();
const [selectTab, setSelectTab] = useState('0')
const [myPin, setMyPin] = useState([
{ type: 'Home' }, { type: 'Office' }, { type: 'Apartment' }, { type: 'Apartment' }
])
const [Tab, setTab] = useState([
{ type: 'Home' }, { type: 'Bookings' }, { type: 'Wallet' }, { type: 'Profile' }
])
useEffect(() => {
// Watch for screen size changes and update the dimensions
const subscription = Dimensions.addEventListener(
'change',
({ window, screen }) => {
setDimensions({ window, screen });
}
);
return () => subscription?.remove();
});
// Fixed values (for snap positions)
const minHeight = props.minHeight || 200;
const maxHeight = props.maxHeight || dimensions.screen.height;
const expandedHeight = props.expandedHeight || dimensions.screen.height * 0.6;
// Animated values
const position = useSharedValue('minimised');
const sheetHeight = useSharedValue(-minHeight);
const navHeight = useSharedValue(0);
const springConfig = {
damping: 50,
mass: 0.3,
stiffness: 120,
overshootClamping: true,
restSpeedThreshold: 0.3,
restDisplacementThreshold: 0.3,
};
const DRAG_BUFFER = 40;
const onGestureEvent = useAnimatedGestureHandler({
// Set the context value to the sheet's current height value
onStart: (_ev, ctx) => {
ctx.offsetY = sheetHeight.value;
},
// Update the sheet's height value based on the gesture
onActive: (ev, ctx) => {
sheetHeight.value = ctx.offsetY + ev.translationY;
},
// Snap the sheet to the correct position once the gesture ends
onEnd: () => {
// Snap to expanded position if the sheet is dragged up from minimised position
// or dragged down from maximised position
const shouldExpand =
(position.value === 'maximised' &&
-sheetHeight.value < maxHeight - DRAG_BUFFER) ||
(position.value === 'minimised' &&
-sheetHeight.value > minHeight + DRAG_BUFFER);
// Snap to minimised position if the sheet is dragged down from expanded position
const shouldMinimise =
position.value === 'expanded' &&
-sheetHeight.value < expandedHeight - DRAG_BUFFER;
// Snap to maximised position if the sheet is dragged up from expanded position
const shouldMaximise =
position.value === 'expanded' &&
-sheetHeight.value > expandedHeight + DRAG_BUFFER;
// Update the sheet's position with spring animation
if (shouldExpand) {
navHeight.value = withSpring(0, springConfig);
sheetHeight.value = withSpring(-expandedHeight, springConfig);
position.value = 'expanded';
} else
// if (shouldMaximise) {
// navHeight.value = withSpring(NAV_HEIGHT + 10, springConfig);
// sheetHeight.value = withSpring(-maxHeight, springConfig);
// position.value = 'maximised';
// } else
if (shouldMinimise) {
navHeight.value = withSpring(0, springConfig);
sheetHeight.value = withSpring(-minHeight, springConfig);
position.value = 'minimised';
} else {
sheetHeight.value = withSpring(
position.value === 'expanded'
? -expandedHeight
: position.value === 'maximised'
? -maxHeight
: -minHeight,
springConfig
);
}
},
});
const sheetHeightAnimatedStyle = useAnimatedStyle(() => ({
height: -sheetHeight.value+80,
}));
const sheetContentAnimatedStyle = useAnimatedStyle(() => ({
paddingBottom: position.value === 'maximised' ? 180 : 0,
paddingTop: position.value === 'maximised' ? 40 : 20,
paddingHorizontal: 20,
}));
const sheetNavigationAnimatedStyle = useAnimatedStyle(() => ({
height: navHeight.value,
overflow: 'hidden',
}));
return (
<View style={styles.container}>
<StatusBar
backgroundColor={"transparent"}
translucent={true}
barStyle={'dark-content'}
/>
<GestureHandlerRootView style={{ flex: 1 }} >
<View style={[{ width: '100%', }]}>
<View style={[Styles.flexRow, Styles.justifyFE, { backgroundColor: 'transparent', position: 'absolute', top: 150, zIndex: 999, width: '100%' }]}>
<View style={[Styles.round, Styles.fullCenter, { marginRight: 16 }]}>
<Icon name="search" color={Color.colorPrimary} size={20} />
</View>
<View style={[Styles.round, Styles.fullCenter, { marginRight: 16 }]}>
<Icons name="badge-percent" color={Color.colorPrimary} size={20} />
</View>
<View style={[Styles.round, Styles.fullCenter, { marginRight: 16 }]}>
<Icon name="bell" color={Color.colorPrimary} size={20} />
<View style={[{ position: 'absolute', top: 10, right: 14, backgroundColor: Color.colorRed, height: 7, width: 7, borderRadius: 10 }]} />
</View>
</View>
<MapView
// provider={PROVIDER_GOOGLE} // remove if not using Google Maps
style={[{ height: height - sheetHeight.value, width: '100%', marginTop: 0 }]}
region={{
latitude: 28.508451,
longitude: 77.031173,
latitudeDelta: 0.015,
longitudeDelta: 0.0121,
}}
>
<Marker
coordinate={{
latitude: 28.508451,
longitude: 77.031173,
}} >
<View style={[Styles.fullCenter, { height: 120, width: 120, borderRadius: 70, backgroundColor: Color.colorPrimary + 55, borderWidth: 0, borderColor: Color.colorPrimary }]}>
<View style={[Styles.fullCenter, { height: 60, width: 60, borderRadius: 30, backgroundColor: 'pink', borderWidth: 3, borderColor: Color.white }]}>
<Image source={require('../../assets/image/boy.png')} style={[{ height: 40, width: 40, }]} />
</View>
</View>
</Marker>
</MapView>
<View style={[{ position: 'absolute', bottom: 0, width: '100%', paddingBottom: 30 }]}>
<ScrollView horizontal showsHorizontalScrollIndicator={false}>
{myPin?.map((item, index) =>
<View style={[styles.savePin]}>
<Icons name="map-marker-alt" color={Color.colorPrimary} />
<Text style={[Styles.textBlack, { fontWeight: '500', paddingHorizontal: 10 }]}>{item.type}</Text>
</View>
)}
</ScrollView>
<View style={[styles.pointer]}>
<Icons name="location" color={Color.white} size={15} />
</View>
</View>
</View>
<PanGestureHandler onGestureEvent={onGestureEvent}>
<Animated.View style={[sheetHeightAnimatedStyle, styles.sheet]}>
<View style={styles.handleContainer}>
<View style={styles.handle} />
</View>
<Animated.View style={{ flex: 1 }}>
<>
<ScrollView style={[{ flex: 1 }]}>
<View style={[styles.scrollview, {}]}>
<View>
<TextInput
placeholder="Where would you go?"
pin
/>
</View>
<View style={[Styles.flexRow, Styles.alignC, Styles.paddingV20, Styles.justifySA]}>
{Tab?.map((item, index) =>
<Pressable
onPress={() => setSelectTab(index)}
style={[Styles.List, styles.bottomTab, { backgroundColor: selectTab == index ? Color.colorPrimaryL : Color.white, }]}>
<Icons name="map-marker-alt" color={selectTab == index ? Color.colorPrimary : Color.colorHintLBlack} />
<Text style={[Styles.textBlack, { fontWeight: '500', paddingHorizontal: 5 }]}>{item.type}</Text>
</Pressable>
)}
</View>
</View>
</ScrollView>
</>
</Animated.View>
</Animated.View>
</PanGestureHandler>
</GestureHandlerRootView>
</View>
);
};
const styles = StyleSheet.create({
container: {
position: 'absolute',
bottom: 0,
left: 0,
right: 0,
},
sheet: {
justifyContent: 'flex-start',
backgroundColor: '#FFFFFF',
borderTopLeftRadius: 20,
borderTopRightRadius: 20,
minHeight: 80,
shadowColor: '#000',
shadowOffset: {
width: 0,
height: -2,
},
shadowOpacity: 0.23,
shadowRadius: 2.62,
elevation: 4,
},
handleContainer: {
alignItems: 'center',
justifyContent: 'center',
paddingTop: 10,
},
handle: {
width: '15%',
height: 4,
borderRadius: 8,
backgroundColor: '#CCCCCC',
},
closeButton: {
width: NAV_HEIGHT,
height: NAV_HEIGHT,
borderRadius: NAV_HEIGHT,
alignItems: 'center',
justifyContent: 'center',
alignSelf: 'flex-start',
marginBottom: 10,
},
bottomTab: {
paddingVertical: 8,
borderRadius: 10,
paddingHorizontal: 10,
marginHorizontal: 2,
borderColor: Color.colorPrimary,
},
scrollview: {
...Styles.alignC,
...Styles.width100,
borderTopLeftRadius: 30,
borderTopRightRadius: 30,
backgroundColor: Color.white,
flex: 1,
},
pointer: {
...Styles.Icon,
...Styles.fullCenter,
borderRadius: 20,
position: 'absolute',
top: -60, right: 20,
backgroundColor: Color.colorPrimary
},
savePin: {
...Styles.List,
...Styles.Compborder1,
backgroundColor: Color.white,
marginHorizontal: 5,
paddingVertical: 10,
borderRadius: 30,
paddingHorizontal: 10,
borderColor: Color.colorPrimary,
paddingLeft: 15
}
});
export default Sheet;
0 comments:
Post a Comment