@papyrus-sdk/ui-react-native 0.2.35-beta.9 → 0.2.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +12 -2
- package/dist/index.d.ts +12 -2
- package/dist/index.js +520 -229
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +533 -241
- package/dist/index.mjs.map +1 -1
- package/package.json +7 -7
- 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 +48 -0
- package/runtime/index.html +224 -79
- package/runtime/runtime.js +224 -79
- 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,21 +21917,37 @@ 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) => {
|
|
21930
|
+
if (selectionSession !== documentSessionId || selectionRendition !== rendition) return;
|
|
21836
21931
|
const start = location && location.start;
|
|
21837
21932
|
let index = start && Number.isInteger(start.index) ? start.index : -1;
|
|
21838
21933
|
if (index < 0 && start && start.href) index = getSpineIndexByHref(start.href);
|
|
21839
21934
|
if (index < 0 || index >= spineItems.length) return;
|
|
21840
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
|
+
}
|
|
21841
21951
|
const nextPage = index + 1;
|
|
21842
21952
|
if (nextPage === currentPage) return;
|
|
21843
21953
|
currentPage = nextPage;
|
|
@@ -21845,21 +21955,23 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
21845
21955
|
});
|
|
21846
21956
|
}
|
|
21847
21957
|
|
|
21958
|
+
applyEpubZoom();
|
|
21848
21959
|
sendEpubDiagnostic('epub.display.start', diagnosticPayload);
|
|
21849
21960
|
await withEpubStageTimeout(
|
|
21850
|
-
|
|
21961
|
+
rendition.display(target || spineItems[0]?.href),
|
|
21851
21962
|
'rendition.display',
|
|
21852
21963
|
diagnosticPayload,
|
|
21853
21964
|
);
|
|
21854
21965
|
if (!isCurrentLoad()) throw new Error('EPUB load superseded by a newer load');
|
|
21855
21966
|
sendEpubDiagnostic('epub.display.end', diagnosticPayload);
|
|
21967
|
+
const resizeRendition=rendition;
|
|
21968
|
+
epubResizeAnchor=window.PapyrusEpubReader.installResizeAnchor(resizeRendition.manager,()=>resizeRendition.location?.start?.cfi);
|
|
21856
21969
|
if (
|
|
21857
21970
|
rendition &&
|
|
21858
21971
|
rendition.manager &&
|
|
21859
21972
|
typeof rendition.manager.on === 'function' &&
|
|
21860
21973
|
typeof rendition.on === 'function'
|
|
21861
21974
|
) {
|
|
21862
|
-
let touchStart = null;
|
|
21863
21975
|
let lastScrollOffset = -1;
|
|
21864
21976
|
const manager = rendition.manager;
|
|
21865
21977
|
epubScrollDiagnostics = createEpubScrollDiagnostics(manager);
|
|
@@ -21934,48 +22046,19 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
21934
22046
|
return result;
|
|
21935
22047
|
};
|
|
21936
22048
|
}
|
|
21937
|
-
const
|
|
21938
|
-
const touch =
|
|
21939
|
-
(event && event.changedTouches && event.changedTouches[0]) ||
|
|
21940
|
-
(event && event.touches && event.touches[0]);
|
|
21941
|
-
if (!touch) return null;
|
|
21942
|
-
const x = Number(touch.screenX ?? touch.clientX);
|
|
21943
|
-
const y = Number(touch.screenY ?? touch.clientY);
|
|
21944
|
-
return Number.isFinite(x) && Number.isFinite(y) ? { x, y } : null;
|
|
21945
|
-
};
|
|
21946
|
-
const handleScroll = (event) => {
|
|
22049
|
+
const handleScroll = event => {
|
|
21947
22050
|
const offsetY = Math.max(0, Number(event && event.top) || 0);
|
|
21948
22051
|
epubScrollDiagnostics && epubScrollDiagnostics.scroll(event);
|
|
21949
|
-
if (Math.abs(offsetY
|
|
21950
|
-
lastScrollOffset
|
|
21951
|
-
sendEvent('VIEWER_SCROLL',
|
|
22052
|
+
if (Math.abs(offsetY-lastScrollOffset)<1) return;
|
|
22053
|
+
lastScrollOffset=offsetY;
|
|
22054
|
+
sendEvent('VIEWER_SCROLL',{offsetY});
|
|
21952
22055
|
};
|
|
21953
|
-
const handleTouchStart = (event) => {
|
|
21954
|
-
touchStart = getTouchPoint(event);
|
|
21955
|
-
epubScrollDiagnostics && epubScrollDiagnostics.touchStart(event);
|
|
21956
|
-
};
|
|
21957
|
-
const handleTouchMove = (event) => {
|
|
21958
|
-
epubScrollDiagnostics && epubScrollDiagnostics.touchMove(event);
|
|
21959
|
-
};
|
|
21960
|
-
const handleTouchEnd = (event) => {
|
|
21961
|
-
const end = getTouchPoint(event);
|
|
21962
|
-
const start = touchStart;
|
|
21963
|
-
touchStart = null;
|
|
21964
|
-
const selectedText = event?.target?.ownerDocument?.defaultView?.getSelection?.()?.toString().trim() || '';
|
|
21965
|
-
if (!selectedText && start && end && Math.hypot(end.x - start.x, end.y - start.y) <= 12) {
|
|
21966
|
-
sendEvent('VIEWER_TAP', {});
|
|
21967
|
-
}
|
|
21968
|
-
epubScrollDiagnostics && epubScrollDiagnostics.touchEnd(event);
|
|
21969
|
-
};
|
|
21970
|
-
|
|
21971
22056
|
manager.on('scroll', handleScroll);
|
|
21972
22057
|
const handleScrolled = (event) => {
|
|
21973
22058
|
epubScrollDiagnostics && epubScrollDiagnostics.settled(event);
|
|
21974
22059
|
};
|
|
21975
22060
|
manager.on('scrolled', handleScrolled);
|
|
21976
|
-
|
|
21977
|
-
rendition.on('touchmove', handleTouchMove);
|
|
21978
|
-
rendition.on('touchend', handleTouchEnd);
|
|
22061
|
+
|
|
21979
22062
|
epubInteractionCleanup = () => {
|
|
21980
22063
|
epubSelectionCleanups.forEach((cleanup) => cleanup());
|
|
21981
22064
|
epubSelectionCleanups.clear();
|
|
@@ -21984,16 +22067,9 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
21984
22067
|
if (originalEnqueue) queue.enqueue = originalEnqueue;
|
|
21985
22068
|
if (typeof manager.off === 'function') manager.off('scroll', handleScroll);
|
|
21986
22069
|
if (typeof manager.off === 'function') manager.off('scrolled', handleScrolled);
|
|
21987
|
-
if (typeof rendition.off === 'function') {
|
|
21988
|
-
rendition.off('touchstart', handleTouchStart);
|
|
21989
|
-
rendition.off('touchmove', handleTouchMove);
|
|
21990
|
-
rendition.off('touchend', handleTouchEnd);
|
|
21991
|
-
}
|
|
21992
22070
|
epubScrollDiagnostics = null;
|
|
21993
22071
|
};
|
|
21994
22072
|
}
|
|
21995
|
-
applyEpubZoom();
|
|
21996
|
-
|
|
21997
22073
|
const outline = await withEpubStageTimeout(
|
|
21998
22074
|
buildOutline(),
|
|
21999
22075
|
'outline',
|
|
@@ -22007,6 +22083,8 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
22007
22083
|
return { pageCount, outline };
|
|
22008
22084
|
};
|
|
22009
22085
|
|
|
22086
|
+
let epubNavigationQueue = Promise.resolve();
|
|
22087
|
+
let epubNavigationRequest = 0;
|
|
22010
22088
|
const displayEpubPage = async (pageIndex) => {
|
|
22011
22089
|
if (!rendition) return;
|
|
22012
22090
|
const item = spineItems[pageIndex];
|
|
@@ -22016,9 +22094,19 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
22016
22094
|
target,
|
|
22017
22095
|
pageIndex,
|
|
22018
22096
|
});
|
|
22019
|
-
|
|
22020
|
-
|
|
22021
|
-
|
|
22097
|
+
const activeRendition = rendition;
|
|
22098
|
+
const session = documentSessionId;
|
|
22099
|
+
const request = ++epubNavigationRequest;
|
|
22100
|
+
const navigation = epubNavigationQueue.catch(() => {}).then(async () => {
|
|
22101
|
+
if (request !== epubNavigationRequest || session !== documentSessionId || activeRendition !== rendition) return;
|
|
22102
|
+
epubResizeAnchor?.invalidate();
|
|
22103
|
+
await activeRendition.display(target);
|
|
22104
|
+
if (request !== epubNavigationRequest || session !== documentSessionId || activeRendition !== rendition) return;
|
|
22105
|
+
currentPage = pageIndex + 1;
|
|
22106
|
+
sendState();
|
|
22107
|
+
});
|
|
22108
|
+
epubNavigationQueue = navigation;
|
|
22109
|
+
await navigation;
|
|
22022
22110
|
};
|
|
22023
22111
|
|
|
22024
22112
|
const getTextContent = async (pageIndex) => {
|
|
@@ -22120,6 +22208,8 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
22120
22208
|
};
|
|
22121
22209
|
|
|
22122
22210
|
let nativeMenuSelection = null;
|
|
22211
|
+
let epubViewMode = "single";
|
|
22212
|
+
let epubLocation = null;
|
|
22123
22213
|
|
|
22124
22214
|
const handleCommand = async (message) => {
|
|
22125
22215
|
const { id, kind, payload } = message;
|
|
@@ -22132,6 +22222,11 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
22132
22222
|
epubAnnotations = [];
|
|
22133
22223
|
annotationDocumentId = undefined;
|
|
22134
22224
|
zoom = 1.0;
|
|
22225
|
+
epubViewMode = payload.epubMode === "chapter-scroll" ? "continuous" : "single";
|
|
22226
|
+
epubLocation = null;
|
|
22227
|
+
nativeMenuSelection = null;
|
|
22228
|
+
epubNavigationRequest += 1;
|
|
22229
|
+
epubNavigationQueue = Promise.resolve();
|
|
22135
22230
|
|
|
22136
22231
|
if (currentType === 'text') {
|
|
22137
22232
|
const result = await loadText(
|
|
@@ -22186,17 +22281,24 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
22186
22281
|
epubAnnotationRenderers.forEach(renderer => renderer.schedule());
|
|
22187
22282
|
} else {
|
|
22188
22283
|
const annotation = epubAnnotations.find(a => a.id === payload.annotationId);
|
|
22189
|
-
if (!annotation) throw new Error('Annotation not available');
|
|
22284
|
+
if (!annotation || (annotation.anchor.documentId && annotation.anchor.documentId !== annotationDocumentId)) throw new Error('Annotation not available for this document');
|
|
22190
22285
|
// Navigation uses the CFI, never a synthetic percentage/page rectangle.
|
|
22191
22286
|
const navigationSession = documentSessionId;
|
|
22192
22287
|
const activeRendition = rendition;
|
|
22193
22288
|
// Open the confirmed chapter first, resolve its quote, then navigate its actual range.
|
|
22194
|
-
|
|
22195
|
-
|
|
22196
|
-
|
|
22197
|
-
|
|
22198
|
-
|
|
22199
|
-
|
|
22289
|
+
epubNavigationRequest += 1;
|
|
22290
|
+
const navigation = epubNavigationQueue.catch(() => {}).then(async () => {
|
|
22291
|
+
if(navigationSession !== documentSessionId || activeRendition !== rendition)throw new Error('Stale EPUB navigation');
|
|
22292
|
+
epubResizeAnchor?.invalidate();
|
|
22293
|
+
await activeRendition.display(annotation.anchor.href);
|
|
22294
|
+
if(navigationSession !== documentSessionId || activeRendition !== rendition)throw new Error('Stale EPUB navigation');
|
|
22295
|
+
const contents = activeRendition.getContents().find(c => spineItems[c.sectionIndex]?.href === annotation.anchor.href);
|
|
22296
|
+
const range = contents && window.PapyrusEpubAnnotations.resolveRange(contents,annotation.anchor);
|
|
22297
|
+
if(!range)throw new Error('EPUB anchor unresolved');
|
|
22298
|
+
await activeRendition.display(contents.cfiFromRange(range));
|
|
22299
|
+
});
|
|
22300
|
+
epubNavigationQueue = navigation;
|
|
22301
|
+
await navigation;
|
|
22200
22302
|
}
|
|
22201
22303
|
sendResponse(id,true,null); return;
|
|
22202
22304
|
}
|
|
@@ -22223,12 +22325,55 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
22223
22325
|
return;
|
|
22224
22326
|
}
|
|
22225
22327
|
|
|
22328
|
+
if (kind === 'epub-turn-page') {
|
|
22329
|
+
if (epubViewMode !== 'single') {sendResponse(id,true,null); return;}
|
|
22330
|
+
if (currentType !== 'epub' || payload.documentSessionId !== documentSessionId) throw new Error('Stale EPUB navigation');
|
|
22331
|
+
const active = rendition;
|
|
22332
|
+
epubNavigationQueue = epubNavigationQueue.catch(() => {}).then(() => {
|
|
22333
|
+
if (active !== rendition || payload.documentSessionId !== documentSessionId) return;
|
|
22334
|
+
epubResizeAnchor?.invalidate();
|
|
22335
|
+
return payload.direction < 0 ? active.prev() : active.next();
|
|
22336
|
+
});
|
|
22337
|
+
await epubNavigationQueue;
|
|
22338
|
+
sendResponse(id,true,null); return;
|
|
22339
|
+
}
|
|
22340
|
+
|
|
22341
|
+
if (kind === 'set-epub-view-mode') {
|
|
22342
|
+
if (currentType !== 'epub' || payload.documentSessionId !== documentSessionId) throw new Error('Stale EPUB layout session');
|
|
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;
|
|
22359
|
+
}
|
|
22360
|
+
|
|
22226
22361
|
if (kind === 'set-zoom') {
|
|
22227
|
-
|
|
22228
|
-
|
|
22229
|
-
|
|
22230
|
-
|
|
22231
|
-
|
|
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;
|
|
22232
22377
|
}
|
|
22233
22378
|
|
|
22234
22379
|
if (kind === 'set-rotation') {
|
|
@@ -23391,6 +23536,7 @@ var IconToolStrikeout = ({
|
|
|
23391
23536
|
),
|
|
23392
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 })
|
|
23393
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" }) });
|
|
23394
23540
|
var IconCopy = ({
|
|
23395
23541
|
size = 20,
|
|
23396
23542
|
color = defaultColor,
|
|
@@ -23455,6 +23601,39 @@ var IconToolNote = ({
|
|
|
23455
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" }),
|
|
23456
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" })
|
|
23457
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
|
+
] });
|
|
23458
23637
|
var IconUnderline = ({
|
|
23459
23638
|
size = 24,
|
|
23460
23639
|
color = "#60a5fa",
|
|
@@ -25883,8 +26062,38 @@ var styles = import_react_native.StyleSheet.create({
|
|
|
25883
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;
|
|
25884
26063
|
var PageRenderer_default = (0, import_react2.memo)(PageRenderer, arePageRendererPropsEqual);
|
|
25885
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
|
+
|
|
25886
26095
|
// components/WebViewViewer.tsx
|
|
25887
|
-
var
|
|
26096
|
+
var import_react4 = require("react");
|
|
25888
26097
|
var import_react_native2 = require("react-native");
|
|
25889
26098
|
var import_clipboard3 = __toESM(require("@react-native-clipboard/clipboard"));
|
|
25890
26099
|
var import_react_native_webview = __toESM(require("react-native-webview"));
|
|
@@ -25952,7 +26161,7 @@ function parseEpubAnnotationEvent(raw, session, documentId) {
|
|
|
25952
26161
|
}
|
|
25953
26162
|
|
|
25954
26163
|
// components/WebViewViewer.tsx
|
|
25955
|
-
var
|
|
26164
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
25956
26165
|
var runtimeAsset = require_runtime();
|
|
25957
26166
|
var resolveRuntimeSource = (asset) => {
|
|
25958
26167
|
if (typeof asset === "string") {
|
|
@@ -25972,6 +26181,7 @@ var resolveRuntimeSource = (asset) => {
|
|
|
25972
26181
|
};
|
|
25973
26182
|
var WebViewViewer = ({
|
|
25974
26183
|
engine,
|
|
26184
|
+
documentType,
|
|
25975
26185
|
documentId,
|
|
25976
26186
|
onDefineSelection,
|
|
25977
26187
|
defineSelectionMode,
|
|
@@ -25979,19 +26189,20 @@ var WebViewViewer = ({
|
|
|
25979
26189
|
onScrollOffset,
|
|
25980
26190
|
onTap
|
|
25981
26191
|
}) => {
|
|
25982
|
-
const webViewRef = (0,
|
|
25983
|
-
const
|
|
25984
|
-
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);
|
|
25985
26196
|
const t = getStrings(locale);
|
|
25986
26197
|
const bridgeEngine = engine;
|
|
25987
|
-
const runtimeSource = (0,
|
|
26198
|
+
const runtimeSource = (0, import_react4.useMemo)(
|
|
25988
26199
|
() => resolveRuntimeSource(
|
|
25989
26200
|
bridgeEngine.getWebViewRuntimeSource?.() ?? runtimeAsset
|
|
25990
26201
|
),
|
|
25991
26202
|
[bridgeEngine]
|
|
25992
26203
|
);
|
|
25993
|
-
const [runtimeHtml, setRuntimeHtml] = (0,
|
|
25994
|
-
(0,
|
|
26204
|
+
const [runtimeHtml, setRuntimeHtml] = (0, import_react4.useState)(null);
|
|
26205
|
+
(0, import_react4.useEffect)(() => {
|
|
25995
26206
|
let active = true;
|
|
25996
26207
|
if ("html" in runtimeSource) {
|
|
25997
26208
|
setRuntimeHtml(runtimeSource.html);
|
|
@@ -26012,7 +26223,7 @@ var WebViewViewer = ({
|
|
|
26012
26223
|
active = false;
|
|
26013
26224
|
};
|
|
26014
26225
|
}, [runtimeSource]);
|
|
26015
|
-
const webViewSource = (0,
|
|
26226
|
+
const webViewSource = (0, import_react4.useMemo)(() => {
|
|
26016
26227
|
if (runtimeHtml !== null) {
|
|
26017
26228
|
return {
|
|
26018
26229
|
html: runtimeHtml,
|
|
@@ -26023,13 +26234,13 @@ var WebViewViewer = ({
|
|
|
26023
26234
|
return runtimeSource;
|
|
26024
26235
|
}, [runtimeHtml, runtimeSource]);
|
|
26025
26236
|
const runtimeConfig = bridgeEngine.getWebViewRuntimeConfig?.();
|
|
26026
|
-
const runtimeConfigScript = (0,
|
|
26237
|
+
const runtimeConfigScript = (0, import_react4.useMemo)(() => {
|
|
26027
26238
|
if (!runtimeConfig) return void 0;
|
|
26028
26239
|
return `window.__PAPYRUS_RUNTIME_CONFIG__=${JSON.stringify(
|
|
26029
26240
|
runtimeConfig
|
|
26030
26241
|
)};true;`;
|
|
26031
26242
|
}, [runtimeConfig]);
|
|
26032
|
-
(0,
|
|
26243
|
+
(0, import_react4.useEffect)(() => {
|
|
26033
26244
|
bridgeEngine.attachWebView?.({
|
|
26034
26245
|
postMessage: (message) => {
|
|
26035
26246
|
if (__DEV__) {
|
|
@@ -26043,10 +26254,10 @@ var WebViewViewer = ({
|
|
|
26043
26254
|
bridgeEngine.detachWebView?.();
|
|
26044
26255
|
};
|
|
26045
26256
|
}, [bridgeEngine]);
|
|
26046
|
-
(0,
|
|
26257
|
+
(0, import_react4.useEffect)(() => {
|
|
26047
26258
|
setSelection(null);
|
|
26048
26259
|
}, [engine, documentId]);
|
|
26049
|
-
(0,
|
|
26260
|
+
(0, import_react4.useEffect)(() => {
|
|
26050
26261
|
if (!isLoaded) return;
|
|
26051
26262
|
let active = true;
|
|
26052
26263
|
void bridgeEngine.syncEpubAnnotations?.(annotations, documentId, { comment: t.annotationNote }).catch(() => {
|
|
@@ -26061,6 +26272,10 @@ var WebViewViewer = ({
|
|
|
26061
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 }));
|
|
26062
26273
|
setSelection(null);
|
|
26063
26274
|
};
|
|
26275
|
+
(0, import_react4.useEffect)(() => {
|
|
26276
|
+
if (!isLoaded) return;
|
|
26277
|
+
webViewRef.current?.postMessage(JSON.stringify({ id: "epub-layout", kind: "set-epub-view-mode", payload: { epubMode: epubReadingMode, documentSessionId: bridgeEngine.getWebViewDocumentSessionId?.() } }));
|
|
26278
|
+
}, [isLoaded, epubReadingMode, bridgeEngine]);
|
|
26064
26279
|
const sendSelectionCommand = (key) => {
|
|
26065
26280
|
webViewRef.current?.postMessage(JSON.stringify({
|
|
26066
26281
|
type: "epub-selection-action",
|
|
@@ -26084,6 +26299,11 @@ var WebViewViewer = ({
|
|
|
26084
26299
|
let annotationRaw = raw;
|
|
26085
26300
|
try {
|
|
26086
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?.();
|
|
26087
26307
|
if (message.type === "event" && message.name === "EPUB_SELECTION_ACTION") {
|
|
26088
26308
|
action = message.payload?.action;
|
|
26089
26309
|
annotationRaw = JSON.stringify({ ...message, name: "EPUB_TEXT_SELECTED" });
|
|
@@ -26147,7 +26367,7 @@ var WebViewViewer = ({
|
|
|
26147
26367
|
console.warn("[Papyrus WebView] error", event.nativeEvent);
|
|
26148
26368
|
}
|
|
26149
26369
|
};
|
|
26150
|
-
const themeOverlayStyle = (0,
|
|
26370
|
+
const themeOverlayStyle = (0, import_react4.useMemo)(() => {
|
|
26151
26371
|
switch (pageTheme) {
|
|
26152
26372
|
case "sepia":
|
|
26153
26373
|
return styles2.themeSepia;
|
|
@@ -26159,7 +26379,7 @@ var WebViewViewer = ({
|
|
|
26159
26379
|
return styles2.themeNone;
|
|
26160
26380
|
}
|
|
26161
26381
|
}, [pageTheme]);
|
|
26162
|
-
const allowingReadAccessToURL = (0,
|
|
26382
|
+
const allowingReadAccessToURL = (0, import_react4.useMemo)(() => {
|
|
26163
26383
|
if (!runtimeSource || typeof runtimeSource !== "object") return void 0;
|
|
26164
26384
|
if ("uri" in runtimeSource && runtimeSource.uri) {
|
|
26165
26385
|
return runtimeSource.uri;
|
|
@@ -26172,8 +26392,8 @@ var WebViewViewer = ({
|
|
|
26172
26392
|
maxWidth: resolvedMaxPageWidth,
|
|
26173
26393
|
alignSelf: "center"
|
|
26174
26394
|
} : void 0;
|
|
26175
|
-
return /* @__PURE__ */ (0,
|
|
26176
|
-
/* @__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)(
|
|
26177
26397
|
import_react_native_webview.default,
|
|
26178
26398
|
{
|
|
26179
26399
|
ref: webViewRef,
|
|
@@ -26197,7 +26417,7 @@ var WebViewViewer = ({
|
|
|
26197
26417
|
style: [styles2.webview, cappedWebViewStyle]
|
|
26198
26418
|
}
|
|
26199
26419
|
),
|
|
26200
|
-
/* @__PURE__ */ (0,
|
|
26420
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
26201
26421
|
import_react_native2.View,
|
|
26202
26422
|
{
|
|
26203
26423
|
pointerEvents: "none",
|
|
@@ -26299,22 +26519,22 @@ function getNearbyPdfNotes(annotations, id) {
|
|
|
26299
26519
|
// components/PdfNoteChooser.tsx
|
|
26300
26520
|
var import_react_native3 = require("react-native");
|
|
26301
26521
|
var import_core5 = require("@papyrus-sdk/core");
|
|
26302
|
-
var
|
|
26522
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
26303
26523
|
function PdfNoteChooser({ notes, title, cancel, onSelect, onClose }) {
|
|
26304
|
-
return /* @__PURE__ */ (0,
|
|
26305
|
-
/* @__PURE__ */ (0,
|
|
26306
|
-
/* @__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: [
|
|
26307
26527
|
index + 1,
|
|
26308
26528
|
". ",
|
|
26309
26529
|
(0, import_core5.getAnnotationNote)(item) || (0, import_core5.getAnnotationQuote)(item)
|
|
26310
26530
|
] }) }) }),
|
|
26311
|
-
/* @__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 }) })
|
|
26312
26532
|
] }) }) });
|
|
26313
26533
|
}
|
|
26314
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 } });
|
|
26315
26535
|
|
|
26316
26536
|
// components/DedicatedAndroidPdfViewer.tsx
|
|
26317
|
-
var
|
|
26537
|
+
var import_react5 = require("react");
|
|
26318
26538
|
var import_react_native4 = require("react-native");
|
|
26319
26539
|
var import_core6 = require("@papyrus-sdk/core");
|
|
26320
26540
|
var import_engine_native2 = require("@papyrus-sdk/engine-native");
|
|
@@ -26335,7 +26555,7 @@ var resolvePageTapChromeVisibility = ({
|
|
|
26335
26555
|
};
|
|
26336
26556
|
|
|
26337
26557
|
// components/DedicatedAndroidPdfViewer.tsx
|
|
26338
|
-
var
|
|
26558
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
26339
26559
|
var TEXT_MARKUP_TOOLS2 = /* @__PURE__ */ new Set(["highlight", "underline", "squiggly", "strikeout"]);
|
|
26340
26560
|
var MOBILE_CHROME_HIDE_DELTA = 28;
|
|
26341
26561
|
var MOBILE_CHROME_SHOW_DELTA = 22;
|
|
@@ -26364,7 +26584,7 @@ function DedicatedAndroidPdfViewer({
|
|
|
26364
26584
|
const searchResults = (0, import_core6.useViewerStore)((state) => state.searchResults);
|
|
26365
26585
|
const annotationNavigationRequest = (0, import_core6.useViewerStore)((state) => state.annotationNavigationRequest);
|
|
26366
26586
|
const annotations = (0, import_core6.useViewerStore)((state) => state.annotations);
|
|
26367
|
-
const [pendingNotes, setPendingNotes] = (0,
|
|
26587
|
+
const [pendingNotes, setPendingNotes] = (0, import_react5.useState)([]);
|
|
26368
26588
|
const handleAnnotationTap = (id) => {
|
|
26369
26589
|
const nearby = getNearbyPdfNotes(annotations, id);
|
|
26370
26590
|
if (nearby.length < 2) {
|
|
@@ -26392,30 +26612,30 @@ function DedicatedAndroidPdfViewer({
|
|
|
26392
26612
|
maxWidth: resolvedMaxPageWidth,
|
|
26393
26613
|
alignSelf: "center"
|
|
26394
26614
|
} : void 0;
|
|
26395
|
-
const [selection, setSelection] = (0,
|
|
26396
|
-
const selectionRef = (0,
|
|
26397
|
-
const lastVisiblePagesKeyRef = (0,
|
|
26398
|
-
const lastScrollOffsetYRef = (0,
|
|
26399
|
-
const scrollDownAccumRef = (0,
|
|
26400
|
-
const scrollUpAccumRef = (0,
|
|
26401
|
-
const pendingChromeShowTimeoutRef = (0,
|
|
26402
|
-
const chromeVisibleRef = (0,
|
|
26403
|
-
const lastZoomChangedAtRef = (0,
|
|
26404
|
-
(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)(() => {
|
|
26405
26625
|
chromeVisibleRef.current = mobileChromeVisible;
|
|
26406
26626
|
}, [mobileChromeVisible]);
|
|
26407
|
-
const clearPendingChromeShow = (0,
|
|
26627
|
+
const clearPendingChromeShow = (0, import_react5.useCallback)(() => {
|
|
26408
26628
|
if (pendingChromeShowTimeoutRef.current) {
|
|
26409
26629
|
clearTimeout(pendingChromeShowTimeoutRef.current);
|
|
26410
26630
|
pendingChromeShowTimeoutRef.current = null;
|
|
26411
26631
|
}
|
|
26412
26632
|
}, []);
|
|
26413
|
-
const setMobileChromeVisible = (0,
|
|
26633
|
+
const setMobileChromeVisible = (0, import_react5.useCallback)((visible, reason) => {
|
|
26414
26634
|
if (chromeVisibleRef.current === visible) return;
|
|
26415
26635
|
chromeVisibleRef.current = visible;
|
|
26416
26636
|
setDocumentState({ mobileChromeVisible: visible });
|
|
26417
26637
|
}, [setDocumentState]);
|
|
26418
|
-
const trackMobileChromeByOffset = (0,
|
|
26638
|
+
const trackMobileChromeByOffset = (0, import_react5.useCallback)((offsetY, reasonPrefix) => {
|
|
26419
26639
|
const safeOffset = Math.max(0, offsetY);
|
|
26420
26640
|
const delta = safeOffset - lastScrollOffsetYRef.current;
|
|
26421
26641
|
lastScrollOffsetYRef.current = safeOffset;
|
|
@@ -26451,12 +26671,12 @@ function DedicatedAndroidPdfViewer({
|
|
|
26451
26671
|
}
|
|
26452
26672
|
}
|
|
26453
26673
|
}, [clearPendingChromeShow, setMobileChromeVisible]);
|
|
26454
|
-
(0,
|
|
26674
|
+
(0, import_react5.useEffect)(() => {
|
|
26455
26675
|
return () => {
|
|
26456
26676
|
clearPendingChromeShow();
|
|
26457
26677
|
};
|
|
26458
26678
|
}, [clearPendingChromeShow]);
|
|
26459
|
-
const applySelection = (0,
|
|
26679
|
+
const applySelection = (0, import_react5.useCallback)((type) => {
|
|
26460
26680
|
const sel = selectionRef.current;
|
|
26461
26681
|
if (!sel || !sel.rects || sel.rects.length === 0) return;
|
|
26462
26682
|
const bounds = sel.rects.reduce((acc, r) => ({
|
|
@@ -26478,12 +26698,12 @@ function DedicatedAndroidPdfViewer({
|
|
|
26478
26698
|
setSelection(null);
|
|
26479
26699
|
selectionRef.current = null;
|
|
26480
26700
|
}, [addAnnotation, beginAnnotationDraft, annotationColor, documentId]);
|
|
26481
|
-
return /* @__PURE__ */ (0,
|
|
26482
|
-
/* @__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) => {
|
|
26483
26703
|
setPendingNotes([]);
|
|
26484
26704
|
setSelectedAnnotation(id);
|
|
26485
26705
|
} }),
|
|
26486
|
-
/* @__PURE__ */ (0,
|
|
26706
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
26487
26707
|
import_engine_native2.PapyrusPdfDocumentView,
|
|
26488
26708
|
{
|
|
26489
26709
|
style: [styles4.viewer, cappedViewerStyle],
|
|
@@ -26597,7 +26817,7 @@ var styles4 = import_react_native4.StyleSheet.create({
|
|
|
26597
26817
|
});
|
|
26598
26818
|
|
|
26599
26819
|
// components/DedicatedIosPdfViewer.tsx
|
|
26600
|
-
var
|
|
26820
|
+
var import_react6 = require("react");
|
|
26601
26821
|
var import_react_native5 = require("react-native");
|
|
26602
26822
|
var import_core7 = require("@papyrus-sdk/core");
|
|
26603
26823
|
var import_engine_native3 = require("@papyrus-sdk/engine-native");
|
|
@@ -26694,7 +26914,7 @@ var resolveNativePdfVisiblePages = (pages) => (pages ?? []).flatMap((page) => {
|
|
|
26694
26914
|
});
|
|
26695
26915
|
|
|
26696
26916
|
// components/DedicatedIosPdfViewer.tsx
|
|
26697
|
-
var
|
|
26917
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
26698
26918
|
var MOBILE_CHROME_HIDE_DELTA2 = 28;
|
|
26699
26919
|
var MOBILE_CHROME_SHOW_DELTA2 = 22;
|
|
26700
26920
|
var MOBILE_CHROME_SHOW_DELAY_MS2 = 180;
|
|
@@ -26726,7 +26946,7 @@ function DedicatedIosPdfViewer({
|
|
|
26726
26946
|
const inkStrokeWidth = (0, import_core7.useViewerStore)((state) => state.inkStrokeWidth);
|
|
26727
26947
|
const annotationNavigationRequest = (0, import_core7.useViewerStore)((state) => state.annotationNavigationRequest);
|
|
26728
26948
|
const annotations = (0, import_core7.useViewerStore)((state) => state.annotations);
|
|
26729
|
-
const [pendingNotes, setPendingNotes] = (0,
|
|
26949
|
+
const [pendingNotes, setPendingNotes] = (0, import_react6.useState)([]);
|
|
26730
26950
|
const handleAnnotationTap = (id) => {
|
|
26731
26951
|
const nearby = getNearbyPdfNotes(annotations, id);
|
|
26732
26952
|
if (nearby.length < 2) {
|
|
@@ -26762,16 +26982,16 @@ function DedicatedIosPdfViewer({
|
|
|
26762
26982
|
supportsNativeEditMenu
|
|
26763
26983
|
);
|
|
26764
26984
|
const resolvedMaxPageWidth = typeof maxPageWidth === "number" && Number.isFinite(maxPageWidth) && maxPageWidth > 0 ? maxPageWidth : void 0;
|
|
26765
|
-
const chromeVisibleRef = (0,
|
|
26766
|
-
const lastScrollOffsetYRef = (0,
|
|
26767
|
-
const scrollDownAccumRef = (0,
|
|
26768
|
-
const scrollUpAccumRef = (0,
|
|
26769
|
-
const pendingChromeShowTimeoutRef = (0,
|
|
26770
|
-
const lastZoomChangedAtRef = (0,
|
|
26771
|
-
const lastVisiblePagesKeyRef = (0,
|
|
26772
|
-
const [selection, setSelection] = (0,
|
|
26773
|
-
const selectionRef = (0,
|
|
26774
|
-
(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)(() => {
|
|
26775
26995
|
const pickerActive = supportsNativeEditMenu && activeTool === "ink";
|
|
26776
26996
|
setDocumentState({ nativeInkToolPickerActive: pickerActive });
|
|
26777
26997
|
return () => {
|
|
@@ -26780,15 +27000,15 @@ function DedicatedIosPdfViewer({
|
|
|
26780
27000
|
}
|
|
26781
27001
|
};
|
|
26782
27002
|
}, [activeTool, setDocumentState]);
|
|
26783
|
-
(0,
|
|
27003
|
+
(0, import_react6.useEffect)(() => {
|
|
26784
27004
|
chromeVisibleRef.current = mobileChromeVisible;
|
|
26785
27005
|
}, [mobileChromeVisible]);
|
|
26786
|
-
const clearPendingChromeShow = (0,
|
|
27006
|
+
const clearPendingChromeShow = (0, import_react6.useCallback)(() => {
|
|
26787
27007
|
if (!pendingChromeShowTimeoutRef.current) return;
|
|
26788
27008
|
clearTimeout(pendingChromeShowTimeoutRef.current);
|
|
26789
27009
|
pendingChromeShowTimeoutRef.current = null;
|
|
26790
27010
|
}, []);
|
|
26791
|
-
const setMobileChromeVisible = (0,
|
|
27011
|
+
const setMobileChromeVisible = (0, import_react6.useCallback)(
|
|
26792
27012
|
(visible) => {
|
|
26793
27013
|
if (chromeVisibleRef.current === visible) return;
|
|
26794
27014
|
chromeVisibleRef.current = visible;
|
|
@@ -26796,14 +27016,14 @@ function DedicatedIosPdfViewer({
|
|
|
26796
27016
|
},
|
|
26797
27017
|
[setDocumentState]
|
|
26798
27018
|
);
|
|
26799
|
-
const updateSelection = (0,
|
|
27019
|
+
const updateSelection = (0, import_react6.useCallback)(
|
|
26800
27020
|
(nextSelection) => {
|
|
26801
27021
|
selectionRef.current = nextSelection;
|
|
26802
27022
|
setSelection(nextSelection);
|
|
26803
27023
|
},
|
|
26804
27024
|
[]
|
|
26805
27025
|
);
|
|
26806
|
-
const handleTextSelectionChange = (0,
|
|
27026
|
+
const handleTextSelectionChange = (0, import_react6.useCallback)(
|
|
26807
27027
|
(event) => {
|
|
26808
27028
|
const nextSelection = resolveNativePdfTextSelection(event.nativeEvent);
|
|
26809
27029
|
updateSelection(nextSelection);
|
|
@@ -26816,7 +27036,7 @@ function DedicatedIosPdfViewer({
|
|
|
26816
27036
|
},
|
|
26817
27037
|
[onTextSelected, setSelectedAnnotation, updateSelection]
|
|
26818
27038
|
);
|
|
26819
|
-
const defineSelection = (0,
|
|
27039
|
+
const defineSelection = (0, import_react6.useCallback)(() => {
|
|
26820
27040
|
const currentSelection = selectionRef.current;
|
|
26821
27041
|
if (!currentSelection) return;
|
|
26822
27042
|
onDefineSelection?.({
|
|
@@ -26825,7 +27045,7 @@ function DedicatedIosPdfViewer({
|
|
|
26825
27045
|
});
|
|
26826
27046
|
updateSelection(null);
|
|
26827
27047
|
}, [onDefineSelection, updateSelection]);
|
|
26828
|
-
const handleNativeDefineSelection = (0,
|
|
27048
|
+
const handleNativeDefineSelection = (0, import_react6.useCallback)(
|
|
26829
27049
|
(event) => {
|
|
26830
27050
|
const text = event.nativeEvent?.text;
|
|
26831
27051
|
const pageIndex = event.nativeEvent?.pageIndex;
|
|
@@ -26837,7 +27057,7 @@ function DedicatedIosPdfViewer({
|
|
|
26837
27057
|
},
|
|
26838
27058
|
[onDefineSelection, updateSelection]
|
|
26839
27059
|
);
|
|
26840
|
-
const handleInkToolPickerVisibilityChange = (0,
|
|
27060
|
+
const handleInkToolPickerVisibilityChange = (0, import_react6.useCallback)(
|
|
26841
27061
|
(event) => {
|
|
26842
27062
|
handleNativeInkPickerVisibility(
|
|
26843
27063
|
event.nativeEvent?.visible === true,
|
|
@@ -26846,7 +27066,7 @@ function DedicatedIosPdfViewer({
|
|
|
26846
27066
|
},
|
|
26847
27067
|
[]
|
|
26848
27068
|
);
|
|
26849
|
-
const trackMobileChromeByOffset = (0,
|
|
27069
|
+
const trackMobileChromeByOffset = (0, import_react6.useCallback)(
|
|
26850
27070
|
(offsetY) => {
|
|
26851
27071
|
if (pageCount <= 0) return;
|
|
26852
27072
|
const safeOffset = Math.max(0, offsetY);
|
|
@@ -26882,11 +27102,11 @@ function DedicatedIosPdfViewer({
|
|
|
26882
27102
|
},
|
|
26883
27103
|
[clearPendingChromeShow, pageCount, setMobileChromeVisible]
|
|
26884
27104
|
);
|
|
26885
|
-
(0,
|
|
27105
|
+
(0, import_react6.useEffect)(
|
|
26886
27106
|
() => () => clearPendingChromeShow(),
|
|
26887
27107
|
[clearPendingChromeShow]
|
|
26888
27108
|
);
|
|
26889
|
-
const handleVisiblePagesChange = (0,
|
|
27109
|
+
const handleVisiblePagesChange = (0, import_react6.useCallback)(
|
|
26890
27110
|
(event) => {
|
|
26891
27111
|
const pages = resolveNativePdfVisiblePages(
|
|
26892
27112
|
event.nativeEvent?.pages
|
|
@@ -26901,13 +27121,13 @@ function DedicatedIosPdfViewer({
|
|
|
26901
27121
|
},
|
|
26902
27122
|
[setDocumentState]
|
|
26903
27123
|
);
|
|
26904
|
-
const handleScroll = (0,
|
|
27124
|
+
const handleScroll = (0, import_react6.useCallback)(
|
|
26905
27125
|
(event) => {
|
|
26906
27126
|
trackMobileChromeByOffset(event.nativeEvent?.offsetY ?? 0);
|
|
26907
27127
|
},
|
|
26908
27128
|
[trackMobileChromeByOffset]
|
|
26909
27129
|
);
|
|
26910
|
-
const handleTap = (0,
|
|
27130
|
+
const handleTap = (0, import_react6.useCallback)(() => {
|
|
26911
27131
|
setSelectedAnnotation(null);
|
|
26912
27132
|
const nextVisible = resolvePageTapChromeVisibility({
|
|
26913
27133
|
chromeVisible: chromeVisibleRef.current,
|
|
@@ -26917,7 +27137,7 @@ function DedicatedIosPdfViewer({
|
|
|
26917
27137
|
});
|
|
26918
27138
|
if (nextVisible !== null) setMobileChromeVisible(nextVisible);
|
|
26919
27139
|
}, [activeTool, selectionActive, setMobileChromeVisible, setSelectedAnnotation]);
|
|
26920
|
-
const handleDeleteAnnotation = (0,
|
|
27140
|
+
const handleDeleteAnnotation = (0, import_react6.useCallback)(
|
|
26921
27141
|
(annotationId) => {
|
|
26922
27142
|
deleteAnnotationAndClearSelection(
|
|
26923
27143
|
annotationId,
|
|
@@ -26932,12 +27152,12 @@ function DedicatedIosPdfViewer({
|
|
|
26932
27152
|
maxWidth: resolvedMaxPageWidth,
|
|
26933
27153
|
alignSelf: "center"
|
|
26934
27154
|
} : void 0;
|
|
26935
|
-
return /* @__PURE__ */ (0,
|
|
26936
|
-
/* @__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) => {
|
|
26937
27157
|
setPendingNotes([]);
|
|
26938
27158
|
setSelectedAnnotation(id);
|
|
26939
27159
|
} }),
|
|
26940
|
-
/* @__PURE__ */ (0,
|
|
27160
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
26941
27161
|
import_engine_native3.PapyrusPdfDocumentView,
|
|
26942
27162
|
{
|
|
26943
27163
|
style: [styles5.viewer, cappedViewerStyle],
|
|
@@ -27006,22 +27226,22 @@ function DedicatedIosPdfViewer({
|
|
|
27006
27226
|
onInkToolPickerVisibilityChange: handleInkToolPickerVisibilityChange
|
|
27007
27227
|
}
|
|
27008
27228
|
),
|
|
27009
|
-
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)(
|
|
27010
27230
|
import_react_native5.Pressable,
|
|
27011
27231
|
{
|
|
27012
27232
|
onPress: defineSelection,
|
|
27013
27233
|
style: styles5.fallbackButton,
|
|
27014
27234
|
accessibilityRole: "button",
|
|
27015
27235
|
accessibilityLabel: t.define,
|
|
27016
|
-
children: /* @__PURE__ */ (0,
|
|
27236
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native5.Text, { style: styles5.fallbackButtonText, children: t.define })
|
|
27017
27237
|
}
|
|
27018
27238
|
) }),
|
|
27019
|
-
fallbackDeleteAnnotation && /* @__PURE__ */ (0,
|
|
27239
|
+
fallbackDeleteAnnotation && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
27020
27240
|
import_react_native5.View,
|
|
27021
27241
|
{
|
|
27022
27242
|
style: styles5.annotationDeleteFallback,
|
|
27023
27243
|
pointerEvents: "box-none",
|
|
27024
|
-
children: /* @__PURE__ */ (0,
|
|
27244
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
27025
27245
|
import_react_native5.Pressable,
|
|
27026
27246
|
{
|
|
27027
27247
|
onPress: () => handleDeleteAnnotation(fallbackDeleteAnnotation.id),
|
|
@@ -27029,7 +27249,7 @@ function DedicatedIosPdfViewer({
|
|
|
27029
27249
|
accessibilityRole: "button",
|
|
27030
27250
|
accessibilityLabel: t.deleteAnnotation,
|
|
27031
27251
|
hitSlop: 8,
|
|
27032
|
-
children: /* @__PURE__ */ (0,
|
|
27252
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native5.Text, { style: styles5.annotationDeleteButtonText, children: t.deleteAnnotation })
|
|
27033
27253
|
}
|
|
27034
27254
|
)
|
|
27035
27255
|
}
|
|
@@ -27092,7 +27312,7 @@ var styles5 = import_react_native5.StyleSheet.create({
|
|
|
27092
27312
|
});
|
|
27093
27313
|
|
|
27094
27314
|
// components/NativePdfDocumentViewer.tsx
|
|
27095
|
-
var
|
|
27315
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
27096
27316
|
function NativePdfDocumentViewer({
|
|
27097
27317
|
engine,
|
|
27098
27318
|
documentId,
|
|
@@ -27105,7 +27325,7 @@ function NativePdfDocumentViewer({
|
|
|
27105
27325
|
import_react_native6.Platform.OS
|
|
27106
27326
|
);
|
|
27107
27327
|
if (implementation === "android") {
|
|
27108
|
-
return /* @__PURE__ */ (0,
|
|
27328
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
27109
27329
|
DedicatedAndroidPdfViewer,
|
|
27110
27330
|
{
|
|
27111
27331
|
engine,
|
|
@@ -27118,7 +27338,7 @@ function NativePdfDocumentViewer({
|
|
|
27118
27338
|
);
|
|
27119
27339
|
}
|
|
27120
27340
|
if (implementation === "ios") {
|
|
27121
|
-
return /* @__PURE__ */ (0,
|
|
27341
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
27122
27342
|
DedicatedIosPdfViewer,
|
|
27123
27343
|
{
|
|
27124
27344
|
engine,
|
|
@@ -27172,26 +27392,6 @@ var resolveMobileChromeOffsets = (insets) => ({
|
|
|
27172
27392
|
right: MOBILE_CHROME_METRICS.screenPadding + Math.max(0, insets.right)
|
|
27173
27393
|
});
|
|
27174
27394
|
|
|
27175
|
-
// components/PapyrusSafeArea.tsx
|
|
27176
|
-
var import_react6 = __toESM(require("react"));
|
|
27177
|
-
var import_react_native_safe_area_context = require("react-native-safe-area-context");
|
|
27178
|
-
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
27179
|
-
var papyrusSafeAreaContext = import_react_native_safe_area_context.SafeAreaInsetsContext;
|
|
27180
|
-
var ZERO_SAFE_AREA_INSETS = {
|
|
27181
|
-
top: 0,
|
|
27182
|
-
bottom: 0,
|
|
27183
|
-
left: 0,
|
|
27184
|
-
right: 0
|
|
27185
|
-
};
|
|
27186
|
-
var usePapyrusSafeAreaInsets = () => (0, import_react6.useContext)(papyrusSafeAreaContext) ?? ZERO_SAFE_AREA_INSETS;
|
|
27187
|
-
function PapyrusSafeAreaBoundary({
|
|
27188
|
-
children
|
|
27189
|
-
}) {
|
|
27190
|
-
const insets = (0, import_react6.useContext)(papyrusSafeAreaContext);
|
|
27191
|
-
if (insets) return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_jsx_runtime9.Fragment, { children });
|
|
27192
|
-
return import_react6.default.createElement(import_react_native_safe_area_context.SafeAreaProvider, null, children);
|
|
27193
|
-
}
|
|
27194
|
-
|
|
27195
27395
|
// components/NativeTextDocumentViewer.tsx
|
|
27196
27396
|
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
27197
27397
|
function NativeTextDocumentViewer({
|
|
@@ -27740,6 +27940,7 @@ var scrollViewerListToOffset = (list, offset, animated) => {
|
|
|
27740
27940
|
list.scrollToOffset?.({ offset, animated });
|
|
27741
27941
|
};
|
|
27742
27942
|
var Viewer = ({
|
|
27943
|
+
documentType,
|
|
27743
27944
|
documentId,
|
|
27744
27945
|
engine,
|
|
27745
27946
|
maxPageWidth,
|
|
@@ -29267,14 +29468,8 @@ var Viewer = ({
|
|
|
29267
29468
|
},
|
|
29268
29469
|
[mobilePerf, perfEnabled, scrollPerfSession]
|
|
29269
29470
|
);
|
|
29270
|
-
const handleWebViewScroll = (0, import_react9.useCallback)(
|
|
29271
|
-
|
|
29272
|
-
if (!chromeVisibleRef.current) {
|
|
29273
|
-
setMobileChromeVisible(true, "scroll.webview.recover");
|
|
29274
|
-
}
|
|
29275
|
-
},
|
|
29276
|
-
[setMobileChromeVisible]
|
|
29277
|
-
);
|
|
29471
|
+
const handleWebViewScroll = (0, import_react9.useCallback)((_offsetY) => {
|
|
29472
|
+
}, []);
|
|
29278
29473
|
const handlePageTap = (0, import_react9.useCallback)(() => {
|
|
29279
29474
|
const nextVisible = resolvePageTapChromeVisibility({
|
|
29280
29475
|
chromeVisible: chromeVisibleRef.current,
|
|
@@ -29496,6 +29691,7 @@ var Viewer = ({
|
|
|
29496
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)(
|
|
29497
29692
|
WebViewViewer_default,
|
|
29498
29693
|
{
|
|
29694
|
+
documentType,
|
|
29499
29695
|
engine,
|
|
29500
29696
|
documentId,
|
|
29501
29697
|
onDefineSelection,
|
|
@@ -30042,6 +30238,7 @@ var styles9 = import_react_native11.StyleSheet.create({
|
|
|
30042
30238
|
// components/PageJumpModal.tsx
|
|
30043
30239
|
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
30044
30240
|
function PageJumpModal({
|
|
30241
|
+
documentType,
|
|
30045
30242
|
visible,
|
|
30046
30243
|
currentPage,
|
|
30047
30244
|
pageCount,
|
|
@@ -30068,8 +30265,8 @@ function PageJumpModal({
|
|
|
30068
30265
|
isDark,
|
|
30069
30266
|
maxHeight: 300,
|
|
30070
30267
|
showHeader: true,
|
|
30071
|
-
title: "Ir para p\xE1gina",
|
|
30072
|
-
closeAccessibilityLabel: "
|
|
30268
|
+
title: documentType === "epub" ? "Ir para cap\xEDtulo" : "Ir para p\xE1gina",
|
|
30269
|
+
closeAccessibilityLabel: "Fechar navega\xE7\xE3o",
|
|
30073
30270
|
sheetStyle: {
|
|
30074
30271
|
paddingHorizontal: 18,
|
|
30075
30272
|
paddingBottom: 18,
|
|
@@ -30097,7 +30294,7 @@ function PageJumpModal({
|
|
|
30097
30294
|
}
|
|
30098
30295
|
],
|
|
30099
30296
|
onSubmitEditing: confirmJump,
|
|
30100
|
-
accessibilityLabel: "
|
|
30297
|
+
accessibilityLabel: documentType === "epub" ? "N\xFAmero do cap\xEDtulo" : "N\xFAmero da p\xE1gina",
|
|
30101
30298
|
testID: "papyrus-page-jump-input"
|
|
30102
30299
|
}
|
|
30103
30300
|
),
|
|
@@ -30152,6 +30349,7 @@ var styles10 = import_react_native12.StyleSheet.create({
|
|
|
30152
30349
|
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
30153
30350
|
var Topbar = ({
|
|
30154
30351
|
engine,
|
|
30352
|
+
documentType,
|
|
30155
30353
|
onOpenSettings,
|
|
30156
30354
|
onOpenOverflow,
|
|
30157
30355
|
title,
|
|
@@ -30172,6 +30370,12 @@ var Topbar = ({
|
|
|
30172
30370
|
locale
|
|
30173
30371
|
} = (0, import_core12.useViewerStore)();
|
|
30174
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
|
+
});
|
|
30175
30379
|
const t = getStrings(locale);
|
|
30176
30380
|
const progress = useNativeInkMotion(inkSession.active, inkSession.supported);
|
|
30177
30381
|
const settingsMotion = (0, import_react_native_reanimated2.useAnimatedStyle)(() => {
|
|
@@ -30227,26 +30431,30 @@ var Topbar = ({
|
|
|
30227
30431
|
children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(IconSettings, { size: MOBILE_CHROME_METRICS.iconSize, color: isDark ? "#e5e7eb" : "#111827" })
|
|
30228
30432
|
}
|
|
30229
30433
|
);
|
|
30230
|
-
if (!
|
|
30434
|
+
if (!chromeVisible && documentType !== "epub") return null;
|
|
30231
30435
|
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
|
|
30232
30436
|
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
30233
|
-
|
|
30437
|
+
import_react_native_reanimated2.default.View,
|
|
30234
30438
|
{
|
|
30235
30439
|
style: [
|
|
30236
30440
|
styles11.chromeFrame,
|
|
30441
|
+
chromeMotion,
|
|
30237
30442
|
{
|
|
30238
30443
|
paddingTop: insets.top,
|
|
30239
30444
|
paddingLeft: MOBILE_CHROME_METRICS.screenPadding + insets.left,
|
|
30240
30445
|
paddingRight: MOBILE_CHROME_METRICS.screenPadding + insets.right
|
|
30241
30446
|
}
|
|
30242
30447
|
],
|
|
30243
|
-
pointerEvents: "box-none",
|
|
30448
|
+
pointerEvents: chromeVisible ? "box-none" : "none",
|
|
30449
|
+
accessibilityElementsHidden: !chromeVisible,
|
|
30450
|
+
importantForAccessibility: chromeVisible ? "auto" : "no-hide-descendants",
|
|
30244
30451
|
testID: "papyrus-floating-top-controls",
|
|
30245
30452
|
children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
30246
30453
|
import_react_native13.View,
|
|
30247
30454
|
{
|
|
30248
30455
|
style: [
|
|
30249
30456
|
styles11.container,
|
|
30457
|
+
import_react_native13.Platform.OS === "ios" && styles11.containerIos,
|
|
30250
30458
|
isDark && styles11.containerDark,
|
|
30251
30459
|
isLandscape && styles11.containerLandscape
|
|
30252
30460
|
],
|
|
@@ -30386,6 +30594,7 @@ var Topbar = ({
|
|
|
30386
30594
|
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
30387
30595
|
PageJumpModal,
|
|
30388
30596
|
{
|
|
30597
|
+
documentType,
|
|
30389
30598
|
visible: jumpModalOpen,
|
|
30390
30599
|
currentPage,
|
|
30391
30600
|
pageCount,
|
|
@@ -30403,7 +30612,8 @@ var styles11 = import_react_native13.StyleSheet.create({
|
|
|
30403
30612
|
maxWidth: MOBILE_CHROME_METRICS.maxFloatingWidth,
|
|
30404
30613
|
marginTop: 10,
|
|
30405
30614
|
paddingHorizontal: 14,
|
|
30406
|
-
|
|
30615
|
+
height: MOBILE_CHROME_METRICS.topbarHeight,
|
|
30616
|
+
paddingVertical: 0,
|
|
30407
30617
|
backgroundColor: "rgba(255,255,255,0.88)",
|
|
30408
30618
|
borderWidth: 1,
|
|
30409
30619
|
borderColor: "rgba(255,255,255,0.72)",
|
|
@@ -30420,6 +30630,10 @@ var styles11 = import_react_native13.StyleSheet.create({
|
|
|
30420
30630
|
backgroundColor: "rgba(15,17,21,0.88)",
|
|
30421
30631
|
borderColor: "rgba(71,85,105,0.48)"
|
|
30422
30632
|
},
|
|
30633
|
+
containerIos: {
|
|
30634
|
+
height: MOBILE_CHROME_METRICS.topbarHeight,
|
|
30635
|
+
paddingVertical: 0
|
|
30636
|
+
},
|
|
30423
30637
|
containerLandscape: {
|
|
30424
30638
|
maxWidth: void 0,
|
|
30425
30639
|
marginTop: 0
|
|
@@ -32556,10 +32770,10 @@ var import_react_native16 = require("react-native");
|
|
|
32556
32770
|
var import_core15 = require("@papyrus-sdk/core");
|
|
32557
32771
|
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
32558
32772
|
var COLORS = ["#fbbf24", "#fb7185", "#60a5fa", "#34d399", "#c084fc"];
|
|
32559
|
-
var AnnotationEditor = () => {
|
|
32773
|
+
var AnnotationEditor = ({ documentId }) => {
|
|
32560
32774
|
const { annotations, annotationDraft, clearAnnotationDraft, addAnnotation, selectedAnnotationId, updateAnnotation, removeAnnotation, setSelectedAnnotation, uiTheme, locale, accentColor } = (0, import_core15.useViewerStore)();
|
|
32561
32775
|
const annotation = annotationDraft?.id === selectedAnnotationId ? annotationDraft : annotations.find((a) => a.id === selectedAnnotationId);
|
|
32562
|
-
const supported = annotation && annotation.type !== "ink";
|
|
32776
|
+
const supported = annotation && annotation.type !== "ink" && (!documentId || !annotation.anchor?.documentId || annotation.anchor.documentId === documentId);
|
|
32563
32777
|
const [editing, setEditing] = (0, import_react16.useState)(false);
|
|
32564
32778
|
const [draft, setDraft] = (0, import_react16.useState)("");
|
|
32565
32779
|
const [color, setColor] = (0, import_react16.useState)(COLORS[0]);
|
|
@@ -32624,14 +32838,34 @@ var AnnotationEditor = () => {
|
|
|
32624
32838
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_native16.Animated.View, { accessibilityViewIsModal: true, style: [styles14.card, { backgroundColor: dark ? "#17191f" : "#fff", marginBottom: Math.max(16, insets.bottom), opacity: progress, transform: [{ translateY: progress.interpolate({ inputRange: [0, 1], outputRange: [12, 0] }) }] }], children: [
|
|
32625
32839
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_native16.View, { style: styles14.header, children: [
|
|
32626
32840
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native16.Text, { style: [styles14.title, textStyle], children: editing ? t.editNote : t.annotationNote }),
|
|
32627
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native16.Pressable, { onPress: close, accessibilityRole: "button", accessibilityLabel: t.close, style: styles14.button, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
32841
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native16.Pressable, { onPress: close, accessibilityRole: "button", accessibilityLabel: t.close, style: [styles14.button, { borderRadius: 22, backgroundColor: dark ? "#242936" : "#f1f5f9" }], children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(IconClose, { size: 20, color: textStyle.color }) })
|
|
32628
32842
|
] }),
|
|
32629
32843
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_native16.ScrollView, { style: styles14.content, keyboardShouldPersistTaps: "handled", children: [
|
|
32630
32844
|
quote ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native16.Text, { style: [styles14.quote, textStyle], selectable: true, children: quote }) : null,
|
|
32631
32845
|
editing ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
|
|
32632
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" }] }),
|
|
32633
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)) }),
|
|
32634
|
-
/* @__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
|
+
)) })
|
|
32635
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 })
|
|
32636
32870
|
] }),
|
|
32637
32871
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_native16.View, { style: styles14.actions, children: [
|
|
@@ -32654,7 +32888,7 @@ var AnnotationEditor = () => {
|
|
|
32654
32888
|
] })
|
|
32655
32889
|
] }) });
|
|
32656
32890
|
};
|
|
32657
|
-
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 } });
|
|
32658
32892
|
var AnnotationEditor_default = AnnotationEditor;
|
|
32659
32893
|
|
|
32660
32894
|
// components/BottomBar.tsx
|
|
@@ -32717,10 +32951,19 @@ var BottomBar = ({
|
|
|
32717
32951
|
documentType,
|
|
32718
32952
|
onOpenInfo,
|
|
32719
32953
|
onOpenSettings,
|
|
32720
|
-
onOpenDestination
|
|
32954
|
+
onOpenDestination,
|
|
32955
|
+
onTurnPage,
|
|
32956
|
+
onNavigateToPage,
|
|
32957
|
+
onOpenPages
|
|
32721
32958
|
}) => {
|
|
32722
32959
|
const {
|
|
32723
32960
|
activeMobileDestination,
|
|
32961
|
+
viewMode,
|
|
32962
|
+
epubReadingMode,
|
|
32963
|
+
epubLocation,
|
|
32964
|
+
comicLayoutMode,
|
|
32965
|
+
currentPage,
|
|
32966
|
+
pageCount,
|
|
32724
32967
|
mobileDockVisible,
|
|
32725
32968
|
setDocumentState,
|
|
32726
32969
|
uiTheme,
|
|
@@ -32735,7 +32978,7 @@ var BottomBar = ({
|
|
|
32735
32978
|
const supportsInkChrome = documentType === "pdf" && inkSession.supported;
|
|
32736
32979
|
const drawing = supportsInkChrome && inkSession.active;
|
|
32737
32980
|
const dockVisible = mobileChromeVisible && mobileDockVisible && !drawing;
|
|
32738
|
-
const dockProgress = useNativeInkMotion(dockVisible, supportsInkChrome);
|
|
32981
|
+
const dockProgress = useNativeInkMotion(dockVisible, supportsInkChrome || documentType === "epub");
|
|
32739
32982
|
const dockMotion = (0, import_react_native_reanimated3.useAnimatedStyle)(() => {
|
|
32740
32983
|
"worklet";
|
|
32741
32984
|
return {
|
|
@@ -32757,6 +33000,15 @@ var BottomBar = ({
|
|
|
32757
33000
|
activeMobileDestination,
|
|
32758
33001
|
toolDockOpen
|
|
32759
33002
|
});
|
|
33003
|
+
const paginated = documentType !== "text" && (documentType === "comic" ? comicLayoutMode === "single" : documentType === "epub" ? epubReadingMode === "paged" : viewMode === "single");
|
|
33004
|
+
if (paginated) {
|
|
33005
|
+
layout.leftSlots.push(...layout.rightSlots.filter((slot) => slot.key === "search"));
|
|
33006
|
+
layout.rightSlots = [];
|
|
33007
|
+
}
|
|
33008
|
+
const turnPage = (direction) => {
|
|
33009
|
+
if (onTurnPage) onTurnPage(direction);
|
|
33010
|
+
else onNavigateToPage?.(currentPage + direction);
|
|
33011
|
+
};
|
|
32760
33012
|
const slotMeta = {
|
|
32761
33013
|
annotate: {
|
|
32762
33014
|
label: t.tools,
|
|
@@ -32817,7 +33069,7 @@ var BottomBar = ({
|
|
|
32817
33069
|
onPress: onOpenSettings
|
|
32818
33070
|
}
|
|
32819
33071
|
};
|
|
32820
|
-
if (!dockVisible && !supportsInkChrome) return null;
|
|
33072
|
+
if (!dockVisible && !supportsInkChrome && documentType !== "epub") return null;
|
|
32821
33073
|
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
32822
33074
|
import_react_native_reanimated3.default.View,
|
|
32823
33075
|
{
|
|
@@ -32882,7 +33134,11 @@ var BottomBar = ({
|
|
|
32882
33134
|
isDark && styles15.islandDark
|
|
32883
33135
|
],
|
|
32884
33136
|
testID: "papyrus-floating-bottom-dock",
|
|
32885
|
-
children:
|
|
33137
|
+
children: paginated ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
|
|
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) }) })
|
|
33141
|
+
] }) : layout.rightSlots.map((slot) => {
|
|
32886
33142
|
const meta = slotMeta[slot.key];
|
|
32887
33143
|
const Icon = meta.icon;
|
|
32888
33144
|
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
@@ -32945,8 +33201,9 @@ var styles15 = import_react_native17.StyleSheet.create({
|
|
|
32945
33201
|
island: {
|
|
32946
33202
|
flexDirection: "row",
|
|
32947
33203
|
alignItems: "center",
|
|
32948
|
-
|
|
32949
|
-
|
|
33204
|
+
height: MOBILE_CHROME_METRICS.bottomBarVisualHeight,
|
|
33205
|
+
paddingVertical: 0,
|
|
33206
|
+
paddingHorizontal: 6,
|
|
32950
33207
|
backgroundColor: "rgba(255,255,255,0.9)",
|
|
32951
33208
|
borderWidth: 1,
|
|
32952
33209
|
borderColor: "rgba(255,255,255,0.72)",
|
|
@@ -32972,6 +33229,8 @@ var styles15 = import_react_native17.StyleSheet.create({
|
|
|
32972
33229
|
borderColor: "rgba(71,85,105,0.48)"
|
|
32973
33230
|
},
|
|
32974
33231
|
iconOnlyItem: {
|
|
33232
|
+
minWidth: 44,
|
|
33233
|
+
height: 44,
|
|
32975
33234
|
alignItems: "center",
|
|
32976
33235
|
justifyContent: "center",
|
|
32977
33236
|
paddingHorizontal: MOBILE_CHROME_METRICS.bottomBarItemPaddingHorizontal,
|
|
@@ -33048,10 +33307,12 @@ var SettingsSheet = ({
|
|
|
33048
33307
|
engine,
|
|
33049
33308
|
visible,
|
|
33050
33309
|
onClose,
|
|
33051
|
-
documentType = "pdf"
|
|
33310
|
+
documentType = "pdf",
|
|
33311
|
+
onOpenInfo
|
|
33052
33312
|
}) => {
|
|
33053
33313
|
const {
|
|
33054
33314
|
viewMode,
|
|
33315
|
+
epubReadingMode,
|
|
33055
33316
|
uiTheme,
|
|
33056
33317
|
zoom,
|
|
33057
33318
|
setDocumentState,
|
|
@@ -33063,12 +33324,16 @@ var SettingsSheet = ({
|
|
|
33063
33324
|
comicReadingDirection
|
|
33064
33325
|
} = (0, import_core17.useViewerStore)();
|
|
33065
33326
|
const isDark = uiTheme === "dark";
|
|
33066
|
-
const isPaged = viewMode === "single";
|
|
33327
|
+
const isPaged = documentType === "epub" ? epubReadingMode === "paged" : viewMode === "single";
|
|
33067
33328
|
const isDouble = viewMode === "double";
|
|
33068
33329
|
const t = getStrings(locale);
|
|
33069
33330
|
const { height: windowHeight } = (0, import_react_native18.useWindowDimensions)();
|
|
33070
33331
|
const sheetMaxHeight = getSettingsSheetMaxHeight(windowHeight);
|
|
33071
33332
|
const handleTransition = (mode) => {
|
|
33333
|
+
if (documentType === "epub") {
|
|
33334
|
+
setDocumentState({ epubReadingMode: mode === "paged" ? "paged" : "chapter-scroll" });
|
|
33335
|
+
return;
|
|
33336
|
+
}
|
|
33072
33337
|
if (mode === "paged") {
|
|
33073
33338
|
setDocumentState({ viewMode: "single" });
|
|
33074
33339
|
return;
|
|
@@ -33113,6 +33378,7 @@ var SettingsSheet = ({
|
|
|
33113
33378
|
contentContainerStyle: styles16.sheetContent,
|
|
33114
33379
|
showsVerticalScrollIndicator: false,
|
|
33115
33380
|
children: [
|
|
33381
|
+
onOpenInfo ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_native18.Pressable, { accessibilityRole: "button", onPress: onOpenInfo, style: { minHeight: 44, justifyContent: "center", marginBottom: 16 }, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_native18.Text, { style: [styles16.sectionTitle, isDark && styles16.sectionTitleDark], children: t.info }) }) : null,
|
|
33116
33382
|
(documentType === "text" || documentType === "epub") && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_react_native18.View, { style: styles16.section, children: [
|
|
33117
33383
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_native18.Text, { style: [styles16.sectionTitle, isDark && styles16.sectionTitleDark], children: locale === "pt-BR" ? "Tamanho da fonte" : "Font size" }),
|
|
33118
33384
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_react_native18.View, { style: { flexDirection: "row", alignItems: "center", gap: 12 }, children: [
|
|
@@ -33291,7 +33557,7 @@ var SettingsSheet = ({
|
|
|
33291
33557
|
isDark && styles16.optionTextDark,
|
|
33292
33558
|
(!isPaged || isDouble) && styles16.optionTextActive
|
|
33293
33559
|
],
|
|
33294
|
-
children: t.continuous
|
|
33560
|
+
children: documentType === "epub" && locale === "pt-BR" ? "Rolagem por cap\xEDtulo" : t.continuous
|
|
33295
33561
|
}
|
|
33296
33562
|
)
|
|
33297
33563
|
}
|
|
@@ -33321,7 +33587,7 @@ var SettingsSheet = ({
|
|
|
33321
33587
|
)
|
|
33322
33588
|
] })
|
|
33323
33589
|
] }),
|
|
33324
|
-
documentType
|
|
33590
|
+
documentType === "pdf" && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_react_native18.View, { style: styles16.section, children: [
|
|
33325
33591
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
33326
33592
|
import_react_native18.Text,
|
|
33327
33593
|
{
|
|
@@ -34199,6 +34465,7 @@ var styles20 = import_react_native22.StyleSheet.create({
|
|
|
34199
34465
|
// components/ProgressPill.tsx
|
|
34200
34466
|
var import_react18 = require("react");
|
|
34201
34467
|
var import_react_native23 = require("react-native");
|
|
34468
|
+
var import_react_native_reanimated4 = __toESM(require("react-native-reanimated"));
|
|
34202
34469
|
var import_core21 = require("@papyrus-sdk/core");
|
|
34203
34470
|
|
|
34204
34471
|
// components/progressPillMode.ts
|
|
@@ -34218,9 +34485,11 @@ var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
|
34218
34485
|
var clampPercent = (value) => Math.max(0, Math.min(100, Math.round(value)));
|
|
34219
34486
|
function ProgressPill({
|
|
34220
34487
|
documentType,
|
|
34488
|
+
navigationInDock = false,
|
|
34221
34489
|
onPress,
|
|
34222
34490
|
onOpenPageJump,
|
|
34223
34491
|
onNavigateToPage,
|
|
34492
|
+
onTurnPage,
|
|
34224
34493
|
onScrubbingChange
|
|
34225
34494
|
}) {
|
|
34226
34495
|
const {
|
|
@@ -34230,12 +34499,20 @@ function ProgressPill({
|
|
|
34230
34499
|
textLength,
|
|
34231
34500
|
comicLayoutMode,
|
|
34232
34501
|
viewMode,
|
|
34502
|
+
epubReadingMode,
|
|
34503
|
+
epubLocation,
|
|
34233
34504
|
locale,
|
|
34234
34505
|
uiTheme,
|
|
34235
34506
|
accentColor,
|
|
34236
34507
|
mobileChromeVisible,
|
|
34237
34508
|
mobileProgressPillVisible
|
|
34238
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
|
+
});
|
|
34239
34516
|
const t = getStrings(locale);
|
|
34240
34517
|
const isDark = uiTheme === "dark";
|
|
34241
34518
|
const offsets = resolveMobileChromeOffsets(usePapyrusSafeAreaInsets());
|
|
@@ -34280,10 +34557,10 @@ function ProgressPill({
|
|
|
34280
34557
|
return `${displayedPage}/${pageCount || 0}`;
|
|
34281
34558
|
}
|
|
34282
34559
|
if (documentType === "epub") {
|
|
34283
|
-
return `Cap. ${displayedPage} \xB7 ${percent}%`;
|
|
34560
|
+
return `Cap. ${displayedPage} \xB7 ${scrubPreviewPage === null && epubLocation ? clampPercent(epubLocation.progress * 100) : percent}%`;
|
|
34284
34561
|
}
|
|
34285
34562
|
return `${percent}%`;
|
|
34286
|
-
}, [displayedPage, documentType, pageCount]);
|
|
34563
|
+
}, [displayedPage, documentType, pageCount, epubLocation, scrubPreviewPage]);
|
|
34287
34564
|
const thumbTop = resolvePageScrubberThumbTop({
|
|
34288
34565
|
currentPage,
|
|
34289
34566
|
trackHeight,
|
|
@@ -34325,7 +34602,7 @@ function ProgressPill({
|
|
|
34325
34602
|
},
|
|
34326
34603
|
[]
|
|
34327
34604
|
);
|
|
34328
|
-
if (!shouldRenderPageScrubber({
|
|
34605
|
+
if (!(documentType === "epub" && mobileProgressPillVisible) && !shouldRenderPageScrubber({
|
|
34329
34606
|
mobileChromeVisible,
|
|
34330
34607
|
mobileProgressPillVisible,
|
|
34331
34608
|
isScrubbing: isScrubbingRef.current
|
|
@@ -34356,16 +34633,17 @@ function ProgressPill({
|
|
|
34356
34633
|
}
|
|
34357
34634
|
);
|
|
34358
34635
|
}
|
|
34359
|
-
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;
|
|
34360
34637
|
const pillMode = resolveProgressPillMode(progressViewMode, currentPage, pageCount);
|
|
34638
|
+
if (pillMode.kind === "navigation" && navigationInDock) return null;
|
|
34361
34639
|
if (pillMode.kind === "navigation") {
|
|
34362
|
-
const previousDisabled = pillMode.previousPage === null || !onNavigateToPage;
|
|
34363
|
-
const nextDisabled = pillMode.nextPage === null || !onNavigateToPage;
|
|
34640
|
+
const previousDisabled = !onTurnPage && (pillMode.previousPage === null || !onNavigateToPage);
|
|
34641
|
+
const nextDisabled = !onTurnPage && (pillMode.nextPage === null || !onNavigateToPage);
|
|
34364
34642
|
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
34365
34643
|
import_react_native23.View,
|
|
34366
34644
|
{
|
|
34367
34645
|
pointerEvents: "box-none",
|
|
34368
|
-
style: [
|
|
34646
|
+
style: [{ position: "absolute", zIndex: 18, bottom: offsets.bottom + MOBILE_CHROME_METRICS.bottomBarVisualHeight + 12, left: offsets.left, right: offsets.right, alignItems: "center" }],
|
|
34369
34647
|
children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_react_native23.View, { style: [styles21.singlePill, isDark && styles21.pillDark], children: [
|
|
34370
34648
|
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
34371
34649
|
import_react_native23.Pressable,
|
|
@@ -34374,7 +34652,7 @@ function ProgressPill({
|
|
|
34374
34652
|
accessibilityLabel: t.previousPage,
|
|
34375
34653
|
accessibilityState: { disabled: previousDisabled },
|
|
34376
34654
|
disabled: previousDisabled,
|
|
34377
|
-
onPress: () => pillMode.previousPage !== null && onNavigateToPageRef.current?.(pillMode.previousPage),
|
|
34655
|
+
onPress: () => onTurnPage ? onTurnPage(-1) : pillMode.previousPage !== null && onNavigateToPageRef.current?.(pillMode.previousPage),
|
|
34378
34656
|
style: styles21.pageArrowHit,
|
|
34379
34657
|
testID: "papyrus-progress-page-previous",
|
|
34380
34658
|
children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react_native23.Text, { style: [styles21.pageArrow, isDark && styles21.labelDark, previousDisabled && styles21.pageArrowDisabled], children: "\u2039" })
|
|
@@ -34402,7 +34680,7 @@ function ProgressPill({
|
|
|
34402
34680
|
accessibilityLabel: t.nextPage,
|
|
34403
34681
|
accessibilityState: { disabled: nextDisabled },
|
|
34404
34682
|
disabled: nextDisabled,
|
|
34405
|
-
onPress: () => pillMode.nextPage !== null && onNavigateToPageRef.current?.(pillMode.nextPage),
|
|
34683
|
+
onPress: () => onTurnPage ? onTurnPage(1) : pillMode.nextPage !== null && onNavigateToPageRef.current?.(pillMode.nextPage),
|
|
34406
34684
|
style: styles21.pageArrowHit,
|
|
34407
34685
|
testID: "papyrus-progress-page-next",
|
|
34408
34686
|
children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react_native23.Text, { style: [styles21.pageArrow, isDark && styles21.labelDark, nextDisabled && styles21.pageArrowDisabled], children: "\u203A" })
|
|
@@ -34546,11 +34824,14 @@ function ProgressPill({
|
|
|
34546
34824
|
}
|
|
34547
34825
|
const responderPanHandlers = scrubberResponderRef.current?.panHandlers ?? {};
|
|
34548
34826
|
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
34549
|
-
|
|
34827
|
+
import_react_native_reanimated4.default.View,
|
|
34550
34828
|
{
|
|
34551
|
-
pointerEvents: "box-none",
|
|
34829
|
+
pointerEvents: chromeVisible ? "box-none" : "none",
|
|
34830
|
+
accessibilityElementsHidden: !chromeVisible,
|
|
34831
|
+
importantForAccessibility: chromeVisible ? "auto" : "no-hide-descendants",
|
|
34552
34832
|
style: [
|
|
34553
34833
|
styles21.frame,
|
|
34834
|
+
chromeMotion,
|
|
34554
34835
|
resolvePageScrubberOverlayStyle(),
|
|
34555
34836
|
{
|
|
34556
34837
|
top: offsets.progress,
|
|
@@ -35279,15 +35560,10 @@ function ReadingShell({
|
|
|
35279
35560
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
35280
35561
|
Topbar_default,
|
|
35281
35562
|
{
|
|
35563
|
+
documentType,
|
|
35282
35564
|
engine,
|
|
35283
35565
|
title,
|
|
35284
|
-
|
|
35285
|
-
closeMobileDestination();
|
|
35286
|
-
setInfoOpen(false);
|
|
35287
|
-
setActionsOpen(false);
|
|
35288
|
-
setSettingsOpen(false);
|
|
35289
|
-
setOverflowOpen(true);
|
|
35290
|
-
},
|
|
35566
|
+
onOpenSettings: () => openDestination("display"),
|
|
35291
35567
|
onOpenPageJump: () => setPageJumpOpen(true),
|
|
35292
35568
|
showPageNavigationControls: false
|
|
35293
35569
|
}
|
|
@@ -35295,6 +35571,7 @@ function ReadingShell({
|
|
|
35295
35571
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_react_native26.View, { style: styles24.viewerStage, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
35296
35572
|
Viewer_default,
|
|
35297
35573
|
{
|
|
35574
|
+
documentType,
|
|
35298
35575
|
engine,
|
|
35299
35576
|
...viewerProps,
|
|
35300
35577
|
pageScrubActive
|
|
@@ -35303,7 +35580,13 @@ function ReadingShell({
|
|
|
35303
35580
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
35304
35581
|
ProgressPill,
|
|
35305
35582
|
{
|
|
35583
|
+
navigationInDock: true,
|
|
35306
35584
|
documentType,
|
|
35585
|
+
onTurnPage: documentType === "epub" ? (direction) => {
|
|
35586
|
+
const paginatedEngine = engine;
|
|
35587
|
+
void paginatedEngine.turnEpubPage?.(direction).catch(() => {
|
|
35588
|
+
});
|
|
35589
|
+
} : void 0,
|
|
35307
35590
|
onNavigateToPage: navigateToPage,
|
|
35308
35591
|
onPress: () => openDestination(
|
|
35309
35592
|
documentType === "pdf" ? "pages" : documentType === "epub" ? "contents" : "progress"
|
|
@@ -35315,6 +35598,12 @@ function ReadingShell({
|
|
|
35315
35598
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
35316
35599
|
BottomBar_default,
|
|
35317
35600
|
{
|
|
35601
|
+
onNavigateToPage: navigateToPage,
|
|
35602
|
+
onOpenPages: () => setPageJumpOpen(true),
|
|
35603
|
+
onTurnPage: documentType === "epub" ? (direction) => {
|
|
35604
|
+
const paginatedEngine = engine;
|
|
35605
|
+
void paginatedEngine.turnEpubPage?.(direction).catch((error) => console.warn("[Papyrus] page navigation failed", error));
|
|
35606
|
+
} : void 0,
|
|
35318
35607
|
documentType,
|
|
35319
35608
|
onOpenDestination: openDestination,
|
|
35320
35609
|
onOpenInfo: () => openDestination("info"),
|
|
@@ -35394,6 +35683,7 @@ function ReadingShell({
|
|
|
35394
35683
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
35395
35684
|
SettingsSheet_default,
|
|
35396
35685
|
{
|
|
35686
|
+
onOpenInfo: () => openDestination("info"),
|
|
35397
35687
|
engine,
|
|
35398
35688
|
documentType,
|
|
35399
35689
|
visible: settingsOpen,
|
|
@@ -35406,6 +35696,7 @@ function ReadingShell({
|
|
|
35406
35696
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
35407
35697
|
PageJumpModal,
|
|
35408
35698
|
{
|
|
35699
|
+
documentType,
|
|
35409
35700
|
visible: pageJumpOpen,
|
|
35410
35701
|
currentPage,
|
|
35411
35702
|
pageCount,
|