Git Product home page Git Product logo

getstream / react-native-bidirectional-infinite-scroll Goto Github PK

View Code? Open in Web Editor NEW
234.0 21.0 27.0 1.84 MB

๐Ÿ“œ React Native - Bidirectional Infinite Smooth Scroll

Home Page: https://getstream.github.io/react-native-bidirectional-infinite-scroll/

License: MIT License

JavaScript 11.29% Java 22.11% TypeScript 46.41% C 0.36% Objective-C 11.36% Swift 0.28% Ruby 2.08% CSS 6.10%
react-native infinite-scroll flatlist

react-native-bidirectional-infinite-scroll's Introduction

๐Ÿ“œ React Native Bi-directional Infinite Scroll

License NPM Compatibility

Implement bidirectional infinite smooth scroll using React Native

[ Built with โ™ฅ at Stream ]

Vishal - Article 01

Introduction

FlatList by react-native only allows infinite scroll in one direction (using onEndReached). This package adds capability on top of FlatList to allow infinite scroll from both directions, and also maintains smooth scroll UX.

  • Accepts prop onStartReached & onEndReached, which you can use to load more results.
  • Calls to onEndReached and onStartReached have been optimized.
  • Inline loading Indicators, which can be customized as well.
  • Uses flat-list-mvcp to maintain scroll position or smooth scroll UX.
iOS Android

๐Ÿ›  Installation and Usage

Please check the complete docs at https://getstream.github.io/react-native-bidirectional-infinite-scroll/

โœ Contributing

See the contributing guide to learn how to contribute to the repository and the development workflow.

๐ŸŽ— License

MIT

react-native-bidirectional-infinite-scroll's People

Contributors

vishalnarkhede avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-native-bidirectional-infinite-scroll's Issues

inconsistencies

Hi, thanks for the work on this. I would like to use it but I'm finding that the results are so inconsistent that it's not usable in production. Your example works perfectly with an initial load of 50 and subsequent fetches of 10. If, however, I change all of the fetches to 30 then it starts bouncing around. I would just use 50/30 in my app yet I find that every change to the number of items or sizing of items causing the list to jump around while scrolling which makes it feel like a guessing game. Any advice?
thanks

Allow `ref`

Please wrap the component in React.forwardRef, to allow for ref to be passed as in Flatlist.

Thanks!

Not Maintaining Viewable Position of Item when getItemLayout Props passed in FlatList

Code:
Lib Version: 0.3.2
React Native: 0.61.5

import { FlatList } from "react-native-bidirectional-infinite-scroll";

<FlatList
       ref={(ref) => { flatListRef = ref }}
       getItemLayout={getItemLayout}
       style={styles.sectionList}
       data={formattedList}
       keyExtractor={(item, index) => item.id}
       renderItem={({ item, index }) => renderDateWise(item, index)}
       showsVerticalScrollIndicator={false}
       onMomentumScrollBegin={() => {
         onEndReachedCalledDuringMomentum = false;
       }}
       onEndReached={onListEndReached}
       onStartReached={onListTopReached}
       activityIndicatorColor={colors.themeColor} // optional
     />

when we scroll down or up -> new data comes from API -> list moved to the top of the content not maintaining viewable content position.

Works fine when we don't pass getItemLayout Props in FlatList.

Thanks in advance!

Can't build example on android : java.lang.NoClassDefFoundError: Could not initialize class org.codehaus.groovy.vmplugin.v7.Java7

Works fine on ios with npx react-native run-ios, but not on android :

npx react-native run-android
info Running jetifier to migrate libraries to AndroidX. You can disable it using "--no-jetifier" flag.
Jetifier found 1032 file(s) to forward-jetify. Using 16 workers...
info Starting JS server...
info Installing the app...
Downloading https://services.gradle.org/distributions/gradle-6.2-all.zip
....................................................................................................................................

Welcome to Gradle 6.2!

