@papyrus-sdk/ui-react-native 0.2.35-beta.6 → 0.2.35-beta.8

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,27 @@ 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
+ "worklet";
29604
+ return {
29605
+ opacity: 1 - progress.value,
29606
+ transform: [{ scale: 1 - progress.value * 0.04 }, { translateX: -progress.value * 6 }]
29607
+ };
29608
+ });
29609
+ const doneMotion = useAnimatedStyle(() => {
29610
+ "worklet";
29611
+ return {
29612
+ opacity: progress.value,
29613
+ transform: [{ scale: 0.96 + progress.value * 0.04 }, { translateX: (1 - progress.value) * 6 }]
29614
+ };
29615
+ });
29616
+ const [jumpModalOpen, setJumpModalOpen] = useState9(false);
29535
29617
  const isDark = uiTheme === "dark";
29536
29618
  const navIconColor = isDark ? "#e5e7eb" : "#111827";
29537
29619
  const { width, height } = useWindowDimensions4();
@@ -29555,7 +29637,22 @@ var Topbar = ({
29555
29637
  };
29556
29638
  const defaultLogo = /* @__PURE__ */ jsx14(View10, { style: [styles10.logoBadge, { backgroundColor: accentColor }], children: /* @__PURE__ */ jsx14(Text4, { style: styles10.logoText, children: "P" }) });
29557
29639
  const logoElement = logo ?? defaultLogo;
29558
- if (!mobileChromeVisible) return null;
29640
+ const settingsControl = /* @__PURE__ */ jsx14(
29641
+ Pressable6,
29642
+ {
29643
+ onPress: () => onOpenOverflow?.() ?? onOpenSettings?.(),
29644
+ style: [
29645
+ styles10.iconButton,
29646
+ isDark && styles10.iconButtonDark,
29647
+ inkSession.supported && styles10.annotationSettingsButton
29648
+ ],
29649
+ accessibilityRole: "button",
29650
+ accessibilityLabel: "Open overflow menu",
29651
+ disabled: inkSession.active,
29652
+ children: /* @__PURE__ */ jsx14(IconSettings, { size: MOBILE_CHROME_METRICS.iconSize, color: isDark ? "#e5e7eb" : "#111827" })
29653
+ }
29654
+ );
29655
+ if (!mobileChromeVisible && !inkSession.active) return null;
29559
29656
  return /* @__PURE__ */ jsxs9(Fragment3, { children: [
29560
29657
  /* @__PURE__ */ jsx14(
29561
29658
  View10,
@@ -29583,7 +29680,10 @@ var Topbar = ({
29583
29680
  onLogoPress ? /* @__PURE__ */ jsx14(
29584
29681
  Pressable6,
29585
29682
  {
29586
- onPress: onLogoPress,
29683
+ onPress: () => {
29684
+ if (inkSession.active) inkSession.finish();
29685
+ else onLogoPress();
29686
+ },
29587
29687
  accessibilityRole: "button",
29588
29688
  accessibilityLabel: logoAccessibilityLabel,
29589
29689
  style: styles10.logoSlot,
@@ -29660,21 +29760,49 @@ var Topbar = ({
29660
29760
  }
29661
29761
  )
29662
29762
  ] }) }) : null,
29663
- /* @__PURE__ */ jsx14(View10, { style: styles10.rightGroup, children: /* @__PURE__ */ jsx14(
29664
- Pressable6,
29763
+ /* @__PURE__ */ jsx14(
29764
+ View10,
29665
29765
  {
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
- )
29766
+ style: [styles10.rightGroup, inkSession.supported && styles10.annotationActionSlot],
29767
+ testID: "papyrus-topbar-action-slot",
29768
+ children: inkSession.supported ? /* @__PURE__ */ jsxs9(Fragment3, { children: [
29769
+ /* @__PURE__ */ jsx14(
29770
+ Animated3.View,
29771
+ {
29772
+ style: [styles10.settingsSlot, settingsMotion],
29773
+ pointerEvents: inkSession.active ? "none" : "auto",
29774
+ accessibilityElementsHidden: inkSession.active,
29775
+ importantForAccessibility: inkSession.active ? "no-hide-descendants" : "auto",
29776
+ children: settingsControl
29777
+ }
29778
+ ),
29779
+ /* @__PURE__ */ jsx14(
29780
+ Animated3.View,
29781
+ {
29782
+ style: [styles10.doneSlot, doneMotion],
29783
+ pointerEvents: inkSession.active ? "auto" : "none",
29784
+ accessibilityElementsHidden: !inkSession.active,
29785
+ importantForAccessibility: inkSession.active ? "auto" : "no-hide-descendants",
29786
+ children: /* @__PURE__ */ jsx14(
29787
+ Pressable6,
29788
+ {
29789
+ onPress: inkSession.finish,
29790
+ disabled: !inkSession.active,
29791
+ style: styles10.doneButton,
29792
+ accessibilityRole: "button",
29793
+ accessibilityLabel: t.done,
29794
+ testID: "papyrus-topbar-ink-done",
29795
+ children: /* @__PURE__ */ jsxs9(Text4, { style: styles10.doneButtonText, children: [
29796
+ "\u2713 ",
29797
+ t.done
29798
+ ] })
29799
+ }
29800
+ )
29801
+ }
29802
+ )
29803
+ ] }) : settingsControl
29676
29804
  }
29677
- ) })
29805
+ )
29678
29806
  ]
29679
29807
  }
29680
29808
  )
