@sfenton/react-native-readium-with-cfi
Version:
A react-native wrapper for https://readium.org/ with CFI support
86 lines (85 loc) • 3.67 kB
JavaScript
import { useCallback, useEffect, useRef } from 'react';
export const useReaderRef = ({ file, onLocationChange, onTableOfContents, }) => {
const readerRef = useRef(null);
const readingOrder = useRef([]);
const onLocationChangeWithTotalProgression = useCallback((newLocation) => {
if (!onLocationChange ||
!readingOrder.current ||
!newLocation.locations) {
return;
}
if (!newLocation.locations.totalProgression) {
const newLocationIndex = readingOrder.current.findIndex((entry) => entry.href === newLocation.href);
if (newLocationIndex < 0 || !readingOrder.current[newLocationIndex]) {
return;
}
const readingOrderCount = readingOrder.current.length;
const chapterTotalProgression = readingOrder.current[newLocationIndex].locations?.totalProgression ||
0;
const intraChapterTotalProgression = newLocation.locations.progression / readingOrderCount;
newLocation.locations.totalProgression =
chapterTotalProgression + intraChapterTotalProgression;
}
onLocationChange(newLocation);
}, [onLocationChange]);
useEffect(() => {
async function run() {
const D2Reader = await import('@d-i-t-a/reader');
const ref = await D2Reader.load({
url: new URL(file.url),
lastReadingPosition: file.initialLocation,
userSettings: { verticalScroll: false },
api: {
updateCurrentLocation: async (location) => {
onLocationChangeWithTotalProgression(location);
return location;
},
},
injectables: injectables,
});
if (onTableOfContents) {
onTableOfContents(ref.tableOfContents);
}
// This way of estimating the totalProgression treats all reading order
// entries as equal in length.
// It is based on the implementation in the Readium Go toolkit
// https://github.com/readium/go-toolkit/blob/31c6a65b588f825ffb6b4f2445337ffdc53af685/pkg/pub/service_positions.go#L66
const oldReadingOrder = ref.readingOrder;
const readingOrderCount = oldReadingOrder.length;
readingOrder.current = oldReadingOrder.map((item, index) => {
const totalProgression = index / readingOrderCount;
return {
...item,
locations: {
...item.locations,
progression: 0,
totalProgression: totalProgression,
},
};
});
readerRef.current = ref;
}
run();
}, [file.url]);
return readerRef;
};
// NOTE: right now we're serving these through statically.io, which is just
// pulling them from Github... Might not be the best way and maybe we should
// consider bundling them with the library.
const injectables = [
{
type: 'style',
url: 'https://cdn.statically.io/gh/d-i-t-a/R2D2BC/production/viewer/readium-css/ReadiumCSS-before.css',
r2before: true,
},
{
type: 'style',
url: 'https://cdn.statically.io/gh/d-i-t-a/R2D2BC/production/viewer/readium-css/ReadiumCSS-default.css',
r2default: true,
},
{
type: 'style',
url: 'https://cdn.statically.io/gh/d-i-t-a/R2D2BC/production/viewer/readium-css/ReadiumCSS-after.css',
r2after: true,
},
];