Here are the highlights of this release:
 - Dependency checksum and signature verification
 - Documentation links in deprecation messages
 - Shareable read-only dependency cache

For more details see https://docs.gradle.org/6.2/release-notes.html

Starting a Gradle Daemon (subsequent builds will be faster)
java.lang.NoClassDefFoundError: Could not initialize class org.codehaus.groovy.vmplugin.v7.Java7
	at org.codehaus.groovy.vmplugin.VMPluginFactory.<clinit>(VMPluginFactory.java:43)
	at org.codehaus.groovy.reflection.GroovyClassValueFactory.<clinit>(GroovyClassValueFactory.java:35)
	at org.codehaus.groovy.reflection.ClassInfo.<clinit>(ClassInfo.java:107)
	at org.codehaus.groovy.reflection.ReflectionCache.getCachedClass(ReflectionCache.java:95)
	at org.codehaus.groovy.reflection.ReflectionCache.<clinit>(ReflectionCache.java:39)
	at org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl.registerMethods(MetaClassRegistryImpl.java:210)
	at org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl.<init>(MetaClassRegistryImpl.java:108)
	at org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl.<init>(MetaClassRegistryImpl.java:86)
	at groovy.lang.GroovySystem.<clinit>(GroovySystem.java:36)
	at org.codehaus.groovy.runtime.InvokerHelper.<clinit>(InvokerHelper.java:86)
	at groovy.lang.GroovyObjectSupport.getDefaultMetaClass(GroovyObjectSupport.java:59)
	at groovy.lang.GroovyObjectSupport.<init>(GroovyObjectSupport.java:32)
	at org.gradle.internal.extensibility.DefaultExtraPropertiesExtension.<init>(DefaultExtraPropertiesExtension.java:29)
	at org.gradle.internal.extensibility.DefaultConvention.<init>(DefaultConvention.java:49)
	at org.gradle.internal.extensibility.ExtensibleDynamicObject.<init>(ExtensibleDynamicObject.java:60)
	at org.gradle.internal.instantiation.generator.MixInExtensibleDynamicObject.<init>(MixInExtensibleDynamicObject.java:35)
	at org.gradle.initialization.DefaultSettings_Decorated.getAsDynamicObject(Unknown Source)
	at org.gradle.initialization.SettingsFactory.createSettings(SettingsFactory.java:58)
	at org.gradle.initialization.ScriptEvaluatingSettingsProcessor.process(ScriptEvaluatingSettingsProcessor.java:64)
	at org.gradle.initialization.SettingsEvaluatedCallbackFiringSettingsProcessor.process(SettingsEvaluatedCallbackFiringSettingsProcessor.java:34)
	at org.gradle.initialization.RootBuildCacheControllerSettingsProcessor.process(RootBuildCacheControllerSettingsProcessor.java:36)
	at org.gradle.initialization.BuildOperationSettingsProcessor$2.call(BuildOperationSettingsProcessor.java:50)
	at org.gradle.initialization.BuildOperationSettingsProcessor$2.call(BuildOperationSettingsProcessor.java:47)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:416)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:406)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:165)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:102)
	at org.gradle.internal.operations.DelegatingBuildOperationExecutor.call(DelegatingBuildOperationExecutor.java:36)
	at org.gradle.initialization.BuildOperationSettingsProcessor.process(BuildOperationSettingsProcessor.java:47)
	at org.gradle.initialization.DefaultSettingsLoader.findSettingsAndLoadIfAppropriate(DefaultSettingsLoader.java:105)
	at org.gradle.initialization.DefaultSettingsLoader.findAndLoadSettings(DefaultSettingsLoader.java:49)
	at org.gradle.initialization.SettingsAttachingSettingsLoader.findAndLoadSettings(SettingsAttachingSettingsLoader.java:35)
	at org.gradle.internal.composite.CommandLineIncludedBuildSettingsLoader.findAndLoadSettings(CommandLineIncludedBuildSettingsLoader.java:34)
	at org.gradle.internal.composite.ChildBuildRegisteringSettingsLoader.findAndLoadSettings(ChildBuildRegisteringSettingsLoader.java:52)
	at org.gradle.internal.composite.CompositeBuildSettingsLoader.findAndLoadSettings(CompositeBuildSettingsLoader.java:35)
	at org.gradle.initialization.DefaultSettingsPreparer.prepareSettings(DefaultSettingsPreparer.java:36)
	at org.gradle.initialization.BuildOperatingFiringSettingsPreparer$LoadBuild.doLoadBuild(BuildOperatingFiringSettingsPreparer.java:59)
	at org.gradle.initialization.BuildOperatingFiringSettingsPreparer$LoadBuild.run(BuildOperatingFiringSettingsPreparer.java:54)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:402)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:394)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:165)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:92)
	at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
	at org.gradle.initialization.BuildOperatingFiringSettingsPreparer.prepareSettings(BuildOperatingFiringSettingsPreparer.java:42)
	at org.gradle.initialization.DefaultGradleLauncher.prepareSettings(DefaultGradleLauncher.java:208)
	at org.gradle.initialization.DefaultGradleLauncher.doClassicBuildStages(DefaultGradleLauncher.java:151)
	at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:140)
	at org.gradle.initialization.DefaultGradleLauncher.executeTasks(DefaultGradleLauncher.java:120)
	at org.gradle.internal.invocation.GradleBuildController$1.create(GradleBuildController.java:74)
	at org.gradle.internal.invocation.GradleBuildController$1.create(GradleBuildController.java:67)
	at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:189)
	at org.gradle.internal.work.StopShieldingWorkerLeaseService.withLocks(StopShieldingWorkerLeaseService.java:40)
	at org.gradle.internal.invocation.GradleBuildController.doBuild(GradleBuildController.java:67)
	at org.gradle.internal.invocation.GradleBuildController.run(GradleBuildController.java:56)
	at org.gradle.tooling.internal.provider.ExecuteBuildActionRunner.run(ExecuteBuildActionRunner.java:31)
	at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
	at org.gradle.launcher.exec.BuildOutcomeReportingBuildActionRunner.run(BuildOutcomeReportingBuildActionRunner.java:63)
	at org.gradle.tooling.internal.provider.ValidatingBuildActionRunner.run(ValidatingBuildActionRunner.java:32)
	at org.gradle.launcher.exec.BuildCompletionNotifyingBuildActionRunner.run(BuildCompletionNotifyingBuildActionRunner.java:39)
	at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner$3.call(RunAsBuildOperationBuildActionRunner.java:51)
	at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner$3.call(RunAsBuildOperationBuildActionRunner.java:45)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:416)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:406)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:165)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:102)
	at org.gradle.internal.operations.DelegatingBuildOperationExecutor.call(DelegatingBuildOperationExecutor.java:36)
	at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner.run(RunAsBuildOperationBuildActionRunner.java:45)
	at org.gradle.launcher.exec.InProcessBuildActionExecuter$1.transform(InProcessBuildActionExecuter.java:50)
	at org.gradle.launcher.exec.InProcessBuildActionExecuter$1.transform(InProcessBuildActionExecuter.java:47)
	at org.gradle.composite.internal.DefaultRootBuildState.run(DefaultRootBuildState.java:80)
	at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:47)
	at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:31)
	at org.gradle.launcher.exec.BuildTreeScopeBuildActionExecuter.execute(BuildTreeScopeBuildActionExecuter.java:42)
	at org.gradle.launcher.exec.BuildTreeScopeBuildActionExecuter.execute(BuildTreeScopeBuildActionExecuter.java:28)
	at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:78)
	at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:52)
	at org.gradle.tooling.internal.provider.SubscribableBuildActionExecuter.execute(SubscribableBuildActionExecuter.java:60)
	at org.gradle.tooling.internal.provider.SubscribableBuildActionExecuter.execute(SubscribableBuildActionExecuter.java:38)
	at org.gradle.tooling.internal.provider.SessionScopeBuildActionExecuter.execute(SessionScopeBuildActionExecuter.java:68)
	at org.gradle.tooling.internal.provider.SessionScopeBuildActionExecuter.execute(SessionScopeBuildActionExecuter.java:38)
	at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:37)
	at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:26)
	at org.gradle.tooling.internal.provider.ParallelismConfigurationBuildActionExecuter.execute(ParallelismConfigurationBuildActionExecuter.java:43)
	at org.gradle.tooling.internal.provider.ParallelismConfigurationBuildActionExecuter.execute(ParallelismConfigurationBuildActionExecuter.java:29)
	at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:60)
	at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:32)
	at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:55)
	at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:41)
	at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:48)
	at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:32)
	at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:68)
	at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
	at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:39)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
	at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:29)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
	at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:35)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
	at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.create(ForwardClientInput.java:78)
	at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.create(ForwardClientInput.java:75)
	at org.gradle.util.Swapper.swap(Swapper.java:38)
	at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:75)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
	at org.gradle.launcher.daemon.server.exec.LogAndCheckHealth.execute(LogAndCheckHealth.java:55)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
	at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:63)
	at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
	at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:82)
	at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
	at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:52)
	at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:297)
	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
	at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
	at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
	at java.base/java.lang.Thread.run(Thread.java:832)

