forked from akai/readest
a2d17e6a79
The sidebar delete handler always removed annotations through the note bubble overlay key (`NOTE_PREFIX + cfi`), but highlights are keyed by the raw CFI. Deleting a highlight from the sidebar therefore left its overlay drawn until the book was reopened, while the popup path — which lets `wrappedFoliateView` default the value to the CFI — worked. Introduce `removeBookNoteOverlays` that mirrors the draw filters in `Annotator.tsx` and clears every overlay a BookNote can own (highlight and/or note bubble), and route the sidebar delete through it. Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
89 lines
3.2 KiB
TypeScript
89 lines
3.2 KiB
TypeScript
import { HIGHLIGHT_COLOR_HEX } from '@/services/constants';
|
|
import { BookNote, DEFAULT_HIGHLIGHT_COLORS, HighlightColor } from '@/types/book';
|
|
import { SystemSettings } from '@/types/settings';
|
|
import { FoliateView, NOTE_PREFIX } from '@/types/view';
|
|
import { Point } from '@/utils/sel';
|
|
|
|
export const isDefaultHighlightColor = (
|
|
color: HighlightColor,
|
|
): color is (typeof DEFAULT_HIGHLIGHT_COLORS)[number] => {
|
|
return (DEFAULT_HIGHLIGHT_COLORS as readonly string[]).includes(color);
|
|
};
|
|
|
|
export const getHighlightColorHex = (
|
|
settings: SystemSettings,
|
|
color?: HighlightColor,
|
|
): string | undefined => {
|
|
if (!color) return undefined;
|
|
if (color.startsWith('#')) return color;
|
|
const customColors = settings.globalReadSettings.customHighlightColors;
|
|
return customColors?.[color] ?? HIGHLIGHT_COLOR_HEX[color];
|
|
};
|
|
|
|
/**
|
|
* Returns a user-defined label for the given color, or `undefined` when none is set.
|
|
* Callers that want to fall back to a translated default name should handle that in
|
|
* the component layer (where `useTranslation` is available).
|
|
*/
|
|
export const getHighlightColorLabel = (
|
|
settings: SystemSettings,
|
|
color: HighlightColor,
|
|
): string | undefined => {
|
|
const { defaultHighlightLabels, userHighlightColors } = settings.globalReadSettings;
|
|
if (color.startsWith('#')) {
|
|
const hex = color.trim().toLowerCase();
|
|
const entry = userHighlightColors?.find((c) => c.hex === hex);
|
|
return entry?.label?.trim() || undefined;
|
|
}
|
|
if (isDefaultHighlightColor(color)) {
|
|
return defaultHighlightLabels?.[color]?.trim() || undefined;
|
|
}
|
|
return undefined;
|
|
};
|
|
|
|
export function getExternalDragHandle(
|
|
currentStart: Point,
|
|
currentEnd: Point,
|
|
externalDragPoint?: Point | null,
|
|
): 'start' | 'end' | null {
|
|
if (!externalDragPoint) return null;
|
|
const distToStart = Math.hypot(
|
|
externalDragPoint.x - currentStart.x,
|
|
externalDragPoint.y - currentStart.y,
|
|
);
|
|
const distToEnd = Math.hypot(
|
|
externalDragPoint.x - currentEnd.x,
|
|
externalDragPoint.y - currentEnd.y,
|
|
);
|
|
return distToStart < distToEnd ? 'start' : 'end';
|
|
}
|
|
|
|
export function toParentViewportPoint(doc: Document, x: number, y: number): Point {
|
|
const frameElement = doc.defaultView?.frameElement;
|
|
const frameRect = frameElement?.getBoundingClientRect() ?? { top: 0, left: 0 };
|
|
return { x: x + frameRect.left, y: y + frameRect.top };
|
|
}
|
|
|
|
/**
|
|
* Remove any overlays drawn for a BookNote from the given view.
|
|
*
|
|
* A single BookNote can have up to two overlays attached:
|
|
* - a highlight/underline/squiggly overlay (keyed by the raw CFI)
|
|
* - a note bubble overlay (keyed by `${NOTE_PREFIX}${cfi}`)
|
|
*
|
|
* The set of overlays drawn is defined by the progress-sync effect in
|
|
* Annotator.tsx, and this helper mirrors those filters so that deleting
|
|
* an annotation from the sidebar clears every overlay that was drawn
|
|
* for it, not just the note bubble.
|
|
*/
|
|
export function removeBookNoteOverlays(view: FoliateView | null, note: BookNote): void {
|
|
if (!view) return;
|
|
if (note.type !== 'annotation') return;
|
|
if (note.style) {
|
|
view.addAnnotation({ ...note, value: note.cfi }, true);
|
|
}
|
|
if (note.note && note.note.trim().length > 0) {
|
|
view.addAnnotation({ ...note, value: `${NOTE_PREFIX}${note.cfi}` }, true);
|
|
}
|
|
}
|