Archived
fix: pdf bookmark
for pdfs only select pages not text
This commit is contained in:
@@ -1,37 +0,0 @@
|
||||
import { useEffect, useMemo } from "react";
|
||||
import { useAnnotations } from "@/context/AnnotationsContext";
|
||||
import { isPdfAnchor, parsePdfAnchor } from "@/utils/pdfAnchor";
|
||||
import { normalizeHighlightColor } from "@/constants/bookmarkHighlightColors";
|
||||
|
||||
export interface PdfPageHighlight {
|
||||
rects: [number, number, number, number][];
|
||||
color: string;
|
||||
}
|
||||
|
||||
export function usePdfHighlights(ebookId: number, currentPage: number): PdfPageHighlight[] {
|
||||
const { markers, loadBookmarks } = useAnnotations();
|
||||
|
||||
const bookMarkers = useMemo(
|
||||
() => markers.filter((m) => m.ebook_id === ebookId),
|
||||
[markers, ebookId],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (!ebookId || Number.isNaN(ebookId)) return;
|
||||
void loadBookmarks(ebookId);
|
||||
}, [ebookId, loadBookmarks]);
|
||||
|
||||
return useMemo(() => {
|
||||
const highlights: PdfPageHighlight[] = [];
|
||||
for (const marker of bookMarkers) {
|
||||
if (!isPdfAnchor(marker.epub_cfi)) continue;
|
||||
const parsed = parsePdfAnchor(marker.epub_cfi);
|
||||
if (!parsed || parsed.page !== currentPage || !parsed.rects.length) continue;
|
||||
highlights.push({
|
||||
rects: parsed.rects,
|
||||
color: normalizeHighlightColor(marker.highlight_color),
|
||||
});
|
||||
}
|
||||
return highlights;
|
||||
}, [bookMarkers, currentPage]);
|
||||
}
|
||||
@@ -26,7 +26,6 @@ export interface UsePdfReaderReturn {
|
||||
error: string | null;
|
||||
isBookmarkPeekActive: boolean;
|
||||
readingAnchor: PdfReadingAnchor | null;
|
||||
pageWrapRef: React.RefObject<HTMLDivElement | null>;
|
||||
goToPage: (page: number) => void;
|
||||
goToNextPage: () => void;
|
||||
goToPrevPage: () => void;
|
||||
@@ -55,7 +54,6 @@ export function usePdfReader(
|
||||
const [isBookmarkPeekActive, setIsBookmarkPeekActive] = useState(false);
|
||||
const [readingAnchor, setReadingAnchor] = useState<PdfReadingAnchor | null>(null);
|
||||
|
||||
const pageWrapRef = useRef<HTMLDivElement | null>(null);
|
||||
const debounceTimer = useRef<ReturnType<typeof setTimeout> | null>(null);
|
||||
const isBookmarkPeekRef = useRef(false);
|
||||
const readingAnchorRef = useRef<PdfReadingAnchor | null>(null);
|
||||
@@ -247,7 +245,6 @@ export function usePdfReader(
|
||||
error,
|
||||
isBookmarkPeekActive,
|
||||
readingAnchor,
|
||||
pageWrapRef,
|
||||
goToPage,
|
||||
goToNextPage,
|
||||
goToPrevPage,
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import type { PendingSelection } from "./useEpubSelection";
|
||||
import { rectsFromSelection, serializePdfAnchor } from "../utils/pdfAnchor";
|
||||
|
||||
export function usePdfSelection(
|
||||
pageWrapRef: React.RefObject<HTMLDivElement | null>,
|
||||
currentPage: number,
|
||||
chapterTitle: string,
|
||||
) {
|
||||
const [pendingSelection, setPendingSelection] = useState<PendingSelection | null>(null);
|
||||
const chapterTitleRef = useRef(chapterTitle);
|
||||
chapterTitleRef.current = chapterTitle;
|
||||
|
||||
const clearSelection = useCallback(() => {
|
||||
setPendingSelection(null);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const wrap = pageWrapRef.current;
|
||||
if (!wrap) return;
|
||||
|
||||
const handler = () => {
|
||||
window.setTimeout(() => {
|
||||
const sel = window.getSelection();
|
||||
const text = sel?.toString()?.trim() ?? "";
|
||||
if (!text || !sel || sel.rangeCount === 0) {
|
||||
setPendingSelection(null);
|
||||
return;
|
||||
}
|
||||
|
||||
const range = sel.getRangeAt(0);
|
||||
if (!wrap.contains(range.commonAncestorContainer)) {
|
||||
setPendingSelection(null);
|
||||
return;
|
||||
}
|
||||
|
||||
const rects = rectsFromSelection(range, wrap);
|
||||
const anchor = serializePdfAnchor(currentPage, rects.length > 0 ? rects : undefined);
|
||||
const rect = range.getBoundingClientRect();
|
||||
|
||||
setPendingSelection({
|
||||
epubCfi: anchor,
|
||||
locationText: text.slice(0, 2000),
|
||||
chapterIndex: currentPage - 1,
|
||||
chapterTitle: chapterTitleRef.current,
|
||||
anchorTop: rect.bottom + 8,
|
||||
anchorLeft: Math.min(rect.left, window.innerWidth - 280),
|
||||
});
|
||||
}, 10);
|
||||
};
|
||||
|
||||
wrap.addEventListener("mouseup", handler);
|
||||
return () => wrap.removeEventListener("mouseup", handler);
|
||||
}, [pageWrapRef, currentPage]);
|
||||
|
||||
return { pendingSelection, clearSelection };
|
||||
}
|
||||
Reference in New Issue
Block a user