I have a sectionlist with notifications and would like to have each row in a section be capable of swiping to delete. I have implemented the swipe to delete functionality but the issue I am facing now is that everytime I scroll down the sectionlist and a pan gesture is active on one of the rows, I cannot scrolling becomes disabled. Can anyone with experience guide me on this ? Happy to learn:)
import { View , Text, StyleSheet, Modal, Button, TouchableOpacity,SectionList} from "react-native";
import {useSelector} from "react-redux";
import { NotificationLikeStack } from "../../components/Stacks/NotificationStacks/NotificationLikeStack";
import { NotificationCommentStack } from "../../components/Stacks/NotificationStacks/NotificationCommentStack";
import { fetchDocs, doDocsExist,deleteDocsFromDB,addDocsToDB, addDocToDB, addDocsWithDifferenDataToDB, fetchData } from "../../firebase/firestoreDB";
import { bottomPopUpMessage } from "../../constants";
import HorizontalScrollButton from "../../components/HorizontalScrollButton/HorizontalScrollButton";
import { Divider } from "@ui-kitten/components";
import { NotificationFollowersStack } from "../../components/Stacks/NotificationStacks/NotificationFollowersStack";
import { isToday } from "../../constants";
import { set } from "firebase/database";
import { handleSendPushNotification } from "../../constants";
import uuid from "react-native-uuid";
import * as Linking from 'expo-linking';
import { FlatList, ScrollView, } from "react-native-gesture-handler";
const NotifcationScreen = ({navigation, route}) => {
const [notifications, setNotifications] = useState([])
const [filteredNotifications, setFilteredNotifications] = useState([notifications])
const buttons = ['All', 'Likes', 'Comments', 'Followers']
const [selectedButton, setSelectedButton] = useState(null)
const userinfo = useSelector((state) => state.auth.userInfo)
const [email, setEmail] = useState(userinfo?.email)
const [filterButtonPressed, setFilterButtonPressed] = useState(false)
const [usersBeingFollowed, setUsersBeingFollowed] = useState([])
const [hasPressedFollowButton, setHasPressedFollowButton] = useState(false)
const LinkingUrl = Linking.useURL();
const sectionListRef = useRef(null)
const [isScrollEnabled, setIsScrollEnabled] = useState(true)
// const section = notifications ? [
// {
// title: 'Likes',
// data: notifications.filter((notification) => notification.type === 'like')
// },
// {
// title: 'Comments',
// data: notifications.filter((notification) => notification.type === 'comment')
// },
// {
// title: 'Followers',
// data: notifications.filter((notification) => notification.type === 'follow')
// }
// ] : []
const section = notifications ? [
{
title: 'Today',
data: !filterButtonPressed ? notifications.filter(
(notification) => isToday(notification.createdAt)
) : filteredNotifications.filter( (notification) => isToday(notification.createdAt)),
},
{
title: 'Older',
data: !filterButtonPressed ? notifications.filter(
(notification) => !isToday(notification.createdAt)
) : filteredNotifications.filter( (notification) => !isToday(notification.createdAt)),
}
]
: [];
const fetchNotifications = async () => {
const path = `users/${email}/notifications`
const response = await fetchDocs(path)
if (response.success){
setNotifications(response.fetchedDocs.reverse())
}
else{
bottomPopUpMessage(response)
}
}
const renderItem = ({ item }) => {
if (item.type === 'like'){
return (
<NotificationLikeStack notification={item} onPressed={() => {
navigation.navigate("HomeScreen", item.params)
}}/>
)
}
else if (item.type === 'comment'){
return (
item.params.type === "polls" ?
<NotificationCommentStack notification={item} onPressed={() => navigation.navigate("HomeScreen",item.params) }/>
: <NotificationLikeStack setIsScrollEnabled={setIsScrollEnabled} notification={item} onPressed={() => {
navigation.navigate("HomeScreen", item.params)
}}/>
)
}
else if (item.type === 'follow'){
const isFollowing = usersBeingFollowed.includes(item.followID)
return (
<NotificationFollowersStack
notification={item}
isFollowing={isFollowing}
onPressFollowButton={() => {
onPressFollow(item, isFollowing)
}
}
onPressed={async () => {
const params = await redirectedProfileHandler(item.followID)
navigation.navigate("Profile", params)
}}
/>
)
}
}
useEffect(() => {
fetchNotifications()
}, [])
//console.log(notifications)
return (
<View style={styles.container}>
<View style={{marginHorizontal: 20}}>
<HorizontalScrollButton
buttons={buttons}
onButtonPress={handleButtonPress}
selectedButton={selectedButton}
setSelectedButton={setSelectedButton}
/>
</View>
<View style={{backgroundColor:'green'}}>
<SectionList
SectionSeparatorComponent={renderSectionSeparator}
stickySectionHeadersEnabled={false}
sections={section}
keyExtractor={(item, index) => item + index}
renderItem={({item}) => renderItem({item})}
renderSectionHeader={({section: {title, data}}) => {
if ( data.length === 0) {
return null; // Don't render the header if there are no likes
}
return <Text style={styles.header}>{title}</Text>;
}}
scrollEnabled={isScrollEnabled}
ref={sectionListRef}
style={{}}
/>
</View>
</View>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'white',
//marginHorizontal: 0
//marginHorizontal: 16,
},
header: {
fontSize: 20,
fontWeight: 'bold',
//backgroundColor: '#fff',
margin:20,
},
})
export default NotifcationScreen;
import React from 'react';
import { View, Text, StyleSheet, TouchableOpacity} from 'react-native';
import { Image } from 'expo-image';
import { ImageDict } from '../../../constants';
import { CustomButtons } from '../../buttons/Buttons';
import { handleTimePosted } from '../../../constants';
import { Ionicons } from '@expo/vector-icons';
import { Gesture, GestureDetector } from 'react-native-gesture-handler';
import Animated,{ runOnJS, useAnimatedStyle, withSpring, useSharedValue} from 'react-native-reanimated';
export const NotificationFollowersStack = ({imageExtraStyle, notification, isFollowing, onPressFollowButton, onPressed }) => {
const profilePic = notification.profilePic ? notification.profilePic : ImageDict.user
const translateX = useSharedValue(0);
const animatedStyles = useAnimatedStyle(() => ({
transform: [{ translateX: withSpring(translateX.value) }],
}));
const gesture = Gesture.Pan().
onBegin(() => {
console.log(translateX.value);
}).
onChange((event) => {
if (event.translationX < 0){
translateX.value = -50;
}
if (event.translationX > 0){
translateX.value = 0;
}
//translateX.value = event.translationX;
}).
onFinalize(() => {
console.log(translateX.value);
//translateX.value = withSpring(10);
})
const onPressOptionsClose = () => {
set
}
return (
<View style={{flex:1}}>
<GestureDetector
gesture={gesture}
>
<Animated.View style={[styles.container, animatedStyles]} onPress={onPressed}>
<Image
style={[styles.profileImageStyles, imageExtraStyle]}
source={profilePic}
/>
<View style={styles.textStackContainer}>
<Text>
<Text style={styles.userhandle}>{notification.userhandle}</Text> {notification.title}
</Text>
<Text style={styles.timeStyle}>{handleTimePosted(notification.createdAt)}</Text>
</View>
<View style={styles.innerContainer}>
{!isFollowing ?
<CustomButtons
name={"follow-long"}
extraStyle={styles.followButtonStyle}
onPress={onPressFollowButton}/> :
<CustomButtons
name={"unfollow-long"}
extraStyle={styles.followButtonStyle}
onPress={onPressFollowButton}/>
}
</View>
</Animated.View>
</GestureDetector>
<View style={styles.deleteStyles}>
<View style={{position:"absolute", right:5}}>
<Ionicons name="trash-sharp" size={24} color="black" />
</View>
<View style={{backgroundColor:"white", position:"absolute", left:0, top:0, bottom:0, height:'100%', width:"50%"}}/>
</View>
</View>
)
}
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
//alignItems:'center',
justifyContent:'space-between',
backgroundColor: 'white',
width: '100%',
padding: 20,
zIndex: 1,
//margin: 20,
},
textStackContainer: {
justifyContent: 'center',
//backgroundColor: 'yellow',
flex: 1,
paddingLeft: 10,
paddingRight: 10,
//padding: 10
//alignItems: 'center',
},
profileImageStyles: {
height:50,
width:50,
borderRadius:25,
},
deleteStyles:{
position: 'absolute',
right: 0,
left: 0,
top: 0,
bottom: 0,
justifyContent: 'center',
alignItems: 'flex-start',
//bottom: 10,
zIndex: 0,
justifyContent:'center',
backgroundColor:'red',
paddingRight: 0,
},
imageStyles: {
height:50,
width:50,
borderRadius:5,
},
userhandle: {
fontWeight: 'bold',
},
timeStyle: {
color:'grey',
marginTop: 5,
//marginLeft:10
},
followButtonStyle: {
backgroundColor: '#FF6657',
width: 80,
height: 40,
borderRadius: 10,
},
})```
New contributor
Dara10 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.