FAILURE: Build failed with an exception.

* What went wrong:
Could not initialize class org.codehaus.groovy.reflection.ReflectionCache

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 8s

error Failed to install the app. Make sure you have the Android development environment set up: https://reactnative.dev/docs/environment-setup. Run CLI with --verbose flag for more details.
Error: Command failed: ./gradlew app:installDebug -PreactNativeDevServerPort=8081
java.lang.NoClassDefFoundError: Could not initialize class org.codehaus.groovy.vmplugin.v7.Java7
java --version
java 15.0.2 2021-01-19
Java(TM) SE Runtime Environment (build 15.0.2+7-27)
Java HotSpot(TM) 64-Bit Server VM (build 15.0.2+7-27, mixed mode, sharing)
sdkmanager --licenses
Exception in thread "main" java.lang.NoClassDefFoundError: javax/xml/bind/annotation/XmlSchema
	at com.android.repository.api.SchemaModule$SchemaModuleVersion.<init>(SchemaModule.java:156)
	at com.android.repository.api.SchemaModule.<init>(SchemaModule.java:75)
	at com.android.sdklib.repository.AndroidSdkHandler.<clinit>(AndroidSdkHandler.java:81)
	at com.android.sdklib.tool.sdkmanager.SdkManagerCli.main(SdkManagerCli.java:73)
	at com.android.sdklib.tool.sdkmanager.SdkManagerCli.main(SdkManagerCli.java:48)
