@papyrus-sdk/ui-react-native 0.2.15 → 0.2.17

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/dist/index.mjs CHANGED
@@ -1,12 +1,13 @@
1
1
  import {
2
2
  DEFAULT_PINCH_ZOOM_BOUNDS,
3
3
  resolveAnchoredViewportOffset,
4
- resolveClampedScrollOffset,
4
+ resolveDocumentSurfaceWidth,
5
+ resolveGlobalHorizontalOffset,
5
6
  resolvePinchGestureZoom,
6
7
  resolvePinchPreviewScale,
7
8
  sanitizePinchPreviewScale,
8
9
  shouldSuppressPressAfterPinch
9
- } from "./chunk-PE5U4ZWV.mjs";
10
+ } from "./chunk-3IPQ5HO7.mjs";
10
11
  import {
11
12
  getSelectionEdgeAutoscroll,
12
13
  getToolDockDismissState,
@@ -21014,7 +21015,7 @@ import {
21014
21015
  } from "react";
21015
21016
  import {
21016
21017
  FlatList,
21017
- ScrollView as ScrollView2,
21018
+ ScrollView,
21018
21019
  StyleSheet as StyleSheet3,
21019
21020
  View as View3,
21020
21021
  useWindowDimensions as useWindowDimensions2
@@ -21035,7 +21036,6 @@ import {
21035
21036
  View,
21036
21037
  StyleSheet,
21037
21038
  Pressable,
21038
- ScrollView,
21039
21039
  PanResponder,
21040
21040
  Platform,
21041
21041
  findNodeHandle,
@@ -21313,8 +21313,6 @@ var buildSquigglyPath = (segments = 16) => {
21313
21313
  return path;
21314
21314
  };
21315
21315
  var SQUIGGLY_PATH = buildSquigglyPath();
21316
- var SELECTION_EDGE_THRESHOLD_PX = 48;
21317
- var SELECTION_EDGE_MAX_STEP_PX = 24;
21318
21316
  var SELECTION_AUTOSCROLL_INTERVAL_MS = 16;
21319
21317
  var PageRenderer = ({
21320
21318
  engine,
@@ -21323,17 +21321,15 @@ var PageRenderer = ({
21323
21321
  pageAspectRatio,
21324
21322
  PageViewComponent = PapyrusPageView,
21325
21323
  availableWidth,
21324
+ pageViewportWidth: providedPageViewportWidth,
21326
21325
  horizontalPadding = 16,
21327
21326
  spacing = 24,
21328
21327
  onSelectionDragActiveChange,
21329
21328
  gestureScrollLockActive = false,
21330
21329
  lastPinchEndedAt = null,
21331
- onHorizontalScrollOffsetChange,
21332
- horizontalScrollRestore = null,
21333
21330
  requestSelectionVerticalAutoscroll
21334
21331
  }) => {
21335
21332
  const viewRef = useRef(null);
21336
- const pageScrollRef = useRef(null);
21337
21333
  const [layout, setLayout] = useState({ width: 0, height: 0 });
21338
21334
  const [pageSize, setPageSize] = useState(null);
21339
21335
  const { width: windowWidth } = useWindowDimensions();
@@ -21341,10 +21337,8 @@ var PageRenderer = ({
21341
21337
  const perfEnabled = isMobilePerfEnabled();
21342
21338
  const renderCountRef = useRef(0);
21343
21339
  const inkDrawingActiveRef = useRef(false);
21344
- const horizontalScrollOffsetRef = useRef(0);
21345
21340
  const selectionDragActiveRef = useRef(false);
21346
21341
  const selectionDragPointRef = useRef(null);
21347
- const lastAppliedHorizontalRestoreRef = useRef(null);
21348
21342
  const selectionAutoscrollIntervalRef = useRef(null);
21349
21343
  const rawTouchMoveLoggedAtRef = useRef(0);
21350
21344
  const currentInkStyleRef = useRef({
@@ -21608,10 +21602,7 @@ var PageRenderer = ({
21608
21602
  setInkPoints([]);
21609
21603
  inkPointsRef.current = [];
21610
21604
  }, [resolvedActiveTool]);
21611
- const pageViewportWidth = Math.max(
21612
- 0,
21613
- (availableWidth ?? windowWidth) - horizontalPadding * 2
21614
- );
21605
+ const viewportWidth = providedPageViewportWidth ?? availableWidth ?? windowWidth;
21615
21606
  const selectionEnabled = Platform.OS === "web" || isNative && shouldEnableSelectionDrag({
21616
21607
  activeTool: resolvedActiveTool,
21617
21608
  interactionMode: resolvedInteractionMode
@@ -21759,35 +21750,12 @@ var PageRenderer = ({
21759
21750
  stopSelectionAutoscroll();
21760
21751
  return;
21761
21752
  }
21762
- const visibleX = point.x - horizontalScrollOffsetRef.current;
21763
- const { dx } = getSelectionEdgeAutoscroll({
21764
- x: visibleX,
21765
- y: SELECTION_EDGE_THRESHOLD_PX,
21766
- width: pageViewportWidth,
21767
- height: SELECTION_EDGE_THRESHOLD_PX * 2,
21768
- threshold: SELECTION_EDGE_THRESHOLD_PX,
21769
- maxStep: SELECTION_EDGE_MAX_STEP_PX
21770
- });
21771
- let appliedDx = 0;
21772
- if (dx !== 0 && pageViewportWidth > 0) {
21773
- const maxOffsetX = Math.max(0, layout.width - pageViewportWidth);
21774
- const nextOffsetX = clamp(
21775
- horizontalScrollOffsetRef.current + dx,
21776
- 0,
21777
- maxOffsetX
21778
- );
21779
- appliedDx = nextOffsetX - horizontalScrollOffsetRef.current;
21780
- if (appliedDx !== 0) {
21781
- horizontalScrollOffsetRef.current = nextOffsetX;
21782
- pageScrollRef.current?.scrollTo({ x: nextOffsetX, animated: false });
21783
- }
21784
- }
21785
21753
  const appliedDy = requestSelectionVerticalAutoscroll?.(point.absoluteY) ?? 0;
21786
- if (appliedDx === 0 && appliedDy === 0) {
21754
+ if (appliedDy === 0) {
21787
21755
  stopSelectionAutoscroll();
21788
21756
  return;
21789
21757
  }
21790
- const nextX = clamp(point.x + appliedDx, 0, layout.width);
21758
+ const nextX = point.x;
21791
21759
  const nextY = clamp(point.y + appliedDy, 0, layout.height);
21792
21760
  selectionDragPointRef.current = {
21793
21761
  absoluteY: point.absoluteY,
@@ -21798,7 +21766,6 @@ var PageRenderer = ({
21798
21766
  }, [
21799
21767
  layout.height,
21800
21768
  layout.width,
21801
- pageViewportWidth,
21802
21769
  requestSelectionVerticalAutoscroll,
21803
21770
  stopSelectionAutoscroll,
21804
21771
  updateSelectionRectFromPoint
@@ -22248,56 +22215,19 @@ var PageRenderer = ({
22248
22215
  const baseWidth = containerWidth * 0.92;
22249
22216
  const pageWidth = isNative ? baseWidth * zoom : baseWidth;
22250
22217
  const pageHeight = pageWidth / aspectRatio;
22251
- const hasActiveSelection = selectionRects.length > 0 || !!selectionBounds || isSelecting;
22252
- const scrollEnabled = isNative && zoom > 1 && !hasActiveSelection && !isInkDrawing && !gestureScrollLockActive;
22253
- useEffect(() => {
22254
- if (!horizontalScrollRestore) return;
22255
- if (lastAppliedHorizontalRestoreRef.current === horizontalScrollRestore.requestId) {
22256
- return;
22257
- }
22258
- const nextOffsetX = resolveClampedScrollOffset(
22259
- horizontalScrollRestore.offsetX,
22260
- pageWidth,
22261
- pageViewportWidth
22262
- );
22263
- lastAppliedHorizontalRestoreRef.current = horizontalScrollRestore.requestId;
22264
- horizontalScrollOffsetRef.current = nextOffsetX;
22265
- pageScrollRef.current?.scrollTo({ x: nextOffsetX, animated: false });
22266
- onHorizontalScrollOffsetChange?.(pageIndex, nextOffsetX);
22267
- }, [
22268
- horizontalScrollRestore,
22269
- onHorizontalScrollOffsetChange,
22270
- pageIndex,
22271
- pageViewportWidth,
22272
- pageWidth
22273
- ]);
22218
+ const pageFrameWidth = Math.max(
22219
+ viewportWidth,
22220
+ pageWidth + horizontalPadding * 2
22221
+ );
22274
22222
  return /* @__PURE__ */ jsx(
22275
- ScrollView,
22223
+ View,
22276
22224
  {
22277
- ref: pageScrollRef,
22278
- horizontal: true,
22279
- scrollEnabled,
22280
- showsHorizontalScrollIndicator: false,
22281
- onScroll: (event) => {
22282
- const nextOffsetX = event.nativeEvent.contentOffset?.x ?? 0;
22283
- horizontalScrollOffsetRef.current = nextOffsetX;
22284
- },
22285
- onScrollEndDrag: () => {
22286
- onHorizontalScrollOffsetChange?.(
22287
- pageIndex,
22288
- horizontalScrollOffsetRef.current
22289
- );
22290
- },
22291
- onMomentumScrollEnd: () => {
22292
- onHorizontalScrollOffsetChange?.(
22293
- pageIndex,
22294
- horizontalScrollOffsetRef.current
22295
- );
22296
- },
22297
- scrollEventThrottle: 16,
22298
- contentContainerStyle: [
22225
+ style: [
22299
22226
  styles.scrollContent,
22300
- { paddingHorizontal: horizontalPadding }
22227
+ {
22228
+ width: pageFrameWidth,
22229
+ paddingHorizontal: horizontalPadding
22230
+ }
22301
22231
  ],
22302
22232
  children: /* @__PURE__ */ jsx(GestureDetector, { gesture: contentGesture, children: /* @__PURE__ */ jsxs(
22303
22233
  Pressable,
@@ -22998,7 +22928,7 @@ var styles = StyleSheet.create({
22998
22928
  borderRadius: 3
22999
22929
  }
23000
22930
  });
23001
- 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;
22931
+ 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.pageViewportWidth === next.pageViewportWidth && previous.horizontalPadding === next.horizontalPadding && previous.spacing === next.spacing && previous.onSelectionDragActiveChange === next.onSelectionDragActiveChange && previous.gestureScrollLockActive === next.gestureScrollLockActive && previous.lastPinchEndedAt === next.lastPinchEndedAt && previous.requestSelectionVerticalAutoscroll === next.requestSelectionVerticalAutoscroll;
23002
22932
  var PageRenderer_default = memo(PageRenderer, arePageRendererPropsEqual);
23003
22933
 
23004
22934
  // components/WebViewViewer.tsx
@@ -23150,8 +23080,8 @@ var MOBILE_CHROME_HIDE_DELTA = 28;
23150
23080
  var MOBILE_CHROME_SHOW_DELTA = 22;
23151
23081
  var MOBILE_CHROME_SHOW_DELAY_MS = 180;
23152
23082
  var MOBILE_CHROME_TOP_RESET = 16;
23153
- var SELECTION_EDGE_THRESHOLD_PX2 = 48;
23154
- var SELECTION_EDGE_MAX_STEP_PX2 = 24;
23083
+ var SELECTION_EDGE_THRESHOLD_PX = 48;
23084
+ var SELECTION_EDGE_MAX_STEP_PX = 24;
23155
23085
  var resolvePositiveInt = (value, fallback, min, max) => {
23156
23086
  if (typeof value !== "number" || !Number.isFinite(value)) return fallback;
23157
23087
  const rounded = Math.round(value);
@@ -23176,6 +23106,7 @@ var Viewer = ({
23176
23106
  const viewMode = useViewerStore3((state) => state.viewMode);
23177
23107
  const zoom = useViewerStore3((state) => state.zoom);
23178
23108
  const listRef = useRef3(null);
23109
+ const horizontalScrollRef = useRef3(null);
23179
23110
  const isDark = uiTheme === "dark";
23180
23111
  const { width: windowWidth } = useWindowDimensions2();
23181
23112
  const isDouble = viewMode === "double";
@@ -23215,18 +23146,16 @@ var Viewer = ({
23215
23146
  const gestureScrollLockActiveRef = useRef3(false);
23216
23147
  const [pinchPreviewScale, setPinchPreviewScale] = useState2(1);
23217
23148
  const [lastPinchEndedAt, setLastPinchEndedAt] = useState2(null);
23218
- const [horizontalScrollRestore, setHorizontalScrollRestore] = useState2(null);
23219
23149
  const pinchGestureActiveRef = useRef3(false);
23220
23150
  const pinchStartZoomRef = useRef3(1);
23221
23151
  const pinchPreviewZoomRef = useRef3(1);
23222
23152
  const pinchFocalPointRef = useRef3({ x: 0, y: 0 });
23223
23153
  const pinchUpdateLoggedAtRef = useRef3(0);
23224
- const horizontalScrollOffsetsRef = useRef3(/* @__PURE__ */ new Map());
23154
+ const horizontalScrollOffsetRef = useRef3(0);
23225
23155
  const pendingPinchAnchorRestoreRef = useRef3(
23226
23156
  null
23227
23157
  );
23228
23158
  const pinchAnchorRestoreFrameRef = useRef3(null);
23229
- const nextHorizontalRestoreRequestIdRef = useRef3(0);
23230
23159
  const viewerFrameRef = useRef3({ y: 0, height: 0 });
23231
23160
  const viewerContentHeightRef = useRef3(0);
23232
23161
  const resolvedWindowSize = useMemo3(
@@ -23526,6 +23455,30 @@ var Viewer = ({
23526
23455
  },
23527
23456
  [columnGap, columnWidth, horizontalPadding, isDouble, windowWidth]
23528
23457
  );
23458
+ const documentSurfaceWidth = useMemo3(() => {
23459
+ if (isDouble) {
23460
+ const leftPageWidth = getPageWidthForZoom(0, zoom);
23461
+ const doubleContentWidth = leftPageWidth * 2 + columnGap;
23462
+ return resolveDocumentSurfaceWidth({
23463
+ viewportWidth: windowWidth,
23464
+ contentWidth: doubleContentWidth,
23465
+ horizontalPadding
23466
+ });
23467
+ }
23468
+ return resolveDocumentSurfaceWidth({
23469
+ viewportWidth: windowWidth,
23470
+ contentWidth: getPageWidthForZoom(currentPage - 1, zoom),
23471
+ horizontalPadding
23472
+ });
23473
+ }, [
23474
+ columnGap,
23475
+ currentPage,
23476
+ getPageWidthForZoom,
23477
+ horizontalPadding,
23478
+ isDouble,
23479
+ windowWidth,
23480
+ zoom
23481
+ ]);
23529
23482
  const getPageLayoutForZoom = useCallback2(
23530
23483
  (pageIndex, zoomValue) => {
23531
23484
  if (isSingle) {
@@ -23760,7 +23713,7 @@ var Viewer = ({
23760
23713
  startPageOffsetY,
23761
23714
  startPageHeight,
23762
23715
  startPageWidth,
23763
- startPageScrollX: horizontalScrollOffsetsRef.current.get(anchorPageIndex) ?? 0,
23716
+ startSurfaceScrollX: horizontalScrollOffsetRef.current,
23764
23717
  pageViewportWidth,
23765
23718
  pageHorizontalPadding,
23766
23719
  pageViewportContentOffsetX: Math.max(
@@ -23796,34 +23749,21 @@ var Viewer = ({
23796
23749
  setDocumentStateTracked,
23797
23750
  zoom
23798
23751
  ]);
23799
- const handlePageHorizontalScrollOffsetChange = useCallback2(
23800
- (pageIndex, offsetX) => {
23801
- horizontalScrollOffsetsRef.current.set(pageIndex, Math.max(0, offsetX));
23802
- const pageWidth = getPageWidthForZoom(pageIndex, zoom);
23803
- const { viewportWidth, horizontalPadding: horizontalPadding2 } = getPageViewportMetrics(pageIndex);
23804
- const pageViewportWidth = Math.max(
23805
- 0,
23806
- viewportWidth - horizontalPadding2 * 2
23807
- );
23808
- const nextOffsetX = resolveClampedScrollOffset(
23752
+ const scrollHorizontalSurfaceTo = useCallback2(
23753
+ (offsetX) => {
23754
+ const nextOffsetX = resolveGlobalHorizontalOffset({
23809
23755
  offsetX,
23810
- pageWidth,
23811
- pageViewportWidth
23812
- );
23813
- setHorizontalScrollRestore((current) => {
23814
- if (current && Math.abs(current.offsetX - nextOffsetX) < 0.5) {
23815
- return current;
23816
- }
23817
- const requestId = nextHorizontalRestoreRequestIdRef.current + 1;
23818
- nextHorizontalRestoreRequestIdRef.current = requestId;
23819
- return {
23820
- pageIndex,
23821
- requestId,
23822
- offsetX: nextOffsetX
23823
- };
23756
+ surfaceWidth: documentSurfaceWidth,
23757
+ viewportWidth: windowWidth
23758
+ });
23759
+ horizontalScrollOffsetRef.current = nextOffsetX;
23760
+ horizontalScrollRef.current?.scrollTo({
23761
+ x: nextOffsetX,
23762
+ animated: false
23824
23763
  });
23764
+ return nextOffsetX;
23825
23765
  },
23826
- [getPageViewportMetrics, getPageWidthForZoom, zoom]
23766
+ [documentSurfaceWidth, windowWidth]
23827
23767
  );
23828
23768
  const viewerPinchGesture = useMemo3(
23829
23769
  () => Gesture2.Pinch().enabled(!isWebView && pageCount > 0).onTouchesDown((event) => {
@@ -23906,7 +23846,7 @@ var Viewer = ({
23906
23846
  );
23907
23847
  const nextOffsetX = resolveAnchoredViewportOffset({
23908
23848
  viewportOffset: pendingRestore.pageViewportContentOffsetX,
23909
- startScrollOffset: pendingRestore.startPageScrollX,
23849
+ startScrollOffset: pendingRestore.startSurfaceScrollX,
23910
23850
  startItemOffset: 0,
23911
23851
  startItemLength: pendingRestore.startPageWidth,
23912
23852
  endItemOffset: 0,
@@ -23914,19 +23854,13 @@ var Viewer = ({
23914
23854
  viewportLength: pageViewportContentWidth,
23915
23855
  endContentLength: endPageWidth
23916
23856
  });
23917
- const requestId = nextHorizontalRestoreRequestIdRef.current + 1;
23918
- nextHorizontalRestoreRequestIdRef.current = requestId;
23919
- setHorizontalScrollRestore({
23920
- pageIndex: pendingRestore.pageIndex,
23921
- requestId,
23922
- offsetX: nextOffsetX
23923
- });
23857
+ const appliedOffsetX = scrollHorizontalSurfaceTo(nextOffsetX);
23924
23858
  pendingPinchAnchorRestoreRef.current = null;
23925
23859
  if (perfEnabled) {
23926
23860
  logPerfEvent("Viewer", "pinch.anchorRestore", {
23927
23861
  page: pendingRestore.pageIndex + 1,
23928
23862
  scrollY: Math.round(nextScrollY * 100) / 100,
23929
- scrollX: Math.round(nextOffsetX * 100) / 100,
23863
+ scrollX: Math.round(appliedOffsetX * 100) / 100,
23930
23864
  zoom: Math.round(zoom * 100) / 100
23931
23865
  });
23932
23866
  }
@@ -23937,22 +23871,18 @@ var Viewer = ({
23937
23871
  pinchAnchorRestoreFrameRef.current = null;
23938
23872
  }
23939
23873
  };
23940
- }, [getPageLayoutForZoom, getPageWidthForZoom, isSingle, perfEnabled, zoom]);
23874
+ }, [
23875
+ getPageLayoutForZoom,
23876
+ getPageWidthForZoom,
23877
+ isSingle,
23878
+ perfEnabled,
23879
+ scrollHorizontalSurfaceTo,
23880
+ zoom
23881
+ ]);
23941
23882
  useEffect3(() => {
23942
- if (zoom > 1) return;
23943
- setHorizontalScrollRestore((current) => {
23944
- if (!current || Math.abs(current.offsetX) < 0.5) {
23945
- return current;
23946
- }
23947
- const requestId = nextHorizontalRestoreRequestIdRef.current + 1;
23948
- nextHorizontalRestoreRequestIdRef.current = requestId;
23949
- return {
23950
- pageIndex: current.pageIndex,
23951
- requestId,
23952
- offsetX: 0
23953
- };
23954
- });
23955
- }, [zoom]);
23883
+ if (zoom > 1 && documentSurfaceWidth > windowWidth) return;
23884
+ scrollHorizontalSurfaceTo(0);
23885
+ }, [documentSurfaceWidth, scrollHorizontalSurfaceTo, windowWidth, zoom]);
23956
23886
  const captureViewerFrame = useCallback2((node) => {
23957
23887
  const measurable = node;
23958
23888
  measurable?.measureInWindow?.((_, y, __, height) => {
@@ -23992,12 +23922,12 @@ var Viewer = ({
23992
23922
  if (!Number.isFinite(absoluteY) || frame.height <= 0) return 0;
23993
23923
  const relativeY = absoluteY - frame.y;
23994
23924
  const { dy } = getSelectionEdgeAutoscroll({
23995
- x: SELECTION_EDGE_THRESHOLD_PX2,
23925
+ x: SELECTION_EDGE_THRESHOLD_PX,
23996
23926
  y: relativeY,
23997
- width: SELECTION_EDGE_THRESHOLD_PX2 * 2,
23927
+ width: SELECTION_EDGE_THRESHOLD_PX * 2,
23998
23928
  height: frame.height,
23999
- threshold: SELECTION_EDGE_THRESHOLD_PX2,
24000
- maxStep: SELECTION_EDGE_MAX_STEP_PX2
23929
+ threshold: SELECTION_EDGE_THRESHOLD_PX,
23930
+ maxStep: SELECTION_EDGE_MAX_STEP_PX
24001
23931
  });
24002
23932
  return scrollViewerBy(dy);
24003
23933
  },
@@ -24235,42 +24165,49 @@ var Viewer = ({
24235
24165
  ({ item }) => {
24236
24166
  if (isDouble) {
24237
24167
  const row = item;
24238
- return /* @__PURE__ */ jsxs3(View3, { style: [styles3.row, { paddingHorizontal: horizontalPadding }], children: [
24239
- /* @__PURE__ */ jsx3(View3, { style: { width: columnWidth }, children: /* @__PURE__ */ jsx3(
24240
- PageRenderer_default,
24241
- {
24242
- engine,
24243
- pageIndex: row.left,
24244
- pageAspectRatio: getPageAspectRatio(row.left),
24245
- availableWidth: columnWidth,
24246
- horizontalPadding: 8,
24247
- spacing: DOUBLE_PAGE_SPACING,
24248
- onSelectionDragActiveChange: setSelectionDragActive,
24249
- gestureScrollLockActive,
24250
- lastPinchEndedAt,
24251
- onHorizontalScrollOffsetChange: handlePageHorizontalScrollOffsetChange,
24252
- horizontalScrollRestore,
24253
- requestSelectionVerticalAutoscroll: handleSelectionVerticalAutoscroll
24254
- }
24255
- ) }),
24256
- row.right !== null ? /* @__PURE__ */ jsx3(View3, { style: { width: columnWidth }, children: /* @__PURE__ */ jsx3(
24257
- PageRenderer_default,
24258
- {
24259
- engine,
24260
- pageIndex: row.right,
24261
- pageAspectRatio: getPageAspectRatio(row.right),
24262
- availableWidth: columnWidth,
24263
- horizontalPadding: 8,
24264
- spacing: DOUBLE_PAGE_SPACING,
24265
- onSelectionDragActiveChange: setSelectionDragActive,
24266
- gestureScrollLockActive,
24267
- lastPinchEndedAt,
24268
- onHorizontalScrollOffsetChange: handlePageHorizontalScrollOffsetChange,
24269
- horizontalScrollRestore,
24270
- requestSelectionVerticalAutoscroll: handleSelectionVerticalAutoscroll
24271
- }
24272
- ) }) : /* @__PURE__ */ jsx3(View3, { style: { width: columnWidth } })
24273
- ] });
24168
+ return /* @__PURE__ */ jsxs3(
24169
+ View3,
24170
+ {
24171
+ style: [
24172
+ styles3.row,
24173
+ { paddingHorizontal: horizontalPadding, width: documentSurfaceWidth }
24174
+ ],
24175
+ children: [
24176
+ /* @__PURE__ */ jsx3(View3, { style: { width: columnWidth }, children: /* @__PURE__ */ jsx3(
24177
+ PageRenderer_default,
24178
+ {
24179
+ engine,
24180
+ pageIndex: row.left,
24181
+ pageAspectRatio: getPageAspectRatio(row.left),
24182
+ availableWidth: columnWidth,
24183
+ horizontalPadding: 8,
24184
+ pageViewportWidth: columnWidth,
24185
+ spacing: DOUBLE_PAGE_SPACING,
24186
+ onSelectionDragActiveChange: setSelectionDragActive,
24187
+ gestureScrollLockActive,
24188
+ lastPinchEndedAt,
24189
+ requestSelectionVerticalAutoscroll: handleSelectionVerticalAutoscroll
24190
+ }
24191
+ ) }),
24192
+ row.right !== null ? /* @__PURE__ */ jsx3(View3, { style: { width: columnWidth }, children: /* @__PURE__ */ jsx3(
24193
+ PageRenderer_default,
24194
+ {
24195
+ engine,
24196
+ pageIndex: row.right,
24197
+ pageAspectRatio: getPageAspectRatio(row.right),
24198
+ availableWidth: columnWidth,
24199
+ horizontalPadding: 8,
24200
+ pageViewportWidth: columnWidth,
24201
+ spacing: DOUBLE_PAGE_SPACING,
24202
+ onSelectionDragActiveChange: setSelectionDragActive,
24203
+ gestureScrollLockActive,
24204
+ lastPinchEndedAt,
24205
+ requestSelectionVerticalAutoscroll: handleSelectionVerticalAutoscroll
24206
+ }
24207
+ ) }) : /* @__PURE__ */ jsx3(View3, { style: { width: columnWidth } })
24208
+ ]
24209
+ }
24210
+ );
24274
24211
  }
24275
24212
  return /* @__PURE__ */ jsx3(
24276
24213
  PageRenderer_default,
@@ -24278,27 +24215,27 @@ var Viewer = ({
24278
24215
  engine,
24279
24216
  pageIndex: item,
24280
24217
  pageAspectRatio: getPageAspectRatio(item),
24218
+ availableWidth: windowWidth,
24219
+ pageViewportWidth: documentSurfaceWidth,
24281
24220
  spacing: CONTINUOUS_PAGE_SPACING,
24282
24221
  onSelectionDragActiveChange: setSelectionDragActive,
24283
24222
  gestureScrollLockActive,
24284
24223
  lastPinchEndedAt,
24285
- onHorizontalScrollOffsetChange: handlePageHorizontalScrollOffsetChange,
24286
- horizontalScrollRestore,
24287
24224
  requestSelectionVerticalAutoscroll: handleSelectionVerticalAutoscroll
24288
24225
  }
24289
24226
  );
24290
24227
  },
24291
24228
  [
24292
24229
  columnWidth,
24230
+ documentSurfaceWidth,
24293
24231
  engine,
24294
24232
  getPageAspectRatio,
24295
- handlePageHorizontalScrollOffsetChange,
24296
24233
  handleSelectionVerticalAutoscroll,
24297
24234
  gestureScrollLockActive,
24298
- horizontalScrollRestore,
24299
24235
  horizontalPadding,
24300
24236
  isDouble,
24301
- lastPinchEndedAt
24237
+ lastPinchEndedAt,
24238
+ windowWidth
24302
24239
  ]
24303
24240
  );
24304
24241
  if (isWebView) {
@@ -24313,52 +24250,66 @@ var Viewer = ({
24313
24250
  { transform: [{ scale: pinchPreviewScale }] }
24314
24251
  ],
24315
24252
  children: /* @__PURE__ */ jsx3(
24316
- ScrollView2,
24253
+ ScrollView,
24317
24254
  {
24318
- ref: (node) => {
24319
- captureViewerFrame(node);
24320
- listRef.current = node;
24321
- },
24322
- contentContainerStyle: styles3.singleContent,
24323
- showsVerticalScrollIndicator: false,
24324
- scrollEnabled: resolvedViewerScrollEnabled,
24325
- onLayout: () => captureViewerFrame(listRef.current),
24326
- onContentSizeChange: (_, height) => {
24327
- viewerContentHeightRef.current = height;
24255
+ ref: horizontalScrollRef,
24256
+ horizontal: true,
24257
+ scrollEnabled: !gestureScrollLockActive && documentSurfaceWidth > windowWidth,
24258
+ showsHorizontalScrollIndicator: false,
24259
+ onScroll: (event) => {
24260
+ horizontalScrollOffsetRef.current = event.nativeEvent.contentOffset?.x ?? 0;
24328
24261
  },
24329
- onScroll: (event) => handleViewerScroll(event, "single"),
24330
- onScrollBeginDrag: perfEnabled ? () => {
24331
- scrollMonitorRef.current.begin("single.beginDrag");
24332
- } : void 0,
24333
- onMomentumScrollBegin: perfEnabled ? () => {
24334
- scrollMonitorRef.current.begin("single.momentumBegin");
24335
- } : void 0,
24336
- onScrollEndDrag: perfEnabled ? () => {
24337
- scrollMonitorRef.current.end("single.endDrag");
24338
- sampleMemory("Viewer", "single.endDrag", { pageCount });
24339
- } : void 0,
24340
- onMomentumScrollEnd: perfEnabled ? () => {
24341
- scrollMonitorRef.current.end("single.momentumEnd");
24342
- sampleMemory("Viewer", "single.momentumEnd", {
24343
- pageCount
24344
- });
24345
- } : void 0,
24346
24262
  scrollEventThrottle: 16,
24347
24263
  children: /* @__PURE__ */ jsx3(
24348
- PageRenderer_default,
24264
+ ScrollView,
24349
24265
  {
24350
- engine,
24351
- pageIndex: Math.max(0, currentPage - 1),
24352
- pageAspectRatio: getPageAspectRatio(
24353
- Math.max(0, currentPage - 1)
24354
- ),
24355
- spacing: 32,
24356
- onSelectionDragActiveChange: setSelectionDragActive,
24357
- gestureScrollLockActive,
24358
- lastPinchEndedAt,
24359
- onHorizontalScrollOffsetChange: handlePageHorizontalScrollOffsetChange,
24360
- horizontalScrollRestore,
24361
- requestSelectionVerticalAutoscroll: handleSelectionVerticalAutoscroll
24266
+ ref: (node) => {
24267
+ captureViewerFrame(node);
24268
+ listRef.current = node;
24269
+ },
24270
+ style: { width: documentSurfaceWidth },
24271
+ contentContainerStyle: styles3.singleContent,
24272
+ showsVerticalScrollIndicator: false,
24273
+ scrollEnabled: resolvedViewerScrollEnabled,
24274
+ onLayout: () => captureViewerFrame(listRef.current),
24275
+ onContentSizeChange: (_, height) => {
24276
+ viewerContentHeightRef.current = height;
24277
+ },
24278
+ onScroll: (event) => handleViewerScroll(event, "single"),
24279
+ onScrollBeginDrag: perfEnabled ? () => {
24280
+ scrollMonitorRef.current.begin("single.beginDrag");
24281
+ } : void 0,
24282
+ onMomentumScrollBegin: perfEnabled ? () => {
24283
+ scrollMonitorRef.current.begin("single.momentumBegin");
24284
+ } : void 0,
24285
+ onScrollEndDrag: perfEnabled ? () => {
24286
+ scrollMonitorRef.current.end("single.endDrag");
24287
+ sampleMemory("Viewer", "single.endDrag", { pageCount });
24288
+ } : void 0,
24289
+ onMomentumScrollEnd: perfEnabled ? () => {
24290
+ scrollMonitorRef.current.end("single.momentumEnd");
24291
+ sampleMemory("Viewer", "single.momentumEnd", {
24292
+ pageCount
24293
+ });
24294
+ } : void 0,
24295
+ scrollEventThrottle: 16,
24296
+ children: /* @__PURE__ */ jsx3(
24297
+ PageRenderer_default,
24298
+ {
24299
+ engine,
24300
+ pageIndex: Math.max(0, currentPage - 1),
24301
+ pageAspectRatio: getPageAspectRatio(
24302
+ Math.max(0, currentPage - 1)
24303
+ ),
24304
+ availableWidth: windowWidth,
24305
+ pageViewportWidth: documentSurfaceWidth,
24306
+ spacing: 32,
24307
+ onSelectionDragActiveChange: setSelectionDragActive,
24308
+ gestureScrollLockActive,
24309
+ lastPinchEndedAt,
24310
+ requestSelectionVerticalAutoscroll: handleSelectionVerticalAutoscroll
24311
+ }
24312
+ )
24362
24313
  }
24363
24314
  )
24364
24315
  }
@@ -24374,74 +24325,90 @@ var Viewer = ({
24374
24325
  { transform: [{ scale: pinchPreviewScale }] }
24375
24326
  ],
24376
24327
  children: /* @__PURE__ */ jsx3(
24377
- FlatList,
24328
+ ScrollView,
24378
24329
  {
24379
- ref: listRef,
24380
- data: isDouble ? rows : pages,
24381
- initialNumToRender: FLATLIST_INITIAL_NUM_TO_RENDER,
24382
- windowSize: resolvedWindowSize,
24383
- maxToRenderPerBatch: resolvedMaxToRenderPerBatch,
24384
- updateCellsBatchingPeriod: FLATLIST_UPDATE_CELLS_BATCHING_PERIOD,
24385
- removeClippedSubviews: resolvedRemoveClippedSubviews,
24386
- getItemLayout,
24387
- keyExtractor,
24388
- contentContainerStyle: styles3.listContent,
24389
- renderItem,
24390
- onViewableItemsChanged,
24391
- viewabilityConfig: { itemVisiblePercentThreshold: 60 },
24392
- scrollEnabled: resolvedViewerScrollEnabled,
24393
- onLayout: () => captureViewerFrame(listRef.current),
24394
- onContentSizeChange: (_, height) => {
24395
- viewerContentHeightRef.current = height;
24330
+ ref: horizontalScrollRef,
24331
+ horizontal: true,
24332
+ scrollEnabled: !gestureScrollLockActive && documentSurfaceWidth > windowWidth,
24333
+ showsHorizontalScrollIndicator: false,
24334
+ onScroll: (event) => {
24335
+ horizontalScrollOffsetRef.current = event.nativeEvent.contentOffset?.x ?? 0;
24396
24336
  },
24397
- onScrollToIndexFailed: ({ index, averageItemLength }) => {
24398
- const dataLength = isDouble ? rows.length : pages.length;
24399
- if (index < 0 || index >= dataLength) return;
24400
- pendingScrollIndexRef.current = index;
24401
- const offset = Math.max(0, getFallbackOffsetForIndex(index));
24402
- listRef.current?.scrollToOffset({ offset, animated: false });
24403
- if (!isDouble) {
24404
- ensurePageDimensions(index);
24405
- } else {
24406
- const row = rows[index];
24407
- if (row) {
24408
- ensurePageDimensions(row.left);
24409
- if (row.right !== null) {
24410
- ensurePageDimensions(row.right);
24337
+ scrollEventThrottle: 16,
24338
+ children: /* @__PURE__ */ jsx3(
24339
+ FlatList,
24340
+ {
24341
+ ref: listRef,
24342
+ data: isDouble ? rows : pages,
24343
+ style: { width: documentSurfaceWidth },
24344
+ initialNumToRender: FLATLIST_INITIAL_NUM_TO_RENDER,
24345
+ windowSize: resolvedWindowSize,
24346
+ maxToRenderPerBatch: resolvedMaxToRenderPerBatch,
24347
+ updateCellsBatchingPeriod: FLATLIST_UPDATE_CELLS_BATCHING_PERIOD,
24348
+ removeClippedSubviews: resolvedRemoveClippedSubviews,
24349
+ getItemLayout,
24350
+ keyExtractor,
24351
+ contentContainerStyle: styles3.listContent,
24352
+ renderItem,
24353
+ onViewableItemsChanged,
24354
+ viewabilityConfig: { itemVisiblePercentThreshold: 60 },
24355
+ scrollEnabled: resolvedViewerScrollEnabled,
24356
+ onLayout: () => captureViewerFrame(listRef.current),
24357
+ onContentSizeChange: (_, height) => {
24358
+ viewerContentHeightRef.current = height;
24359
+ },
24360
+ onScrollToIndexFailed: ({ index, averageItemLength }) => {
24361
+ const dataLength = isDouble ? rows.length : pages.length;
24362
+ if (index < 0 || index >= dataLength) return;
24363
+ pendingScrollIndexRef.current = index;
24364
+ const offset = Math.max(0, getFallbackOffsetForIndex(index));
24365
+ listRef.current?.scrollToOffset({ offset, animated: false });
24366
+ if (!isDouble) {
24367
+ ensurePageDimensions(index);
24368
+ } else {
24369
+ const row = rows[index];
24370
+ if (row) {
24371
+ ensurePageDimensions(row.left);
24372
+ if (row.right !== null) {
24373
+ ensurePageDimensions(row.right);
24374
+ }
24375
+ }
24411
24376
  }
24412
- }
24413
- }
24414
- scheduleScrollRetry("onScrollToIndexFailed");
24415
- if (perfEnabled) {
24416
- logPerfEvent("Viewer", "scrollToIndexFailed", {
24417
- index,
24418
- averageItemLength,
24419
- fallbackOffset: offset,
24420
- fallbackSource: "cached-item-layout",
24421
- itemCount: dataLength,
24422
- retryAttempt: pendingScrollAttemptsRef.current
24423
- });
24377
+ scheduleScrollRetry("onScrollToIndexFailed");
24378
+ if (perfEnabled) {
24379
+ logPerfEvent("Viewer", "scrollToIndexFailed", {
24380
+ index,
24381
+ averageItemLength,
24382
+ fallbackOffset: offset,
24383
+ fallbackSource: "cached-item-layout",
24384
+ itemCount: dataLength,
24385
+ retryAttempt: pendingScrollAttemptsRef.current
24386
+ });
24387
+ }
24388
+ },
24389
+ onScroll: (event) => handleViewerScroll(event, "continuous"),
24390
+ onScrollBeginDrag: perfEnabled ? () => {
24391
+ scrollMonitorRef.current.begin("continuous.beginDrag");
24392
+ } : void 0,
24393
+ onMomentumScrollBegin: perfEnabled ? () => {
24394
+ scrollMonitorRef.current.begin("continuous.momentumBegin");
24395
+ } : void 0,
24396
+ onScrollEndDrag: perfEnabled ? () => {
24397
+ scrollMonitorRef.current.end("continuous.endDrag");
24398
+ sampleMemory("Viewer", "continuous.endDrag", {
24399
+ pageCount
24400
+ });
24401
+ } : void 0,
24402
+ onMomentumScrollEnd: perfEnabled ? () => {
24403
+ scrollMonitorRef.current.end("continuous.momentumEnd");
24404
+ sampleMemory("Viewer", "continuous.momentumEnd", {
24405
+ pageCount
24406
+ });
24407
+ } : void 0,
24408
+ scrollEventThrottle: 16,
24409
+ showsVerticalScrollIndicator: false
24424
24410
  }
24425
- },
24426
- onScroll: (event) => handleViewerScroll(event, "continuous"),
24427
- onScrollBeginDrag: perfEnabled ? () => {
24428
- scrollMonitorRef.current.begin("continuous.beginDrag");
24429
- } : void 0,
24430
- onMomentumScrollBegin: perfEnabled ? () => {
24431
- scrollMonitorRef.current.begin("continuous.momentumBegin");
24432
- } : void 0,
24433
- onScrollEndDrag: perfEnabled ? () => {
24434
- scrollMonitorRef.current.end("continuous.endDrag");
24435
- sampleMemory("Viewer", "continuous.endDrag", { pageCount });
24436
- } : void 0,
24437
- onMomentumScrollEnd: perfEnabled ? () => {
24438
- scrollMonitorRef.current.end("continuous.momentumEnd");
24439
- sampleMemory("Viewer", "continuous.momentumEnd", {
24440
- pageCount
24441
- });
24442
- } : void 0,
24443
- scrollEventThrottle: 16,
24444
- showsVerticalScrollIndicator: false
24411
+ )
24445
24412
  }
24446
24413
  )
24447
24414
  }
@@ -25492,7 +25459,7 @@ import {
25492
25459
  Text as Text3,
25493
25460
  Pressable as Pressable4,
25494
25461
  StyleSheet as StyleSheet6,
25495
- ScrollView as ScrollView3,
25462
+ ScrollView as ScrollView2,
25496
25463
  useWindowDimensions as useWindowDimensions3
25497
25464
  } from "react-native";
25498
25465
  import { useViewerStore as useViewerStore5 } from "@papyrus-sdk/core";
@@ -26072,7 +26039,7 @@ var ToolDock = () => {
26072
26039
  }
26073
26040
  ],
26074
26041
  children: primaryToolsRowIsScrollable ? /* @__PURE__ */ jsx7(
26075
- ScrollView3,
26042
+ ScrollView2,
26076
26043
  {
26077
26044
  horizontal: true,
26078
26045
  bounces: false,
@@ -28790,7 +28757,7 @@ var styles12 = StyleSheet12.create({
28790
28757
  import {
28791
28758
  Modal as Modal4,
28792
28759
  Pressable as Pressable10,
28793
- ScrollView as ScrollView4,
28760
+ ScrollView as ScrollView3,
28794
28761
  StyleSheet as StyleSheet13,
28795
28762
  Text as Text9,
28796
28763
  View as View13
@@ -28961,7 +28928,7 @@ function InfoSheet({
28961
28928
  /* @__PURE__ */ jsx14(View13, { style: styles13.topRowSpacer })
28962
28929
  ] }),
28963
28930
  /* @__PURE__ */ jsxs14(
28964
- ScrollView4,
28931
+ ScrollView3,
28965
28932
  {
28966
28933
  style: styles13.content,
28967
28934
  contentContainerStyle: styles13.contentInner,
@@ -29621,7 +29588,7 @@ var styles16 = StyleSheet16.create({
29621
29588
  import {
29622
29589
  Modal as Modal6,
29623
29590
  Pressable as Pressable14,
29624
- ScrollView as ScrollView5,
29591
+ ScrollView as ScrollView4,
29625
29592
  StyleSheet as StyleSheet17,
29626
29593
  Text as Text13,
29627
29594
  View as View17
@@ -29670,7 +29637,7 @@ function SearchResultsSheet({
29670
29637
  t.results
29671
29638
  ] })
29672
29639
  ] }),
29673
- /* @__PURE__ */ jsx18(ScrollView5, { contentContainerStyle: styles17.content, children: searchResults.length === 0 ? /* @__PURE__ */ jsx18(Text13, { style: [styles17.emptyText, isDark && styles17.emptyTextDark], children: t.noResults }) : searchResults.map((result, index) => {
29640
+ /* @__PURE__ */ jsx18(ScrollView4, { contentContainerStyle: styles17.content, children: searchResults.length === 0 ? /* @__PURE__ */ jsx18(Text13, { style: [styles17.emptyText, isDark && styles17.emptyTextDark], children: t.noResults }) : searchResults.map((result, index) => {
29674
29641
  const isActive = index === activeSearchIndex;
29675
29642
  return /* @__PURE__ */ jsxs18(
29676
29643
  Pressable14,