deanmcpherson / react-native-sortable-listview

Drag drop capable wrapper of ListView for React Native
MIT License
917 stars 235 forks source link

onPress vs. on Long Press? #158

Open barrylachapelle opened 5 years ago

barrylachapelle commented 5 years ago

Silly question is it possible to detect press/tap on a row before the long press trigger? To make the row clickable? Maybe Im missing something super simple?

fnfilho commented 5 years ago

Hey @barrylachapelle, were you able to figure it out? Thanks!

barrylachapelle commented 5 years ago

@fnfilho yes I did. If you nest another component inside the row and have a TouchableHighlight in it... the TouchableHighlight can handle onPress inside the Rows long press. Does that make sense?

Example... checkout RowComponent below...


import React from 'react';
import { StyleSheet, View, TouchableHighlight, Image, Dimensions, Text, Button, ActivityIndicator } from 'react-native';
import firebase from 'firebase';
import SortableListView from 'react-native-sortable-listview';
import { Ionicons } from '@expo/vector-icons';

class RowComponent extends React.Component {

    render() {

        const window = Dimensions.get('window');

        return (

            <TouchableHighlight
                underlayColor={'#eee'}
                onPress={() => this.props.gotoEditPhoto({
                                    photoName:  this.props.data.photoName,
                                    photoId: this.props.data.photoId,
                                    photoUrl: this.props.data.photoUrl,
                                })}
                style={{
                    padding: 16,
                    backgroundColor: 'white',
                    borderBottomWidth: 1,
                    borderColor: '#eee',
                    width: window.width,
                }}
                {...this.props.sortHandlers}>

                <View style={styles.rowData}>

                    <View style={styles.photoHolder}>
                        <Image
                            style={{ borderRadius: 6, width: 64, height: 64 }}
                            source={{ uri: this.props.data.photoUrl }} /> 

                    </View>

                    <View style={styles.nameHolder}>
                        <Text>{this.props.data.photoName}</Text>
                    </View>

                    <View style={styles.photoRowIcon}>
                    <Ionicons name="md-arrow-dropright" size={24} color="#CCCCCC" />
                    </View>

                </View>

            </TouchableHighlight>

        )
    }
}

let tmpImages = {};
let order;

export default class OrganizePhotos extends React.Component {

    constructor(props) {
        super(props);

        this.state = {
            loading: false,
            photoData: {},
        };

        order = Object.keys(this.state.photoData) 
        this.getPhotos = this.getPhotos.bind(this);
    }

    static navigationOptions = ({ navigation }) => {

        const params = navigation.state.params || {};

        return {
            title: 'Drag to Order',
            headerStyle: {
                backgroundColor: '#26AE60',
            },
            headerBackTitle: null,
            headerTintColor: '#fff',
            headerTitleStyle: {
                fontWeight: 'bold',
            },
            headerRight: (
                <Button
                    onPress={() => params.saveOrder()}
                    title="Save"
                    color="#fff"
                />
            ),
        }
    };

    getPhotos = () => {

        tmpImages = {};
        tmpImages = this.state.photoData;

        let bookRef = firebase.database().ref('users/' + this.props.navigation.getParam('uid') + '/books/' + this.props.navigation.getParam('bookId') + '/_photos');

        bookRef.orderByChild('order').on('value', (snapshot) => {

            let data = snapshot.val();
            if (data !== null) {

                snapshot.forEach(function (childSnapshot) {
                    let photoId = childSnapshot.key;
                    let childdata = childSnapshot.val();
                    let photoCreated = childdata.created;
                    //let photoOrder= childdata.order;
                    let photoName = childdata.name;
                    let photoUrl = childdata.image_thumb;

                    tmpImages[photoId] = {
                        'photoId': photoId,
                        'photoCreated': photoCreated,
                        'photoName': photoName,
                        'photoUrl': photoUrl,
                    }

                });

            }

            this.setState({
                photoData: tmpImages
            });

            order = Object.keys(this.state.photoData);

        })

    }

    saveOrder = () => {
        this.sortPhotos(order);
    }

    sortPhotos = (order) => {

        this.setState({
            loading: true,
        });

        var photosRef = firebase.database().ref('users/' + this.props.navigation.getParam('uid') + '/books/' + this.props.navigation.getParam('bookId') + '/_photos/'); 

        photosRef.once('value', function (snapshot) {

            if (this.isUnmounted) {
                return;
            }

            snapshot.forEach(function (childSnapshot) {

                let photoKey = childSnapshot.key;
                let orderToWrite = order.indexOf(photoKey);

                photosRef.child(photoKey).update({
                    order: orderToWrite,
                });

            });
        })
        .then(() => {

            this.setState({
                loading: false,
            });

            //update and go to viewbook
            this.props.navigation.state.params.refreshPhotos();
            this.props.navigation.goBack();

        });

    }

    gotoEditPhoto = (data) => {

        this.props.navigation.navigate('EditPhoto',{
            photoName: data.photoName,
            photoId: data.photoId,
            photoUrl: data.photoUrl,
            uid: this.props.navigation.getParam('uid'),
            bookId: this.props.navigation.getParam('bookId'),
            refreshPhotos: this.getPhotos,
        });

    }

    componentDidMount = () => {
        this.getPhotos();
        this.props.navigation.setParams({ saveOrder: this.saveOrder });
    }

    componentWillUnmount() {
        this.isMounted = true;
    }

    render() {

        return (

            <View style={styles.container}>

                <SortableListView
                    style={styles.sortable}
                    data={this.state.photoData}
                    activeOpacity={0.8}
                    sortRowStyle={styles.rowDrag}
                    onRowMoved={e => {
                        order.splice(e.to, 0, order.splice(e.from, 1)[0]);
                        this.forceUpdate()
                    }}
                    order={order}
                    renderRow={row => <RowComponent data={row} gotoEditPhoto={(data) => this.gotoEditPhoto(data)} />}/>

                {this.state.loading &&
                    <View style={styles.loadingAnimation}><ActivityIndicator size="small" /></View>
                }   

            </View>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: '#F5F5F5',
        alignItems: 'center',
        justifyContent: 'center',
    },
    inputStyle: {
        fontSize: 16,
        backgroundColor: 'white',
        width: '80%',
        height: 56,
        borderRadius: 6,
        marginBottom: 16,
        paddingLeft: 16,
    },
    inputMultiLineStyle: {
        fontSize: 16,
        backgroundColor: 'white',
        width: '80%',
        height: 166,
        borderRadius: 6,
        marginBottom: 16,
        paddingLeft: 16,
        paddingTop: 16,
    },
    sortable: {
        //backgroundColor: 'green',
    },
    rowDrag: {
        transform: [{ rotate: '3deg' }],
        shadowColor: '#000000',
        shadowOffset: {
            width: 2,
            height: 2
        },
        shadowRadius: 4,
        shadowOpacity: 0.0,
    },
    rowData: {
        flexDirection: 'row',
    },
    photoHolder:{
        justifyContent: 'flex-start',
        width: 64,
        height: 64,
    },
    nameHolder: {
        justifyContent: 'center',
        alignItems: 'flex-start',
        flex: 1,
        height: 64,
        paddingLeft: 24,
    },
    photoRowIcon: {
        justifyContent: 'center',
        alignItems: 'flex-end',
        height: 64,
    }

});