Caused by: java.lang.ClassNotFoundException: javax.xml.bind.annotation.XmlSchema
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:606)
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:168)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)

onEndReached Not called every time

I want load more data from firebase as my previous project I Used same method and same code it's working perfectly;but right now it was not working onEndReached called only one time after scroll bottom to top it's not called.

How To Load more data in flatlist?

I have attached my source code here.

let me know what should I do?

Thank You

        <FlatList
        enableAutoscrollToTop={false}
        showsVerticalScrollIndicator={false}
        ref={ref => (this.flatList = ref)}
        onContentChange={this.scrollToEnd}
        data={this.state.messages}
        inverted
        style={{marginBottom: hp(2.5)}}
        onEndReached={() => this.loadMoreOlderMessages()}
        renderItem={({item, index}) => {
          var isMyMessage =
            this.props.user.userDetails.id == item.user._id ? true : false;
          return (
            <Message
              item={item}
              key={index}
              OnlIds={this.state.dates.map(item => item?.id)}
              isLeft={isMyMessage ? false : true}
              message={item?.text}
              onSwipe={(text, isLeft) => {
                this.props.user?.userDetails?.isCommunityChatBlock
                  ? null
                  : this.swipeToReply(text, isLeft, item, this.flatList);
                setTimeout(() => {
                  this.inputRef?.focus();
                }, 0);
              }}
            />
          );
        }}
        keyExtractor={item => item.id}
        HeaderLoadingIndicator={() => null}
        onStartReachedThreshold={10} // optional
        onEndReachedThreshold={0.1}
        initialNumToRender={15}
      />
        
