Open MicahDavid opened 7 months ago
it isn't clear. can you provide more code? does it always snap back or only some of the time?
it isn't clear. can you provide more code? does it always snap back or only some of the time?
Yes, it snaps back every time. Here is the entire component. Its worth noting, that this component lives inside a tab view, in case that has any relevance.
import React, {useState} from 'react'
import { connect } from 'react-redux'
import {FlatList, StyleSheet, Text} from 'react-native'
import { View } from 'native-base'
import { useNavigation } from '@react-navigation/native'
import {widthPercentageToDP as wp, heightPercentageToDP as hp} from 'react-native-responsive-screen'
import Loading from '../../../components/Loading'
import { FavoriteWarning } from '../../../components/blanks'
import { ForecastItem } from '../../../components/items'
import { getUserUnits } from '../../../utils/localStorageUtil'
import locationActions from '../../../redux/locations/actions'
const { fetchForecastItemRequest} = locationActions
import { globalStyles } from "../../../assets/styles/globalStyles"
import DraggableFlatList, {ShadowDecorator} from 'react-native-draggable-flatlist'
import axios from "axios"
import {getEndpoint} from "../../../utils/urlHelper"
import {axiosHeader} from "../../../utils/authUtil"
import {AlertModal} from "../../../components/modals"
const FavouritesContent = (props) => {
const navigation = useNavigation()
const { forecastSlug, favList, fetchForecastItemRequest, isOffline, showErrorMsg } = props
const handleShowDetail = async(locationSlug) => {
if (!isOffline) {
if (forecastSlug !== locationSlug) {
let units = await getUserUnits()
fetchForecastItemRequest({
slug: locationSlug,
units: units ? units : 1
})
}
navigation.navigate('ForecastDetail')
}
}
const reorderFaves = (data) => {
let orderArray = []
data.forEach(loc => {
orderArray.push(loc.id)
})
axios.patch(getEndpoint('api/favorites/reorder'),
{newOrder: orderArray},
{headers: axiosHeader}
).then(function (response) {
if (response.hasOwnProperty('data') && response.data.hasOwnProperty('errorMsg') && response.data.errorMsg)
showErrorMsg(response.data.errorMsg)
})
.catch(function (error) {
showErrorMsg('Error: '+error)
})
}
const renderItem = ({item,drag,isActive}) => {
return (
item?.locationBeachId && (
<ShadowDecorator>
<ForecastItem
drag={drag}
dragIsActive={isActive}
item={item}
openDetails={handleShowDetail}
/>
</ShadowDecorator>
)
)
}
return (
<View style={{flexGrow:1}}>
{
favList && (
<View style={{position:'relative'}}>
<DraggableFlatList
data={favList}
renderItem={renderItem}
keyExtractor={item => item?.locationBeachId}
/*
onDragEnd={({ data, from, to }) => {
if (from !== to)
reorderFaves(data)
//console.log('data',data)
}}
*/
contentContainerStyle={{paddingBottom:40}}
/>
<View style={styles.favReorderContainer}>
<Text style={styles.favReorderText}>Press and hold location, then drag to re-order.</Text>
</View>
</View>
)
}
</View>
)
}
const Favorites = (props) => {
const { favList, fLoading, setShowSLocationModal } = props
const [errorModal, setErrorModal] = useState({
title: null,
content: null,
open: false
})
return (
<View style={styles.container}>
{
fLoading === true && (
<Loading/>
)
}
<View style={styles.mainContent}>
{
(!favList || favList.length === 0) ?
<FavoriteWarning
setShowSLocationModal={setShowSLocationModal}
/> :
<FavouritesContent
favList={favList}
showErrorMsg={(message) => {
setErrorModal({
title: 'Error',
content: message,
open: !!message
})
}}
{...props}
/>
}
</View>
<AlertModal
data={errorModal}
visible={errorModal.open}
onClose={() =>
setErrorModal({
title: null,
content: null,
open: false
})
}
/>
</View>
)
}
const styles = StyleSheet.create({
container: {
flex:1,
backgroundColor: globalStyles.colors.paleBlue,
},
mainContent: {
marginTop: hp(1),
marginBottom: hp(1),
zIndex:1
},
mapView: {
position: 'absolute',
bottom: hp(3),
right: wp(3)
},
favReorderContainer: {
position:'absolute',
bottom:0,
left:0,
width:'100%',
backgroundColor: globalStyles.colors.paleBlue,
paddingTop:10
},
favReorderText: {
fontFamily:'Roboto',
fontSize:14,
color:globalStyles.colors.gray500,
textAlign:'center',
},
errorMsgContainer: {
backgroundColor:globalStyles.colors.warning500,
borderRadius:4,
alignItems:'center',
marginHorizontal:10,
marginVertical:8,
flexBasis:'auto'
},
errorMsgText: {
fontFamily:'Roboto-Medium',
color:'#fff',
fontSize:16,
lineHeight:28
}
})
const mapStateToProps = state => ({
fLoading: state.locationReducer.favLoading,
forecastSlug: state.locationReducer.forecastSlug,
isOffline: state.authReducer.isOffline
})
const mapDispatchToProps = {
fetchForecastItemRequest
}
export default connect(mapStateToProps, mapDispatchToProps)(Favorites)
Here is the rendered item component:
import React, {memo} from 'react'
import { connect } from 'react-redux'
import { useWindowDimensions, Pressable, Text } from 'react-native'
import { View, Icon } from 'native-base'
import HTML from 'react-native-render-html'
import { RFValue } from "react-native-responsive-fontsize"
import { forecastItemStyles } from "../../assets/styles/ForecastDayItem"
//import { WI_ICONS } from '../../assets/images/wx-icons'
import { globalStyles } from '../../assets/styles/globalStyles'
import WindIcon from '../../assets/images/icon/wind-arrow-summary.svg'
import {windArrowStyles} from "../../assets/styles/timeforecast"
import Ionicons from 'react-native-vector-icons/Ionicons'
const ForecastItem = (props) => {
const {item, openDetails, drag, dragIsActive} = props
const handleOpenDetails = () => {
openDetails(item.locationBeachSlug)
}
const { width } = useWindowDimensions();
//const WICON = item?.wxicon ? WI_ICONS[Object.keys(WI_ICONS).includes(item.wxicon) ? item.wxicon : 'none'] : WI_ICONS['none']
return (
<Pressable
onLongPress={drag ? drag : null}
disabled={dragIsActive ? dragIsActive : null}
onPress={handleOpenDetails}
style={({ pressed }) => [forecastItemStyles.container, {borderWidth: (dragIsActive ? 1 : 0),borderColor: globalStyles.colors.gray350, backgroundColor: dragIsActive || pressed ? globalStyles.colors.blue50 : 'white'}]}
>
<View style={forecastItemStyles.itemLeftPart}>
{ /*
<View style={{flexDirect:'row'}}>
<View style={{flexDirection:'row',flex:1,flexWrap: 'wrap', justifyContent:'center'}}>
<WICON width={RFValue(30)} height={RFValue(30)} style={{...forecastItemStyles.itemWeatherIcon,width:30}} fill="#00111C" />
<Text style={{...forecastItemStyles.itemTempText,paddingLeft:2, fontSize:12}}>
{item?.weather.atmp + "\u00B0"}
</Text>
</View>
</View>
*/
}
<View style={{flexDirect:'row', justifyContent:'center', alignItems: 'center'}}>
<WindIcon width={14} height={18}
style={{ ...windArrowStyles[item?.weather?.wind_dir ? 'dir-'+(item.weather.wind_dir).toLowerCase() : 'dir-'], marginRight: 6}}
/>
<Text style={{...forecastItemStyles.itemWindText, marginTop:16}}>{item?.weather.wind_dir+' '+item?.weather.wind_spd_digit}
<Text style={{fontSize:9}}>{item?.weather.wind_spd_unit}</Text>
</Text>
</View>
</View>
<View style={forecastItemStyles.itemRightPart}>
<View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
<Text style={forecastItemStyles.itemTitle}>
{
item?.locationName && (
<HTML
defaultTextProps={{allowFontScaling:false}}
contentWidth={width}
source={{ html: `<div class="location-title">${item.locationName}</div>` }}
classesStyles={{
'location-title': {
fontFamily: 'Roboto-Medium',
color: globalStyles.colors.blue800,
fontSize: 18,
}
}}
/>
)
}
</Text>
<Text style={forecastItemStyles.itemDistance}>
</Text>
</View>
<View style={forecastItemStyles.itemBottomBtnGroup}>
<View
style={[
forecastItemStyles.itemBtn,
item?.condAm ? item.condAm === 'choppy' ? forecastItemStyles.itemChoppyBtn : (item.condAm === 'fair' ? forecastItemStyles.itemFairBtn : (item.condAm === 'clean' ? forecastItemStyles.itemCleanBtn : {})) : {}
]}
>
<Text style={forecastItemStyles.itemTimeBtnLText}>
AM
</Text>
<Text style={forecastItemStyles.itemTimeBtnRText}>
{item?.surfAm}
</Text>
</View>
<View
style={[
forecastItemStyles.itemBtn,
item?.condPm ? item.condPm === 'choppy' ? forecastItemStyles.itemChoppyBtn : (item.condPm === 'fair' ? forecastItemStyles.itemFairBtn : (item.condPm === 'clean' ? forecastItemStyles.itemCleanBtn : {})) : {}
]}
>
<Text style={forecastItemStyles.itemTimeBtnLText}>
PM
</Text>
<Text style={forecastItemStyles.itemTimeBtnRText}>
{item?.surfPm}
</Text>
</View>
<View style={forecastItemStyles.itemDetails}>
<Icon
as={Ionicons}
name="chevron-forward"
size="lg"
style={forecastItemStyles.itemDetailsIcon}
/>
</View>
</View>
</View>
</Pressable>
)
}
export default memo(ForecastItem)
Thanks for any suggestions.
I got rid of everything except a simple test list, and still the draggable item returns to its original position.
Here is a test component that I rendered without anything else:
import React, {useState} from 'react'
import {Text, Pressable} from 'react-native'
import { View } from 'native-base'
import DraggableFlatList from 'react-native-draggable-flatlist'
const renderItem = ({item,drag,isActive}) => {
return (
<Pressable
onLongPress={drag ? drag : null}
disabled={isActive ? isActive : null}
>
<View style={{height:50,borderWidth:2,borderColor:'red'}}>
<Text>{item.name}</Text>
</View>
</Pressable>
)
}
const Favorites = () => {
//const { favList, fLoading, setShowSLocationModal } = props
const favList = [
{
id: 1,
name: 'A'
},
{
id: 2,
name: 'B'
},
{
id: 3,
name: 'C'
}
]
return (
<View>
{
favList && (
<View>
<DraggableFlatList
data={favList}
renderItem={renderItem}
keyExtractor={item => item?.id}
/>
</View>
)
}
</View>
)
}
export default Favorites
Not sure what else to try.
I'm a colossal idiot. I somehow overlooked that I needed to set the data on the re-order function. Please accept my apology on behalf of my idiocy and for any waste of time. Hopefully if someone is as bit of an idiot as me, they will run across this thread.
Describe the bug After dragging an item to a new position, after a short period, the item returns to the original position.
Platform & Dependencies react-native-draggable-flatlist version: 4.0.1
Platform: iOS
React Native or Expo version: 0.72.7
Reanimated version: 3.6.1
React Native Gesture Handler version: 2.14.0
https://github.com/computerjazz/react-native-draggable-flatlist/assets/51126961/a6c46861-7fed-4148-a350-07cea68192d4
My first guess was the list component was being re-rendered, but it is not.
Here's the basic code:
Any suggestions?