Archived
feat: floating bookmarks
add floating bookmarks
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
import { useMemo } from "react";
|
||||
import type { MarkerEntry } from "@/types";
|
||||
import { layoutBookmarkRail, type BookmarkRailItem } from "@/utils/bookmarkRailLayout";
|
||||
|
||||
export function useBookmarkRailLayout(markers: MarkerEntry[]): BookmarkRailItem[] {
|
||||
return useMemo(() => layoutBookmarkRail(markers), [markers]);
|
||||
}
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
applyRenditionSettings,
|
||||
isEpubCfi,
|
||||
marginWidthToGap,
|
||||
percentageFromCfi,
|
||||
resolveSpineHref,
|
||||
updateChapterTitleFromRendition,
|
||||
type EpubRendition,
|
||||
@@ -28,13 +29,6 @@ export interface ReadingAnchor {
|
||||
percentage: number;
|
||||
}
|
||||
|
||||
function percentageFromCfi(rendition: EpubRendition, cfi: string): number {
|
||||
if (!rendition.book?.locations) return 0;
|
||||
const pct = rendition.book.locations.percentageFromCfi(cfi);
|
||||
if (pct === null || pct === undefined) return 0;
|
||||
return Math.round(pct * 100);
|
||||
}
|
||||
|
||||
function cfiFromRendition(rendition: EpubRendition | null): string | null {
|
||||
if (!rendition) return null;
|
||||
const start = (rendition as EpubRendition & { location?: { start?: { cfi?: string } } }).location
|
||||
@@ -157,7 +151,7 @@ export function useEpubReader(
|
||||
cfi = cfiFromRendition(rendition);
|
||||
}
|
||||
if (!cfi) return null;
|
||||
const percentage = rendition ? percentageFromCfi(rendition, cfi) : 0;
|
||||
const percentage = rendition ? (percentageFromCfi(rendition, cfi) ?? 0) : 0;
|
||||
return { cfi, percentage };
|
||||
}, [location]);
|
||||
|
||||
@@ -187,7 +181,7 @@ export function useEpubReader(
|
||||
|
||||
setLocation(anchor.cfi);
|
||||
const rendition = renditionRef.current;
|
||||
const pct = rendition ? percentageFromCfi(rendition, anchor.cfi) : anchor.percentage;
|
||||
const pct = rendition ? (percentageFromCfi(rendition, anchor.cfi) ?? anchor.percentage) : anchor.percentage;
|
||||
void flushProgress(anchor.cfi, pct > 0 ? pct : anchor.percentage);
|
||||
}, [clearPeekState, flushProgress]);
|
||||
|
||||
@@ -267,7 +261,7 @@ export function useEpubReader(
|
||||
if (!isEpubCfi(loc)) return;
|
||||
|
||||
const rendition = renditionRef.current;
|
||||
const percentage = rendition ? percentageFromCfi(rendition, loc) : 0;
|
||||
const percentage = rendition ? (percentageFromCfi(rendition, loc) ?? 0) : 0;
|
||||
|
||||
if (rendition) {
|
||||
void updateChapterTitleFromRendition(rendition).then((title) => {
|
||||
@@ -306,7 +300,7 @@ export function useEpubReader(
|
||||
const cfi = start?.cfi;
|
||||
if (!cfi || !isEpubCfi(cfi)) return;
|
||||
|
||||
const percentage = percentageFromCfi(rendition, cfi);
|
||||
const percentage = percentageFromCfi(rendition, cfi) ?? 0;
|
||||
void flushProgress(cfi, percentage);
|
||||
|
||||
if (percentage <= 0 && attempt < 2) {
|
||||
|
||||
Reference in New Issue
Block a user