Added pages cache
This commit is contained in:
parent
620852b536
commit
a3d24c373c
@ -1,14 +1,12 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
|
||||
type TextNode = Text & { nodeValue: string };
|
||||
type PositionElement = [number, TextNode];
|
||||
type IdPositions = Record<string, number>;
|
||||
type UsePaginationReturnTuple = [
|
||||
ready: boolean,
|
||||
goToPage: (pageNum: number) => void,
|
||||
currentPage: number,
|
||||
pageNumber: number
|
||||
];
|
||||
import {
|
||||
IdPositions,
|
||||
PositionElement,
|
||||
TextNode,
|
||||
UsePaginationReturnTuple,
|
||||
} from "~/types/usePagination";
|
||||
import { loadPages, savePages } from "~/utils/localStorage";
|
||||
|
||||
const isTextNode = (el: Node): el is TextNode => el.nodeType === Node.TEXT_NODE;
|
||||
const isElementNode = (el: Node): el is HTMLElement =>
|
||||
@ -18,6 +16,7 @@ export const usePagination = (
|
||||
contentEl: React.RefObject<HTMLDivElement>,
|
||||
pageContainerEl: React.RefObject<HTMLDivElement>,
|
||||
pageEl: React.RefObject<HTMLDivElement>,
|
||||
hash?: string,
|
||||
bookContent?: string
|
||||
): UsePaginationReturnTuple => {
|
||||
const [ready, setReady] = useState(false);
|
||||
@ -57,7 +56,11 @@ export const usePagination = (
|
||||
setIdPositions(idPositions);
|
||||
};
|
||||
|
||||
const findPages = async (page: HTMLElement, pageContainer: HTMLElement) => {
|
||||
const findPages = async (
|
||||
hash: string,
|
||||
page: HTMLElement,
|
||||
pageContainer: HTMLElement
|
||||
) => {
|
||||
const pages = [];
|
||||
pages.push(0);
|
||||
let jump = 100;
|
||||
@ -79,6 +82,7 @@ export const usePagination = (
|
||||
|
||||
setPages(pages);
|
||||
setCurrentPage(0);
|
||||
savePages(hash, window.innerHeight, window.innerWidth, pages);
|
||||
};
|
||||
|
||||
const findPage = (
|
||||
@ -216,16 +220,17 @@ export const usePagination = (
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (contentEl.current && bookContent) {
|
||||
if (contentEl.current && hash && bookContent) {
|
||||
contentEl.current.innerHTML = bookContent;
|
||||
computeStartPositionsOfElements(contentEl.current);
|
||||
}
|
||||
}, [bookContent]);
|
||||
}, [hash, bookContent]);
|
||||
|
||||
useEffect(() => {
|
||||
if (positions.length && pageEl.current && pageContainerEl.current)
|
||||
findPages(pageEl.current, pageContainerEl.current);
|
||||
}, [positions, idPositions]);
|
||||
if (hash && positions.length && pageEl.current && pageContainerEl.current)
|
||||
if (!loadPages(hash, window.innerHeight, window.innerWidth, setPages))
|
||||
findPages(hash, pageEl.current, pageContainerEl.current);
|
||||
}, [hash, positions, idPositions]);
|
||||
|
||||
useEffect(() => {
|
||||
if (pageEl.current && pages.length && !ready)
|
||||
@ -235,7 +240,7 @@ export const usePagination = (
|
||||
const makeDisplayPage = (page: React.RefObject<HTMLDivElement>) => {
|
||||
if (page.current)
|
||||
return (pageNum: number) => displayPage(pageNum, page.current!);
|
||||
else return (pageNum: number) => {};
|
||||
else return () => {};
|
||||
};
|
||||
|
||||
return [ready, makeDisplayPage(pageEl), currentPage, pages.length - 1];
|
||||
|
@ -21,6 +21,7 @@ export const BookView = ({ setLoading, loading }: IPageProps) => {
|
||||
contentRef,
|
||||
pageContainerRef,
|
||||
pageRef,
|
||||
books && loading ? params?.hash : undefined,
|
||||
params?.hash && books && loading ? books[params.hash]?.content : undefined
|
||||
);
|
||||
|
||||
|
9
src/types/usePagination.ts
Normal file
9
src/types/usePagination.ts
Normal file
@ -0,0 +1,9 @@
|
||||
export type TextNode = Text & { nodeValue: string };
|
||||
export type PositionElement = [number, TextNode];
|
||||
export type IdPositions = Record<string, number>;
|
||||
export type UsePaginationReturnTuple = [
|
||||
ready: boolean,
|
||||
goToPage: (pageNum: number) => void,
|
||||
currentPage: number,
|
||||
pageNumber: number
|
||||
];
|
@ -5,3 +5,13 @@ export const isArrOfStr = (obj: unknown): obj is string[] => {
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const isObject = (obj: unknown): obj is Record<string, unknown> => {
|
||||
if (obj && typeof obj === "object" && !Array.isArray(obj)) {
|
||||
for (const key of Object.keys(obj))
|
||||
if (typeof key !== "string") return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
@ -29,3 +29,41 @@ export const saveBook = (key: string, book: IBook) =>
|
||||
|
||||
export const updateHashList = (hashList: string[]) =>
|
||||
localStorage.setItem("list", JSON.stringify(hashList));
|
||||
|
||||
const validatePages = (obj: unknown): obj is number[] => {
|
||||
if (obj && Array.isArray(obj)) {
|
||||
for (const el of obj) if (typeof el !== "number") return false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const hashStr = (hash: string, height: number, width: number) =>
|
||||
`pages-${hash}-${height}-${width}`;
|
||||
|
||||
export const loadPages = (
|
||||
hash: string,
|
||||
height: number,
|
||||
width: number,
|
||||
cb: (pages: number[]) => void
|
||||
) => {
|
||||
const str = localStorage.getItem(hashStr(hash, height, width));
|
||||
|
||||
if (str) {
|
||||
const obj: unknown = JSON.parse(str);
|
||||
|
||||
if (validatePages(obj)) {
|
||||
cb(obj);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
export const savePages = (
|
||||
hash: string,
|
||||
height: number,
|
||||
width: number,
|
||||
pages: number[]
|
||||
) => localStorage.setItem(hashStr(hash, height, width), JSON.stringify(pages));
|
||||
|
Loading…
x
Reference in New Issue
Block a user