@@ -29820,6 +29948,42 @@ var styles10 = StyleSheet10.create({
29820
29948
  flexShrink: 0,
29821
29949
  marginLeft: 12
29822
29950
  },
29951
+ annotationActionSlot: {
29952
+ width: 108,
29953
+ height: 44
29954
+ },
29955
+ settingsSlot: {
29956
+ position: "absolute",
29957
+ right: 0,
29958
+ top: 0
29959
+ },
29960
+ annotationSettingsButton: {
29961
+ minWidth: 44,
29962
+ minHeight: 44,
29963
+ marginLeft: 0,
29964
+ justifyContent: "center",
29965
+ alignItems: "center"
29966
+ },
29967
+ doneSlot: {
29968
+ position: "absolute",
29969
+ left: 0,
29970
+ right: 0,
29971
+ top: 0
29972
+ },
29973
+ doneButton: {
29974
+ minWidth: 44,
29975
+ minHeight: 44,
29976
+ paddingHorizontal: 10,
29977
+ borderRadius: 12,
29978
+ backgroundColor: "#2563eb",
29979
+ alignItems: "center",
29980
+ justifyContent: "center"
29981
+ },
29982
+ doneButtonText: {
29983
+ color: "#fff",
29984
+ fontSize: 14,
29985
+ fontWeight: "700"
29986
+ },
29823
29987
  iconButton: {
29824
29988
  paddingHorizontal: 10,
29825
29989
  paddingVertical: 6,
@@ -29855,7 +30019,7 @@ var styles10 = StyleSheet10.create({
29855
30019
  var Topbar_default = Topbar;
29856
30020
 
29857
30021
  // components/ToolDock.tsx
29858
- import React13, { useEffect as useEffect10, useMemo as useMemo6, useRef as useRef7, useState as useState9 } from "react";
30022
+ import React13, { useEffect as useEffect11, useMemo as useMemo6, useRef as useRef7, useState as useState10 } from "react";
29859
30023
  import {
29860
30024
  View as View11,
29861
30025
  Text as Text5,
@@ -29864,7 +30028,7 @@ import {
29864
30028
  ScrollView as ScrollView3,
29865
30029
  useWindowDimensions as useWindowDimensions5
29866
30030
  } from "react-native";
29867
- import { useViewerStore as useViewerStore9 } from "@papyrus-sdk/core";
30031
+ import { useViewerStore as useViewerStore10 } from "@papyrus-sdk/core";
29868
30032
 
29869
30033
  // components/ToolDock.layout.ts
29870
30034
  var TOOL_DOCK_SCROLL_THRESHOLD = 420;
@@ -29969,18 +30133,18 @@ var OpacitySlider = React13.memo(function OpacitySlider2({
29969
30133
  isDark,
29970
30134
  onCommit
29971
30135
  }) {
29972
- const [trackWidth, setTrackWidth] = useState9(0);
29973
- const [draftValue, setDraftValue] = useState9(value);
30136
+ const [trackWidth, setTrackWidth] = useState10(0);
30137
+ const [draftValue, setDraftValue] = useState10(value);
29974
30138
  const dragValueRef = useRef7(draftValue);
29975
30139
  const isDraggingRef = useRef7(false);
29976
30140
  const frameRef = useRef7(null);
29977
- useEffect10(() => {
30141
+ useEffect11(() => {
29978
30142
  if (!isDraggingRef.current) {
29979
30143
  dragValueRef.current = value;
29980
30144
  setDraftValue(value);
29981
30145
  }
29982
30146
  }, [value]);
29983
- useEffect10(() => {
30147
+ useEffect11(() => {
29984
30148
  return () => {
29985
30149
  if (frameRef.current !== null) {
29986
30150
  cancelAnimationFrame(frameRef.current);
@@ -30080,9 +30244,9 @@ var ToolDock = () => {
30080
30244
  annotationRedoStack,
30081
30245
  undoAnnotations,
30082
30246
  redoAnnotations
30083
- } = useViewerStore9();
30084
- const [paletteExpanded, setPaletteExpanded] = useState9(false);
30085
- const [extrasExpanded, setExtrasExpanded] = useState9(false);
30247
+ } = useViewerStore10();
30248
+ const [paletteExpanded, setPaletteExpanded] = useState10(false);
30249
+ const [extrasExpanded, setExtrasExpanded] = useState10(false);
30086
30250
  const isDark = uiTheme === "dark";
30087
30251
  const { width: windowWidth } = useWindowDimensions5();
30088
30252
  const t = getStrings(locale);
@@ -30109,7 +30273,7 @@ var ToolDock = () => {
30109
30273
  const canUndo = annotationUndoStack.length > 0;
30110
30274
  const canRedo = annotationRedoStack.length > 0;
30111
30275
  const primaryToolsRowIsScrollable = shouldUseScrollablePrimaryToolsRow(windowWidth);
30112
- useEffect10(() => {
30276
+ useEffect11(() => {
30113
30277
  if (!nativeInkToolPickerActive) return;
30114
30278
  setPaletteExpanded(false);
30115
30279
  setExtrasExpanded(false);
@@ -30822,15 +30986,15 @@ var ToolDock_default = ToolDock;
30822
30986
 
30823
30987
  // components/RightSheet.tsx
30824
30988
  import {
30825
- useCallback as useCallback5,
30826
- useEffect as useEffect11,
30989
+ useCallback as useCallback6,
30990
+ useEffect as useEffect12,
30827
30991
  useMemo as useMemo7,
30828
30992
  useRef as useRef8,
30829
- useState as useState10
30993
+ useState as useState11
30830
30994
  } from "react";
30831
30995
  import {
30832
30996
  Image as Image2,
30833
- Platform as Platform5,
30997
+ Platform as Platform6,
30834
30998
  Pressable as Pressable8,
30835
30999
  StyleSheet as StyleSheet12,
30836
31000
  Text as Text6,
@@ -30839,7 +31003,7 @@ import {
30839
31003
  findNodeHandle as findNodeHandle2,
30840
31004
  useWindowDimensions as useWindowDimensions6
30841
31005
  } from "react-native";
30842
- import { useViewerStore as useViewerStore10 } from "@papyrus-sdk/core";
31006
+ import { useViewerStore as useViewerStore11 } from "@papyrus-sdk/core";
30843
31007
  import { PapyrusPageView as PapyrusPageView2 } from "@papyrus-sdk/engine-native";
30844
31008
 
30845
31009
  // components/rightSheetLayout.ts
@@ -30905,13 +31069,13 @@ var PageThumbnail = ({
30905
31069
  onPress
30906
31070
  }) => {
30907
31071
  const viewRef = useRef8(null);
30908
- const [layoutReady, setLayoutReady] = useState10(false);
30909
- const [previewUri, setPreviewUri] = useState10(null);
30910
- useEffect11(() => {
31072
+ const [layoutReady, setLayoutReady] = useState11(false);
31073
+ const [previewUri, setPreviewUri] = useState11(null);
31074
+ useEffect12(() => {
30911
31075
  if (!layoutReady || !useNativePreview || !shouldRenderPreview) return;
30912
31076
  const viewTag = findNodeHandle2(viewRef.current);
30913
31077
  if (!viewTag) return;
30914
- const isNative = Platform5.OS === "android" || Platform5.OS === "ios";
31078
+ const isNative = Platform6.OS === "android" || Platform6.OS === "ios";
30915
31079
  const renderScale = isNative ? 2 / Math.max(zoom, 0.5) : 2;
30916
31080
  void engine.renderPage(pageIndex, viewTag, renderScale);
30917
31081
  }, [
@@ -30922,7 +31086,7 @@ var PageThumbnail = ({
30922
31086
  useNativePreview,
30923
31087
  zoom
30924
31088
  ]);
30925
- useEffect11(() => {
31089
+ useEffect12(() => {
30926
31090
  if (!useImagePreview || !shouldRenderPreview) {
30927
31091
  setPreviewUri(null);
30928
31092
  return;
@@ -31051,12 +31215,12 @@ var RightSheet = ({
31051
31215
  zoom,
31052
31216
  locale,
31053
31217
  accentColor
31054
- } = useViewerStore10();
31218
+ } = useViewerStore11();
31055
31219
  const { height: windowHeight, width: windowWidth } = useWindowDimensions6();
31056
- const [pagesMode, setPagesMode] = useState10(
31220
+ const [pagesMode, setPagesMode] = useState11(
31057
31221
  documentType === "pdf" || documentType === "comic" ? "thumbnails" : "summary"
31058
31222
  );
31059
- useEffect11(() => {
31223
+ useEffect12(() => {
31060
31224
  setPagesMode(
31061
31225
  documentType === "pdf" || documentType === "comic" ? "thumbnails" : "summary"
31062
31226
  );
@@ -31080,8 +31244,8 @@ var RightSheet = ({
31080
31244
  const thumbnailDimensionsCacheRef = useRef8(/* @__PURE__ */ new Map());
31081
31245
  const thumbnailDimensionsPendingRef = useRef8(/* @__PURE__ */ new Set());
31082
31246
  const thumbnailRefreshTimeoutRef = useRef8(null);
31083
- const [thumbnailLayoutRevision, setThumbnailLayoutRevision] = useState10(0);
31084
- const [visibleThumbnailPages, setVisibleThumbnailPages] = useState10(() => /* @__PURE__ */ new Set());
31247
+ const [thumbnailLayoutRevision, setThumbnailLayoutRevision] = useState11(0);
31248
+ const [visibleThumbnailPages, setVisibleThumbnailPages] = useState11(() => /* @__PURE__ */ new Set());
31085
31249
  const resolvedThumbsInitialCount = useMemo7(
31086
31250
  () => resolvePositiveInt2(
31087
31251
  thumbsInitialCount,
@@ -31101,10 +31265,10 @@ var RightSheet = ({
31101
31265
  const navigationTitle = showingProgress ? t.progress : documentType === "epub" || activeMobileDestination === "contents" ? t.contents : t.pages;
31102
31266
  const summaryLabel = documentType === "epub" ? t.contents : t.summaryTab;
31103
31267
  const thumbnailLabel = documentType === "epub" ? t.pages : t.pagesTab;
31104
- const closeSheet = useCallback5(() => {
31268
+ const closeSheet = useCallback6(() => {
31105
31269
  setDocumentState({ sidebarRightOpen: false });
31106
31270
  }, [setDocumentState]);
31107
- const jumpToPage = useCallback5(
31271
+ const jumpToPage = useCallback6(
31108
31272
  (pageIndex) => {
31109
31273
  engine.goToPage(pageIndex + 1);
31110
31274
  setDocumentState({ currentPage: pageIndex + 1 });
@@ -31113,14 +31277,14 @@ var RightSheet = ({
31113
31277
  },
31114
31278
  [closeSheet, engine, setDocumentState, triggerScrollToPage]
31115
31279
  );
31116
- const scheduleThumbnailLayoutRefresh = useCallback5(() => {
31280
+ const scheduleThumbnailLayoutRefresh = useCallback6(() => {
31117
31281
  if (thumbnailRefreshTimeoutRef.current) return;
31118
31282
  thumbnailRefreshTimeoutRef.current = setTimeout(() => {
31119
31283
  thumbnailRefreshTimeoutRef.current = null;
31120
31284
  setThumbnailLayoutRevision((value) => value + 1);
31121
31285
  }, 80);
31122
31286
  }, []);
31123
- const ensureThumbnailDimensions = useCallback5(
31287
+ const ensureThumbnailDimensions = useCallback6(
31124
31288
  (pageIndex) => {
31125
31289
  if (pageIndex < 0 || pageIndex >= pageCount) return;
31126
31290
  if (thumbnailDimensionsCacheRef.current.has(pageIndex)) return;
@@ -31139,7 +31303,7 @@ var RightSheet = ({
31139
31303
  },
31140
31304
  [engine, pageCount, scheduleThumbnailLayoutRefresh]
31141
31305
  );
31142
- const getThumbnailFrameHeight = useCallback5(
31306
+ const getThumbnailFrameHeight = useCallback6(
31143
31307
  (pageIndex) => {
31144
31308
  const dims = thumbnailDimensionsCacheRef.current.get(pageIndex);
31145
31309
  const ratio = !dims || dims.width <= 0 || dims.height <= 0 ? THUMBNAILS_DEFAULT_ASPECT_RATIO : dims.height / dims.width;
@@ -31151,7 +31315,7 @@ var RightSheet = ({
31151
31315
  },
31152
31316
  [frameWidth, thumbnailLayoutRevision]
31153
31317
  );
31154
- useEffect11(
31318
+ useEffect12(
31155
31319
  () => () => {
31156
31320
  if (thumbnailRefreshTimeoutRef.current) {
31157
31321
  clearTimeout(thumbnailRefreshTimeoutRef.current);
@@ -31159,11 +31323,11 @@ var RightSheet = ({
31159
31323
  },
31160
31324
  []
31161
31325
  );
31162
- useEffect11(() => {
31326
+ useEffect12(() => {
31163
31327
  if (sidebarRightOpen) return;
31164
31328
  setVisibleThumbnailPages(/* @__PURE__ */ new Set());
31165
31329
  }, [sidebarRightOpen]);
31166
- useEffect11(() => {
31330
+ useEffect12(() => {
31167
31331
  if (!sidebarRightOpen || sidebarRightTab !== "pages") return;
31168
31332
  if (activeMobileDestination === "pages") {
31169
31333
  setPagesMode("thumbnails");
@@ -31171,7 +31335,7 @@ var RightSheet = ({
31171
31335
  }
31172
31336
  setPagesMode("summary");
31173
31337
  }, [activeMobileDestination, sidebarRightOpen, sidebarRightTab]);
31174
- useEffect11(() => {
31338
+ useEffect12(() => {
31175
31339
  if (!sidebarRightOpen || sidebarRightTab !== "pages") return;
31176
31340
  if (pagesMode !== "thumbnails" || !supportsThumbnails) return;
31177
31341
  if (pageCount <= 0) return;
@@ -31212,7 +31376,7 @@ var RightSheet = ({
31212
31376
  })),
31213
31377
  [pageCount, pages]
31214
31378
  );
31215
- const onThumbnailsViewableItemsChanged = useCallback5(
31379
+ const onThumbnailsViewableItemsChanged = useCallback6(
31216
31380
  ({ viewableItems }) => {
31217
31381
  const nextVisible = /* @__PURE__ */ new Set();
31218
31382
  viewableItems.forEach((token) => {
@@ -31229,7 +31393,7 @@ var RightSheet = ({
31229
31393
  },
31230
31394
  [ensureThumbnailDimensions]
31231
31395
  );
31232
- const renderThumbnailItem = useCallback5(
31396
+ const renderThumbnailItem = useCallback6(
31233
31397
  ({ item }) => {
31234
31398
  const shouldRenderPreview = (useNativePreview || useImagePreview) && (visibleThumbnailPages.has(item) || item < resolvedThumbsPrewarmCount || Math.abs(item + 1 - currentPage) <= 1);
31235
31399
  return /* @__PURE__ */ jsx16(
@@ -31835,7 +31999,7 @@ var styles12 = StyleSheet12.create({
31835
31999
  var RightSheet_default = RightSheet;
31836
32000
 
31837
32001
  // components/AnnotationEditor.tsx
31838
- import { useEffect as useEffect12, useState as useState11 } from "react";
32002
+ import { useEffect as useEffect13, useState as useState12 } from "react";
31839
32003
  import {
31840
32004
  Modal as Modal2,
31841
32005
  View as View13,
@@ -31844,7 +32008,7 @@ import {
31844
32008
  Pressable as Pressable9,
31845
32009
  StyleSheet as StyleSheet13
31846
32010
  } from "react-native";
31847
- import { useViewerStore as useViewerStore11 } from "@papyrus-sdk/core";
32011
+ import { useViewerStore as useViewerStore12 } from "@papyrus-sdk/core";
31848
32012
  import { jsx as jsx17, jsxs as jsxs12 } from "react/jsx-runtime";
31849
32013
  var AnnotationEditor = () => {
31850
32014
  const {
@@ -31856,13 +32020,13 @@ var AnnotationEditor = () => {
31856
32020
  uiTheme,
31857
32021
  locale,
31858
32022
  accentColor
31859
- } = useViewerStore11();
32023
+ } = useViewerStore12();
31860
32024
  const annotation = annotations.find((ann) => ann.id === selectedAnnotationId);
31861
32025
  const isEditable = annotation && (annotation.type === "text" || annotation.type === "comment");
31862
- const [draft, setDraft] = useState11("");
32026
+ const [draft, setDraft] = useState12("");
31863
32027
  const isDark = uiTheme === "dark";
31864
32028
  const t = getStrings(locale);
31865
- useEffect12(() => {
32029
+ useEffect13(() => {
31866
32030
  if (isEditable) {
31867
32031
  setDraft(annotation?.content ?? "");
31868
32032
  }
@@ -32019,8 +32183,9 @@ var styles13 = StyleSheet13.create({
32019
32183
  var AnnotationEditor_default = AnnotationEditor;
32020
32184
 
32021
32185
  // 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";
32186
+ import { View as View14, Pressable as Pressable10, StyleSheet as StyleSheet14, useWindowDimensions as useWindowDimensions7 } from "react-native";
32187
+ import { useViewerStore as useViewerStore13 } from "@papyrus-sdk/core";
32188
+ import Animated4, { useAnimatedStyle as useAnimatedStyle2 } from "react-native-reanimated";
32024
32189
 
32025
32190
  // components/bottomBarModel.ts
32026
32191
  function buildBottomBarLayout({
@@ -32089,9 +32254,20 @@ var BottomBar = ({
32089
32254
  mobileChromeVisible,
32090
32255
  toolDockOpen,
32091
32256
  activeTool,
32092
- interactionMode,
32093
- nativePdfViewerActive
32094
- } = useViewerStore12();
32257
+ interactionMode
32258
+ } = useViewerStore13();
32259
+ const inkSession = useNativeInkSession();
32260
+ const supportsInkChrome = documentType === "pdf" && inkSession.supported;
32261
+ const drawing = supportsInkChrome && inkSession.active;
32262
+ const dockVisible = mobileChromeVisible && mobileDockVisible && !drawing;
32263
+ const dockProgress = useNativeInkMotion(dockVisible, supportsInkChrome);
32264
+ const dockMotion = useAnimatedStyle2(() => {
32265
+ "worklet";
32266
+ return {
32267
+ opacity: dockProgress.value,
32268
+ transform: [{ translateY: (1 - dockProgress.value) * 8 }]
32269
+ };
32270
+ });
32095
32271
  const isDark = uiTheme === "dark";
32096
32272
  const t = getStrings(locale);
32097
32273
  const { width, height } = useWindowDimensions7();
@@ -32111,7 +32287,7 @@ var BottomBar = ({
32111
32287
  label: t.tools,
32112
32288
  icon: IconToolDockTrigger,
32113
32289
  onPress: () => {
32114
- const isNativeIosInkViewer = Platform6.OS === "ios" && Number.parseInt(String(Platform6.Version), 10) >= 16 && nativePdfViewerActive;
32290
+ const isNativeIosInkViewer = supportsInkChrome;
32115
32291
  const action = resolveAnnotateButtonAction({
32116
32292
  isNativeIosInkViewer,
32117
32293
  activeTool,
@@ -32128,13 +32304,7 @@ var BottomBar = ({
32128
32304
  return;
32129
32305
  }
32130
32306
  if (action === "deactivate-native-ink") {
32131
- setDocumentState({
32132
- activeTool: "select",
32133
- interactionMode: "pan",
32134
- nativeInkToolPickerActive: false,
32135
- toolDockOpen: false,
32136
- activeMobileDestination: "none"
32137
- });
32307
+ inkSession.finish();
32138
32308
  return;
32139
32309
  }
32140
32310
  if (action === "dismiss-tool-dock") {
@@ -32172,96 +32342,108 @@ var BottomBar = ({
32172
32342
  onPress: onOpenSettings
32173
32343
  }
32174
32344
  };
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,
32345
+ if (!dockVisible && !supportsInkChrome) return null;
32346
+ return /* @__PURE__ */ jsx18(
32347
+ Animated4.View,
32348
+ {
32349
+ pointerEvents: dockVisible ? "box-none" : "none",
32350
+ accessibilityElementsHidden: !dockVisible,
32351
+ importantForAccessibility: dockVisible ? "auto" : "no-hide-descendants",
32352
+ testID: "papyrus-bottom-bar-frame",
32353
+ style: [styles14.frame, { paddingBottom: offsets.bottom, paddingLeft: offsets.left, paddingRight: offsets.right }, dockMotion],
32354
+ children: /* @__PURE__ */ jsxs13(View14, { style: [styles14.row, isLandscape && styles14.rowLandscape], children: [
32355
+ layout.leftSlots.length > 0 ? /* @__PURE__ */ jsx18(
32356
+ View14,
32357
+ {
32358
+ style: [
32359
+ styles14.island,
32360
+ styles14.editIsland,
32361
+ isDark && styles14.islandDark
32362
+ ],
32363
+ testID: "papyrus-floating-bottom-dock-edit",
32364
+ children: layout.leftSlots.map((slot) => {
32365
+ const meta = slotMeta[slot.key];
32366
+ const Icon = meta.icon;
32367
+ return /* @__PURE__ */ jsx18(
32368
+ Pressable10,
32201
32369
  {
32370
+ disabled: !dockVisible,
32371
+ onPress: meta.onPress,
32202
32372
  style: [
32203
- styles14.itemIcon,
32204
- isDark && styles14.itemIconDark,
32205
- slot.active && styles14.itemIconActive
32373
+ styles14.iconOnlyItem,
32374
+ slot.active && styles14.itemActive
32206
32375
  ],
32376
+ accessibilityLabel: meta.label,
32377
+ testID: `papyrus-mobile-destination-${slot.key}`,
32207
32378
  children: /* @__PURE__ */ jsx18(
32208
- Icon,
32379
+ View14,
32209
32380
  {
32210
- size: MOBILE_CHROME_METRICS.iconSize,
32211
- color: iconColor(slot.active)
32381
+ style: [
32382
+ styles14.itemIcon,
32383
+ isDark && styles14.itemIconDark,
32384
+ slot.active && styles14.itemIconActive
32385
+ ],
32386
+ children: /* @__PURE__ */ jsx18(
32387
+ Icon,
32388
+ {
32389
+ size: MOBILE_CHROME_METRICS.iconSize,
32390
+ color: iconColor(slot.active)
32391
+ }
32392
+ )
32212
32393
  }
32213
32394
  )
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,
32395
+ },
32396
+ slot.key
32397
+ );
32398
+ })
32399
+ }
32400
+ ) : null,
32401
+ /* @__PURE__ */ jsx18(
32402
+ View14,
32403
+ {
32404
+ style: [
32405
+ styles14.island,
32406
+ styles14.utilityIsland,
32407
+ isDark && styles14.islandDark
32408
+ ],
32409
+ testID: "papyrus-floating-bottom-dock",
32410
+ children: layout.rightSlots.map((slot) => {
32411
+ const meta = slotMeta[slot.key];
32412
+ const Icon = meta.icon;
32413
+ return /* @__PURE__ */ jsx18(
32414
+ Pressable10,
32243
32415
  {
32244
- style: [
32245
- styles14.itemIcon,
32246
- isDark && styles14.itemIconDark,
32247
- slot.active && styles14.itemIconActive
32248
- ],
32416
+ disabled: !dockVisible,
32417
+ onPress: meta.onPress,
32418
+ style: [styles14.iconOnlyItem, slot.active && styles14.itemActive],
32419
+ accessibilityLabel: meta.label,
32420
+ testID: `papyrus-mobile-destination-${slot.key}`,
32249
32421
  children: /* @__PURE__ */ jsx18(
32250
- Icon,
32422
+ View14,
32251
32423
  {
32252
- size: MOBILE_CHROME_METRICS.iconSize,
32253
- color: iconColor(slot.active)
32424
+ style: [
32425
+ styles14.itemIcon,
32426
+ isDark && styles14.itemIconDark,
32427
+ slot.active && styles14.itemIconActive
32428
+ ],
32429
+ children: /* @__PURE__ */ jsx18(
32430
+ Icon,
32431
+ {
32432
+ size: MOBILE_CHROME_METRICS.iconSize,
32433
+ color: iconColor(slot.active)
32434
+ }
32435
+ )
32254
32436
  }
32255
32437
  )
32256
- }
32257
- )
32258
- },
32259
- slot.key
32260
- );
32261
- })
32262
- }
32263
- )
32264
- ] }) });
32438
+ },
32439
+ slot.key
32440
+ );
32441
+ })
32442
+ }
32443
+ )
32444
+ ] })
32445
+ }
32446
+ );
32265
32447
  };
32266
32448
  var styles14 = StyleSheet14.create({
32267
32449
  frame: {
@@ -32351,7 +32533,7 @@ import {
32351
32533
  StyleSheet as StyleSheet15,
32352
32534
  useWindowDimensions as useWindowDimensions8
32353
32535
  } from "react-native";
32354
- import { useViewerStore as useViewerStore13 } from "@papyrus-sdk/core";
32536
+ import { useViewerStore as useViewerStore14 } from "@papyrus-sdk/core";
32355
32537
 
32356
32538
  // components/rotationReset.ts
32357
32539
  var resetEngineRotation = (engine, onRotationChange) => {
@@ -32411,7 +32593,7 @@ var SettingsSheet = ({
32411
32593
  comicLayoutMode,
32412
32594
  comicFitMode,
32413
32595
  comicReadingDirection
32414
- } = useViewerStore13();
32596
+ } = useViewerStore14();
32415
32597
  const isDark = uiTheme === "dark";
32416
32598
  const isPaged = viewMode === "single";
32417
32599
  const isDouble = viewMode === "double";
@@ -32994,7 +33176,7 @@ var styles15 = StyleSheet15.create({
32994
33176
  var SettingsSheet_default = SettingsSheet;
32995
33177
 
32996
33178
  // components/CoverPreview.tsx
32997
- import { useEffect as useEffect13, useMemo as useMemo8, useRef as useRef9, useState as useState12 } from "react";
33179
+ import { useEffect as useEffect14, useMemo as useMemo8, useRef as useRef9, useState as useState13 } from "react";
32998
33180
  import {
32999
33181
  ActivityIndicator,
33000
33182
  StyleSheet as StyleSheet16,
@@ -33052,18 +33234,18 @@ var CoverPreview = ({
33052
33234
  onLoadEnd,
33053
33235
  onError
33054
33236
  }) => {
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);
33237
+ const [engine, setEngine] = useState13(null);
33238
+ const [layoutReady, setLayoutReady] = useState13(false);
33239
+ const [loaded, setLoaded] = useState13(false);
33240
+ const [loading, setLoading] = useState13(false);
33241
+ const [error, setError] = useState13(null);
33060
33242
  const viewRef = useRef9(null);
33061
33243
  const resolvedType = useMemo8(() => inferDocumentType(source, type), [source, type]);
33062
33244
  const isPdf = resolvedType === "pdf";
33063
33245
  const hasNativePageView = Boolean(UIManager2.getViewManagerConfig?.("PapyrusPageView"));
33064
33246
  const canRender = !isPdf || hasNativePageView;
33065
33247
  const shouldRender = Boolean(visible);
33066
- useEffect13(() => {
33248
+ useEffect14(() => {
33067
33249
  if (!shouldRender) {
33068
33250
  if (!keepAlive) {
33069
33251
  setEngine(null);
@@ -33076,7 +33258,7 @@ var CoverPreview = ({
33076
33258
  setEngine(new MobileDocumentEngine());
33077
33259
  }
33078
33260
  }, [shouldRender, keepAlive, engine, canRender]);
33079
- useEffect13(() => {
33261
+ useEffect14(() => {
33080
33262
  if (!engine || !shouldRender || !canRender) return;
33081
33263
  let active = true;
33082
33264
  setLoading(true);
@@ -33103,13 +33285,13 @@ var CoverPreview = ({
33103
33285
  active = false;
33104
33286
  };
33105
33287
  }, [engine, shouldRender, canRender, source, type, pageIndex, isPdf, onLoadStart, onLoadEnd, onError]);
33106
- useEffect13(() => {
33288
+ useEffect14(() => {
33107
33289
  if (!engine || !isPdf || !loaded || !layoutReady || !shouldRender || !canRender) return;
33108
33290
  const viewTag = findNodeHandle3(viewRef.current);
33109
33291
  if (!viewTag) return;
33110
33292
  engine.renderPage(pageIndex, viewTag, renderScale);
33111
33293
  }, [engine, isPdf, loaded, layoutReady, shouldRender, canRender, pageIndex, renderScale]);
33112
- useEffect13(() => {
33294
+ useEffect14(() => {
33113
33295
  return () => {
33114
33296
  engine?.destroy();
33115
33297
  };
@@ -33176,19 +33358,19 @@ var styles16 = StyleSheet16.create({
33176
33358
  var CoverPreview_default = CoverPreview;
33177
33359
 
33178
33360
  // components/ReadingShell.tsx
33179
- import React19, { useState as useState15 } from "react";
33361
+ import React19, { useState as useState16 } from "react";
33180
33362
  import { Keyboard as Keyboard2, View as View22, StyleSheet as StyleSheet23 } from "react-native";
33181
- import { useViewerStore as useViewerStore20 } from "@papyrus-sdk/core";
33363
+ import { useViewerStore as useViewerStore21 } from "@papyrus-sdk/core";
33182
33364
 
33183
33365
  // components/DocumentActionsSheet.tsx
33184
33366
  import { StyleSheet as StyleSheet17, Text as Text10, View as View17 } from "react-native";
33185
- import { useViewerStore as useViewerStore14 } from "@papyrus-sdk/core";
33367
+ import { useViewerStore as useViewerStore15 } from "@papyrus-sdk/core";
33186
33368
  import { jsx as jsx21, jsxs as jsxs16 } from "react/jsx-runtime";
33187
33369
  function DocumentActionsSheet({
33188
33370
  visible,
33189
33371
  onClose
33190
33372
  }) {
33191
- const { uiTheme } = useViewerStore14();
33373
+ const { uiTheme } = useViewerStore15();
33192
33374
  const isDark = uiTheme === "dark";
33193
33375
  const palette = getReaderSheetPalette(isDark);
33194
33376
  return /* @__PURE__ */ jsx21(
@@ -33257,7 +33439,7 @@ var styles17 = StyleSheet17.create({
33257
33439
 
33258
33440
  // components/InfoSheet.tsx
33259
33441
  import { StyleSheet as StyleSheet18, Text as Text11, View as View18 } from "react-native";
33260
- import { useViewerStore as useViewerStore15 } from "@papyrus-sdk/core";
33442
+ import { useViewerStore as useViewerStore16 } from "@papyrus-sdk/core";
33261
33443
 
33262
33444
  // components/infoSheetModel.ts
33263
33445
  var roundPercent = (value) => Math.max(0, Math.min(100, Math.round(value)));
@@ -33372,7 +33554,7 @@ function InfoSheet({
33372
33554
  viewMode,
33373
33555
  pageTheme,
33374
33556
  locale
33375
- } = useViewerStore15();
33557
+ } = useViewerStore16();
33376
33558
  const isDark = uiTheme === "dark";
33377
33559
  const palette = getReaderSheetPalette(isDark);
33378
33560
  const isPortuguese = locale === "pt-BR";
@@ -33482,7 +33664,7 @@ var styles18 = StyleSheet18.create({
33482
33664
 
33483
33665
  // components/OverflowSheet.tsx
33484
33666
  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";
33667
+ import { useViewerStore as useViewerStore17 } from "@papyrus-sdk/core";
33486
33668
  import { jsx as jsx23 } from "react/jsx-runtime";
33487
33669
  var actionLabels = [{ key: "actions", label: "Document actions" }];
33488
33670
  function OverflowSheet({
@@ -33490,7 +33672,7 @@ function OverflowSheet({
33490
33672
  onClose,
33491
33673
  onOpenActions
33492
33674
  }) {
33493
- const isDark = useViewerStore16((state) => state.uiTheme === "dark");
33675
+ const isDark = useViewerStore17((state) => state.uiTheme === "dark");
33494
33676
  const palette = getReaderSheetPalette(isDark);
33495
33677
  return /* @__PURE__ */ jsx23(
33496
33678
  NativeSheet,
@@ -33540,9 +33722,9 @@ var styles19 = StyleSheet19.create({
33540
33722
  });
33541
33723
 
33542
33724
  // components/ProgressPill.tsx
33543
- import { useEffect as useEffect14, useMemo as useMemo9, useRef as useRef10, useState as useState13 } from "react";
33725
+ import { useEffect as useEffect15, useMemo as useMemo9, useRef as useRef10, useState as useState14 } from "react";
33544
33726
  import {
33545
- Animated as Animated3,
33727
+ Animated as Animated5,
33546
33728
  PanResponder as PanResponder2,
33547
33729
  Pressable as Pressable13,
33548
33730
  StyleSheet as StyleSheet20,
@@ -33550,7 +33732,7 @@ import {
33550
33732
  View as View20,
33551
33733
  useWindowDimensions as useWindowDimensions9
33552
33734
  } from "react-native";
33553
- import { useViewerStore as useViewerStore17 } from "@papyrus-sdk/core";
33735
+ import { useViewerStore as useViewerStore18 } from "@papyrus-sdk/core";
33554
33736
 
33555
33737
  // components/progressPillMode.ts
33556
33738
  function resolveProgressPillMode(viewMode, currentPage, pageCount) {
@@ -33586,7 +33768,7 @@ function ProgressPill({
33586
33768
  accentColor,
33587
33769
  mobileChromeVisible,
33588
33770
  mobileProgressPillVisible
33589
- } = useViewerStore17();
33771
+ } = useViewerStore18();
33590
33772
  const t = getStrings(locale);
33591
33773
  const isDark = uiTheme === "dark";
33592
33774
  const offsets = resolveMobileChromeOffsets(usePapyrusSafeAreaInsets());
@@ -33608,7 +33790,7 @@ function ProgressPill({
33608
33790
  const longPressTriggeredRef = useRef10(false);
33609
33791
  const longPressTimerRef = useRef10(null);
33610
33792
  const pendingReleasedScrubPageRef = useRef10(null);
33611
- const [scrubPreviewPage, setScrubPreviewPage] = useState13(null);
33793
+ const [scrubPreviewPage, setScrubPreviewPage] = useState14(null);
33612
33794
  const onNavigateToPageRef = useRef10(onNavigateToPage);
33613
33795
  const onPressRef = useRef10(onPress);
33614
33796
  const onOpenPageJumpRef = useRef10(onOpenPageJump);
@@ -33641,34 +33823,34 @@ function ProgressPill({
33641
33823
  thumbHeight,
33642
33824
  pageCount
33643
33825
  });
33644
- const thumbTopRef = useRef10(new Animated3.Value(thumbTop));
33826
+ const thumbTopRef = useRef10(new Animated5.Value(thumbTop));
33645
33827
  const thumbTopSnapshotRef = useRef10(thumbTop);
33646
33828
  thumbTopSnapshotRef.current = thumbTop;
33647
33829
  const scrubStartThumbTopRef = useRef10(0);
33648
- const trackReveal = useRef10(new Animated3.Value(0)).current;
33649
- const [trackOriginY, setTrackOriginY] = useState13(0);
33830
+ const trackReveal = useRef10(new Animated5.Value(0)).current;
33831
+ const [trackOriginY, setTrackOriginY] = useState14(0);
33650
33832
  const scrubberMetricsRef = useRef10({ trackHeight, thumbHeight, pageCount });
33651
33833
  scrubberMetricsRef.current = { trackHeight, thumbHeight, pageCount };
33652
- useEffect14(() => {
33834
+ useEffect15(() => {
33653
33835
  onNavigateToPageRef.current = onNavigateToPage;
33654
33836
  }, [onNavigateToPage]);
33655
- useEffect14(() => {
33837
+ useEffect15(() => {
33656
33838
  onPressRef.current = onPress;
33657
33839
  onOpenPageJumpRef.current = onOpenPageJump;
33658
33840
  }, [onOpenPageJump, onPress]);
33659
- useEffect14(() => {
33841
+ useEffect15(() => {
33660
33842
  const pendingPage = pendingReleasedScrubPageRef.current;
33661
33843
  if (pendingPage !== null && currentPage === pendingPage) {
33662
33844
  pendingReleasedScrubPageRef.current = null;
33663
33845
  setScrubPreviewPage(null);
33664
33846
  }
33665
33847
  }, [currentPage]);
33666
- useEffect14(() => {
33848
+ useEffect15(() => {
33667
33849
  if (!isScrubbingRef.current) {
33668
33850
  thumbTopRef.current.setValue(thumbTop);
33669
33851
  }
33670
33852
  }, [thumbTop, thumbTopRef]);
33671
- useEffect14(
33853
+ useEffect15(
33672
33854
  () => () => {
33673
33855
  if (longPressTimerRef.current !== null) {
33674
33856
  clearTimeout(longPressTimerRef.current);
@@ -33803,7 +33985,7 @@ function ProgressPill({
33803
33985
  })
33804
33986
  );
33805
33987
  trackReveal.setValue(0);
33806
- Animated3.timing(trackReveal, {
33988
+ Animated5.timing(trackReveal, {
33807
33989
  toValue: 1,
33808
33990
  duration: 180,
33809
33991
  useNativeDriver: false
@@ -33849,7 +34031,7 @@ function ProgressPill({
33849
34031
  }
33850
34032
  isScrubbingRef.current = false;
33851
34033
  onScrubbingChangeRef.current?.(false);
33852
- Animated3.timing(trackReveal, {
34034
+ Animated5.timing(trackReveal, {
33853
34035
  toValue: 0,
33854
34036
  duration: 140,
33855
34037
  useNativeDriver: false
@@ -33881,7 +34063,7 @@ function ProgressPill({
33881
34063
  }
33882
34064
  isScrubbingRef.current = false;
33883
34065
  onScrubbingChangeRef.current?.(false);
33884
- Animated3.timing(trackReveal, {
34066
+ Animated5.timing(trackReveal, {
33885
34067
  toValue: 0,
33886
34068
  duration: 140,
33887
34069
  useNativeDriver: false
@@ -33921,7 +34103,7 @@ function ProgressPill({
33921
34103
  },
33922
34104
  children: [
33923
34105
  /* @__PURE__ */ jsx24(
33924
- Animated3.View,
34106
+ Animated5.View,
33925
34107
  {
33926
34108
  pointerEvents: "none",
33927
34109
  style: [
@@ -33937,7 +34119,7 @@ function ProgressPill({
33937
34119
  }
33938
34120
  ),
33939
34121
  /* @__PURE__ */ jsx24(
33940
- Animated3.View,
34122
+ Animated5.View,
33941
34123
  {
33942
34124
  pointerEvents: "box-none",
33943
34125
  style: [styles20.thumb, { top: thumbTopRef.current }],
@@ -34078,7 +34260,7 @@ var styles20 = StyleSheet20.create({
34078
34260
  });
34079
34261
 
34080
34262
  // components/SearchOverlay.tsx
34081
- import React18, { useEffect as useEffect15, useMemo as useMemo10, useState as useState14 } from "react";
34263
+ import React18, { useEffect as useEffect16, useMemo as useMemo10, useState as useState15 } from "react";
34082
34264
  import {
34083
34265
  Keyboard,
34084
34266
  Pressable as Pressable14,
@@ -34088,7 +34270,7 @@ import {
34088
34270
  View as View21,
34089
34271
  useWindowDimensions as useWindowDimensions10
34090
34272
  } from "react-native";
34091
- import { SearchService, useViewerStore as useViewerStore18 } from "@papyrus-sdk/core";
34273
+ import { SearchService, useViewerStore as useViewerStore19 } from "@papyrus-sdk/core";
34092
34274
 
34093
34275
  // components/searchOverlayLayout.ts
34094
34276
  var getSearchOverlayLayout = (windowWidth) => {
@@ -34129,9 +34311,9 @@ function SearchOverlay({
34129
34311
  setSearch,
34130
34312
  uiTheme,
34131
34313
  accentColor
34132
- } = useViewerStore18();
34133
- const [draft, setDraft] = useState14(searchQuery);
34134
- const [isSearching, setIsSearching] = useState14(false);
34314
+ } = useViewerStore19();
34315
+ const [draft, setDraft] = useState15(searchQuery);
34316
+ const [isSearching, setIsSearching] = useState15(false);
34135
34317
  const searchRequestIdRef = React18.useRef(0);
34136
34318
  const isDark = uiTheme === "dark";
34137
34319
  const { width: windowWidth } = useWindowDimensions10();
@@ -34140,12 +34322,12 @@ function SearchOverlay({
34140
34322
  const t = getStrings(locale);
34141
34323
  const searchService = useMemo10(() => new SearchService(engine), [engine]);
34142
34324
  const results = documentType === "text" ? textSearchResults : searchResults;
34143
- useEffect15(() => {
34325
+ useEffect16(() => {
34144
34326
  searchService.clearCache();
34145
34327
  }, [isLoaded, pageCount, searchService]);
34146
34328
  const currentCount = results.length > 0 && activeSearchIndex >= 0 ? activeSearchIndex + 1 : 0;
34147
34329
  const targetLabel = documentType === "pdf" ? t.page : documentType === "epub" ? t.contents : t.progress;
34148
- useEffect15(() => {
34330
+ useEffect16(() => {
34149
34331
  if (!visible) return;
34150
34332
  setDraft(searchQuery);
34151
34333
  }, [searchQuery, visible]);
@@ -34434,7 +34616,7 @@ var styles21 = StyleSheet21.create({
34434
34616
 
34435
34617
  // components/SearchResultsSheet.tsx
34436
34618
  import { Pressable as Pressable15, StyleSheet as StyleSheet22, Text as Text15 } from "react-native";
34437
- import { useViewerStore as useViewerStore19 } from "@papyrus-sdk/core";
34619
+ import { useViewerStore as useViewerStore20 } from "@papyrus-sdk/core";
34438
34620
  import { jsx as jsx26, jsxs as jsxs20 } from "react/jsx-runtime";
34439
34621
  function SearchResultsSheet({
34440
34622
  documentType,
@@ -34453,7 +34635,7 @@ function SearchResultsSheet({
34453
34635
  triggerScrollToTextOffset,
34454
34636
  uiTheme,
34455
34637
  accentColor
34456
- } = useViewerStore19();
34638
+ } = useViewerStore20();
34457
34639
  const results = documentType === "text" ? textSearchResults : searchResults;
34458
34640
  const isDark = uiTheme === "dark";
34459
34641
  const palette = getReaderSheetPalette(isDark);
@@ -34567,14 +34749,14 @@ function ReadingShell({
34567
34749
  pageCount,
34568
34750
  uiTheme,
34569
34751
  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);
34752
+ } = useViewerStore21();
34753
+ const [overflowOpen, setOverflowOpen] = useState16(false);
34754
+ const [infoOpen, setInfoOpen] = useState16(false);
34755
+ const [actionsOpen, setActionsOpen] = useState16(false);
34756
+ const [settingsOpen, setSettingsOpen] = useState16(false);
34757
+ const [searchResultsOpen, setSearchResultsOpen] = useState16(false);
34758
+ const [pageJumpOpen, setPageJumpOpen] = useState16(false);
34759
+ const [pageScrubActive, setPageScrubActive] = useState16(false);
34578
34760
  const isDark = uiTheme === "dark";
34579
34761
  React19.useEffect(() => {
34580
34762
  const showSubscription = Keyboard2.addListener("keyboardDidShow", () => {