Added pages cache
This commit is contained in:
parent
620852b536
commit
a3d24c373c
@ -1,14 +1,12 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
|
|
||||||
type TextNode = Text & { nodeValue: string };
|
import {
|
||||||
type PositionElement = [number, TextNode];
|
IdPositions,
|
||||||
type IdPositions = Record<string, number>;
|
PositionElement,
|
||||||
type UsePaginationReturnTuple = [
|
TextNode,
|
||||||
ready: boolean,
|
UsePaginationReturnTuple,
|
||||||
goToPage: (pageNum: number) => void,
|
} from "~/types/usePagination";
|
||||||
currentPage: number,
|
import { loadPages, savePages } from "~/utils/localStorage";
|
||||||
pageNumber: number
|
|
||||||
];
|
|
||||||
|
|
||||||
const isTextNode = (el: Node): el is TextNode => el.nodeType === Node.TEXT_NODE;
|
const isTextNode = (el: Node): el is TextNode => el.nodeType === Node.TEXT_NODE;
|
||||||
const isElementNode = (el: Node): el is HTMLElement =>
|
const isElementNode = (el: Node): el is HTMLElement =>
|
||||||
@ -18,6 +16,7 @@ export const usePagination = (
|
|||||||
contentEl: React.RefObject<HTMLDivElement>,
|
contentEl: React.RefObject<HTMLDivElement>,
|
||||||
pageContainerEl: React.RefObject<HTMLDivElement>,
|
pageContainerEl: React.RefObject<HTMLDivElement>,
|
||||||
pageEl: React.RefObject<HTMLDivElement>,
|
pageEl: React.RefObject<HTMLDivElement>,
|
||||||
|
hash?: string,
|
||||||
bookContent?: string
|
bookContent?: string
|
||||||
): UsePaginationReturnTuple => {
|
): UsePaginationReturnTuple => {
|
||||||
const [ready, setReady] = useState(false);
|
const [ready, setReady] = useState(false);
|
||||||
@ -57,7 +56,11 @@ export const usePagination = (
|
|||||||
setIdPositions(idPositions);
|
setIdPositions(idPositions);
|
||||||
};
|
};
|
||||||
|
|
||||||
const findPages = async (page: HTMLElement, pageContainer: HTMLElement) => {
|
const findPages = async (
|
||||||
|
hash: string,
|
||||||
|
page: HTMLElement,
|
||||||
|
pageContainer: HTMLElement
|
||||||
|
) => {
|
||||||
const pages = [];
|
const pages = [];
|
||||||
pages.push(0);
|
pages.push(0);
|
||||||
let jump = 100;
|
let jump = 100;
|
||||||
@ -79,6 +82,7 @@ export const usePagination = (
|
|||||||
|
|
||||||
setPages(pages);
|
setPages(pages);
|
||||||
setCurrentPage(0);
|
setCurrentPage(0);
|
||||||
|
savePages(hash, window.innerHeight, window.innerWidth, pages);
|
||||||
};
|
};
|
||||||
|
|
||||||
const findPage = (
|
const findPage = (
|
||||||
@ -216,16 +220,17 @@ export const usePagination = (
|
|||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (contentEl.current && bookContent) {
|
if (contentEl.current && hash && bookContent) {
|
||||||
contentEl.current.innerHTML = bookContent;
|
contentEl.current.innerHTML = bookContent;
|
||||||
computeStartPositionsOfElements(contentEl.current);
|
computeStartPositionsOfElements(contentEl.current);
|
||||||
}
|
}
|
||||||
}, [bookContent]);
|
}, [hash, bookContent]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (positions.length && pageEl.current && pageContainerEl.current)
|
if (hash && positions.length && pageEl.current && pageContainerEl.current)
|
||||||
findPages(pageEl.current, pageContainerEl.current);
|
if (!loadPages(hash, window.innerHeight, window.innerWidth, setPages))
|
||||||
}, [positions, idPositions]);
|
findPages(hash, pageEl.current, pageContainerEl.current);
|
||||||
|
}, [hash, positions, idPositions]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (pageEl.current && pages.length && !ready)
|
if (pageEl.current && pages.length && !ready)
|
||||||
@ -235,7 +240,7 @@ export const usePagination = (
|
|||||||
const makeDisplayPage = (page: React.RefObject<HTMLDivElement>) => {
|
const makeDisplayPage = (page: React.RefObject<HTMLDivElement>) => {
|
||||||
if (page.current)
|
if (page.current)
|
||||||
return (pageNum: number) => displayPage(pageNum, page.current!);
|
return (pageNum: number) => displayPage(pageNum, page.current!);
|
||||||
else return (pageNum: number) => {};
|
else return () => {};
|
||||||
};
|
};
|
||||||
|
|
||||||
return [ready, makeDisplayPage(pageEl), currentPage, pages.length - 1];
|
return [ready, makeDisplayPage(pageEl), currentPage, pages.length - 1];
|
||||||
|
@ -21,6 +21,7 @@ export const BookView = ({ setLoading, loading }: IPageProps) => {
|
|||||||
contentRef,
|
contentRef,
|
||||||
pageContainerRef,
|
pageContainerRef,
|
||||||
pageRef,
|
pageRef,
|
||||||
|
books && loading ? params?.hash : undefined,
|
||||||
params?.hash && books && loading ? books[params.hash]?.content : 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;
|
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[]) =>
|
export const updateHashList = (hashList: string[]) =>
|
||||||
localStorage.setItem("list", JSON.stringify(hashList));
|
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