meliorence / meliorence/react-native-snap-carousel

onBeforeSnapToItem not working properly

Open
#839 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
JavaScript
Stars
10.5k
Forks
2.3k
PR merge metrics
No merged PRs in 30d

Description

Hey, I am using this package in my app, but when I am dragging from one item to another onBeforeSnapToItem called on every scroll, it gives me only one index (1) every time.

Code:

import React, { Component, useState } from 'react';
import {
  View,
  StyleSheet,
  Image,
  Dimensions,
  TouchableOpacity,
  Text,
  Animated,
  FlatList,
  TouchableWithoutFeedback,
  ActivityIndicator
} from 'react-native';
import styled from 'styled-components/native';
import BottomTabBar from '../components/BottomNavigation';
import BuzzFeed from '../components/BuzzFeed';
import CategoryTab from '../components/CategoryTab';
import { useSelector, useDispatch } from 'react-redux';
import R from '../res/R';
import StoryBoard from '../components/Story/StoryBoard';
import ApiHelper from '../controllers/ApiHelper';
import { fillCategories, fillArticles } from '../store/actions';
import Carousel from 'react-native-snap-carousel';


const Dashboard = (props) => {
  let categories = useSelector(state => state.category);
  let [currentPaggingIndex, setCurrentPaggingIndex] = useState(0);
  const dispatcher = useDispatch();
  categories = [{

    "category_id": "mix_bag",
    "category_name": "Mix Bag",
    "category_image": "http://www.gothru.in/uploads/2019061717313125-CATEGORY-8.jpg"

  }, ...categories]

  const allStories = useSelector(state => state.article);
  let [currentArticles, setCurrentArticles] = useState(allStories)
  const [currentCategory, setCurrentCategory] = useState(categories[0].category_id);
  const [screenToShow, setScreenToShow] = useState(2);
  const [isLoading, setIsLoading] = useState(false);

  const handleCategoryChange = async (item) => {
    setCurrentCategory(item.category_id);
    setIsLoading(true);
    let resArticles;
    if (item.category_id === "mix_bag") {
      resArticles = await ApiHelper.getArticle();
    } else {
      resArticles = await ApiHelper.getArticle(item.category_id);
    }
    if (resArticles) {
      const articles = resArticles.data.article_list;
      dispatcher(fillArticles(articles));
      setIsLoading(false);
    }

  }

  const renderItem = ({ item }) => (
    <TouchableWithoutFeedback>
      <StoryBoard type="category" navigate={props.navigate} stories={stories} category={item} />
    </TouchableWithoutFeedback>
  );
  const renderTabItem = ({ item }) => (
    <TouchableOpacity onPress={() => handleCategoryChange(item)}>
      <View style={currentCategory === item.category_id ? styles.tabItemSelected : styles.tabItem}>
        <TabMenuText>{item.category_name}</TabMenuText>
      </View>
    </TouchableOpacity>
  );

  const renderStoryBoard = ({ item, index }) => (
    <View style={{
      flex: 1,
      width: R.dimens.screenWidth,
      alignContent: "center",
      justifyContent: "center",
      alignItems: "center",
      alignSelf: "center"
    }}>
      <StoryBoard type="category" category={currentCategory} navigate={props.navigation} stories={currentArticles} />
    </View>
  );

  // onViewableItemsChanged = async ({ viewableItems, changed }) => {
  //   const { item } = changed[0];
  //   console.log(viewableItems)
  //   console.log('MY ITEM IS : ', item);
  //   if (item.category_id !== "mix_bag") {
  //     setCurrentCategory(changed[0].item.category_id)
  //     setIsLoading(true);
  //     let resArticles;
  //     if (item.category_id === "mix_bag") {
  //       resArticles = await ApiHelper.getArticle();
  //     } else {
  //       resArticles = await ApiHelper.getArticle(item.category_id);
  //     }
  //     if (resArticles) {
  //       const articles = resArticles.data.article_list;
  //       dispatcher(fillArticles(articles));
  //       setIsLoading(false);
  //     }
  //   }
  // }

  const onScrollEnd = async (category) => {
    let resArticles;
    console.log(category);
    if (category === "mix_bag") {
      resArticles = await ApiHelper.getArticle();
    } else {
      resArticles = await ApiHelper.getArticle(category);
    }
    if (resArticles) {
      const articles = resArticles.data.article_list;
      dispatcher(fillArticles(articles));
      setIsLoading(false);
    }
  }


  return (
    <Container style={styles.container}>
      <View>
        {/* Header Logo */}
        <HeaderImage
          style={styles.header_logo}
          source={R.images.header_logo}
        />
        {/* Preference Button */}
        <TouchableOpacity
          style={{ position: 'absolute', alignSelf: 'flex-start' }}
          onPress={() => props.navigation.navigate('Preferences')}>
          <Prefrences
            style={styles.prefrences}
            source={R.images.prefrences}
          />
        </TouchableOpacity>
      </View>

      <View style={{ marginTop: 10 }}></View>
      {/* Category Tab */}
      <View styles={styles.tabBar}>
        <Animated.FlatList
          data={categories}
          keyExtractor={item => item.category_id}
          renderItem={renderTabItem}
          horizontal
          showsHorizontalScrollIndicator={false}
        />
      </View>
      {/*  Category Feed  */}
      {/* <Animated.FlatList
        data={categories}
        keyExtractor={item => item.category_id}
        renderItem={renderItem}
        bounces={false}
        scrollEnabled={false}
        horizontal
        showsHorizontalScrollIndicator={false}
      /> */}
      {
        isLoading ? <View style={{
          flex: 1,
          justifyContent: 'center',
          alignItems: 'center'
        }}>
          <ActivityIndicator size="large" color={R.colors.primary_yellow} />

        </View> : <Carousel
          renderItem={renderStoryBoard}
          data={categories}
          initialNumToRender={categories.length}
          // contentContainerCustomStyle={{
          //   left: 0, // Left spacing for the very first card
          //   paddingRight: 0 //right spacing for very last card 
          // }}
          sliderWidth={R.dimens.screenWidth}
          autoplay={true}
          itemWidth={R.dimens.screenWidth}
          onBeforeSnapToItem={(index) => {
            console.log(index);
            setIsLoading(true);
            console.log(categories[index]);
            setCurrentCategory(categories[index].category_id)
            onScrollEnd(categories[index].category_id);
          }}
          enableMomentum={false}
          // onSnapToItem={index => {
          //   console.log(index);
          //   setIsLoading(true);
          //   console.log(categories[index]);
          //   setCurrentCategory(categories[index].category_id)
          //   onScrollEnd(categories[index].category_id);
          // }}
        >
        </Carousel>


      }
      {/* Floating Bottom Navigation Bar */}
      <BottomTabBar
        onTabChnaged={(index) => {
          setScreenToShow(index)
        }}
      />
    </Container>
  );

}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    // backgroundColor: 'white',
  },
  header_logo: {
    alignSelf: 'center',
    height: R.dimens.screenWidth * 0.125,
    resizeMode: 'contain',
    marginTop: R.dimens.screenWidth * 0.025,
  },
  prefrences: {
    marginTop: R.dimens.screenWidth * 0.05,
    height: R.dimens.screenWidth * 0.08,
    resizeMode: 'contain',
  },
  tabItem: {
    padding: 10,
    marginBottom: 10
  },
  tabItemSelected: {
    backgroundColor: R.colors.primary_yellow,
    padding: 10,
    marginBottom: 10,
    borderRadius: 6
  },
  scene: {
    flex: 1,
  },
  tabBar: {
    marginLeft: 15,
    marginRight: 15
  }
});

const Container = styled.View`
  background: ${(props) => props.theme.background};
`;

const Prefrences = styled.Image`
  tint-color: ${(props) => props.theme.text};
`;

const HeaderImage = styled.Image`
  tint-color: ${(props) => props.theme.text};
`;

const TabMenuText = styled.Text`
  color: ${(props) => props.theme.tab_item_text_color};
`;

export default Dashboard;

Thank you so much.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the issue in the Dashboard component using the shown Carousel data and onBeforeSnapToItem handler, then compare its behavior with the commented onSnapToItem handler. Trace the callback index against categories while dragging and autoplaying; done means the callback reports the destination category index consistently and the existing category/API update flow uses it correctly.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, react-native
Domain
mobile-dev
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.