forked from akai/readest
This commit is contained in:
@@ -35,6 +35,7 @@ import {
|
||||
} from '@/utils/style';
|
||||
import { mountAdditionalFonts, mountCustomFont } from '@/styles/fonts';
|
||||
import { getBookDirFromLanguage, getBookDirFromWritingMode } from '@/utils/book';
|
||||
import { getIndexFromCfi } from '@/utils/cfi';
|
||||
import { useUICSS } from '@/hooks/useUICSS';
|
||||
import {
|
||||
handleKeydown,
|
||||
@@ -253,9 +254,16 @@ const FoliateViewer: React.FC<{
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
const sectionIndex = detail.index;
|
||||
const booknotes = config.booknotes || [];
|
||||
booknotes
|
||||
.filter((item) => !item.deletedAt && item.type === 'annotation' && item.style)
|
||||
.filter(
|
||||
(item) =>
|
||||
!item.deletedAt &&
|
||||
item.type === 'annotation' &&
|
||||
item.style &&
|
||||
getIndexFromCfi(item.cfi) === sectionIndex,
|
||||
)
|
||||
.forEach((annotation) => viewRef.current?.addAnnotation(annotation));
|
||||
}, 100);
|
||||
|
||||
|
||||
@@ -9,7 +9,11 @@ import { useReaderStore } from '@/store/readerStore';
|
||||
import { useSettingsStore } from '@/store/settingsStore';
|
||||
import { useResponsiveSize } from '@/hooks/useResponsiveSize';
|
||||
import { useAnnotationEditor } from '../../hooks/useAnnotationEditor';
|
||||
import { getHighlightColorHex } from '../../utils/annotatorUtil';
|
||||
import {
|
||||
getEffectiveLoupePoint,
|
||||
getExternalDragHandle,
|
||||
getHighlightColorHex,
|
||||
} from '../../utils/annotatorUtil';
|
||||
import MagnifierLoupe from './MagnifierLoupe';
|
||||
|
||||
interface HandleProps {
|
||||
@@ -136,6 +140,7 @@ interface AnnotationRangeEditorProps {
|
||||
annotation: BookNote;
|
||||
selection: TextSelection;
|
||||
handleColor: HighlightColor;
|
||||
externalDragPoint?: Point | null;
|
||||
getAnnotationText: (range: Range) => Promise<string>;
|
||||
setSelection: React.Dispatch<React.SetStateAction<TextSelection | null>>;
|
||||
onStartEdit: () => void;
|
||||
@@ -147,6 +152,7 @@ const AnnotationRangeEditor: React.FC<AnnotationRangeEditorProps> = ({
|
||||
annotation,
|
||||
selection,
|
||||
handleColor,
|
||||
externalDragPoint,
|
||||
getAnnotationText,
|
||||
setSelection,
|
||||
onStartEdit,
|
||||
@@ -247,12 +253,17 @@ const AnnotationRangeEditor: React.FC<AnnotationRangeEditorProps> = ({
|
||||
return null;
|
||||
}
|
||||
|
||||
const showLoupe = loupePoint !== null && appService?.isMobile && !viewSettings?.vertical;
|
||||
const effectiveLoupePoint = getEffectiveLoupePoint(loupePoint, externalDragPoint);
|
||||
const activeHandle =
|
||||
draggingHandle ??
|
||||
(externalDragPoint ? getExternalDragHandle(externalDragPoint, currentStart, currentEnd) : null);
|
||||
|
||||
const showLoupe = effectiveLoupePoint !== null && appService?.isMobile && !viewSettings?.vertical;
|
||||
|
||||
return (
|
||||
<div className='pointer-events-none fixed inset-0 z-50'>
|
||||
<Handle
|
||||
hidden={draggingHandle === 'end'}
|
||||
hidden={activeHandle === 'end'}
|
||||
position={currentStart}
|
||||
isVertical={isVertical}
|
||||
type='start'
|
||||
@@ -262,7 +273,7 @@ const AnnotationRangeEditor: React.FC<AnnotationRangeEditorProps> = ({
|
||||
onDragEnd={handleDragEnd}
|
||||
/>
|
||||
<Handle
|
||||
hidden={draggingHandle === 'start'}
|
||||
hidden={activeHandle === 'start'}
|
||||
position={currentEnd}
|
||||
isVertical={isVertical}
|
||||
type='end'
|
||||
@@ -271,10 +282,10 @@ const AnnotationRangeEditor: React.FC<AnnotationRangeEditorProps> = ({
|
||||
onDrag={handleEndDrag}
|
||||
onDragEnd={handleDragEnd}
|
||||
/>
|
||||
{showLoupe && (
|
||||
{showLoupe && effectiveLoupePoint && (
|
||||
<MagnifierLoupe
|
||||
bookKey={bookKey}
|
||||
dragPoint={loupePoint}
|
||||
dragPoint={effectiveLoupePoint}
|
||||
isVertical={isVertical}
|
||||
color={handleColorHex}
|
||||
/>
|
||||
|
||||
@@ -20,7 +20,7 @@ import { useFoliateEvents } from '../../hooks/useFoliateEvents';
|
||||
import { useNotesSync } from '../../hooks/useNotesSync';
|
||||
import { useReadwiseSync } from '../../hooks/useReadwiseSync';
|
||||
import { useTextSelector } from '../../hooks/useTextSelector';
|
||||
import { Position, TextSelection } from '@/utils/sel';
|
||||
import { Point, Position, TextSelection } from '@/utils/sel';
|
||||
import { getPopupPosition, getPosition, getTextFromRange } from '@/utils/sel';
|
||||
import { eventDispatcher } from '@/utils/event';
|
||||
import { findTocItemBS } from '@/utils/toc';
|
||||
@@ -79,6 +79,7 @@ const Annotator: React.FC<{ bookKey: string }> = ({ bookKey }) => {
|
||||
const [showAnnotationNotes, setShowAnnotationNotes] = useState(false);
|
||||
const [annotationNotes, setAnnotationNotes] = useState<BookNote[]>([]);
|
||||
const [editingAnnotation, setEditingAnnotation] = useState<BookNote | null>(null);
|
||||
const [externalDragPoint, setExternalDragPoint] = useState<Point | null>(null);
|
||||
const [showExportDialog, setShowExportDialog] = useState(false);
|
||||
const [exportData, setExportData] = useState<{
|
||||
booknotes: BookNote[];
|
||||
@@ -207,6 +208,7 @@ const Annotator: React.FC<{ bookKey: string }> = ({ bookKey }) => {
|
||||
|
||||
const {
|
||||
isTextSelected,
|
||||
isInstantAnnotating,
|
||||
handleScroll,
|
||||
handleTouchStart,
|
||||
handleTouchMove,
|
||||
@@ -219,7 +221,14 @@ const Annotator: React.FC<{ bookKey: string }> = ({ bookKey }) => {
|
||||
handleShowPopup,
|
||||
handleUpToPopup,
|
||||
handleContextmenu,
|
||||
} = useTextSelector(bookKey, setSelection, getAnnotationText, handleDismissPopup);
|
||||
} = useTextSelector(
|
||||
bookKey,
|
||||
setSelection,
|
||||
setEditingAnnotation,
|
||||
setExternalDragPoint,
|
||||
getAnnotationText,
|
||||
handleDismissPopup,
|
||||
);
|
||||
|
||||
const handleDismissPopupAndSelection = () => {
|
||||
handleDismissPopup();
|
||||
@@ -235,7 +244,9 @@ const Annotator: React.FC<{ bookKey: string }> = ({ bookKey }) => {
|
||||
// Available on iOS, on Android not fired
|
||||
// To make the popup not follow the selection while dragging
|
||||
setShowAnnotPopup(false);
|
||||
setEditingAnnotation(null);
|
||||
if (!isInstantAnnotating.current) {
|
||||
setEditingAnnotation(null);
|
||||
}
|
||||
handleTouchMove(ev);
|
||||
};
|
||||
|
||||
@@ -1003,6 +1014,7 @@ const Annotator: React.FC<{ bookKey: string }> = ({ bookKey }) => {
|
||||
annotation={editingAnnotation}
|
||||
selection={selection}
|
||||
handleColor={selectedColor}
|
||||
externalDragPoint={externalDragPoint}
|
||||
getAnnotationText={getAnnotationText}
|
||||
setSelection={setSelection}
|
||||
onStartEdit={handleStartEditAnnotation}
|
||||
|
||||
@@ -18,14 +18,31 @@ const MagnifierLoupe: React.FC<MagnifierLoupeProps> = ({
|
||||
color,
|
||||
}) => {
|
||||
const { getView } = useReaderStore();
|
||||
const radius = useResponsiveSize(52);
|
||||
const gap = useResponsiveSize(22);
|
||||
const margin = useResponsiveSize(8);
|
||||
const radius = useResponsiveSize(28);
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
const view = getView(bookKey);
|
||||
view?.renderer.hideLoupe?.();
|
||||
};
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [bookKey]);
|
||||
|
||||
// Update loupe position on every drag move (fast path — no DOM recreation).
|
||||
useEffect(() => {
|
||||
const view = getView(bookKey);
|
||||
if (!view) return;
|
||||
view.renderer.showLoupe?.(dragPoint.x, dragPoint.y, { isVertical, color, radius });
|
||||
return () => view.renderer.hideLoupe?.();
|
||||
}, [bookKey, dragPoint, getView, isVertical, color, radius]);
|
||||
view.renderer.showLoupe?.(dragPoint.x, dragPoint.y, {
|
||||
isVertical,
|
||||
color,
|
||||
gap,
|
||||
margin,
|
||||
radius,
|
||||
magnification: 1.1,
|
||||
});
|
||||
}, [bookKey, dragPoint, getView, isVertical, color, radius, gap, margin]);
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user