loadMoreOlderMessages = async () => {
await ChatController.loadMoremessagesData({
  path: `${COLLECTIONS.COMMUNITYMESSAGES}`,
})
  .then(response => {
    if ('data' in response) {
      if (response.data.length > 0) {
        response.data.map(item => {
          this.callBack({data: {data: item, type: 'added'}}, false);
        });
      } else {
      }
    } else {
    }
  })
  .catch(error => {
    return;
  });

};

Cannot build example project

I cannot build the example project for iOS. The error from X-Code is
'atomic_notify_one<unsigned long>' is unavailable inside react-native-bidirectional-infinite-scroll/example/ios/Pods/Headers/Private/Flipper-Folly/folly/synchronization/DistributedMutex-inl.h:1051:5:

Type Error: from onEndReached prop

TypeError: onEndReached().then is not a function. (In 'onEndReached().then(p)', 'onEndReached().then' is undefined)

Does this error mean that the function i supply to onEndReached prop is supposed to be asynchronous?

Need some help on this please, deadline is in a few days!

Decrease number of re-renders on renderItem

I was trying to decrease the number of re-renders when items where added to the list after onStartReached or onEndReached were called. There were unecessary re-renders of already created items (at least in my view, maybe there is a reasoning for that), so I wanted only new items to call the renderItem prop passed to the Flatlist and improve the list rendering.

For that, I proposed a PR #1 using React.memo and React.useCallback to memoize the already rendered items and only call the renderItem to the new items on the list. Hope it'll be helpful somehow.

Jumping not solved on Android when scrolling up

First I would like to thank you for this publication with flat-list-mvcp and effort to solve the jumping problem on Android.
In my case, after setting the maintainVisibleContentPosition, the jumping problem disappeared on iOS but still present on Android.
Here is what happens on Android when scrolling up (scrolling down no problem) , flashing and jumping :

Bouncing on Android

I share some code snippets here so you can check if I made a mistake using FlatList :

import { FlatList } from 'react-native-bidirectional-infinite-scroll';

const viewConfigRef = useRef({
    itemVisiblePercentThreshold: 90,
    minimumViewTime: 200,
  });

  <FlatList
    data={moments}
    keyExtractor={keyExtractor}
    renderItem={renderMomentItem}
    horizontal={false}
    numColumns={1}
    viewabilityConfig={viewConfigRef.current}
    onViewableItemsChanged={onViewRef.current}
    ref={setRef}
    onScrollToIndexFailed={onScrollToIndexFailedMoments}
    onEndReached={loadMoreOlderMessages}
    onStartReached={loadMoreRecentMessages}
    onEndReachedThreshold={0.4}
    scrollEventThrottle={20}
    bounces={false}
    windowSize={5}   // tried without windowSize, with 5 or 10 same behaviour
    showsVerticalScrollIndicator={false}
    ListFooterComponent={
      momentLoading ? <ActivityIndicator size='large' /> : renderFooter
    }
    maintainVisibleContentPosition={{
      autoscrollToTopThreshold: undefined,
      minIndexForVisible: 0,
    }}
  />

TypeError: undefined is not a function

Hi. I copied the example and ran it in my application. Everything looked ok. Then I just scroll up to the bottom of the list and immediately scroll down to the top of the list and oops ... Maybe I missed something?
Screenshot_1640626259

OnStartReached method is triggered frequently

2021-06-24.9.15.16.mov

