victorsoares96 / epubjs-react-native

ePub.js Reader for React Native
MIT License
160 stars 51 forks source link

After app restart, getCurrentLocation can't get a new CFI until I swipe into a new chapter #322

Open mattdvhope opened 3 weeks ago

mattdvhope commented 3 weeks ago

Summary

When I restart my app, goToLocation fires properly, enabling me to go to the locally stored cfi location. But, in Pagination, as I swipe to the next/previous page within a single chapter, my current cfi remains unchanged. Only after I transition to another section/chapter does the actual cfi of the current page start to be made available again. Thereafter, each page-swipe gives getCurrentLocation() a fresh cfi.

If the reader never transitions to another chapter during one reading session, when he opens the app again, he will revert to the previously stored cfi. Only when he transitions to a new chapter will a fresh cfi be provided (for getCurrentLocation()) with each new page-swipe.

I did notice that as soon as I restart my app, if I very quickly swipe to another page or two within the chapter after loading, the correct CFI of the next page (or two) will be provided for getCurrentLocation(). But then this "shuts down" after a very short time-window (about 2-3 seconds). My "current cfi" then stays stuck (as I page-swipe within the current chapter) until I swipe into the next/previous chapter.

I looked at https://github.com/victorsoares96/epubjs-react-native/issues/286 which does have some similarities to my situation. But in my case, it seems that the only thing that will "trigger" getCurrentLocation() getting a new cfi is transitioning to a new chapter after app-restart.

What platform(s) does this occur on?

Android

What workflow(s) does this occur on?

Expo Workflow

Environment (or package.json)

expo-env-info 1.2.0 environment info: System: OS: macOS 14.6.1 Shell: 3.2.57 - /bin/bash Binaries: Node: 22.9.0 - /usr/local/bin/node Yarn: 1.22.22 - /usr/local/bin/yarn npm: 10.8.3 - /usr/local/bin/npm Watchman: 2024.11.04.00 - /usr/local/bin/watchman Managers: CocoaPods: 1.15.2 - /Users/matthewmalone/.rbenv/shims/pod SDKs: iOS SDK: Platforms: DriverKit 24.1, iOS 18.1, macOS 15.1, tvOS 18.1, visionOS 2.1, watchOS 11.1 IDEs: Android Studio: 2024.2 AI-242.23339.11.2421.12483815 Xcode: 16.1/16B40 - /usr/bin/xcodebuild npmPackages: expo: ~51.0.28 => 51.0.38 expo-router: ^3.5.23 => 3.5.23 react: 18.2.0 => 18.2.0 react-dom: 18.2.0 => 18.2.0 react-native: 0.74.5 => 0.74.5 react-native-web: ~0.19.10 => 0.19.13 npmGlobalPackages: eas-cli: 12.6.2 expo-cli: 6.3.12 Expo Workflow: managed

Your .epub file

No response

Minimal reproducible example

import React, { useState, useEffect } from "react";
import { SafeAreaView } from 'react-native';
import { ReaderProvider, Reader, useReader } from "@epubjs-react-native/core";
import { useFileSystem } from "@epubjs-react-native/expo-file-system";
import * as SecureStore from "expo-secure-store";

export default function App() {
  const { goToLocation } = useReader();
  return (
    <ReaderProvider>
      <SafeAreaView style={{ flex: 1 }}>
        <ReaderComponent
          epubUri="https://s3.amazonaws.com/moby-dick/OPS/package.opf"
          storedCfi={storedCfi}
          onTocLoad={setTocData}
          setGoToLocation={setGoToLocation}
        />
      </SafeAreaView>
    </ReaderProvider>
  );
};

const ReaderComponent = ({ epubUri, setGoToLocation }) => {
  const { goToLocation, getCurrentLocation, getLocations } = useReader();
  const [triggered, setTriggered] = useState(false);

  const handleReady = async () => { // This enables the rendering of the stored page/CFI after restart.
      const storedCfi = await SecureStore.getItemAsync("lastLocationCfi");
      if (goToLocation) {
          setGoToLocation(() => goToLocation);
          if (storedCfi) {
              console.log("Navigating to stored CFI:", storedCfi);
              await goToLocation(storedCfi);
          }
      }
  };

  const storeCurrentCfi = async (cfi) => { // This stores the current CFI.
      try {
          await SecureStore.setItemAsync("lastLocationCfi", cfi);
          console.log("Stored current CFI:", cfi);
      } catch (error) {
          console.error("Error storing current CFI:", error);
      }
  };

  useEffect(() => {  // This invokes storeCurrentCfi after a location change.
      const location = getCurrentLocation();
      if (location && location.start && location.start.cfi) {
          const destinationCfi = location.start.cfi;
          storeCurrentCfi(destinationCfi);
      }
  }, [triggered]);

  const handleLocationChange = () => { // This triggers the useEffect code block above.
      setTriggered((prev) => !prev);
  };

  return (
      <Reader
          src={epubUri}
          fileSystem={useFileSystem}
          onReady={handleReady}
          onLocationChange={handleLocationChange}
        />
   );
};

I confirm that i have

araycollado commented 1 week ago

Any update on this? I'm experiencing the same thing

forjoyilive commented 1 week ago

@araycollado I had this and applying the fix in #286 actually fixed it — it sounds like OP already tried that, but if you haven’t, it would be worth giving it a try.

(I’d rather have a more robust fix though as then I could load the book faster without waiting for onLocationsReady.)

araycollado commented 1 week ago

@forjoyilive Just tried that solution again and it does work. Might have confused it with another issue. I appreciate the help!