@papyrus-sdk/ui-react-native 0.2.35-beta.5 → 0.2.35-beta.7

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
@@ -26071,6 +26071,29 @@ var STRINGS = {
26071
26071
  };
26072
26072
  var getStrings = (locale) => STRINGS[locale ?? "en"] ?? STRINGS.en;
26073
26073
 
26074
+ // components/nativeInkSession.ts
26075
+ function isNativeIosPencilKitViewer(platform, version, nativePdfViewerActive) {
26076
+ return platform === "ios" && Number.parseInt(String(version), 10) >= 16 && nativePdfViewerActive;
26077
+ }
26078
+ function finishNativeInkSession(setDocumentState) {
26079
+ setDocumentState({
26080
+ activeTool: "select",
26081
+ interactionMode: "pan",
26082
+ nativeInkToolPickerActive: false,
26083
+ toolDockOpen: false,
26084
+ activeMobileDestination: "none",
26085
+ mobileChromeVisible: true
26086
+ });
26087
+ }
26088
+ function handleNativeInkPickerVisibility(visible, state) {
26089
+ if (visible && (state.activeTool !== "ink" || !state.nativePdfViewerActive)) return;
26090
+ if (!visible && state.activeTool === "ink" && state.nativePdfViewerActive) {
26091
+ finishNativeInkSession(state.setDocumentState);
26092
+ return;
26093
+ }
26094
+ state.setDocumentState({ nativeInkToolPickerActive: visible });
26095
+ }
26096
+
26074
26097
  // components/annotationDeletion.ts