React Native version: 0.59.9

<SafeAreaView style={{ flex: 1}}>
                   <FlatList
                       style={{ flex: 1 }}
                       data={this.state.data}
                       inverted
                       onEndReached={this.loadMoreOlderMessages}
                       onStartReached={this.loadMoreRecentMessages}
                       renderItem={this.renderItem}
</SafeAreaView>
loadMoreOlderMessages = async () => {
            const newMessages = await queryMoreMessages(10);
            const { data } = this.state;
            this.setState({
                data: [].concat(data).concat(newMessages)
            });
        };

       loadMoreRecentMessages = async () => {
           const newMessages = await queryMoreMessages(10);
           const { data } = this.state;
           this.setState({
               data: [].concat(newMessages).concat(data)
           });
       };

       renderItem = ({ item }) => {
           if (item.isMyMessage) {
               return (
                   <View
                       key={`${item.id}`}
                       style={[styles.messageBubble, styles.myMessageBubble]}
                   >
                       <Text style={styles.myMessageText}>{item.text}</Text>
                   </View>
               );
           }

           return (
               <View key={`${item.id}`} style={styles.messageBubble}>
                   <Text style={styles.messageText}>{item.text}</Text>
               </View>
           );
       }

Is it the version 0.59.9 I am using?
Who can help look at it? Thanks ~~~

ListHeaderComponent not working

Hey,

I'm trying to use the ListHeaderComponent, but it's not working. It's working fine with RN native FlatList:

				<FlatList
					ListHeaderComponent={() => {
						return <UsersStatuses />
					}}
					ref={flatList}
					data={data.FollowingPosts.posts}
					keyExtractor={item => item._id}
					renderItem={({ item }) => <Post data={item} />}
					onStartReached={loadNewPosts}
					onEndReached={loadPreviousPosts}
					onStartReachedThreshold={0.2}
					onEndReachedThreshold={0.2}
					enableAutoscrollToTop={false}
				/>

onStartReached not being called

Code:
Lib Version: 0.3.3
React Native: 0.61.5

import { FlatList } from "react-native-bidirectional-infinite-scroll";

<FlatList
        ref={(ref) => setFlatListRef(ref)}
        initialNumToRender={Math.min(formattedList.length, 45)}
        style={styles.flatList}
        data={data}
        keyExtractor={(item, index) => item.id}
        renderItem={renderCard}
        showsVerticalScrollIndicator={false}
        onMomentumScrollBegin={() => {
          onEndReachedCalledDuringMomentum = false;
        }}
        onEndReached={onListEndReached}
        onStartReached={onListTopReached}
        onScrollToIndexFailed={scrollToIndexFailed}
        viewabilityConfig={viewConfigRef.current}
        onViewableItemsChanged={onViewableItemsChangedRef.current}
        showDefaultLoadingIndicators={false}
        removeClippedSubviews
      />

I have a huge list and when scrolling upwards, I render 10 records at a time. I have to implement a logic as to when more than 60 records are added to list, I have to slice the list from bottom, ensuring only 50 records at max should be there.
While implementing this, everything else works fine, but onStartReached stops getting invoked at all after certain calls.
Removing this logic works fine though.

Any ideas / suggestions?

Thanks in advance!

Maintained

Is this repository actively maintained?
Some PR are open some time and the last closed issue which was not a bug/request from the author is from march last year

onStartReached gets triggered in the initial scroll down

This gets triggered when you start scrolling down, so technically before it has reaches the start. Not sure if this is an intended behaviour. I imagined it would be triggered only when you come back to the first element after you scroll down.

Double call onEndReached/onStartReached function

Hi. Thanks for such library, but i faced two issues. Ill create another "issue" to separate them later.
So the first as title says: every time i have double call for both end reached functions.
I have tried some blockers like "isLoading" with useState or useRef, and anyway i've got a double call.

