#3 Fix doesn't re-rerendering bug

Fixed a bug where re-rendering would not work when options and styles were changed.
main
NB 4 years ago
parent 73f2b9d98b
commit 7dae8d3fbe
  1. 22
      public/css/index.css
  2. 27
      src/index.tsx
  3. 190
      src/modules/epubViewer/EpubViewer.tsx
  4. 10
      src/modules/epubViewer/styles.ts
  5. 37
      src/modules/reactViewer/ReactViewer.tsx

@ -1,14 +1,14 @@
html, body {
padding: 0;
margin: 0;
}
html {
width: 100vw;
height: 100vh;
html,
body {
padding: 0;
margin: 0;
width: 100vw;
height: 100vh;
}
#root {
width: 100%;
height: 100%;
}
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}

@ -1,20 +1,35 @@
import { useRef } from 'react'
import ReactDOM from 'react-dom';
import EpubViewer from 'modules/epubViewer/EpubViewer'
import ReactEpubViewer from 'modules/reactViewer/ReactViewer'
import { ViewerRef } from 'types'
interface Props {
VIEWER_TYPE?: "ReactViewer" | "EpubViewer"
}
const App = () => {
const App = ({ VIEWER_TYPE = "ReactViewer" }: Props) => {
const EPUB_URL = "/react-epub-viewer/files/Alices Adventures in Wonderland.epub";
const ref = useRef<ViewerRef>(null);
return (
<ReactEpubViewer
url={EPUB_URL}
ref={ref}
/>
<>
{VIEWER_TYPE === "ReactViewer" && <>
<ReactEpubViewer
url={EPUB_URL}
ref={ref}
/>
</>
}
{VIEWER_TYPE === "EpubViewer" && <>
<EpubViewer
url={EPUB_URL}
ref={ref}
/>
</>
}
</>
);
}
ReactDOM.render(<App />, document.getElementById('root'));

@ -53,84 +53,8 @@ const EpubViewer = ({
const [rendition, setRendition] = useState<Rendition | null>(null);
const [toc, setToc] = useState<Toc[]>([]);
const currentCfi = useRef<string>('');
/**
* Init Book
* @method
* - Set book state
* - Set Epub path state
* - Set isLoaded state
* - Set toc state
*/
const initBook = () => {
if (book) {
book.destroy();
}
const book_ = new Book(url, epubFileOptions);
setBook(book_);
bookChanged && bookChanged(book_);
book_.loaded.navigation.then(({ toc }) => {
const toc_: Toc[] = toc.map(t => ({
label: t.label,
href: t.href
}));
setIsLoaded(true);
setToc(toc_);
tocChanged && tocChanged(toc_);
initRendition(book_);
});
// Init Location & Pagination
book_.ready.then(function() {
const stored = localStorage.getItem(book_.key() + '-locations');
if (stored) {
return book_.locations.load(stored);
} else {
return book_.locations.generate(1024);
}
}).then(() => {
localStorage.setItem(book_.key() + '-locations', book_.locations.save());
});
};
/**
* Init Rendition
* @method
* - Init iframe tag on DOM element
* - Set rendition
* - Set start page
*/
const initRendition = (book_: Book) => {
const node = ref.current;
if (!node || !book_) return;
const rendition_ = book_.renderTo(node, {
width: "100%",
height: "100%",
...epubOptions
});
setRendition(rendition_);
rendtionChanged && rendtionChanged(rendition_);
if(typeof location === "string") {
rendition_.display(location);
} else if(toc.length > 0 && toc[0].href) {
rendition_.display(toc[0].href);
} else {
rendition_.display();
}
}
/**
* Move page
* @method
@ -238,20 +162,114 @@ const EpubViewer = ({
/** Ref checker */
/** Ref Checker */
useEffect(() => {
if (!ref) {
throw new Error("[React-Epub-Viewer] Put a ref argument that has a ViewerRef type.");
}
}, [ref]);
/** Epub Init */
/* eslint-disable */
/** Epub init options Changed */
useEffect(() => {
if (!url) return;
initBook();
}, [url]);
/* eslint-enable */
let mounted: boolean = true;
let book_: Book | any = null;
if (!mounted) return;
if (book_) {
book_.destroy();
}
book_ = new Book(url, epubFileOptions);
setBook(book_);
return () => {
mounted = false;
}
}, [url, epubFileOptions, setBook, setIsLoaded]);
/** Book Changed */
useEffect(() => {
if (!book) return;
if (bookChanged) bookChanged(book);
book.loaded.navigation.then(({ toc }) => {
const toc_: Toc[] = toc.map(t => ({
label: t.label,
href: t.href
}));
setIsLoaded(true);
if (tocChanged) tocChanged(toc_);
});
book.ready.then(function() {
if (!book) return;
const stored = localStorage.getItem(book.key() + '-locations');
if (stored) {
return book.locations.load(stored);
} else {
return book.locations.generate(1024);
}
}).then(() => {
if (!book) return;
localStorage.setItem(book.key() + '-locations', book.locations.save());
});
}, [book, bookChanged, tocChanged]);
/** Rendition Changed */
useEffect(() => {
if (!rendition) return;
if (rendtionChanged) rendtionChanged(rendition);
}, [rendition, rendtionChanged]);
/** Viewer Option Changed */
useEffect(() => {
let mounted = true;
if (!book) return;
const node = ref.current;
if (!node) return;
node.innerHTML = "";
book.ready.then(function() {
if (!mounted) return;
if (book.spine) {
const loc = book.rendition?.location?.start?.cfi;
// if (book.rendition) book.rendition.destroy();
const rendition_ = book.renderTo(node, {
width: "100%",
height: "100%",
...epubOptions
});
setRendition(rendition_);
if(loc) {
rendition_.display(loc)
} else {
rendition_.display();
}
}
});
return () => {
mounted = false;
}
}, [ref, book, epubOptions, style, setRendition]);
/** Location Changed */
useEffect(() => {
if (!ref.current || !location) return;
if (ref.current.setLocation) ref.current.setLocation(location);
}, [ref, location]);
/**
* Emit Viewer Event
@ -284,14 +302,6 @@ const EpubViewer = ({
]);
/* eslint-enable */
/** Display page by changed location */
useEffect(() => {
if (!location || !rendition) return;
rendition.display(location);
}, [location, rendition]);
return (<>
{!isLoaded && loadingView}
<div ref={ref} style={viewerStyle} />

@ -3,10 +3,16 @@
*/
const styles: {
boxSizing: any,
margin: any
margin: any,
width: any,
height: any,
overflowY: any
} = {
boxSizing: "border-box",
margin: "0px auto"
margin: "0px auto",
width: "100%",
height: "100%",
overflowY: 'hidden'
}
export default styles

@ -50,14 +50,14 @@ const ReactViewer = ({
const [rendition, setRendition] = useState<Rendition | null>(null);
const [layoutStyle, setLayoutStyle] = useState<Object>({});
const [layoutStyle, setLayoutStyle] = useState<{[key: string]: any}>({});
const [bookStyle, setBookStyle] = useState<BookStyle>({
fontFamily: 'Origin',
fontSize: 18,
fontSize: 16,
lineHeight: 1.4,
marginHorizontal: 15,
marginVertical: 5
marginHorizontal: 0,
marginVertical: 0
});
const [bookOption, setBookOption] = useState<BookOption>({
@ -71,8 +71,6 @@ const ReactViewer = ({
contents: null
});
/**
* Run book changed
* @method
@ -118,17 +116,23 @@ const ReactViewer = ({
const h = bookOption.flow === "scrolled-doc"
? win_h - componentHeight
: win_h - componentHeight - ~~((win_h - componentHeight - viewerLayout_.MIN_VIEWER_HEIGHT) / 100 * bookStyle.marginVertical);
const marginTop = bookOption.flow === "scrolled-doc"
const marginVertical = bookOption.flow === "scrolled-doc"
? ""
: `${~~((win_h - componentHeight - viewerLayout_.MIN_VIEWER_HEIGHT) / 100 * bookStyle.marginVertical) / 2}px`;
setLayoutStyle(l => ({
...l,
width: w,
height: h,
marginTop
}));
setLayoutStyle(layout => {
if (layout.width !== w || layout.height !== h || layout.marginTop !== marginVertical) {
return {
...layout,
width: w,
height: h,
marginTop: marginVertical,
marginBottom: marginVertical
};
}
return layout;
});
try {
rendition.resize(w, h);
} catch { }
@ -212,8 +216,8 @@ const ReactViewer = ({
/** Set viewer Styles/Options */
useEffect(() => {
viewerStyle && setBookStyle(viewerStyle);
viewerOption && setBookOption(viewerOption);
viewerStyle && setBookStyle(v => ({ ...v, ...viewerStyle }));
viewerOption && setBookOption(v => ({ ...v, ...viewerOption }));
}, [viewerStyle, viewerOption]);
/** Apply viewer Styles/Options */
@ -277,7 +281,6 @@ const ReactViewer = ({
rendition.on("mouseup", onSelected);
return () => rendition.off("mouseup", onSelected);
}, [rendition, onSelected]);
return (<>

Loading…
Cancel
Save