@papyrus-sdk/ui-react-native 0.2.27 → 0.2.29

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
@@ -26956,6 +26956,17 @@ var Viewer = ({
26956
26956
  },
26957
26957
  [scaledListLayoutMetrics]
26958
26958
  );
26959
+ const scrollToPendingTarget = useCallback3(
26960
+ (animated) => {
26961
+ const target = pendingScrollTargetRef.current;
26962
+ if (target === null || listRef.current === null) return;
26963
+ listRef.current.scrollToOffset({
26964
+ offset: Math.max(0, getFallbackOffsetForIndex(target.listIndex)),
26965
+ animated
26966
+ });
26967
+ },
26968
+ [getFallbackOffsetForIndex]
26969
+ );
26959
26970
  const restoreOrientationScrollOffset = useCallback3(() => {
26960
26971
  if (pendingOrientationRestoreWidthRef.current !== windowWidth || pageCount <= 0 || isSingle || isWebView) {
26961
26972
  return;
@@ -26986,6 +26997,11 @@ var Viewer = ({
26986
26997
  }
26987
26998
  restoreOrientationScrollOffset();
26988
26999
  }, [restoreOrientationScrollOffset, windowWidth]);
27000
+ useEffect4(() => {
27001
+ if (pendingScrollTargetRef.current !== null) {
27002
+ scrollToPendingTarget(false);
27003
+ }
27004
+ }, [layoutRevision, scrollToPendingTarget]);
26989
27005
  const getItemLayout = useCallback3(
26990
27006
  (_, index) => {
26991
27007
  if (scaledListLayoutMetrics.itemCount === 0) {
@@ -27056,15 +27072,12 @@ var Viewer = ({
27056
27072
  },
27057
27073
  "scrollToPageSignal.flatList"
27058
27074
  );
27059
- listRef.current?.scrollToIndex({
27060
- index: target.listIndex,
27061
- animated: true,
27062
- viewPosition: 0
27063
- });
27075
+ scrollToPendingTarget(true);
27064
27076
  }, [
27065
27077
  clearPendingScrollRetry,
27066
27078
  clearPendingScrollTarget,
27067
27079
  ensurePageDimensions,
27080
+ scrollToPendingTarget,
27068
27081
  scrollToPageSignal,
27069
27082
  pageCount,
27070
27083
  setDocumentStateTracked,
@@ -27456,9 +27469,11 @@ var Viewer = ({
27456
27469
  onLayout: () => {
27457
27470
  captureViewerFrame(listRef.current);
27458
27471
  restoreOrientationScrollOffset();
27472
+ scrollToPendingTarget(false);
27459
27473
  },
27460
27474
  onContentSizeChange: (_, height) => {
27461
27475
  viewerContentHeightRef.current = height;
27476
+ scrollToPendingTarget(false);
27462
27477
  },
27463
27478
  onScrollToIndexFailed: ({ index, averageItemLength }) => {
27464
27479
  const dataLength = isDouble ? rows.length : pages.length;
@@ -27547,13 +27562,13 @@ var styles4 = StyleSheet4.create({
27547
27562
  var Viewer_default = Viewer;
27548
27563
 
27549
27564
  // components/Topbar.tsx
27550
- import { useState as useState6 } from "react";
27565
+ import { useState as useState7 } from "react";
27551
27566
  import {
27552
27567
  View as View7,
27553
27568
  Text as Text3,
27554
27569
  Pressable as Pressable5,
27555
27570
  StyleSheet as StyleSheet7,
27556
- useWindowDimensions as useWindowDimensions3
27571
+ useWindowDimensions as useWindowDimensions4
27557
27572
  } from "react-native";
27558
27573
  import { useViewerStore as useViewerStore5 } from "@papyrus-sdk/core";
27559
27574
 
@@ -27587,7 +27602,7 @@ var resolveMobileChromeOffsets = (insets) => ({
27587
27602
  });
27588
27603
 
27589
27604
  // components/PageJumpModal.tsx
27590
- import { useEffect as useEffect5, useState as useState5 } from "react";
27605
+ import { useEffect as useEffect6, useState as useState6 } from "react";
27591
27606
  import { Pressable as Pressable4, StyleSheet as StyleSheet6, Text as Text2, TextInput, View as View6 } from "react-native";
27592
27607
 
27593
27608
  // components/pageJumpModel.ts
@@ -27599,15 +27614,17 @@ var resolvePageJumpTarget = (value, pageCount) => {
27599
27614
  };
27600
27615
 
27601
27616
  // components/NativeSheet.tsx
27602
- import React7 from "react";
27617
+ import React7, { useEffect as useEffect5, useRef as useRef5, useState as useState5 } from "react";
27603
27618
  import {
27619
+ Animated as Animated2,
27604
27620
  FlatList as FlatList2,
27605
27621
  Modal,
27606
27622
  Pressable as Pressable3,
27607
27623
  ScrollView as ScrollView2,
27608
27624
  StyleSheet as StyleSheet5,
27609
27625
  Text,
27610
- View as View5
27626
+ View as View5,
27627
+ useWindowDimensions as useWindowDimensions3
27611
27628
  } from "react-native";
27612
27629
 
27613
27630
  // components/nativeSheetLayout.ts
@@ -27697,25 +27714,73 @@ function NativeSheet({
27697
27714
  }) {
27698
27715
  const insets = usePapyrusSafeAreaInsets();
27699
27716
  const palette = getNativeSheetPalette(Boolean(isDark));
27717
+ const { height: windowHeight } = useWindowDimensions3();
27718
+ const [rendered, setRendered] = useState5(visible);
27719
+ const renderedRef = useRef5(visible);
27720
+ const motion = useRef5(new Animated2.Value(visible ? 0 : 1)).current;
27721
+ const backdropOpacity = useRef5(new Animated2.Value(visible ? 1 : 0)).current;
27722
+ useEffect5(() => {
27723
+ motion.stopAnimation();
27724
+ backdropOpacity.stopAnimation();
27725
+ if (visible) {
27726
+ renderedRef.current = true;
27727
+ setRendered(true);
27728
+ motion.setValue(1);
27729
+ backdropOpacity.setValue(0);
27730
+ Animated2.parallel([
27731
+ Animated2.spring(motion, {
27732
+ toValue: 0,
27733
+ damping: 22,
27734
+ stiffness: 220,
27735
+ mass: 0.8,
27736
+ useNativeDriver: true
27737
+ }),
27738
+ Animated2.timing(backdropOpacity, {
27739
+ toValue: 1,
27740
+ duration: 180,
27741
+ useNativeDriver: true
27742
+ })
27743
+ ]).start();
27744
+ return;
27745
+ }
27746
+ if (!renderedRef.current) return;
27747
+ Animated2.parallel([
27748
+ Animated2.timing(motion, {
27749
+ toValue: 1,
27750
+ duration: 180,
27751
+ useNativeDriver: true
27752
+ }),
27753
+ Animated2.timing(backdropOpacity, {
27754
+ toValue: 0,
27755
+ duration: 140,
27756
+ useNativeDriver: true
27757
+ })
27758
+ ]).start(({ finished }) => {
27759
+ if (!finished) return;
27760
+ renderedRef.current = false;
27761
+ setRendered(false);
27762
+ });
27763
+ }, [backdropOpacity, motion, visible]);
27764
+ if (!rendered) return null;
27700
27765
  return /* @__PURE__ */ jsx8(
27701
27766
  Modal,
27702
27767
  {
27703
- animationType: "fade",
27768
+ animationType: "none",
27704
27769
  transparent: true,
27705
- visible,
27770
+ visible: rendered,
27706
27771
  onRequestClose: onClose,
27707
27772
  children: /* @__PURE__ */ jsxs6(View5, { style: styles5.root, children: [
27708
- /* @__PURE__ */ jsx8(
27773
+ /* @__PURE__ */ jsx8(Animated2.View, { style: [styles5.backdrop, { opacity: backdropOpacity }], children: /* @__PURE__ */ jsx8(
27709
27774
  Pressable3,
27710
27775
  {
27711
27776
  accessibilityRole: "button",
27712
27777
  accessibilityLabel: closeAccessibilityLabel,
27713
- style: styles5.backdrop,
27778
+ style: StyleSheet5.absoluteFill,
27714
27779
  onPress: onClose
27715
27780
  }
27716
- ),
27781
+ ) }),
27717
27782
  /* @__PURE__ */ jsxs6(
27718
- View5,
27783
+ Animated2.View,
27719
27784
  {
27720
27785
  style: [
27721
27786
  styles5.sheet,
@@ -27726,7 +27791,17 @@ function NativeSheet({
27726
27791
  backgroundColor: palette.backgroundColor,
27727
27792
  borderTopColor: palette.borderColor
27728
27793
  },
27729
- sheetStyle
27794
+ sheetStyle,
27795
+ {
27796
+ transform: [
27797
+ {
27798
+ translateY: motion.interpolate({
27799
+ inputRange: [0, 1],
27800
+ outputRange: [0, windowHeight]
27801
+ })
27802
+ }
27803
+ ]
27804
+ }
27730
27805
  ],
27731
27806
  children: [
27732
27807
  showHeader ? /* @__PURE__ */ jsxs6(View5, { style: styles5.header, children: [
@@ -27834,9 +27909,9 @@ function PageJumpModal({
27834
27909
  onClose,
27835
27910
  onConfirm
27836
27911
  }) {
27837
- const [value, setValue] = useState5(`${currentPage}`);
27912
+ const [value, setValue] = useState6(`${currentPage}`);
27838
27913
  const palette = getReaderSheetPalette(isDark);
27839
- useEffect5(() => {
27914
+ useEffect6(() => {
27840
27915
  if (visible) setValue(`${currentPage}`);
27841
27916
  }, [currentPage, visible]);
27842
27917
  const confirmJump = () => {
@@ -27954,10 +28029,10 @@ var Topbar = ({
27954
28029
  accentColor,
27955
28030
  mobileChromeVisible
27956
28031
  } = useViewerStore5();
27957
- const [jumpModalOpen, setJumpModalOpen] = useState6(false);
28032
+ const [jumpModalOpen, setJumpModalOpen] = useState7(false);
27958
28033
  const isDark = uiTheme === "dark";
27959
28034
  const navIconColor = isDark ? "#e5e7eb" : "#111827";
27960
- const { width, height } = useWindowDimensions3();
28035
+ const { width, height } = useWindowDimensions4();
27961
28036
  const isLandscape = width > height;
27962
28037
  const insets = usePapyrusSafeAreaInsets();
27963
28038
  const navigateToPage = (targetPage) => {
@@ -28278,14 +28353,14 @@ var styles7 = StyleSheet7.create({
28278
28353
  var Topbar_default = Topbar;
28279
28354
 
28280
28355
  // components/ToolDock.tsx
28281
- import React10, { useEffect as useEffect6, useMemo as useMemo4, useRef as useRef5, useState as useState7 } from "react";
28356
+ import React10, { useEffect as useEffect7, useMemo as useMemo4, useRef as useRef6, useState as useState8 } from "react";
28282
28357
  import {
28283
28358
  View as View8,
28284
28359
  Text as Text4,
28285
28360
  Pressable as Pressable6,
28286
28361
  StyleSheet as StyleSheet8,
28287
28362
  ScrollView as ScrollView3,
28288
- useWindowDimensions as useWindowDimensions4
28363
+ useWindowDimensions as useWindowDimensions5
28289
28364
  } from "react-native";
28290
28365
  import { useViewerStore as useViewerStore6 } from "@papyrus-sdk/core";
28291
28366
 
@@ -28518,18 +28593,18 @@ var OpacitySlider = React10.memo(function OpacitySlider2({
28518
28593
  isDark,
28519
28594
  onCommit
28520
28595
  }) {
28521
- const [trackWidth, setTrackWidth] = useState7(0);
28522
- const [draftValue, setDraftValue] = useState7(value);
28523
- const dragValueRef = useRef5(draftValue);
28524
- const isDraggingRef = useRef5(false);
28525
- const frameRef = useRef5(null);
28526
- useEffect6(() => {
28596
+ const [trackWidth, setTrackWidth] = useState8(0);
28597
+ const [draftValue, setDraftValue] = useState8(value);
28598
+ const dragValueRef = useRef6(draftValue);
28599
+ const isDraggingRef = useRef6(false);
28600
+ const frameRef = useRef6(null);
28601
+ useEffect7(() => {
28527
28602
  if (!isDraggingRef.current) {
28528
28603
  dragValueRef.current = value;
28529
28604
  setDraftValue(value);
28530
28605
  }
28531
28606
  }, [value]);
28532
- useEffect6(() => {
28607
+ useEffect7(() => {
28533
28608
  return () => {
28534
28609
  if (frameRef.current !== null) {
28535
28610
  cancelAnimationFrame(frameRef.current);
@@ -28628,10 +28703,10 @@ var ToolDock = () => {
28628
28703
  undoAnnotations,
28629
28704
  redoAnnotations
28630
28705
  } = useViewerStore6();
28631
- const [paletteExpanded, setPaletteExpanded] = useState7(false);
28632
- const [extrasExpanded, setExtrasExpanded] = useState7(false);
28706
+ const [paletteExpanded, setPaletteExpanded] = useState8(false);
28707
+ const [extrasExpanded, setExtrasExpanded] = useState8(false);
28633
28708
  const isDark = uiTheme === "dark";
28634
- const { width: windowWidth } = useWindowDimensions4();
28709
+ const { width: windowWidth } = useWindowDimensions5();
28635
28710
  const t = getStrings(locale);
28636
28711
  const panelColor = isDark ? "rgba(24,24,27,0.92)" : "rgba(255,255,255,0.96)";
28637
28712
  const borderColor = isDark ? "rgba(71,85,105,0.48)" : "rgba(229,231,235,0.88)";
@@ -29354,10 +29429,10 @@ var ToolDock_default = ToolDock;
29354
29429
  // components/RightSheet.tsx
29355
29430
  import {
29356
29431
  useCallback as useCallback4,
29357
- useEffect as useEffect7,
29432
+ useEffect as useEffect8,
29358
29433
  useMemo as useMemo5,
29359
- useRef as useRef6,
29360
- useState as useState8
29434
+ useRef as useRef7,
29435
+ useState as useState9
29361
29436
  } from "react";
29362
29437
  import {
29363
29438
  Dimensions,
@@ -29420,10 +29495,10 @@ var PageThumbnail = ({
29420
29495
  shouldRenderPreview,
29421
29496
  onPress
29422
29497
  }) => {
29423
- const viewRef = useRef6(null);
29424
- const [layoutReady, setLayoutReady] = useState8(false);
29425
- const [previewUri, setPreviewUri] = useState8(null);
29426
- useEffect7(() => {
29498
+ const viewRef = useRef7(null);
29499
+ const [layoutReady, setLayoutReady] = useState9(false);
29500
+ const [previewUri, setPreviewUri] = useState9(null);
29501
+ useEffect8(() => {
29427
29502
  if (!layoutReady || !useNativePreview || !shouldRenderPreview) return;
29428
29503
  const viewTag = findNodeHandle2(viewRef.current);
29429
29504
  if (!viewTag) return;
@@ -29438,7 +29513,7 @@ var PageThumbnail = ({
29438
29513
  useNativePreview,
29439
29514
  zoom
29440
29515
  ]);
29441
- useEffect7(() => {
29516
+ useEffect8(() => {
29442
29517
  if (!useImagePreview || !shouldRenderPreview) {
29443
29518
  setPreviewUri(null);
29444
29519
  return;
@@ -29568,10 +29643,10 @@ var RightSheet = ({
29568
29643
  locale,
29569
29644
  accentColor
29570
29645
  } = useViewerStore7();
29571
- const [pagesMode, setPagesMode] = useState8(
29646
+ const [pagesMode, setPagesMode] = useState9(
29572
29647
  documentType === "pdf" || documentType === "comic" ? "thumbnails" : "summary"
29573
29648
  );
29574
- useEffect7(() => {
29649
+ useEffect8(() => {
29575
29650
  setPagesMode(
29576
29651
  documentType === "pdf" || documentType === "comic" ? "thumbnails" : "summary"
29577
29652
  );
@@ -29595,11 +29670,11 @@ var RightSheet = ({
29595
29670
  );
29596
29671
  const useNativePreview = renderTarget !== "webview" && hasNativePageView;
29597
29672
  const useImagePreview = documentType === "comic" && renderTarget === "webview" && typeof engine.getPagePreview === "function";
29598
- const thumbnailDimensionsCacheRef = useRef6(/* @__PURE__ */ new Map());
29599
- const thumbnailDimensionsPendingRef = useRef6(/* @__PURE__ */ new Set());
29600
- const thumbnailRefreshTimeoutRef = useRef6(null);
29601
- const [thumbnailLayoutRevision, setThumbnailLayoutRevision] = useState8(0);
29602
- const [visibleThumbnailPages, setVisibleThumbnailPages] = useState8(() => /* @__PURE__ */ new Set());
29673
+ const thumbnailDimensionsCacheRef = useRef7(/* @__PURE__ */ new Map());
29674
+ const thumbnailDimensionsPendingRef = useRef7(/* @__PURE__ */ new Set());
29675
+ const thumbnailRefreshTimeoutRef = useRef7(null);
29676
+ const [thumbnailLayoutRevision, setThumbnailLayoutRevision] = useState9(0);
29677
+ const [visibleThumbnailPages, setVisibleThumbnailPages] = useState9(() => /* @__PURE__ */ new Set());
29603
29678
  const resolvedThumbsInitialCount = useMemo5(
29604
29679
  () => resolvePositiveInt2(
29605
29680
  thumbsInitialCount,
@@ -29669,7 +29744,7 @@ var RightSheet = ({
29669
29744
  },
29670
29745
  [frameWidth, thumbnailLayoutRevision]
29671
29746
  );
29672
- useEffect7(
29747
+ useEffect8(
29673
29748
  () => () => {
29674
29749
  if (thumbnailRefreshTimeoutRef.current) {
29675
29750
  clearTimeout(thumbnailRefreshTimeoutRef.current);
@@ -29677,11 +29752,11 @@ var RightSheet = ({
29677
29752
  },
29678
29753
  []
29679
29754
  );
29680
- useEffect7(() => {
29755
+ useEffect8(() => {
29681
29756
  if (sidebarRightOpen) return;
29682
29757
  setVisibleThumbnailPages(/* @__PURE__ */ new Set());
29683
29758
  }, [sidebarRightOpen]);
29684
- useEffect7(() => {
29759
+ useEffect8(() => {
29685
29760
  if (!sidebarRightOpen || sidebarRightTab !== "pages") return;
29686
29761
  if (activeMobileDestination === "pages") {
29687
29762
  setPagesMode("thumbnails");
@@ -29689,7 +29764,7 @@ var RightSheet = ({
29689
29764
  }
29690
29765
  setPagesMode("summary");
29691
29766
  }, [activeMobileDestination, sidebarRightOpen, sidebarRightTab]);
29692
- useEffect7(() => {
29767
+ useEffect8(() => {
29693
29768
  if (!sidebarRightOpen || sidebarRightTab !== "pages") return;
29694
29769
  if (pagesMode !== "thumbnails" || !supportsThumbnails) return;
29695
29770
  if (pageCount <= 0) return;
@@ -30305,7 +30380,7 @@ var styles9 = StyleSheet9.create({
30305
30380
  var RightSheet_default = RightSheet;
30306
30381
 
30307
30382
  // components/AnnotationEditor.tsx
30308
- import { useEffect as useEffect8, useState as useState9 } from "react";
30383
+ import { useEffect as useEffect9, useState as useState10 } from "react";
30309
30384
  import {
30310
30385
  Modal as Modal2,
30311
30386
  View as View10,
@@ -30328,10 +30403,10 @@ var AnnotationEditor = () => {
30328
30403
  } = useViewerStore8();
30329
30404
  const annotation = annotations.find((ann) => ann.id === selectedAnnotationId);
30330
30405
  const isEditable = annotation && (annotation.type === "text" || annotation.type === "comment");
30331
- const [draft, setDraft] = useState9("");
30406
+ const [draft, setDraft] = useState10("");
30332
30407
  const isDark = uiTheme === "dark";
30333
30408
  const t = getStrings(locale);
30334
- useEffect8(() => {
30409
+ useEffect9(() => {
30335
30410
  if (isEditable) {
30336
30411
  setDraft(annotation?.content ?? "");
30337
30412
  }
@@ -30458,7 +30533,7 @@ var styles10 = StyleSheet10.create({
30458
30533
  var AnnotationEditor_default = AnnotationEditor;
30459
30534
 
30460
30535
  // components/BottomBar.tsx
30461
- import { View as View11, Pressable as Pressable9, StyleSheet as StyleSheet11, useWindowDimensions as useWindowDimensions5 } from "react-native";
30536
+ import { View as View11, Pressable as Pressable9, StyleSheet as StyleSheet11, useWindowDimensions as useWindowDimensions6 } from "react-native";
30462
30537
  import { useViewerStore as useViewerStore9 } from "@papyrus-sdk/core";
30463
30538
 
30464
30539
  // components/bottomBarModel.ts
@@ -30526,7 +30601,7 @@ var BottomBar = ({
30526
30601
  } = useViewerStore9();
30527
30602
  const isDark = uiTheme === "dark";
30528
30603
  const t = getStrings(locale);
30529
- const { width, height } = useWindowDimensions5();
30604
+ const { width, height } = useWindowDimensions6();
30530
30605
  const isLandscape = width > height;
30531
30606
  const offsets = resolveMobileChromeOffsets(usePapyrusSafeAreaInsets());
30532
30607
  const iconColor = (active) => {
@@ -31314,7 +31389,7 @@ var styles12 = StyleSheet12.create({
31314
31389
  var SettingsSheet_default = SettingsSheet;
31315
31390
 
31316
31391
  // components/CoverPreview.tsx
31317
- import { useEffect as useEffect9, useMemo as useMemo6, useRef as useRef7, useState as useState10 } from "react";
31392
+ import { useEffect as useEffect10, useMemo as useMemo6, useRef as useRef8, useState as useState11 } from "react";
31318
31393
  import {
31319
31394
  ActivityIndicator,
31320
31395
  StyleSheet as StyleSheet13,
@@ -31372,18 +31447,18 @@ var CoverPreview = ({
31372
31447
  onLoadEnd,
31373
31448
  onError
31374
31449
  }) => {
31375
- const [engine, setEngine] = useState10(null);
31376
- const [layoutReady, setLayoutReady] = useState10(false);
31377
- const [loaded, setLoaded] = useState10(false);
31378
- const [loading, setLoading] = useState10(false);
31379
- const [error, setError] = useState10(null);
31380
- const viewRef = useRef7(null);
31450
+ const [engine, setEngine] = useState11(null);
31451
+ const [layoutReady, setLayoutReady] = useState11(false);
31452
+ const [loaded, setLoaded] = useState11(false);
31453
+ const [loading, setLoading] = useState11(false);
31454
+ const [error, setError] = useState11(null);
31455
+ const viewRef = useRef8(null);
31381
31456
  const resolvedType = useMemo6(() => inferDocumentType(source, type), [source, type]);
31382
31457
  const isPdf = resolvedType === "pdf";
31383
31458
  const hasNativePageView = Boolean(UIManager2.getViewManagerConfig?.("PapyrusPageView"));
31384
31459
  const canRender = !isPdf || hasNativePageView;
31385
31460
  const shouldRender = Boolean(visible);
31386
- useEffect9(() => {
31461
+ useEffect10(() => {
31387
31462
  if (!shouldRender) {
31388
31463
  if (!keepAlive) {
31389
31464
  setEngine(null);
@@ -31396,7 +31471,7 @@ var CoverPreview = ({
31396
31471
  setEngine(new MobileDocumentEngine());
31397
31472
  }
31398
31473
  }, [shouldRender, keepAlive, engine, canRender]);
31399
- useEffect9(() => {
31474
+ useEffect10(() => {
31400
31475
  if (!engine || !shouldRender || !canRender) return;
31401
31476
  let active = true;
31402
31477
  setLoading(true);
@@ -31423,13 +31498,13 @@ var CoverPreview = ({
31423
31498
  active = false;
31424
31499
  };
31425
31500
  }, [engine, shouldRender, canRender, source, type, pageIndex, isPdf, onLoadStart, onLoadEnd, onError]);
31426
- useEffect9(() => {
31501
+ useEffect10(() => {
31427
31502
  if (!engine || !isPdf || !loaded || !layoutReady || !shouldRender || !canRender) return;
31428
31503
  const viewTag = findNodeHandle3(viewRef.current);
31429
31504
  if (!viewTag) return;
31430
31505
  engine.renderPage(pageIndex, viewTag, renderScale);
31431
31506
  }, [engine, isPdf, loaded, layoutReady, shouldRender, canRender, pageIndex, renderScale]);
31432
- useEffect9(() => {
31507
+ useEffect10(() => {
31433
31508
  return () => {
31434
31509
  engine?.destroy();
31435
31510
  };
@@ -31496,7 +31571,7 @@ var styles13 = StyleSheet13.create({
31496
31571
  var CoverPreview_default = CoverPreview;
31497
31572
 
31498
31573
  // components/ReadingShell.tsx
31499
- import React16, { useState as useState13 } from "react";
31574
+ import React16, { useState as useState14 } from "react";
31500
31575
  import { Keyboard as Keyboard2, View as View19, StyleSheet as StyleSheet20 } from "react-native";
31501
31576
  import { useViewerStore as useViewerStore17 } from "@papyrus-sdk/core";
31502
31577
 
@@ -31860,14 +31935,14 @@ var styles16 = StyleSheet16.create({
31860
31935
  });
31861
31936
 
31862
31937
  // components/ProgressPill.tsx
31863
- import { useEffect as useEffect10, useMemo as useMemo7, useRef as useRef8, useState as useState11 } from "react";
31938
+ import { useEffect as useEffect11, useMemo as useMemo7, useRef as useRef9, useState as useState12 } from "react";
31864
31939
  import {
31865
- Animated as Animated2,
31940
+ Animated as Animated3,
31866
31941
  PanResponder as PanResponder2,
31867
31942
  StyleSheet as StyleSheet17,
31868
31943
  Text as Text12,
31869
31944
  View as View17,
31870
- useWindowDimensions as useWindowDimensions6
31945
+ useWindowDimensions as useWindowDimensions7
31871
31946
  } from "react-native";
31872
31947
  import { useViewerStore as useViewerStore14 } from "@papyrus-sdk/core";
31873
31948
  import { jsx as jsx20, jsxs as jsxs17 } from "react/jsx-runtime";
@@ -31889,35 +31964,35 @@ function ProgressPill({
31889
31964
  } = useViewerStore14();
31890
31965
  const isDark = uiTheme === "dark";
31891
31966
  const offsets = resolveMobileChromeOffsets(usePapyrusSafeAreaInsets());
31892
- const { height: windowHeight } = useWindowDimensions6();
31967
+ const { height: windowHeight } = useWindowDimensions7();
31893
31968
  const trackHeight = Math.max(
31894
31969
  180,
31895
31970
  Math.min(520, windowHeight - offsets.progress - offsets.bottom - 132)
31896
31971
  );
31897
31972
  const thumbHeight = 44;
31898
- const trackYRef = useRef8(0);
31899
- const scrubberRef = useRef8(null);
31900
- const currentPageRef = useRef8(currentPage);
31973
+ const trackYRef = useRef9(0);
31974
+ const scrubberRef = useRef9(null);
31975
+ const currentPageRef = useRef9(currentPage);
31901
31976
  currentPageRef.current = currentPage;
31902
- const isScrubbingRef = useRef8(false);
31903
- const hasMovedRef = useRef8(false);
31904
- const longPressTriggeredRef = useRef8(false);
31905
- const longPressTimerRef = useRef8(null);
31906
- const pendingReleasedScrubPageRef = useRef8(null);
31907
- const [scrubPreviewPage, setScrubPreviewPage] = useState11(null);
31908
- const onNavigateToPageRef = useRef8(onNavigateToPage);
31909
- const onPressRef = useRef8(onPress);
31910
- const onOpenPageJumpRef = useRef8(onOpenPageJump);
31911
- const onScrubbingChangeRef = useRef8(onScrubbingChange);
31977
+ const isScrubbingRef = useRef9(false);
31978
+ const hasMovedRef = useRef9(false);
31979
+ const longPressTriggeredRef = useRef9(false);
31980
+ const longPressTimerRef = useRef9(null);
31981
+ const pendingReleasedScrubPageRef = useRef9(null);
31982
+ const [scrubPreviewPage, setScrubPreviewPage] = useState12(null);
31983
+ const onNavigateToPageRef = useRef9(onNavigateToPage);
31984
+ const onPressRef = useRef9(onPress);
31985
+ const onOpenPageJumpRef = useRef9(onOpenPageJump);
31986
+ const onScrubbingChangeRef = useRef9(onScrubbingChange);
31912
31987
  onScrubbingChangeRef.current = onScrubbingChange;
31913
- const scrubToPositionRef = useRef8(() => {
31988
+ const scrubToPositionRef = useRef9(() => {
31914
31989
  });
31915
- const scrubNavigationControllerRef = useRef8(
31990
+ const scrubNavigationControllerRef = useRef9(
31916
31991
  createPageScrubberNavigationController((page) => {
31917
31992
  onNavigateToPageRef.current?.(page);
31918
31993
  })
31919
31994
  );
31920
- const scrubberResponderRef = useRef8(null);
31995
+ const scrubberResponderRef = useRef9(null);
31921
31996
  const touchPolicy = resolvePageScrubberTouchPolicy();
31922
31997
  const displayedPage = scrubPreviewPage ?? currentPage;
31923
31998
  const label = useMemo7(() => {
@@ -31937,31 +32012,31 @@ function ProgressPill({
31937
32012
  thumbHeight,
31938
32013
  pageCount
31939
32014
  });
31940
- const thumbTopRef = useRef8(new Animated2.Value(thumbTop));
31941
- const thumbTopSnapshotRef = useRef8(thumbTop);
32015
+ const thumbTopRef = useRef9(new Animated3.Value(thumbTop));
32016
+ const thumbTopSnapshotRef = useRef9(thumbTop);
31942
32017
  thumbTopSnapshotRef.current = thumbTop;
31943
- const scrubberMetricsRef = useRef8({ trackHeight, thumbHeight, pageCount });
32018
+ const scrubberMetricsRef = useRef9({ trackHeight, thumbHeight, pageCount });
31944
32019
  scrubberMetricsRef.current = { trackHeight, thumbHeight, pageCount };
31945
- useEffect10(() => {
32020
+ useEffect11(() => {
31946
32021
  onNavigateToPageRef.current = onNavigateToPage;
31947
32022
  }, [onNavigateToPage]);
31948
- useEffect10(() => {
32023
+ useEffect11(() => {
31949
32024
  onPressRef.current = onPress;
31950
32025
  onOpenPageJumpRef.current = onOpenPageJump;
31951
32026
  }, [onOpenPageJump, onPress]);
31952
- useEffect10(() => {
32027
+ useEffect11(() => {
31953
32028
  const pendingPage = pendingReleasedScrubPageRef.current;
31954
32029
  if (pendingPage !== null && currentPage === pendingPage) {
31955
32030
  pendingReleasedScrubPageRef.current = null;
31956
32031
  setScrubPreviewPage(null);
31957
32032
  }
31958
32033
  }, [currentPage]);
31959
- useEffect10(() => {
32034
+ useEffect11(() => {
31960
32035
  if (!isScrubbingRef.current) {
31961
32036
  thumbTopRef.current.setValue(thumbTop);
31962
32037
  }
31963
32038
  }, [thumbTop, thumbTopRef]);
31964
- useEffect10(
32039
+ useEffect11(
31965
32040
  () => () => {
31966
32041
  if (longPressTimerRef.current !== null) {
31967
32042
  clearTimeout(longPressTimerRef.current);
@@ -32100,7 +32175,7 @@ function ProgressPill({
32100
32175
  },
32101
32176
  children: [
32102
32177
  /* @__PURE__ */ jsx20(View17, { style: [styles17.track, isDark && styles17.trackDark] }),
32103
- /* @__PURE__ */ jsx20(Animated2.View, { style: [styles17.thumb, { top: thumbTopRef.current }], children: /* @__PURE__ */ jsxs17(
32178
+ /* @__PURE__ */ jsx20(Animated3.View, { style: [styles17.thumb, { top: thumbTopRef.current }], children: /* @__PURE__ */ jsxs17(
32104
32179
  View17,
32105
32180
  {
32106
32181
  style: [
@@ -32199,7 +32274,7 @@ var styles17 = StyleSheet17.create({
32199
32274
  });
32200
32275
 
32201
32276
  // components/SearchOverlay.tsx
32202
- import React15, { useEffect as useEffect11, useMemo as useMemo8, useState as useState12 } from "react";
32277
+ import React15, { useEffect as useEffect12, useMemo as useMemo8, useState as useState13 } from "react";
32203
32278
  import {
32204
32279
  Keyboard,
32205
32280
  Pressable as Pressable12,
@@ -32230,19 +32305,19 @@ function SearchOverlay({
32230
32305
  uiTheme,
32231
32306
  accentColor
32232
32307
  } = useViewerStore15();
32233
- const [draft, setDraft] = useState12(searchQuery);
32234
- const [isSearching, setIsSearching] = useState12(false);
32308
+ const [draft, setDraft] = useState13(searchQuery);
32309
+ const [isSearching, setIsSearching] = useState13(false);
32235
32310
  const searchRequestIdRef = React15.useRef(0);
32236
32311
  const isDark = uiTheme === "dark";
32237
32312
  const offsets = resolveMobileChromeOffsets(usePapyrusSafeAreaInsets());
32238
32313
  const t = getStrings(locale);
32239
32314
  const searchService = useMemo8(() => new SearchService(engine), [engine]);
32240
- useEffect11(() => {
32315
+ useEffect12(() => {
32241
32316
  searchService.clearCache();
32242
32317
  }, [isLoaded, pageCount, searchService]);
32243
32318
  const currentCount = searchResults.length > 0 && activeSearchIndex >= 0 ? activeSearchIndex + 1 : 0;
32244
32319
  const targetLabel = documentType === "pdf" ? t.page : documentType === "epub" ? t.contents : t.progress;
32245
- useEffect11(() => {
32320
+ useEffect12(() => {
32246
32321
  if (!visible) return;
32247
32322
  setDraft(searchQuery);
32248
32323
  }, [searchQuery, visible]);
@@ -32636,13 +32711,13 @@ function ReadingShell({
32636
32711
  uiTheme,
32637
32712
  accentColor
32638
32713
  } = useViewerStore17();
32639
- const [overflowOpen, setOverflowOpen] = useState13(false);
32640
- const [infoOpen, setInfoOpen] = useState13(false);
32641
- const [actionsOpen, setActionsOpen] = useState13(false);
32642
- const [settingsOpen, setSettingsOpen] = useState13(false);
32643
- const [searchResultsOpen, setSearchResultsOpen] = useState13(false);
32644
- const [pageJumpOpen, setPageJumpOpen] = useState13(false);
32645
- const [pageScrubActive, setPageScrubActive] = useState13(false);
32714
+ const [overflowOpen, setOverflowOpen] = useState14(false);
32715
+ const [infoOpen, setInfoOpen] = useState14(false);
32716
+ const [actionsOpen, setActionsOpen] = useState14(false);
32717
+ const [settingsOpen, setSettingsOpen] = useState14(false);
32718
+ const [searchResultsOpen, setSearchResultsOpen] = useState14(false);
32719
+ const [pageJumpOpen, setPageJumpOpen] = useState14(false);
32720
+ const [pageScrubActive, setPageScrubActive] = useState14(false);
32646
32721
  const isDark = uiTheme === "dark";
32647
32722
  React16.useEffect(() => {
32648
32723
  const showSubscription = Keyboard2.addListener("keyboardDidShow", () => {
@@ -32758,7 +32833,11 @@ function ReadingShell({
32758
32833
  setSearchResultsOpen(false);
32759
32834
  closeMobileDestination();
32760
32835
  },
32761
- onOpenResults: () => setSearchResultsOpen(true)
32836
+ onOpenResults: () => {
32837
+ Keyboard2.dismiss();
32838
+ setSearchResultsOpen(true);
32839
+ closeMobileDestination();
32840
+ }
32762
32841
  }
32763
32842
  ),
32764
32843
  /* @__PURE__ */ jsx23(
@@ -32853,6 +32932,7 @@ export {
32853
32932
  BottomBar_default as BottomBar,
32854
32933
  CoverPreview_default as CoverPreview,
32855
32934
  DocumentActionsSheet,
32935
+ IconPageNav,
32856
32936
  InfoSheet,
32857
32937
  MOBILE_CHROME_METRICS,
32858
32938
  MobilePerfProvider,