onEndReached={() => fetchNextEvents('someParams')}
onStartReached={() => fetchPrevEvents('someParams')}
onEndReached={fetchNextEvents}
onStartReached={fetchPrevEvents}

const fetchPrevEvents = async (someParams = 'DEFAULT_PARAM') => {
    try {
        const events = await fetchEvents(someParams);
        ...
    } catch (err) {
      console.log('Error fetching prev events', err);
    }
};

IOS simulator - iPhone 11 - 14.4

"react-native": "0.64.0",
"react-native-bidirectional-infinite-scroll": "^0.3.3",
"@stream-io/flat-list-mvcp": "^0.10.1",
"react": "17.0.1",

Not able to mock this module for unit tests

Hi,

I need to mock this module to run unit tests successfully on my component. However m not able to use it in tests.
On writing tests, it is throwing this error on Flatlist:

console.error Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports. Check the render method of 'Component'.

I am importing Flatlist like this in my component:

import { FlatList } from 'react-native-bidirectional-infinite-scroll';

Could you please help with this? Would highly appreciate!

Package.json:

"react-native-bidirectional-infinite-scroll": "^0.3.3",
"react": "16.9",
"react-native": "0.61.5",

Default loading indicator is not showing

this is my element

import {FlatList as BidirectionList} from 'react-native-bidirectional-infinite-scroll';
<BidirectionList
        ref={listRef}
        data={data}
        keyExtractor={keyExtractor}
        renderItem={renderItem}
        onStartReached={onStartReached}
        onEndReached={onEndReached}
        showDefaultLoadingIndicators={true}
        onStartReachedThreshold={10}
        onEndReachedThreshold={10}
        activityIndicatorColor={'black'}
      />

Get `ref` not exist error in typescript

Try to do this:

            <FlatList
                ref={(list) => flatListRef.current = list}
            />
        );

but get:

Type '{ ref: (list: any) => any; data: Page[]; renderItem: ({ item: page }: ListRenderItemInfo<Page>) => Element; onStartReached: () => Promise<void>; onEndReached: () => Promise<...>; keyExtractor: (page: Page) => string; extraData: number; }' is not assignable to type 'IntrinsicAttributes & Omit<FlatListProps<Page>, "maintainVisibleContentPosition"> & { onEndReached: () => Promise<void>; ... 10 more ...; ListFooterComponent?: ComponentType<...>; }'.
  Property 'ref' does not exist on type 'IntrinsicAttributes & Omit<FlatListProps<Page>, "maintainVisibleContentPosition"> & { onEndReached: () => Promise<void>; ... 10 more ...; ListFooterComponent?: ComponentType<...>; }'.ts(2322)

Versions

โ”œโ”€ @stream-io/[email protected]
โ””โ”€ [email protected]

Scroll position is not maintained when using sticky header

I have a list that is sectioned by date. When new items are appended at the second position because the topmost list element is a date which is the sticky header, the scroll position is not maintained. But when I remove the sticky header property it maintains list position as expected

Scroll is not smooth if initial items quantity is small

Screen.Recording.2021-05-05.at.18.07.30.mp4

Hi once again, so the second issue is: whenever you have a small initial list like 5-10 items with small height, e.g window height is 896, and the content is about to 800/700 and you try to call onStartReached function scroll position will jump on items append, and later on everything is fine. Also as soon as i increase initial quantity of items to 100 then issue is gone and everything works very smooth. So for my case i tried to increase initial items quantity and set initialScrollIndex with getItemsLayout props, but with such approach it becomes even much worse than it was before

IOS simulator - iPhone 11 - 14.4

"react-native": "0.64.0",
"react-native-bidirectional-infinite-scroll": "^0.3.3",
"@stream-io/flat-list-mvcp": "^0.10.1",
"react": "17.0.1",

Handle starting from a random point in the bidirectional-list

I'm not sure if this is handled or this is the expected behavior - start the bidirectional list from a random point
The scroll position is always on the last item when the list is inverted