26075
26098
  var MARKUP_ANNOTATION_TYPES = /* @__PURE__ */ new Set([
26076
26099
  "highlight",
@@ -26273,19 +26296,12 @@ function DedicatedIosPdfViewer({
26273
26296
  );
26274
26297
  const handleInkToolPickerVisibilityChange = useCallback3(
26275
26298
  (event) => {
26276
- const visible = event.nativeEvent?.visible === true;
26277
- if (!visible && activeTool === "ink") {
26278
- setDocumentState({
26279
- activeTool: "select",
26280
- interactionMode: "pan",
26281
- nativeInkToolPickerActive: false,
26282
- toolDockOpen: false
26283
- });
26284
- return;
26285
- }
26286
- setDocumentState({ nativeInkToolPickerActive: visible });
26299
+ handleNativeInkPickerVisibility(
26300
+ event.nativeEvent?.visible === true,
26301
+ useViewerStore4.getState()
26302
+ );
26287
26303
  },
26288
- [activeTool, setDocumentState]
26304
+ []
26289
26305
  );
26290
26306
  const trackMobileChromeByOffset = useCallback3(
26291
26307
  (offsetY) => {
@@ -29082,7 +29098,7 @@ var styles7 = StyleSheet7.create({
29082
29098
  var Viewer_default = Viewer;
29083
29099
 
29084
29100
  // components/Topbar.tsx
29085
- import { useState as useState8 } from "react";
29101
+ import { useState as useState9 } from "react";
29086
29102
  import {
29087
29103
  View as View10,
29088
29104
  Text as Text4,
@@ -29090,10 +29106,58 @@ import {
29090
29106
  StyleSheet as StyleSheet10,
29091
29107
  useWindowDimensions as useWindowDimensions4
29092
29108
  } from "react-native";
29109
+ import { useViewerStore as useViewerStore9 } from "@papyrus-sdk/core";
29110
+ import Animated3, { useAnimatedStyle } from "react-native-reanimated";
29111
+
29112
+ // components/useNativeInkChrome.ts
29113
+ import { useCallback as useCallback5, useEffect as useEffect8, useState as useState6 } from "react";
29114
+ import { AccessibilityInfo, Platform as Platform5 } from "react-native";
29093
29115
  import { useViewerStore as useViewerStore8 } from "@papyrus-sdk/core";
29116
+ import {
29117
+ cancelAnimation,
29118
+ Easing,
29119
+ ReduceMotion,
29120
+ useReducedMotion,
29121
+ useSharedValue,
29122
+ withTiming
29123
+ } from "react-native-reanimated";
29124
+ function useNativeInkSession() {
29125
+ const nativePdfViewerActive = useViewerStore8((state) => state.nativePdfViewerActive);
29126
+ const activeTool = useViewerStore8((state) => state.activeTool);
29127
+ const supported = isNativeIosPencilKitViewer(Platform5.OS, Platform5.Version, nativePdfViewerActive);
29128
+ const finish = useCallback5(() => {
29129
+ finishNativeInkSession(useViewerStore8.getState().setDocumentState);
29130
+ }, []);
29131
+ return { supported, active: supported && activeTool === "ink", finish };
29132
+ }
29133
+ function useNativeInkMotion(visible, enabled) {
29134
+ const systemReducedMotion = useReducedMotion();
29135
+ const [reducedMotion, setReducedMotion] = useState6(systemReducedMotion);
29136
+ const progress = useSharedValue(visible ? 1 : 0);
29137
+ useEffect8(() => {
29138
+ let mounted = true;
29139
+ const subscription = AccessibilityInfo.addEventListener("reduceMotionChanged", setReducedMotion);
29140
+ AccessibilityInfo.isReduceMotionEnabled().then((value) => {
29141
+ if (mounted) setReducedMotion(value);
29142
+ });
29143
+ return () => {
29144
+ mounted = false;
29145
+ subscription.remove();
29146
+ };
29147
+ }, []);
29148
+ useEffect8(() => {
29149
+ progress.value = enabled ? withTiming(visible ? 1 : 0, {
29150
+ duration: reducedMotion ? 0 : 220,
29151
+ easing: Easing.out(Easing.cubic),
29152
+ reduceMotion: ReduceMotion.System
29153
+ }) : visible ? 1 : 0;
29154
+ }, [enabled, progress, reducedMotion, visible]);
29155
+ useEffect8(() => () => cancelAnimation(progress), [progress]);
29156
+ return progress;
29157
+ }
29094
29158
 
29095
29159
  // components/PageJumpModal.tsx
29096
- import { useEffect as useEffect9, useState as useState7 } from "react";
29160
+ import { useEffect as useEffect10, useState as useState8 } from "react";
29097
29161
  import { Pressable as Pressable5, StyleSheet as StyleSheet9, Text as Text3, TextInput, View as View9 } from "react-native";
29098
29162
 
29099
29163
  // components/pageJumpModel.ts
@@ -29105,7 +29169,7 @@ var resolvePageJumpTarget = (value, pageCount) => {
29105
29169
  };
29106
29170
 
29107
29171
  // components/NativeSheet.tsx
29108
- import React10, { useEffect as useEffect8, useRef as useRef6, useState as useState6 } from "react";
29172
+ import React10, { useEffect as useEffect9, useRef as useRef6, useState as useState7 } from "react";
29109
29173
  import {
29110
29174
  Animated as Animated2,
29111
29175
  FlatList as FlatList2,
@@ -29213,11 +29277,11 @@ function NativeSheet({
29213
29277
  const palette = getNativeSheetPalette(Boolean(isDark));
29214
29278
  const { height: windowHeight, width: windowWidth } = useWindowDimensions3();
29215
29279
  const tabletLayout = getNativeSheetLayoutStyles(windowWidth);
29216
- const [rendered, setRendered] = useState6(visible);
29280
+ const [rendered, setRendered] = useState7(visible);
29217
29281
  const renderedRef = useRef6(visible);
29218
29282
  const motion = useRef6(new Animated2.Value(visible ? 0 : 1)).current;
29219
29283
  const backdropOpacity = useRef6(new Animated2.Value(visible ? 1 : 0)).current;
29220
- useEffect8(() => {
29284
+ useEffect9(() => {
29221
29285
  motion.stopAnimation();
29222
29286
  backdropOpacity.stopAnimation();
29223
29287
  if (visible) {
@@ -29411,9 +29475,9 @@ function PageJumpModal({
29411
29475
  onClose,
29412
29476
  onConfirm
29413
29477
  }) {
29414
- const [value, setValue] = useState7(`${currentPage}`);
29478
+ const [value, setValue] = useState8(`${currentPage}`);
29415
29479
  const palette = getReaderSheetPalette(isDark);
29416
- useEffect9(() => {
29480
+ useEffect10(() => {
29417
29481
  if (visible) setValue(`${currentPage}`);
29418
29482
  }, [currentPage, visible]);
29419
29483
  const confirmJump = () => {
@@ -29529,9 +29593,21 @@ var Topbar = ({
29529
29593
  setDocumentState,
29530
29594
  triggerScrollToPage,
29531
29595
  accentColor,
29532
- mobileChromeVisible
29533
- } = useViewerStore8();
29534
- const [jumpModalOpen, setJumpModalOpen] = useState8(false);
29596
+ mobileChromeVisible,
29597
+ locale
29598
+ } = useViewerStore9();
29599
+ const inkSession = useNativeInkSession();
29600
+ const t = getStrings(locale);
29601
+ const progress = useNativeInkMotion(inkSession.active, inkSession.supported);
29602
+ const settingsMotion = useAnimatedStyle(() => ({
29603
+ opacity: 1 - progress.value,
29604
+ transform: [{ scale: 1 - progress.value * 0.04 }, { translateX: -progress.value * 6 }]
29605
+ }));
29606
+ const doneMotion = useAnimatedStyle(() => ({
29607
+ opacity: progress.value,
29608
+ transform: [{ scale: 0.96 + progress.value * 0.04 }, { translateX: (1 - progress.value) * 6 }]
29609
+ }));
29610
+ const [jumpModalOpen, setJumpModalOpen] = useState9(false);
29535
29611
  const isDark = uiTheme === "dark";
29536
29612
  const navIconColor = isDark ? "#e5e7eb" : "#111827";
29537
29613
  const { width, height } = useWindowDimensions4();
@@ -29555,7 +29631,22 @@ var Topbar = ({
29555
29631
  };
29556
29632
  const defaultLogo = /* @__PURE__ */ jsx14(View10, { style: [styles10.logoBadge, { backgroundColor: accentColor }], children: /* @__PURE__ */ jsx14(Text4, { style: styles10.logoText, children: "P" }) });
29557
29633
  const logoElement = logo ?? defaultLogo;
29558
- if (!mobileChromeVisible) return null;
29634
+ const settingsControl = /* @__PURE__ */ jsx14(
29635
+ Pressable6,
29636
+ {
29637
+ onPress: () => onOpenOverflow?.() ?? onOpenSettings?.(),
29638
+ style: [
29639
+ styles10.iconButton,
29640
+ isDark && styles10.iconButtonDark,
29641
+ inkSession.supported && styles10.annotationSettingsButton
29642
+ ],
29643
+ accessibilityRole: "button",
29644
+ accessibilityLabel: "Open overflow menu",
29645
+ disabled: inkSession.active,
29646
+ children: /* @__PURE__ */ jsx14(IconSettings, { size: MOBILE_CHROME_METRICS.iconSize, color: isDark ? "#e5e7eb" : "#111827" })
29647
+ }
29648
+ );
29649
+ if (!mobileChromeVisible && !inkSession.active) return null;
29559
29650
  return /* @__PURE__ */ jsxs9(Fragment3, { children: [
29560
29651
  /* @__PURE__ */ jsx14(
29561
29652
  View10,
@@ -29583,7 +29674,10 @@ var Topbar = ({
29583
29674
  onLogoPress ? /* @__PURE__ */ jsx14(
29584
29675
  Pressable6,
29585
29676
  {
29586
- onPress: onLogoPress,
29677
+ onPress: () => {
29678
+ if (inkSession.active) inkSession.finish();
29679
+ else onLogoPress();
29680
+ },
29587
29681
  accessibilityRole: "button",
29588
29682
  accessibilityLabel: logoAccessibilityLabel,
29589
29683
  style: styles10.logoSlot,
@@ -29660,21 +29754,49 @@ var Topbar = ({
29660
29754
  }
29661
29755
  )
29662
29756
  ] }) }) : null,
29663
- /* @__PURE__ */ jsx14(View10, { style: styles10.rightGroup, children: /* @__PURE__ */ jsx14(
29664
- Pressable6,
29757
+ /* @__PURE__ */ jsx14(
29758
+ View10,
29665
29759
  {
29666
- onPress: () => onOpenOverflow?.() ?? onOpenSettings?.(),
29667
- style: [styles10.iconButton, isDark && styles10.iconButtonDark],
29668
- accessibilityLabel: "Open overflow menu",
29669
- children: /* @__PURE__ */ jsx14(
29670
- IconSettings,
29671
- {
29672
- size: MOBILE_CHROME_METRICS.iconSize,
29673
- color: isDark ? "#e5e7eb" : "#111827"
29674
- }
29675
- )
29760
+ style: [styles10.rightGroup, inkSession.supported && styles10.annotationActionSlot],
29761
+ testID: "papyrus-topbar-action-slot",
29762
+ children: inkSession.supported ? /* @__PURE__ */ jsxs9(Fragment3, { children: [
29763
+ /* @__PURE__ */ jsx14(
29764
+ Animated3.View,
29765
+ {
29766
+ style: [styles10.settingsSlot, settingsMotion],
29767
+ pointerEvents: inkSession.active ? "none" : "auto",
29768
+ accessibilityElementsHidden: inkSession.active,
29769
+ importantForAccessibility: inkSession.active ? "no-hide-descendants" : "auto",
29770
+ children: settingsControl
29771
+ }
29772
+ ),
29773
+ /* @__PURE__ */ jsx14(
29774
+ Animated3.View,
29775
+ {
29776
+ style: [styles10.doneSlot, doneMotion],
29777
+ pointerEvents: inkSession.active ? "auto" : "none",
29778
+ accessibilityElementsHidden: !inkSession.active,
29779
+ importantForAccessibility: inkSession.active ? "auto" : "no-hide-descendants",
29780
+ children: /* @__PURE__ */ jsx14(
29781
+ Pressable6,
29782
+ {
29783
+ onPress: inkSession.finish,
29784
+ disabled: !inkSession.active,
29785
+ style: styles10.doneButton,
29786
+ accessibilityRole: "button",
29787
+ accessibilityLabel: t.done,
29788
+ testID: "papyrus-topbar-ink-done",
29789
+ children: /* @__PURE__ */ jsxs9(Text4, { style: styles10.doneButtonText, children: [
29790
+ "\u2713 ",
29791
+ t.done
29792
+ ] })
29793
+ }
29794
+ )
29795
+ }
29796
+ )
29797
+ ] }) : settingsControl
29676
29798
  }
29677
- ) })
29799
+ )
29678
29800
  ]
29679
29801
  }
29680
29802
  )
@@ -29820,6 +29942,42 @@ var styles10 = StyleSheet10.create({
29820
29942
  flexShrink: 0,
29821
29943
  marginLeft: 12
29822
29944
  },
29945
+ annotationActionSlot: {
29946
+ width: 108,
29947
+ height: 44
29948
+ },
29949
+ settingsSlot: {
29950
+ position: "absolute",
29951
+ right: 0,
29952
+ top: 0
29953
+ },
29954
+ annotationSettingsButton: {
29955
+ minWidth: 44,
29956
+ minHeight: 44,
29957
+ marginLeft: 0,
29958
+ justifyContent: "center",
29959
+ alignItems: "center"
29960
+ },
29961
+ doneSlot: {
29962
+ position: "absolute",
29963
+ left: 0,
29964
+ right: 0,
29965
+ top: 0
29966
+ },
29967
+ doneButton: {
29968
+ minWidth: 44,
29969
+ minHeight: 44,
29970
+ paddingHorizontal: 10,
29971
+ borderRadius: 12,
29972
+ backgroundColor: "#2563eb",
29973
+ alignItems: "center",
29974
+ justifyContent: "center"
29975
+ },
29976
+ doneButtonText: {
29977
+ color: "#fff",
29978
+ fontSize: 14,
29979
+ fontWeight: "700"
29980
+ },
29823
29981
  iconButton: {
29824
29982
  paddingHorizontal: 10,
29825
29983
  paddingVertical: 6,
@@ -29855,7 +30013,7 @@ var styles10 = StyleSheet10.create({
29855
30013
  var Topbar_default = Topbar;
29856
30014
 
29857
30015
  // components/ToolDock.tsx
29858
- import React13, { useEffect as useEffect10, useMemo as useMemo6, useRef as useRef7, useState as useState9 } from "react";
30016
+ import React13, { useEffect as useEffect11, useMemo as useMemo6, useRef as useRef7, useState as useState10 } from "react";
29859
30017
  import {
29860
30018
  View as View11,
29861
30019
  Text as Text5,
@@ -29864,7 +30022,7 @@ import {
29864
30022
  ScrollView as ScrollView3,
29865
30023
  useWindowDimensions as useWindowDimensions5
29866
30024
  } from "react-native";
29867
- import { useViewerStore as useViewerStore9 } from "@papyrus-sdk/core";
30025
+ import { useViewerStore as useViewerStore10 } from "@papyrus-sdk/core";
29868
30026
 
29869
30027
  // components/ToolDock.layout.ts
29870
30028
  var TOOL_DOCK_SCROLL_THRESHOLD = 420;
@@ -29969,18 +30127,18 @@ var OpacitySlider = React13.memo(function OpacitySlider2({
29969
30127
  isDark,
29970
30128
  onCommit
29971
30129
  }) {
29972
- const [trackWidth, setTrackWidth] = useState9(0);
29973
- const [draftValue, setDraftValue] = useState9(value);
30130
+ const [trackWidth, setTrackWidth] = useState10(0);
30131
+ const [draftValue, setDraftValue] = useState10(value);
29974
30132
  const dragValueRef = useRef7(draftValue);
29975
30133
  const isDraggingRef = useRef7(false);
29976
30134
  const frameRef = useRef7(null);
29977
- useEffect10(() => {
30135
+ useEffect11(() => {
29978
30136
  if (!isDraggingRef.current) {
29979
30137
  dragValueRef.current = value;
29980
30138
  setDraftValue(value);
29981
30139
  }
29982
30140
  }, [value]);
29983
- useEffect10(() => {
30141
+ useEffect11(() => {
29984
30142
  return () => {
29985
30143
  if (frameRef.current !== null) {
29986
30144
  cancelAnimationFrame(frameRef.current);
@@ -30080,9 +30238,9 @@ var ToolDock = () => {
30080
30238
  annotationRedoStack,
30081
30239
  undoAnnotations,
30082
30240
  redoAnnotations
30083
- } = useViewerStore9();
30084
- const [paletteExpanded, setPaletteExpanded] = useState9(false);
30085
- const [extrasExpanded, setExtrasExpanded] = useState9(false);
30241
+ } = useViewerStore10();
30242
+ const [paletteExpanded, setPaletteExpanded] = useState10(false);
30243
+ const [extrasExpanded, setExtrasExpanded] = useState10(false);
30086
30244
  const isDark = uiTheme === "dark";
30087
30245
  const { width: windowWidth } = useWindowDimensions5();
30088
30246
  const t = getStrings(locale);
@@ -30109,7 +30267,7 @@ var ToolDock = () => {
30109
30267
  const canUndo = annotationUndoStack.length > 0;
30110
30268
  const canRedo = annotationRedoStack.length > 0;
30111
30269
  const primaryToolsRowIsScrollable = shouldUseScrollablePrimaryToolsRow(windowWidth);
30112
- useEffect10(() => {
30270
+ useEffect11(() => {
30113
30271
  if (!nativeInkToolPickerActive) return;
30114
30272
  setPaletteExpanded(false);
30115
30273
  setExtrasExpanded(false);
@@ -30822,15 +30980,15 @@ var ToolDock_default = ToolDock;
30822
30980
 
30823
30981
  // components/RightSheet.tsx
30824
30982
  import {
30825
- useCallback as useCallback5,
30826
- useEffect as useEffect11,
30983
+ useCallback as useCallback6,
30984
+ useEffect as useEffect12,
30827
30985
  useMemo as useMemo7,
30828
30986
  useRef as useRef8,
30829
- useState as useState10
30987
+ useState as useState11
30830
30988
  } from "react";
30831
30989
  import {
30832
30990
  Image as Image2,
30833
- Platform as Platform5,
30991
+ Platform as Platform6,
30834
30992
  Pressable as Pressable8,
30835
30993
  StyleSheet as StyleSheet12,
30836
30994
  Text as Text6,
@@ -30839,7 +30997,7 @@ import {
30839
30997
  findNodeHandle as findNodeHandle2,
30840
30998
  useWindowDimensions as useWindowDimensions6
30841
30999
  } from "react-native";
30842
- import { useViewerStore as useViewerStore10 } from "@papyrus-sdk/core";
31000
+ import { useViewerStore as useViewerStore11 } from "@papyrus-sdk/core";
30843
31001
  import { PapyrusPageView as PapyrusPageView2 } from "@papyrus-sdk/engine-native";
30844
31002
 
30845
31003
  // components/rightSheetLayout.ts
@@ -30905,13 +31063,13 @@ var PageThumbnail = ({
30905
31063
  onPress
30906
31064
  }) => {
30907
31065
  const viewRef = useRef8(null);
30908
- const [layoutReady, setLayoutReady] = useState10(false);
30909
- const [previewUri, setPreviewUri] = useState10(null);
30910
- useEffect11(() => {
31066
+ const [layoutReady, setLayoutReady] = useState11(false);
31067
+ const [previewUri, setPreviewUri] = useState11(null);
31068
+ useEffect12(() => {
30911
31069
  if (!layoutReady || !useNativePreview || !shouldRenderPreview) return;
30912
31070
  const viewTag = findNodeHandle2(viewRef.current);
30913
31071
  if (!viewTag) return;
30914
- const isNative = Platform5.OS === "android" || Platform5.OS === "ios";
31072
+ const isNative = Platform6.OS === "android" || Platform6.OS === "ios";
30915
31073
  const renderScale = isNative ? 2 / Math.max(zoom, 0.5) : 2;
30916
31074
  void engine.renderPage(pageIndex, viewTag, renderScale);
30917
31075
  }, [
@@ -30922,7 +31080,7 @@ var PageThumbnail = ({
30922
31080
  useNativePreview,
30923
31081
  zoom
30924
31082
  ]);
30925
- useEffect11(() => {
31083
+ useEffect12(() => {
30926
31084
  if (!useImagePreview || !shouldRenderPreview) {
30927
31085
  setPreviewUri(null);
30928
31086
  return;
@@ -31051,12 +31209,12 @@ var RightSheet = ({
31051
31209
  zoom,
31052
31210
  locale,
31053
31211
  accentColor
31054
- } = useViewerStore10();
31212
+ } = useViewerStore11();
31055
31213
  const { height: windowHeight, width: windowWidth } = useWindowDimensions6();
31056
- const [pagesMode, setPagesMode] = useState10(
31214
+ const [pagesMode, setPagesMode] = useState11(
31057
31215
  documentType === "pdf" || documentType === "comic" ? "thumbnails" : "summary"
31058
31216
  );
31059
- useEffect11(() => {
31217
+ useEffect12(() => {
31060
31218
  setPagesMode(
31061
31219
  documentType === "pdf" || documentType === "comic" ? "thumbnails" : "summary"
31062
31220
  );
@@ -31080,8 +31238,8 @@ var RightSheet = ({
31080
31238
  const thumbnailDimensionsCacheRef = useRef8(/* @__PURE__ */ new Map());
31081
31239
  const thumbnailDimensionsPendingRef = useRef8(/* @__PURE__ */ new Set());
31082
31240
  const thumbnailRefreshTimeoutRef = useRef8(null);
31083
- const [thumbnailLayoutRevision, setThumbnailLayoutRevision] = useState10(0);
31084
- const [visibleThumbnailPages, setVisibleThumbnailPages] = useState10(() => /* @__PURE__ */ new Set());
31241
+ const [thumbnailLayoutRevision, setThumbnailLayoutRevision] = useState11(0);
31242
+ const [visibleThumbnailPages, setVisibleThumbnailPages] = useState11(() => /* @__PURE__ */ new Set());
31085
31243
  const resolvedThumbsInitialCount = useMemo7(
31086
31244
  () => resolvePositiveInt2(
31087
31245
  thumbsInitialCount,
@@ -31101,10 +31259,10 @@ var RightSheet = ({
31101
31259
  const navigationTitle = showingProgress ? t.progress : documentType === "epub" || activeMobileDestination === "contents" ? t.contents : t.pages;
31102
31260
  const summaryLabel = documentType === "epub" ? t.contents : t.summaryTab;
31103
31261
  const thumbnailLabel = documentType === "epub" ? t.pages : t.pagesTab;
31104
- const closeSheet = useCallback5(() => {
31262
+ const closeSheet = useCallback6(() => {
31105
31263
  setDocumentState({ sidebarRightOpen: false });
31106
31264
  }, [setDocumentState]);
31107
- const jumpToPage = useCallback5(
31265
+ const jumpToPage = useCallback6(
31108
31266
  (pageIndex) => {
31109
31267
  engine.goToPage(pageIndex + 1);
31110
31268
  setDocumentState({ currentPage: pageIndex + 1 });
@@ -31113,14 +31271,14 @@ var RightSheet = ({
31113
31271
  },
31114
31272
  [closeSheet, engine, setDocumentState, triggerScrollToPage]
31115
31273
  );
31116
- const scheduleThumbnailLayoutRefresh = useCallback5(() => {
31274
+ const scheduleThumbnailLayoutRefresh = useCallback6(() => {
31117
31275
  if (thumbnailRefreshTimeoutRef.current) return;
31118
31276
  thumbnailRefreshTimeoutRef.current = setTimeout(() => {
31119
31277
  thumbnailRefreshTimeoutRef.current = null;
31120
31278
  setThumbnailLayoutRevision((value) => value + 1);
31121
31279
  }, 80);
31122
31280
  }, []);
31123
- const ensureThumbnailDimensions = useCallback5(
31281
+ const ensureThumbnailDimensions = useCallback6(
31124
31282
  (pageIndex) => {
31125
31283
  if (pageIndex < 0 || pageIndex >= pageCount) return;
31126
31284
  if (thumbnailDimensionsCacheRef.current.has(pageIndex)) return;
@@ -31139,7 +31297,7 @@ var RightSheet = ({
31139
31297
  },
31140
31298
  [engine, pageCount, scheduleThumbnailLayoutRefresh]
31141
31299
  );
31142
- const getThumbnailFrameHeight = useCallback5(
31300
+ const getThumbnailFrameHeight = useCallback6(
31143
31301
  (pageIndex) => {
31144
31302
  const dims = thumbnailDimensionsCacheRef.current.get(pageIndex);
31145
31303
  const ratio = !dims || dims.width <= 0 || dims.height <= 0 ? THUMBNAILS_DEFAULT_ASPECT_RATIO : dims.height / dims.width;
@@ -31151,7 +31309,7 @@ var RightSheet = ({
31151
31309
  },
31152
31310
  [frameWidth, thumbnailLayoutRevision]
31153
31311
  );
31154
- useEffect11(
31312
+ useEffect12(
31155
31313
  () => () => {
31156
31314
  if (thumbnailRefreshTimeoutRef.current) {
31157
31315
  clearTimeout(thumbnailRefreshTimeoutRef.current);
@@ -31159,11 +31317,11 @@ var RightSheet = ({
31159
31317
  },
31160
31318
  []
31161
31319
  );
31162
- useEffect11(() => {
31320
+ useEffect12(() => {
31163
31321
  if (sidebarRightOpen) return;
31164
31322
  setVisibleThumbnailPages(/* @__PURE__ */ new Set());
31165
31323
  }, [sidebarRightOpen]);
31166
- useEffect11(() => {
31324
+ useEffect12(() => {
31167
31325
  if (!sidebarRightOpen || sidebarRightTab !== "pages") return;
31168
31326
  if (activeMobileDestination === "pages") {
31169
31327
  setPagesMode("thumbnails");
@@ -31171,7 +31329,7 @@ var RightSheet = ({
31171
31329
  }
31172
31330
  setPagesMode("summary");
31173
31331
  }, [activeMobileDestination, sidebarRightOpen, sidebarRightTab]);
31174
- useEffect11(() => {
31332
+ useEffect12(() => {
31175
31333
  if (!sidebarRightOpen || sidebarRightTab !== "pages") return;
31176
31334
  if (pagesMode !== "thumbnails" || !supportsThumbnails) return;
31177
31335
  if (pageCount <= 0) return;
@@ -31212,7 +31370,7 @@ var RightSheet = ({
31212
31370
  })),
31213
31371
  [pageCount, pages]
31214
31372
  );
31215
- const onThumbnailsViewableItemsChanged = useCallback5(
31373
+ const onThumbnailsViewableItemsChanged = useCallback6(
31216
31374
  ({ viewableItems }) => {
31217
31375
  const nextVisible = /* @__PURE__ */ new Set();
31218
31376
  viewableItems.forEach((token) => {
@@ -31229,7 +31387,7 @@ var RightSheet = ({
31229
31387
  },
31230
31388
  [ensureThumbnailDimensions]
31231
31389
  );
31232
- const renderThumbnailItem = useCallback5(
31390
+ const renderThumbnailItem = useCallback6(
31233
31391
  ({ item }) => {
31234
31392
  const shouldRenderPreview = (useNativePreview || useImagePreview) && (visibleThumbnailPages.has(item) || item < resolvedThumbsPrewarmCount || Math.abs(item + 1 - currentPage) <= 1);
31235
31393
  return /* @__PURE__ */ jsx16(
@@ -31835,7 +31993,7 @@ var styles12 = StyleSheet12.create({
31835
31993
  var RightSheet_default = RightSheet;
31836
31994
 
31837
31995
  // components/AnnotationEditor.tsx
31838
- import { useEffect as useEffect12, useState as useState11 } from "react";
31996
+ import { useEffect as useEffect13, useState as useState12 } from "react";
31839
31997
  import {
31840
31998
  Modal as Modal2,
31841
31999
  View as View13,
@@ -31844,7 +32002,7 @@ import {
31844
32002
  Pressable as Pressable9,
31845
32003
  StyleSheet as StyleSheet13
31846
32004
  } from "react-native";
31847
- import { useViewerStore as useViewerStore11 } from "@papyrus-sdk/core";
32005
+ import { useViewerStore as useViewerStore12 } from "@papyrus-sdk/core";
31848
32006
  import { jsx as jsx17, jsxs as jsxs12 } from "react/jsx-runtime";
31849
32007
  var AnnotationEditor = () => {
31850
32008
  const {
@@ -31856,13 +32014,13 @@ var AnnotationEditor = () => {
31856
32014
  uiTheme,
31857
32015
  locale,
31858
32016
  accentColor
31859
- } = useViewerStore11();
32017
+ } = useViewerStore12();
31860
32018
  const annotation = annotations.find((ann) => ann.id === selectedAnnotationId);
31861
32019
  const isEditable = annotation && (annotation.type === "text" || annotation.type === "comment");
31862
- const [draft, setDraft] = useState11("");
32020
+ const [draft, setDraft] = useState12("");
31863
32021
  const isDark = uiTheme === "dark";
31864
32022
  const t = getStrings(locale);
31865
- useEffect12(() => {
32023
+ useEffect13(() => {
31866
32024
  if (isEditable) {
31867
32025
  setDraft(annotation?.content ?? "");
31868
32026
  }
@@ -32019,8 +32177,9 @@ var styles13 = StyleSheet13.create({
32019
32177
  var AnnotationEditor_default = AnnotationEditor;
32020
32178
 
32021
32179
  // components/BottomBar.tsx
32022
- import { View as View14, Pressable as Pressable10, StyleSheet as StyleSheet14, useWindowDimensions as useWindowDimensions7, Platform as Platform6 } from "react-native";
32023
- import { useViewerStore as useViewerStore12 } from "@papyrus-sdk/core";
32180
+ import { View as View14, Pressable as Pressable10, StyleSheet as StyleSheet14, useWindowDimensions as useWindowDimensions7 } from "react-native";
32181
+ import { useViewerStore as useViewerStore13 } from "@papyrus-sdk/core";
32182
+ import Animated4, { useAnimatedStyle as useAnimatedStyle2 } from "react-native-reanimated";
32024
32183
 
32025
32184
  // components/bottomBarModel.ts
32026
32185
  function buildBottomBarLayout({
@@ -32089,9 +32248,17 @@ var BottomBar = ({
32089
32248
  mobileChromeVisible,
32090
32249
  toolDockOpen,
32091
32250
  activeTool,
32092
- interactionMode,
32093
- nativePdfViewerActive
32094
- } = useViewerStore12();
32251
+ interactionMode
32252
+ } = useViewerStore13();
32253
+ const inkSession = useNativeInkSession();
32254
+ const supportsInkChrome = documentType === "pdf" && inkSession.supported;
32255
+ const drawing = supportsInkChrome && inkSession.active;
32256
+ const dockVisible = mobileChromeVisible && mobileDockVisible && !drawing;
32257
+ const dockProgress = useNativeInkMotion(dockVisible, supportsInkChrome);
32258
+ const dockMotion = useAnimatedStyle2(() => ({
32259
+ opacity: dockProgress.value,
32260
+ transform: [{ translateY: (1 - dockProgress.value) * 8 }]
32261
+ }));
32095
32262
  const isDark = uiTheme === "dark";
32096
32263
  const t = getStrings(locale);
32097
32264
  const { width, height } = useWindowDimensions7();
@@ -32111,7 +32278,7 @@ var BottomBar = ({
32111
32278
  label: t.tools,
32112
32279
  icon: IconToolDockTrigger,
32113
32280
  onPress: () => {
32114
- const isNativeIosInkViewer = Platform6.OS === "ios" && Number.parseInt(String(Platform6.Version), 10) >= 16 && nativePdfViewerActive;
32281
+ const isNativeIosInkViewer = supportsInkChrome;
32115
32282
  const action = resolveAnnotateButtonAction({
32116
32283
  isNativeIosInkViewer,
32117
32284
  activeTool,
@@ -32128,13 +32295,7 @@ var BottomBar = ({
32128
32295
  return;
32129
32296
  }
32130
32297
  if (action === "deactivate-native-ink") {
32131
- setDocumentState({
32132
- activeTool: "select",
32133
- interactionMode: "pan",
32134
- nativeInkToolPickerActive: false,
32135
- toolDockOpen: false,
32136
- activeMobileDestination: "none"
32137
- });
32298
+ inkSession.finish();
32138
32299
  return;
32139
32300
  }
32140
32301
  if (action === "dismiss-tool-dock") {
@@ -32172,96 +32333,108 @@ var BottomBar = ({
32172
32333
  onPress: onOpenSettings
32173
32334
  }
32174
32335
  };
32175
- if (!mobileChromeVisible || !mobileDockVisible) return null;
32176
- return /* @__PURE__ */ jsx18(View14, { pointerEvents: "box-none", style: [styles14.frame, { paddingBottom: offsets.bottom, paddingLeft: offsets.left, paddingRight: offsets.right }], children: /* @__PURE__ */ jsxs13(View14, { style: [styles14.row, isLandscape && styles14.rowLandscape], children: [
32177
- layout.leftSlots.length > 0 ? /* @__PURE__ */ jsx18(
32178
- View14,
32179
- {
32180
- style: [
32181
- styles14.island,
32182
- styles14.editIsland,
32183
- isDark && styles14.islandDark
32184
- ],
32185
- testID: "papyrus-floating-bottom-dock-edit",
32186
- children: layout.leftSlots.map((slot) => {
32187
- const meta = slotMeta[slot.key];
32188
- const Icon = meta.icon;
32189
- return /* @__PURE__ */ jsx18(
32190
- Pressable10,
32191
- {
32192
- onPress: meta.onPress,
32193
- style: [
32194
- styles14.iconOnlyItem,
32195
- slot.active && styles14.itemActive
32196
- ],
32197
- accessibilityLabel: meta.label,
32198
- testID: `papyrus-mobile-destination-${slot.key}`,
32199
- children: /* @__PURE__ */ jsx18(
32200
- View14,
32336
+ if (!dockVisible && !supportsInkChrome) return null;
32337
+ return /* @__PURE__ */ jsx18(
32338
+ Animated4.View,
32339
+ {
32340
+ pointerEvents: dockVisible ? "box-none" : "none",
32341
+ accessibilityElementsHidden: !dockVisible,
32342
+ importantForAccessibility: dockVisible ? "auto" : "no-hide-descendants",
32343
+ testID: "papyrus-bottom-bar-frame",
32344
+ style: [styles14.frame, { paddingBottom: offsets.bottom, paddingLeft: offsets.left, paddingRight: offsets.right }, dockMotion],
32345
+ children: /* @__PURE__ */ jsxs13(View14, { style: [styles14.row, isLandscape && styles14.rowLandscape], children: [
32346
+ layout.leftSlots.length > 0 ? /* @__PURE__ */ jsx18(
32347
+ View14,
32348
+ {
32349
+ style: [
32350
+ styles14.island,
32351
+ styles14.editIsland,
32352
+ isDark && styles14.islandDark
32353
+ ],
32354
+ testID: "papyrus-floating-bottom-dock-edit",
32355
+ children: layout.leftSlots.map((slot) => {
32356
+ const meta = slotMeta[slot.key];
32357
+ const Icon = meta.icon;
32358
+ return /* @__PURE__ */ jsx18(
32359
+ Pressable10,
32201
32360
  {
32361
+ disabled: !dockVisible,
32362
+ onPress: meta.onPress,
32202
32363
  style: [
32203
- styles14.itemIcon,
32204
- isDark && styles14.itemIconDark,
32205
- slot.active && styles14.itemIconActive
32364
+ styles14.iconOnlyItem,
32365
+ slot.active && styles14.itemActive
32206
32366
  ],
32367
+ accessibilityLabel: meta.label,
32368
+ testID: `papyrus-mobile-destination-${slot.key}`,
32207
32369
  children: /* @__PURE__ */ jsx18(
32208
- Icon,
32370
+ View14,
32209
32371
  {
32210
- size: MOBILE_CHROME_METRICS.iconSize,
32211
- color: iconColor(slot.active)
32372
+ style: [
32373
+ styles14.itemIcon,
32374
+ isDark && styles14.itemIconDark,
32375
+ slot.active && styles14.itemIconActive
32376
+ ],
32377
+ children: /* @__PURE__ */ jsx18(
32378
+ Icon,
32379
+ {
32380
+ size: MOBILE_CHROME_METRICS.iconSize,
32381
+ color: iconColor(slot.active)
32382
+ }
32383
+ )
32212
32384
  }
32213
32385
  )
32214
- }
32215
- )
32216
- },
32217
- slot.key
32218
- );
32219
- })
32220
- }
32221
- ) : null,
32222
- /* @__PURE__ */ jsx18(
32223
- View14,
32224
- {
32225
- style: [
32226
- styles14.island,
32227
- styles14.utilityIsland,
32228
- isDark && styles14.islandDark
32229
- ],
32230
- testID: "papyrus-floating-bottom-dock",
32231
- children: layout.rightSlots.map((slot) => {
32232
- const meta = slotMeta[slot.key];
32233
- const Icon = meta.icon;
32234
- return /* @__PURE__ */ jsx18(
32235
- Pressable10,
32236
- {
32237
- onPress: meta.onPress,
32238
- style: [styles14.iconOnlyItem, slot.active && styles14.itemActive],
32239
- accessibilityLabel: meta.label,
32240
- testID: `papyrus-mobile-destination-${slot.key}`,
32241
- children: /* @__PURE__ */ jsx18(
32242
- View14,
32386
+ },
32387
+ slot.key
32388
+ );
32389
+ })
32390
+ }
32391
+ ) : null,
32392
+ /* @__PURE__ */ jsx18(
32393
+ View14,
32394
+ {
32395
+ style: [
32396
+ styles14.island,
32397
+ styles14.utilityIsland,
32398
+ isDark && styles14.islandDark
32399
+ ],
32400
+ testID: "papyrus-floating-bottom-dock",
32401
+ children: layout.rightSlots.map((slot) => {
32402
+ const meta = slotMeta[slot.key];
32403
+ const Icon = meta.icon;
32404
+ return /* @__PURE__ */ jsx18(
32405
+ Pressable10,
32243
32406
  {
32244
- style: [
32245
- styles14.itemIcon,
32246
- isDark && styles14.itemIconDark,
32247
- slot.active && styles14.itemIconActive
32248
- ],
32407
+ disabled: !dockVisible,
32408
+ onPress: meta.onPress,
32409
+ style: [styles14.iconOnlyItem, slot.active && styles14.itemActive],
32410
+ accessibilityLabel: meta.label,
32411
+ testID: `papyrus-mobile-destination-${slot.key}`,
32249
32412
  children: /* @__PURE__ */ jsx18(
32250
- Icon,
32413
+ View14,
32251
32414
  {
32252
- size: MOBILE_CHROME_METRICS.iconSize,
32253
- color: iconColor(slot.active)
32415
+ style: [
32416
+ styles14.itemIcon,
32417
+ isDark && styles14.itemIconDark,
32418
+ slot.active && styles14.itemIconActive
32419
+ ],
32420
+ children: /* @__PURE__ */ jsx18(
32421
+ Icon,
32422
+ {
32423
+ size: MOBILE_CHROME_METRICS.iconSize,
32424
+ color: iconColor(slot.active)
32425
+ }
32426
+ )
32254
32427
  }
32255
32428
  )
32256
- }
32257
- )
32258
- },
32259
- slot.key
32260
- );
32261
- })
32262
- }
32263
- )
32264
- ] }) });
32429
+ },
32430
+ slot.key
32431
+ );
32432
+ })
32433
+ }
32434
+ )
32435
+ ] })
32436
+ }
32437
+ );
32265
32438
  };
32266
32439
  var styles14 = StyleSheet14.create({
32267
32440
  frame: {
@@ -32351,7 +32524,7 @@ import {
32351
32524
  StyleSheet as StyleSheet15,
32352
32525
  useWindowDimensions as useWindowDimensions8
32353
32526
  } from "react-native";
32354
- import { useViewerStore as useViewerStore13 } from "@papyrus-sdk/core";
32527
+ import { useViewerStore as useViewerStore14 } from "@papyrus-sdk/core";
32355
32528
 
32356
32529
  // components/rotationReset.ts
32357
32530
  var resetEngineRotation = (engine, onRotationChange) => {
@@ -32411,7 +32584,7 @@ var SettingsSheet = ({
32411
32584
  comicLayoutMode,
32412
32585
  comicFitMode,
32413
32586
  comicReadingDirection
32414
- } = useViewerStore13();
32587
+ } = useViewerStore14();
32415
32588
  const isDark = uiTheme === "dark";
32416
32589
  const isPaged = viewMode === "single";
32417
32590
  const isDouble = viewMode === "double";
@@ -32994,7 +33167,7 @@ var styles15 = StyleSheet15.create({
32994
33167
  var SettingsSheet_default = SettingsSheet;
32995
33168
 
32996
33169
  // components/CoverPreview.tsx
32997
- import { useEffect as useEffect13, useMemo as useMemo8, useRef as useRef9, useState as useState12 } from "react";
33170
+ import { useEffect as useEffect14, useMemo as useMemo8, useRef as useRef9, useState as useState13 } from "react";
32998
33171
  import {
32999
33172
  ActivityIndicator,
33000
33173
  StyleSheet as StyleSheet16,
@@ -33052,18 +33225,18 @@ var CoverPreview = ({
33052
33225
  onLoadEnd,
33053
33226
  onError
33054
33227
  }) => {
33055
- const [engine, setEngine] = useState12(null);
33056
- const [layoutReady, setLayoutReady] = useState12(false);
33057
- const [loaded, setLoaded] = useState12(false);
33058
- const [loading, setLoading] = useState12(false);
33059
- const [error, setError] = useState12(null);
33228
+ const [engine, setEngine] = useState13(null);
33229
+ const [layoutReady, setLayoutReady] = useState13(false);
33230
+ const [loaded, setLoaded] = useState13(false);
33231
+ const [loading, setLoading] = useState13(false);
33232
+ const [error, setError] = useState13(null);
33060
33233
  const viewRef = useRef9(null);
33061
33234
  const resolvedType = useMemo8(() => inferDocumentType(source, type), [source, type]);
33062
33235
  const isPdf = resolvedType === "pdf";
33063
33236
  const hasNativePageView = Boolean(UIManager2.getViewManagerConfig?.("PapyrusPageView"));
33064
33237
  const canRender = !isPdf || hasNativePageView;
33065
33238
  const shouldRender = Boolean(visible);
33066
- useEffect13(() => {
33239
+ useEffect14(() => {
33067
33240
  if (!shouldRender) {
33068
33241
  if (!keepAlive) {
33069
33242
  setEngine(null);
@@ -33076,7 +33249,7 @@ var CoverPreview = ({
33076
33249
  setEngine(new MobileDocumentEngine());
33077
33250
  }
33078
33251
  }, [shouldRender, keepAlive, engine, canRender]);
33079
- useEffect13(() => {
33252
+ useEffect14(() => {
33080
33253
  if (!engine || !shouldRender || !canRender) return;
33081
33254
  let active = true;
33082
33255
  setLoading(true);
@@ -33103,13 +33276,13 @@ var CoverPreview = ({
33103
33276
  active = false;
33104
33277
  };
33105
33278
  }, [engine, shouldRender, canRender, source, type, pageIndex, isPdf, onLoadStart, onLoadEnd, onError]);
33106
- useEffect13(() => {
33279
+ useEffect14(() => {
33107
33280
  if (!engine || !isPdf || !loaded || !layoutReady || !shouldRender || !canRender) return;
33108
33281
  const viewTag = findNodeHandle3(viewRef.current);
33109
33282
  if (!viewTag) return;
33110
33283
  engine.renderPage(pageIndex, viewTag, renderScale);
33111
33284
  }, [engine, isPdf, loaded, layoutReady, shouldRender, canRender, pageIndex, renderScale]);
33112
- useEffect13(() => {
33285
+ useEffect14(() => {
33113
33286
  return () => {
33114
33287
  engine?.destroy();
33115
33288
  };
@@ -33176,19 +33349,19 @@ var styles16 = StyleSheet16.create({
33176
33349
  var CoverPreview_default = CoverPreview;
33177
33350
 
33178
33351
  // components/ReadingShell.tsx
33179
- import React19, { useState as useState15 } from "react";
33352
+ import React19, { useState as useState16 } from "react";
33180
33353
  import { Keyboard as Keyboard2, View as View22, StyleSheet as StyleSheet23 } from "react-native";
33181
- import { useViewerStore as useViewerStore20 } from "@papyrus-sdk/core";
33354
+ import { useViewerStore as useViewerStore21 } from "@papyrus-sdk/core";
33182
33355
 
33183
33356
  // components/DocumentActionsSheet.tsx
33184
33357
  import { StyleSheet as StyleSheet17, Text as Text10, View as View17 } from "react-native";
33185
- import { useViewerStore as useViewerStore14 } from "@papyrus-sdk/core";
33358
+ import { useViewerStore as useViewerStore15 } from "@papyrus-sdk/core";
33186
33359
  import { jsx as jsx21, jsxs as jsxs16 } from "react/jsx-runtime";
33187
33360
  function DocumentActionsSheet({
33188
33361
  visible,
33189
33362
  onClose
33190
33363
  }) {
33191
- const { uiTheme } = useViewerStore14();
33364
+ const { uiTheme } = useViewerStore15();
33192
33365
  const isDark = uiTheme === "dark";
33193
33366
  const palette = getReaderSheetPalette(isDark);
33194
33367
  return /* @__PURE__ */ jsx21(
@@ -33257,7 +33430,7 @@ var styles17 = StyleSheet17.create({
33257
33430
 
33258
33431
  // components/InfoSheet.tsx
33259
33432
  import { StyleSheet as StyleSheet18, Text as Text11, View as View18 } from "react-native";
33260
- import { useViewerStore as useViewerStore15 } from "@papyrus-sdk/core";
33433
+ import { useViewerStore as useViewerStore16 } from "@papyrus-sdk/core";
33261
33434
 
33262
33435
  // components/infoSheetModel.ts
33263
33436
  var roundPercent = (value) => Math.max(0, Math.min(100, Math.round(value)));
@@ -33372,7 +33545,7 @@ function InfoSheet({
33372
33545
  viewMode,
33373
33546
  pageTheme,
33374
33547
  locale
33375
- } = useViewerStore15();
33548
+ } = useViewerStore16();
33376
33549
  const isDark = uiTheme === "dark";
33377
33550
  const palette = getReaderSheetPalette(isDark);
33378
33551
  const isPortuguese = locale === "pt-BR";
@@ -33482,7 +33655,7 @@ var styles18 = StyleSheet18.create({
33482
33655
 
33483
33656
  // components/OverflowSheet.tsx
33484
33657
  import { Pressable as Pressable12, StyleSheet as StyleSheet19, Text as Text12, View as View19 } from "react-native";
33485
- import { useViewerStore as useViewerStore16 } from "@papyrus-sdk/core";
33658
+ import { useViewerStore as useViewerStore17 } from "@papyrus-sdk/core";
33486
33659
  import { jsx as jsx23 } from "react/jsx-runtime";
33487
33660
  var actionLabels = [{ key: "actions", label: "Document actions" }];
33488
33661
  function OverflowSheet({
@@ -33490,7 +33663,7 @@ function OverflowSheet({
33490
33663
  onClose,
33491
33664
  onOpenActions
33492
33665
  }) {
33493
- const isDark = useViewerStore16((state) => state.uiTheme === "dark");
33666
+ const isDark = useViewerStore17((state) => state.uiTheme === "dark");
33494
33667
  const palette = getReaderSheetPalette(isDark);
33495
33668
  return /* @__PURE__ */ jsx23(
33496
33669
  NativeSheet,
@@ -33540,9 +33713,9 @@ var styles19 = StyleSheet19.create({
33540
33713
  });
33541
33714
 
33542
33715
  // components/ProgressPill.tsx
33543
- import { useEffect as useEffect14, useMemo as useMemo9, useRef as useRef10, useState as useState13 } from "react";
33716
+ import { useEffect as useEffect15, useMemo as useMemo9, useRef as useRef10, useState as useState14 } from "react";
33544
33717
  import {
33545
- Animated as Animated3,
33718
+ Animated as Animated5,
33546
33719
  PanResponder as PanResponder2,
33547
33720
  Pressable as Pressable13,
33548
33721
  StyleSheet as StyleSheet20,
@@ -33550,7 +33723,7 @@ import {
33550
33723
  View as View20,
33551
33724
  useWindowDimensions as useWindowDimensions9
33552
33725
  } from "react-native";
33553
- import { useViewerStore as useViewerStore17 } from "@papyrus-sdk/core";
33726
+ import { useViewerStore as useViewerStore18 } from "@papyrus-sdk/core";
33554
33727
 
33555
33728
  // components/progressPillMode.ts
33556
33729
  function resolveProgressPillMode(viewMode, currentPage, pageCount) {
@@ -33586,7 +33759,7 @@ function ProgressPill({
33586
33759
  accentColor,
33587
33760
  mobileChromeVisible,
33588
33761
  mobileProgressPillVisible
33589
- } = useViewerStore17();
33762
+ } = useViewerStore18();
33590
33763
  const t = getStrings(locale);
33591
33764
  const isDark = uiTheme === "dark";
33592
33765
  const offsets = resolveMobileChromeOffsets(usePapyrusSafeAreaInsets());
@@ -33608,7 +33781,7 @@ function ProgressPill({
33608
33781
  const longPressTriggeredRef = useRef10(false);
33609
33782
  const longPressTimerRef = useRef10(null);
33610
33783
  const pendingReleasedScrubPageRef = useRef10(null);
33611
- const [scrubPreviewPage, setScrubPreviewPage] = useState13(null);
33784
+ const [scrubPreviewPage, setScrubPreviewPage] = useState14(null);
33612
33785
  const onNavigateToPageRef = useRef10(onNavigateToPage);
33613
33786
  const onPressRef = useRef10(onPress);
33614
33787
  const onOpenPageJumpRef = useRef10(onOpenPageJump);
@@ -33641,34 +33814,34 @@ function ProgressPill({
33641
33814
  thumbHeight,
33642
33815
  pageCount
33643
33816
  });
33644
- const thumbTopRef = useRef10(new Animated3.Value(thumbTop));
33817
+ const thumbTopRef = useRef10(new Animated5.Value(thumbTop));
33645
33818
  const thumbTopSnapshotRef = useRef10(thumbTop);
33646
33819
  thumbTopSnapshotRef.current = thumbTop;
33647
33820
  const scrubStartThumbTopRef = useRef10(0);
33648
- const trackReveal = useRef10(new Animated3.Value(0)).current;
33649
- const [trackOriginY, setTrackOriginY] = useState13(0);
33821
+ const trackReveal = useRef10(new Animated5.Value(0)).current;
33822
+ const [trackOriginY, setTrackOriginY] = useState14(0);
33650
33823
  const scrubberMetricsRef = useRef10({ trackHeight, thumbHeight, pageCount });
33651
33824
  scrubberMetricsRef.current = { trackHeight, thumbHeight, pageCount };
33652
- useEffect14(() => {
33825
+ useEffect15(() => {
33653
33826
  onNavigateToPageRef.current = onNavigateToPage;
33654
33827
  }, [onNavigateToPage]);
33655
- useEffect14(() => {
33828
+ useEffect15(() => {
33656
33829
  onPressRef.current = onPress;
33657
33830
  onOpenPageJumpRef.current = onOpenPageJump;
33658
33831
  }, [onOpenPageJump, onPress]);
33659
- useEffect14(() => {
33832
+ useEffect15(() => {
33660
33833
  const pendingPage = pendingReleasedScrubPageRef.current;
33661
33834
  if (pendingPage !== null && currentPage === pendingPage) {
33662
33835
  pendingReleasedScrubPageRef.current = null;
33663
33836
  setScrubPreviewPage(null);
33664
33837
  }
33665
33838
  }, [currentPage]);
33666
- useEffect14(() => {
33839
+ useEffect15(() => {
33667
33840
  if (!isScrubbingRef.current) {
33668
33841
  thumbTopRef.current.setValue(thumbTop);
33669
33842
  }
33670
33843
  }, [thumbTop, thumbTopRef]);
33671
- useEffect14(
33844
+ useEffect15(
33672
33845
  () => () => {
33673
33846
  if (longPressTimerRef.current !== null) {
33674
33847
  clearTimeout(longPressTimerRef.current);
@@ -33803,7 +33976,7 @@ function ProgressPill({
33803
33976
  })
33804
33977
  );
33805
33978
  trackReveal.setValue(0);
33806
- Animated3.timing(trackReveal, {
33979
+ Animated5.timing(trackReveal, {
33807
33980
  toValue: 1,
33808
33981
  duration: 180,
33809
33982
  useNativeDriver: false
@@ -33849,7 +34022,7 @@ function ProgressPill({
33849
34022
  }
33850
34023
  isScrubbingRef.current = false;
33851
34024
  onScrubbingChangeRef.current?.(false);
33852
- Animated3.timing(trackReveal, {
34025
+ Animated5.timing(trackReveal, {
33853
34026
  toValue: 0,
33854
34027
  duration: 140,
33855
34028
  useNativeDriver: false
@@ -33881,7 +34054,7 @@ function ProgressPill({
33881
34054
  }
33882
34055
  isScrubbingRef.current = false;
33883
34056
  onScrubbingChangeRef.current?.(false);
33884
- Animated3.timing(trackReveal, {
34057
+ Animated5.timing(trackReveal, {
33885
34058
  toValue: 0,
33886
34059
  duration: 140,
33887
34060
  useNativeDriver: false
@@ -33921,7 +34094,7 @@ function ProgressPill({
33921
34094
  },
33922
34095
  children: [
33923
34096
  /* @__PURE__ */ jsx24(
33924
- Animated3.View,
34097
+ Animated5.View,
33925
34098
  {
33926
34099
  pointerEvents: "none",
33927
34100
  style: [
@@ -33937,7 +34110,7 @@ function ProgressPill({
33937
34110
  }
33938
34111
  ),
33939
34112
  /* @__PURE__ */ jsx24(
33940
- Animated3.View,
34113
+ Animated5.View,
33941
34114
  {
33942
34115
  pointerEvents: "box-none",
33943
34116
  style: [styles20.thumb, { top: thumbTopRef.current }],
@@ -34078,7 +34251,7 @@ var styles20 = StyleSheet20.create({
34078
34251
  });
34079
34252
 
34080
34253
  // components/SearchOverlay.tsx
34081
- import React18, { useEffect as useEffect15, useMemo as useMemo10, useState as useState14 } from "react";
34254
+ import React18, { useEffect as useEffect16, useMemo as useMemo10, useState as useState15 } from "react";
34082
34255
  import {
34083
34256
  Keyboard,
34084
34257
  Pressable as Pressable14,
@@ -34088,7 +34261,7 @@ import {
34088
34261
  View as View21,
34089
34262
  useWindowDimensions as useWindowDimensions10
34090
34263
  } from "react-native";
34091
- import { SearchService, useViewerStore as useViewerStore18 } from "@papyrus-sdk/core";
34264
+ import { SearchService, useViewerStore as useViewerStore19 } from "@papyrus-sdk/core";
34092
34265
 
34093
34266
  // components/searchOverlayLayout.ts
34094
34267
  var getSearchOverlayLayout = (windowWidth) => {
@@ -34129,9 +34302,9 @@ function SearchOverlay({
34129
34302
  setSearch,
34130
34303
  uiTheme,
34131
34304
  accentColor
34132
- } = useViewerStore18();
34133
- const [draft, setDraft] = useState14(searchQuery);
34134
- const [isSearching, setIsSearching] = useState14(false);
34305
+ } = useViewerStore19();
34306
+ const [draft, setDraft] = useState15(searchQuery);
34307
+ const [isSearching, setIsSearching] = useState15(false);
34135
34308
  const searchRequestIdRef = React18.useRef(0);
34136
34309
  const isDark = uiTheme === "dark";
34137
34310
  const { width: windowWidth } = useWindowDimensions10();
@@ -34140,12 +34313,12 @@ function SearchOverlay({
34140
34313
  const t = getStrings(locale);
34141
34314
  const searchService = useMemo10(() => new SearchService(engine), [engine]);
34142
34315
  const results = documentType === "text" ? textSearchResults : searchResults;
34143
- useEffect15(() => {
34316
+ useEffect16(() => {
34144
34317
  searchService.clearCache();
34145
34318
  }, [isLoaded, pageCount, searchService]);
34146
34319
  const currentCount = results.length > 0 && activeSearchIndex >= 0 ? activeSearchIndex + 1 : 0;
34147
34320
  const targetLabel = documentType === "pdf" ? t.page : documentType === "epub" ? t.contents : t.progress;
34148
- useEffect15(() => {
34321
+ useEffect16(() => {
34149
34322
  if (!visible) return;
34150
34323
  setDraft(searchQuery);
34151
34324
  }, [searchQuery, visible]);
@@ -34434,7 +34607,7 @@ var styles21 = StyleSheet21.create({
34434
34607
 
34435
34608
  // components/SearchResultsSheet.tsx
34436
34609
  import { Pressable as Pressable15, StyleSheet as StyleSheet22, Text as Text15 } from "react-native";
34437
- import { useViewerStore as useViewerStore19 } from "@papyrus-sdk/core";
34610
+ import { useViewerStore as useViewerStore20 } from "@papyrus-sdk/core";
34438
34611
  import { jsx as jsx26, jsxs as jsxs20 } from "react/jsx-runtime";
34439
34612
  function SearchResultsSheet({
34440
34613
  documentType,
@@ -34453,7 +34626,7 @@ function SearchResultsSheet({
34453
34626
  triggerScrollToTextOffset,
34454
34627
  uiTheme,
34455
34628
  accentColor
34456
- } = useViewerStore19();
34629
+ } = useViewerStore20();
34457
34630
  const results = documentType === "text" ? textSearchResults : searchResults;
34458
34631
  const isDark = uiTheme === "dark";
34459
34632
  const palette = getReaderSheetPalette(isDark);
@@ -34567,14 +34740,14 @@ function ReadingShell({
34567
34740
  pageCount,
34568
34741
  uiTheme,
34569
34742
  accentColor
34570
- } = useViewerStore20();
34571
- const [overflowOpen, setOverflowOpen] = useState15(false);
34572
- const [infoOpen, setInfoOpen] = useState15(false);
34573
- const [actionsOpen, setActionsOpen] = useState15(false);
34574
- const [settingsOpen, setSettingsOpen] = useState15(false);
34575
- const [searchResultsOpen, setSearchResultsOpen] = useState15(false);
34576
- const [pageJumpOpen, setPageJumpOpen] = useState15(false);
34577
- const [pageScrubActive, setPageScrubActive] = useState15(false);
34743
+ } = useViewerStore21();
34744
+ const [overflowOpen, setOverflowOpen] = useState16(false);
34745
+ const [infoOpen, setInfoOpen] = useState16(false);
34746
+ const [actionsOpen, setActionsOpen] = useState16(false);
34747
+ const [settingsOpen, setSettingsOpen] = useState16(false);
34748
+ const [searchResultsOpen, setSearchResultsOpen] = useState16(false);
34749
+ const [pageJumpOpen, setPageJumpOpen] = useState16(false);
34750
+ const [pageScrubActive, setPageScrubActive] = useState16(false);
34578
34751
  const isDark = uiTheme === "dark";
34579
34752
  React19.useEffect(() => {
34580
34753
  const showSubscription = Keyboard2.addListener("keyboardDidShow", () => {