victorsoares96 / epubjs-react-native

ePub.js Reader for React Native
MIT License
140 stars 48 forks source link

onLocationChange not getting triggered after goToLocation fired #286

Open artisanphil opened 2 months ago

artisanphil commented 2 months ago

Summary

I am saving the latest location in the local storage and if the user closes the book and reopens it later, it goes to the saved location using goToLocation after onReady is fired. The odd thing is, that after that onLocationChange is no longer triggered when swiping to the next page and it also no longer updates the current location.

What platform(s) does this occur on?

Android

What workflow(s) does this occur on?

Expo Workflow

Environment (or package.json)

{ "dependencies": { "@epubjs-react-native/core": "1.4.5", "@epubjs-react-native/expo-file-system": "latest", "@expo/metro-runtime": "~3.2.1", "@expo/vector-icons": "^14.0.0", "@gorhom/bottom-sheet": "^4", "@react-native-async-storage/async-storage": "1.23.1", "@react-native-community/slider": "^4.5.2", "@react-navigation/native": "^6.1.15", "@react-navigation/native-stack": "^6.9.24", "expo": "^51.0.8", "expo-document-picker": "~12.0.1", "react": "18.2.0", "react-dom": "18.2.0", "react-native": "0.74.1", "react-native-fs": "^2.20.0", "react-native-gesture-handler": "~2.16.1", "react-native-paper": "^5.12.3", "react-native-reanimated": "~3.10.1", "react-native-safe-area-context": "4.10.1", "react-native-screens": "3.31.1", "react-native-vector-icons": "^10.0.3", "react-native-web": "~0.19.6", "react-native-webview": "13.8.6", "usehooks-ts": "^3.1.0", "expo-router": "~3.5.15", "expo-linking": "~6.3.1", "expo-constants": "~16.0.2", "expo-status-bar": "~1.12.1" }, "devDependencies": { "@babel/core": "^7.19.3", "@types/react": "~18.2.14", "typescript": "~5.3.3" }, "scripts": { "start": "expo start", "android": "expo run:android", "ios": "expo run:ios", "web": "expo start --web" }, "version": "1.0.0", "private": true, "name": "example-expo", "main": "expo-router/entry" }

Your .epub file

https://www.clozetesting.com/readdaily/roblox/book.epub

Minimal reproducible example

export function Book({ route }) {
  const { goToLocation, goNext } = useReader();
  let currentLocation;
  let src = `https://www.clozetesting.com/readdaily/${route}/book.epub`;
  if(route === 'test') {
    src = 'https://s3.amazonaws.com/moby-dick/OPS/package.opf';
  }

  const goToSavedLocation = async (currentLocation) => {
    try {
      let savedLocationString = await AsyncStorage.getItem('savedLocationObject_' + route);
      let savedLocationObject = JSON.parse(savedLocationString);
      let savedLocationPos = savedLocationObject.end.location;  
      this.currentLocation = savedLocationObject;    
      if(savedLocationPos !== null && savedLocationPos != '0' && savedLocationPos != currentLocation) {        
        goToLocation(savedLocationObject.end.cfi);          
      } 

    } catch (e) {
      console.log('error getting saved location');
    }
  };    
  const saveLocation = async (currentLocation) => {
    try {
      let savedLocationString = await AsyncStorage.getItem('savedLocationObject_' + route);
      let savedLocationObject = JSON.parse(savedLocationString);  

      if(savedLocationObject.end.location != 0 && (currentLocation.end.location == 0 || currentLocation.end.location == savedLocationObject.end.location)) {
        console.log('no change!');
        return;
      }  
    } catch(e) {
      //just continue to saving location
    }

    try {
      let currentLocationString = JSON.stringify(currentLocation);
      console.log('saving: ' + currentLocation.end.location);
      await AsyncStorage.setItem('savedLocationObject_' + route, currentLocationString);
    } catch (e) {
        console.log('error saving location');
    }  
  };      

  return (
    <SafeAreaView style={{ flex: 1 }}>
      <Reader
        src={src}
        fileSystem={useFileSystem}
        height={Dimensions.get('screen').height * 0.8}
        waitForLocationsReady
        onReady={(location) => {
          console.log('onReady');
          goToSavedLocation(location);
        }}
        onSwipeLeft={() => {
          console.log('on swipe left');
          goNext();
        }}
        onLocationChange={(total, current, progress, currentSection) => {
          currentLocation = current;
          console.log('on location change');
          saveLocation(current);
        }}
        onWebViewMessage={(message) => {
          console.log(message);
          if (message.type === 'onCfiFromLocation') {
            goToLocation(message.cfi);
          }
        }}
      />
      <Footer />
    </SafeAreaView>
  );
}

I confirm that i have

victorsoares96 commented 2 weeks ago

i try to reproduce this scenario, but when called goToLocation the onLocationChange was fired

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

function Component() {
  const { goToLocation } = useReader();
  return (
    <Reader
      // src="https://s3.amazonaws.com/moby-dick/OPS/package.opf"
      src="https://www.clozetesting.com/readdaily/roblox/book.epub"
      fileSystem={useFileSystem}
      onReady={() => {
        console.log('onReady');
        goToLocation('text/ch001.xhtml#chapter-5-a-new-challenge');
      }}
      onLocationChange={() => console.log('onLocationChange')}
    />
  );
}

export function Basic() {
  return (
    <SafeAreaView style={{ flex: 1 }}>
      <ReaderProvider>
        <Component />
      </ReaderProvider>
    </SafeAreaView>
  );
}
dcallus commented 1 week ago

This has just started happening to me. I'll try and find out as much info as I can.

edit: I couldn't replicate this with a minimum repo, so I think I've broken something. Will report back once I figure it out edit2: Although mine does seem to be related to goToLocation as well. I'll troubleshoot some more