@papyrus-sdk/ui-react-native 0.2.35-beta.11 → 0.2.35-beta.11.epub.2
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/LICENSE +21 -0
- package/dist/index.d.mts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +415 -231
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +359 -175
- package/dist/index.mjs.map +1 -1
- package/package.json +13 -13
- package/runtime/comicRuntime.test.ts +9 -9
- package/runtime/epubAnnotations.js +7 -4
- package/runtime/epubAnnotations.test.ts +6 -2
- package/runtime/epubReader.js +58 -0
- package/runtime/epubReader.test.ts +74 -0
- package/runtime/epubRuntime.test.ts +45 -0
- package/runtime/index.html +178 -91
- package/runtime/runtime.js +178 -91
- package/runtime/syncComicRuntime.mjs +6 -3
package/dist/index.js
CHANGED
|
@@ -20517,6 +20517,67 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
20517
20517
|
<!-- @papyrus-comic-runtime:end -->
|
|
20518
20518
|
<script>
|
|
20519
20519
|
(function () {
|
|
20520
|
+
/* @papyrus-epub-reader:start */
|
|
20521
|
+
(function(root){
|
|
20522
|
+
function mode(value){return value==='chapter-scroll'?'chapter-scroll':'paged';}
|
|
20523
|
+
function validCfi(value){return typeof value==='string' && value.length<=4096 && /^epubcfi\\([^\\n<>]+\\)$/.test(value);}
|
|
20524
|
+
function options(value){return {manager:'default',flow:mode(value)==='paged'?'paginated':'scrolled-doc',spread:'none',width:'100%',height:'100%',allowScriptedContent:false};}
|
|
20525
|
+
function gesture(start,end,state){
|
|
20526
|
+
if(!start || !end || state.selected || state.interactive || state.multitouch)return null;
|
|
20527
|
+
var dx=end.x-start.x,dy=end.y-start.y,elapsed=end.time-start.time;
|
|
20528
|
+
if(state.mode==='paged' && Math.abs(dx)>=48 && Math.abs(dx)>Math.abs(dy)*1.5 && elapsed>=0 && elapsed<1500)return (dx<0)!==Boolean(state.rtl)?'next':'prev';
|
|
20529
|
+
if(elapsed>=0 && elapsed<450 && Math.hypot(dx,dy)<=12)return 'tap';
|
|
20530
|
+
return null;
|
|
20531
|
+
}
|
|
20532
|
+
function location(raw,count,readingMode,geometry){
|
|
20533
|
+
var start=raw && raw.start;if(!start || !validCfi(start.cfi))return null;
|
|
20534
|
+
var displayed=start.displayed||{},chapter=Math.max(1,(Number(start.index)||0)+1);
|
|
20535
|
+
var visualPage=mode(readingMode)==='paged' && Number.isFinite(displayed.page)?displayed.page:null;
|
|
20536
|
+
var total=mode(readingMode)==='paged' && Number.isFinite(displayed.total)?displayed.total:null;
|
|
20537
|
+
var atStart=Boolean(raw.atStart),atEnd=Boolean(raw.atEnd);
|
|
20538
|
+
// Chromium may round a column offset down by a fraction of a CSS pixel.
|
|
20539
|
+
// Keep epub.js authoritative outside a 1px boundary, and for RTL layouts.
|
|
20540
|
+
if(visualPage!==null && total>0 && geometry && geometry.direction==='ltr' && geometry.pageWidth>0 && Number.isFinite(geometry.offset)){
|
|
20541
|
+
var boundary=Math.round(geometry.offset/geometry.pageWidth);
|
|
20542
|
+
if(Math.abs(geometry.offset-boundary*geometry.pageWidth)<=1){
|
|
20543
|
+
visualPage=Math.min(total,Math.max(1,boundary+1));
|
|
20544
|
+
atStart=chapter===(geometry.firstIndex ?? 0)+1 && visualPage===1;
|
|
20545
|
+
atEnd=chapter===(geometry.lastIndex ?? count-1)+1 && visualPage===total;
|
|
20546
|
+
}
|
|
20547
|
+
}
|
|
20548
|
+
var fraction=total?Math.max(0,(visualPage-1)/total):0;
|
|
20549
|
+
return {version:1,cfi:start.cfi,href:start.href||'',chapter:chapter,chapterCount:count,visualPage:visualPage,visualPageCount:total,progress:Math.min(1,Math.max(0,(chapter-1+fraction)/Math.max(1,count))),mode:mode(readingMode),atStart:atStart,atEnd:atEnd};
|
|
20550
|
+
}
|
|
20551
|
+
function installResizeAnchor(manager,readCfi){
|
|
20552
|
+
var original=manager.resize,anchor=null;
|
|
20553
|
+
function resize(width,height,target){
|
|
20554
|
+
if(validCfi(target))anchor=target;
|
|
20555
|
+
if(!anchor){var current=readCfi();if(validCfi(current))anchor=current;}
|
|
20556
|
+
// epub.js accepts a logical target as its third argument. Keep it across
|
|
20557
|
+
// keyboard/dialog reflows instead of adopting each new viewport start.
|
|
20558
|
+
return original.call(this,width,height,anchor || target);
|
|
20559
|
+
}
|
|
20560
|
+
manager.resize=resize;
|
|
20561
|
+
return {cfi:function(){return anchor;},invalidate:function(){anchor=null;},destroy:function(){if(manager.resize===resize)manager.resize=original;anchor=null;}};
|
|
20562
|
+
}
|
|
20563
|
+
function install(contents,config){
|
|
20564
|
+
var doc=contents.document,win=contents.window,start=null,blocked=false;
|
|
20565
|
+
function point(e){var t=e.changedTouches&&e.changedTouches[0]||e.touches&&e.touches[0];return t?{x:t.clientX,y:t.clientY,time:Date.now()}:null;}
|
|
20566
|
+
function selected(){return Boolean(String(win.getSelection()||'').trim()) || config.blocked();}
|
|
20567
|
+
function interactive(target){return Boolean(target && target.closest && target.closest('a,button,input,textarea,select,[contenteditable="true"],[data-papyrus-overlay]'));}
|
|
20568
|
+
function begin(e){start=point(e);blocked=e.touches.length!==1 || selected() || interactive(e.target);}
|
|
20569
|
+
function invalidateScroll(finish){if(config.current() && start && finish && config.mode()==='chapter-scroll' && !blocked && !selected() && Math.abs(finish.y-start.y)>12 && Math.abs(finish.y-start.y)>Math.abs(finish.x-start.x) && config.interact)config.interact();}
|
|
20570
|
+
function move(e){if(e.touches.length!==1)blocked=true;invalidateScroll(point(e));}
|
|
20571
|
+
function end(e){var finish=point(e);invalidateScroll(finish);var action=gesture(start,finish,{mode:config.mode(),rtl:config.rtl(),selected:selected(),interactive:blocked||interactive(e.target)||Boolean(config.annotationHit && config.annotationHit(point(e))),multitouch:blocked});start=null;if(!config.current())return;if(action==='tap')config.tap();else if(action)config.turn(action==='next'?1:-1);}
|
|
20572
|
+
function cancel(){start=null;blocked=true;}
|
|
20573
|
+
function link(e){if(config.current() && e.target?.closest?.('a') && config.interact)config.interact();}
|
|
20574
|
+
doc.addEventListener('touchstart',begin,{passive:true});doc.addEventListener('touchmove',move,{passive:true});doc.addEventListener('touchend',end,{passive:true});doc.addEventListener('touchcancel',cancel,{passive:true});doc.addEventListener('click',link);
|
|
20575
|
+
return function(){doc.removeEventListener('touchstart',begin);doc.removeEventListener('touchmove',move);doc.removeEventListener('touchend',end);doc.removeEventListener('touchcancel',cancel);doc.removeEventListener('click',link);};
|
|
20576
|
+
}
|
|
20577
|
+
root.PapyrusEpubReader={mode:mode,validCfi:validCfi,options:options,gesture:gesture,location:location,installResizeAnchor:installResizeAnchor,install:install};
|
|
20578
|
+
})(typeof window==='undefined'?globalThis:window);
|
|
20579
|
+
|
|
20580
|
+
/* @papyrus-epub-reader:end */
|
|
20520
20581
|
/* @papyrus-epub-annotations:start */
|
|
20521
20582
|
(function (root, factory) {
|
|
20522
20583
|
if (typeof module === 'object' && module.exports) module.exports = factory();
|
|
@@ -20595,6 +20656,7 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
20595
20656
|
var color = /^#[0-9a-f]{6}$/i.test(annotation.color) ? annotation.color : '#FFC928';
|
|
20596
20657
|
var style = annotation.markupStyle || annotation.type;
|
|
20597
20658
|
var opacity = Number.isFinite(annotation.opacity) ? Math.max(0,Math.min(1,annotation.opacity)) : 0.35;
|
|
20659
|
+
if(style === 'highlight')opacity=Math.min(0.35,opacity);
|
|
20598
20660
|
rects.forEach(function(rect) {
|
|
20599
20661
|
var mark = doc.createElement('div');
|
|
20600
20662
|
var bodyRect=doc.body.getBoundingClientRect();
|
|
@@ -20607,8 +20669,10 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
20607
20669
|
if (hasNote) {
|
|
20608
20670
|
var last = rects[rects.length-1], button = doc.createElement('button');
|
|
20609
20671
|
button.textContent = '\u25CF'; button.setAttribute('aria-label',options.labels().comment || '');
|
|
20610
|
-
|
|
20611
|
-
var
|
|
20672
|
+
var pageWidth=Math.max(44, options.pageWidth ? options.pageWidth() : win.innerWidth);
|
|
20673
|
+
var bodyRect=doc.body.getBoundingClientRect(), column=Math.max(0,Math.floor((last.left-bodyRect.left)/pageWidth));
|
|
20674
|
+
button.style.cssText = 'position:absolute;pointer-events:auto;border:0;background:transparent;color:'+color+';width:44px;height:44px;left:'+((column+1)*pageWidth-44)+'px;top:'+(Math.floor(last.top/44)*44-doc.body.getBoundingClientRect().top)+'px';
|
|
20675
|
+
var key = column+":"+Math.floor(last.top/44);
|
|
20612
20676
|
var neighbors=noteGroups.get(key);
|
|
20613
20677
|
if(!neighbors){neighbors={button:button,ids:[]};noteGroups.set(key,neighbors);group.appendChild(button);}
|
|
20614
20678
|
neighbors.ids.push(annotation.id);
|
|
@@ -20629,10 +20693,10 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
20629
20693
|
doc.addEventListener('click',tapMarkup);
|
|
20630
20694
|
var observer = typeof win.ResizeObserver === 'function' ? new win.ResizeObserver(schedule) : null;
|
|
20631
20695
|
if (observer) observer.observe(doc.body);
|
|
20632
|
-
win.addEventListener('resize',schedule); doc.addEventListener('load',schedule,true);
|
|
20696
|
+
win.addEventListener('resize',schedule);win.addEventListener('scroll',schedule); doc.addEventListener('load',schedule,true);
|
|
20633
20697
|
if (doc.fonts && doc.fonts.ready) doc.fonts.ready.then(schedule);
|
|
20634
20698
|
schedule();
|
|
20635
|
-
return {schedule:schedule, range:function(anchor){return resolveRange(contents,anchor);}, destroy:function(){alive=false;if(frame)win.cancelAnimationFrame(frame);if(observer)observer.disconnect();win.removeEventListener('resize',schedule);doc.removeEventListener('load',schedule,true);doc.removeEventListener('click',tapMarkup);overlay.remove();doc.body.style.position=originalPosition;registry.clear();}};
|
|
20699
|
+
return {schedule:schedule, hit:function(x,y){return hitRegions.some(function(item){return item.rects.some(function(r){return x>=r.left && x<=r.right && y>=r.top && y<=r.bottom;});});}, range:function(anchor){return resolveRange(contents,anchor);}, destroy:function(){alive=false;if(frame)win.cancelAnimationFrame(frame);if(observer)observer.disconnect();win.removeEventListener('resize',schedule);win.removeEventListener('scroll',schedule);doc.removeEventListener('load',schedule,true);doc.removeEventListener('click',tapMarkup);overlay.remove();doc.body.style.position=originalPosition;registry.clear();}};
|
|
20636
20700
|
}
|
|
20637
20701
|
return {validAnchor:validAnchor,recoverRange:recoverRange,resolveRange:resolveRange,selection:selection,install:install};
|
|
20638
20702
|
});
|
|
@@ -20645,6 +20709,7 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
20645
20709
|
let currentType = null;
|
|
20646
20710
|
let book = null;
|
|
20647
20711
|
let rendition = null;
|
|
20712
|
+
let epubResizeAnchor = null;
|
|
20648
20713
|
let documentSessionId = null;
|
|
20649
20714
|
let annotationDocumentId;
|
|
20650
20715
|
let annotationLabels = {};
|
|
@@ -21057,6 +21122,7 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
21057
21122
|
};
|
|
21058
21123
|
|
|
21059
21124
|
const clearViewer = () => {
|
|
21125
|
+
if(epubResizeAnchor){epubResizeAnchor.destroy();epubResizeAnchor=null;}
|
|
21060
21126
|
epubAnnotationRenderers.forEach(renderer => renderer.destroy());
|
|
21061
21127
|
epubAnnotationRenderers.clear();
|
|
21062
21128
|
if (epubInteractionCleanup) {
|
|
@@ -21713,26 +21779,57 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
21713
21779
|
pageCount,
|
|
21714
21780
|
});
|
|
21715
21781
|
|
|
21782
|
+
if (book.locations?.generate) {
|
|
21783
|
+
const activeBook=book;
|
|
21784
|
+
activeBook.locations.generate(150).then(() => {
|
|
21785
|
+
if (isCurrentLoad() && activeBook===book && epubLocation) {
|
|
21786
|
+
epubLocation.progress=activeBook.locations.percentageFromCfi(epubLocation.cfi);
|
|
21787
|
+
sendEvent('EPUB_LOCATION',{documentSessionId,location:epubLocation});
|
|
21788
|
+
}
|
|
21789
|
+
}).catch(() => {});
|
|
21790
|
+
}
|
|
21791
|
+
return renderEpubRendition(loadId,generation,null);
|
|
21792
|
+
};
|
|
21793
|
+
|
|
21794
|
+
const renderEpubRendition = async (loadId,generation,target) => {
|
|
21795
|
+
const diagnosticPayload={loadId};
|
|
21796
|
+
const isCurrentLoad=()=>generation===epubLoadGeneration;
|
|
21797
|
+
if(epubInteractionCleanup)epubInteractionCleanup();
|
|
21798
|
+
if(rendition)rendition.destroy();
|
|
21716
21799
|
clearViewer();
|
|
21717
|
-
rendition = book.renderTo(viewer,
|
|
21718
|
-
manager: 'continuous',
|
|
21719
|
-
allowScriptedContent: false,
|
|
21720
|
-
width: '100%',
|
|
21721
|
-
height: '100%',
|
|
21722
|
-
flow: 'scrolled-continuous',
|
|
21723
|
-
spread: 'none',
|
|
21724
|
-
});
|
|
21800
|
+
rendition = book.renderTo(viewer, window.PapyrusEpubReader.options(epubViewMode === 'single' ? 'paged' : 'chapter-scroll'));
|
|
21725
21801
|
sendEpubDiagnostic('epub.rendition.created', diagnosticPayload);
|
|
21726
21802
|
|
|
21727
21803
|
if (rendition && rendition.hooks && rendition.hooks.content) {
|
|
21728
21804
|
const session = documentSessionId;
|
|
21729
21805
|
const activeRendition = rendition;
|
|
21730
21806
|
rendition.hooks.content.register((contents) => {
|
|
21807
|
+
const removeGestureListeners = window.PapyrusEpubReader.install(contents, {
|
|
21808
|
+
mode: () => epubViewMode === 'single' ? 'paged' : 'chapter-scroll',
|
|
21809
|
+
rtl: () => book.package?.metadata?.direction === 'rtl' || book.spine?.direction === 'rtl',
|
|
21810
|
+
blocked: () => Boolean(nativeMenuSelection && String(nativeMenuSelection.contents?.window?.getSelection() || '').trim()),
|
|
21811
|
+
annotationHit: point => epubAnnotationRenderers.get(contents)?.hit(point.x,point.y),
|
|
21812
|
+
current: () => session === documentSessionId && activeRendition === rendition,
|
|
21813
|
+
interact: () => epubResizeAnchor?.invalidate(),
|
|
21814
|
+
tap: () => sendEvent('EPUB_CONTENT_TAP',{documentSessionId:session}),
|
|
21815
|
+
turn: direction => {
|
|
21816
|
+
epubNavigationQueue = epubNavigationQueue.catch(()=>{}).then(() => {
|
|
21817
|
+
if(session !== documentSessionId || activeRendition !== rendition)return;
|
|
21818
|
+
epubResizeAnchor?.invalidate();
|
|
21819
|
+
return direction<0?activeRendition.prev():activeRendition.next();
|
|
21820
|
+
});
|
|
21821
|
+
epubNavigationQueue.catch(error => sendEvent('EPUB_NAVIGATION_ERROR',{message:String(error)}));
|
|
21822
|
+
},
|
|
21823
|
+
});
|
|
21824
|
+
const gestureCleanup = () => {removeGestureListeners();epubSelectionCleanups.delete(gestureCleanup);};
|
|
21825
|
+
epubSelectionCleanups.add(gestureCleanup);
|
|
21826
|
+
contents.__papyrusGestureCleanup=gestureCleanup;
|
|
21731
21827
|
const href = spineItems[contents.sectionIndex]?.href;
|
|
21732
21828
|
if (href && window.PapyrusEpubAnnotations) {
|
|
21733
21829
|
const renderer = window.PapyrusEpubAnnotations.install(contents, {
|
|
21734
21830
|
href, get documentId() { return annotationDocumentId; },
|
|
21735
21831
|
isCurrent: () => session === documentSessionId && activeRendition === rendition,
|
|
21832
|
+
pageWidth: () => activeRendition.layout?.width || viewer.clientWidth,
|
|
21736
21833
|
annotations: () => epubAnnotations, labels: () => annotationLabels,
|
|
21737
21834
|
onTap: (id, ids) => sendEvent("EPUB_ANNOTATION_TAP", {documentSessionId: session, id, ids}),
|
|
21738
21835
|
});
|
|
@@ -21751,8 +21848,7 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
21751
21848
|
typeof selectionWindow.getSelection === 'function'
|
|
21752
21849
|
) {
|
|
21753
21850
|
let selectionTimer = null;
|
|
21754
|
-
|
|
21755
|
-
let lastSelectionAt = 0;
|
|
21851
|
+
|
|
21756
21852
|
const reportSelection = () => {
|
|
21757
21853
|
selectionTimer = null;
|
|
21758
21854
|
if (session !== documentSessionId || activeRendition !== rendition) return;
|
|
@@ -21767,11 +21863,7 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
21767
21863
|
try { cfi = contents.cfiFromRange(range); } catch (_) { return; }
|
|
21768
21864
|
const anchor = window.PapyrusEpubAnnotations?.selection(contents, cfi, href, annotationDocumentId);
|
|
21769
21865
|
if (!anchor) return;
|
|
21770
|
-
|
|
21771
|
-
const now = Date.now();
|
|
21772
|
-
if (key === lastSelectionKey && now - lastSelectionAt < 750) return;
|
|
21773
|
-
lastSelectionKey = key;
|
|
21774
|
-
lastSelectionAt = now;
|
|
21866
|
+
if (nativeMenuSelection?.payload?.anchor?.cfiRange === anchor.cfiRange && nativeMenuSelection?.payload?.anchor?.quote === anchor.quote) return;
|
|
21775
21867
|
const payload = {documentSessionId: session, text: anchor.quote,
|
|
21776
21868
|
pageIndex: contents.sectionIndex + 1, anchor};
|
|
21777
21869
|
nativeMenuSelection = {contents, payload};
|
|
@@ -21786,6 +21878,7 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
21786
21878
|
// The content document still emits selectionchange, so resolve its
|
|
21787
21879
|
// live Range to a CFI before the native menu action can fire.
|
|
21788
21880
|
if (text) reportSelection();
|
|
21881
|
+
else if (nativeMenuSelection?.contents === contents) nativeMenuSelection = null;
|
|
21789
21882
|
};
|
|
21790
21883
|
selectionDocument.addEventListener('selectionchange', handleSelectionChange);
|
|
21791
21884
|
const selectionCleanup = () => {
|
|
@@ -21808,6 +21901,7 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
21808
21901
|
typeof rendition.hooks.unloaded.register === 'function'
|
|
21809
21902
|
) {
|
|
21810
21903
|
rendition.hooks.unloaded.register((view) => {
|
|
21904
|
+
view?.contents?.__papyrusGestureCleanup?.();
|
|
21811
21905
|
const cleanup = view && view.contents && view.contents.__papyrusSelectionCleanup;
|
|
21812
21906
|
if (typeof cleanup === 'function') cleanup();
|
|
21813
21907
|
const renderer = epubAnnotationRenderers.get(view?.contents);
|
|
@@ -21823,13 +21917,13 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
21823
21917
|
if (selectionSession !== documentSessionId || selectionRendition !== rendition) return;
|
|
21824
21918
|
const href = spineItems[contents.sectionIndex]?.href;
|
|
21825
21919
|
const anchor = href && window.PapyrusEpubAnnotations?.selection(contents,cfiRange,href,annotationDocumentId);
|
|
21826
|
-
if (!anchor) return;
|
|
21920
|
+
if (!anchor || nativeMenuSelection?.payload?.anchor?.cfiRange === anchor.cfiRange && nativeMenuSelection?.payload?.anchor?.quote === anchor.quote) return;
|
|
21827
21921
|
epubScrollDiagnostics && epubScrollDiagnostics.setSelectionActive(true);
|
|
21828
21922
|
const payload = {documentSessionId: selectionSession, text: anchor.quote, pageIndex: contents.sectionIndex+1, anchor};
|
|
21829
21923
|
nativeMenuSelection = {contents, payload};
|
|
21830
21924
|
sendEvent('EPUB_TEXT_SELECTED', payload);
|
|
21831
21925
|
});
|
|
21832
|
-
['rendered','resized','layout'].forEach(name => rendition.on(name, () => {
|
|
21926
|
+
['rendered','resized','layout','relocated'].forEach(name => rendition.on(name, () => {
|
|
21833
21927
|
if (selectionSession === documentSessionId && selectionRendition === rendition) epubAnnotationRenderers.forEach(renderer => renderer.schedule());
|
|
21834
21928
|
}));
|
|
21835
21929
|
rendition.on('relocated', (location) => {
|
|
@@ -21839,6 +21933,21 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
21839
21933
|
if (index < 0 && start && start.href) index = getSpineIndexByHref(start.href);
|
|
21840
21934
|
if (index < 0 || index >= spineItems.length) return;
|
|
21841
21935
|
epubScrollDiagnostics && epubScrollDiagnostics.relocated(location);
|
|
21936
|
+
let pageGeometry;
|
|
21937
|
+
const manager=rendition.manager,layout=manager?.layout;
|
|
21938
|
+
if(epubViewMode==='single' && layout?.divisor===1 && !manager?.settings?.fullsize && manager?.settings?.direction==='ltr'){
|
|
21939
|
+
const visible=manager.visible?.();
|
|
21940
|
+
const view=visible?.find(view=>view.index===index);
|
|
21941
|
+
if(view && manager.container){
|
|
21942
|
+
pageGeometry={direction:'ltr',firstIndex:book.spine.first()?.index,lastIndex:book.spine.last()?.index,pageWidth:layout.pageWidth,offset:manager.container.getBoundingClientRect().left-view.position().left};
|
|
21943
|
+
}
|
|
21944
|
+
}
|
|
21945
|
+
epubLocation=window.PapyrusEpubReader.location(location,spineItems.length,epubViewMode==='single'?'paged':'chapter-scroll',pageGeometry);
|
|
21946
|
+
if(epubLocation){
|
|
21947
|
+
epubLocation.cfi=epubResizeAnchor?.cfi() || epubLocation.cfi;
|
|
21948
|
+
if(book.locations?.length?.()>0)epubLocation.progress=book.locations.percentageFromCfi(epubLocation.cfi);
|
|
21949
|
+
sendEvent('EPUB_LOCATION',{documentSessionId,location:epubLocation});
|
|
21950
|
+
}
|
|
21842
21951
|
const nextPage = index + 1;
|
|
21843
21952
|
if (nextPage === currentPage) return;
|
|
21844
21953
|
currentPage = nextPage;
|
|
@@ -21846,21 +21955,23 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
21846
21955
|
});
|
|
21847
21956
|
}
|
|
21848
21957
|
|
|
21958
|
+
applyEpubZoom();
|
|
21849
21959
|
sendEpubDiagnostic('epub.display.start', diagnosticPayload);
|
|
21850
21960
|
await withEpubStageTimeout(
|
|
21851
|
-
|
|
21961
|
+
rendition.display(target || spineItems[0]?.href),
|
|
21852
21962
|
'rendition.display',
|
|
21853
21963
|
diagnosticPayload,
|
|
21854
21964
|
);
|
|
21855
21965
|
if (!isCurrentLoad()) throw new Error('EPUB load superseded by a newer load');
|
|
21856
21966
|
sendEpubDiagnostic('epub.display.end', diagnosticPayload);
|
|
21967
|
+
const resizeRendition=rendition;
|
|
21968
|
+
epubResizeAnchor=window.PapyrusEpubReader.installResizeAnchor(resizeRendition.manager,()=>resizeRendition.location?.start?.cfi);
|
|
21857
21969
|
if (
|
|
21858
21970
|
rendition &&
|
|
21859
21971
|
rendition.manager &&
|
|
21860
21972
|
typeof rendition.manager.on === 'function' &&
|
|
21861
21973
|
typeof rendition.on === 'function'
|
|
21862
21974
|
) {
|
|
21863
|
-
let touchStart = null;
|
|
21864
21975
|
let lastScrollOffset = -1;
|
|
21865
21976
|
const manager = rendition.manager;
|
|
21866
21977
|
epubScrollDiagnostics = createEpubScrollDiagnostics(manager);
|
|
@@ -21935,57 +22046,19 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
21935
22046
|
return result;
|
|
21936
22047
|
};
|
|
21937
22048
|
}
|
|
21938
|
-
const
|
|
21939
|
-
const touch =
|
|
21940
|
-
(event && event.changedTouches && event.changedTouches[0]) ||
|
|
21941
|
-
(event && event.touches && event.touches[0]);
|
|
21942
|
-
if (!touch) return null;
|
|
21943
|
-
const x = Number(touch.screenX ?? touch.clientX);
|
|
21944
|
-
const y = Number(touch.screenY ?? touch.clientY);
|
|
21945
|
-
return Number.isFinite(x) && Number.isFinite(y) ? { x, y } : null;
|
|
21946
|
-
};
|
|
21947
|
-
const handleScroll = (event) => {
|
|
22049
|
+
const handleScroll = event => {
|
|
21948
22050
|
const offsetY = Math.max(0, Number(event && event.top) || 0);
|
|
21949
22051
|
epubScrollDiagnostics && epubScrollDiagnostics.scroll(event);
|
|
21950
|
-
if (Math.abs(offsetY
|
|
21951
|
-
lastScrollOffset
|
|
21952
|
-
sendEvent('VIEWER_SCROLL',
|
|
22052
|
+
if (Math.abs(offsetY-lastScrollOffset)<1) return;
|
|
22053
|
+
lastScrollOffset=offsetY;
|
|
22054
|
+
sendEvent('VIEWER_SCROLL',{offsetY});
|
|
21953
22055
|
};
|
|
21954
|
-
const handleTouchStart = (event) => {
|
|
21955
|
-
touchStart = event?.touches?.length > 1 ? null : getTouchPoint(event);
|
|
21956
|
-
epubScrollDiagnostics && epubScrollDiagnostics.touchStart(event);
|
|
21957
|
-
};
|
|
21958
|
-
const handleTouchMove = (event) => {
|
|
21959
|
-
if (event?.touches?.length > 1) touchStart = null;
|
|
21960
|
-
epubScrollDiagnostics && epubScrollDiagnostics.touchMove(event);
|
|
21961
|
-
};
|
|
21962
|
-
const handleTouchEnd = (event) => {
|
|
21963
|
-
const end = getTouchPoint(event);
|
|
21964
|
-
const start = touchStart;
|
|
21965
|
-
touchStart = null;
|
|
21966
|
-
const selectedText = event?.target?.ownerDocument?.defaultView?.getSelection?.()?.toString().trim() || '';
|
|
21967
|
-
if (!selectedText && start && end && epubViewMode === 'single' && Math.abs(end.x-start.x) >= 48 && Math.abs(end.x-start.x) > Math.abs(end.y-start.y)*1.5) {
|
|
21968
|
-
const active = rendition;
|
|
21969
|
-
const interactionSession = documentSessionId;
|
|
21970
|
-
epubNavigationQueue = epubNavigationQueue.catch(() => {}).then(() => {
|
|
21971
|
-
if (active !== rendition || interactionSession !== documentSessionId) return;
|
|
21972
|
-
return end.x < start.x ? active.next() : active.prev();
|
|
21973
|
-
});
|
|
21974
|
-
epubNavigationQueue.catch(error => sendEvent('EPUB_NAVIGATION_ERROR', {message:String(error)}));
|
|
21975
|
-
} else if (!selectedText && start && end && Math.hypot(end.x - start.x, end.y - start.y) <= 12) {
|
|
21976
|
-
sendEvent('VIEWER_TAP', {});
|
|
21977
|
-
}
|
|
21978
|
-
epubScrollDiagnostics && epubScrollDiagnostics.touchEnd(event);
|
|
21979
|
-
};
|
|
21980
|
-
|
|
21981
22056
|
manager.on('scroll', handleScroll);
|
|
21982
22057
|
const handleScrolled = (event) => {
|
|
21983
22058
|
epubScrollDiagnostics && epubScrollDiagnostics.settled(event);
|
|
21984
22059
|
};
|
|
21985
22060
|
manager.on('scrolled', handleScrolled);
|
|
21986
|
-
|
|
21987
|
-
rendition.on('touchmove', handleTouchMove);
|
|
21988
|
-
rendition.on('touchend', handleTouchEnd);
|
|
22061
|
+
|
|
21989
22062
|
epubInteractionCleanup = () => {
|
|
21990
22063
|
epubSelectionCleanups.forEach((cleanup) => cleanup());
|
|
21991
22064
|
epubSelectionCleanups.clear();
|
|
@@ -21994,16 +22067,9 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
21994
22067
|
if (originalEnqueue) queue.enqueue = originalEnqueue;
|
|
21995
22068
|
if (typeof manager.off === 'function') manager.off('scroll', handleScroll);
|
|
21996
22069
|
if (typeof manager.off === 'function') manager.off('scrolled', handleScrolled);
|
|
21997
|
-
if (typeof rendition.off === 'function') {
|
|
21998
|
-
rendition.off('touchstart', handleTouchStart);
|
|
21999
|
-
rendition.off('touchmove', handleTouchMove);
|
|
22000
|
-
rendition.off('touchend', handleTouchEnd);
|
|
22001
|
-
}
|
|
22002
22070
|
epubScrollDiagnostics = null;
|
|
22003
22071
|
};
|
|
22004
22072
|
}
|
|
22005
|
-
applyEpubZoom();
|
|
22006
|
-
|
|
22007
22073
|
const outline = await withEpubStageTimeout(
|
|
22008
22074
|
buildOutline(),
|
|
22009
22075
|
'outline',
|
|
@@ -22033,6 +22099,7 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
22033
22099
|
const request = ++epubNavigationRequest;
|
|
22034
22100
|
const navigation = epubNavigationQueue.catch(() => {}).then(async () => {
|
|
22035
22101
|
if (request !== epubNavigationRequest || session !== documentSessionId || activeRendition !== rendition) return;
|
|
22102
|
+
epubResizeAnchor?.invalidate();
|
|
22036
22103
|
await activeRendition.display(target);
|
|
22037
22104
|
if (request !== epubNavigationRequest || session !== documentSessionId || activeRendition !== rendition) return;
|
|
22038
22105
|
currentPage = pageIndex + 1;
|
|
@@ -22141,7 +22208,8 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
22141
22208
|
};
|
|
22142
22209
|
|
|
22143
22210
|
let nativeMenuSelection = null;
|
|
22144
|
-
let epubViewMode = "
|
|
22211
|
+
let epubViewMode = "single";
|
|
22212
|
+
let epubLocation = null;
|
|
22145
22213
|
|
|
22146
22214
|
const handleCommand = async (message) => {
|
|
22147
22215
|
const { id, kind, payload } = message;
|
|
@@ -22154,7 +22222,9 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
22154
22222
|
epubAnnotations = [];
|
|
22155
22223
|
annotationDocumentId = undefined;
|
|
22156
22224
|
zoom = 1.0;
|
|
22157
|
-
epubViewMode = "continuous";
|
|
22225
|
+
epubViewMode = payload.epubMode === "chapter-scroll" ? "continuous" : "single";
|
|
22226
|
+
epubLocation = null;
|
|
22227
|
+
nativeMenuSelection = null;
|
|
22158
22228
|
epubNavigationRequest += 1;
|
|
22159
22229
|
epubNavigationQueue = Promise.resolve();
|
|
22160
22230
|
|
|
@@ -22219,6 +22289,7 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
22219
22289
|
epubNavigationRequest += 1;
|
|
22220
22290
|
const navigation = epubNavigationQueue.catch(() => {}).then(async () => {
|
|
22221
22291
|
if(navigationSession !== documentSessionId || activeRendition !== rendition)throw new Error('Stale EPUB navigation');
|
|
22292
|
+
epubResizeAnchor?.invalidate();
|
|
22222
22293
|
await activeRendition.display(annotation.anchor.href);
|
|
22223
22294
|
if(navigationSession !== documentSessionId || activeRendition !== rendition)throw new Error('Stale EPUB navigation');
|
|
22224
22295
|
const contents = activeRendition.getContents().find(c => spineItems[c.sectionIndex]?.href === annotation.anchor.href);
|
|
@@ -22260,6 +22331,7 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
22260
22331
|
const active = rendition;
|
|
22261
22332
|
epubNavigationQueue = epubNavigationQueue.catch(() => {}).then(() => {
|
|
22262
22333
|
if (active !== rendition || payload.documentSessionId !== documentSessionId) return;
|
|
22334
|
+
epubResizeAnchor?.invalidate();
|
|
22263
22335
|
return payload.direction < 0 ? active.prev() : active.next();
|
|
22264
22336
|
});
|
|
22265
22337
|
await epubNavigationQueue;
|
|
@@ -22268,25 +22340,40 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
22268
22340
|
|
|
22269
22341
|
if (kind === 'set-epub-view-mode') {
|
|
22270
22342
|
if (currentType !== 'epub' || payload.documentSessionId !== documentSessionId) throw new Error('Stale EPUB layout session');
|
|
22271
|
-
|
|
22272
|
-
|
|
22273
|
-
|
|
22274
|
-
|
|
22275
|
-
|
|
22276
|
-
|
|
22277
|
-
|
|
22278
|
-
|
|
22279
|
-
|
|
22280
|
-
|
|
22281
|
-
sendResponse(id,true,null);
|
|
22343
|
+
const next=payload.epubMode ? (payload.epubMode==='paged'?'single':'continuous') : (payload.viewMode==='single'?'single':'continuous');
|
|
22344
|
+
{
|
|
22345
|
+
epubNavigationQueue=epubNavigationQueue.catch(()=>{}).then(async()=>{
|
|
22346
|
+
if(payload.documentSessionId!==documentSessionId || next===epubViewMode)return;
|
|
22347
|
+
const target=epubResizeAnchor?.cfi() || epubLocation?.cfi;
|
|
22348
|
+
epubViewMode=next;
|
|
22349
|
+
await renderEpubRendition('layout',epubLoadGeneration,target);
|
|
22350
|
+
});
|
|
22351
|
+
await epubNavigationQueue;
|
|
22352
|
+
}
|
|
22353
|
+
sendResponse(id,true,null);return;
|
|
22354
|
+
}
|
|
22355
|
+
if(kind === 'epub-go-to-location'){
|
|
22356
|
+
if(currentType!=='epub' || payload.documentSessionId!==documentSessionId || !window.PapyrusEpubReader.validCfi(payload.cfi))throw new Error('Invalid EPUB location');
|
|
22357
|
+
epubNavigationQueue=epubNavigationQueue.catch(()=>{}).then(()=>{if(payload.documentSessionId!==documentSessionId)return;epubResizeAnchor?.invalidate();return rendition.display(payload.cfi);});
|
|
22358
|
+
await epubNavigationQueue;sendResponse(id,true,null);return;
|
|
22282
22359
|
}
|
|
22283
22360
|
|
|
22284
22361
|
if (kind === 'set-zoom') {
|
|
22285
|
-
|
|
22286
|
-
|
|
22287
|
-
|
|
22288
|
-
|
|
22289
|
-
|
|
22362
|
+
const requestedZoom=Math.max(0.5,Math.min(4.0,payload.zoom || 1.0));
|
|
22363
|
+
if(currentType === 'epub') {
|
|
22364
|
+
const session=documentSessionId;
|
|
22365
|
+
epubNavigationQueue=epubNavigationQueue.catch(()=>{}).then(async()=>{
|
|
22366
|
+
if(session!==documentSessionId)return;
|
|
22367
|
+
const active=rendition;
|
|
22368
|
+
const cfi=epubResizeAnchor?.cfi() || epubLocation?.cfi;
|
|
22369
|
+
zoom=requestedZoom;applyEpubZoom();
|
|
22370
|
+
// Let the content CSS update before redisplaying the logical anchor.
|
|
22371
|
+
await new Promise(resolve=>(window.requestAnimationFrame || (callback=>setTimeout(callback,0)))(resolve));
|
|
22372
|
+
if(cfi && active===rendition && session===documentSessionId)await active.display(cfi);
|
|
22373
|
+
});
|
|
22374
|
+
await epubNavigationQueue;
|
|
22375
|
+
} else {zoom=requestedZoom;applyZoom();}
|
|
22376
|
+
sendState();sendResponse(id,true,{zoom});return;
|
|
22290
22377
|
}
|
|
22291
22378
|
|
|
22292
22379
|
if (kind === 'set-rotation') {
|
|
@@ -23449,6 +23536,7 @@ var IconToolStrikeout = ({
|
|
|
23449
23536
|
),
|
|
23450
23537
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native_svg.Rect, { x: "10.9", y: "17.1", width: "14.2", height: "2.4", rx: "1.2", fill: color })
|
|
23451
23538
|
] });
|
|
23539
|
+
var IconStrikeout = ({ size = 22, color = defaultColor, strokeWidth = 1.8 }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native_svg.default, { width: size, height: size, viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native_svg.Path, { d: "M17 5c-1-1-3-2-5-2-3 0-5 2-5 4 0 2 2 3 5 4M17 15c0 2-2 4-5 4-2 0-4-1-5-2M4 12h16", stroke: color, strokeWidth, strokeLinecap: "round", strokeLinejoin: "round" }) });
|
|
23452
23540
|
var IconCopy = ({
|
|
23453
23541
|
size = 20,
|
|
23454
23542
|
color = defaultColor,
|
|
@@ -23513,6 +23601,39 @@ var IconToolNote = ({
|
|
|
23513
23601
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native_svg.Line, { x1: "15", y1: "14.8", x2: "21.6", y2: "14.8", stroke: color, strokeWidth: "1.8", strokeLinecap: "round" }),
|
|
23514
23602
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native_svg.Line, { x1: "15", y1: "18.2", x2: "19.2", y2: "18.2", stroke: color, strokeWidth: "1.8", strokeLinecap: "round" })
|
|
23515
23603
|
] });
|
|
23604
|
+
var IconHighlight = ({
|
|
23605
|
+
size = 24,
|
|
23606
|
+
color = "#fbbf24"
|
|
23607
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native_svg.default, { width: size, height: size, viewBox: "0 0 24 24", fill: "none", children: [
|
|
23608
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
23609
|
+
import_react_native_svg.Path,
|
|
23610
|
+
{
|
|
23611
|
+
d: "M4 15h16v3a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1v-3Z",
|
|
23612
|
+
fill: color,
|
|
23613
|
+
opacity: "0.85"
|
|
23614
|
+
}
|
|
23615
|
+
),
|
|
23616
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
23617
|
+
import_react_native_svg.Path,
|
|
23618
|
+
{
|
|
23619
|
+
d: "M6 5h12v10H6V5Z",
|
|
23620
|
+
stroke: color,
|
|
23621
|
+
strokeWidth: "2",
|
|
23622
|
+
strokeLinecap: "round",
|
|
23623
|
+
strokeLinejoin: "round",
|
|
23624
|
+
fill: "none"
|
|
23625
|
+
}
|
|
23626
|
+
),
|
|
23627
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
23628
|
+
import_react_native_svg.Path,
|
|
23629
|
+
{
|
|
23630
|
+
d: "M8 8h8M8 11h5",
|
|
23631
|
+
stroke: color,
|
|
23632
|
+
strokeWidth: "2",
|
|
23633
|
+
strokeLinecap: "round"
|
|
23634
|
+
}
|
|
23635
|
+
)
|
|
23636
|
+
] });
|
|
23516
23637
|
var IconUnderline = ({
|
|
23517
23638
|
size = 24,
|
|
23518
23639
|
color = "#60a5fa",
|
|
@@ -25941,8 +26062,38 @@ var styles = import_react_native.StyleSheet.create({
|
|
|
25941
26062
|
var arePageRendererPropsEqual = (previous, next) => previous.documentId === next.documentId && previous.engine === next.engine && previous.pageIndex === next.pageIndex && previous.scale === next.scale && previous.PageViewComponent === next.PageViewComponent && previous.availableWidth === next.availableWidth && previous.maxPageWidth === next.maxPageWidth && previous.maxPageHeight === next.maxPageHeight && previous.pageViewportWidth === next.pageViewportWidth && previous.horizontalPadding === next.horizontalPadding && previous.spacing === next.spacing && previous.onSelectionDragActiveChange === next.onSelectionDragActiveChange && previous.gestureScrollLockActive === next.gestureScrollLockActive && previous.lastPinchEndedAt === next.lastPinchEndedAt && previous.requestSelectionVerticalAutoscroll === next.requestSelectionVerticalAutoscroll;
|
|
25942
26063
|
var PageRenderer_default = (0, import_react2.memo)(PageRenderer, arePageRendererPropsEqual);
|
|
25943
26064
|
|
|
26065
|
+
// components/PapyrusSafeArea.tsx
|
|
26066
|
+
var import_react3 = __toESM(require("react"));
|
|
26067
|
+
var import_react_native_safe_area_context = require("react-native-safe-area-context");
|
|
26068
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
26069
|
+
var papyrusSafeAreaContext = import_react_native_safe_area_context.SafeAreaInsetsContext;
|
|
26070
|
+
var ZERO_SAFE_AREA_INSETS = {
|
|
26071
|
+
top: 0,
|
|
26072
|
+
bottom: 0,
|
|
26073
|
+
left: 0,
|
|
26074
|
+
right: 0
|
|
26075
|
+
};
|
|
26076
|
+
var usePapyrusSafeAreaInsets = () => (0, import_react3.useContext)(papyrusSafeAreaContext) ?? ZERO_SAFE_AREA_INSETS;
|
|
26077
|
+
function PapyrusSafeAreaBoundary({
|
|
26078
|
+
children
|
|
26079
|
+
}) {
|
|
26080
|
+
const insets = (0, import_react3.useContext)(papyrusSafeAreaContext);
|
|
26081
|
+
if (insets) return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_jsx_runtime4.Fragment, { children });
|
|
26082
|
+
return import_react3.default.createElement(import_react_native_safe_area_context.SafeAreaProvider, null, children);
|
|
26083
|
+
}
|
|
26084
|
+
|
|
26085
|
+
// components/epubReadingLocation.ts
|
|
26086
|
+
function parseEpubReadingLocation(raw) {
|
|
26087
|
+
if (!raw || typeof raw !== "object") return null;
|
|
26088
|
+
const p = raw;
|
|
26089
|
+
if (p.version !== 1 || typeof p.cfi !== "string" || p.cfi.length > 4096 || !/^epubcfi\([^\n<>]+\)$/.test(p.cfi) || typeof p.href !== "string" || !Number.isSafeInteger(p.chapter) || p.chapter < 1 || !Number.isSafeInteger(p.chapterCount) || p.chapterCount < p.chapter || !Number.isFinite(p.progress) || p.progress < 0 || p.progress > 1 || typeof p.atStart !== "boolean" || typeof p.atEnd !== "boolean") return null;
|
|
26090
|
+
if (p.mode === "chapter-scroll") return p.visualPage === null && p.visualPageCount === null ? p : null;
|
|
26091
|
+
if (p.mode !== "paged" || !Number.isSafeInteger(p.visualPage) || (p.visualPage ?? 0) < 1 || !Number.isSafeInteger(p.visualPageCount) || (p.visualPageCount ?? 0) < (p.visualPage ?? 0)) return null;
|
|
26092
|
+
return p;
|
|
26093
|
+
}
|
|
26094
|
+
|
|
25944
26095
|
// components/WebViewViewer.tsx
|
|
25945
|
-
var
|
|
26096
|
+
var import_react4 = require("react");
|
|
25946
26097
|
var import_react_native2 = require("react-native");
|
|
25947
26098
|
var import_clipboard3 = __toESM(require("@react-native-clipboard/clipboard"));
|
|
25948
26099
|
var import_react_native_webview = __toESM(require("react-native-webview"));
|
|
@@ -26010,7 +26161,7 @@ function parseEpubAnnotationEvent(raw, session, documentId) {
|
|
|
26010
26161
|
}
|
|
26011
26162
|
|
|
26012
26163
|
// components/WebViewViewer.tsx
|
|
26013
|
-
var
|
|
26164
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
26014
26165
|
var runtimeAsset = require_runtime();
|
|
26015
26166
|
var resolveRuntimeSource = (asset) => {
|
|
26016
26167
|
if (typeof asset === "string") {
|
|
@@ -26030,6 +26181,7 @@ var resolveRuntimeSource = (asset) => {
|
|
|
26030
26181
|
};
|
|
26031
26182
|
var WebViewViewer = ({
|
|
26032
26183
|
engine,
|
|
26184
|
+
documentType,
|
|
26033
26185
|
documentId,
|
|
26034
26186
|
onDefineSelection,
|
|
26035
26187
|
defineSelectionMode,
|
|
@@ -26037,19 +26189,20 @@ var WebViewViewer = ({
|
|
|
26037
26189
|
onScrollOffset,
|
|
26038
26190
|
onTap
|
|
26039
26191
|
}) => {
|
|
26040
|
-
const webViewRef = (0,
|
|
26041
|
-
const
|
|
26042
|
-
const
|
|
26192
|
+
const webViewRef = (0, import_react4.useRef)(null);
|
|
26193
|
+
const insets = usePapyrusSafeAreaInsets();
|
|
26194
|
+
const { pageTheme, epubReadingMode, setDocumentState, annotations, isLoaded, locale, annotationColor, annotationOpacity, addAnnotation, beginAnnotationDraft, setSelectedAnnotation } = (0, import_core4.useViewerStore)();
|
|
26195
|
+
const [selection, setSelection] = (0, import_react4.useState)(null);
|
|
26043
26196
|
const t = getStrings(locale);
|
|
26044
26197
|
const bridgeEngine = engine;
|
|
26045
|
-
const runtimeSource = (0,
|
|
26198
|
+
const runtimeSource = (0, import_react4.useMemo)(
|
|
26046
26199
|
() => resolveRuntimeSource(
|
|
26047
26200
|
bridgeEngine.getWebViewRuntimeSource?.() ?? runtimeAsset
|
|
26048
26201
|
),
|
|
26049
26202
|
[bridgeEngine]
|
|
26050
26203
|
);
|
|
26051
|
-
const [runtimeHtml, setRuntimeHtml] = (0,
|
|
26052
|
-
(0,
|
|
26204
|
+
const [runtimeHtml, setRuntimeHtml] = (0, import_react4.useState)(null);
|
|
26205
|
+
(0, import_react4.useEffect)(() => {
|
|
26053
26206
|
let active = true;
|
|
26054
26207
|
if ("html" in runtimeSource) {
|
|
26055
26208
|
setRuntimeHtml(runtimeSource.html);
|
|
@@ -26070,7 +26223,7 @@ var WebViewViewer = ({
|
|
|
26070
26223
|
active = false;
|
|
26071
26224
|
};
|
|
26072
26225
|
}, [runtimeSource]);
|
|
26073
|
-
const webViewSource = (0,
|
|
26226
|
+
const webViewSource = (0, import_react4.useMemo)(() => {
|
|
26074
26227
|
if (runtimeHtml !== null) {
|
|
26075
26228
|
return {
|
|
26076
26229
|
html: runtimeHtml,
|
|
@@ -26081,13 +26234,13 @@ var WebViewViewer = ({
|
|
|
26081
26234
|
return runtimeSource;
|
|
26082
26235
|
}, [runtimeHtml, runtimeSource]);
|
|
26083
26236
|
const runtimeConfig = bridgeEngine.getWebViewRuntimeConfig?.();
|
|
26084
|
-
const runtimeConfigScript = (0,
|
|
26237
|
+
const runtimeConfigScript = (0, import_react4.useMemo)(() => {
|
|
26085
26238
|
if (!runtimeConfig) return void 0;
|
|
26086
26239
|
return `window.__PAPYRUS_RUNTIME_CONFIG__=${JSON.stringify(
|
|
26087
26240
|
runtimeConfig
|
|
26088
26241
|
)};true;`;
|
|
26089
26242
|
}, [runtimeConfig]);
|
|
26090
|
-
(0,
|
|
26243
|
+
(0, import_react4.useEffect)(() => {
|
|
26091
26244
|
bridgeEngine.attachWebView?.({
|
|
26092
26245
|
postMessage: (message) => {
|
|
26093
26246
|
if (__DEV__) {
|
|
@@ -26101,10 +26254,10 @@ var WebViewViewer = ({
|
|
|
26101
26254
|
bridgeEngine.detachWebView?.();
|
|
26102
26255
|
};
|
|
26103
26256
|
}, [bridgeEngine]);
|
|
26104
|
-
(0,
|
|
26257
|
+
(0, import_react4.useEffect)(() => {
|
|
26105
26258
|
setSelection(null);
|
|
26106
26259
|
}, [engine, documentId]);
|
|
26107
|
-
(0,
|
|
26260
|
+
(0, import_react4.useEffect)(() => {
|
|
26108
26261
|
if (!isLoaded) return;
|
|
26109
26262
|
let active = true;
|
|
26110
26263
|
void bridgeEngine.syncEpubAnnotations?.(annotations, documentId, { comment: t.annotationNote }).catch(() => {
|
|
@@ -26119,10 +26272,10 @@ var WebViewViewer = ({
|
|
|
26119
26272
|
(note !== void 0 ? beginAnnotationDraft : addAnnotation)((0, import_core4.createContextualAnnotation)({ id: `annotation-${Date.now()}-${Math.random().toString(36).slice(2)}`, anchor: selected.anchor, pageIndex: selected.pageIndex, style, color: annotationColor, opacity: annotationOpacity, note }));
|
|
26120
26273
|
setSelection(null);
|
|
26121
26274
|
};
|
|
26122
|
-
(0,
|
|
26275
|
+
(0, import_react4.useEffect)(() => {
|
|
26123
26276
|
if (!isLoaded) return;
|
|
26124
|
-
webViewRef.current?.postMessage(JSON.stringify({ id: "epub-layout", kind: "set-epub-view-mode", payload: {
|
|
26125
|
-
}, [isLoaded,
|
|
26277
|
+
webViewRef.current?.postMessage(JSON.stringify({ id: "epub-layout", kind: "set-epub-view-mode", payload: { epubMode: epubReadingMode, documentSessionId: bridgeEngine.getWebViewDocumentSessionId?.() } }));
|
|
26278
|
+
}, [isLoaded, epubReadingMode, bridgeEngine]);
|
|
26126
26279
|
const sendSelectionCommand = (key) => {
|
|
26127
26280
|
webViewRef.current?.postMessage(JSON.stringify({
|
|
26128
26281
|
type: "epub-selection-action",
|
|
@@ -26146,6 +26299,11 @@ var WebViewViewer = ({
|
|
|
26146
26299
|
let annotationRaw = raw;
|
|
26147
26300
|
try {
|
|
26148
26301
|
const message = JSON.parse(raw);
|
|
26302
|
+
if (message.type === "event" && message.name === "EPUB_LOCATION" && message.payload?.documentSessionId === bridgeEngine.getWebViewDocumentSessionId?.()) {
|
|
26303
|
+
const location = parseEpubReadingLocation(message.payload.location);
|
|
26304
|
+
if (location) setDocumentState({ epubLocation: location });
|
|
26305
|
+
}
|
|
26306
|
+
if (message.type === "event" && message.name === "EPUB_CONTENT_TAP" && message.payload?.documentSessionId === bridgeEngine.getWebViewDocumentSessionId?.()) onTap?.();
|
|
26149
26307
|
if (message.type === "event" && message.name === "EPUB_SELECTION_ACTION") {
|
|
26150
26308
|
action = message.payload?.action;
|
|
26151
26309
|
annotationRaw = JSON.stringify({ ...message, name: "EPUB_TEXT_SELECTED" });
|
|
@@ -26209,7 +26367,7 @@ var WebViewViewer = ({
|
|
|
26209
26367
|
console.warn("[Papyrus WebView] error", event.nativeEvent);
|
|
26210
26368
|
}
|
|
26211
26369
|
};
|
|
26212
|
-
const themeOverlayStyle = (0,
|
|
26370
|
+
const themeOverlayStyle = (0, import_react4.useMemo)(() => {
|
|
26213
26371
|
switch (pageTheme) {
|
|
26214
26372
|
case "sepia":
|
|
26215
26373
|
return styles2.themeSepia;
|
|
@@ -26221,7 +26379,7 @@ var WebViewViewer = ({
|
|
|
26221
26379
|
return styles2.themeNone;
|
|
26222
26380
|
}
|
|
26223
26381
|
}, [pageTheme]);
|
|
26224
|
-
const allowingReadAccessToURL = (0,
|
|
26382
|
+
const allowingReadAccessToURL = (0, import_react4.useMemo)(() => {
|
|
26225
26383
|
if (!runtimeSource || typeof runtimeSource !== "object") return void 0;
|
|
26226
26384
|
if ("uri" in runtimeSource && runtimeSource.uri) {
|
|
26227
26385
|
return runtimeSource.uri;
|
|
@@ -26234,8 +26392,8 @@ var WebViewViewer = ({
|
|
|
26234
26392
|
maxWidth: resolvedMaxPageWidth,
|
|
26235
26393
|
alignSelf: "center"
|
|
26236
26394
|
} : void 0;
|
|
26237
|
-
return /* @__PURE__ */ (0,
|
|
26238
|
-
/* @__PURE__ */ (0,
|
|
26395
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native2.View, { style: [styles2.container, documentType === "epub" && { paddingTop: insets.top, paddingBottom: insets.bottom }], children: [
|
|
26396
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
26239
26397
|
import_react_native_webview.default,
|
|
26240
26398
|
{
|
|
26241
26399
|
ref: webViewRef,
|
|
@@ -26259,7 +26417,7 @@ var WebViewViewer = ({
|
|
|
26259
26417
|
style: [styles2.webview, cappedWebViewStyle]
|
|
26260
26418
|
}
|
|
26261
26419
|
),
|
|
26262
|
-
/* @__PURE__ */ (0,
|
|
26420
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
26263
26421
|
import_react_native2.View,
|
|
26264
26422
|
{
|
|
26265
26423
|
pointerEvents: "none",
|
|
@@ -26361,22 +26519,22 @@ function getNearbyPdfNotes(annotations, id) {
|
|
|
26361
26519
|
// components/PdfNoteChooser.tsx
|
|
26362
26520
|
var import_react_native3 = require("react-native");
|
|
26363
26521
|
var import_core5 = require("@papyrus-sdk/core");
|
|
26364
|
-
var
|
|
26522
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
26365
26523
|
function PdfNoteChooser({ notes, title, cancel, onSelect, onClose }) {
|
|
26366
|
-
return /* @__PURE__ */ (0,
|
|
26367
|
-
/* @__PURE__ */ (0,
|
|
26368
|
-
/* @__PURE__ */ (0,
|
|
26524
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native3.Modal, { visible: notes.length > 1, transparent: true, animationType: "none", onRequestClose: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native3.View, { style: styles3.backdrop, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_native3.View, { style: styles3.sheet, accessibilityViewIsModal: true, children: [
|
|
26525
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native3.Text, { style: styles3.title, children: title }),
|
|
26526
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native3.FlatList, { data: notes, keyExtractor: (a) => a.id, renderItem: ({ item, index }) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native3.Pressable, { accessibilityRole: "button", style: styles3.row, onPress: () => onSelect(item.id), children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_native3.Text, { children: [
|
|
26369
26527
|
index + 1,
|
|
26370
26528
|
". ",
|
|
26371
26529
|
(0, import_core5.getAnnotationNote)(item) || (0, import_core5.getAnnotationQuote)(item)
|
|
26372
26530
|
] }) }) }),
|
|
26373
|
-
/* @__PURE__ */ (0,
|
|
26531
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native3.Pressable, { accessibilityRole: "button", style: styles3.row, onPress: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native3.Text, { children: cancel }) })
|
|
26374
26532
|
] }) }) });
|
|
26375
26533
|
}
|
|
26376
26534
|
var styles3 = import_react_native3.StyleSheet.create({ backdrop: { flex: 1, backgroundColor: "#0008", justifyContent: "center", padding: 24 }, sheet: { backgroundColor: "#fff", borderRadius: 16, padding: 16, maxHeight: "75%" }, title: { fontSize: 18, fontWeight: "600", marginBottom: 12 }, row: { minHeight: 44, padding: 12 } });
|
|
26377
26535
|
|
|
26378
26536
|
// components/DedicatedAndroidPdfViewer.tsx
|
|
26379
|
-
var
|
|
26537
|
+
var import_react5 = require("react");
|
|
26380
26538
|
var import_react_native4 = require("react-native");
|
|
26381
26539
|
var import_core6 = require("@papyrus-sdk/core");
|
|
26382
26540
|
var import_engine_native2 = require("@papyrus-sdk/engine-native");
|
|
@@ -26397,7 +26555,7 @@ var resolvePageTapChromeVisibility = ({
|
|
|
26397
26555
|
};
|
|
26398
26556
|
|
|
26399
26557
|
// components/DedicatedAndroidPdfViewer.tsx
|
|
26400
|
-
var
|
|
26558
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
26401
26559
|
var TEXT_MARKUP_TOOLS2 = /* @__PURE__ */ new Set(["highlight", "underline", "squiggly", "strikeout"]);
|
|
26402
26560
|
var MOBILE_CHROME_HIDE_DELTA = 28;
|
|
26403
26561
|
var MOBILE_CHROME_SHOW_DELTA = 22;
|
|
@@ -26426,7 +26584,7 @@ function DedicatedAndroidPdfViewer({
|
|
|
26426
26584
|
const searchResults = (0, import_core6.useViewerStore)((state) => state.searchResults);
|
|
26427
26585
|
const annotationNavigationRequest = (0, import_core6.useViewerStore)((state) => state.annotationNavigationRequest);
|
|
26428
26586
|
const annotations = (0, import_core6.useViewerStore)((state) => state.annotations);
|
|
26429
|
-
const [pendingNotes, setPendingNotes] = (0,
|
|
26587
|
+
const [pendingNotes, setPendingNotes] = (0, import_react5.useState)([]);
|
|
26430
26588
|
const handleAnnotationTap = (id) => {
|
|
26431
26589
|
const nearby = getNearbyPdfNotes(annotations, id);
|
|
26432
26590
|
if (nearby.length < 2) {
|
|
@@ -26454,30 +26612,30 @@ function DedicatedAndroidPdfViewer({
|
|
|
26454
26612
|
maxWidth: resolvedMaxPageWidth,
|
|
26455
26613
|
alignSelf: "center"
|
|
26456
26614
|
} : void 0;
|
|
26457
|
-
const [selection, setSelection] = (0,
|
|
26458
|
-
const selectionRef = (0,
|
|
26459
|
-
const lastVisiblePagesKeyRef = (0,
|
|
26460
|
-
const lastScrollOffsetYRef = (0,
|
|
26461
|
-
const scrollDownAccumRef = (0,
|
|
26462
|
-
const scrollUpAccumRef = (0,
|
|
26463
|
-
const pendingChromeShowTimeoutRef = (0,
|
|
26464
|
-
const chromeVisibleRef = (0,
|
|
26465
|
-
const lastZoomChangedAtRef = (0,
|
|
26466
|
-
(0,
|
|
26615
|
+
const [selection, setSelection] = (0, import_react5.useState)(null);
|
|
26616
|
+
const selectionRef = (0, import_react5.useRef)(null);
|
|
26617
|
+
const lastVisiblePagesKeyRef = (0, import_react5.useRef)("");
|
|
26618
|
+
const lastScrollOffsetYRef = (0, import_react5.useRef)(0);
|
|
26619
|
+
const scrollDownAccumRef = (0, import_react5.useRef)(0);
|
|
26620
|
+
const scrollUpAccumRef = (0, import_react5.useRef)(0);
|
|
26621
|
+
const pendingChromeShowTimeoutRef = (0, import_react5.useRef)(null);
|
|
26622
|
+
const chromeVisibleRef = (0, import_react5.useRef)(true);
|
|
26623
|
+
const lastZoomChangedAtRef = (0, import_react5.useRef)(null);
|
|
26624
|
+
(0, import_react5.useEffect)(() => {
|
|
26467
26625
|
chromeVisibleRef.current = mobileChromeVisible;
|
|
26468
26626
|
}, [mobileChromeVisible]);
|
|
26469
|
-
const clearPendingChromeShow = (0,
|
|
26627
|
+
const clearPendingChromeShow = (0, import_react5.useCallback)(() => {
|
|
26470
26628
|
if (pendingChromeShowTimeoutRef.current) {
|
|
26471
26629
|
clearTimeout(pendingChromeShowTimeoutRef.current);
|
|
26472
26630
|
pendingChromeShowTimeoutRef.current = null;
|
|
26473
26631
|
}
|
|
26474
26632
|
}, []);
|
|
26475
|
-
const setMobileChromeVisible = (0,
|
|
26633
|
+
const setMobileChromeVisible = (0, import_react5.useCallback)((visible, reason) => {
|
|
26476
26634
|
if (chromeVisibleRef.current === visible) return;
|
|
26477
26635
|
chromeVisibleRef.current = visible;
|
|
26478
26636
|
setDocumentState({ mobileChromeVisible: visible });
|
|
26479
26637
|
}, [setDocumentState]);
|
|
26480
|
-
const trackMobileChromeByOffset = (0,
|
|
26638
|
+
const trackMobileChromeByOffset = (0, import_react5.useCallback)((offsetY, reasonPrefix) => {
|
|
26481
26639
|
const safeOffset = Math.max(0, offsetY);
|
|
26482
26640
|
const delta = safeOffset - lastScrollOffsetYRef.current;
|
|
26483
26641
|
lastScrollOffsetYRef.current = safeOffset;
|
|
@@ -26513,12 +26671,12 @@ function DedicatedAndroidPdfViewer({
|
|
|
26513
26671
|
}
|
|
26514
26672
|
}
|
|
26515
26673
|
}, [clearPendingChromeShow, setMobileChromeVisible]);
|
|
26516
|
-
(0,
|
|
26674
|
+
(0, import_react5.useEffect)(() => {
|
|
26517
26675
|
return () => {
|
|
26518
26676
|
clearPendingChromeShow();
|
|
26519
26677
|
};
|
|
26520
26678
|
}, [clearPendingChromeShow]);
|
|
26521
|
-
const applySelection = (0,
|
|
26679
|
+
const applySelection = (0, import_react5.useCallback)((type) => {
|
|
26522
26680
|
const sel = selectionRef.current;
|
|
26523
26681
|
if (!sel || !sel.rects || sel.rects.length === 0) return;
|
|
26524
26682
|
const bounds = sel.rects.reduce((acc, r) => ({
|
|
@@ -26540,12 +26698,12 @@ function DedicatedAndroidPdfViewer({
|
|
|
26540
26698
|
setSelection(null);
|
|
26541
26699
|
selectionRef.current = null;
|
|
26542
26700
|
}, [addAnnotation, beginAnnotationDraft, annotationColor, documentId]);
|
|
26543
|
-
return /* @__PURE__ */ (0,
|
|
26544
|
-
/* @__PURE__ */ (0,
|
|
26701
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react_native4.View, { style: styles4.container, children: [
|
|
26702
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(PdfNoteChooser, { notes: pendingNotes, title: t.annotationNote, cancel: t.cancel, onClose: () => setPendingNotes([]), onSelect: (id) => {
|
|
26545
26703
|
setPendingNotes([]);
|
|
26546
26704
|
setSelectedAnnotation(id);
|
|
26547
26705
|
} }),
|
|
26548
|
-
/* @__PURE__ */ (0,
|
|
26706
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
26549
26707
|
import_engine_native2.PapyrusPdfDocumentView,
|
|
26550
26708
|
{
|
|
26551
26709
|
style: [styles4.viewer, cappedViewerStyle],
|
|
@@ -26659,7 +26817,7 @@ var styles4 = import_react_native4.StyleSheet.create({
|
|
|
26659
26817
|
});
|
|
26660
26818
|
|
|
26661
26819
|
// components/DedicatedIosPdfViewer.tsx
|
|
26662
|
-
var
|
|
26820
|
+
var import_react6 = require("react");
|
|
26663
26821
|
var import_react_native5 = require("react-native");
|
|
26664
26822
|
var import_core7 = require("@papyrus-sdk/core");
|
|
26665
26823
|
var import_engine_native3 = require("@papyrus-sdk/engine-native");
|
|
@@ -26756,7 +26914,7 @@ var resolveNativePdfVisiblePages = (pages) => (pages ?? []).flatMap((page) => {
|
|
|
26756
26914
|
});
|
|
26757
26915
|
|
|
26758
26916
|
// components/DedicatedIosPdfViewer.tsx
|
|
26759
|
-
var
|
|
26917
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
26760
26918
|
var MOBILE_CHROME_HIDE_DELTA2 = 28;
|
|
26761
26919
|
var MOBILE_CHROME_SHOW_DELTA2 = 22;
|
|
26762
26920
|
var MOBILE_CHROME_SHOW_DELAY_MS2 = 180;
|
|
@@ -26788,7 +26946,7 @@ function DedicatedIosPdfViewer({
|
|
|
26788
26946
|
const inkStrokeWidth = (0, import_core7.useViewerStore)((state) => state.inkStrokeWidth);
|
|
26789
26947
|
const annotationNavigationRequest = (0, import_core7.useViewerStore)((state) => state.annotationNavigationRequest);
|
|
26790
26948
|
const annotations = (0, import_core7.useViewerStore)((state) => state.annotations);
|
|
26791
|
-
const [pendingNotes, setPendingNotes] = (0,
|
|
26949
|
+
const [pendingNotes, setPendingNotes] = (0, import_react6.useState)([]);
|
|
26792
26950
|
const handleAnnotationTap = (id) => {
|
|
26793
26951
|
const nearby = getNearbyPdfNotes(annotations, id);
|
|
26794
26952
|
if (nearby.length < 2) {
|
|
@@ -26824,16 +26982,16 @@ function DedicatedIosPdfViewer({
|
|
|
26824
26982
|
supportsNativeEditMenu
|
|
26825
26983
|
);
|
|
26826
26984
|
const resolvedMaxPageWidth = typeof maxPageWidth === "number" && Number.isFinite(maxPageWidth) && maxPageWidth > 0 ? maxPageWidth : void 0;
|
|
26827
|
-
const chromeVisibleRef = (0,
|
|
26828
|
-
const lastScrollOffsetYRef = (0,
|
|
26829
|
-
const scrollDownAccumRef = (0,
|
|
26830
|
-
const scrollUpAccumRef = (0,
|
|
26831
|
-
const pendingChromeShowTimeoutRef = (0,
|
|
26832
|
-
const lastZoomChangedAtRef = (0,
|
|
26833
|
-
const lastVisiblePagesKeyRef = (0,
|
|
26834
|
-
const [selection, setSelection] = (0,
|
|
26835
|
-
const selectionRef = (0,
|
|
26836
|
-
(0,
|
|
26985
|
+
const chromeVisibleRef = (0, import_react6.useRef)(mobileChromeVisible);
|
|
26986
|
+
const lastScrollOffsetYRef = (0, import_react6.useRef)(0);
|
|
26987
|
+
const scrollDownAccumRef = (0, import_react6.useRef)(0);
|
|
26988
|
+
const scrollUpAccumRef = (0, import_react6.useRef)(0);
|
|
26989
|
+
const pendingChromeShowTimeoutRef = (0, import_react6.useRef)(null);
|
|
26990
|
+
const lastZoomChangedAtRef = (0, import_react6.useRef)(null);
|
|
26991
|
+
const lastVisiblePagesKeyRef = (0, import_react6.useRef)("");
|
|
26992
|
+
const [selection, setSelection] = (0, import_react6.useState)(null);
|
|
26993
|
+
const selectionRef = (0, import_react6.useRef)(null);
|
|
26994
|
+
(0, import_react6.useEffect)(() => {
|
|
26837
26995
|
const pickerActive = supportsNativeEditMenu && activeTool === "ink";
|
|
26838
26996
|
setDocumentState({ nativeInkToolPickerActive: pickerActive });
|
|
26839
26997
|
return () => {
|
|
@@ -26842,15 +27000,15 @@ function DedicatedIosPdfViewer({
|
|
|
26842
27000
|
}
|
|
26843
27001
|
};
|
|
26844
27002
|
}, [activeTool, setDocumentState]);
|
|
26845
|
-
(0,
|
|
27003
|
+
(0, import_react6.useEffect)(() => {
|
|
26846
27004
|
chromeVisibleRef.current = mobileChromeVisible;
|
|
26847
27005
|
}, [mobileChromeVisible]);
|
|
26848
|
-
const clearPendingChromeShow = (0,
|
|
27006
|
+
const clearPendingChromeShow = (0, import_react6.useCallback)(() => {
|
|
26849
27007
|
if (!pendingChromeShowTimeoutRef.current) return;
|
|
26850
27008
|
clearTimeout(pendingChromeShowTimeoutRef.current);
|
|
26851
27009
|
pendingChromeShowTimeoutRef.current = null;
|
|
26852
27010
|
}, []);
|
|
26853
|
-
const setMobileChromeVisible = (0,
|
|
27011
|
+
const setMobileChromeVisible = (0, import_react6.useCallback)(
|
|
26854
27012
|
(visible) => {
|
|
26855
27013
|
if (chromeVisibleRef.current === visible) return;
|
|
26856
27014
|
chromeVisibleRef.current = visible;
|
|
@@ -26858,14 +27016,14 @@ function DedicatedIosPdfViewer({
|
|
|
26858
27016
|
},
|
|
26859
27017
|
[setDocumentState]
|
|
26860
27018
|
);
|
|
26861
|
-
const updateSelection = (0,
|
|
27019
|
+
const updateSelection = (0, import_react6.useCallback)(
|
|
26862
27020
|
(nextSelection) => {
|
|
26863
27021
|
selectionRef.current = nextSelection;
|
|
26864
27022
|
setSelection(nextSelection);
|
|
26865
27023
|
},
|
|
26866
27024
|
[]
|
|
26867
27025
|
);
|
|
26868
|
-
const handleTextSelectionChange = (0,
|
|
27026
|
+
const handleTextSelectionChange = (0, import_react6.useCallback)(
|
|
26869
27027
|
(event) => {
|
|
26870
27028
|
const nextSelection = resolveNativePdfTextSelection(event.nativeEvent);
|
|
26871
27029
|
updateSelection(nextSelection);
|
|
@@ -26878,7 +27036,7 @@ function DedicatedIosPdfViewer({
|
|
|
26878
27036
|
},
|
|
26879
27037
|
[onTextSelected, setSelectedAnnotation, updateSelection]
|
|
26880
27038
|
);
|
|
26881
|
-
const defineSelection = (0,
|
|
27039
|
+
const defineSelection = (0, import_react6.useCallback)(() => {
|
|
26882
27040
|
const currentSelection = selectionRef.current;
|
|
26883
27041
|
if (!currentSelection) return;
|
|
26884
27042
|
onDefineSelection?.({
|
|
@@ -26887,7 +27045,7 @@ function DedicatedIosPdfViewer({
|
|
|
26887
27045
|
});
|
|
26888
27046
|
updateSelection(null);
|
|
26889
27047
|
}, [onDefineSelection, updateSelection]);
|
|
26890
|
-
const handleNativeDefineSelection = (0,
|
|
27048
|
+
const handleNativeDefineSelection = (0, import_react6.useCallback)(
|
|
26891
27049
|
(event) => {
|
|
26892
27050
|
const text = event.nativeEvent?.text;
|
|
26893
27051
|
const pageIndex = event.nativeEvent?.pageIndex;
|
|
@@ -26899,7 +27057,7 @@ function DedicatedIosPdfViewer({
|
|
|
26899
27057
|
},
|
|
26900
27058
|
[onDefineSelection, updateSelection]
|
|
26901
27059
|
);
|
|
26902
|
-
const handleInkToolPickerVisibilityChange = (0,
|
|
27060
|
+
const handleInkToolPickerVisibilityChange = (0, import_react6.useCallback)(
|
|
26903
27061
|
(event) => {
|
|
26904
27062
|
handleNativeInkPickerVisibility(
|
|
26905
27063
|
event.nativeEvent?.visible === true,
|
|
@@ -26908,7 +27066,7 @@ function DedicatedIosPdfViewer({
|
|
|
26908
27066
|
},
|
|
26909
27067
|
[]
|
|
26910
27068
|
);
|
|
26911
|
-
const trackMobileChromeByOffset = (0,
|
|
27069
|
+
const trackMobileChromeByOffset = (0, import_react6.useCallback)(
|
|
26912
27070
|
(offsetY) => {
|
|
26913
27071
|
if (pageCount <= 0) return;
|
|
26914
27072
|
const safeOffset = Math.max(0, offsetY);
|
|
@@ -26944,11 +27102,11 @@ function DedicatedIosPdfViewer({
|
|
|
26944
27102
|
},
|
|
26945
27103
|
[clearPendingChromeShow, pageCount, setMobileChromeVisible]
|
|
26946
27104
|
);
|
|
26947
|
-
(0,
|
|
27105
|
+
(0, import_react6.useEffect)(
|
|
26948
27106
|
() => () => clearPendingChromeShow(),
|
|
26949
27107
|
[clearPendingChromeShow]
|
|
26950
27108
|
);
|
|
26951
|
-
const handleVisiblePagesChange = (0,
|
|
27109
|
+
const handleVisiblePagesChange = (0, import_react6.useCallback)(
|
|
26952
27110
|
(event) => {
|
|
26953
27111
|
const pages = resolveNativePdfVisiblePages(
|
|
26954
27112
|
event.nativeEvent?.pages
|
|
@@ -26963,13 +27121,13 @@ function DedicatedIosPdfViewer({
|
|
|
26963
27121
|
},
|
|
26964
27122
|
[setDocumentState]
|
|
26965
27123
|
);
|
|
26966
|
-
const handleScroll = (0,
|
|
27124
|
+
const handleScroll = (0, import_react6.useCallback)(
|
|
26967
27125
|
(event) => {
|
|
26968
27126
|
trackMobileChromeByOffset(event.nativeEvent?.offsetY ?? 0);
|
|
26969
27127
|
},
|
|
26970
27128
|
[trackMobileChromeByOffset]
|
|
26971
27129
|
);
|
|
26972
|
-
const handleTap = (0,
|
|
27130
|
+
const handleTap = (0, import_react6.useCallback)(() => {
|
|
26973
27131
|
setSelectedAnnotation(null);
|
|
26974
27132
|
const nextVisible = resolvePageTapChromeVisibility({
|
|
26975
27133
|
chromeVisible: chromeVisibleRef.current,
|
|
@@ -26979,7 +27137,7 @@ function DedicatedIosPdfViewer({
|
|
|
26979
27137
|
});
|
|
26980
27138
|
if (nextVisible !== null) setMobileChromeVisible(nextVisible);
|
|
26981
27139
|
}, [activeTool, selectionActive, setMobileChromeVisible, setSelectedAnnotation]);
|
|
26982
|
-
const handleDeleteAnnotation = (0,
|
|
27140
|
+
const handleDeleteAnnotation = (0, import_react6.useCallback)(
|
|
26983
27141
|
(annotationId) => {
|
|
26984
27142
|
deleteAnnotationAndClearSelection(
|
|
26985
27143
|
annotationId,
|
|
@@ -26994,12 +27152,12 @@ function DedicatedIosPdfViewer({
|
|
|
26994
27152
|
maxWidth: resolvedMaxPageWidth,
|
|
26995
27153
|
alignSelf: "center"
|
|
26996
27154
|
} : void 0;
|
|
26997
|
-
return /* @__PURE__ */ (0,
|
|
26998
|
-
/* @__PURE__ */ (0,
|
|
27155
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_react_native5.View, { style: styles5.container, children: [
|
|
27156
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(PdfNoteChooser, { notes: pendingNotes, title: t.annotationNote, cancel: t.cancel, onClose: () => setPendingNotes([]), onSelect: (id) => {
|
|
26999
27157
|
setPendingNotes([]);
|
|
27000
27158
|
setSelectedAnnotation(id);
|
|
27001
27159
|
} }),
|
|
27002
|
-
/* @__PURE__ */ (0,
|
|
27160
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
27003
27161
|
import_engine_native3.PapyrusPdfDocumentView,
|
|
27004
27162
|
{
|
|
27005
27163
|
style: [styles5.viewer, cappedViewerStyle],
|
|
@@ -27068,22 +27226,22 @@ function DedicatedIosPdfViewer({
|
|
|
27068
27226
|
onInkToolPickerVisibilityChange: handleInkToolPickerVisibilityChange
|
|
27069
27227
|
}
|
|
27070
27228
|
),
|
|
27071
|
-
selection && !supportsNativeEditMenu && onDefineSelection && shouldShowDefineSelection(selection.text, defineSelectionMode) && /* @__PURE__ */ (0,
|
|
27229
|
+
selection && !supportsNativeEditMenu && onDefineSelection && shouldShowDefineSelection(selection.text, defineSelectionMode) && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native5.View, { style: styles5.selectionFallback, pointerEvents: "box-none", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
27072
27230
|
import_react_native5.Pressable,
|
|
27073
27231
|
{
|
|
27074
27232
|
onPress: defineSelection,
|
|
27075
27233
|
style: styles5.fallbackButton,
|
|
27076
27234
|
accessibilityRole: "button",
|
|
27077
27235
|
accessibilityLabel: t.define,
|
|
27078
|
-
children: /* @__PURE__ */ (0,
|
|
27236
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native5.Text, { style: styles5.fallbackButtonText, children: t.define })
|
|
27079
27237
|
}
|
|
27080
27238
|
) }),
|
|
27081
|
-
fallbackDeleteAnnotation && /* @__PURE__ */ (0,
|
|
27239
|
+
fallbackDeleteAnnotation && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
27082
27240
|
import_react_native5.View,
|
|
27083
27241
|
{
|
|
27084
27242
|
style: styles5.annotationDeleteFallback,
|
|
27085
27243
|
pointerEvents: "box-none",
|
|
27086
|
-
children: /* @__PURE__ */ (0,
|
|
27244
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
27087
27245
|
import_react_native5.Pressable,
|
|
27088
27246
|
{
|
|
27089
27247
|
onPress: () => handleDeleteAnnotation(fallbackDeleteAnnotation.id),
|
|
@@ -27091,7 +27249,7 @@ function DedicatedIosPdfViewer({
|
|
|
27091
27249
|
accessibilityRole: "button",
|
|
27092
27250
|
accessibilityLabel: t.deleteAnnotation,
|
|
27093
27251
|
hitSlop: 8,
|
|
27094
|
-
children: /* @__PURE__ */ (0,
|
|
27252
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native5.Text, { style: styles5.annotationDeleteButtonText, children: t.deleteAnnotation })
|
|
27095
27253
|
}
|
|
27096
27254
|
)
|
|
27097
27255
|
}
|
|
@@ -27154,7 +27312,7 @@ var styles5 = import_react_native5.StyleSheet.create({
|
|
|
27154
27312
|
});
|
|
27155
27313
|
|
|
27156
27314
|
// components/NativePdfDocumentViewer.tsx
|
|
27157
|
-
var
|
|
27315
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
27158
27316
|
function NativePdfDocumentViewer({
|
|
27159
27317
|
engine,
|
|
27160
27318
|
documentId,
|
|
@@ -27167,7 +27325,7 @@ function NativePdfDocumentViewer({
|
|
|
27167
27325
|
import_react_native6.Platform.OS
|
|
27168
27326
|
);
|
|
27169
27327
|
if (implementation === "android") {
|
|
27170
|
-
return /* @__PURE__ */ (0,
|
|
27328
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
27171
27329
|
DedicatedAndroidPdfViewer,
|
|
27172
27330
|
{
|
|
27173
27331
|
engine,
|
|
@@ -27180,7 +27338,7 @@ function NativePdfDocumentViewer({
|
|
|
27180
27338
|
);
|
|
27181
27339
|
}
|
|
27182
27340
|
if (implementation === "ios") {
|
|
27183
|
-
return /* @__PURE__ */ (0,
|
|
27341
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
27184
27342
|
DedicatedIosPdfViewer,
|
|
27185
27343
|
{
|
|
27186
27344
|
engine,
|
|
@@ -27234,26 +27392,6 @@ var resolveMobileChromeOffsets = (insets) => ({
|
|
|
27234
27392
|
right: MOBILE_CHROME_METRICS.screenPadding + Math.max(0, insets.right)
|
|
27235
27393
|
});
|
|
27236
27394
|
|
|
27237
|
-
// components/PapyrusSafeArea.tsx
|
|
27238
|
-
var import_react6 = __toESM(require("react"));
|
|
27239
|
-
var import_react_native_safe_area_context = require("react-native-safe-area-context");
|
|
27240
|
-
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
27241
|
-
var papyrusSafeAreaContext = import_react_native_safe_area_context.SafeAreaInsetsContext;
|
|
27242
|
-
var ZERO_SAFE_AREA_INSETS = {
|
|
27243
|
-
top: 0,
|
|
27244
|
-
bottom: 0,
|
|
27245
|
-
left: 0,
|
|
27246
|
-
right: 0
|
|
27247
|
-
};
|
|
27248
|
-
var usePapyrusSafeAreaInsets = () => (0, import_react6.useContext)(papyrusSafeAreaContext) ?? ZERO_SAFE_AREA_INSETS;
|
|
27249
|
-
function PapyrusSafeAreaBoundary({
|
|
27250
|
-
children
|
|
27251
|
-
}) {
|
|
27252
|
-
const insets = (0, import_react6.useContext)(papyrusSafeAreaContext);
|
|
27253
|
-
if (insets) return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_jsx_runtime9.Fragment, { children });
|
|
27254
|
-
return import_react6.default.createElement(import_react_native_safe_area_context.SafeAreaProvider, null, children);
|
|
27255
|
-
}
|
|
27256
|
-
|
|
27257
27395
|
// components/NativeTextDocumentViewer.tsx
|
|
27258
27396
|
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
27259
27397
|
function NativeTextDocumentViewer({
|
|
@@ -27802,6 +27940,7 @@ var scrollViewerListToOffset = (list, offset, animated) => {
|
|
|
27802
27940
|
list.scrollToOffset?.({ offset, animated });
|
|
27803
27941
|
};
|
|
27804
27942
|
var Viewer = ({
|
|
27943
|
+
documentType,
|
|
27805
27944
|
documentId,
|
|
27806
27945
|
engine,
|
|
27807
27946
|
maxPageWidth,
|
|
@@ -29329,14 +29468,8 @@ var Viewer = ({
|
|
|
29329
29468
|
},
|
|
29330
29469
|
[mobilePerf, perfEnabled, scrollPerfSession]
|
|
29331
29470
|
);
|
|
29332
|
-
const handleWebViewScroll = (0, import_react9.useCallback)(
|
|
29333
|
-
|
|
29334
|
-
if (!chromeVisibleRef.current) {
|
|
29335
|
-
setMobileChromeVisible(true, "scroll.webview.recover");
|
|
29336
|
-
}
|
|
29337
|
-
},
|
|
29338
|
-
[setMobileChromeVisible]
|
|
29339
|
-
);
|
|
29471
|
+
const handleWebViewScroll = (0, import_react9.useCallback)((_offsetY) => {
|
|
29472
|
+
}, []);
|
|
29340
29473
|
const handlePageTap = (0, import_react9.useCallback)(() => {
|
|
29341
29474
|
const nextVisible = resolvePageTapChromeVisibility({
|
|
29342
29475
|
chromeVisible: chromeVisibleRef.current,
|
|
@@ -29558,6 +29691,7 @@ var Viewer = ({
|
|
|
29558
29691
|
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native9.View, { style: [styles8.container, isDark && styles8.containerDark], children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
29559
29692
|
WebViewViewer_default,
|
|
29560
29693
|
{
|
|
29694
|
+
documentType,
|
|
29561
29695
|
engine,
|
|
29562
29696
|
documentId,
|
|
29563
29697
|
onDefineSelection,
|
|
@@ -30104,6 +30238,7 @@ var styles9 = import_react_native11.StyleSheet.create({
|
|
|
30104
30238
|
// components/PageJumpModal.tsx
|
|
30105
30239
|
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
30106
30240
|
function PageJumpModal({
|
|
30241
|
+
documentType,
|
|
30107
30242
|
visible,
|
|
30108
30243
|
currentPage,
|
|
30109
30244
|
pageCount,
|
|
@@ -30130,8 +30265,8 @@ function PageJumpModal({
|
|
|
30130
30265
|
isDark,
|
|
30131
30266
|
maxHeight: 300,
|
|
30132
30267
|
showHeader: true,
|
|
30133
|
-
title: "Ir para p\xE1gina",
|
|
30134
|
-
closeAccessibilityLabel: "
|
|
30268
|
+
title: documentType === "epub" ? "Ir para cap\xEDtulo" : "Ir para p\xE1gina",
|
|
30269
|
+
closeAccessibilityLabel: "Fechar navega\xE7\xE3o",
|
|
30135
30270
|
sheetStyle: {
|
|
30136
30271
|
paddingHorizontal: 18,
|
|
30137
30272
|
paddingBottom: 18,
|
|
@@ -30159,7 +30294,7 @@ function PageJumpModal({
|
|
|
30159
30294
|
}
|
|
30160
30295
|
],
|
|
30161
30296
|
onSubmitEditing: confirmJump,
|
|
30162
|
-
accessibilityLabel: "
|
|
30297
|
+
accessibilityLabel: documentType === "epub" ? "N\xFAmero do cap\xEDtulo" : "N\xFAmero da p\xE1gina",
|
|
30163
30298
|
testID: "papyrus-page-jump-input"
|
|
30164
30299
|
}
|
|
30165
30300
|
),
|
|
@@ -30214,6 +30349,7 @@ var styles10 = import_react_native12.StyleSheet.create({
|
|
|
30214
30349
|
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
30215
30350
|
var Topbar = ({
|
|
30216
30351
|
engine,
|
|
30352
|
+
documentType,
|
|
30217
30353
|
onOpenSettings,
|
|
30218
30354
|
onOpenOverflow,
|
|
30219
30355
|
title,
|
|
@@ -30234,6 +30370,12 @@ var Topbar = ({
|
|
|
30234
30370
|
locale
|
|
30235
30371
|
} = (0, import_core12.useViewerStore)();
|
|
30236
30372
|
const inkSession = useNativeInkSession();
|
|
30373
|
+
const chromeVisible = mobileChromeVisible || inkSession.active;
|
|
30374
|
+
const chromeProgress = useNativeInkMotion(chromeVisible, documentType === "epub");
|
|
30375
|
+
const chromeMotion = (0, import_react_native_reanimated2.useAnimatedStyle)(() => {
|
|
30376
|
+
"worklet";
|
|
30377
|
+
return { opacity: chromeProgress.value };
|
|
30378
|
+
});
|
|
30237
30379
|
const t = getStrings(locale);
|
|
30238
30380
|
const progress = useNativeInkMotion(inkSession.active, inkSession.supported);
|
|
30239
30381
|
const settingsMotion = (0, import_react_native_reanimated2.useAnimatedStyle)(() => {
|
|
@@ -30289,20 +30431,23 @@ var Topbar = ({
|
|
|
30289
30431
|
children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(IconSettings, { size: MOBILE_CHROME_METRICS.iconSize, color: isDark ? "#e5e7eb" : "#111827" })
|
|
30290
30432
|
}
|
|
30291
30433
|
);
|
|
30292
|
-
if (!
|
|
30434
|
+
if (!chromeVisible && documentType !== "epub") return null;
|
|
30293
30435
|
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
|
|
30294
30436
|
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
30295
|
-
|
|
30437
|
+
import_react_native_reanimated2.default.View,
|
|
30296
30438
|
{
|
|
30297
30439
|
style: [
|
|
30298
30440
|
styles11.chromeFrame,
|
|
30441
|
+
chromeMotion,
|
|
30299
30442
|
{
|
|
30300
30443
|
paddingTop: insets.top,
|
|
30301
30444
|
paddingLeft: MOBILE_CHROME_METRICS.screenPadding + insets.left,
|
|
30302
30445
|
paddingRight: MOBILE_CHROME_METRICS.screenPadding + insets.right
|
|
30303
30446
|
}
|
|
30304
30447
|
],
|
|
30305
|
-
pointerEvents: "box-none",
|
|
30448
|
+
pointerEvents: chromeVisible ? "box-none" : "none",
|
|
30449
|
+
accessibilityElementsHidden: !chromeVisible,
|
|
30450
|
+
importantForAccessibility: chromeVisible ? "auto" : "no-hide-descendants",
|
|
30306
30451
|
testID: "papyrus-floating-top-controls",
|
|
30307
30452
|
children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
30308
30453
|
import_react_native13.View,
|
|
@@ -30449,6 +30594,7 @@ var Topbar = ({
|
|
|
30449
30594
|
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
30450
30595
|
PageJumpModal,
|
|
30451
30596
|
{
|
|
30597
|
+
documentType,
|
|
30452
30598
|
visible: jumpModalOpen,
|
|
30453
30599
|
currentPage,
|
|
30454
30600
|
pageCount,
|
|
@@ -32699,7 +32845,27 @@ var AnnotationEditor = ({ documentId }) => {
|
|
|
32699
32845
|
editing ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
|
|
32700
32846
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native16.TextInput, { accessibilityLabel: t.editNote, value: draft, onChangeText: setDraft, multiline: true, autoFocus: true, placeholder: t.notePlaceholder, placeholderTextColor: dark ? "#9ca3af" : "#6b7280", style: [styles14.input, textStyle, { borderColor: dark ? "#374151" : "#d1d5db" }] }),
|
|
32701
32847
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native16.View, { style: styles14.options, children: COLORS.map((value) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native16.Pressable, { accessibilityRole: "button", accessibilityLabel: `${t.annotationColor} ${value}`, accessibilityState: { selected: color === value }, onPress: () => setColor(value), style: [styles14.color, { backgroundColor: value, borderColor: color === value ? accentColor : "transparent" }] }, value)) }),
|
|
32702
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native16.View, { style: styles14.
|
|
32848
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native16.View, { style: styles14.markupOptions, children: [
|
|
32849
|
+
["highlight", t.annotationHighlight, IconHighlight],
|
|
32850
|
+
["underline", t.annotationUnderline, IconUnderline],
|
|
32851
|
+
["strikeout", t.annotationStrikeout, IconStrikeout],
|
|
32852
|
+
["none", t.annotationIndicatorOnly, IconComment]
|
|
32853
|
+
].map(([style, label, Icon]) => /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
32854
|
+
import_react_native16.Pressable,
|
|
32855
|
+
{
|
|
32856
|
+
onPress: () => setMarkup(style),
|
|
32857
|
+
accessibilityRole: "button",
|
|
32858
|
+
accessibilityLabel: label,
|
|
32859
|
+
accessibilityState: { selected: markup === style },
|
|
32860
|
+
testID: `annotation-style-${style}`,
|
|
32861
|
+
style: [styles14.markupButton, { backgroundColor: dark ? "#242936" : "#f1f5f9", borderColor: markup === style ? accentColor : "transparent" }],
|
|
32862
|
+
children: [
|
|
32863
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native16.View, { accessible: false, importantForAccessibility: "no-hide-descendants", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Icon, { size: 22, color: markup === style ? accentColor : textStyle.color }) }),
|
|
32864
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native16.Text, { style: [styles14.markupLabel, textStyle], children: style === "none" ? locale === "pt-BR" ? "Indicador" : "Indicator" : label })
|
|
32865
|
+
]
|
|
32866
|
+
},
|
|
32867
|
+
style
|
|
32868
|
+
)) })
|
|
32703
32869
|
] }) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native16.Text, { style: [styles14.note, textStyle], selectable: true, children: (0, import_core15.getAnnotationNote)(annotation) || t.notePlaceholder })
|
|
32704
32870
|
] }),
|
|
32705
32871
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_native16.View, { style: styles14.actions, children: [
|
|
@@ -32722,7 +32888,7 @@ var AnnotationEditor = ({ documentId }) => {
|
|
|
32722
32888
|
] })
|
|
32723
32889
|
] }) });
|
|
32724
32890
|
};
|
|
32725
|
-
var styles14 = import_react_native16.StyleSheet.create({ host: { flex: 1, justifyContent: "flex-end", backgroundColor: "rgba(0,0,0,.18)", paddingHorizontal: 12 }, card: { borderRadius: 20, padding: 16, maxHeight: "72%", elevation: 12 }, header: { flexDirection: "row", alignItems: "center", justifyContent: "space-between" }, title: { fontSize: 17, fontWeight: "700" }, content: { flexGrow: 0 }, quote: { fontSize: 14, lineHeight: 21, borderLeftWidth: 3, borderLeftColor: "#9ca3af", paddingLeft: 10, marginVertical: 12 }, note: { fontSize: 16, lineHeight: 24, paddingVertical: 12 }, input: { minHeight: 112, maxHeight: 240, borderWidth: 1, borderRadius: 12, padding: 12, fontSize: 16, textAlignVertical: "top" }, button: { minWidth: 44, minHeight: 44, paddingHorizontal: 10, borderRadius: 10, alignItems: "center", justifyContent: "center" }, actions: { flexDirection: "row", alignItems: "center", flexWrap: "wrap", marginTop: 12 }, options: { flexDirection: "row", flexWrap: "wrap", gap: 8, marginTop: 12 }, color: { width: 44, height: 44, borderRadius: 22, borderWidth: 3 } });
|
|
32891
|
+
var styles14 = import_react_native16.StyleSheet.create({ host: { flex: 1, justifyContent: "flex-end", backgroundColor: "rgba(0,0,0,.18)", paddingHorizontal: 12 }, card: { borderRadius: 20, padding: 16, maxHeight: "72%", elevation: 12 }, header: { flexDirection: "row", alignItems: "center", justifyContent: "space-between" }, title: { fontSize: 17, fontWeight: "700" }, content: { flexGrow: 0 }, quote: { fontSize: 14, lineHeight: 21, borderLeftWidth: 3, borderLeftColor: "#9ca3af", paddingLeft: 10, marginVertical: 12 }, note: { fontSize: 16, lineHeight: 24, paddingVertical: 12 }, input: { minHeight: 112, maxHeight: 240, borderWidth: 1, borderRadius: 12, padding: 12, fontSize: 16, textAlignVertical: "top" }, button: { minWidth: 44, minHeight: 44, paddingHorizontal: 10, borderRadius: 10, alignItems: "center", justifyContent: "center" }, actions: { flexDirection: "row", alignItems: "center", flexWrap: "wrap", marginTop: 12 }, markupOptions: { flexDirection: "row", flexWrap: "wrap", gap: 8, marginTop: 12 }, markupButton: { flex: 1, minWidth: 64, minHeight: 64, borderWidth: 1, borderRadius: 12, paddingHorizontal: 4, paddingVertical: 8, alignItems: "center", justifyContent: "center", gap: 6 }, markupLabel: { fontSize: 11, lineHeight: 15, textAlign: "center" }, options: { flexDirection: "row", flexWrap: "wrap", gap: 8, marginTop: 12 }, color: { width: 44, height: 44, borderRadius: 22, borderWidth: 3 } });
|
|
32726
32892
|
var AnnotationEditor_default = AnnotationEditor;
|
|
32727
32893
|
|
|
32728
32894
|
// components/BottomBar.tsx
|
|
@@ -32793,6 +32959,8 @@ var BottomBar = ({
|
|
|
32793
32959
|
const {
|
|
32794
32960
|
activeMobileDestination,
|
|
32795
32961
|
viewMode,
|
|
32962
|
+
epubReadingMode,
|
|
32963
|
+
epubLocation,
|
|
32796
32964
|
comicLayoutMode,
|
|
32797
32965
|
currentPage,
|
|
32798
32966
|
pageCount,
|
|
@@ -32810,7 +32978,7 @@ var BottomBar = ({
|
|
|
32810
32978
|
const supportsInkChrome = documentType === "pdf" && inkSession.supported;
|
|
32811
32979
|
const drawing = supportsInkChrome && inkSession.active;
|
|
32812
32980
|
const dockVisible = mobileChromeVisible && mobileDockVisible && !drawing;
|
|
32813
|
-
const dockProgress = useNativeInkMotion(dockVisible, supportsInkChrome);
|
|
32981
|
+
const dockProgress = useNativeInkMotion(dockVisible, supportsInkChrome || documentType === "epub");
|
|
32814
32982
|
const dockMotion = (0, import_react_native_reanimated3.useAnimatedStyle)(() => {
|
|
32815
32983
|
"worklet";
|
|
32816
32984
|
return {
|
|
@@ -32832,7 +33000,7 @@ var BottomBar = ({
|
|
|
32832
33000
|
activeMobileDestination,
|
|
32833
33001
|
toolDockOpen
|
|
32834
33002
|
});
|
|
32835
|
-
const paginated = documentType !== "text" && (documentType === "comic" ? comicLayoutMode === "single" : viewMode === "single");
|
|
33003
|
+
const paginated = documentType !== "text" && (documentType === "comic" ? comicLayoutMode === "single" : documentType === "epub" ? epubReadingMode === "paged" : viewMode === "single");
|
|
32836
33004
|
if (paginated) {
|
|
32837
33005
|
layout.leftSlots.push(...layout.rightSlots.filter((slot) => slot.key === "search"));
|
|
32838
33006
|
layout.rightSlots = [];
|
|
@@ -32901,7 +33069,7 @@ var BottomBar = ({
|
|
|
32901
33069
|
onPress: onOpenSettings
|
|
32902
33070
|
}
|
|
32903
33071
|
};
|
|
32904
|
-
if (!dockVisible && !supportsInkChrome) return null;
|
|
33072
|
+
if (!dockVisible && !supportsInkChrome && documentType !== "epub") return null;
|
|
32905
33073
|
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
32906
33074
|
import_react_native_reanimated3.default.View,
|
|
32907
33075
|
{
|
|
@@ -32967,13 +33135,9 @@ var BottomBar = ({
|
|
|
32967
33135
|
],
|
|
32968
33136
|
testID: "papyrus-floating-bottom-dock",
|
|
32969
33137
|
children: paginated ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
|
|
32970
|
-
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_react_native17.Pressable, { accessibilityRole: "button", accessibilityLabel: locale === "pt-BR" ? "P\xE1gina anterior" : "Previous page", disabled: !dockVisible || !onTurnPage && currentPage <= 1, onPress: () => turnPage(-1), style: styles15.iconOnlyItem, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(IconChevronLeft, { size: MOBILE_CHROME_METRICS.iconSize, color: iconColor(false) }) }),
|
|
32971
|
-
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_react_native17.Pressable, { accessibilityRole: "button", accessibilityLabel: locale === "pt-BR" ? "Ir para p\xE1gina" : "Go to page", onPress: onOpenPages, style: [styles15.iconOnlyItem, { minWidth: 56 }], children: /* @__PURE__ */ (0, import_jsx_runtime19.
|
|
32972
|
-
|
|
32973
|
-
"/",
|
|
32974
|
-
pageCount
|
|
32975
|
-
] }) }),
|
|
32976
|
-
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_react_native17.Pressable, { accessibilityRole: "button", accessibilityLabel: locale === "pt-BR" ? "Pr\xF3xima p\xE1gina" : "Next page", disabled: !dockVisible || !onTurnPage && currentPage >= pageCount, onPress: () => turnPage(1), style: styles15.iconOnlyItem, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(IconChevronRight, { size: MOBILE_CHROME_METRICS.iconSize, color: iconColor(false) }) })
|
|
33138
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_react_native17.Pressable, { accessibilityRole: "button", accessibilityLabel: locale === "pt-BR" ? "P\xE1gina anterior" : "Previous page", disabled: !dockVisible || (documentType === "epub" ? epubLocation?.atStart : !onTurnPage && currentPage <= 1), onPress: () => turnPage(-1), style: styles15.iconOnlyItem, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(IconChevronLeft, { size: MOBILE_CHROME_METRICS.iconSize, color: iconColor(false) }) }),
|
|
33139
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_react_native17.Pressable, { accessibilityRole: "button", accessibilityLabel: locale === "pt-BR" ? "Ir para p\xE1gina" : "Go to page", onPress: onOpenPages, style: [styles15.iconOnlyItem, { minWidth: 56 }], children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_react_native17.Text, { style: { color: iconColor(false), fontWeight: "700", fontSize: 13, lineHeight: 18, includeFontPadding: false }, children: documentType === "epub" ? epubLocation?.visualPage ? `Cap. ${epubLocation.chapter} \xB7 ${epubLocation.visualPage}/${epubLocation.visualPageCount}` : `Cap. ${currentPage}` : `${currentPage}/${pageCount}` }) }),
|
|
33140
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_react_native17.Pressable, { accessibilityRole: "button", accessibilityLabel: locale === "pt-BR" ? "Pr\xF3xima p\xE1gina" : "Next page", disabled: !dockVisible || (documentType === "epub" ? epubLocation?.atEnd : !onTurnPage && currentPage >= pageCount), onPress: () => turnPage(1), style: styles15.iconOnlyItem, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(IconChevronRight, { size: MOBILE_CHROME_METRICS.iconSize, color: iconColor(false) }) })
|
|
32977
33141
|
] }) : layout.rightSlots.map((slot) => {
|
|
32978
33142
|
const meta = slotMeta[slot.key];
|
|
32979
33143
|
const Icon = meta.icon;
|
|
@@ -33148,6 +33312,7 @@ var SettingsSheet = ({
|
|
|
33148
33312
|
}) => {
|
|
33149
33313
|
const {
|
|
33150
33314
|
viewMode,
|
|
33315
|
+
epubReadingMode,
|
|
33151
33316
|
uiTheme,
|
|
33152
33317
|
zoom,
|
|
33153
33318
|
setDocumentState,
|
|
@@ -33159,12 +33324,16 @@ var SettingsSheet = ({
|
|
|
33159
33324
|
comicReadingDirection
|
|
33160
33325
|
} = (0, import_core17.useViewerStore)();
|
|
33161
33326
|
const isDark = uiTheme === "dark";
|
|
33162
|
-
const isPaged = viewMode === "single";
|
|
33327
|
+
const isPaged = documentType === "epub" ? epubReadingMode === "paged" : viewMode === "single";
|
|
33163
33328
|
const isDouble = viewMode === "double";
|
|
33164
33329
|
const t = getStrings(locale);
|
|
33165
33330
|
const { height: windowHeight } = (0, import_react_native18.useWindowDimensions)();
|
|
33166
33331
|
const sheetMaxHeight = getSettingsSheetMaxHeight(windowHeight);
|
|
33167
33332
|
const handleTransition = (mode) => {
|
|
33333
|
+
if (documentType === "epub") {
|
|
33334
|
+
setDocumentState({ epubReadingMode: mode === "paged" ? "paged" : "chapter-scroll" });
|
|
33335
|
+
return;
|
|
33336
|
+
}
|
|
33168
33337
|
if (mode === "paged") {
|
|
33169
33338
|
setDocumentState({ viewMode: "single" });
|
|
33170
33339
|
return;
|
|
@@ -33388,7 +33557,7 @@ var SettingsSheet = ({
|
|
|
33388
33557
|
isDark && styles16.optionTextDark,
|
|
33389
33558
|
(!isPaged || isDouble) && styles16.optionTextActive
|
|
33390
33559
|
],
|
|
33391
|
-
children: t.continuous
|
|
33560
|
+
children: documentType === "epub" && locale === "pt-BR" ? "Rolagem por cap\xEDtulo" : t.continuous
|
|
33392
33561
|
}
|
|
33393
33562
|
)
|
|
33394
33563
|
}
|
|
@@ -33418,7 +33587,7 @@ var SettingsSheet = ({
|
|
|
33418
33587
|
)
|
|
33419
33588
|
] })
|
|
33420
33589
|
] }),
|
|
33421
|
-
documentType
|
|
33590
|
+
documentType === "pdf" && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_react_native18.View, { style: styles16.section, children: [
|
|
33422
33591
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
33423
33592
|
import_react_native18.Text,
|
|
33424
33593
|
{
|
|
@@ -34296,6 +34465,7 @@ var styles20 = import_react_native22.StyleSheet.create({
|
|
|
34296
34465
|
// components/ProgressPill.tsx
|
|
34297
34466
|
var import_react18 = require("react");
|
|
34298
34467
|
var import_react_native23 = require("react-native");
|
|
34468
|
+
var import_react_native_reanimated4 = __toESM(require("react-native-reanimated"));
|
|
34299
34469
|
var import_core21 = require("@papyrus-sdk/core");
|
|
34300
34470
|
|
|
34301
34471
|
// components/progressPillMode.ts
|
|
@@ -34329,12 +34499,20 @@ function ProgressPill({
|
|
|
34329
34499
|
textLength,
|
|
34330
34500
|
comicLayoutMode,
|
|
34331
34501
|
viewMode,
|
|
34502
|
+
epubReadingMode,
|
|
34503
|
+
epubLocation,
|
|
34332
34504
|
locale,
|
|
34333
34505
|
uiTheme,
|
|
34334
34506
|
accentColor,
|
|
34335
34507
|
mobileChromeVisible,
|
|
34336
34508
|
mobileProgressPillVisible
|
|
34337
34509
|
} = (0, import_core21.useViewerStore)();
|
|
34510
|
+
const chromeVisible = mobileChromeVisible && mobileProgressPillVisible;
|
|
34511
|
+
const chromeProgress = useNativeInkMotion(chromeVisible, documentType === "epub");
|
|
34512
|
+
const chromeMotion = (0, import_react_native_reanimated4.useAnimatedStyle)(() => {
|
|
34513
|
+
"worklet";
|
|
34514
|
+
return { opacity: chromeProgress.value };
|
|
34515
|
+
});
|
|
34338
34516
|
const t = getStrings(locale);
|
|
34339
34517
|
const isDark = uiTheme === "dark";
|
|
34340
34518
|
const offsets = resolveMobileChromeOffsets(usePapyrusSafeAreaInsets());
|
|
@@ -34379,10 +34557,10 @@ function ProgressPill({
|
|
|
34379
34557
|
return `${displayedPage}/${pageCount || 0}`;
|
|
34380
34558
|
}
|
|
34381
34559
|
if (documentType === "epub") {
|
|
34382
|
-
return `Cap. ${displayedPage} \xB7 ${percent}%`;
|
|
34560
|
+
return `Cap. ${displayedPage} \xB7 ${scrubPreviewPage === null && epubLocation ? clampPercent(epubLocation.progress * 100) : percent}%`;
|
|
34383
34561
|
}
|
|
34384
34562
|
return `${percent}%`;
|
|
34385
|
-
}, [displayedPage, documentType, pageCount]);
|
|
34563
|
+
}, [displayedPage, documentType, pageCount, epubLocation, scrubPreviewPage]);
|
|
34386
34564
|
const thumbTop = resolvePageScrubberThumbTop({
|
|
34387
34565
|
currentPage,
|
|
34388
34566
|
trackHeight,
|
|
@@ -34424,7 +34602,7 @@ function ProgressPill({
|
|
|
34424
34602
|
},
|
|
34425
34603
|
[]
|
|
34426
34604
|
);
|
|
34427
|
-
if (!shouldRenderPageScrubber({
|
|
34605
|
+
if (!(documentType === "epub" && mobileProgressPillVisible) && !shouldRenderPageScrubber({
|
|
34428
34606
|
mobileChromeVisible,
|
|
34429
34607
|
mobileProgressPillVisible,
|
|
34430
34608
|
isScrubbing: isScrubbingRef.current
|
|
@@ -34455,7 +34633,7 @@ function ProgressPill({
|
|
|
34455
34633
|
}
|
|
34456
34634
|
);
|
|
34457
34635
|
}
|
|
34458
|
-
const progressViewMode = documentType === "comic" ? comicLayoutMode === "single" ? "single" : "continuous" : viewMode;
|
|
34636
|
+
const progressViewMode = documentType === "comic" ? comicLayoutMode === "single" ? "single" : "continuous" : documentType === "epub" ? epubReadingMode === "paged" ? "single" : "continuous" : viewMode;
|
|
34459
34637
|
const pillMode = resolveProgressPillMode(progressViewMode, currentPage, pageCount);
|
|
34460
34638
|
if (pillMode.kind === "navigation" && navigationInDock) return null;
|
|
34461
34639
|
if (pillMode.kind === "navigation") {
|
|
@@ -34646,11 +34824,14 @@ function ProgressPill({
|
|
|
34646
34824
|
}
|
|
34647
34825
|
const responderPanHandlers = scrubberResponderRef.current?.panHandlers ?? {};
|
|
34648
34826
|
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
34649
|
-
|
|
34827
|
+
import_react_native_reanimated4.default.View,
|
|
34650
34828
|
{
|
|
34651
|
-
pointerEvents: "box-none",
|
|
34829
|
+
pointerEvents: chromeVisible ? "box-none" : "none",
|
|
34830
|
+
accessibilityElementsHidden: !chromeVisible,
|
|
34831
|
+
importantForAccessibility: chromeVisible ? "auto" : "no-hide-descendants",
|
|
34652
34832
|
style: [
|
|
34653
34833
|
styles21.frame,
|
|
34834
|
+
chromeMotion,
|
|
34654
34835
|
resolvePageScrubberOverlayStyle(),
|
|
34655
34836
|
{
|
|
34656
34837
|
top: offsets.progress,
|
|
@@ -35379,6 +35560,7 @@ function ReadingShell({
|
|
|
35379
35560
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
35380
35561
|
Topbar_default,
|
|
35381
35562
|
{
|
|
35563
|
+
documentType,
|
|
35382
35564
|
engine,
|
|
35383
35565
|
title,
|
|
35384
35566
|
onOpenSettings: () => openDestination("display"),
|
|
@@ -35389,6 +35571,7 @@ function ReadingShell({
|
|
|
35389
35571
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_react_native26.View, { style: styles24.viewerStage, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
35390
35572
|
Viewer_default,
|
|
35391
35573
|
{
|
|
35574
|
+
documentType,
|
|
35392
35575
|
engine,
|
|
35393
35576
|
...viewerProps,
|
|
35394
35577
|
pageScrubActive
|
|
@@ -35513,6 +35696,7 @@ function ReadingShell({
|
|
|
35513
35696
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
35514
35697
|
PageJumpModal,
|
|
35515
35698
|
{
|
|
35699
|
+
documentType,
|
|
35516
35700
|
visible: pageJumpOpen,
|
|
35517
35701
|
currentPage,
|
|
35518
35702
|
pageCount,
|