@papyrus-sdk/ui-react-native 0.1.2 → 0.1.4
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.d.mts +21 -2
- package/dist/index.d.ts +21 -2
- package/dist/index.js +208 -19
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +214 -19
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
- package/runtime/index.html +31 -19
- package/runtime/runtime.js +29 -11
package/dist/index.mjs
CHANGED
|
@@ -125,13 +125,21 @@ https://github.com/nodeca/pako/blob/main/LICENSE\r
|
|
|
125
125
|
}\r
|
|
126
126
|
};\r
|
|
127
127
|
\r
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
128
|
+
const shouldIgnoreError = (error) => {
|
|
129
|
+
const message = error && error.message ? error.message : String(error || '');
|
|
130
|
+
return message.includes('ResizeObserver loop');
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
window.addEventListener('error', (event) => {
|
|
134
|
+
const error = event.error || event.message;
|
|
135
|
+
if (shouldIgnoreError(error)) return;
|
|
136
|
+
reportError(error, 'window.error');
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
window.addEventListener('unhandledrejection', (event) => {
|
|
140
|
+
if (shouldIgnoreError(event.reason)) return;
|
|
141
|
+
reportError(event.reason, 'unhandledrejection');
|
|
142
|
+
});
|
|
135
143
|
\r
|
|
136
144
|
const clearViewer = () => {\r
|
|
137
145
|
while (viewer.firstChild) {\r
|
|
@@ -394,8 +402,12 @@ https://github.com/nodeca/pako/blob/main/LICENSE\r
|
|
|
394
402
|
});\r
|
|
395
403
|
\r
|
|
396
404
|
const getPageIndex = (dest) => {\r
|
|
397
|
-
if (
|
|
405
|
+
if (!dest) return null;\r
|
|
398
406
|
if (typeof dest === 'string') return getSpineIndexByHref(dest);\r
|
|
407
|
+
if (typeof dest !== 'object') return null;\r
|
|
408
|
+
if (dest.kind === 'href') return getSpineIndexByHref(dest.value);\r
|
|
409
|
+
if (dest.kind === 'pageIndex') return dest.value;\r
|
|
410
|
+
if (dest.kind === 'pageNumber') return Math.max(0, dest.value - 1);\r
|
|
399
411
|
return null;\r
|
|
400
412
|
};\r
|
|
401
413
|
\r
|
|
@@ -522,6 +534,9 @@ https://github.com/nodeca/pako/blob/main/LICENSE\r
|
|
|
522
534
|
if (raw && typeof raw === 'object' && raw.kind && raw.id) {
|
|
523
535
|
message = raw;
|
|
524
536
|
} else if (typeof raw === 'string') {
|
|
537
|
+
if (raw.startsWith('setImmediate$')) {
|
|
538
|
+
return;
|
|
539
|
+
}
|
|
525
540
|
const trimmed = raw.trim();
|
|
526
541
|
if (!trimmed || (!trimmed.startsWith('{') && !trimmed.startsWith('['))) {
|
|
527
542
|
return;
|
|
@@ -529,18 +544,15 @@ https://github.com/nodeca/pako/blob/main/LICENSE\r
|
|
|
529
544
|
try {
|
|
530
545
|
message = JSON.parse(trimmed);
|
|
531
546
|
} catch (err) {
|
|
532
|
-
sendEvent('RUNTIME_ERROR', {
|
|
533
|
-
message: 'Failed to parse message'
|
|
534
|
-
context: 'runtime.onMessage'
|
|
535
|
-
stack: err && err.stack ? err.stack : null
|
|
536
|
-
preview: trimmed.slice(0, 200)
|
|
537
|
-
})
|
|
538
|
-
return
|
|
539
|
-
}
|
|
547
|
+
sendEvent('RUNTIME_ERROR', {\r
|
|
548
|
+
message: 'Failed to parse message',\r
|
|
549
|
+
context: 'runtime.onMessage',\r
|
|
550
|
+
stack: err && err.stack ? err.stack : null,\r
|
|
551
|
+
preview: trimmed.slice(0, 200),\r
|
|
552
|
+
});\r
|
|
553
|
+
return;\r
|
|
554
|
+
}\r
|
|
540
555
|
} else {
|
|
541
|
-
sendEvent('RUNTIME_LOG', {
|
|
542
|
-
message: \`Ignoring message of type \${typeof raw}\`,
|
|
543
|
-
});
|
|
544
556
|
return;
|
|
545
557
|
}
|
|
546
558
|
\r
|
|
@@ -3606,9 +3618,192 @@ var styles9 = StyleSheet9.create({
|
|
|
3606
3618
|
}
|
|
3607
3619
|
});
|
|
3608
3620
|
var SettingsSheet_default = SettingsSheet;
|
|
3621
|
+
|
|
3622
|
+
// components/CoverPreview.tsx
|
|
3623
|
+
import { useEffect as useEffect7, useMemo as useMemo5, useRef as useRef5, useState as useState5 } from "react";
|
|
3624
|
+
import {
|
|
3625
|
+
ActivityIndicator as ActivityIndicator2,
|
|
3626
|
+
StyleSheet as StyleSheet10,
|
|
3627
|
+
Text as Text7,
|
|
3628
|
+
UIManager as UIManager2,
|
|
3629
|
+
View as View10,
|
|
3630
|
+
findNodeHandle as findNodeHandle3
|
|
3631
|
+
} from "react-native";
|
|
3632
|
+
import { MobileDocumentEngine, PapyrusPageView as PapyrusPageView3 } from "@papyrus-sdk/engine-native";
|
|
3633
|
+
import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
3634
|
+
var parseDataUri = (value) => {
|
|
3635
|
+
const match = /^data:([^;,]+)?(;base64)?,/.exec(value);
|
|
3636
|
+
if (!match) return null;
|
|
3637
|
+
return { mime: match[1] ?? "" };
|
|
3638
|
+
};
|
|
3639
|
+
var inferDocumentType = (source, explicitType) => {
|
|
3640
|
+
if (explicitType) return explicitType;
|
|
3641
|
+
if (typeof source === "string") {
|
|
3642
|
+
const dataUri = parseDataUri(source);
|
|
3643
|
+
if (dataUri?.mime) {
|
|
3644
|
+
const mime = dataUri.mime.toLowerCase();
|
|
3645
|
+
if (mime.includes("epub")) return "epub";
|
|
3646
|
+
if (mime.includes("text")) return "text";
|
|
3647
|
+
if (mime.includes("pdf")) return "pdf";
|
|
3648
|
+
}
|
|
3649
|
+
const clean = source.split("?")[0].split("#")[0];
|
|
3650
|
+
const ext = clean.includes(".") ? clean.split(".").pop()?.toLowerCase() : void 0;
|
|
3651
|
+
if (ext === "epub") return "epub";
|
|
3652
|
+
if (ext === "txt") return "text";
|
|
3653
|
+
if (ext === "pdf") return "pdf";
|
|
3654
|
+
return "pdf";
|
|
3655
|
+
}
|
|
3656
|
+
if (typeof source === "object" && source !== null && "uri" in source) {
|
|
3657
|
+
const clean = source.uri.split("?")[0].split("#")[0];
|
|
3658
|
+
const ext = clean.includes(".") ? clean.split(".").pop()?.toLowerCase() : void 0;
|
|
3659
|
+
if (ext === "epub") return "epub";
|
|
3660
|
+
if (ext === "txt") return "text";
|
|
3661
|
+
if (ext === "pdf") return "pdf";
|
|
3662
|
+
}
|
|
3663
|
+
return "pdf";
|
|
3664
|
+
};
|
|
3665
|
+
var CoverPreview = ({
|
|
3666
|
+
source,
|
|
3667
|
+
type,
|
|
3668
|
+
pageIndex = 0,
|
|
3669
|
+
visible = true,
|
|
3670
|
+
keepAlive = false,
|
|
3671
|
+
allowInteraction = false,
|
|
3672
|
+
renderScale = 2,
|
|
3673
|
+
showLoading = true,
|
|
3674
|
+
loadingIndicator,
|
|
3675
|
+
placeholder,
|
|
3676
|
+
style,
|
|
3677
|
+
onLoadStart,
|
|
3678
|
+
onLoadEnd,
|
|
3679
|
+
onError
|
|
3680
|
+
}) => {
|
|
3681
|
+
const [engine, setEngine] = useState5(null);
|
|
3682
|
+
const [layoutReady, setLayoutReady] = useState5(false);
|
|
3683
|
+
const [loaded, setLoaded] = useState5(false);
|
|
3684
|
+
const [loading, setLoading] = useState5(false);
|
|
3685
|
+
const [error, setError] = useState5(null);
|
|
3686
|
+
const viewRef = useRef5(null);
|
|
3687
|
+
const resolvedType = useMemo5(() => inferDocumentType(source, type), [source, type]);
|
|
3688
|
+
const isPdf = resolvedType === "pdf";
|
|
3689
|
+
const hasNativePageView = Boolean(UIManager2.getViewManagerConfig?.("PapyrusPageView"));
|
|
3690
|
+
const canRender = !isPdf || hasNativePageView;
|
|
3691
|
+
const shouldRender = Boolean(visible);
|
|
3692
|
+
useEffect7(() => {
|
|
3693
|
+
if (!shouldRender) {
|
|
3694
|
+
if (!keepAlive) {
|
|
3695
|
+
setEngine(null);
|
|
3696
|
+
setLoaded(false);
|
|
3697
|
+
setError(null);
|
|
3698
|
+
}
|
|
3699
|
+
return;
|
|
3700
|
+
}
|
|
3701
|
+
if (!engine && canRender) {
|
|
3702
|
+
setEngine(new MobileDocumentEngine());
|
|
3703
|
+
}
|
|
3704
|
+
}, [shouldRender, keepAlive, engine, canRender]);
|
|
3705
|
+
useEffect7(() => {
|
|
3706
|
+
if (!engine || !shouldRender || !canRender) return;
|
|
3707
|
+
let active = true;
|
|
3708
|
+
setLoading(true);
|
|
3709
|
+
setLoaded(false);
|
|
3710
|
+
setError(null);
|
|
3711
|
+
onLoadStart?.();
|
|
3712
|
+
const loadInput = type ? { type, source } : source;
|
|
3713
|
+
engine.load(loadInput).then(() => {
|
|
3714
|
+
if (!active) return;
|
|
3715
|
+
if (!isPdf && pageIndex > 0) {
|
|
3716
|
+
engine.goToPage(pageIndex + 1);
|
|
3717
|
+
}
|
|
3718
|
+
setLoaded(true);
|
|
3719
|
+
setLoading(false);
|
|
3720
|
+
onLoadEnd?.();
|
|
3721
|
+
}).catch((err) => {
|
|
3722
|
+
if (!active) return;
|
|
3723
|
+
const errorValue = err instanceof Error ? err : new Error("[Papyrus] Failed to load document");
|
|
3724
|
+
setError(errorValue);
|
|
3725
|
+
setLoading(false);
|
|
3726
|
+
onError?.(errorValue);
|
|
3727
|
+
});
|
|
3728
|
+
return () => {
|
|
3729
|
+
active = false;
|
|
3730
|
+
};
|
|
3731
|
+
}, [engine, shouldRender, canRender, source, type, pageIndex, isPdf, onLoadStart, onLoadEnd, onError]);
|
|
3732
|
+
useEffect7(() => {
|
|
3733
|
+
if (!engine || !isPdf || !loaded || !layoutReady || !shouldRender || !canRender) return;
|
|
3734
|
+
const viewTag = findNodeHandle3(viewRef.current);
|
|
3735
|
+
if (!viewTag) return;
|
|
3736
|
+
engine.renderPage(pageIndex, viewTag, renderScale);
|
|
3737
|
+
}, [engine, isPdf, loaded, layoutReady, shouldRender, canRender, pageIndex, renderScale]);
|
|
3738
|
+
useEffect7(() => {
|
|
3739
|
+
return () => {
|
|
3740
|
+
engine?.destroy();
|
|
3741
|
+
};
|
|
3742
|
+
}, [engine]);
|
|
3743
|
+
const handleLayout = (event) => {
|
|
3744
|
+
const { width, height } = event.nativeEvent.layout;
|
|
3745
|
+
if (width > 0 && height > 0) {
|
|
3746
|
+
setLayoutReady(true);
|
|
3747
|
+
}
|
|
3748
|
+
};
|
|
3749
|
+
if (!shouldRender || !canRender) {
|
|
3750
|
+
return /* @__PURE__ */ jsx11(View10, { style: [styles10.container, style], children: placeholder ?? /* @__PURE__ */ jsx11(View10, { style: styles10.placeholder, children: /* @__PURE__ */ jsx11(Text7, { style: styles10.placeholderText, children: "Preview" }) }) });
|
|
3751
|
+
}
|
|
3752
|
+
return /* @__PURE__ */ jsxs11(View10, { style: [styles10.container, style], onLayout: handleLayout, children: [
|
|
3753
|
+
/* @__PURE__ */ jsx11(View10, { style: styles10.previewFrame, pointerEvents: allowInteraction ? "auto" : "none", children: isPdf ? /* @__PURE__ */ jsx11(PapyrusPageView3, { ref: viewRef, style: styles10.pageView }) : engine && /* @__PURE__ */ jsx11(WebViewViewer_default, { engine }) }),
|
|
3754
|
+
showLoading && loading && /* @__PURE__ */ jsx11(View10, { pointerEvents: "none", style: styles10.loadingOverlay, children: loadingIndicator ?? /* @__PURE__ */ jsx11(ActivityIndicator2, { size: "small", color: "#2563eb" }) }),
|
|
3755
|
+
error && /* @__PURE__ */ jsx11(View10, { pointerEvents: "none", style: styles10.errorOverlay, children: /* @__PURE__ */ jsx11(Text7, { style: styles10.errorText, children: "Preview unavailable" }) })
|
|
3756
|
+
] });
|
|
3757
|
+
};
|
|
3758
|
+
var styles10 = StyleSheet10.create({
|
|
3759
|
+
container: {
|
|
3760
|
+
backgroundColor: "#f8fafc",
|
|
3761
|
+
borderRadius: 12,
|
|
3762
|
+
overflow: "hidden"
|
|
3763
|
+
},
|
|
3764
|
+
previewFrame: {
|
|
3765
|
+
flex: 1,
|
|
3766
|
+
backgroundColor: "#ffffff"
|
|
3767
|
+
},
|
|
3768
|
+
pageView: {
|
|
3769
|
+
width: "100%",
|
|
3770
|
+
height: "100%",
|
|
3771
|
+
backgroundColor: "transparent"
|
|
3772
|
+
},
|
|
3773
|
+
loadingOverlay: {
|
|
3774
|
+
...StyleSheet10.absoluteFillObject,
|
|
3775
|
+
alignItems: "center",
|
|
3776
|
+
justifyContent: "center",
|
|
3777
|
+
backgroundColor: "rgba(15, 23, 42, 0.15)"
|
|
3778
|
+
},
|
|
3779
|
+
errorOverlay: {
|
|
3780
|
+
...StyleSheet10.absoluteFillObject,
|
|
3781
|
+
alignItems: "center",
|
|
3782
|
+
justifyContent: "center",
|
|
3783
|
+
backgroundColor: "rgba(15, 23, 42, 0.4)"
|
|
3784
|
+
},
|
|
3785
|
+
errorText: {
|
|
3786
|
+
fontSize: 12,
|
|
3787
|
+
fontWeight: "600",
|
|
3788
|
+
color: "#f8fafc"
|
|
3789
|
+
},
|
|
3790
|
+
placeholder: {
|
|
3791
|
+
flex: 1,
|
|
3792
|
+
alignItems: "center",
|
|
3793
|
+
justifyContent: "center",
|
|
3794
|
+
backgroundColor: "#e2e8f0"
|
|
3795
|
+
},
|
|
3796
|
+
placeholderText: {
|
|
3797
|
+
fontSize: 12,
|
|
3798
|
+
fontWeight: "600",
|
|
3799
|
+
color: "#475569"
|
|
3800
|
+
}
|
|
3801
|
+
});
|
|
3802
|
+
var CoverPreview_default = CoverPreview;
|
|
3609
3803
|
export {
|
|
3610
3804
|
AnnotationEditor_default as AnnotationEditor,
|
|
3611
3805
|
BottomBar_default as BottomBar,
|
|
3806
|
+
CoverPreview_default as CoverPreview,
|
|
3612
3807
|
PageRenderer_default as PageRenderer,
|
|
3613
3808
|
RightSheet_default as RightSheet,
|
|
3614
3809
|
SettingsSheet_default as SettingsSheet,
|