Added pages cache

This commit is contained in:
Dmitriy Shishkov 2021-07-16 19:24:37 +05:00
parent 620852b536
commit a3d24c373c
No known key found for this signature in database
GPG Key ID: 14358F96FCDD8060
5 changed files with 79 additions and 16 deletions

View File

@ -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];

View File

@ -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
);

View 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
];

View File

@ -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;
};

View File

@ -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));