Let's say we have a chat with 1000 messages and we load chunks of 25 at a time
Let's say we want to start from message 500
Here's what we do ATM (we use an inverted bidirectional-infinite-scroll)

  • when the list is opened
  • we show a general loading as the initial batch (500 - 525) are loading
  • then we render 500 - 525. We want be anchored at 500 but we actually see message 525 on the bottom of the list
  • then we fix scroll position by scrolling to the indexOf message 500
  • this triggers a onStartReached which is OK and loads messages above 500 (475 - 500)
  • scroll position stays at 500 - OK

The problem is, since that messages are complex we don't use getItemLayout and have to wait for the items to be rendered before scrolling, which causes a bad UX
Ideally we want to be anchored on message 500 when we load past data

When we use a non-inverted list this seems to work OK as scroll position is naturally top to bottom and we're on the top
Which brings the question - why use the inverted prop at all?
The explanation is that most chat apps prefer it that way, but isn't a bidirectional list solving this problem - you can easily add message at the begging as well as at the end

How to make the bottom activity loader to be evident

Hi greetings.
I am trying to make the activity loader to be clearly visible when user scroll down to list. but to see activity indicator i need to swipe twice.
For the first time i am able to scroll to the last element and cant see the activity indicator. the again if i swipe i was able to see the activity indicator.

my code implementation

const onEndReached = async() => {
return fetch()
}
 <View style={{ backgroundColor: 'white', flex: 1 }}>
      <FlatList
        data={creatorStore.bytesGridViewList}
        renderItem={renderItem}
        onStartReached={handleOnStartReached}
        onEndReached={handleOnEndReached}
        numColumns={3}
      />
    </View>
    ````
    
can anyone help me to sort this out
    
    

Error on package?

Hi,
i succesfully install the package but when run : npx react-native run-android
this error appear :

Error: While trying to resolve module react-native-bidirectional-infinite-scroll from file C:\rnProd\GuglielmiProd\src\components\programmi\modifyProgram.js, the package C:\rnProd\GuglielmiProd\node_modules\react-native-bidirectional-infinite-scroll\package.json was successfully found. However, this package itself specifies a main module field that could not be resolved (C:\rnProd\GuglielmiProd\node_modules\react-native-bidirectional-infinite-scroll\src\index.

Suggestions ?

Thanks !

Never ending loading when onEndReached and onStartReached are called simultaneously

If both onEndReached and onStartReached are called at the same time (eg. the list of data is really short) the end loading indicator never stops loading.

Video

flatlist.mov

Basic setup to reproduce:

<FlatList
  data={[1, 2, 3]}
  renderItem={() => (
    <View style={{ marginBottom: 20, backgroundColor: '#102C1A', height: 100, width: '100%' }} />
  )}
  keyExtractor={(item) => item.toString()}
  onStartReached={loadPrevious}
  onStartReachedThreshold={0.2}
  onEndReached={loadAfter}
  onEndReachedThreshold={0.2}
/>
const loadPrevious = async () => {
  console.log('PREVIOUS START');

  return new Promise<any>((resolve) =>
    setTimeout(() => {
      console.log('PREVIOUS RESOLVE');
      resolve(null);
    }, 1000),
  );
};
const loadAfter = async () => {
  console.log('AFTER START');

  return new Promise<any>((resolve) =>
    setTimeout(() => {
      console.log('AFTER RESOLVE');
      resolve(null);
    }, 2000),
  );
};

Does it work on web?

Can you please add documentation regarding to web support? Thank you for this wonderful component!

List jumps to the top of the List when onStartReached is called

I'm fetching data from an API which will either be appended at the end of the List (onEndReached) or the beginning of the list (onStartReached).
However when onStartReached is triggered, the list will jump to the very top, which will then again call onStartReached. It should not jump to the top of the list. Even with enableAutoscrollToTop set to false, which I know is the default value, it still jumps to the top.
When I reach the end (onEndReached) everything works as expected.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.