@papyrus-sdk/ui-react-native 0.2.11 → 0.2.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +12 -2
- package/dist/chunk-GCVUTXFR.mjs +63 -0
- package/dist/chunk-GCVUTXFR.mjs.map +1 -0
- package/dist/chunk-PE5U4ZWV.mjs +101 -0
- package/dist/chunk-PE5U4ZWV.mjs.map +1 -0
- package/dist/chunk-ZD7AOCMD.mjs +9 -0
- package/dist/chunk-ZD7AOCMD.mjs.map +1 -0
- package/dist/gesture/pinchZoom.js +135 -0
- package/dist/gesture/pinchZoom.js.map +1 -0
- package/dist/gesture/pinchZoom.mjs +30 -0
- package/dist/gesture/pinchZoom.mjs.map +1 -0
- package/dist/gesture/selectionInteraction.js +90 -0
- package/dist/gesture/selectionInteraction.js.map +1 -0
- package/dist/gesture/selectionInteraction.mjs +16 -0
- package/dist/gesture/selectionInteraction.mjs.map +1 -0
- package/dist/index.d.mts +11 -73
- package/dist/index.d.ts +11 -73
- package/dist/index.js +1284 -287
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1172 -280
- package/dist/index.mjs.map +1 -1
- package/package.json +9 -7
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import {
|
|
2
|
+
DEFAULT_PINCH_ZOOM_BOUNDS,
|
|
3
|
+
resolveAnchoredViewportOffset,
|
|
4
|
+
resolveClampedScrollOffset,
|
|
5
|
+
resolvePinchGestureZoom,
|
|
6
|
+
resolvePinchPreviewScale,
|
|
7
|
+
sanitizePinchPreviewScale,
|
|
8
|
+
shouldSuppressPressAfterPinch
|
|
9
|
+
} from "./chunk-PE5U4ZWV.mjs";
|
|
10
|
+
import {
|
|
11
|
+
getSelectionEdgeAutoscroll,
|
|
12
|
+
getToolDockDismissState,
|
|
13
|
+
isToolDockToolSelected,
|
|
14
|
+
shouldEnableSelectionDrag,
|
|
15
|
+
shouldEnableViewerScroll
|
|
16
|
+
} from "./chunk-GCVUTXFR.mjs";
|
|
17
|
+
import {
|
|
18
|
+
__commonJS
|
|
19
|
+
} from "./chunk-ZD7AOCMD.mjs";
|
|
5
20
|
|
|
6
21
|
// runtime/index.html
|
|
7
22
|
var require_runtime = __commonJS({
|
|
@@ -21004,6 +21019,7 @@ import {
|
|
|
21004
21019
|
View as View3,
|
|
21005
21020
|
useWindowDimensions as useWindowDimensions2
|
|
21006
21021
|
} from "react-native";
|
|
21022
|
+
import { Gesture as Gesture2, GestureDetector as GestureDetector2 } from "react-native-gesture-handler";
|
|
21007
21023
|
import { useViewerStore as useViewerStore3 } from "@papyrus-sdk/core";
|
|
21008
21024
|
|
|
21009
21025
|
// components/PageRenderer.tsx
|
|
@@ -21025,6 +21041,7 @@ import {
|
|
|
21025
21041
|
findNodeHandle,
|
|
21026
21042
|
useWindowDimensions
|
|
21027
21043
|
} from "react-native";
|
|
21044
|
+
import { Gesture, GestureDetector } from "react-native-gesture-handler";
|
|
21028
21045
|
import Svg, { Path as SvgPath } from "react-native-svg";
|
|
21029
21046
|
import { useViewerStore } from "@papyrus-sdk/core";
|
|
21030
21047
|
import {
|
|
@@ -21275,6 +21292,9 @@ var buildSquigglyPath = (segments = 16) => {
|
|
|
21275
21292
|
return path;
|
|
21276
21293
|
};
|
|
21277
21294
|
var SQUIGGLY_PATH = buildSquigglyPath();
|
|
21295
|
+
var SELECTION_EDGE_THRESHOLD_PX = 48;
|
|
21296
|
+
var SELECTION_EDGE_MAX_STEP_PX = 24;
|
|
21297
|
+
var SELECTION_AUTOSCROLL_INTERVAL_MS = 16;
|
|
21278
21298
|
var PageRenderer = ({
|
|
21279
21299
|
engine,
|
|
21280
21300
|
pageIndex,
|
|
@@ -21282,26 +21302,37 @@ var PageRenderer = ({
|
|
|
21282
21302
|
PageViewComponent = PapyrusPageView,
|
|
21283
21303
|
availableWidth,
|
|
21284
21304
|
horizontalPadding = 16,
|
|
21285
|
-
spacing = 24
|
|
21305
|
+
spacing = 24,
|
|
21306
|
+
onSelectionDragActiveChange,
|
|
21307
|
+
gestureScrollLockActive = false,
|
|
21308
|
+
lastPinchEndedAt = null,
|
|
21309
|
+
onHorizontalScrollOffsetChange,
|
|
21310
|
+
horizontalScrollRestore = null,
|
|
21311
|
+
requestSelectionVerticalAutoscroll
|
|
21286
21312
|
}) => {
|
|
21287
21313
|
const viewRef = useRef(null);
|
|
21314
|
+
const pageScrollRef = useRef(null);
|
|
21288
21315
|
const [layout, setLayout] = useState({ width: 0, height: 0 });
|
|
21289
21316
|
const [pageSize, setPageSize] = useState(null);
|
|
21290
21317
|
const { width: windowWidth } = useWindowDimensions();
|
|
21291
21318
|
const isNative = Platform.OS === "android" || Platform.OS === "ios";
|
|
21292
21319
|
const perfEnabled = isMobilePerfEnabled();
|
|
21293
21320
|
const renderCountRef = useRef(0);
|
|
21294
|
-
const
|
|
21295
|
-
|
|
21296
|
-
);
|
|
21321
|
+
const inkDrawingActiveRef = useRef(false);
|
|
21322
|
+
const horizontalScrollOffsetRef = useRef(0);
|
|
21323
|
+
const selectionDragActiveRef = useRef(false);
|
|
21324
|
+
const selectionDragPointRef = useRef(null);
|
|
21325
|
+
const lastAppliedHorizontalRestoreRef = useRef(null);
|
|
21326
|
+
const selectionAutoscrollIntervalRef = useRef(null);
|
|
21327
|
+
const rawTouchMoveLoggedAtRef = useRef(0);
|
|
21297
21328
|
const zoom = useViewerStore((state) => state.zoom);
|
|
21298
21329
|
const rotation = useViewerStore((state) => state.rotation);
|
|
21299
21330
|
const pageTheme = useViewerStore((state) => state.pageTheme);
|
|
21300
21331
|
const annotations = useViewerStore((state) => state.annotations);
|
|
21301
21332
|
const annotationColor = useViewerStore((state) => state.annotationColor);
|
|
21302
21333
|
const addAnnotation = useViewerStore((state) => state.addAnnotation);
|
|
21303
|
-
const setDocumentState = useViewerStore((state) => state.setDocumentState);
|
|
21304
21334
|
const activeTool = useViewerStore((state) => state.activeTool);
|
|
21335
|
+
const interactionMode = useViewerStore((state) => state.interactionMode);
|
|
21305
21336
|
const accentColor = useViewerStore((state) => state.accentColor);
|
|
21306
21337
|
const selectedAnnotationId = useViewerStore(
|
|
21307
21338
|
(state) => state.selectedAnnotationId
|
|
@@ -21315,19 +21346,6 @@ var PageRenderer = ({
|
|
|
21315
21346
|
const setSelectionActive = useViewerStore(
|
|
21316
21347
|
(state) => state.setSelectionActive
|
|
21317
21348
|
);
|
|
21318
|
-
const setDocumentStateTracked = useCallback(
|
|
21319
|
-
(state, reason) => {
|
|
21320
|
-
if (perfEnabled) {
|
|
21321
|
-
setStateBurstRef.current({
|
|
21322
|
-
reason,
|
|
21323
|
-
page: pageIndex + 1,
|
|
21324
|
-
keys: Object.keys(state).join(",")
|
|
21325
|
-
});
|
|
21326
|
-
}
|
|
21327
|
-
setDocumentState(state);
|
|
21328
|
-
},
|
|
21329
|
-
[pageIndex, perfEnabled, setDocumentState]
|
|
21330
|
-
);
|
|
21331
21349
|
const logSelectionPerf = useCallback(
|
|
21332
21350
|
(event, payload) => {
|
|
21333
21351
|
if (!perfEnabled) return;
|
|
@@ -21338,6 +21356,56 @@ var PageRenderer = ({
|
|
|
21338
21356
|
},
|
|
21339
21357
|
[pageIndex, perfEnabled]
|
|
21340
21358
|
);
|
|
21359
|
+
const logGestureDebug = useCallback(
|
|
21360
|
+
(event, payload) => {
|
|
21361
|
+
if (!perfEnabled || !isNative) return;
|
|
21362
|
+
logPerfEvent("PageRenderer", `gesture.${event}`, {
|
|
21363
|
+
page: pageIndex + 1,
|
|
21364
|
+
activeTool,
|
|
21365
|
+
interactionMode,
|
|
21366
|
+
pinchActive: gestureScrollLockActive,
|
|
21367
|
+
gestureLockActive: gestureScrollLockActive,
|
|
21368
|
+
selectionEnabled: Platform.OS === "web" || isNative && shouldEnableSelectionDrag({
|
|
21369
|
+
activeTool,
|
|
21370
|
+
interactionMode
|
|
21371
|
+
}),
|
|
21372
|
+
zoom: Math.round(zoom * 100) / 100,
|
|
21373
|
+
...payload
|
|
21374
|
+
});
|
|
21375
|
+
},
|
|
21376
|
+
[activeTool, interactionMode, isNative, pageIndex, perfEnabled, zoom]
|
|
21377
|
+
);
|
|
21378
|
+
const logRawTouchDebug = useCallback(
|
|
21379
|
+
(phase, event) => {
|
|
21380
|
+
if (!perfEnabled || !isNative) return;
|
|
21381
|
+
const touches = Array.isArray(event?.nativeEvent?.touches) ? event.nativeEvent.touches.length : 0;
|
|
21382
|
+
const changedTouches = Array.isArray(event?.nativeEvent?.changedTouches) ? event.nativeEvent.changedTouches.length : 0;
|
|
21383
|
+
if (phase === "move") {
|
|
21384
|
+
if (touches < 2 && !gestureScrollLockActive) return;
|
|
21385
|
+
const now = Date.now();
|
|
21386
|
+
if (now - rawTouchMoveLoggedAtRef.current < 120) return;
|
|
21387
|
+
rawTouchMoveLoggedAtRef.current = now;
|
|
21388
|
+
}
|
|
21389
|
+
logGestureDebug(`touch.${phase}`, {
|
|
21390
|
+
touches,
|
|
21391
|
+
changedTouches,
|
|
21392
|
+
target: event?.nativeEvent?.target ?? null,
|
|
21393
|
+
locationX: Math.round((event?.nativeEvent?.locationX ?? 0) * 100) / 100,
|
|
21394
|
+
locationY: Math.round((event?.nativeEvent?.locationY ?? 0) * 100) / 100,
|
|
21395
|
+
pageX: Math.round((event?.nativeEvent?.pageX ?? 0) * 100) / 100,
|
|
21396
|
+
pageY: Math.round((event?.nativeEvent?.pageY ?? 0) * 100) / 100
|
|
21397
|
+
});
|
|
21398
|
+
},
|
|
21399
|
+
[isNative, logGestureDebug, perfEnabled]
|
|
21400
|
+
);
|
|
21401
|
+
const setSelectionDragState = useCallback(
|
|
21402
|
+
(active) => {
|
|
21403
|
+
if (selectionDragActiveRef.current === active) return;
|
|
21404
|
+
selectionDragActiveRef.current = active;
|
|
21405
|
+
onSelectionDragActiveChange?.(active);
|
|
21406
|
+
},
|
|
21407
|
+
[onSelectionDragActiveChange]
|
|
21408
|
+
);
|
|
21341
21409
|
const pageAnnotations = useMemo(
|
|
21342
21410
|
() => annotations.filter((ann) => ann.pageIndex === pageIndex),
|
|
21343
21411
|
[annotations, pageIndex]
|
|
@@ -21366,12 +21434,6 @@ var PageRenderer = ({
|
|
|
21366
21434
|
const selectionRectRef = useRef(null);
|
|
21367
21435
|
const selectionBoundsRef = useRef(null);
|
|
21368
21436
|
const selectionBoundsStart = useRef(null);
|
|
21369
|
-
const lastTapRef = useRef(
|
|
21370
|
-
null
|
|
21371
|
-
);
|
|
21372
|
-
const pinchRef = useRef(null);
|
|
21373
|
-
const isPinchingRef = useRef(false);
|
|
21374
|
-
const pinchLogZoomRef = useRef(zoom);
|
|
21375
21437
|
const [isInkDrawing, setIsInkDrawing] = useState(false);
|
|
21376
21438
|
const [inkPoints, setInkPoints] = useState(
|
|
21377
21439
|
[]
|
|
@@ -21494,11 +21556,30 @@ var PageRenderer = ({
|
|
|
21494
21556
|
}, [inkPoints]);
|
|
21495
21557
|
useEffect(() => {
|
|
21496
21558
|
if (activeTool === "ink") return;
|
|
21559
|
+
inkDrawingActiveRef.current = false;
|
|
21497
21560
|
setIsInkDrawing(false);
|
|
21498
21561
|
setInkPoints([]);
|
|
21499
21562
|
inkPointsRef.current = [];
|
|
21500
21563
|
}, [activeTool]);
|
|
21501
|
-
const
|
|
21564
|
+
const pageViewportWidth = Math.max(
|
|
21565
|
+
0,
|
|
21566
|
+
(availableWidth ?? windowWidth) - horizontalPadding * 2
|
|
21567
|
+
);
|
|
21568
|
+
const selectionEnabled = Platform.OS === "web" || isNative && shouldEnableSelectionDrag({
|
|
21569
|
+
activeTool,
|
|
21570
|
+
interactionMode
|
|
21571
|
+
});
|
|
21572
|
+
const inkEnabled = isNative && activeTool === "ink";
|
|
21573
|
+
const stopSelectionAutoscroll = useCallback(() => {
|
|
21574
|
+
if (selectionAutoscrollIntervalRef.current) {
|
|
21575
|
+
clearInterval(selectionAutoscrollIntervalRef.current);
|
|
21576
|
+
selectionAutoscrollIntervalRef.current = null;
|
|
21577
|
+
}
|
|
21578
|
+
}, []);
|
|
21579
|
+
const clearSelection = useCallback(() => {
|
|
21580
|
+
stopSelectionAutoscroll();
|
|
21581
|
+
selectionDragPointRef.current = null;
|
|
21582
|
+
setSelectionDragState(false);
|
|
21502
21583
|
setSelectionRect(null);
|
|
21503
21584
|
selectionRectRef.current = null;
|
|
21504
21585
|
setSelectionRects([]);
|
|
@@ -21508,13 +21589,19 @@ var PageRenderer = ({
|
|
|
21508
21589
|
setIsSelecting(false);
|
|
21509
21590
|
selectionStart.current = null;
|
|
21510
21591
|
selectionBoundsStart.current = null;
|
|
21511
|
-
lastTapRef.current = null;
|
|
21512
21592
|
setSelectionActive(false);
|
|
21513
|
-
};
|
|
21593
|
+
}, [setSelectionActive, setSelectionDragState, stopSelectionAutoscroll]);
|
|
21514
21594
|
useEffect(() => {
|
|
21515
21595
|
if (activeTool === "select") return;
|
|
21516
21596
|
clearSelection();
|
|
21517
21597
|
}, [activeTool]);
|
|
21598
|
+
useEffect(
|
|
21599
|
+
() => () => {
|
|
21600
|
+
stopSelectionAutoscroll();
|
|
21601
|
+
setSelectionDragState(false);
|
|
21602
|
+
},
|
|
21603
|
+
[setSelectionDragState, stopSelectionAutoscroll]
|
|
21604
|
+
);
|
|
21518
21605
|
const stopPressPropagation = (event) => {
|
|
21519
21606
|
event.stopPropagation?.();
|
|
21520
21607
|
};
|
|
@@ -21591,50 +21678,193 @@ var PageRenderer = ({
|
|
|
21591
21678
|
};
|
|
21592
21679
|
await selectFromBounds(bounds);
|
|
21593
21680
|
};
|
|
21594
|
-
const
|
|
21595
|
-
|
|
21596
|
-
|
|
21597
|
-
|
|
21598
|
-
|
|
21599
|
-
|
|
21600
|
-
|
|
21601
|
-
|
|
21602
|
-
|
|
21603
|
-
|
|
21604
|
-
|
|
21605
|
-
|
|
21606
|
-
|
|
21607
|
-
|
|
21608
|
-
|
|
21681
|
+
const cancelSelectionDrag = useCallback(() => {
|
|
21682
|
+
stopSelectionAutoscroll();
|
|
21683
|
+
selectionDragPointRef.current = null;
|
|
21684
|
+
setSelectionDragState(false);
|
|
21685
|
+
setIsSelecting(false);
|
|
21686
|
+
selectionStart.current = null;
|
|
21687
|
+
selectionRectRef.current = null;
|
|
21688
|
+
setSelectionRect(null);
|
|
21689
|
+
}, [setSelectionDragState, stopSelectionAutoscroll]);
|
|
21690
|
+
const updateSelectionRectFromPoint = useCallback(
|
|
21691
|
+
(x, y) => {
|
|
21692
|
+
const start = selectionStart.current;
|
|
21693
|
+
if (!start || !layout.width || !layout.height) return;
|
|
21694
|
+
const left = Math.max(0, Math.min(start.x, x));
|
|
21695
|
+
const top = Math.max(0, Math.min(start.y, y));
|
|
21696
|
+
const right = Math.min(layout.width, Math.max(start.x, x));
|
|
21697
|
+
const bottom = Math.min(layout.height, Math.max(start.y, y));
|
|
21698
|
+
const rect = {
|
|
21699
|
+
x: left,
|
|
21700
|
+
y: top,
|
|
21701
|
+
width: right - left,
|
|
21702
|
+
height: bottom - top
|
|
21703
|
+
};
|
|
21704
|
+
selectionRectRef.current = rect;
|
|
21705
|
+
setSelectionRect(rect);
|
|
21706
|
+
},
|
|
21707
|
+
[layout.height, layout.width]
|
|
21708
|
+
);
|
|
21709
|
+
const applySelectionEdgeAutoscroll = useCallback(() => {
|
|
21710
|
+
const point = selectionDragPointRef.current;
|
|
21711
|
+
if (!point || !selectionStart.current || !layout.width || !layout.height) {
|
|
21712
|
+
stopSelectionAutoscroll();
|
|
21713
|
+
return;
|
|
21714
|
+
}
|
|
21715
|
+
const visibleX = point.x - horizontalScrollOffsetRef.current;
|
|
21716
|
+
const { dx } = getSelectionEdgeAutoscroll({
|
|
21717
|
+
x: visibleX,
|
|
21718
|
+
y: SELECTION_EDGE_THRESHOLD_PX,
|
|
21719
|
+
width: pageViewportWidth,
|
|
21720
|
+
height: SELECTION_EDGE_THRESHOLD_PX * 2,
|
|
21721
|
+
threshold: SELECTION_EDGE_THRESHOLD_PX,
|
|
21722
|
+
maxStep: SELECTION_EDGE_MAX_STEP_PX
|
|
21609
21723
|
});
|
|
21610
|
-
|
|
21611
|
-
|
|
21612
|
-
|
|
21613
|
-
|
|
21614
|
-
|
|
21615
|
-
|
|
21616
|
-
|
|
21617
|
-
|
|
21618
|
-
|
|
21619
|
-
|
|
21620
|
-
|
|
21621
|
-
|
|
21622
|
-
|
|
21623
|
-
distance: Math.round(distance * 100) / 100,
|
|
21624
|
-
zoom: Math.round(nextZoom * 100) / 100
|
|
21625
|
-
});
|
|
21724
|
+
let appliedDx = 0;
|
|
21725
|
+
if (dx !== 0 && pageViewportWidth > 0) {
|
|
21726
|
+
const maxOffsetX = Math.max(0, layout.width - pageViewportWidth);
|
|
21727
|
+
const nextOffsetX = clamp(
|
|
21728
|
+
horizontalScrollOffsetRef.current + dx,
|
|
21729
|
+
0,
|
|
21730
|
+
maxOffsetX
|
|
21731
|
+
);
|
|
21732
|
+
appliedDx = nextOffsetX - horizontalScrollOffsetRef.current;
|
|
21733
|
+
if (appliedDx !== 0) {
|
|
21734
|
+
horizontalScrollOffsetRef.current = nextOffsetX;
|
|
21735
|
+
pageScrollRef.current?.scrollTo({ x: nextOffsetX, animated: false });
|
|
21736
|
+
}
|
|
21626
21737
|
}
|
|
21627
|
-
|
|
21628
|
-
|
|
21629
|
-
|
|
21630
|
-
|
|
21631
|
-
tool: activeTool,
|
|
21632
|
-
zoom: Math.round(zoom * 100) / 100
|
|
21633
|
-
});
|
|
21738
|
+
const appliedDy = requestSelectionVerticalAutoscroll?.(point.absoluteY) ?? 0;
|
|
21739
|
+
if (appliedDx === 0 && appliedDy === 0) {
|
|
21740
|
+
stopSelectionAutoscroll();
|
|
21741
|
+
return;
|
|
21634
21742
|
}
|
|
21635
|
-
|
|
21636
|
-
|
|
21743
|
+
const nextX = clamp(point.x + appliedDx, 0, layout.width);
|
|
21744
|
+
const nextY = clamp(point.y + appliedDy, 0, layout.height);
|
|
21745
|
+
selectionDragPointRef.current = {
|
|
21746
|
+
absoluteY: point.absoluteY,
|
|
21747
|
+
x: nextX,
|
|
21748
|
+
y: nextY
|
|
21749
|
+
};
|
|
21750
|
+
updateSelectionRectFromPoint(nextX, nextY);
|
|
21751
|
+
}, [
|
|
21752
|
+
layout.height,
|
|
21753
|
+
layout.width,
|
|
21754
|
+
pageViewportWidth,
|
|
21755
|
+
requestSelectionVerticalAutoscroll,
|
|
21756
|
+
stopSelectionAutoscroll,
|
|
21757
|
+
updateSelectionRectFromPoint
|
|
21758
|
+
]);
|
|
21759
|
+
const ensureSelectionAutoscroll = useCallback(() => {
|
|
21760
|
+
if (selectionAutoscrollIntervalRef.current) return;
|
|
21761
|
+
selectionAutoscrollIntervalRef.current = setInterval(
|
|
21762
|
+
applySelectionEdgeAutoscroll,
|
|
21763
|
+
SELECTION_AUTOSCROLL_INTERVAL_MS
|
|
21764
|
+
);
|
|
21765
|
+
}, [applySelectionEdgeAutoscroll]);
|
|
21766
|
+
const beginSelectionDrag = useCallback(
|
|
21767
|
+
(x, y, absoluteY) => {
|
|
21768
|
+
if (!selectionEnabled || !layout.width || !layout.height || selectionRects.length > 0 || selectionBounds) {
|
|
21769
|
+
return;
|
|
21770
|
+
}
|
|
21771
|
+
const start = {
|
|
21772
|
+
x: clamp(x, 0, layout.width),
|
|
21773
|
+
y: clamp(y, 0, layout.height)
|
|
21774
|
+
};
|
|
21775
|
+
selectionStart.current = start;
|
|
21776
|
+
selectionDragPointRef.current = { absoluteY, ...start };
|
|
21777
|
+
setSelectionDragState(true);
|
|
21778
|
+
setIsSelecting(true);
|
|
21779
|
+
const rect = { x: start.x, y: start.y, width: 0, height: 0 };
|
|
21780
|
+
selectionRectRef.current = rect;
|
|
21781
|
+
setSelectionRect(rect);
|
|
21782
|
+
},
|
|
21783
|
+
[
|
|
21784
|
+
layout.height,
|
|
21785
|
+
layout.width,
|
|
21786
|
+
selectionBounds,
|
|
21787
|
+
selectionEnabled,
|
|
21788
|
+
selectionRects.length,
|
|
21789
|
+
setSelectionDragState
|
|
21790
|
+
]
|
|
21791
|
+
);
|
|
21792
|
+
const updateSelectionDrag = useCallback(
|
|
21793
|
+
(x, y, absoluteY) => {
|
|
21794
|
+
if (!selectionEnabled || !selectionStart.current) return;
|
|
21795
|
+
const nextX = clamp(x, 0, layout.width);
|
|
21796
|
+
const nextY = clamp(y, 0, layout.height);
|
|
21797
|
+
selectionDragPointRef.current = {
|
|
21798
|
+
absoluteY,
|
|
21799
|
+
x: nextX,
|
|
21800
|
+
y: nextY
|
|
21801
|
+
};
|
|
21802
|
+
updateSelectionRectFromPoint(nextX, nextY);
|
|
21803
|
+
ensureSelectionAutoscroll();
|
|
21804
|
+
},
|
|
21805
|
+
[
|
|
21806
|
+
ensureSelectionAutoscroll,
|
|
21807
|
+
layout.height,
|
|
21808
|
+
layout.width,
|
|
21809
|
+
selectionEnabled,
|
|
21810
|
+
updateSelectionRectFromPoint
|
|
21811
|
+
]
|
|
21812
|
+
);
|
|
21813
|
+
const finishSelectionDrag = useCallback(async () => {
|
|
21814
|
+
stopSelectionAutoscroll();
|
|
21815
|
+
selectionDragPointRef.current = null;
|
|
21816
|
+
setSelectionDragState(false);
|
|
21817
|
+
const rect = selectionRectRef.current;
|
|
21818
|
+
if (!selectionEnabled || !rect || !layout.width || !layout.height) {
|
|
21819
|
+
setIsSelecting(false);
|
|
21820
|
+
selectionStart.current = null;
|
|
21821
|
+
return;
|
|
21822
|
+
}
|
|
21823
|
+
setIsSelecting(false);
|
|
21824
|
+
selectionStart.current = null;
|
|
21825
|
+
const minSize = 6;
|
|
21826
|
+
if (rect.width < minSize || rect.height < minSize) {
|
|
21827
|
+
clearSelection();
|
|
21828
|
+
return;
|
|
21829
|
+
}
|
|
21830
|
+
const normalized = {
|
|
21831
|
+
x: rect.x / layout.width,
|
|
21832
|
+
y: rect.y / layout.height,
|
|
21833
|
+
width: rect.width / layout.width,
|
|
21834
|
+
height: rect.height / layout.height
|
|
21835
|
+
};
|
|
21836
|
+
await selectFromBounds(normalized);
|
|
21837
|
+
setSelectionRect(null);
|
|
21838
|
+
}, [
|
|
21839
|
+
clearSelection,
|
|
21840
|
+
layout.height,
|
|
21841
|
+
layout.width,
|
|
21842
|
+
selectionEnabled,
|
|
21843
|
+
setSelectionDragState,
|
|
21844
|
+
stopSelectionAutoscroll
|
|
21845
|
+
]);
|
|
21846
|
+
const handleDoubleTap = useCallback(
|
|
21847
|
+
(x, y) => {
|
|
21848
|
+
if (shouldSuppressPressAfterPinch(lastPinchEndedAt)) {
|
|
21849
|
+
return;
|
|
21850
|
+
}
|
|
21851
|
+
if (!isNative || activeTool !== "select" || selectionRects.length > 0 || selectionBounds) {
|
|
21852
|
+
return;
|
|
21853
|
+
}
|
|
21854
|
+
void selectAtPoint(x, y);
|
|
21855
|
+
},
|
|
21856
|
+
[
|
|
21857
|
+
activeTool,
|
|
21858
|
+
isNative,
|
|
21859
|
+
lastPinchEndedAt,
|
|
21860
|
+
selectionBounds,
|
|
21861
|
+
selectionRects.length
|
|
21862
|
+
]
|
|
21863
|
+
);
|
|
21637
21864
|
const handlePress = (event) => {
|
|
21865
|
+
if (shouldSuppressPressAfterPinch(lastPinchEndedAt)) {
|
|
21866
|
+
return;
|
|
21867
|
+
}
|
|
21638
21868
|
if (!layout.width || !layout.height) return;
|
|
21639
21869
|
const { locationX, locationY } = event.nativeEvent;
|
|
21640
21870
|
if (selectionRects.length > 0 || selectionBounds) {
|
|
@@ -21655,20 +21885,7 @@ var PageRenderer = ({
|
|
|
21655
21885
|
return;
|
|
21656
21886
|
}
|
|
21657
21887
|
setSelectedAnnotation(null);
|
|
21658
|
-
if (!isNative || activeTool === "ink") return;
|
|
21659
|
-
const now = Date.now();
|
|
21660
|
-
const lastTap = lastTapRef.current;
|
|
21661
|
-
lastTapRef.current = { time: now, x: locationX, y: locationY };
|
|
21662
|
-
if (!lastTap) return;
|
|
21663
|
-
const timeDelta = now - lastTap.time;
|
|
21664
|
-
const distance = Math.hypot(locationX - lastTap.x, locationY - lastTap.y);
|
|
21665
|
-
if (timeDelta < 280 && distance < 24 && activeTool === "select") {
|
|
21666
|
-
void selectAtPoint(locationX, locationY);
|
|
21667
|
-
}
|
|
21668
21888
|
};
|
|
21669
|
-
const selectionEnabled = Platform.OS === "web" || isNative && (activeTool === "select" || TEXT_MARKUP_TOOLS.has(activeTool));
|
|
21670
|
-
const inkEnabled = isNative && activeTool === "ink";
|
|
21671
|
-
const pinchEnabled = isNative;
|
|
21672
21889
|
const toNormalizedPoint = (x, y) => {
|
|
21673
21890
|
if (!layout.width || !layout.height) return null;
|
|
21674
21891
|
return {
|
|
@@ -21680,6 +21897,7 @@ var PageRenderer = ({
|
|
|
21680
21897
|
const point = toNormalizedPoint(x, y);
|
|
21681
21898
|
if (!point) return;
|
|
21682
21899
|
clearSelection();
|
|
21900
|
+
inkDrawingActiveRef.current = true;
|
|
21683
21901
|
setIsInkDrawing(true);
|
|
21684
21902
|
setInkPoints([point]);
|
|
21685
21903
|
inkPointsRef.current = [point];
|
|
@@ -21698,6 +21916,7 @@ var PageRenderer = ({
|
|
|
21698
21916
|
const finishInkDrawing = () => {
|
|
21699
21917
|
const points = inkPointsRef.current;
|
|
21700
21918
|
if (points.length === 0) return;
|
|
21919
|
+
inkDrawingActiveRef.current = false;
|
|
21701
21920
|
setIsInkDrawing(false);
|
|
21702
21921
|
setInkPoints([]);
|
|
21703
21922
|
inkPointsRef.current = [];
|
|
@@ -21720,31 +21939,18 @@ var PageRenderer = ({
|
|
|
21720
21939
|
const panResponder = useMemo(
|
|
21721
21940
|
() => PanResponder.create({
|
|
21722
21941
|
onStartShouldSetPanResponder: (event) => {
|
|
21942
|
+
if (isNative) return false;
|
|
21723
21943
|
const touches = event.nativeEvent.touches ?? [];
|
|
21724
|
-
|
|
21944
|
+
if (touches.length !== 1) return false;
|
|
21945
|
+
return inkEnabled;
|
|
21725
21946
|
},
|
|
21726
21947
|
onMoveShouldSetPanResponder: (event) => {
|
|
21948
|
+
if (isNative) return false;
|
|
21727
21949
|
const touches = event.nativeEvent.touches ?? [];
|
|
21728
|
-
|
|
21729
|
-
|
|
21730
|
-
onStartShouldSetPanResponderCapture: (event) => {
|
|
21731
|
-
const touches = event.nativeEvent.touches ?? [];
|
|
21732
|
-
return pinchEnabled && shouldHandlePinch(touches);
|
|
21733
|
-
},
|
|
21734
|
-
onMoveShouldSetPanResponderCapture: (event) => {
|
|
21735
|
-
const touches = event.nativeEvent.touches ?? [];
|
|
21736
|
-
return pinchEnabled && shouldHandlePinch(touches);
|
|
21950
|
+
if (touches.length !== 1) return false;
|
|
21951
|
+
return selectionEnabled || inkEnabled;
|
|
21737
21952
|
},
|
|
21738
21953
|
onPanResponderGrant: (event) => {
|
|
21739
|
-
const touches = event.nativeEvent.touches ?? [];
|
|
21740
|
-
if (pinchEnabled && shouldHandlePinch(touches)) {
|
|
21741
|
-
isPinchingRef.current = true;
|
|
21742
|
-
setIsSelecting(false);
|
|
21743
|
-
selectionStart.current = null;
|
|
21744
|
-
handlePinchStart(touches);
|
|
21745
|
-
return;
|
|
21746
|
-
}
|
|
21747
|
-
isPinchingRef.current = false;
|
|
21748
21954
|
if (inkEnabled) {
|
|
21749
21955
|
beginInkDrawing(
|
|
21750
21956
|
event.nativeEvent.locationX,
|
|
@@ -21752,26 +21958,13 @@ var PageRenderer = ({
|
|
|
21752
21958
|
);
|
|
21753
21959
|
return;
|
|
21754
21960
|
}
|
|
21755
|
-
|
|
21756
|
-
|
|
21757
|
-
|
|
21758
|
-
|
|
21759
|
-
|
|
21760
|
-
selectionRectRef.current = rect;
|
|
21761
|
-
setSelectionRect(rect);
|
|
21961
|
+
beginSelectionDrag(
|
|
21962
|
+
event.nativeEvent.locationX,
|
|
21963
|
+
event.nativeEvent.locationY,
|
|
21964
|
+
event.nativeEvent.pageY ?? event.nativeEvent.locationY
|
|
21965
|
+
);
|
|
21762
21966
|
},
|
|
21763
|
-
onPanResponderMove: (event
|
|
21764
|
-
const touches = event.nativeEvent.touches ?? [];
|
|
21765
|
-
if (pinchEnabled && (shouldHandlePinch(touches) || isPinchingRef.current)) {
|
|
21766
|
-
if (shouldHandlePinch(touches)) {
|
|
21767
|
-
if (!isPinchingRef.current) {
|
|
21768
|
-
isPinchingRef.current = true;
|
|
21769
|
-
handlePinchStart(touches);
|
|
21770
|
-
}
|
|
21771
|
-
handlePinchMove(touches);
|
|
21772
|
-
}
|
|
21773
|
-
return;
|
|
21774
|
-
}
|
|
21967
|
+
onPanResponderMove: (event) => {
|
|
21775
21968
|
if (inkEnabled) {
|
|
21776
21969
|
pushInkPoint(
|
|
21777
21970
|
event.nativeEvent.locationX,
|
|
@@ -21779,79 +21972,90 @@ var PageRenderer = ({
|
|
|
21779
21972
|
);
|
|
21780
21973
|
return;
|
|
21781
21974
|
}
|
|
21782
|
-
|
|
21783
|
-
|
|
21784
|
-
|
|
21785
|
-
|
|
21786
|
-
|
|
21787
|
-
const top = Math.max(0, Math.min(start.y, currentY));
|
|
21788
|
-
const right = Math.min(layout.width, Math.max(start.x, currentX));
|
|
21789
|
-
const bottom = Math.min(layout.height, Math.max(start.y, currentY));
|
|
21790
|
-
const rect = {
|
|
21791
|
-
x: left,
|
|
21792
|
-
y: top,
|
|
21793
|
-
width: right - left,
|
|
21794
|
-
height: bottom - top
|
|
21795
|
-
};
|
|
21796
|
-
selectionRectRef.current = rect;
|
|
21797
|
-
setSelectionRect(rect);
|
|
21975
|
+
updateSelectionDrag(
|
|
21976
|
+
event.nativeEvent.locationX,
|
|
21977
|
+
event.nativeEvent.locationY,
|
|
21978
|
+
event.nativeEvent.pageY ?? event.nativeEvent.locationY
|
|
21979
|
+
);
|
|
21798
21980
|
},
|
|
21799
21981
|
onPanResponderRelease: async () => {
|
|
21800
|
-
if (isPinchingRef.current) {
|
|
21801
|
-
isPinchingRef.current = false;
|
|
21802
|
-
handlePinchEnd();
|
|
21803
|
-
return;
|
|
21804
|
-
}
|
|
21805
21982
|
if (inkEnabled) {
|
|
21806
21983
|
finishInkDrawing();
|
|
21807
21984
|
return;
|
|
21808
21985
|
}
|
|
21809
|
-
|
|
21810
|
-
if (!selectionEnabled || !rect || !layout.width || !layout.height) {
|
|
21811
|
-
setIsSelecting(false);
|
|
21812
|
-
selectionStart.current = null;
|
|
21813
|
-
return;
|
|
21814
|
-
}
|
|
21815
|
-
setIsSelecting(false);
|
|
21816
|
-
selectionStart.current = null;
|
|
21817
|
-
const minSize = 6;
|
|
21818
|
-
if (rect.width < minSize || rect.height < minSize) {
|
|
21819
|
-
clearSelection();
|
|
21820
|
-
return;
|
|
21821
|
-
}
|
|
21822
|
-
const normalized = {
|
|
21823
|
-
x: rect.x / layout.width,
|
|
21824
|
-
y: rect.y / layout.height,
|
|
21825
|
-
width: rect.width / layout.width,
|
|
21826
|
-
height: rect.height / layout.height
|
|
21827
|
-
};
|
|
21828
|
-
await selectFromBounds(normalized);
|
|
21829
|
-
setSelectionRect(null);
|
|
21986
|
+
await finishSelectionDrag();
|
|
21830
21987
|
},
|
|
21831
21988
|
onPanResponderTerminate: () => {
|
|
21832
|
-
if (isPinchingRef.current) {
|
|
21833
|
-
isPinchingRef.current = false;
|
|
21834
|
-
handlePinchEnd();
|
|
21835
|
-
return;
|
|
21836
|
-
}
|
|
21837
21989
|
if (inkEnabled) {
|
|
21838
21990
|
finishInkDrawing();
|
|
21839
21991
|
return;
|
|
21840
21992
|
}
|
|
21841
|
-
|
|
21842
|
-
selectionStart.current = null;
|
|
21993
|
+
cancelSelectionDrag();
|
|
21843
21994
|
}
|
|
21844
21995
|
}),
|
|
21845
21996
|
[
|
|
21846
|
-
|
|
21997
|
+
beginSelectionDrag,
|
|
21998
|
+
cancelSelectionDrag,
|
|
21999
|
+
finishSelectionDrag,
|
|
22000
|
+
isNative,
|
|
21847
22001
|
inkEnabled,
|
|
21848
|
-
|
|
21849
|
-
|
|
21850
|
-
|
|
21851
|
-
|
|
21852
|
-
|
|
22002
|
+
beginInkDrawing,
|
|
22003
|
+
finishInkDrawing,
|
|
22004
|
+
pushInkPoint,
|
|
22005
|
+
selectionEnabled,
|
|
22006
|
+
updateSelectionDrag
|
|
22007
|
+
]
|
|
22008
|
+
);
|
|
22009
|
+
const selectionGesture = useMemo(
|
|
22010
|
+
() => Gesture.Pan().enabled(
|
|
22011
|
+
isNative && selectionEnabled && selectionRects.length === 0 && !selectionBounds
|
|
22012
|
+
).maxPointers(1).minDistance(4).runOnJS(true).onStart((event) => {
|
|
22013
|
+
beginSelectionDrag(event.x, event.y, event.absoluteY);
|
|
22014
|
+
}).onUpdate((event) => {
|
|
22015
|
+
updateSelectionDrag(event.x, event.y, event.absoluteY);
|
|
22016
|
+
}).onEnd(() => {
|
|
22017
|
+
void finishSelectionDrag();
|
|
22018
|
+
}).onFinalize(() => {
|
|
22019
|
+
if (selectionDragActiveRef.current) {
|
|
22020
|
+
cancelSelectionDrag();
|
|
22021
|
+
}
|
|
22022
|
+
}),
|
|
22023
|
+
[
|
|
22024
|
+
beginSelectionDrag,
|
|
22025
|
+
cancelSelectionDrag,
|
|
22026
|
+
finishSelectionDrag,
|
|
22027
|
+
isNative,
|
|
22028
|
+
selectionBounds,
|
|
22029
|
+
selectionEnabled,
|
|
22030
|
+
selectionRects.length,
|
|
22031
|
+
updateSelectionDrag
|
|
21853
22032
|
]
|
|
21854
22033
|
);
|
|
22034
|
+
const inkGesture = useMemo(
|
|
22035
|
+
() => Gesture.Pan().enabled(isNative && inkEnabled).maxPointers(1).minDistance(0).runOnJS(true).onStart((event) => {
|
|
22036
|
+
beginInkDrawing(event.x, event.y);
|
|
22037
|
+
}).onUpdate((event) => {
|
|
22038
|
+
pushInkPoint(event.x, event.y);
|
|
22039
|
+
}).onEnd(() => {
|
|
22040
|
+
finishInkDrawing();
|
|
22041
|
+
}).onFinalize(() => {
|
|
22042
|
+
if (inkDrawingActiveRef.current) {
|
|
22043
|
+
finishInkDrawing();
|
|
22044
|
+
}
|
|
22045
|
+
}),
|
|
22046
|
+
[beginInkDrawing, finishInkDrawing, inkEnabled, isNative, pushInkPoint]
|
|
22047
|
+
);
|
|
22048
|
+
const doubleTapGesture = useMemo(
|
|
22049
|
+
() => Gesture.Tap().enabled(isNative && activeTool === "select").numberOfTaps(2).maxDistance(24).maxDelay(280).maxDuration(250).runOnJS(true).onEnd((event, success) => {
|
|
22050
|
+
if (!success) return;
|
|
22051
|
+
handleDoubleTap(event.x, event.y);
|
|
22052
|
+
}),
|
|
22053
|
+
[activeTool, handleDoubleTap, isNative]
|
|
22054
|
+
);
|
|
22055
|
+
const contentGesture = useMemo(
|
|
22056
|
+
() => Gesture.Simultaneous(selectionGesture, inkGesture, doubleTapGesture),
|
|
22057
|
+
[doubleTapGesture, inkGesture, selectionGesture]
|
|
22058
|
+
);
|
|
21855
22059
|
const selectionBoundsPx = useMemo(() => {
|
|
21856
22060
|
if (!selectionBounds || !layout.width || !layout.height) return null;
|
|
21857
22061
|
return {
|
|
@@ -21959,29 +22163,83 @@ var PageRenderer = ({
|
|
|
21959
22163
|
const pageWidth = isNative ? baseWidth * zoom : baseWidth;
|
|
21960
22164
|
const pageHeight = pageWidth / aspectRatio;
|
|
21961
22165
|
const hasActiveSelection = selectionRects.length > 0 || !!selectionBounds || isSelecting;
|
|
21962
|
-
const scrollEnabled = isNative && zoom > 1 && !hasActiveSelection && !isInkDrawing;
|
|
22166
|
+
const scrollEnabled = isNative && zoom > 1 && !hasActiveSelection && !isInkDrawing && !gestureScrollLockActive;
|
|
22167
|
+
useEffect(() => {
|
|
22168
|
+
if (!horizontalScrollRestore) return;
|
|
22169
|
+
if (lastAppliedHorizontalRestoreRef.current === horizontalScrollRestore.requestId) {
|
|
22170
|
+
return;
|
|
22171
|
+
}
|
|
22172
|
+
const nextOffsetX = resolveClampedScrollOffset(
|
|
22173
|
+
horizontalScrollRestore.offsetX,
|
|
22174
|
+
pageWidth,
|
|
22175
|
+
pageViewportWidth
|
|
22176
|
+
);
|
|
22177
|
+
lastAppliedHorizontalRestoreRef.current = horizontalScrollRestore.requestId;
|
|
22178
|
+
horizontalScrollOffsetRef.current = nextOffsetX;
|
|
22179
|
+
pageScrollRef.current?.scrollTo({ x: nextOffsetX, animated: false });
|
|
22180
|
+
onHorizontalScrollOffsetChange?.(pageIndex, nextOffsetX);
|
|
22181
|
+
}, [
|
|
22182
|
+
horizontalScrollRestore,
|
|
22183
|
+
onHorizontalScrollOffsetChange,
|
|
22184
|
+
pageIndex,
|
|
22185
|
+
pageViewportWidth,
|
|
22186
|
+
pageWidth
|
|
22187
|
+
]);
|
|
21963
22188
|
return /* @__PURE__ */ jsx(
|
|
21964
22189
|
ScrollView,
|
|
21965
22190
|
{
|
|
22191
|
+
ref: pageScrollRef,
|
|
21966
22192
|
horizontal: true,
|
|
21967
22193
|
scrollEnabled,
|
|
21968
22194
|
showsHorizontalScrollIndicator: false,
|
|
22195
|
+
onScroll: (event) => {
|
|
22196
|
+
const nextOffsetX = event.nativeEvent.contentOffset?.x ?? 0;
|
|
22197
|
+
horizontalScrollOffsetRef.current = nextOffsetX;
|
|
22198
|
+
},
|
|
22199
|
+
onScrollEndDrag: () => {
|
|
22200
|
+
onHorizontalScrollOffsetChange?.(
|
|
22201
|
+
pageIndex,
|
|
22202
|
+
horizontalScrollOffsetRef.current
|
|
22203
|
+
);
|
|
22204
|
+
},
|
|
22205
|
+
onMomentumScrollEnd: () => {
|
|
22206
|
+
onHorizontalScrollOffsetChange?.(
|
|
22207
|
+
pageIndex,
|
|
22208
|
+
horizontalScrollOffsetRef.current
|
|
22209
|
+
);
|
|
22210
|
+
},
|
|
22211
|
+
scrollEventThrottle: 16,
|
|
21969
22212
|
contentContainerStyle: [
|
|
21970
22213
|
styles.scrollContent,
|
|
21971
22214
|
{ paddingHorizontal: horizontalPadding }
|
|
21972
22215
|
],
|
|
21973
|
-
children: /* @__PURE__ */ jsxs(
|
|
22216
|
+
children: /* @__PURE__ */ jsx(GestureDetector, { gesture: contentGesture, children: /* @__PURE__ */ jsxs(
|
|
21974
22217
|
Pressable,
|
|
21975
22218
|
{
|
|
21976
22219
|
...panResponder.panHandlers,
|
|
21977
22220
|
style: [
|
|
21978
22221
|
styles.container,
|
|
21979
|
-
{
|
|
22222
|
+
{
|
|
22223
|
+
width: pageWidth,
|
|
22224
|
+
height: pageHeight,
|
|
22225
|
+
marginBottom: spacing
|
|
22226
|
+
}
|
|
21980
22227
|
],
|
|
21981
22228
|
onLayout: handleLayout,
|
|
22229
|
+
onTouchStart: (event) => logRawTouchDebug("start", event),
|
|
22230
|
+
onTouchMove: (event) => logRawTouchDebug("move", event),
|
|
22231
|
+
onTouchEnd: (event) => logRawTouchDebug("end", event),
|
|
22232
|
+
onTouchCancel: (event) => logRawTouchDebug("cancel", event),
|
|
21982
22233
|
onPress: handlePress,
|
|
21983
22234
|
children: [
|
|
21984
|
-
/* @__PURE__ */ jsx(
|
|
22235
|
+
/* @__PURE__ */ jsx(
|
|
22236
|
+
PageViewComponent,
|
|
22237
|
+
{
|
|
22238
|
+
ref: viewRef,
|
|
22239
|
+
pointerEvents: "none",
|
|
22240
|
+
style: styles.page
|
|
22241
|
+
}
|
|
22242
|
+
),
|
|
21985
22243
|
/* @__PURE__ */ jsx(
|
|
21986
22244
|
View,
|
|
21987
22245
|
{
|
|
@@ -22118,7 +22376,9 @@ var PageRenderer = ({
|
|
|
22118
22376
|
const isSelected = selectedAnnotationId === ann.id;
|
|
22119
22377
|
const isText = ann.type === "comment" || ann.type === "text";
|
|
22120
22378
|
const isInk = ann.type === "ink" && Array.isArray(ann.path) && ann.path.length > 1;
|
|
22121
|
-
const isMarkup = TEXT_MARKUP_TOOLS.has(
|
|
22379
|
+
const isMarkup = TEXT_MARKUP_TOOLS.has(
|
|
22380
|
+
ann.type
|
|
22381
|
+
);
|
|
22122
22382
|
const rects = ann.rects && ann.rects.length > 0 ? ann.rects : [ann.rect];
|
|
22123
22383
|
const hitTargetStyle = {
|
|
22124
22384
|
left: `${ann.rect.x * 100}%`,
|
|
@@ -22158,7 +22418,10 @@ var PageRenderer = ({
|
|
|
22158
22418
|
View,
|
|
22159
22419
|
{
|
|
22160
22420
|
pointerEvents: "none",
|
|
22161
|
-
style: [
|
|
22421
|
+
style: [
|
|
22422
|
+
styles.annotationLineContainer,
|
|
22423
|
+
rectStyle
|
|
22424
|
+
],
|
|
22162
22425
|
children: /* @__PURE__ */ jsx(
|
|
22163
22426
|
View,
|
|
22164
22427
|
{
|
|
@@ -22177,7 +22440,10 @@ var PageRenderer = ({
|
|
|
22177
22440
|
View,
|
|
22178
22441
|
{
|
|
22179
22442
|
pointerEvents: "none",
|
|
22180
|
-
style: [
|
|
22443
|
+
style: [
|
|
22444
|
+
styles.annotationLineContainer,
|
|
22445
|
+
rectStyle
|
|
22446
|
+
],
|
|
22181
22447
|
children: /* @__PURE__ */ jsx(
|
|
22182
22448
|
View,
|
|
22183
22449
|
{
|
|
@@ -22410,7 +22676,7 @@ var PageRenderer = ({
|
|
|
22410
22676
|
) : null
|
|
22411
22677
|
]
|
|
22412
22678
|
}
|
|
22413
|
-
)
|
|
22679
|
+
) })
|
|
22414
22680
|
}
|
|
22415
22681
|
);
|
|
22416
22682
|
};
|
|
@@ -22637,7 +22903,7 @@ var styles = StyleSheet.create({
|
|
|
22637
22903
|
borderRadius: 3
|
|
22638
22904
|
}
|
|
22639
22905
|
});
|
|
22640
|
-
var arePageRendererPropsEqual = (previous, next) => previous.engine === next.engine && previous.pageIndex === next.pageIndex && previous.scale === next.scale && previous.PageViewComponent === next.PageViewComponent && previous.availableWidth === next.availableWidth && previous.horizontalPadding === next.horizontalPadding && previous.spacing === next.spacing;
|
|
22906
|
+
var arePageRendererPropsEqual = (previous, next) => previous.engine === next.engine && previous.pageIndex === next.pageIndex && previous.scale === next.scale && previous.PageViewComponent === next.PageViewComponent && previous.availableWidth === next.availableWidth && previous.horizontalPadding === next.horizontalPadding && previous.spacing === next.spacing && previous.onSelectionDragActiveChange === next.onSelectionDragActiveChange && previous.gestureScrollLockActive === next.gestureScrollLockActive && previous.lastPinchEndedAt === next.lastPinchEndedAt && previous.onHorizontalScrollOffsetChange === next.onHorizontalScrollOffsetChange && previous.horizontalScrollRestore?.requestId === next.horizontalScrollRestore?.requestId && previous.horizontalScrollRestore?.offsetX === next.horizontalScrollRestore?.offsetX && previous.requestSelectionVerticalAutoscroll === next.requestSelectionVerticalAutoscroll;
|
|
22641
22907
|
var PageRenderer_default = memo(PageRenderer, arePageRendererPropsEqual);
|
|
22642
22908
|
|
|
22643
22909
|
// components/WebViewViewer.tsx
|
|
@@ -22789,6 +23055,8 @@ var MOBILE_CHROME_HIDE_DELTA = 28;
|
|
|
22789
23055
|
var MOBILE_CHROME_SHOW_DELTA = 22;
|
|
22790
23056
|
var MOBILE_CHROME_SHOW_DELAY_MS = 180;
|
|
22791
23057
|
var MOBILE_CHROME_TOP_RESET = 16;
|
|
23058
|
+
var SELECTION_EDGE_THRESHOLD_PX2 = 48;
|
|
23059
|
+
var SELECTION_EDGE_MAX_STEP_PX2 = 24;
|
|
22792
23060
|
var resolvePositiveInt = (value, fallback, min, max) => {
|
|
22793
23061
|
if (typeof value !== "number" || !Number.isFinite(value)) return fallback;
|
|
22794
23062
|
const rounded = Math.round(value);
|
|
@@ -22846,6 +23114,26 @@ var Viewer = ({
|
|
|
22846
23114
|
const scrollDownAccumRef = useRef3(0);
|
|
22847
23115
|
const scrollUpAccumRef = useRef3(0);
|
|
22848
23116
|
const [layoutRevision, setLayoutRevision] = useState2(0);
|
|
23117
|
+
const [selectionDragActive, setSelectionDragActive] = useState2(false);
|
|
23118
|
+
const selectionDragActiveRef = useRef3(false);
|
|
23119
|
+
const [gestureScrollLockActive, setGestureScrollLockActive] = useState2(false);
|
|
23120
|
+
const gestureScrollLockActiveRef = useRef3(false);
|
|
23121
|
+
const [pinchPreviewScale, setPinchPreviewScale] = useState2(1);
|
|
23122
|
+
const [lastPinchEndedAt, setLastPinchEndedAt] = useState2(null);
|
|
23123
|
+
const [horizontalScrollRestore, setHorizontalScrollRestore] = useState2(null);
|
|
23124
|
+
const pinchGestureActiveRef = useRef3(false);
|
|
23125
|
+
const pinchStartZoomRef = useRef3(1);
|
|
23126
|
+
const pinchPreviewZoomRef = useRef3(1);
|
|
23127
|
+
const pinchFocalPointRef = useRef3({ x: 0, y: 0 });
|
|
23128
|
+
const pinchUpdateLoggedAtRef = useRef3(0);
|
|
23129
|
+
const horizontalScrollOffsetsRef = useRef3(/* @__PURE__ */ new Map());
|
|
23130
|
+
const pendingPinchAnchorRestoreRef = useRef3(
|
|
23131
|
+
null
|
|
23132
|
+
);
|
|
23133
|
+
const pinchAnchorRestoreFrameRef = useRef3(null);
|
|
23134
|
+
const nextHorizontalRestoreRequestIdRef = useRef3(0);
|
|
23135
|
+
const viewerFrameRef = useRef3({ y: 0, height: 0 });
|
|
23136
|
+
const viewerContentHeightRef = useRef3(0);
|
|
22849
23137
|
const resolvedWindowSize = useMemo3(
|
|
22850
23138
|
() => resolvePositiveInt(virtualWindowSize, FLATLIST_WINDOW_SIZE, 2, 30),
|
|
22851
23139
|
[virtualWindowSize]
|
|
@@ -22944,6 +23232,9 @@ var Viewer = ({
|
|
|
22944
23232
|
if (layoutRefreshTimeoutRef.current) {
|
|
22945
23233
|
clearTimeout(layoutRefreshTimeoutRef.current);
|
|
22946
23234
|
}
|
|
23235
|
+
if (pinchAnchorRestoreFrameRef.current !== null) {
|
|
23236
|
+
cancelAnimationFrame(pinchAnchorRestoreFrameRef.current);
|
|
23237
|
+
}
|
|
22947
23238
|
clearPendingScrollRetry();
|
|
22948
23239
|
clearPendingChromeShow();
|
|
22949
23240
|
},
|
|
@@ -23110,6 +23401,513 @@ var Viewer = ({
|
|
|
23110
23401
|
const columnGap = 12;
|
|
23111
23402
|
const horizontalPadding = 16;
|
|
23112
23403
|
const columnWidth = isDouble ? (windowWidth - horizontalPadding * 2 - columnGap) / 2 : windowWidth;
|
|
23404
|
+
const getPageWidthForZoom = useCallback2(
|
|
23405
|
+
(pageIndex, zoomValue) => {
|
|
23406
|
+
const safeZoom = Math.max(zoomValue, 0.25);
|
|
23407
|
+
const baseWidth = isDouble ? columnWidth * 0.92 : windowWidth * 0.92;
|
|
23408
|
+
return baseWidth * safeZoom;
|
|
23409
|
+
},
|
|
23410
|
+
[columnWidth, isDouble, windowWidth]
|
|
23411
|
+
);
|
|
23412
|
+
const getPageHeightForZoom = useCallback2(
|
|
23413
|
+
(pageIndex, zoomValue) => getPageWidthForZoom(pageIndex, zoomValue) / getPageAspectRatio(pageIndex),
|
|
23414
|
+
[getPageAspectRatio, getPageWidthForZoom]
|
|
23415
|
+
);
|
|
23416
|
+
const getPageViewportMetrics = useCallback2(
|
|
23417
|
+
(pageIndex) => {
|
|
23418
|
+
if (isDouble) {
|
|
23419
|
+
const isRight = pageIndex % 2 === 1;
|
|
23420
|
+
return {
|
|
23421
|
+
viewportWidth: columnWidth,
|
|
23422
|
+
horizontalPadding: 8,
|
|
23423
|
+
viewportOffsetX: horizontalPadding + (isRight ? columnWidth + columnGap : 0)
|
|
23424
|
+
};
|
|
23425
|
+
}
|
|
23426
|
+
return {
|
|
23427
|
+
viewportWidth: windowWidth,
|
|
23428
|
+
horizontalPadding: 16,
|
|
23429
|
+
viewportOffsetX: 0
|
|
23430
|
+
};
|
|
23431
|
+
},
|
|
23432
|
+
[columnGap, columnWidth, horizontalPadding, isDouble, windowWidth]
|
|
23433
|
+
);
|
|
23434
|
+
const getPageLayoutForZoom = useCallback2(
|
|
23435
|
+
(pageIndex, zoomValue) => {
|
|
23436
|
+
if (isSingle) {
|
|
23437
|
+
const pageHeight = getPageHeightForZoom(pageIndex, zoomValue);
|
|
23438
|
+
return {
|
|
23439
|
+
pageOffsetY: 18,
|
|
23440
|
+
pageHeight,
|
|
23441
|
+
totalContentHeight: 18 + pageHeight + 140
|
|
23442
|
+
};
|
|
23443
|
+
}
|
|
23444
|
+
if (isDouble) {
|
|
23445
|
+
let offsetY2 = LIST_TOP_PADDING;
|
|
23446
|
+
for (let rowIndex = 0; rowIndex < rows.length; rowIndex += 1) {
|
|
23447
|
+
const row = rows[rowIndex];
|
|
23448
|
+
const leftHeight = getPageHeightForZoom(row.left, zoomValue);
|
|
23449
|
+
const rightHeight = row.right === null ? leftHeight : getPageHeightForZoom(row.right, zoomValue);
|
|
23450
|
+
const rowLength = Math.max(leftHeight, rightHeight) + DOUBLE_PAGE_SPACING;
|
|
23451
|
+
if (row.left === pageIndex || row.right === pageIndex) {
|
|
23452
|
+
let totalContentHeight = LIST_TOP_PADDING;
|
|
23453
|
+
for (let totalRowIndex = 0; totalRowIndex < rows.length; totalRowIndex += 1) {
|
|
23454
|
+
const totalRow = rows[totalRowIndex];
|
|
23455
|
+
const totalLeftHeight = getPageHeightForZoom(
|
|
23456
|
+
totalRow.left,
|
|
23457
|
+
zoomValue
|
|
23458
|
+
);
|
|
23459
|
+
const totalRightHeight = totalRow.right === null ? totalLeftHeight : getPageHeightForZoom(totalRow.right, zoomValue);
|
|
23460
|
+
totalContentHeight += Math.max(totalLeftHeight, totalRightHeight) + DOUBLE_PAGE_SPACING;
|
|
23461
|
+
}
|
|
23462
|
+
totalContentHeight += LIST_BOTTOM_PADDING;
|
|
23463
|
+
return {
|
|
23464
|
+
pageOffsetY: offsetY2,
|
|
23465
|
+
pageHeight: getPageHeightForZoom(pageIndex, zoomValue),
|
|
23466
|
+
totalContentHeight
|
|
23467
|
+
};
|
|
23468
|
+
}
|
|
23469
|
+
offsetY2 += rowLength;
|
|
23470
|
+
}
|
|
23471
|
+
}
|
|
23472
|
+
let offsetY = LIST_TOP_PADDING;
|
|
23473
|
+
for (let currentPageIndex = 0; currentPageIndex < pageCount; currentPageIndex += 1) {
|
|
23474
|
+
const currentPageHeight = getPageHeightForZoom(
|
|
23475
|
+
currentPageIndex,
|
|
23476
|
+
zoomValue
|
|
23477
|
+
);
|
|
23478
|
+
if (currentPageIndex === pageIndex) {
|
|
23479
|
+
let totalContentHeight = LIST_TOP_PADDING;
|
|
23480
|
+
for (let totalPageIndex = 0; totalPageIndex < pageCount; totalPageIndex += 1) {
|
|
23481
|
+
totalContentHeight += getPageHeightForZoom(totalPageIndex, zoomValue) + CONTINUOUS_PAGE_SPACING;
|
|
23482
|
+
}
|
|
23483
|
+
totalContentHeight += LIST_BOTTOM_PADDING;
|
|
23484
|
+
return {
|
|
23485
|
+
pageOffsetY: offsetY,
|
|
23486
|
+
pageHeight: currentPageHeight,
|
|
23487
|
+
totalContentHeight
|
|
23488
|
+
};
|
|
23489
|
+
}
|
|
23490
|
+
offsetY += currentPageHeight + CONTINUOUS_PAGE_SPACING;
|
|
23491
|
+
}
|
|
23492
|
+
return {
|
|
23493
|
+
pageOffsetY: LIST_TOP_PADDING,
|
|
23494
|
+
pageHeight: getPageHeightForZoom(pageIndex, zoomValue),
|
|
23495
|
+
totalContentHeight: LIST_TOP_PADDING + getPageHeightForZoom(pageIndex, zoomValue) + CONTINUOUS_PAGE_SPACING + LIST_BOTTOM_PADDING
|
|
23496
|
+
};
|
|
23497
|
+
},
|
|
23498
|
+
[getPageHeightForZoom, isDouble, isSingle, pageCount, rows]
|
|
23499
|
+
);
|
|
23500
|
+
const resolvePinchAnchorPageIndex = useCallback2(
|
|
23501
|
+
(focalX, focalY, zoomValue, scrollOffsetY = lastScrollOffsetYRef.current) => {
|
|
23502
|
+
if (isSingle) {
|
|
23503
|
+
return Math.max(0, currentPage - 1);
|
|
23504
|
+
}
|
|
23505
|
+
const contentY = Math.max(0, scrollOffsetY + focalY);
|
|
23506
|
+
if (isDouble) {
|
|
23507
|
+
let offsetY2 = LIST_TOP_PADDING;
|
|
23508
|
+
for (let rowIndex = 0; rowIndex < rows.length; rowIndex += 1) {
|
|
23509
|
+
const row = rows[rowIndex];
|
|
23510
|
+
const leftHeight = getPageHeightForZoom(row.left, zoomValue);
|
|
23511
|
+
const rightHeight = row.right === null ? leftHeight : getPageHeightForZoom(row.right, zoomValue);
|
|
23512
|
+
const rowLength = Math.max(leftHeight, rightHeight) + DOUBLE_PAGE_SPACING;
|
|
23513
|
+
if (contentY <= offsetY2 + rowLength || rowIndex === rows.length - 1) {
|
|
23514
|
+
const isRight = row.right !== null && focalX > horizontalPadding + columnWidth + columnGap / 2;
|
|
23515
|
+
return isRight ? row.right : row.left;
|
|
23516
|
+
}
|
|
23517
|
+
offsetY2 += rowLength;
|
|
23518
|
+
}
|
|
23519
|
+
return rows[rows.length - 1]?.left ?? 0;
|
|
23520
|
+
}
|
|
23521
|
+
let offsetY = LIST_TOP_PADDING;
|
|
23522
|
+
for (let pageIndex = 0; pageIndex < pageCount; pageIndex += 1) {
|
|
23523
|
+
const pageLength = getPageHeightForZoom(pageIndex, zoomValue) + CONTINUOUS_PAGE_SPACING;
|
|
23524
|
+
if (contentY <= offsetY + pageLength || pageIndex === pageCount - 1) {
|
|
23525
|
+
return pageIndex;
|
|
23526
|
+
}
|
|
23527
|
+
offsetY += pageLength;
|
|
23528
|
+
}
|
|
23529
|
+
return Math.max(0, pageCount - 1);
|
|
23530
|
+
},
|
|
23531
|
+
[
|
|
23532
|
+
columnGap,
|
|
23533
|
+
columnWidth,
|
|
23534
|
+
currentPage,
|
|
23535
|
+
getPageHeightForZoom,
|
|
23536
|
+
horizontalPadding,
|
|
23537
|
+
isDouble,
|
|
23538
|
+
isSingle,
|
|
23539
|
+
pageCount,
|
|
23540
|
+
rows
|
|
23541
|
+
]
|
|
23542
|
+
);
|
|
23543
|
+
const resolvedViewerScrollEnabled = shouldEnableViewerScroll({
|
|
23544
|
+
selectionDragActive,
|
|
23545
|
+
gestureScrollLockActive
|
|
23546
|
+
});
|
|
23547
|
+
const setViewerScrollEnabledNative = useCallback2((enabled) => {
|
|
23548
|
+
const scrollNode = listRef.current;
|
|
23549
|
+
scrollNode?.setNativeProps?.({ scrollEnabled: enabled });
|
|
23550
|
+
}, []);
|
|
23551
|
+
const syncViewerScrollEnabled = useCallback2(
|
|
23552
|
+
(nextSelectionDragActive = selectionDragActiveRef.current, nextGestureScrollLockActive = gestureScrollLockActiveRef.current) => {
|
|
23553
|
+
setViewerScrollEnabledNative(
|
|
23554
|
+
shouldEnableViewerScroll({
|
|
23555
|
+
selectionDragActive: nextSelectionDragActive,
|
|
23556
|
+
gestureScrollLockActive: nextGestureScrollLockActive
|
|
23557
|
+
})
|
|
23558
|
+
);
|
|
23559
|
+
},
|
|
23560
|
+
[setViewerScrollEnabledNative]
|
|
23561
|
+
);
|
|
23562
|
+
const handleGestureScrollLockChange = useCallback2(
|
|
23563
|
+
(active) => {
|
|
23564
|
+
if (gestureScrollLockActiveRef.current === active) return;
|
|
23565
|
+
gestureScrollLockActiveRef.current = active;
|
|
23566
|
+
setGestureScrollLockActive(active);
|
|
23567
|
+
syncViewerScrollEnabled(selectionDragActiveRef.current, active);
|
|
23568
|
+
},
|
|
23569
|
+
[syncViewerScrollEnabled]
|
|
23570
|
+
);
|
|
23571
|
+
const handlePinchPreviewScaleChange = useCallback2((scale) => {
|
|
23572
|
+
const nextScale = sanitizePinchPreviewScale(scale);
|
|
23573
|
+
setPinchPreviewScale((current) => {
|
|
23574
|
+
if (Math.abs(current - nextScale) < 5e-4) {
|
|
23575
|
+
return current;
|
|
23576
|
+
}
|
|
23577
|
+
return nextScale;
|
|
23578
|
+
});
|
|
23579
|
+
}, []);
|
|
23580
|
+
const resetViewerPinchPreview = useCallback2(() => {
|
|
23581
|
+
pinchPreviewZoomRef.current = pinchStartZoomRef.current;
|
|
23582
|
+
handlePinchPreviewScaleChange(1);
|
|
23583
|
+
}, [handlePinchPreviewScaleChange]);
|
|
23584
|
+
const beginViewerPinch = useCallback2(
|
|
23585
|
+
(focalX, focalY) => {
|
|
23586
|
+
pinchGestureActiveRef.current = true;
|
|
23587
|
+
pinchStartZoomRef.current = zoom;
|
|
23588
|
+
pinchPreviewZoomRef.current = zoom;
|
|
23589
|
+
pinchFocalPointRef.current = { x: focalX, y: focalY };
|
|
23590
|
+
pinchUpdateLoggedAtRef.current = 0;
|
|
23591
|
+
setLastPinchEndedAt(null);
|
|
23592
|
+
handlePinchPreviewScaleChange(1);
|
|
23593
|
+
handleGestureScrollLockChange(true);
|
|
23594
|
+
if (perfEnabled) {
|
|
23595
|
+
logPerfEvent("Viewer", "pinch.start", {
|
|
23596
|
+
zoom: Math.round(zoom * 100) / 100
|
|
23597
|
+
});
|
|
23598
|
+
}
|
|
23599
|
+
},
|
|
23600
|
+
[
|
|
23601
|
+
handleGestureScrollLockChange,
|
|
23602
|
+
handlePinchPreviewScaleChange,
|
|
23603
|
+
perfEnabled,
|
|
23604
|
+
zoom
|
|
23605
|
+
]
|
|
23606
|
+
);
|
|
23607
|
+
const updateViewerPinch = useCallback2(
|
|
23608
|
+
(scaleFactor, focalX, focalY) => {
|
|
23609
|
+
if (!pinchGestureActiveRef.current) return;
|
|
23610
|
+
pinchFocalPointRef.current = { x: focalX, y: focalY };
|
|
23611
|
+
const nextZoom = resolvePinchGestureZoom(
|
|
23612
|
+
pinchStartZoomRef.current,
|
|
23613
|
+
scaleFactor
|
|
23614
|
+
);
|
|
23615
|
+
pinchPreviewZoomRef.current = nextZoom;
|
|
23616
|
+
handlePinchPreviewScaleChange(
|
|
23617
|
+
resolvePinchPreviewScale(pinchStartZoomRef.current, nextZoom)
|
|
23618
|
+
);
|
|
23619
|
+
if (!perfEnabled) return;
|
|
23620
|
+
const now = Date.now();
|
|
23621
|
+
if (now - pinchUpdateLoggedAtRef.current < 120) return;
|
|
23622
|
+
pinchUpdateLoggedAtRef.current = now;
|
|
23623
|
+
logPerfEvent("Viewer", "pinch.update", {
|
|
23624
|
+
scale: Math.round(scaleFactor * 1e3) / 1e3,
|
|
23625
|
+
nextZoom: Math.round(nextZoom * 100) / 100
|
|
23626
|
+
});
|
|
23627
|
+
},
|
|
23628
|
+
[handlePinchPreviewScaleChange, perfEnabled]
|
|
23629
|
+
);
|
|
23630
|
+
const finishViewerPinch = useCallback2(() => {
|
|
23631
|
+
if (!pinchGestureActiveRef.current) return;
|
|
23632
|
+
pinchGestureActiveRef.current = false;
|
|
23633
|
+
const focalX = pinchFocalPointRef.current.x;
|
|
23634
|
+
const focalY = pinchFocalPointRef.current.y;
|
|
23635
|
+
const viewerScrollOffsetY = lastScrollOffsetYRef.current;
|
|
23636
|
+
const finalZoom = resolvePinchGestureZoom(
|
|
23637
|
+
pinchPreviewZoomRef.current || pinchStartZoomRef.current,
|
|
23638
|
+
1,
|
|
23639
|
+
DEFAULT_PINCH_ZOOM_BOUNDS
|
|
23640
|
+
);
|
|
23641
|
+
setLastPinchEndedAt(Date.now());
|
|
23642
|
+
if (Math.abs(finalZoom - zoom) >= 1e-3) {
|
|
23643
|
+
const anchorPageIndex = resolvePinchAnchorPageIndex(
|
|
23644
|
+
focalX,
|
|
23645
|
+
focalY,
|
|
23646
|
+
zoom,
|
|
23647
|
+
viewerScrollOffsetY
|
|
23648
|
+
);
|
|
23649
|
+
const { pageOffsetY: startPageOffsetY, pageHeight: startPageHeight } = getPageLayoutForZoom(anchorPageIndex, zoom);
|
|
23650
|
+
const startPageWidth = getPageWidthForZoom(anchorPageIndex, zoom);
|
|
23651
|
+
const {
|
|
23652
|
+
viewportWidth: pageViewportWidth,
|
|
23653
|
+
horizontalPadding: pageHorizontalPadding,
|
|
23654
|
+
viewportOffsetX
|
|
23655
|
+
} = getPageViewportMetrics(anchorPageIndex);
|
|
23656
|
+
const pageViewportContentWidth = Math.max(
|
|
23657
|
+
0,
|
|
23658
|
+
pageViewportWidth - pageHorizontalPadding * 2
|
|
23659
|
+
);
|
|
23660
|
+
pendingPinchAnchorRestoreRef.current = {
|
|
23661
|
+
finalZoom,
|
|
23662
|
+
focalY,
|
|
23663
|
+
viewerScrollOffsetY,
|
|
23664
|
+
pageIndex: anchorPageIndex,
|
|
23665
|
+
startPageOffsetY,
|
|
23666
|
+
startPageHeight,
|
|
23667
|
+
startPageWidth,
|
|
23668
|
+
startPageScrollX: horizontalScrollOffsetsRef.current.get(anchorPageIndex) ?? 0,
|
|
23669
|
+
pageViewportWidth,
|
|
23670
|
+
pageHorizontalPadding,
|
|
23671
|
+
pageViewportContentOffsetX: Math.max(
|
|
23672
|
+
0,
|
|
23673
|
+
Math.min(
|
|
23674
|
+
pageViewportContentWidth,
|
|
23675
|
+
focalX - viewportOffsetX - pageHorizontalPadding
|
|
23676
|
+
)
|
|
23677
|
+
)
|
|
23678
|
+
};
|
|
23679
|
+
setDocumentStateTracked({ zoom: finalZoom }, "pinch.viewerEnd");
|
|
23680
|
+
engine.setZoom(finalZoom);
|
|
23681
|
+
} else {
|
|
23682
|
+
pendingPinchAnchorRestoreRef.current = null;
|
|
23683
|
+
}
|
|
23684
|
+
resetViewerPinchPreview();
|
|
23685
|
+
handleGestureScrollLockChange(false);
|
|
23686
|
+
if (perfEnabled) {
|
|
23687
|
+
logPerfEvent("Viewer", "pinch.end", {
|
|
23688
|
+
finalZoom: Math.round(finalZoom * 100) / 100,
|
|
23689
|
+
page: pendingPinchAnchorRestoreRef.current?.pageIndex ?? null
|
|
23690
|
+
});
|
|
23691
|
+
}
|
|
23692
|
+
}, [
|
|
23693
|
+
engine,
|
|
23694
|
+
getPageLayoutForZoom,
|
|
23695
|
+
getPageViewportMetrics,
|
|
23696
|
+
getPageWidthForZoom,
|
|
23697
|
+
handleGestureScrollLockChange,
|
|
23698
|
+
perfEnabled,
|
|
23699
|
+
resetViewerPinchPreview,
|
|
23700
|
+
resolvePinchAnchorPageIndex,
|
|
23701
|
+
setDocumentStateTracked,
|
|
23702
|
+
zoom
|
|
23703
|
+
]);
|
|
23704
|
+
const handlePageHorizontalScrollOffsetChange = useCallback2(
|
|
23705
|
+
(pageIndex, offsetX) => {
|
|
23706
|
+
horizontalScrollOffsetsRef.current.set(pageIndex, Math.max(0, offsetX));
|
|
23707
|
+
const pageWidth = getPageWidthForZoom(pageIndex, zoom);
|
|
23708
|
+
const { viewportWidth, horizontalPadding: horizontalPadding2 } = getPageViewportMetrics(pageIndex);
|
|
23709
|
+
const pageViewportWidth = Math.max(
|
|
23710
|
+
0,
|
|
23711
|
+
viewportWidth - horizontalPadding2 * 2
|
|
23712
|
+
);
|
|
23713
|
+
const nextOffsetX = resolveClampedScrollOffset(
|
|
23714
|
+
offsetX,
|
|
23715
|
+
pageWidth,
|
|
23716
|
+
pageViewportWidth
|
|
23717
|
+
);
|
|
23718
|
+
setHorizontalScrollRestore((current) => {
|
|
23719
|
+
if (current && Math.abs(current.offsetX - nextOffsetX) < 0.5) {
|
|
23720
|
+
return current;
|
|
23721
|
+
}
|
|
23722
|
+
const requestId = nextHorizontalRestoreRequestIdRef.current + 1;
|
|
23723
|
+
nextHorizontalRestoreRequestIdRef.current = requestId;
|
|
23724
|
+
return {
|
|
23725
|
+
pageIndex,
|
|
23726
|
+
requestId,
|
|
23727
|
+
offsetX: nextOffsetX
|
|
23728
|
+
};
|
|
23729
|
+
});
|
|
23730
|
+
},
|
|
23731
|
+
[getPageViewportMetrics, getPageWidthForZoom, zoom]
|
|
23732
|
+
);
|
|
23733
|
+
const viewerPinchGesture = useMemo3(
|
|
23734
|
+
() => Gesture2.Pinch().enabled(!isWebView && pageCount > 0).onTouchesDown((event) => {
|
|
23735
|
+
if ((event.allTouches?.length ?? 0) >= 2) {
|
|
23736
|
+
handleGestureScrollLockChange(true);
|
|
23737
|
+
}
|
|
23738
|
+
}).onTouchesUp((event) => {
|
|
23739
|
+
if ((event.allTouches?.length ?? 0) < 2 && !pinchGestureActiveRef.current) {
|
|
23740
|
+
handleGestureScrollLockChange(false);
|
|
23741
|
+
}
|
|
23742
|
+
}).runOnJS(true).onStart((event) => {
|
|
23743
|
+
beginViewerPinch(event.focalX, event.focalY);
|
|
23744
|
+
}).onUpdate((event) => {
|
|
23745
|
+
updateViewerPinch(event.scale, event.focalX, event.focalY);
|
|
23746
|
+
}).onEnd(() => {
|
|
23747
|
+
finishViewerPinch();
|
|
23748
|
+
}).onFinalize(() => {
|
|
23749
|
+
finishViewerPinch();
|
|
23750
|
+
resetViewerPinchPreview();
|
|
23751
|
+
handleGestureScrollLockChange(false);
|
|
23752
|
+
}),
|
|
23753
|
+
[
|
|
23754
|
+
beginViewerPinch,
|
|
23755
|
+
finishViewerPinch,
|
|
23756
|
+
handleGestureScrollLockChange,
|
|
23757
|
+
isWebView,
|
|
23758
|
+
pageCount,
|
|
23759
|
+
resetViewerPinchPreview,
|
|
23760
|
+
updateViewerPinch
|
|
23761
|
+
]
|
|
23762
|
+
);
|
|
23763
|
+
useEffect3(() => {
|
|
23764
|
+
selectionDragActiveRef.current = selectionDragActive;
|
|
23765
|
+
syncViewerScrollEnabled(
|
|
23766
|
+
selectionDragActive,
|
|
23767
|
+
gestureScrollLockActiveRef.current
|
|
23768
|
+
);
|
|
23769
|
+
}, [selectionDragActive, syncViewerScrollEnabled]);
|
|
23770
|
+
useEffect3(() => {
|
|
23771
|
+
const pendingRestore = pendingPinchAnchorRestoreRef.current;
|
|
23772
|
+
if (!pendingRestore) return;
|
|
23773
|
+
if (Math.abs(pendingRestore.finalZoom - zoom) >= 1e-3) return;
|
|
23774
|
+
if (pinchAnchorRestoreFrameRef.current !== null) {
|
|
23775
|
+
cancelAnimationFrame(pinchAnchorRestoreFrameRef.current);
|
|
23776
|
+
}
|
|
23777
|
+
pinchAnchorRestoreFrameRef.current = requestAnimationFrame(() => {
|
|
23778
|
+
pinchAnchorRestoreFrameRef.current = null;
|
|
23779
|
+
const {
|
|
23780
|
+
pageOffsetY: endPageOffsetY,
|
|
23781
|
+
pageHeight: endPageHeight,
|
|
23782
|
+
totalContentHeight: endContentHeight
|
|
23783
|
+
} = getPageLayoutForZoom(pendingRestore.pageIndex, zoom);
|
|
23784
|
+
const viewerViewportHeight = viewerFrameRef.current.height;
|
|
23785
|
+
const nextScrollY = resolveAnchoredViewportOffset({
|
|
23786
|
+
viewportOffset: pendingRestore.focalY,
|
|
23787
|
+
startScrollOffset: pendingRestore.viewerScrollOffsetY,
|
|
23788
|
+
startItemOffset: pendingRestore.startPageOffsetY,
|
|
23789
|
+
startItemLength: pendingRestore.startPageHeight,
|
|
23790
|
+
endItemOffset: endPageOffsetY,
|
|
23791
|
+
endItemLength: endPageHeight,
|
|
23792
|
+
viewportLength: viewerViewportHeight,
|
|
23793
|
+
endContentLength: endContentHeight
|
|
23794
|
+
});
|
|
23795
|
+
if (isSingle) {
|
|
23796
|
+
listRef.current?.scrollTo?.({
|
|
23797
|
+
y: nextScrollY,
|
|
23798
|
+
animated: false
|
|
23799
|
+
});
|
|
23800
|
+
} else {
|
|
23801
|
+
listRef.current?.scrollToOffset({
|
|
23802
|
+
offset: nextScrollY,
|
|
23803
|
+
animated: false
|
|
23804
|
+
});
|
|
23805
|
+
}
|
|
23806
|
+
lastScrollOffsetYRef.current = nextScrollY;
|
|
23807
|
+
const endPageWidth = getPageWidthForZoom(pendingRestore.pageIndex, zoom);
|
|
23808
|
+
const pageViewportContentWidth = Math.max(
|
|
23809
|
+
0,
|
|
23810
|
+
pendingRestore.pageViewportWidth - pendingRestore.pageHorizontalPadding * 2
|
|
23811
|
+
);
|
|
23812
|
+
const nextOffsetX = resolveAnchoredViewportOffset({
|
|
23813
|
+
viewportOffset: pendingRestore.pageViewportContentOffsetX,
|
|
23814
|
+
startScrollOffset: pendingRestore.startPageScrollX,
|
|
23815
|
+
startItemOffset: 0,
|
|
23816
|
+
startItemLength: pendingRestore.startPageWidth,
|
|
23817
|
+
endItemOffset: 0,
|
|
23818
|
+
endItemLength: endPageWidth,
|
|
23819
|
+
viewportLength: pageViewportContentWidth,
|
|
23820
|
+
endContentLength: endPageWidth
|
|
23821
|
+
});
|
|
23822
|
+
const requestId = nextHorizontalRestoreRequestIdRef.current + 1;
|
|
23823
|
+
nextHorizontalRestoreRequestIdRef.current = requestId;
|
|
23824
|
+
setHorizontalScrollRestore({
|
|
23825
|
+
pageIndex: pendingRestore.pageIndex,
|
|
23826
|
+
requestId,
|
|
23827
|
+
offsetX: nextOffsetX
|
|
23828
|
+
});
|
|
23829
|
+
pendingPinchAnchorRestoreRef.current = null;
|
|
23830
|
+
if (perfEnabled) {
|
|
23831
|
+
logPerfEvent("Viewer", "pinch.anchorRestore", {
|
|
23832
|
+
page: pendingRestore.pageIndex + 1,
|
|
23833
|
+
scrollY: Math.round(nextScrollY * 100) / 100,
|
|
23834
|
+
scrollX: Math.round(nextOffsetX * 100) / 100,
|
|
23835
|
+
zoom: Math.round(zoom * 100) / 100
|
|
23836
|
+
});
|
|
23837
|
+
}
|
|
23838
|
+
});
|
|
23839
|
+
return () => {
|
|
23840
|
+
if (pinchAnchorRestoreFrameRef.current !== null) {
|
|
23841
|
+
cancelAnimationFrame(pinchAnchorRestoreFrameRef.current);
|
|
23842
|
+
pinchAnchorRestoreFrameRef.current = null;
|
|
23843
|
+
}
|
|
23844
|
+
};
|
|
23845
|
+
}, [getPageLayoutForZoom, getPageWidthForZoom, isSingle, perfEnabled, zoom]);
|
|
23846
|
+
useEffect3(() => {
|
|
23847
|
+
if (zoom > 1) return;
|
|
23848
|
+
setHorizontalScrollRestore((current) => {
|
|
23849
|
+
if (!current || Math.abs(current.offsetX) < 0.5) {
|
|
23850
|
+
return current;
|
|
23851
|
+
}
|
|
23852
|
+
const requestId = nextHorizontalRestoreRequestIdRef.current + 1;
|
|
23853
|
+
nextHorizontalRestoreRequestIdRef.current = requestId;
|
|
23854
|
+
return {
|
|
23855
|
+
pageIndex: current.pageIndex,
|
|
23856
|
+
requestId,
|
|
23857
|
+
offsetX: 0
|
|
23858
|
+
};
|
|
23859
|
+
});
|
|
23860
|
+
}, [zoom]);
|
|
23861
|
+
const captureViewerFrame = useCallback2((node) => {
|
|
23862
|
+
const measurable = node;
|
|
23863
|
+
measurable?.measureInWindow?.((_, y, __, height) => {
|
|
23864
|
+
viewerFrameRef.current = { y, height };
|
|
23865
|
+
});
|
|
23866
|
+
}, []);
|
|
23867
|
+
const scrollViewerBy = useCallback2(
|
|
23868
|
+
(deltaY) => {
|
|
23869
|
+
if (!Number.isFinite(deltaY) || deltaY === 0) return 0;
|
|
23870
|
+
const viewportHeight = viewerFrameRef.current.height;
|
|
23871
|
+
const maxOffset = Math.max(
|
|
23872
|
+
0,
|
|
23873
|
+
viewerContentHeightRef.current - viewportHeight
|
|
23874
|
+
);
|
|
23875
|
+
const nextOffset = Math.max(
|
|
23876
|
+
0,
|
|
23877
|
+
Math.min(maxOffset, lastScrollOffsetYRef.current + deltaY)
|
|
23878
|
+
);
|
|
23879
|
+
const appliedDelta = nextOffset - lastScrollOffsetYRef.current;
|
|
23880
|
+
if (appliedDelta === 0) return 0;
|
|
23881
|
+
lastScrollOffsetYRef.current = nextOffset;
|
|
23882
|
+
if (isSingle) {
|
|
23883
|
+
listRef.current?.scrollTo?.({
|
|
23884
|
+
y: nextOffset,
|
|
23885
|
+
animated: false
|
|
23886
|
+
});
|
|
23887
|
+
return appliedDelta;
|
|
23888
|
+
}
|
|
23889
|
+
listRef.current?.scrollToOffset({ offset: nextOffset, animated: false });
|
|
23890
|
+
return appliedDelta;
|
|
23891
|
+
},
|
|
23892
|
+
[isSingle]
|
|
23893
|
+
);
|
|
23894
|
+
const handleSelectionVerticalAutoscroll = useCallback2(
|
|
23895
|
+
(absoluteY) => {
|
|
23896
|
+
const frame = viewerFrameRef.current;
|
|
23897
|
+
if (!Number.isFinite(absoluteY) || frame.height <= 0) return 0;
|
|
23898
|
+
const relativeY = absoluteY - frame.y;
|
|
23899
|
+
const { dy } = getSelectionEdgeAutoscroll({
|
|
23900
|
+
x: SELECTION_EDGE_THRESHOLD_PX2,
|
|
23901
|
+
y: relativeY,
|
|
23902
|
+
width: SELECTION_EDGE_THRESHOLD_PX2 * 2,
|
|
23903
|
+
height: frame.height,
|
|
23904
|
+
threshold: SELECTION_EDGE_THRESHOLD_PX2,
|
|
23905
|
+
maxStep: SELECTION_EDGE_MAX_STEP_PX2
|
|
23906
|
+
});
|
|
23907
|
+
return scrollViewerBy(dy);
|
|
23908
|
+
},
|
|
23909
|
+
[scrollViewerBy]
|
|
23910
|
+
);
|
|
23113
23911
|
const listLayoutMetrics = useMemo3(() => {
|
|
23114
23912
|
const offsets = [];
|
|
23115
23913
|
const lengths = [];
|
|
@@ -23350,7 +24148,13 @@ var Viewer = ({
|
|
|
23350
24148
|
pageIndex: row.left,
|
|
23351
24149
|
availableWidth: columnWidth,
|
|
23352
24150
|
horizontalPadding: 8,
|
|
23353
|
-
spacing: DOUBLE_PAGE_SPACING
|
|
24151
|
+
spacing: DOUBLE_PAGE_SPACING,
|
|
24152
|
+
onSelectionDragActiveChange: setSelectionDragActive,
|
|
24153
|
+
gestureScrollLockActive,
|
|
24154
|
+
lastPinchEndedAt,
|
|
24155
|
+
onHorizontalScrollOffsetChange: handlePageHorizontalScrollOffsetChange,
|
|
24156
|
+
horizontalScrollRestore,
|
|
24157
|
+
requestSelectionVerticalAutoscroll: handleSelectionVerticalAutoscroll
|
|
23354
24158
|
}
|
|
23355
24159
|
) }),
|
|
23356
24160
|
row.right !== null ? /* @__PURE__ */ jsx3(View3, { style: { width: columnWidth }, children: /* @__PURE__ */ jsx3(
|
|
@@ -23360,7 +24164,13 @@ var Viewer = ({
|
|
|
23360
24164
|
pageIndex: row.right,
|
|
23361
24165
|
availableWidth: columnWidth,
|
|
23362
24166
|
horizontalPadding: 8,
|
|
23363
|
-
spacing: DOUBLE_PAGE_SPACING
|
|
24167
|
+
spacing: DOUBLE_PAGE_SPACING,
|
|
24168
|
+
onSelectionDragActiveChange: setSelectionDragActive,
|
|
24169
|
+
gestureScrollLockActive,
|
|
24170
|
+
lastPinchEndedAt,
|
|
24171
|
+
onHorizontalScrollOffsetChange: handlePageHorizontalScrollOffsetChange,
|
|
24172
|
+
horizontalScrollRestore,
|
|
24173
|
+
requestSelectionVerticalAutoscroll: handleSelectionVerticalAutoscroll
|
|
23364
24174
|
}
|
|
23365
24175
|
) }) : /* @__PURE__ */ jsx3(View3, { style: { width: columnWidth } })
|
|
23366
24176
|
] });
|
|
@@ -23370,114 +24180,170 @@ var Viewer = ({
|
|
|
23370
24180
|
{
|
|
23371
24181
|
engine,
|
|
23372
24182
|
pageIndex: item,
|
|
23373
|
-
spacing: CONTINUOUS_PAGE_SPACING
|
|
24183
|
+
spacing: CONTINUOUS_PAGE_SPACING,
|
|
24184
|
+
onSelectionDragActiveChange: setSelectionDragActive,
|
|
24185
|
+
gestureScrollLockActive,
|
|
24186
|
+
lastPinchEndedAt,
|
|
24187
|
+
onHorizontalScrollOffsetChange: handlePageHorizontalScrollOffsetChange,
|
|
24188
|
+
horizontalScrollRestore,
|
|
24189
|
+
requestSelectionVerticalAutoscroll: handleSelectionVerticalAutoscroll
|
|
23374
24190
|
}
|
|
23375
24191
|
);
|
|
23376
24192
|
},
|
|
23377
|
-
[
|
|
24193
|
+
[
|
|
24194
|
+
columnWidth,
|
|
24195
|
+
engine,
|
|
24196
|
+
handlePageHorizontalScrollOffsetChange,
|
|
24197
|
+
handleSelectionVerticalAutoscroll,
|
|
24198
|
+
gestureScrollLockActive,
|
|
24199
|
+
horizontalScrollRestore,
|
|
24200
|
+
horizontalPadding,
|
|
24201
|
+
isDouble,
|
|
24202
|
+
lastPinchEndedAt
|
|
24203
|
+
]
|
|
23378
24204
|
);
|
|
23379
24205
|
if (isWebView) {
|
|
23380
24206
|
return /* @__PURE__ */ jsx3(View3, { style: [styles3.container, isDark && styles3.containerDark], children: /* @__PURE__ */ jsx3(WebViewViewer_default, { engine }) });
|
|
23381
24207
|
}
|
|
23382
24208
|
if (isSingle) {
|
|
23383
|
-
return /* @__PURE__ */ jsx3(View3, { style: [styles3.container, isDark && styles3.containerDark], children: /* @__PURE__ */ jsx3(
|
|
23384
|
-
|
|
24209
|
+
return /* @__PURE__ */ jsx3(View3, { style: [styles3.container, isDark && styles3.containerDark], children: /* @__PURE__ */ jsx3(GestureDetector2, { gesture: viewerPinchGesture, children: /* @__PURE__ */ jsx3(
|
|
24210
|
+
View3,
|
|
23385
24211
|
{
|
|
23386
|
-
|
|
23387
|
-
|
|
23388
|
-
|
|
23389
|
-
|
|
23390
|
-
onScrollBeginDrag: perfEnabled ? () => {
|
|
23391
|
-
scrollMonitorRef.current.begin("single.beginDrag");
|
|
23392
|
-
} : void 0,
|
|
23393
|
-
onMomentumScrollBegin: perfEnabled ? () => {
|
|
23394
|
-
scrollMonitorRef.current.begin("single.momentumBegin");
|
|
23395
|
-
} : void 0,
|
|
23396
|
-
onScrollEndDrag: perfEnabled ? () => {
|
|
23397
|
-
scrollMonitorRef.current.end("single.endDrag");
|
|
23398
|
-
sampleMemory("Viewer", "single.endDrag", { pageCount });
|
|
23399
|
-
} : void 0,
|
|
23400
|
-
onMomentumScrollEnd: perfEnabled ? () => {
|
|
23401
|
-
scrollMonitorRef.current.end("single.momentumEnd");
|
|
23402
|
-
sampleMemory("Viewer", "single.momentumEnd", { pageCount });
|
|
23403
|
-
} : void 0,
|
|
23404
|
-
scrollEventThrottle: 16,
|
|
24212
|
+
style: [
|
|
24213
|
+
styles3.gestureSurface,
|
|
24214
|
+
{ transform: [{ scale: pinchPreviewScale }] }
|
|
24215
|
+
],
|
|
23405
24216
|
children: /* @__PURE__ */ jsx3(
|
|
23406
|
-
|
|
24217
|
+
ScrollView2,
|
|
23407
24218
|
{
|
|
23408
|
-
|
|
23409
|
-
|
|
23410
|
-
|
|
24219
|
+
ref: (node) => {
|
|
24220
|
+
captureViewerFrame(node);
|
|
24221
|
+
listRef.current = node;
|
|
24222
|
+
},
|
|
24223
|
+
contentContainerStyle: styles3.singleContent,
|
|
24224
|
+
showsVerticalScrollIndicator: false,
|
|
24225
|
+
scrollEnabled: resolvedViewerScrollEnabled,
|
|
24226
|
+
onLayout: () => captureViewerFrame(listRef.current),
|
|
24227
|
+
onContentSizeChange: (_, height) => {
|
|
24228
|
+
viewerContentHeightRef.current = height;
|
|
24229
|
+
},
|
|
24230
|
+
onScroll: (event) => handleViewerScroll(event, "single"),
|
|
24231
|
+
onScrollBeginDrag: perfEnabled ? () => {
|
|
24232
|
+
scrollMonitorRef.current.begin("single.beginDrag");
|
|
24233
|
+
} : void 0,
|
|
24234
|
+
onMomentumScrollBegin: perfEnabled ? () => {
|
|
24235
|
+
scrollMonitorRef.current.begin("single.momentumBegin");
|
|
24236
|
+
} : void 0,
|
|
24237
|
+
onScrollEndDrag: perfEnabled ? () => {
|
|
24238
|
+
scrollMonitorRef.current.end("single.endDrag");
|
|
24239
|
+
sampleMemory("Viewer", "single.endDrag", { pageCount });
|
|
24240
|
+
} : void 0,
|
|
24241
|
+
onMomentumScrollEnd: perfEnabled ? () => {
|
|
24242
|
+
scrollMonitorRef.current.end("single.momentumEnd");
|
|
24243
|
+
sampleMemory("Viewer", "single.momentumEnd", {
|
|
24244
|
+
pageCount
|
|
24245
|
+
});
|
|
24246
|
+
} : void 0,
|
|
24247
|
+
scrollEventThrottle: 16,
|
|
24248
|
+
children: /* @__PURE__ */ jsx3(
|
|
24249
|
+
PageRenderer_default,
|
|
24250
|
+
{
|
|
24251
|
+
engine,
|
|
24252
|
+
pageIndex: Math.max(0, currentPage - 1),
|
|
24253
|
+
spacing: 32,
|
|
24254
|
+
onSelectionDragActiveChange: setSelectionDragActive,
|
|
24255
|
+
gestureScrollLockActive,
|
|
24256
|
+
lastPinchEndedAt,
|
|
24257
|
+
onHorizontalScrollOffsetChange: handlePageHorizontalScrollOffsetChange,
|
|
24258
|
+
horizontalScrollRestore,
|
|
24259
|
+
requestSelectionVerticalAutoscroll: handleSelectionVerticalAutoscroll
|
|
24260
|
+
}
|
|
24261
|
+
)
|
|
23411
24262
|
}
|
|
23412
24263
|
)
|
|
23413
24264
|
}
|
|
23414
|
-
) });
|
|
24265
|
+
) }) });
|
|
23415
24266
|
}
|
|
23416
|
-
return /* @__PURE__ */ jsx3(View3, { style: [styles3.container, isDark && styles3.containerDark], children: /* @__PURE__ */ jsx3(
|
|
23417
|
-
|
|
24267
|
+
return /* @__PURE__ */ jsx3(View3, { style: [styles3.container, isDark && styles3.containerDark], children: /* @__PURE__ */ jsx3(GestureDetector2, { gesture: viewerPinchGesture, children: /* @__PURE__ */ jsx3(
|
|
24268
|
+
View3,
|
|
23418
24269
|
{
|
|
23419
|
-
|
|
23420
|
-
|
|
23421
|
-
|
|
23422
|
-
|
|
23423
|
-
|
|
23424
|
-
|
|
23425
|
-
|
|
23426
|
-
|
|
23427
|
-
|
|
23428
|
-
|
|
23429
|
-
|
|
23430
|
-
|
|
23431
|
-
|
|
23432
|
-
|
|
23433
|
-
|
|
23434
|
-
|
|
23435
|
-
|
|
23436
|
-
|
|
23437
|
-
|
|
23438
|
-
|
|
23439
|
-
|
|
23440
|
-
|
|
23441
|
-
|
|
23442
|
-
|
|
23443
|
-
|
|
23444
|
-
|
|
23445
|
-
|
|
23446
|
-
|
|
24270
|
+
style: [
|
|
24271
|
+
styles3.gestureSurface,
|
|
24272
|
+
{ transform: [{ scale: pinchPreviewScale }] }
|
|
24273
|
+
],
|
|
24274
|
+
children: /* @__PURE__ */ jsx3(
|
|
24275
|
+
FlatList,
|
|
24276
|
+
{
|
|
24277
|
+
ref: listRef,
|
|
24278
|
+
data: isDouble ? rows : pages,
|
|
24279
|
+
initialNumToRender: FLATLIST_INITIAL_NUM_TO_RENDER,
|
|
24280
|
+
windowSize: resolvedWindowSize,
|
|
24281
|
+
maxToRenderPerBatch: resolvedMaxToRenderPerBatch,
|
|
24282
|
+
updateCellsBatchingPeriod: FLATLIST_UPDATE_CELLS_BATCHING_PERIOD,
|
|
24283
|
+
removeClippedSubviews: resolvedRemoveClippedSubviews,
|
|
24284
|
+
getItemLayout,
|
|
24285
|
+
keyExtractor,
|
|
24286
|
+
contentContainerStyle: styles3.listContent,
|
|
24287
|
+
renderItem,
|
|
24288
|
+
onViewableItemsChanged,
|
|
24289
|
+
viewabilityConfig: { itemVisiblePercentThreshold: 60 },
|
|
24290
|
+
scrollEnabled: resolvedViewerScrollEnabled,
|
|
24291
|
+
onLayout: () => captureViewerFrame(listRef.current),
|
|
24292
|
+
onContentSizeChange: (_, height) => {
|
|
24293
|
+
viewerContentHeightRef.current = height;
|
|
24294
|
+
},
|
|
24295
|
+
onScrollToIndexFailed: ({ index, averageItemLength }) => {
|
|
24296
|
+
const dataLength = isDouble ? rows.length : pages.length;
|
|
24297
|
+
if (index < 0 || index >= dataLength) return;
|
|
24298
|
+
pendingScrollIndexRef.current = index;
|
|
24299
|
+
const offset = Math.max(0, getFallbackOffsetForIndex(index));
|
|
24300
|
+
listRef.current?.scrollToOffset({ offset, animated: false });
|
|
24301
|
+
if (!isDouble) {
|
|
24302
|
+
ensurePageDimensions(index);
|
|
24303
|
+
} else {
|
|
24304
|
+
const row = rows[index];
|
|
24305
|
+
if (row) {
|
|
24306
|
+
ensurePageDimensions(row.left);
|
|
24307
|
+
if (row.right !== null) {
|
|
24308
|
+
ensurePageDimensions(row.right);
|
|
24309
|
+
}
|
|
24310
|
+
}
|
|
23447
24311
|
}
|
|
23448
|
-
|
|
23449
|
-
|
|
23450
|
-
|
|
23451
|
-
|
|
23452
|
-
|
|
23453
|
-
|
|
23454
|
-
|
|
23455
|
-
|
|
23456
|
-
|
|
23457
|
-
|
|
23458
|
-
|
|
23459
|
-
}
|
|
24312
|
+
scheduleScrollRetry("onScrollToIndexFailed");
|
|
24313
|
+
if (perfEnabled) {
|
|
24314
|
+
logPerfEvent("Viewer", "scrollToIndexFailed", {
|
|
24315
|
+
index,
|
|
24316
|
+
averageItemLength,
|
|
24317
|
+
fallbackOffset: offset,
|
|
24318
|
+
fallbackSource: "cached-item-layout",
|
|
24319
|
+
itemCount: dataLength,
|
|
24320
|
+
retryAttempt: pendingScrollAttemptsRef.current
|
|
24321
|
+
});
|
|
24322
|
+
}
|
|
24323
|
+
},
|
|
24324
|
+
onScroll: (event) => handleViewerScroll(event, "continuous"),
|
|
24325
|
+
onScrollBeginDrag: perfEnabled ? () => {
|
|
24326
|
+
scrollMonitorRef.current.begin("continuous.beginDrag");
|
|
24327
|
+
} : void 0,
|
|
24328
|
+
onMomentumScrollBegin: perfEnabled ? () => {
|
|
24329
|
+
scrollMonitorRef.current.begin("continuous.momentumBegin");
|
|
24330
|
+
} : void 0,
|
|
24331
|
+
onScrollEndDrag: perfEnabled ? () => {
|
|
24332
|
+
scrollMonitorRef.current.end("continuous.endDrag");
|
|
24333
|
+
sampleMemory("Viewer", "continuous.endDrag", { pageCount });
|
|
24334
|
+
} : void 0,
|
|
24335
|
+
onMomentumScrollEnd: perfEnabled ? () => {
|
|
24336
|
+
scrollMonitorRef.current.end("continuous.momentumEnd");
|
|
24337
|
+
sampleMemory("Viewer", "continuous.momentumEnd", {
|
|
24338
|
+
pageCount
|
|
24339
|
+
});
|
|
24340
|
+
} : void 0,
|
|
24341
|
+
scrollEventThrottle: 16,
|
|
24342
|
+
showsVerticalScrollIndicator: false
|
|
23460
24343
|
}
|
|
23461
|
-
|
|
23462
|
-
onScroll: (event) => handleViewerScroll(event, "continuous"),
|
|
23463
|
-
onScrollBeginDrag: perfEnabled ? () => {
|
|
23464
|
-
scrollMonitorRef.current.begin("continuous.beginDrag");
|
|
23465
|
-
} : void 0,
|
|
23466
|
-
onMomentumScrollBegin: perfEnabled ? () => {
|
|
23467
|
-
scrollMonitorRef.current.begin("continuous.momentumBegin");
|
|
23468
|
-
} : void 0,
|
|
23469
|
-
onScrollEndDrag: perfEnabled ? () => {
|
|
23470
|
-
scrollMonitorRef.current.end("continuous.endDrag");
|
|
23471
|
-
sampleMemory("Viewer", "continuous.endDrag", { pageCount });
|
|
23472
|
-
} : void 0,
|
|
23473
|
-
onMomentumScrollEnd: perfEnabled ? () => {
|
|
23474
|
-
scrollMonitorRef.current.end("continuous.momentumEnd");
|
|
23475
|
-
sampleMemory("Viewer", "continuous.momentumEnd", { pageCount });
|
|
23476
|
-
} : void 0,
|
|
23477
|
-
scrollEventThrottle: 16,
|
|
23478
|
-
showsVerticalScrollIndicator: false
|
|
24344
|
+
)
|
|
23479
24345
|
}
|
|
23480
|
-
) });
|
|
24346
|
+
) }) });
|
|
23481
24347
|
};
|
|
23482
24348
|
var styles3 = StyleSheet3.create({
|
|
23483
24349
|
container: {
|
|
@@ -23487,6 +24353,9 @@ var styles3 = StyleSheet3.create({
|
|
|
23487
24353
|
containerDark: {
|
|
23488
24354
|
backgroundColor: "#0f1115"
|
|
23489
24355
|
},
|
|
24356
|
+
gestureSurface: {
|
|
24357
|
+
flex: 1
|
|
24358
|
+
},
|
|
23490
24359
|
listContent: {
|
|
23491
24360
|
paddingTop: LIST_TOP_PADDING,
|
|
23492
24361
|
paddingBottom: LIST_BOTTOM_PADDING
|
|
@@ -24166,6 +25035,7 @@ var ToolDock = () => {
|
|
|
24166
25035
|
setAnnotationColor,
|
|
24167
25036
|
accentColor,
|
|
24168
25037
|
activeTool,
|
|
25038
|
+
interactionMode,
|
|
24169
25039
|
toolDockOpen,
|
|
24170
25040
|
setDocumentState
|
|
24171
25041
|
} = useViewerStore5();
|
|
@@ -24177,7 +25047,12 @@ var ToolDock = () => {
|
|
|
24177
25047
|
/* @__PURE__ */ jsx6(
|
|
24178
25048
|
Pressable3,
|
|
24179
25049
|
{
|
|
24180
|
-
onPress: () => setDocumentState(
|
|
25050
|
+
onPress: () => setDocumentState(
|
|
25051
|
+
getToolDockDismissState({
|
|
25052
|
+
activeTool,
|
|
25053
|
+
interactionMode
|
|
25054
|
+
})
|
|
25055
|
+
),
|
|
24181
25056
|
style: [styles5.closeButton, isDark && styles5.closeButtonDark],
|
|
24182
25057
|
children: /* @__PURE__ */ jsx6(
|
|
24183
25058
|
Text2,
|
|
@@ -24190,12 +25065,29 @@ var ToolDock = () => {
|
|
|
24190
25065
|
)
|
|
24191
25066
|
] }),
|
|
24192
25067
|
/* @__PURE__ */ jsx6(View5, { style: styles5.toolsRow, children: TOOL_OPTIONS.map((tool) => {
|
|
24193
|
-
const isSelected =
|
|
25068
|
+
const isSelected = isToolDockToolSelected({
|
|
25069
|
+
toolId: tool.id,
|
|
25070
|
+
activeTool,
|
|
25071
|
+
interactionMode
|
|
25072
|
+
});
|
|
24194
25073
|
const label = tool.label === "note" ? t.note : tool.label === "select" ? t.select : tool.label === "underline" ? t.underline : tool.label === "squiggly" ? t.squiggly : tool.label === "strikeout" ? t.strikeout : tool.label === "ink" ? t.ink : t.highlight;
|
|
24195
25074
|
return /* @__PURE__ */ jsx6(
|
|
24196
25075
|
Pressable3,
|
|
24197
25076
|
{
|
|
24198
|
-
onPress: () =>
|
|
25077
|
+
onPress: () => {
|
|
25078
|
+
if (tool.id === "select") {
|
|
25079
|
+
const shouldArmSelection = activeTool !== "select" || interactionMode !== "select";
|
|
25080
|
+
setDocumentState({
|
|
25081
|
+
activeTool: "select",
|
|
25082
|
+
interactionMode: shouldArmSelection ? "select" : "pan"
|
|
25083
|
+
});
|
|
25084
|
+
return;
|
|
25085
|
+
}
|
|
25086
|
+
setDocumentState({
|
|
25087
|
+
activeTool: tool.id,
|
|
25088
|
+
interactionMode: "pan"
|
|
25089
|
+
});
|
|
25090
|
+
},
|
|
24199
25091
|
style: [
|
|
24200
25092
|
styles5.toolButton,
|
|
24201
25093
|
isDark && styles5.toolButtonDark,
|