@papyrus-sdk/ui-react-native 0.2.35-beta.9 → 0.2.36
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 +829 -236
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +843 -249
- package/dist/index.mjs.map +1 -1
- package/package.json +10 -8
- package/runtime/epubAnnotations.js +276 -8
- package/runtime/epubReader.js +58 -0
- package/runtime/index.html +505 -84
- package/runtime/runtime.js +505 -84
- package/runtime/syncComicRuntime.mjs +6 -3
- package/runtime/comicRuntime.test.ts +0 -241
- package/runtime/documentLoadRuntime.test.ts +0 -172
- package/runtime/epubAnnotations.test.ts +0 -31
- package/runtime/epubScrollDiagnostics.test.ts +0 -107
- package/runtime/epubSelectionMenu.test.ts +0 -39
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],[data-papyrus-ink-capture]'));}
|
|
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();
|
|
@@ -20528,6 +20589,84 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
20528
20589
|
typeof anchor.href === 'string' && !/^(javascript|data):/i.test(anchor.href) &&
|
|
20529
20590
|
typeof anchor.quote === 'string' && anchor.quote.length > 0 && anchor.quote.length <= 100000;
|
|
20530
20591
|
}
|
|
20592
|
+
function simplifyPath(points, tolerance, maxPoints) {
|
|
20593
|
+
if (!Array.isArray(points) || points.length <= 2) return Array.isArray(points) ? points.slice() : [];
|
|
20594
|
+
tolerance = Number.isFinite(tolerance) ? Math.max(0, tolerance) : 1.5;
|
|
20595
|
+
maxPoints = Number.isSafeInteger(maxPoints) ? Math.max(2, maxPoints) : 512;
|
|
20596
|
+
var keep = new Uint8Array(points.length); keep[0] = 1; keep[points.length - 1] = 1;
|
|
20597
|
+
var stack = [[0, points.length - 1]], toleranceSquared = tolerance * tolerance;
|
|
20598
|
+
while (stack.length) {
|
|
20599
|
+
var interval = stack.pop(), first = interval[0], last = interval[1], a = points[first], b = points[last];
|
|
20600
|
+
var dx = b.x - a.x, dy = b.y - a.y, lengthSquared = dx * dx + dy * dy, maxDistance = toleranceSquared, split = -1;
|
|
20601
|
+
for (var i = first + 1; i < last; i++) {
|
|
20602
|
+
var p = points[i], ratio = lengthSquared ? Math.max(0, Math.min(1, ((p.x - a.x) * dx + (p.y - a.y) * dy) / lengthSquared)) : 0;
|
|
20603
|
+
var px = a.x + ratio * dx, py = a.y + ratio * dy, ox = p.x - px, oy = p.y - py, distance = ox * ox + oy * oy;
|
|
20604
|
+
if (distance > maxDistance) { maxDistance = distance; split = i; }
|
|
20605
|
+
}
|
|
20606
|
+
if (split >= 0) { keep[split] = 1; stack.push([first, split], [split, last]); }
|
|
20607
|
+
}
|
|
20608
|
+
var result = []; for (var j = 0; j < points.length; j++) if (keep[j]) result.push(points[j]);
|
|
20609
|
+
if (result.length <= maxPoints) return result;
|
|
20610
|
+
var capped = []; for (var k = 0; k < maxPoints; k++) capped.push(result[Math.round(k * (result.length - 1) / (maxPoints - 1))]);
|
|
20611
|
+
return capped;
|
|
20612
|
+
}
|
|
20613
|
+
function compactGesturePoints(points, maxPoints) {
|
|
20614
|
+
if (!Array.isArray(points)) return [];
|
|
20615
|
+
maxPoints = Number.isSafeInteger(maxPoints) ? Math.max(2, maxPoints) : 1024;
|
|
20616
|
+
if (points.length <= maxPoints) return points.slice();
|
|
20617
|
+
var compacted = [];
|
|
20618
|
+
for (var i = 0; i < maxPoints; i++) compacted.push(points[Math.round(i * (points.length - 1) / (maxPoints - 1))]);
|
|
20619
|
+
return compacted;
|
|
20620
|
+
}
|
|
20621
|
+
function densifyPath(points, maxStep, maxPoints) {
|
|
20622
|
+
if (!Array.isArray(points) || !points.length) return [];
|
|
20623
|
+
if (points.length === 1) return points.slice();
|
|
20624
|
+
maxStep = Number.isFinite(maxStep) ? Math.max(1, maxStep) : 12;
|
|
20625
|
+
maxPoints = Number.isSafeInteger(maxPoints) ? Math.max(2, maxPoints) : 512;
|
|
20626
|
+
var cumulative = [0], total = 0;
|
|
20627
|
+
for (var i = 1; i < points.length; i++) {
|
|
20628
|
+
if (![points[i-1].x,points[i-1].y,points[i].x,points[i].y].every(Number.isFinite)) return [];
|
|
20629
|
+
total += Math.hypot(points[i].x-points[i-1].x, points[i].y-points[i-1].y);
|
|
20630
|
+
cumulative.push(total);
|
|
20631
|
+
}
|
|
20632
|
+
if (!total) return [points[0], points[points.length-1]];
|
|
20633
|
+
var intervals = Math.min(maxPoints-1, Math.max(1, Math.ceil(total/maxStep))), result = [], segment = 1;
|
|
20634
|
+
for (var sample = 0; sample <= intervals; sample++) {
|
|
20635
|
+
var distance = total*sample/intervals;
|
|
20636
|
+
while (segment < cumulative.length-1 && cumulative[segment] < distance) segment++;
|
|
20637
|
+
var start = points[segment-1], end = points[segment], span = cumulative[segment]-cumulative[segment-1];
|
|
20638
|
+
var ratio = span ? (distance-cumulative[segment-1])/span : 0;
|
|
20639
|
+
result.push({x:start.x+(end.x-start.x)*ratio,y:start.y+(end.y-start.y)*ratio});
|
|
20640
|
+
}
|
|
20641
|
+
return result;
|
|
20642
|
+
}
|
|
20643
|
+
function createSpatialIndex(entries, cellSize) {
|
|
20644
|
+
cellSize = Number.isFinite(cellSize) ? Math.max(8, cellSize) : 64;
|
|
20645
|
+
var cells = new Map();
|
|
20646
|
+
entries.forEach(function(entry) {
|
|
20647
|
+
var left = Math.floor(entry.left / cellSize), right = Math.floor(entry.right / cellSize);
|
|
20648
|
+
var top = Math.floor(entry.top / cellSize), bottom = Math.floor(entry.bottom / cellSize);
|
|
20649
|
+
for (var x = left; x <= right; x++) for (var y = top; y <= bottom; y++) {
|
|
20650
|
+
var key = x + ':' + y, bucket = cells.get(key); if (!bucket) { bucket = []; cells.set(key, bucket); } bucket.push(entry);
|
|
20651
|
+
}
|
|
20652
|
+
});
|
|
20653
|
+
return {cells:cells,cellSize:cellSize};
|
|
20654
|
+
}
|
|
20655
|
+
function queryNearestTextRect(index, x, y, maxDistance) {
|
|
20656
|
+
if (!index || !Number.isFinite(x) || !Number.isFinite(y) || !Number.isFinite(maxDistance) || maxDistance < 0) return null;
|
|
20657
|
+
var size = index.cellSize, minX = Math.floor((x-maxDistance)/size), maxX = Math.floor((x+maxDistance)/size);
|
|
20658
|
+
var minY = Math.floor((y-maxDistance)/size), maxY = Math.floor((y+maxDistance)/size), seen = new Set(), best = null;
|
|
20659
|
+
for (var cx=minX; cx<=maxX; cx++) for (var cy=minY; cy<=maxY; cy++) {
|
|
20660
|
+
var bucket = index.cells.get(cx+':'+cy); if (!bucket) continue;
|
|
20661
|
+
bucket.forEach(function(entry) {
|
|
20662
|
+
if (seen.has(entry)) return; seen.add(entry);
|
|
20663
|
+
var nearestX = Math.max(entry.left,Math.min(entry.right,x)), nearestY = Math.max(entry.top,Math.min(entry.bottom,y));
|
|
20664
|
+
var dx=x-nearestX,dy=y-nearestY,distance=Math.sqrt(dx*dx+dy*dy);
|
|
20665
|
+
if (distance<=maxDistance && (!best || distance<best.distance)) best={entry:entry,distance:distance,x:nearestX,y:nearestY};
|
|
20666
|
+
});
|
|
20667
|
+
}
|
|
20668
|
+
return best;
|
|
20669
|
+
}
|
|
20531
20670
|
function textNodes(document) {
|
|
20532
20671
|
var walker = document.createTreeWalker(document.body, 4);
|
|
20533
20672
|
var nodes = [], text = '', node;
|
|
@@ -20577,13 +20716,196 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
20577
20716
|
if(win.getComputedStyle(doc.body).position==='static')doc.body.style.position='relative';
|
|
20578
20717
|
doc.body.appendChild(overlay);
|
|
20579
20718
|
var registry = new Map(), hitRegions = [];
|
|
20719
|
+
var inkRegistry = new Map(), rangeCache = new Map(), spatialIndex = null, activeGesture = null, inkConfig = {enabled:false,preset:'ink'};
|
|
20720
|
+
var inkSvg = doc.createElementNS('http://www.w3.org/2000/svg','svg');
|
|
20721
|
+
inkSvg.setAttribute('data-papyrus-ink-overlay','');
|
|
20722
|
+
inkSvg.style.cssText = 'position:absolute;left:0;top:0;overflow:visible;pointer-events:none;z-index:1';
|
|
20723
|
+
overlay.appendChild(inkSvg);
|
|
20724
|
+
var inkCanvas = doc.createElement('canvas');
|
|
20725
|
+
inkCanvas.dataset.papyrusInkCapture = '';
|
|
20726
|
+
inkCanvas.style.cssText = 'position:fixed;left:0;top:0;width:1px;height:1px;z-index:2147483000;background:transparent;pointer-events:none;touch-action:none';
|
|
20727
|
+
doc.body.appendChild(inkCanvas);
|
|
20728
|
+
var inkContext = null; try { if(typeof win.CanvasRenderingContext2D==='function')inkContext = inkCanvas.getContext('2d'); } catch (_) {}
|
|
20729
|
+
function resizeCanvas() {
|
|
20730
|
+
var bodyRect=doc.body.getBoundingClientRect(), ratio = Math.max(1,Math.min(3,win.devicePixelRatio || 1));
|
|
20731
|
+
var width=Math.max(1,Math.min(4096,doc.body.clientWidth||bodyRect.width||Math.min(4096,win.innerWidth||1)));
|
|
20732
|
+
var height=Math.max(1,Math.min(4096,doc.body.clientHeight||bodyRect.height||Math.min(4096,win.innerHeight||1)));
|
|
20733
|
+
inkCanvas.style.width=width+'px';inkCanvas.style.height=height+'px';
|
|
20734
|
+
inkCanvas.width = Math.round(width*ratio); inkCanvas.height = Math.round(height*ratio);
|
|
20735
|
+
if (inkContext) { inkContext.setTransform(ratio,0,0,ratio,0,0); inkContext.clearRect(0,0,width,height); }
|
|
20736
|
+
}
|
|
20737
|
+
function collectTextRects() {
|
|
20738
|
+
var walker = doc.createTreeWalker(doc.body,4), node, entries=[];
|
|
20739
|
+
while ((node=walker.nextNode())) {
|
|
20740
|
+
var parent=node.parentElement;
|
|
20741
|
+
if (!parent || parent.closest('script,style,noscript,textarea,[data-papyrus-overlay],[data-papyrus-ink-capture]')) continue;
|
|
20742
|
+
var text=node.nodeValue || '', style=win.getComputedStyle(parent), computed=parseFloat(style.lineHeight);
|
|
20743
|
+
for (var start=0; start<text.length;) {
|
|
20744
|
+
var end=Math.min(text.length,start+24), last=text.charCodeAt(end-1), next=text.charCodeAt(end);
|
|
20745
|
+
if(end<text.length&&last>=0xD800&&last<=0xDBFF&&next>=0xDC00&&next<=0xDFFF)end++;
|
|
20746
|
+
var range=doc.createRange(); range.setStart(node,start); range.setEnd(node,end);
|
|
20747
|
+
var rects=[]; try { rects=Array.from(range.getClientRects()); } catch (_) {}
|
|
20748
|
+
rects.forEach(function(rect) {
|
|
20749
|
+
if (!(rect.width>0 && rect.height>0)) return;
|
|
20750
|
+
entries.push({left:rect.left+win.scrollX,top:rect.top+win.scrollY,right:rect.right+win.scrollX,bottom:rect.bottom+win.scrollY,width:rect.width,height:rect.height,
|
|
20751
|
+
node:node,start:start,end:end,lineHeight:Number.isFinite(computed)&&computed>0?computed:rect.height});
|
|
20752
|
+
});
|
|
20753
|
+
start=end;
|
|
20754
|
+
}
|
|
20755
|
+
}
|
|
20756
|
+
return entries;
|
|
20757
|
+
}
|
|
20758
|
+
function rebuildSpatialIndex() { spatialIndex=createSpatialIndex(collectTextRects(),64); rangeCache.clear(); }
|
|
20759
|
+
function inkViewportExtent() {
|
|
20760
|
+
var root=doc.documentElement,body=doc.body,bodyRect=body.getBoundingClientRect();
|
|
20761
|
+
var width=root.clientWidth||body.clientWidth||bodyRect.width||win.innerWidth||1;
|
|
20762
|
+
var height=root.clientHeight||body.clientHeight||bodyRect.height||win.innerHeight||1;
|
|
20763
|
+
return Math.max(1,Math.min(4096,width),Math.min(4096,height));
|
|
20764
|
+
}
|
|
20765
|
+
function inkStrokeWidthPx(width,preset) {
|
|
20766
|
+
var scale=preset==='highlight'?0.8:preset==='underline'?0.1:0.15;
|
|
20767
|
+
return Math.max(1,Math.min(24,(Number.isFinite(width)?width:0.006)*inkViewportExtent()*scale));
|
|
20768
|
+
}
|
|
20769
|
+
function closestGlyph(entry,x,y,maxDistance) {
|
|
20770
|
+
var source=(entry.node.nodeValue || '').slice(entry.start,entry.end), best=null, offset=0;
|
|
20771
|
+
for (var glyph of source) {
|
|
20772
|
+
var range=doc.createRange(); range.setStart(entry.node,entry.start+offset); range.setEnd(entry.node,entry.start+offset+glyph.length); offset+=glyph.length;
|
|
20773
|
+
var rects=[]; try { rects=Array.from(range.getClientRects()); } catch (_) {}
|
|
20774
|
+
rects.forEach(function(rect) {
|
|
20775
|
+
if (!(rect.width>0 && rect.height>0)) return;
|
|
20776
|
+
var nx=Math.max(rect.left+win.scrollX,Math.min(rect.right+win.scrollX,x)), ny=Math.max(rect.top+win.scrollY,Math.min(rect.bottom+win.scrollY,y));
|
|
20777
|
+
var dx=x-nx,dy=y-ny,distance=Math.sqrt(dx*dx+dy*dy);
|
|
20778
|
+
if (distance<=maxDistance && (!best || distance<best.distance)) best={range:range,rect:rect,distance:distance};
|
|
20779
|
+
});
|
|
20780
|
+
}
|
|
20781
|
+
if (!best || typeof contents.cfiFromRange!=='function') return null;
|
|
20782
|
+
var quote=best.range.toString(), cfiRange; try { cfiRange=contents.cfiFromRange(best.range); } catch (_) { return null; }
|
|
20783
|
+
if (!quote || typeof cfiRange!=='string' || !/^epubcfi\\([^\\n<>]+\\)$/.test(cfiRange)) return null;
|
|
20784
|
+
var lineHeight=Math.max(1,entry.lineHeight || best.rect.height), px=x-(best.rect.left+win.scrollX), py=y-(best.rect.top+win.scrollY);
|
|
20785
|
+
return {cfiRange:cfiRange,quote:quote,x:Math.max(-3,Math.min(3,px/lineHeight)),y:Math.max(-3,Math.min(3,py/lineHeight))};
|
|
20786
|
+
}
|
|
20787
|
+
function renderInkAnnotation(annotation,keep,bodyRect) {
|
|
20788
|
+
var baseRect=bodyRect || doc.body.getBoundingClientRect() || {left:0,top:0};
|
|
20789
|
+
var data=annotation.epubInk;
|
|
20790
|
+
if (!data || data.version!==1 || data.kind!=='epub-ink' || !Array.isArray(data.segments)) return;
|
|
20791
|
+
keep.add(annotation.id);
|
|
20792
|
+
var group=inkRegistry.get(annotation.id);
|
|
20793
|
+
if (!group) { group=doc.createElementNS('http://www.w3.org/2000/svg','g'); group.setAttribute('data-epub-ink-id',annotation.id); inkSvg.appendChild(group); inkRegistry.set(annotation.id,group); }
|
|
20794
|
+
group.replaceChildren();
|
|
20795
|
+
var color=/^#[0-9a-f]{6}$/i.test(annotation.color)?annotation.color:'#2563eb';
|
|
20796
|
+
var opacity=Number.isFinite(annotation.opacity)?Math.max(0,Math.min(1,annotation.opacity)):1;
|
|
20797
|
+
var preset=['ink','highlight','underline'].indexOf(data.preset)>=0?data.preset:'ink';
|
|
20798
|
+
var stroke=inkStrokeWidthPx(annotation.strokeWidth,preset);
|
|
20799
|
+
data.segments.forEach(function(segment) {
|
|
20800
|
+
if (segment.href!==options.href || !Array.isArray(segment.points)) return;
|
|
20801
|
+
var paths=[], current=[];
|
|
20802
|
+
segment.points.forEach(function(point) {
|
|
20803
|
+
var range=rangeCache.get(point.cfiRange);
|
|
20804
|
+
if (!range) { try { range=contents.range(point.cfiRange); } catch (_) { range=null; } if (range) rangeCache.set(point.cfiRange,range); }
|
|
20805
|
+
if (!range || range.toString()!==point.quote) { if(current.length>1)paths.push(current);current=[];return; }
|
|
20806
|
+
var rect; try { rect=range.getBoundingClientRect(); } catch (_) { rect=null; }
|
|
20807
|
+
if (!rect || !(rect.width>0 && rect.height>0)) { if(current.length>1)paths.push(current);current=[];return; }
|
|
20808
|
+
var lineHeight=Math.max(1,rect.height), x=rect.left-baseRect.left+point.x*lineHeight, y=rect.top-baseRect.top+point.y*lineHeight;
|
|
20809
|
+
var previous=current[current.length-1], jumpLimit=Math.max(24,lineHeight*2.5);
|
|
20810
|
+
if (previous && Math.hypot(x-previous.x,y-previous.y)>jumpLimit) { if(current.length>1)paths.push(current);current=[]; }
|
|
20811
|
+
current.push({x:x,y:y,lineHeight:lineHeight});
|
|
20812
|
+
});
|
|
20813
|
+
if(current.length>1)paths.push(current);
|
|
20814
|
+
paths.forEach(function(points) {
|
|
20815
|
+
var d='M '+points[0].x.toFixed(1)+' '+points[0].y.toFixed(1);
|
|
20816
|
+
for(var i=1;i<points.length;i++){var prev=points[i-1],point=points[i],mx=(prev.x+point.x)/2,my=(prev.y+point.y)/2;d+=' Q '+prev.x.toFixed(1)+' '+prev.y.toFixed(1)+' '+mx.toFixed(1)+' '+my.toFixed(1);}
|
|
20817
|
+
var last=points[points.length-1];d+=' L '+last.x.toFixed(1)+' '+last.y.toFixed(1);
|
|
20818
|
+
var path=doc.createElementNS('http://www.w3.org/2000/svg','path');path.setAttribute('d',d);path.setAttribute('fill','none');path.setAttribute('stroke',color);path.setAttribute('stroke-width',String(stroke));path.setAttribute('stroke-linecap','round');path.setAttribute('stroke-linejoin','round');path.setAttribute('opacity',String(opacity));group.appendChild(path);
|
|
20819
|
+
});
|
|
20820
|
+
});
|
|
20821
|
+
}
|
|
20822
|
+
function clearPreview() {
|
|
20823
|
+
if(inkContext)inkContext.clearRect(0,0,inkCanvas.width,inkCanvas.height);
|
|
20824
|
+
inkSvg.querySelectorAll('[data-papyrus-ink-preview]').forEach(function(path){path.remove();});
|
|
20825
|
+
}
|
|
20826
|
+
function createPreviewPath(x,y) {
|
|
20827
|
+
var path=doc.createElementNS('http://www.w3.org/2000/svg','path');
|
|
20828
|
+
path.setAttribute('data-papyrus-ink-preview','');path.setAttribute('d','M '+x.toFixed(1)+' '+y.toFixed(1));path.setAttribute('fill','none');
|
|
20829
|
+
path.setAttribute('stroke',inkConfig.color);path.setAttribute('stroke-width',String(inkStrokeWidthPx(inkConfig.strokeWidth,inkConfig.preset)));
|
|
20830
|
+
path.setAttribute('stroke-linecap','round');path.setAttribute('stroke-linejoin','round');path.setAttribute('opacity',String(inkConfig.opacity));
|
|
20831
|
+
path.style.pointerEvents='none';inkSvg.appendChild(path);return path;
|
|
20832
|
+
}
|
|
20833
|
+
function updatePreviewPath(clientX,clientY) {
|
|
20834
|
+
var bodyRect=doc.body.getBoundingClientRect(),x=clientX-bodyRect.left,y=clientY-bodyRect.top;
|
|
20835
|
+
var gesture=activeGesture;
|
|
20836
|
+
if(!gesture.previewPath||gesture.previewPathPoints>=32){
|
|
20837
|
+
gesture.previewPath=createPreviewPath(gesture.previewLast?gesture.previewLast.x:x,gesture.previewLast?gesture.previewLast.y:y);
|
|
20838
|
+
gesture.previewPathPoints=1;
|
|
20839
|
+
}
|
|
20840
|
+
var pathData=gesture.previewPath.getAttribute('d')||'';
|
|
20841
|
+
gesture.previewPath.setAttribute('d',pathData+' L '+x.toFixed(1)+' '+y.toFixed(1));
|
|
20842
|
+
gesture.previewPathPoints++;
|
|
20843
|
+
gesture.previewLast={x:x,y:y};
|
|
20844
|
+
}
|
|
20845
|
+
function cancelGesture() {
|
|
20846
|
+
var gesture=activeGesture; activeGesture=null; clearPreview();
|
|
20847
|
+
if(gesture)try{inkCanvas.releasePointerCapture(gesture.pointerId);}catch(_){}
|
|
20848
|
+
}
|
|
20849
|
+
function commitGesture() {
|
|
20850
|
+
var gesture=activeGesture; activeGesture=null; clearPreview();
|
|
20851
|
+
if(!gesture || !alive || !options.isCurrent() || !inkConfig.enabled || !spatialIndex) return;
|
|
20852
|
+
var simplified=simplifyPath(gesture.points,1.5,512), anchorSamples=densifyPath(simplified,12,512), segments=[], current=[];
|
|
20853
|
+
anchorSamples.forEach(function(point) {
|
|
20854
|
+
var coarse=queryNearestTextRect(spatialIndex,point.x,point.y,28);
|
|
20855
|
+
var cutoff=coarse?Math.max(12,Math.min(28,0.8*coarse.entry.lineHeight)):12;
|
|
20856
|
+
var anchored=coarse && closestGlyph(coarse.entry,point.x,point.y,cutoff);
|
|
20857
|
+
if(!anchored){if(current.length>1)segments.push({href:options.href,spineIndex:options.spineIndex,points:current});current=[];return;}
|
|
20858
|
+
current.push(anchored);
|
|
20859
|
+
});
|
|
20860
|
+
if(current.length>1)segments.push({href:options.href,spineIndex:options.spineIndex,points:current});
|
|
20861
|
+
segments=segments.slice(0,64);
|
|
20862
|
+
var pointCount=segments.reduce(function(total,segment){return total+segment.points.length;},0);
|
|
20863
|
+
if(!pointCount)return;
|
|
20864
|
+
var width=Math.max(1,doc.documentElement.scrollWidth,win.innerWidth),height=Math.max(1,doc.documentElement.scrollHeight,win.innerHeight);
|
|
20865
|
+
var normalized=simplified.map(function(p){return {x:Math.max(0,Math.min(1,p.x/width)),y:Math.max(0,Math.min(1,p.y/height))};});
|
|
20866
|
+
var minX=Math.min.apply(null,normalized.map(function(p){return p.x;})),maxX=Math.max.apply(null,normalized.map(function(p){return p.x;}));
|
|
20867
|
+
var minY=Math.min.apply(null,normalized.map(function(p){return p.y;})),maxY=Math.max.apply(null,normalized.map(function(p){return p.y;}));
|
|
20868
|
+
var first=segments[0].points[0], href=segments[0].href, documentId=typeof options.documentId==='function'?options.documentId():options.documentId;
|
|
20869
|
+
var annotation={id:'epub-ink-'+Date.now()+'-'+Math.random().toString(36).slice(2,9),type:'ink',pageIndex:(options.spineIndex||0)+1,
|
|
20870
|
+
rect:{x:minX,y:minY,width:Math.min(1-minX,Math.max(0.001,maxX-minX)),height:Math.min(1-minY,Math.max(0.001,maxY-minY))},path:normalized,color:inkConfig.color,opacity:inkConfig.opacity,strokeWidth:inkConfig.strokeWidth,createdAt:Date.now(),content:first.quote,
|
|
20871
|
+
anchor:{version:1,kind:'epub-cfi',cfiRange:first.cfiRange,href:href,spineIndex:options.spineIndex,documentId:documentId,quote:first.quote},
|
|
20872
|
+
epubInk:{version:1,kind:'epub-ink',documentId:documentId,preset:inkConfig.preset,segments:segments}};
|
|
20873
|
+
if(typeof options.onInkCommit==='function')options.onInkCommit(annotation);
|
|
20874
|
+
}
|
|
20875
|
+
function pointerDown(event) {
|
|
20876
|
+
if(!inkConfig.enabled || !alive || !options.isCurrent() || event.button!==undefined && event.button!==0)return;
|
|
20877
|
+
if(activeGesture){cancelGesture();return;}
|
|
20878
|
+
event.preventDefault();event.stopPropagation();
|
|
20879
|
+
activeGesture={pointerId:event.pointerId,points:[{x:event.clientX+win.scrollX,y:event.clientY+win.scrollY}],last:{x:event.clientX,y:event.clientY},previewPath:null,previewPathPoints:0,previewLast:null};
|
|
20880
|
+
updatePreviewPath(event.clientX,event.clientY);
|
|
20881
|
+
try{inkCanvas.setPointerCapture(event.pointerId);}catch(_){}
|
|
20882
|
+
}
|
|
20883
|
+
function pointerMove(event) {
|
|
20884
|
+
if(!activeGesture || activeGesture.pointerId!==event.pointerId)return;
|
|
20885
|
+
if(!options.isCurrent()||!inkConfig.enabled){cancelGesture();return;}
|
|
20886
|
+
event.preventDefault();event.stopPropagation();
|
|
20887
|
+
var point={x:event.clientX+win.scrollX,y:event.clientY+win.scrollY};activeGesture.points.push(point);
|
|
20888
|
+
if(activeGesture.points.length>2048)activeGesture.points=compactGesturePoints(activeGesture.points,1024);
|
|
20889
|
+
if(inkContext){inkContext.beginPath();inkContext.moveTo(activeGesture.last.x,activeGesture.last.y);inkContext.lineTo(event.clientX,event.clientY);inkContext.strokeStyle=inkConfig.color;inkContext.globalAlpha=inkConfig.opacity;inkContext.lineWidth=inkStrokeWidthPx(inkConfig.strokeWidth,inkConfig.preset);inkContext.lineCap='round';inkContext.lineJoin='round';inkContext.stroke();}
|
|
20890
|
+
updatePreviewPath(event.clientX,event.clientY);
|
|
20891
|
+
activeGesture.last={x:event.clientX,y:event.clientY};
|
|
20892
|
+
}
|
|
20893
|
+
function pointerUp(event) {if(!activeGesture || activeGesture.pointerId!==event.pointerId)return;event.preventDefault();event.stopPropagation();var end={x:event.clientX+win.scrollX,y:event.clientY+win.scrollY},last=activeGesture.points[activeGesture.points.length-1];if(Math.hypot(end.x-last.x,end.y-last.y)>0.5){activeGesture.points.push(end);updatePreviewPath(event.clientX,event.clientY);}commitGesture();}
|
|
20894
|
+
function pointerCancel(event) {if(activeGesture && (event.pointerId===undefined || activeGesture.pointerId===event.pointerId))cancelGesture();}
|
|
20895
|
+
resizeCanvas();rebuildSpatialIndex();
|
|
20896
|
+
inkCanvas.addEventListener('pointerdown',pointerDown);inkCanvas.addEventListener('pointermove',pointerMove);inkCanvas.addEventListener('pointerup',pointerUp);inkCanvas.addEventListener('pointercancel',pointerCancel);inkCanvas.addEventListener('lostpointercapture',pointerCancel);
|
|
20897
|
+
win.addEventListener('blur',pointerCancel);win.addEventListener('resize',resizeCanvas);
|
|
20580
20898
|
function render() {
|
|
20581
20899
|
frame = 0; if (!alive || !options.isCurrent()) return;
|
|
20582
|
-
var keep = new Set(), noteGroups = new Map();
|
|
20900
|
+
var keep = new Set(), keepInk = new Set(), noteGroups = new Map();
|
|
20583
20901
|
hitRegions = [];
|
|
20902
|
+
var bodyRect=doc.body.getBoundingClientRect() || {left:0,top:0};
|
|
20903
|
+
inkSvg.setAttribute('width',String(Math.max(doc.documentElement.scrollWidth,win.innerWidth)));
|
|
20904
|
+
inkSvg.setAttribute('height',String(Math.max(doc.documentElement.scrollHeight,win.innerHeight)));
|
|
20584
20905
|
options.annotations().forEach(function(annotation) {
|
|
20585
20906
|
var anchor = annotation.anchor;
|
|
20586
20907
|
if (!validAnchor(anchor) || anchor.href !== options.href || anchor.documentId && options.documentId && anchor.documentId !== options.documentId) return;
|
|
20908
|
+
if(annotation.type==='ink' && annotation.epubInk){renderInkAnnotation(annotation,keepInk,bodyRect);return;}
|
|
20587
20909
|
var range = resolveRange(contents,anchor); if (!range) return;
|
|
20588
20910
|
var rects = Array.from(range.getClientRects()).filter(function(r){return r.width>0 && r.height>0;});
|
|
20589
20911
|
if (!rects.length) return;
|
|
@@ -20595,6 +20917,7 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
20595
20917
|
var color = /^#[0-9a-f]{6}$/i.test(annotation.color) ? annotation.color : '#FFC928';
|
|
20596
20918
|
var style = annotation.markupStyle || annotation.type;
|
|
20597
20919
|
var opacity = Number.isFinite(annotation.opacity) ? Math.max(0,Math.min(1,annotation.opacity)) : 0.35;
|
|
20920
|
+
if(style === 'highlight')opacity=Math.min(0.35,opacity);
|
|
20598
20921
|
rects.forEach(function(rect) {
|
|
20599
20922
|
var mark = doc.createElement('div');
|
|
20600
20923
|
var bodyRect=doc.body.getBoundingClientRect();
|
|
@@ -20607,8 +20930,10 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
20607
20930
|
if (hasNote) {
|
|
20608
20931
|
var last = rects[rects.length-1], button = doc.createElement('button');
|
|
20609
20932
|
button.textContent = '\u25CF'; button.setAttribute('aria-label',options.labels().comment || '');
|
|
20610
|
-
|
|
20611
|
-
var
|
|
20933
|
+
var pageWidth=Math.max(44, options.pageWidth ? options.pageWidth() : win.innerWidth);
|
|
20934
|
+
var bodyRect=doc.body.getBoundingClientRect(), column=Math.max(0,Math.floor((last.left-bodyRect.left)/pageWidth));
|
|
20935
|
+
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';
|
|
20936
|
+
var key = column+":"+Math.floor(last.top/44);
|
|
20612
20937
|
var neighbors=noteGroups.get(key);
|
|
20613
20938
|
if(!neighbors){neighbors={button:button,ids:[]};noteGroups.set(key,neighbors);group.appendChild(button);}
|
|
20614
20939
|
neighbors.ids.push(annotation.id);
|
|
@@ -20619,22 +20944,26 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
20619
20944
|
group.button.addEventListener('click',function(e){e.stopPropagation();if(options.isCurrent())options.onTap(group.ids[0],group.ids);});
|
|
20620
20945
|
});
|
|
20621
20946
|
registry.forEach(function(group,id){if (!keep.has(id)) {group.remove();registry.delete(id);}});
|
|
20947
|
+
inkRegistry.forEach(function(group,id){if (!keepInk.has(id)) {group.remove();inkRegistry.delete(id);}});
|
|
20622
20948
|
}
|
|
20623
20949
|
function schedule() { if (alive && !frame) frame = win.requestAnimationFrame(render); }
|
|
20950
|
+
function rebuildAndSchedule(){if(!alive)return;rebuildSpatialIndex();schedule();}
|
|
20951
|
+
function handleResize(){resizeCanvas();rebuildAndSchedule();}
|
|
20952
|
+
function handleDocumentLoad(){rebuildAndSchedule();}
|
|
20624
20953
|
function tapMarkup(event) {
|
|
20625
20954
|
if(!alive || !options.isCurrent() || String(win.getSelection() || '').length || event.target.closest('[data-papyrus-overlay]'))return;
|
|
20626
20955
|
var hit=hitRegions.find(function(item){return item.rects.some(function(r){return event.clientX>=r.left && event.clientX<=r.right && event.clientY>=r.top && event.clientY<=r.bottom;});});
|
|
20627
20956
|
if(hit) {event.stopPropagation();options.onTap(hit.id);}
|
|
20628
20957
|
}
|
|
20629
20958
|
doc.addEventListener('click',tapMarkup);
|
|
20630
|
-
var observer = typeof win.ResizeObserver === 'function' ? new win.ResizeObserver(
|
|
20959
|
+
var observer = typeof win.ResizeObserver === 'function' ? new win.ResizeObserver(rebuildAndSchedule) : null;
|
|
20631
20960
|
if (observer) observer.observe(doc.body);
|
|
20632
|
-
win.addEventListener('resize',schedule); doc.addEventListener('load',
|
|
20633
|
-
if (doc.fonts && doc.fonts.ready) doc.fonts.ready.then(schedule);
|
|
20961
|
+
win.addEventListener('resize',handleResize);win.addEventListener('scroll',schedule); doc.addEventListener('load',handleDocumentLoad,true);
|
|
20962
|
+
if (doc.fonts && doc.fonts.ready) doc.fonts.ready.then(function(){if(alive){rebuildSpatialIndex();schedule();}});
|
|
20634
20963
|
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',
|
|
20964
|
+
return {schedule:schedule, setInkMode:function(config){var preset=['ink','highlight','underline'].indexOf(config?.preset)>=0?config.preset:'ink';inkConfig={enabled:!!config?.enabled,preset:preset,color:/^#[0-9a-f]{6}$/i.test(config?.color)?config.color:'#2563eb',opacity:Number.isFinite(config?.opacity)?Math.max(0,Math.min(1,config.opacity)):1,strokeWidth:Number.isFinite(config?.strokeWidth)?Math.max(0.0025,Math.min(0.02,config.strokeWidth)):0.006};inkCanvas.style.pointerEvents=inkConfig.enabled?'auto':'none';if(!inkConfig.enabled)cancelGesture();}, invalidateLayout:rebuildAndSchedule, 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;cancelGesture();if(frame)win.cancelAnimationFrame(frame);if(observer)observer.disconnect();win.removeEventListener('resize',handleResize);win.removeEventListener('scroll',schedule);win.removeEventListener('blur',pointerCancel);doc.removeEventListener('load',handleDocumentLoad,true);doc.removeEventListener('click',tapMarkup);inkCanvas.removeEventListener('pointerdown',pointerDown);inkCanvas.removeEventListener('pointermove',pointerMove);inkCanvas.removeEventListener('pointerup',pointerUp);inkCanvas.removeEventListener('pointercancel',pointerCancel);inkCanvas.removeEventListener('lostpointercapture',pointerCancel);inkCanvas.remove();overlay.remove();doc.body.style.position=originalPosition;registry.clear();inkRegistry.clear();rangeCache.clear();}};
|
|
20636
20965
|
}
|
|
20637
|
-
return {validAnchor:validAnchor,recoverRange:recoverRange,resolveRange:resolveRange,selection:selection,install:install};
|
|
20966
|
+
return {validAnchor:validAnchor,simplifyPath:simplifyPath,compactGesturePoints:compactGesturePoints,densifyPath:densifyPath,createSpatialIndex:createSpatialIndex,queryNearestTextRect:queryNearestTextRect,recoverRange:recoverRange,resolveRange:resolveRange,selection:selection,install:install};
|
|
20638
20967
|
});
|
|
20639
20968
|
|
|
20640
20969
|
/* @papyrus-epub-annotations:end */
|
|
@@ -20645,10 +20974,12 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
20645
20974
|
let currentType = null;
|
|
20646
20975
|
let book = null;
|
|
20647
20976
|
let rendition = null;
|
|
20977
|
+
let epubResizeAnchor = null;
|
|
20648
20978
|
let documentSessionId = null;
|
|
20649
20979
|
let annotationDocumentId;
|
|
20650
20980
|
let annotationLabels = {};
|
|
20651
20981
|
let epubAnnotations = [];
|
|
20982
|
+
let epubInkMode = {enabled:false,color:'#2563eb',opacity:1,strokeWidth:0.006};
|
|
20652
20983
|
const epubAnnotationRenderers = new Map();
|
|
20653
20984
|
let spineItems = [];
|
|
20654
20985
|
let textPages = [];
|
|
@@ -21057,6 +21388,7 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
21057
21388
|
};
|
|
21058
21389
|
|
|
21059
21390
|
const clearViewer = () => {
|
|
21391
|
+
if(epubResizeAnchor){epubResizeAnchor.destroy();epubResizeAnchor=null;}
|
|
21060
21392
|
epubAnnotationRenderers.forEach(renderer => renderer.destroy());
|
|
21061
21393
|
epubAnnotationRenderers.clear();
|
|
21062
21394
|
if (epubInteractionCleanup) {
|
|
@@ -21713,29 +22045,63 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
21713
22045
|
pageCount,
|
|
21714
22046
|
});
|
|
21715
22047
|
|
|
22048
|
+
if (book.locations?.generate) {
|
|
22049
|
+
const activeBook=book;
|
|
22050
|
+
activeBook.locations.generate(150).then(() => {
|
|
22051
|
+
if (isCurrentLoad() && activeBook===book && epubLocation) {
|
|
22052
|
+
epubLocation.progress=activeBook.locations.percentageFromCfi(epubLocation.cfi);
|
|
22053
|
+
sendEvent('EPUB_LOCATION',{documentSessionId,location:epubLocation});
|
|
22054
|
+
}
|
|
22055
|
+
}).catch(() => {});
|
|
22056
|
+
}
|
|
22057
|
+
return renderEpubRendition(loadId,generation,null);
|
|
22058
|
+
};
|
|
22059
|
+
|
|
22060
|
+
const renderEpubRendition = async (loadId,generation,target) => {
|
|
22061
|
+
const diagnosticPayload={loadId};
|
|
22062
|
+
const isCurrentLoad=()=>generation===epubLoadGeneration;
|
|
22063
|
+
if(epubInteractionCleanup)epubInteractionCleanup();
|
|
22064
|
+
if(rendition)rendition.destroy();
|
|
21716
22065
|
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
|
-
});
|
|
22066
|
+
rendition = book.renderTo(viewer, window.PapyrusEpubReader.options(epubViewMode === 'single' ? 'paged' : 'chapter-scroll'));
|
|
21725
22067
|
sendEpubDiagnostic('epub.rendition.created', diagnosticPayload);
|
|
21726
22068
|
|
|
21727
22069
|
if (rendition && rendition.hooks && rendition.hooks.content) {
|
|
21728
22070
|
const session = documentSessionId;
|
|
21729
22071
|
const activeRendition = rendition;
|
|
21730
22072
|
rendition.hooks.content.register((contents) => {
|
|
22073
|
+
const removeGestureListeners = window.PapyrusEpubReader.install(contents, {
|
|
22074
|
+
mode: () => epubViewMode === 'single' ? 'paged' : 'chapter-scroll',
|
|
22075
|
+
rtl: () => book.package?.metadata?.direction === 'rtl' || book.spine?.direction === 'rtl',
|
|
22076
|
+
blocked: () => Boolean(nativeMenuSelection && String(nativeMenuSelection.contents?.window?.getSelection() || '').trim()),
|
|
22077
|
+
annotationHit: point => epubAnnotationRenderers.get(contents)?.hit(point.x,point.y),
|
|
22078
|
+
current: () => session === documentSessionId && activeRendition === rendition,
|
|
22079
|
+
interact: () => epubResizeAnchor?.invalidate(),
|
|
22080
|
+
tap: () => sendEvent('EPUB_CONTENT_TAP',{documentSessionId:session}),
|
|
22081
|
+
turn: direction => {
|
|
22082
|
+
epubNavigationQueue = epubNavigationQueue.catch(()=>{}).then(() => {
|
|
22083
|
+
if(session !== documentSessionId || activeRendition !== rendition)return;
|
|
22084
|
+
epubResizeAnchor?.invalidate();
|
|
22085
|
+
return direction<0?activeRendition.prev():activeRendition.next();
|
|
22086
|
+
});
|
|
22087
|
+
epubNavigationQueue.catch(error => sendEvent('EPUB_NAVIGATION_ERROR',{message:String(error)}));
|
|
22088
|
+
},
|
|
22089
|
+
});
|
|
22090
|
+
const gestureCleanup = () => {removeGestureListeners();epubSelectionCleanups.delete(gestureCleanup);};
|
|
22091
|
+
epubSelectionCleanups.add(gestureCleanup);
|
|
22092
|
+
contents.__papyrusGestureCleanup=gestureCleanup;
|
|
21731
22093
|
const href = spineItems[contents.sectionIndex]?.href;
|
|
21732
22094
|
if (href && window.PapyrusEpubAnnotations) {
|
|
21733
22095
|
const renderer = window.PapyrusEpubAnnotations.install(contents, {
|
|
21734
22096
|
href, get documentId() { return annotationDocumentId; },
|
|
22097
|
+
spineIndex:contents.sectionIndex,
|
|
21735
22098
|
isCurrent: () => session === documentSessionId && activeRendition === rendition,
|
|
22099
|
+
pageWidth: () => activeRendition.layout?.width || viewer.clientWidth,
|
|
21736
22100
|
annotations: () => epubAnnotations, labels: () => annotationLabels,
|
|
22101
|
+
onInkCommit: annotation => sendEvent('EPUB_INK_CREATED',{documentSessionId:session,annotation}),
|
|
21737
22102
|
onTap: (id, ids) => sendEvent("EPUB_ANNOTATION_TAP", {documentSessionId: session, id, ids}),
|
|
21738
22103
|
});
|
|
22104
|
+
renderer.setInkMode(epubInkMode);
|
|
21739
22105
|
epubAnnotationRenderers.set(contents,renderer);
|
|
21740
22106
|
}
|
|
21741
22107
|
const frame = contents && contents.document ? contents.document.defaultView.frameElement : null;
|
|
@@ -21751,8 +22117,7 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
21751
22117
|
typeof selectionWindow.getSelection === 'function'
|
|
21752
22118
|
) {
|
|
21753
22119
|
let selectionTimer = null;
|
|
21754
|
-
|
|
21755
|
-
let lastSelectionAt = 0;
|
|
22120
|
+
|
|
21756
22121
|
const reportSelection = () => {
|
|
21757
22122
|
selectionTimer = null;
|
|
21758
22123
|
if (session !== documentSessionId || activeRendition !== rendition) return;
|
|
@@ -21767,11 +22132,7 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
21767
22132
|
try { cfi = contents.cfiFromRange(range); } catch (_) { return; }
|
|
21768
22133
|
const anchor = window.PapyrusEpubAnnotations?.selection(contents, cfi, href, annotationDocumentId);
|
|
21769
22134
|
if (!anchor) return;
|
|
21770
|
-
|
|
21771
|
-
const now = Date.now();
|
|
21772
|
-
if (key === lastSelectionKey && now - lastSelectionAt < 750) return;
|
|
21773
|
-
lastSelectionKey = key;
|
|
21774
|
-
lastSelectionAt = now;
|
|
22135
|
+
if (nativeMenuSelection?.payload?.anchor?.cfiRange === anchor.cfiRange && nativeMenuSelection?.payload?.anchor?.quote === anchor.quote) return;
|
|
21775
22136
|
const payload = {documentSessionId: session, text: anchor.quote,
|
|
21776
22137
|
pageIndex: contents.sectionIndex + 1, anchor};
|
|
21777
22138
|
nativeMenuSelection = {contents, payload};
|
|
@@ -21786,6 +22147,7 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
21786
22147
|
// The content document still emits selectionchange, so resolve its
|
|
21787
22148
|
// live Range to a CFI before the native menu action can fire.
|
|
21788
22149
|
if (text) reportSelection();
|
|
22150
|
+
else if (nativeMenuSelection?.contents === contents) nativeMenuSelection = null;
|
|
21789
22151
|
};
|
|
21790
22152
|
selectionDocument.addEventListener('selectionchange', handleSelectionChange);
|
|
21791
22153
|
const selectionCleanup = () => {
|
|
@@ -21808,6 +22170,7 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
21808
22170
|
typeof rendition.hooks.unloaded.register === 'function'
|
|
21809
22171
|
) {
|
|
21810
22172
|
rendition.hooks.unloaded.register((view) => {
|
|
22173
|
+
view?.contents?.__papyrusGestureCleanup?.();
|
|
21811
22174
|
const cleanup = view && view.contents && view.contents.__papyrusSelectionCleanup;
|
|
21812
22175
|
if (typeof cleanup === 'function') cleanup();
|
|
21813
22176
|
const renderer = epubAnnotationRenderers.get(view?.contents);
|
|
@@ -21823,21 +22186,37 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
21823
22186
|
if (selectionSession !== documentSessionId || selectionRendition !== rendition) return;
|
|
21824
22187
|
const href = spineItems[contents.sectionIndex]?.href;
|
|
21825
22188
|
const anchor = href && window.PapyrusEpubAnnotations?.selection(contents,cfiRange,href,annotationDocumentId);
|
|
21826
|
-
if (!anchor) return;
|
|
22189
|
+
if (!anchor || nativeMenuSelection?.payload?.anchor?.cfiRange === anchor.cfiRange && nativeMenuSelection?.payload?.anchor?.quote === anchor.quote) return;
|
|
21827
22190
|
epubScrollDiagnostics && epubScrollDiagnostics.setSelectionActive(true);
|
|
21828
22191
|
const payload = {documentSessionId: selectionSession, text: anchor.quote, pageIndex: contents.sectionIndex+1, anchor};
|
|
21829
22192
|
nativeMenuSelection = {contents, payload};
|
|
21830
22193
|
sendEvent('EPUB_TEXT_SELECTED', payload);
|
|
21831
22194
|
});
|
|
21832
|
-
['rendered','resized','layout'].forEach(name => rendition.on(name, () => {
|
|
21833
|
-
if (selectionSession === documentSessionId && selectionRendition === rendition) epubAnnotationRenderers.forEach(renderer => renderer.schedule());
|
|
22195
|
+
['rendered','resized','layout','relocated'].forEach(name => rendition.on(name, () => {
|
|
22196
|
+
if (selectionSession === documentSessionId && selectionRendition === rendition) epubAnnotationRenderers.forEach(renderer => name==='relocated'?renderer.schedule():renderer.invalidateLayout());
|
|
21834
22197
|
}));
|
|
21835
22198
|
rendition.on('relocated', (location) => {
|
|
22199
|
+
if (selectionSession !== documentSessionId || selectionRendition !== rendition) return;
|
|
21836
22200
|
const start = location && location.start;
|
|
21837
22201
|
let index = start && Number.isInteger(start.index) ? start.index : -1;
|
|
21838
22202
|
if (index < 0 && start && start.href) index = getSpineIndexByHref(start.href);
|
|
21839
22203
|
if (index < 0 || index >= spineItems.length) return;
|
|
21840
22204
|
epubScrollDiagnostics && epubScrollDiagnostics.relocated(location);
|
|
22205
|
+
let pageGeometry;
|
|
22206
|
+
const manager=rendition.manager,layout=manager?.layout;
|
|
22207
|
+
if(epubViewMode==='single' && layout?.divisor===1 && !manager?.settings?.fullsize && manager?.settings?.direction==='ltr'){
|
|
22208
|
+
const visible=manager.visible?.();
|
|
22209
|
+
const view=visible?.find(view=>view.index===index);
|
|
22210
|
+
if(view && manager.container){
|
|
22211
|
+
pageGeometry={direction:'ltr',firstIndex:book.spine.first()?.index,lastIndex:book.spine.last()?.index,pageWidth:layout.pageWidth,offset:manager.container.getBoundingClientRect().left-view.position().left};
|
|
22212
|
+
}
|
|
22213
|
+
}
|
|
22214
|
+
epubLocation=window.PapyrusEpubReader.location(location,spineItems.length,epubViewMode==='single'?'paged':'chapter-scroll',pageGeometry);
|
|
22215
|
+
if(epubLocation){
|
|
22216
|
+
epubLocation.cfi=epubResizeAnchor?.cfi() || epubLocation.cfi;
|
|
22217
|
+
if(book.locations?.length?.()>0)epubLocation.progress=book.locations.percentageFromCfi(epubLocation.cfi);
|
|
22218
|
+
sendEvent('EPUB_LOCATION',{documentSessionId,location:epubLocation});
|
|
22219
|
+
}
|
|
21841
22220
|
const nextPage = index + 1;
|
|
21842
22221
|
if (nextPage === currentPage) return;
|
|
21843
22222
|
currentPage = nextPage;
|
|
@@ -21845,21 +22224,23 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
21845
22224
|
});
|
|
21846
22225
|
}
|
|
21847
22226
|
|
|
22227
|
+
applyEpubZoom();
|
|
21848
22228
|
sendEpubDiagnostic('epub.display.start', diagnosticPayload);
|
|
21849
22229
|
await withEpubStageTimeout(
|
|
21850
|
-
|
|
22230
|
+
rendition.display(target || spineItems[0]?.href),
|
|
21851
22231
|
'rendition.display',
|
|
21852
22232
|
diagnosticPayload,
|
|
21853
22233
|
);
|
|
21854
22234
|
if (!isCurrentLoad()) throw new Error('EPUB load superseded by a newer load');
|
|
21855
22235
|
sendEpubDiagnostic('epub.display.end', diagnosticPayload);
|
|
22236
|
+
const resizeRendition=rendition;
|
|
22237
|
+
epubResizeAnchor=window.PapyrusEpubReader.installResizeAnchor(resizeRendition.manager,()=>resizeRendition.location?.start?.cfi);
|
|
21856
22238
|
if (
|
|
21857
22239
|
rendition &&
|
|
21858
22240
|
rendition.manager &&
|
|
21859
22241
|
typeof rendition.manager.on === 'function' &&
|
|
21860
22242
|
typeof rendition.on === 'function'
|
|
21861
22243
|
) {
|
|
21862
|
-
let touchStart = null;
|
|
21863
22244
|
let lastScrollOffset = -1;
|
|
21864
22245
|
const manager = rendition.manager;
|
|
21865
22246
|
epubScrollDiagnostics = createEpubScrollDiagnostics(manager);
|
|
@@ -21934,48 +22315,19 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
21934
22315
|
return result;
|
|
21935
22316
|
};
|
|
21936
22317
|
}
|
|
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) => {
|
|
22318
|
+
const handleScroll = event => {
|
|
21947
22319
|
const offsetY = Math.max(0, Number(event && event.top) || 0);
|
|
21948
22320
|
epubScrollDiagnostics && epubScrollDiagnostics.scroll(event);
|
|
21949
|
-
if (Math.abs(offsetY
|
|
21950
|
-
lastScrollOffset
|
|
21951
|
-
sendEvent('VIEWER_SCROLL',
|
|
21952
|
-
};
|
|
21953
|
-
const handleTouchStart = (event) => {
|
|
21954
|
-
touchStart = getTouchPoint(event);
|
|
21955
|
-
epubScrollDiagnostics && epubScrollDiagnostics.touchStart(event);
|
|
21956
|
-
};
|
|
21957
|
-
const handleTouchMove = (event) => {
|
|
21958
|
-
epubScrollDiagnostics && epubScrollDiagnostics.touchMove(event);
|
|
22321
|
+
if (Math.abs(offsetY-lastScrollOffset)<1) return;
|
|
22322
|
+
lastScrollOffset=offsetY;
|
|
22323
|
+
sendEvent('VIEWER_SCROLL',{offsetY});
|
|
21959
22324
|
};
|
|
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
22325
|
manager.on('scroll', handleScroll);
|
|
21972
22326
|
const handleScrolled = (event) => {
|
|
21973
22327
|
epubScrollDiagnostics && epubScrollDiagnostics.settled(event);
|
|
21974
22328
|
};
|
|
21975
22329
|
manager.on('scrolled', handleScrolled);
|
|
21976
|
-
|
|
21977
|
-
rendition.on('touchmove', handleTouchMove);
|
|
21978
|
-
rendition.on('touchend', handleTouchEnd);
|
|
22330
|
+
|
|
21979
22331
|
epubInteractionCleanup = () => {
|
|
21980
22332
|
epubSelectionCleanups.forEach((cleanup) => cleanup());
|
|
21981
22333
|
epubSelectionCleanups.clear();
|
|
@@ -21984,16 +22336,9 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
21984
22336
|
if (originalEnqueue) queue.enqueue = originalEnqueue;
|
|
21985
22337
|
if (typeof manager.off === 'function') manager.off('scroll', handleScroll);
|
|
21986
22338
|
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
22339
|
epubScrollDiagnostics = null;
|
|
21993
22340
|
};
|
|
21994
22341
|
}
|
|
21995
|
-
applyEpubZoom();
|
|
21996
|
-
|
|
21997
22342
|
const outline = await withEpubStageTimeout(
|
|
21998
22343
|
buildOutline(),
|
|
21999
22344
|
'outline',
|
|
@@ -22007,6 +22352,8 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
22007
22352
|
return { pageCount, outline };
|
|
22008
22353
|
};
|
|
22009
22354
|
|
|
22355
|
+
let epubNavigationQueue = Promise.resolve();
|
|
22356
|
+
let epubNavigationRequest = 0;
|
|
22010
22357
|
const displayEpubPage = async (pageIndex) => {
|
|
22011
22358
|
if (!rendition) return;
|
|
22012
22359
|
const item = spineItems[pageIndex];
|
|
@@ -22016,9 +22363,19 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
22016
22363
|
target,
|
|
22017
22364
|
pageIndex,
|
|
22018
22365
|
});
|
|
22019
|
-
|
|
22020
|
-
|
|
22021
|
-
|
|
22366
|
+
const activeRendition = rendition;
|
|
22367
|
+
const session = documentSessionId;
|
|
22368
|
+
const request = ++epubNavigationRequest;
|
|
22369
|
+
const navigation = epubNavigationQueue.catch(() => {}).then(async () => {
|
|
22370
|
+
if (request !== epubNavigationRequest || session !== documentSessionId || activeRendition !== rendition) return;
|
|
22371
|
+
epubResizeAnchor?.invalidate();
|
|
22372
|
+
await activeRendition.display(target);
|
|
22373
|
+
if (request !== epubNavigationRequest || session !== documentSessionId || activeRendition !== rendition) return;
|
|
22374
|
+
currentPage = pageIndex + 1;
|
|
22375
|
+
sendState();
|
|
22376
|
+
});
|
|
22377
|
+
epubNavigationQueue = navigation;
|
|
22378
|
+
await navigation;
|
|
22022
22379
|
};
|
|
22023
22380
|
|
|
22024
22381
|
const getTextContent = async (pageIndex) => {
|
|
@@ -22120,6 +22477,8 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
22120
22477
|
};
|
|
22121
22478
|
|
|
22122
22479
|
let nativeMenuSelection = null;
|
|
22480
|
+
let epubViewMode = "single";
|
|
22481
|
+
let epubLocation = null;
|
|
22123
22482
|
|
|
22124
22483
|
const handleCommand = async (message) => {
|
|
22125
22484
|
const { id, kind, payload } = message;
|
|
@@ -22131,7 +22490,13 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
22131
22490
|
documentSessionId = payload.documentSessionId || null;
|
|
22132
22491
|
epubAnnotations = [];
|
|
22133
22492
|
annotationDocumentId = undefined;
|
|
22493
|
+
epubInkMode = {enabled:false,color:'#2563eb',opacity:1,strokeWidth:0.006};
|
|
22134
22494
|
zoom = 1.0;
|
|
22495
|
+
epubViewMode = payload.epubMode === "chapter-scroll" ? "continuous" : "single";
|
|
22496
|
+
epubLocation = null;
|
|
22497
|
+
nativeMenuSelection = null;
|
|
22498
|
+
epubNavigationRequest += 1;
|
|
22499
|
+
epubNavigationQueue = Promise.resolve();
|
|
22135
22500
|
|
|
22136
22501
|
if (currentType === 'text') {
|
|
22137
22502
|
const result = await loadText(
|
|
@@ -22186,17 +22551,24 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
22186
22551
|
epubAnnotationRenderers.forEach(renderer => renderer.schedule());
|
|
22187
22552
|
} else {
|
|
22188
22553
|
const annotation = epubAnnotations.find(a => a.id === payload.annotationId);
|
|
22189
|
-
if (!annotation) throw new Error('Annotation not available');
|
|
22554
|
+
if (!annotation || (annotation.anchor.documentId && annotation.anchor.documentId !== annotationDocumentId)) throw new Error('Annotation not available for this document');
|
|
22190
22555
|
// Navigation uses the CFI, never a synthetic percentage/page rectangle.
|
|
22191
22556
|
const navigationSession = documentSessionId;
|
|
22192
22557
|
const activeRendition = rendition;
|
|
22193
22558
|
// Open the confirmed chapter first, resolve its quote, then navigate its actual range.
|
|
22194
|
-
|
|
22195
|
-
|
|
22196
|
-
|
|
22197
|
-
|
|
22198
|
-
|
|
22199
|
-
|
|
22559
|
+
epubNavigationRequest += 1;
|
|
22560
|
+
const navigation = epubNavigationQueue.catch(() => {}).then(async () => {
|
|
22561
|
+
if(navigationSession !== documentSessionId || activeRendition !== rendition)throw new Error('Stale EPUB navigation');
|
|
22562
|
+
epubResizeAnchor?.invalidate();
|
|
22563
|
+
await activeRendition.display(annotation.anchor.href);
|
|
22564
|
+
if(navigationSession !== documentSessionId || activeRendition !== rendition)throw new Error('Stale EPUB navigation');
|
|
22565
|
+
const contents = activeRendition.getContents().find(c => spineItems[c.sectionIndex]?.href === annotation.anchor.href);
|
|
22566
|
+
const range = contents && window.PapyrusEpubAnnotations.resolveRange(contents,annotation.anchor);
|
|
22567
|
+
if(!range)throw new Error('EPUB anchor unresolved');
|
|
22568
|
+
await activeRendition.display(contents.cfiFromRange(range));
|
|
22569
|
+
});
|
|
22570
|
+
epubNavigationQueue = navigation;
|
|
22571
|
+
await navigation;
|
|
22200
22572
|
}
|
|
22201
22573
|
sendResponse(id,true,null); return;
|
|
22202
22574
|
}
|
|
@@ -22223,12 +22595,61 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
22223
22595
|
return;
|
|
22224
22596
|
}
|
|
22225
22597
|
|
|
22598
|
+
if (kind === 'epub-turn-page') {
|
|
22599
|
+
if (epubViewMode !== 'single') {sendResponse(id,true,null); return;}
|
|
22600
|
+
if (currentType !== 'epub' || payload.documentSessionId !== documentSessionId) throw new Error('Stale EPUB navigation');
|
|
22601
|
+
const active = rendition;
|
|
22602
|
+
epubNavigationQueue = epubNavigationQueue.catch(() => {}).then(() => {
|
|
22603
|
+
if (active !== rendition || payload.documentSessionId !== documentSessionId) return;
|
|
22604
|
+
epubResizeAnchor?.invalidate();
|
|
22605
|
+
return payload.direction < 0 ? active.prev() : active.next();
|
|
22606
|
+
});
|
|
22607
|
+
await epubNavigationQueue;
|
|
22608
|
+
sendResponse(id,true,null); return;
|
|
22609
|
+
}
|
|
22610
|
+
|
|
22611
|
+
if (kind === 'set-epub-view-mode') {
|
|
22612
|
+
if (currentType !== 'epub' || payload.documentSessionId !== documentSessionId) throw new Error('Stale EPUB layout session');
|
|
22613
|
+
const next=payload.epubMode ? (payload.epubMode==='paged'?'single':'continuous') : (payload.viewMode==='single'?'single':'continuous');
|
|
22614
|
+
{
|
|
22615
|
+
epubNavigationQueue=epubNavigationQueue.catch(()=>{}).then(async()=>{
|
|
22616
|
+
if(payload.documentSessionId!==documentSessionId || next===epubViewMode)return;
|
|
22617
|
+
const target=epubResizeAnchor?.cfi() || epubLocation?.cfi;
|
|
22618
|
+
epubViewMode=next;
|
|
22619
|
+
await renderEpubRendition('layout',epubLoadGeneration,target);
|
|
22620
|
+
});
|
|
22621
|
+
await epubNavigationQueue;
|
|
22622
|
+
}
|
|
22623
|
+
sendResponse(id,true,null);return;
|
|
22624
|
+
}
|
|
22625
|
+
if (kind === 'set-epub-ink-mode') {
|
|
22626
|
+
if(currentType!=='epub'||!documentSessionId||payload.documentSessionId!==documentSessionId)throw new Error('Stale EPUB ink session');
|
|
22627
|
+
epubInkMode={enabled:payload.enabled===true,preset:['ink','highlight','underline'].indexOf(payload.preset)>=0?payload.preset:'ink',color:/^#[0-9a-f]{6}$/i.test(payload.color||'')?payload.color:'#2563eb',opacity:Number.isFinite(payload.opacity)?Math.max(0,Math.min(1,payload.opacity)):1,strokeWidth:Number.isFinite(payload.strokeWidth)?Math.max(0.0025,Math.min(0.02,payload.strokeWidth)):0.006};
|
|
22628
|
+
epubAnnotationRenderers.forEach(renderer=>renderer.setInkMode(epubInkMode));
|
|
22629
|
+
sendResponse(id,true,null);return;
|
|
22630
|
+
}
|
|
22631
|
+
if(kind === 'epub-go-to-location'){
|
|
22632
|
+
if(currentType!=='epub' || payload.documentSessionId!==documentSessionId || !window.PapyrusEpubReader.validCfi(payload.cfi))throw new Error('Invalid EPUB location');
|
|
22633
|
+
epubNavigationQueue=epubNavigationQueue.catch(()=>{}).then(()=>{if(payload.documentSessionId!==documentSessionId)return;epubResizeAnchor?.invalidate();return rendition.display(payload.cfi);});
|
|
22634
|
+
await epubNavigationQueue;sendResponse(id,true,null);return;
|
|
22635
|
+
}
|
|
22636
|
+
|
|
22226
22637
|
if (kind === 'set-zoom') {
|
|
22227
|
-
|
|
22228
|
-
|
|
22229
|
-
|
|
22230
|
-
|
|
22231
|
-
|
|
22638
|
+
const requestedZoom=Math.max(0.5,Math.min(4.0,payload.zoom || 1.0));
|
|
22639
|
+
if(currentType === 'epub') {
|
|
22640
|
+
const session=documentSessionId;
|
|
22641
|
+
epubNavigationQueue=epubNavigationQueue.catch(()=>{}).then(async()=>{
|
|
22642
|
+
if(session!==documentSessionId)return;
|
|
22643
|
+
const active=rendition;
|
|
22644
|
+
const cfi=epubResizeAnchor?.cfi() || epubLocation?.cfi;
|
|
22645
|
+
zoom=requestedZoom;applyEpubZoom();
|
|
22646
|
+
// Let the content CSS update before redisplaying the logical anchor.
|
|
22647
|
+
await new Promise(resolve=>(window.requestAnimationFrame || (callback=>setTimeout(callback,0)))(resolve));
|
|
22648
|
+
if(cfi && active===rendition && session===documentSessionId)await active.display(cfi);
|
|
22649
|
+
});
|
|
22650
|
+
await epubNavigationQueue;
|
|
22651
|
+
} else {zoom=requestedZoom;applyZoom();}
|
|
22652
|
+
sendState();sendResponse(id,true,{zoom});return;
|
|
22232
22653
|
}
|
|
22233
22654
|
|
|
22234
22655
|
if (kind === 'set-rotation') {
|
|
@@ -23391,6 +23812,7 @@ var IconToolStrikeout = ({
|
|
|
23391
23812
|
),
|
|
23392
23813
|
/* @__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
23814
|
] });
|
|
23815
|
+
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
23816
|
var IconCopy = ({
|
|
23395
23817
|
size = 20,
|
|
23396
23818
|
color = defaultColor,
|
|
@@ -23455,6 +23877,39 @@ var IconToolNote = ({
|
|
|
23455
23877
|
/* @__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
23878
|
/* @__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
23879
|
] });
|
|
23880
|
+
var IconHighlight = ({
|
|
23881
|
+
size = 24,
|
|
23882
|
+
color = "#fbbf24"
|
|
23883
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native_svg.default, { width: size, height: size, viewBox: "0 0 24 24", fill: "none", children: [
|
|
23884
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
23885
|
+
import_react_native_svg.Path,
|
|
23886
|
+
{
|
|
23887
|
+
d: "M4 15h16v3a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1v-3Z",
|
|
23888
|
+
fill: color,
|
|
23889
|
+
opacity: "0.85"
|
|
23890
|
+
}
|
|
23891
|
+
),
|
|
23892
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
23893
|
+
import_react_native_svg.Path,
|
|
23894
|
+
{
|
|
23895
|
+
d: "M6 5h12v10H6V5Z",
|
|
23896
|
+
stroke: color,
|
|
23897
|
+
strokeWidth: "2",
|
|
23898
|
+
strokeLinecap: "round",
|
|
23899
|
+
strokeLinejoin: "round",
|
|
23900
|
+
fill: "none"
|
|
23901
|
+
}
|
|
23902
|
+
),
|
|
23903
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
23904
|
+
import_react_native_svg.Path,
|
|
23905
|
+
{
|
|
23906
|
+
d: "M8 8h8M8 11h5",
|
|
23907
|
+
stroke: color,
|
|
23908
|
+
strokeWidth: "2",
|
|
23909
|
+
strokeLinecap: "round"
|
|
23910
|
+
}
|
|
23911
|
+
)
|
|
23912
|
+
] });
|
|
23458
23913
|
var IconUnderline = ({
|
|
23459
23914
|
size = 24,
|
|
23460
23915
|
color = "#60a5fa",
|
|
@@ -25883,8 +26338,38 @@ var styles = import_react_native.StyleSheet.create({
|
|
|
25883
26338
|
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
26339
|
var PageRenderer_default = (0, import_react2.memo)(PageRenderer, arePageRendererPropsEqual);
|
|
25885
26340
|
|
|
26341
|
+
// components/PapyrusSafeArea.tsx
|
|
26342
|
+
var import_react3 = __toESM(require("react"));
|
|
26343
|
+
var import_react_native_safe_area_context = require("react-native-safe-area-context");
|
|
26344
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
26345
|
+
var papyrusSafeAreaContext = import_react_native_safe_area_context.SafeAreaInsetsContext;
|
|
26346
|
+
var ZERO_SAFE_AREA_INSETS = {
|
|
26347
|
+
top: 0,
|
|
26348
|
+
bottom: 0,
|
|
26349
|
+
left: 0,
|
|
26350
|
+
right: 0
|
|
26351
|
+
};
|
|
26352
|
+
var usePapyrusSafeAreaInsets = () => (0, import_react3.useContext)(papyrusSafeAreaContext) ?? ZERO_SAFE_AREA_INSETS;
|
|
26353
|
+
function PapyrusSafeAreaBoundary({
|
|
26354
|
+
children
|
|
26355
|
+
}) {
|
|
26356
|
+
const insets = (0, import_react3.useContext)(papyrusSafeAreaContext);
|
|
26357
|
+
if (insets) return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_jsx_runtime4.Fragment, { children });
|
|
26358
|
+
return import_react3.default.createElement(import_react_native_safe_area_context.SafeAreaProvider, null, children);
|
|
26359
|
+
}
|
|
26360
|
+
|
|
26361
|
+
// components/epubReadingLocation.ts
|
|
26362
|
+
function parseEpubReadingLocation(raw) {
|
|
26363
|
+
if (!raw || typeof raw !== "object") return null;
|
|
26364
|
+
const p = raw;
|
|
26365
|
+
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;
|
|
26366
|
+
if (p.mode === "chapter-scroll") return p.visualPage === null && p.visualPageCount === null ? p : null;
|
|
26367
|
+
if (p.mode !== "paged" || !Number.isSafeInteger(p.visualPage) || (p.visualPage ?? 0) < 1 || !Number.isSafeInteger(p.visualPageCount) || (p.visualPageCount ?? 0) < (p.visualPage ?? 0)) return null;
|
|
26368
|
+
return p;
|
|
26369
|
+
}
|
|
26370
|
+
|
|
25886
26371
|
// components/WebViewViewer.tsx
|
|
25887
|
-
var
|
|
26372
|
+
var import_react4 = require("react");
|
|
25888
26373
|
var import_react_native2 = require("react-native");
|
|
25889
26374
|
var import_clipboard3 = __toESM(require("@react-native-clipboard/clipboard"));
|
|
25890
26375
|
var import_react_native_webview = __toESM(require("react-native-webview"));
|
|
@@ -25935,8 +26420,14 @@ var parseWebViewInteraction = (raw) => {
|
|
|
25935
26420
|
|
|
25936
26421
|
// components/epubAnnotationEvents.ts
|
|
25937
26422
|
var import_core3 = require("@papyrus-sdk/core");
|
|
26423
|
+
var EPUB_INK_PRESETS = ["ink", "highlight", "underline"];
|
|
26424
|
+
function resolveEpubInkMode(input) {
|
|
26425
|
+
if (!input.isLoaded || input.documentType !== "epub") return null;
|
|
26426
|
+
const preset = EPUB_INK_PRESETS.includes(input.preset) ? input.preset : "ink";
|
|
26427
|
+
return { enabled: input.activeTool === "ink" && EPUB_INK_PRESETS.includes(input.preset), preset, color: input.color, opacity: input.opacity, strokeWidth: input.strokeWidth };
|
|
26428
|
+
}
|
|
25938
26429
|
function parseEpubAnnotationEvent(raw, session, documentId) {
|
|
25939
|
-
if (!session || raw.length >
|
|
26430
|
+
if (!session || raw.length > 75e4) return null;
|
|
25940
26431
|
let message;
|
|
25941
26432
|
try {
|
|
25942
26433
|
message = JSON.parse(raw);
|
|
@@ -25946,13 +26437,20 @@ function parseEpubAnnotationEvent(raw, session, documentId) {
|
|
|
25946
26437
|
const p = message?.payload;
|
|
25947
26438
|
if (message?.type !== "event" || !p || p.documentSessionId !== session) return null;
|
|
25948
26439
|
if (message.name === "EPUB_ANNOTATION_TAP") return typeof p.id === "string" && p.id.length <= 256 ? { kind: "tap", id: p.id, ids: Array.isArray(p.ids) && p.ids.length <= 100 && p.ids.every((id) => typeof id === "string" && id.length <= 256) ? p.ids : void 0 } : null;
|
|
26440
|
+
if (message.name === "EPUB_INK_CREATED") {
|
|
26441
|
+
const a = p.annotation, sidecar = a?.epubInk, first = sidecar?.segments?.[0], point = first?.points?.[0];
|
|
26442
|
+
if (!a || a.type !== "ink" || typeof a.id !== "string" || !a.id || a.id.length > 256 || !Number.isSafeInteger(a.pageIndex) || a.pageIndex < 1 || !(0, import_core3.validateAnnotationAnchor)(a.anchor) || a.anchor.kind !== "epub-cfi" || !(0, import_core3.validateEpubInkData)(sidecar) || !point || a.anchor.cfiRange !== point.cfiRange || a.anchor.quote !== point.quote || a.anchor.href !== first.href || documentId && (sidecar.documentId && sidecar.documentId !== documentId || a.anchor.documentId && a.anchor.documentId !== documentId) || sidecar.documentId && a.anchor.documentId && sidecar.documentId !== a.anchor.documentId) return null;
|
|
26443
|
+
const rect = a.rect, path = a.path;
|
|
26444
|
+
if (!rect || ![rect.x, rect.y, rect.width, rect.height].every((n) => typeof n === "number" && Number.isFinite(n) && n >= 0 && n <= 1) || rect.x + rect.width > 1.000001 || rect.y + rect.height > 1.000001 || !Array.isArray(path) || path.length < 2 || path.length > 512 || path.some((p2) => !p2 || ![p2.x, p2.y].every((n) => typeof n === "number" && Number.isFinite(n) && n >= 0 && n <= 1)) || typeof a.color !== "string" || !/^#[0-9a-f]{6}$/i.test(a.color) || !Number.isFinite(a.createdAt) || a.opacity !== void 0 && (!Number.isFinite(a.opacity) || a.opacity < 0 || a.opacity > 1) || a.strokeWidth !== void 0 && (!Number.isFinite(a.strokeWidth) || a.strokeWidth < 25e-4 || a.strokeWidth > 0.02)) return null;
|
|
26445
|
+
return { kind: "ink", session, annotation: a };
|
|
26446
|
+
}
|
|
25949
26447
|
if (message.name !== "EPUB_TEXT_SELECTED" || !(0, import_core3.validateAnnotationAnchor)(p.anchor) || p.anchor.kind !== "epub-cfi" || p.text !== p.anchor.quote || !Number.isSafeInteger(p.pageIndex) || p.pageIndex < 1) return null;
|
|
25950
26448
|
if (documentId && p.anchor.documentId && p.anchor.documentId !== documentId) return null;
|
|
25951
26449
|
return { kind: "selection", session, text: p.text, pageIndex: p.pageIndex, anchor: { ...p.anchor, documentId: documentId ?? p.anchor.documentId } };
|
|
25952
26450
|
}
|
|
25953
26451
|
|
|
25954
26452
|
// components/WebViewViewer.tsx
|
|
25955
|
-
var
|
|
26453
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
25956
26454
|
var runtimeAsset = require_runtime();
|
|
25957
26455
|
var resolveRuntimeSource = (asset) => {
|
|
25958
26456
|
if (typeof asset === "string") {
|
|
@@ -25972,6 +26470,7 @@ var resolveRuntimeSource = (asset) => {
|
|
|
25972
26470
|
};
|
|
25973
26471
|
var WebViewViewer = ({
|
|
25974
26472
|
engine,
|
|
26473
|
+
documentType,
|
|
25975
26474
|
documentId,
|
|
25976
26475
|
onDefineSelection,
|
|
25977
26476
|
defineSelectionMode,
|
|
@@ -25979,19 +26478,20 @@ var WebViewViewer = ({
|
|
|
25979
26478
|
onScrollOffset,
|
|
25980
26479
|
onTap
|
|
25981
26480
|
}) => {
|
|
25982
|
-
const webViewRef = (0,
|
|
25983
|
-
const
|
|
25984
|
-
const
|
|
26481
|
+
const webViewRef = (0, import_react4.useRef)(null);
|
|
26482
|
+
const insets = usePapyrusSafeAreaInsets();
|
|
26483
|
+
const { pageTheme, epubReadingMode, setDocumentState, annotations, isLoaded, locale, annotationColor, annotationOpacity, inkStrokeWidth, activeTool, activeDrawToolPreset, addAnnotation, beginAnnotationDraft, setSelectedAnnotation } = (0, import_core4.useViewerStore)();
|
|
26484
|
+
const [selection, setSelection] = (0, import_react4.useState)(null);
|
|
25985
26485
|
const t = getStrings(locale);
|
|
25986
26486
|
const bridgeEngine = engine;
|
|
25987
|
-
const runtimeSource = (0,
|
|
26487
|
+
const runtimeSource = (0, import_react4.useMemo)(
|
|
25988
26488
|
() => resolveRuntimeSource(
|
|
25989
26489
|
bridgeEngine.getWebViewRuntimeSource?.() ?? runtimeAsset
|
|
25990
26490
|
),
|
|
25991
26491
|
[bridgeEngine]
|
|
25992
26492
|
);
|
|
25993
|
-
const [runtimeHtml, setRuntimeHtml] = (0,
|
|
25994
|
-
(0,
|
|
26493
|
+
const [runtimeHtml, setRuntimeHtml] = (0, import_react4.useState)(null);
|
|
26494
|
+
(0, import_react4.useEffect)(() => {
|
|
25995
26495
|
let active = true;
|
|
25996
26496
|
if ("html" in runtimeSource) {
|
|
25997
26497
|
setRuntimeHtml(runtimeSource.html);
|
|
@@ -26012,7 +26512,7 @@ var WebViewViewer = ({
|
|
|
26012
26512
|
active = false;
|
|
26013
26513
|
};
|
|
26014
26514
|
}, [runtimeSource]);
|
|
26015
|
-
const webViewSource = (0,
|
|
26515
|
+
const webViewSource = (0, import_react4.useMemo)(() => {
|
|
26016
26516
|
if (runtimeHtml !== null) {
|
|
26017
26517
|
return {
|
|
26018
26518
|
html: runtimeHtml,
|
|
@@ -26023,13 +26523,13 @@ var WebViewViewer = ({
|
|
|
26023
26523
|
return runtimeSource;
|
|
26024
26524
|
}, [runtimeHtml, runtimeSource]);
|
|
26025
26525
|
const runtimeConfig = bridgeEngine.getWebViewRuntimeConfig?.();
|
|
26026
|
-
const runtimeConfigScript = (0,
|
|
26526
|
+
const runtimeConfigScript = (0, import_react4.useMemo)(() => {
|
|
26027
26527
|
if (!runtimeConfig) return void 0;
|
|
26028
26528
|
return `window.__PAPYRUS_RUNTIME_CONFIG__=${JSON.stringify(
|
|
26029
26529
|
runtimeConfig
|
|
26030
26530
|
)};true;`;
|
|
26031
26531
|
}, [runtimeConfig]);
|
|
26032
|
-
(0,
|
|
26532
|
+
(0, import_react4.useEffect)(() => {
|
|
26033
26533
|
bridgeEngine.attachWebView?.({
|
|
26034
26534
|
postMessage: (message) => {
|
|
26035
26535
|
if (__DEV__) {
|
|
@@ -26043,10 +26543,10 @@ var WebViewViewer = ({
|
|
|
26043
26543
|
bridgeEngine.detachWebView?.();
|
|
26044
26544
|
};
|
|
26045
26545
|
}, [bridgeEngine]);
|
|
26046
|
-
(0,
|
|
26546
|
+
(0, import_react4.useEffect)(() => {
|
|
26047
26547
|
setSelection(null);
|
|
26048
26548
|
}, [engine, documentId]);
|
|
26049
|
-
(0,
|
|
26549
|
+
(0, import_react4.useEffect)(() => {
|
|
26050
26550
|
if (!isLoaded) return;
|
|
26051
26551
|
let active = true;
|
|
26052
26552
|
void bridgeEngine.syncEpubAnnotations?.(annotations, documentId, { comment: t.annotationNote }).catch(() => {
|
|
@@ -26061,6 +26561,19 @@ var WebViewViewer = ({
|
|
|
26061
26561
|
(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
26562
|
setSelection(null);
|
|
26063
26563
|
};
|
|
26564
|
+
(0, import_react4.useEffect)(() => {
|
|
26565
|
+
if (!isLoaded) return;
|
|
26566
|
+
webViewRef.current?.postMessage(JSON.stringify({ id: "epub-layout", kind: "set-epub-view-mode", payload: { epubMode: epubReadingMode, documentSessionId: bridgeEngine.getWebViewDocumentSessionId?.() } }));
|
|
26567
|
+
}, [isLoaded, epubReadingMode, bridgeEngine]);
|
|
26568
|
+
(0, import_react4.useEffect)(() => {
|
|
26569
|
+
if (!isLoaded || documentType !== "epub") return;
|
|
26570
|
+
const inkMode = resolveEpubInkMode({ documentType, isLoaded, activeTool, preset: activeDrawToolPreset, color: annotationColor, opacity: annotationOpacity, strokeWidth: inkStrokeWidth });
|
|
26571
|
+
if (!inkMode) return;
|
|
26572
|
+
webViewRef.current?.postMessage(JSON.stringify({ id: `epub-ink-mode-${Date.now()}`, kind: "set-epub-ink-mode", payload: {
|
|
26573
|
+
...inkMode,
|
|
26574
|
+
documentSessionId: bridgeEngine.getWebViewDocumentSessionId?.()
|
|
26575
|
+
} }));
|
|
26576
|
+
}, [isLoaded, documentType, activeTool, activeDrawToolPreset, annotationColor, annotationOpacity, inkStrokeWidth, bridgeEngine]);
|
|
26064
26577
|
const sendSelectionCommand = (key) => {
|
|
26065
26578
|
webViewRef.current?.postMessage(JSON.stringify({
|
|
26066
26579
|
type: "epub-selection-action",
|
|
@@ -26084,6 +26597,11 @@ var WebViewViewer = ({
|
|
|
26084
26597
|
let annotationRaw = raw;
|
|
26085
26598
|
try {
|
|
26086
26599
|
const message = JSON.parse(raw);
|
|
26600
|
+
if (message.type === "event" && message.name === "EPUB_LOCATION" && message.payload?.documentSessionId === bridgeEngine.getWebViewDocumentSessionId?.()) {
|
|
26601
|
+
const location = parseEpubReadingLocation(message.payload.location);
|
|
26602
|
+
if (location) setDocumentState({ epubLocation: location });
|
|
26603
|
+
}
|
|
26604
|
+
if (message.type === "event" && message.name === "EPUB_CONTENT_TAP" && message.payload?.documentSessionId === bridgeEngine.getWebViewDocumentSessionId?.()) onTap?.();
|
|
26087
26605
|
if (message.type === "event" && message.name === "EPUB_SELECTION_ACTION") {
|
|
26088
26606
|
action = message.payload?.action;
|
|
26089
26607
|
annotationRaw = JSON.stringify({ ...message, name: "EPUB_TEXT_SELECTED" });
|
|
@@ -26115,6 +26633,10 @@ var WebViewViewer = ({
|
|
|
26115
26633
|
else setSelectedAnnotation(annotationEvent.id);
|
|
26116
26634
|
return;
|
|
26117
26635
|
}
|
|
26636
|
+
if (annotationEvent?.kind === "ink" && isLoaded && annotationEvent.session === bridgeEngine.getWebViewDocumentSessionId?.()) {
|
|
26637
|
+
addAnnotation(annotationEvent.annotation);
|
|
26638
|
+
setSelection(null);
|
|
26639
|
+
}
|
|
26118
26640
|
const interaction = parseWebViewInteraction(raw);
|
|
26119
26641
|
if (interaction?.kind === "scroll") onScrollOffset?.(interaction.offsetY);
|
|
26120
26642
|
if (interaction?.kind === "tap") onTap?.();
|
|
@@ -26147,7 +26669,7 @@ var WebViewViewer = ({
|
|
|
26147
26669
|
console.warn("[Papyrus WebView] error", event.nativeEvent);
|
|
26148
26670
|
}
|
|
26149
26671
|
};
|
|
26150
|
-
const themeOverlayStyle = (0,
|
|
26672
|
+
const themeOverlayStyle = (0, import_react4.useMemo)(() => {
|
|
26151
26673
|
switch (pageTheme) {
|
|
26152
26674
|
case "sepia":
|
|
26153
26675
|
return styles2.themeSepia;
|
|
@@ -26159,7 +26681,7 @@ var WebViewViewer = ({
|
|
|
26159
26681
|
return styles2.themeNone;
|
|
26160
26682
|
}
|
|
26161
26683
|
}, [pageTheme]);
|
|
26162
|
-
const allowingReadAccessToURL = (0,
|
|
26684
|
+
const allowingReadAccessToURL = (0, import_react4.useMemo)(() => {
|
|
26163
26685
|
if (!runtimeSource || typeof runtimeSource !== "object") return void 0;
|
|
26164
26686
|
if ("uri" in runtimeSource && runtimeSource.uri) {
|
|
26165
26687
|
return runtimeSource.uri;
|
|
@@ -26172,8 +26694,8 @@ var WebViewViewer = ({
|
|
|
26172
26694
|
maxWidth: resolvedMaxPageWidth,
|
|
26173
26695
|
alignSelf: "center"
|
|
26174
26696
|
} : void 0;
|
|
26175
|
-
return /* @__PURE__ */ (0,
|
|
26176
|
-
/* @__PURE__ */ (0,
|
|
26697
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native2.View, { style: [styles2.container, documentType === "epub" && { paddingTop: insets.top, paddingBottom: insets.bottom }], children: [
|
|
26698
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
26177
26699
|
import_react_native_webview.default,
|
|
26178
26700
|
{
|
|
26179
26701
|
ref: webViewRef,
|
|
@@ -26197,7 +26719,7 @@ var WebViewViewer = ({
|
|
|
26197
26719
|
style: [styles2.webview, cappedWebViewStyle]
|
|
26198
26720
|
}
|
|
26199
26721
|
),
|
|
26200
|
-
/* @__PURE__ */ (0,
|
|
26722
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
26201
26723
|
import_react_native2.View,
|
|
26202
26724
|
{
|
|
26203
26725
|
pointerEvents: "none",
|
|
@@ -26299,22 +26821,22 @@ function getNearbyPdfNotes(annotations, id) {
|
|
|
26299
26821
|
// components/PdfNoteChooser.tsx
|
|
26300
26822
|
var import_react_native3 = require("react-native");
|
|
26301
26823
|
var import_core5 = require("@papyrus-sdk/core");
|
|
26302
|
-
var
|
|
26824
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
26303
26825
|
function PdfNoteChooser({ notes, title, cancel, onSelect, onClose }) {
|
|
26304
|
-
return /* @__PURE__ */ (0,
|
|
26305
|
-
/* @__PURE__ */ (0,
|
|
26306
|
-
/* @__PURE__ */ (0,
|
|
26826
|
+
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: [
|
|
26827
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native3.Text, { style: styles3.title, children: title }),
|
|
26828
|
+
/* @__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
26829
|
index + 1,
|
|
26308
26830
|
". ",
|
|
26309
26831
|
(0, import_core5.getAnnotationNote)(item) || (0, import_core5.getAnnotationQuote)(item)
|
|
26310
26832
|
] }) }) }),
|
|
26311
|
-
/* @__PURE__ */ (0,
|
|
26833
|
+
/* @__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
26834
|
] }) }) });
|
|
26313
26835
|
}
|
|
26314
26836
|
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
26837
|
|
|
26316
26838
|
// components/DedicatedAndroidPdfViewer.tsx
|
|
26317
|
-
var
|
|
26839
|
+
var import_react5 = require("react");
|
|
26318
26840
|
var import_react_native4 = require("react-native");
|
|
26319
26841
|
var import_core6 = require("@papyrus-sdk/core");
|
|
26320
26842
|
var import_engine_native2 = require("@papyrus-sdk/engine-native");
|
|
@@ -26335,7 +26857,7 @@ var resolvePageTapChromeVisibility = ({
|
|
|
26335
26857
|
};
|
|
26336
26858
|
|
|
26337
26859
|
// components/DedicatedAndroidPdfViewer.tsx
|
|
26338
|
-
var
|
|
26860
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
26339
26861
|
var TEXT_MARKUP_TOOLS2 = /* @__PURE__ */ new Set(["highlight", "underline", "squiggly", "strikeout"]);
|
|
26340
26862
|
var MOBILE_CHROME_HIDE_DELTA = 28;
|
|
26341
26863
|
var MOBILE_CHROME_SHOW_DELTA = 22;
|
|
@@ -26364,7 +26886,7 @@ function DedicatedAndroidPdfViewer({
|
|
|
26364
26886
|
const searchResults = (0, import_core6.useViewerStore)((state) => state.searchResults);
|
|
26365
26887
|
const annotationNavigationRequest = (0, import_core6.useViewerStore)((state) => state.annotationNavigationRequest);
|
|
26366
26888
|
const annotations = (0, import_core6.useViewerStore)((state) => state.annotations);
|
|
26367
|
-
const [pendingNotes, setPendingNotes] = (0,
|
|
26889
|
+
const [pendingNotes, setPendingNotes] = (0, import_react5.useState)([]);
|
|
26368
26890
|
const handleAnnotationTap = (id) => {
|
|
26369
26891
|
const nearby = getNearbyPdfNotes(annotations, id);
|
|
26370
26892
|
if (nearby.length < 2) {
|
|
@@ -26392,30 +26914,30 @@ function DedicatedAndroidPdfViewer({
|
|
|
26392
26914
|
maxWidth: resolvedMaxPageWidth,
|
|
26393
26915
|
alignSelf: "center"
|
|
26394
26916
|
} : 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,
|
|
26917
|
+
const [selection, setSelection] = (0, import_react5.useState)(null);
|
|
26918
|
+
const selectionRef = (0, import_react5.useRef)(null);
|
|
26919
|
+
const lastVisiblePagesKeyRef = (0, import_react5.useRef)("");
|
|
26920
|
+
const lastScrollOffsetYRef = (0, import_react5.useRef)(0);
|
|
26921
|
+
const scrollDownAccumRef = (0, import_react5.useRef)(0);
|
|
26922
|
+
const scrollUpAccumRef = (0, import_react5.useRef)(0);
|
|
26923
|
+
const pendingChromeShowTimeoutRef = (0, import_react5.useRef)(null);
|
|
26924
|
+
const chromeVisibleRef = (0, import_react5.useRef)(true);
|
|
26925
|
+
const lastZoomChangedAtRef = (0, import_react5.useRef)(null);
|
|
26926
|
+
(0, import_react5.useEffect)(() => {
|
|
26405
26927
|
chromeVisibleRef.current = mobileChromeVisible;
|
|
26406
26928
|
}, [mobileChromeVisible]);
|
|
26407
|
-
const clearPendingChromeShow = (0,
|
|
26929
|
+
const clearPendingChromeShow = (0, import_react5.useCallback)(() => {
|
|
26408
26930
|
if (pendingChromeShowTimeoutRef.current) {
|
|
26409
26931
|
clearTimeout(pendingChromeShowTimeoutRef.current);
|
|
26410
26932
|
pendingChromeShowTimeoutRef.current = null;
|
|
26411
26933
|
}
|
|
26412
26934
|
}, []);
|
|
26413
|
-
const setMobileChromeVisible = (0,
|
|
26935
|
+
const setMobileChromeVisible = (0, import_react5.useCallback)((visible, reason) => {
|
|
26414
26936
|
if (chromeVisibleRef.current === visible) return;
|
|
26415
26937
|
chromeVisibleRef.current = visible;
|
|
26416
26938
|
setDocumentState({ mobileChromeVisible: visible });
|
|
26417
26939
|
}, [setDocumentState]);
|
|
26418
|
-
const trackMobileChromeByOffset = (0,
|
|
26940
|
+
const trackMobileChromeByOffset = (0, import_react5.useCallback)((offsetY, reasonPrefix) => {
|
|
26419
26941
|
const safeOffset = Math.max(0, offsetY);
|
|
26420
26942
|
const delta = safeOffset - lastScrollOffsetYRef.current;
|
|
26421
26943
|
lastScrollOffsetYRef.current = safeOffset;
|
|
@@ -26451,12 +26973,12 @@ function DedicatedAndroidPdfViewer({
|
|
|
26451
26973
|
}
|
|
26452
26974
|
}
|
|
26453
26975
|
}, [clearPendingChromeShow, setMobileChromeVisible]);
|
|
26454
|
-
(0,
|
|
26976
|
+
(0, import_react5.useEffect)(() => {
|
|
26455
26977
|
return () => {
|
|
26456
26978
|
clearPendingChromeShow();
|
|
26457
26979
|
};
|
|
26458
26980
|
}, [clearPendingChromeShow]);
|
|
26459
|
-
const applySelection = (0,
|
|
26981
|
+
const applySelection = (0, import_react5.useCallback)((type) => {
|
|
26460
26982
|
const sel = selectionRef.current;
|
|
26461
26983
|
if (!sel || !sel.rects || sel.rects.length === 0) return;
|
|
26462
26984
|
const bounds = sel.rects.reduce((acc, r) => ({
|
|
@@ -26478,12 +27000,12 @@ function DedicatedAndroidPdfViewer({
|
|
|
26478
27000
|
setSelection(null);
|
|
26479
27001
|
selectionRef.current = null;
|
|
26480
27002
|
}, [addAnnotation, beginAnnotationDraft, annotationColor, documentId]);
|
|
26481
|
-
return /* @__PURE__ */ (0,
|
|
26482
|
-
/* @__PURE__ */ (0,
|
|
27003
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react_native4.View, { style: styles4.container, children: [
|
|
27004
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(PdfNoteChooser, { notes: pendingNotes, title: t.annotationNote, cancel: t.cancel, onClose: () => setPendingNotes([]), onSelect: (id) => {
|
|
26483
27005
|
setPendingNotes([]);
|
|
26484
27006
|
setSelectedAnnotation(id);
|
|
26485
27007
|
} }),
|
|
26486
|
-
/* @__PURE__ */ (0,
|
|
27008
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
26487
27009
|
import_engine_native2.PapyrusPdfDocumentView,
|
|
26488
27010
|
{
|
|
26489
27011
|
style: [styles4.viewer, cappedViewerStyle],
|
|
@@ -26597,7 +27119,7 @@ var styles4 = import_react_native4.StyleSheet.create({
|
|
|
26597
27119
|
});
|
|
26598
27120
|
|
|
26599
27121
|
// components/DedicatedIosPdfViewer.tsx
|
|
26600
|
-
var
|
|
27122
|
+
var import_react6 = require("react");
|
|
26601
27123
|
var import_react_native5 = require("react-native");
|
|
26602
27124
|
var import_core7 = require("@papyrus-sdk/core");
|
|
26603
27125
|
var import_engine_native3 = require("@papyrus-sdk/engine-native");
|
|
@@ -26694,7 +27216,7 @@ var resolveNativePdfVisiblePages = (pages) => (pages ?? []).flatMap((page) => {
|
|
|
26694
27216
|
});
|
|
26695
27217
|
|
|
26696
27218
|
// components/DedicatedIosPdfViewer.tsx
|
|
26697
|
-
var
|
|
27219
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
26698
27220
|
var MOBILE_CHROME_HIDE_DELTA2 = 28;
|
|
26699
27221
|
var MOBILE_CHROME_SHOW_DELTA2 = 22;
|
|
26700
27222
|
var MOBILE_CHROME_SHOW_DELAY_MS2 = 180;
|
|
@@ -26726,7 +27248,7 @@ function DedicatedIosPdfViewer({
|
|
|
26726
27248
|
const inkStrokeWidth = (0, import_core7.useViewerStore)((state) => state.inkStrokeWidth);
|
|
26727
27249
|
const annotationNavigationRequest = (0, import_core7.useViewerStore)((state) => state.annotationNavigationRequest);
|
|
26728
27250
|
const annotations = (0, import_core7.useViewerStore)((state) => state.annotations);
|
|
26729
|
-
const [pendingNotes, setPendingNotes] = (0,
|
|
27251
|
+
const [pendingNotes, setPendingNotes] = (0, import_react6.useState)([]);
|
|
26730
27252
|
const handleAnnotationTap = (id) => {
|
|
26731
27253
|
const nearby = getNearbyPdfNotes(annotations, id);
|
|
26732
27254
|
if (nearby.length < 2) {
|
|
@@ -26762,16 +27284,16 @@ function DedicatedIosPdfViewer({
|
|
|
26762
27284
|
supportsNativeEditMenu
|
|
26763
27285
|
);
|
|
26764
27286
|
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,
|
|
27287
|
+
const chromeVisibleRef = (0, import_react6.useRef)(mobileChromeVisible);
|
|
27288
|
+
const lastScrollOffsetYRef = (0, import_react6.useRef)(0);
|
|
27289
|
+
const scrollDownAccumRef = (0, import_react6.useRef)(0);
|
|
27290
|
+
const scrollUpAccumRef = (0, import_react6.useRef)(0);
|
|
27291
|
+
const pendingChromeShowTimeoutRef = (0, import_react6.useRef)(null);
|
|
27292
|
+
const lastZoomChangedAtRef = (0, import_react6.useRef)(null);
|
|
27293
|
+
const lastVisiblePagesKeyRef = (0, import_react6.useRef)("");
|
|
27294
|
+
const [selection, setSelection] = (0, import_react6.useState)(null);
|
|
27295
|
+
const selectionRef = (0, import_react6.useRef)(null);
|
|
27296
|
+
(0, import_react6.useEffect)(() => {
|
|
26775
27297
|
const pickerActive = supportsNativeEditMenu && activeTool === "ink";
|
|
26776
27298
|
setDocumentState({ nativeInkToolPickerActive: pickerActive });
|
|
26777
27299
|
return () => {
|
|
@@ -26780,15 +27302,15 @@ function DedicatedIosPdfViewer({
|
|
|
26780
27302
|
}
|
|
26781
27303
|
};
|
|
26782
27304
|
}, [activeTool, setDocumentState]);
|
|
26783
|
-
(0,
|
|
27305
|
+
(0, import_react6.useEffect)(() => {
|
|
26784
27306
|
chromeVisibleRef.current = mobileChromeVisible;
|
|
26785
27307
|
}, [mobileChromeVisible]);
|
|
26786
|
-
const clearPendingChromeShow = (0,
|
|
27308
|
+
const clearPendingChromeShow = (0, import_react6.useCallback)(() => {
|
|
26787
27309
|
if (!pendingChromeShowTimeoutRef.current) return;
|
|
26788
27310
|
clearTimeout(pendingChromeShowTimeoutRef.current);
|
|
26789
27311
|
pendingChromeShowTimeoutRef.current = null;
|
|
26790
27312
|
}, []);
|
|
26791
|
-
const setMobileChromeVisible = (0,
|
|
27313
|
+
const setMobileChromeVisible = (0, import_react6.useCallback)(
|
|
26792
27314
|
(visible) => {
|
|
26793
27315
|
if (chromeVisibleRef.current === visible) return;
|
|
26794
27316
|
chromeVisibleRef.current = visible;
|
|
@@ -26796,14 +27318,14 @@ function DedicatedIosPdfViewer({
|
|
|
26796
27318
|
},
|
|
26797
27319
|
[setDocumentState]
|
|
26798
27320
|
);
|
|
26799
|
-
const updateSelection = (0,
|
|
27321
|
+
const updateSelection = (0, import_react6.useCallback)(
|
|
26800
27322
|
(nextSelection) => {
|
|
26801
27323
|
selectionRef.current = nextSelection;
|
|
26802
27324
|
setSelection(nextSelection);
|
|
26803
27325
|
},
|
|
26804
27326
|
[]
|
|
26805
27327
|
);
|
|
26806
|
-
const handleTextSelectionChange = (0,
|
|
27328
|
+
const handleTextSelectionChange = (0, import_react6.useCallback)(
|
|
26807
27329
|
(event) => {
|
|
26808
27330
|
const nextSelection = resolveNativePdfTextSelection(event.nativeEvent);
|
|
26809
27331
|
updateSelection(nextSelection);
|
|
@@ -26816,7 +27338,7 @@ function DedicatedIosPdfViewer({
|
|
|
26816
27338
|
},
|
|
26817
27339
|
[onTextSelected, setSelectedAnnotation, updateSelection]
|
|
26818
27340
|
);
|
|
26819
|
-
const defineSelection = (0,
|
|
27341
|
+
const defineSelection = (0, import_react6.useCallback)(() => {
|
|
26820
27342
|
const currentSelection = selectionRef.current;
|
|
26821
27343
|
if (!currentSelection) return;
|
|
26822
27344
|
onDefineSelection?.({
|
|
@@ -26825,7 +27347,7 @@ function DedicatedIosPdfViewer({
|
|
|
26825
27347
|
});
|
|
26826
27348
|
updateSelection(null);
|
|
26827
27349
|
}, [onDefineSelection, updateSelection]);
|
|
26828
|
-
const handleNativeDefineSelection = (0,
|
|
27350
|
+
const handleNativeDefineSelection = (0, import_react6.useCallback)(
|
|
26829
27351
|
(event) => {
|
|
26830
27352
|
const text = event.nativeEvent?.text;
|
|
26831
27353
|
const pageIndex = event.nativeEvent?.pageIndex;
|
|
@@ -26837,7 +27359,7 @@ function DedicatedIosPdfViewer({
|
|
|
26837
27359
|
},
|
|
26838
27360
|
[onDefineSelection, updateSelection]
|
|
26839
27361
|
);
|
|
26840
|
-
const handleInkToolPickerVisibilityChange = (0,
|
|
27362
|
+
const handleInkToolPickerVisibilityChange = (0, import_react6.useCallback)(
|
|
26841
27363
|
(event) => {
|
|
26842
27364
|
handleNativeInkPickerVisibility(
|
|
26843
27365
|
event.nativeEvent?.visible === true,
|
|
@@ -26846,7 +27368,7 @@ function DedicatedIosPdfViewer({
|
|
|
26846
27368
|
},
|
|
26847
27369
|
[]
|
|
26848
27370
|
);
|
|
26849
|
-
const trackMobileChromeByOffset = (0,
|
|
27371
|
+
const trackMobileChromeByOffset = (0, import_react6.useCallback)(
|
|
26850
27372
|
(offsetY) => {
|
|
26851
27373
|
if (pageCount <= 0) return;
|
|
26852
27374
|
const safeOffset = Math.max(0, offsetY);
|
|
@@ -26882,11 +27404,11 @@ function DedicatedIosPdfViewer({
|
|
|
26882
27404
|
},
|
|
26883
27405
|
[clearPendingChromeShow, pageCount, setMobileChromeVisible]
|
|
26884
27406
|
);
|
|
26885
|
-
(0,
|
|
27407
|
+
(0, import_react6.useEffect)(
|
|
26886
27408
|
() => () => clearPendingChromeShow(),
|
|
26887
27409
|
[clearPendingChromeShow]
|
|
26888
27410
|
);
|
|
26889
|
-
const handleVisiblePagesChange = (0,
|
|
27411
|
+
const handleVisiblePagesChange = (0, import_react6.useCallback)(
|
|
26890
27412
|
(event) => {
|
|
26891
27413
|
const pages = resolveNativePdfVisiblePages(
|
|
26892
27414
|
event.nativeEvent?.pages
|
|
@@ -26901,13 +27423,13 @@ function DedicatedIosPdfViewer({
|
|
|
26901
27423
|
},
|
|
26902
27424
|
[setDocumentState]
|
|
26903
27425
|
);
|
|
26904
|
-
const handleScroll = (0,
|
|
27426
|
+
const handleScroll = (0, import_react6.useCallback)(
|
|
26905
27427
|
(event) => {
|
|
26906
27428
|
trackMobileChromeByOffset(event.nativeEvent?.offsetY ?? 0);
|
|
26907
27429
|
},
|
|
26908
27430
|
[trackMobileChromeByOffset]
|
|
26909
27431
|
);
|
|
26910
|
-
const handleTap = (0,
|
|
27432
|
+
const handleTap = (0, import_react6.useCallback)(() => {
|
|
26911
27433
|
setSelectedAnnotation(null);
|
|
26912
27434
|
const nextVisible = resolvePageTapChromeVisibility({
|
|
26913
27435
|
chromeVisible: chromeVisibleRef.current,
|
|
@@ -26917,7 +27439,7 @@ function DedicatedIosPdfViewer({
|
|
|
26917
27439
|
});
|
|
26918
27440
|
if (nextVisible !== null) setMobileChromeVisible(nextVisible);
|
|
26919
27441
|
}, [activeTool, selectionActive, setMobileChromeVisible, setSelectedAnnotation]);
|
|
26920
|
-
const handleDeleteAnnotation = (0,
|
|
27442
|
+
const handleDeleteAnnotation = (0, import_react6.useCallback)(
|
|
26921
27443
|
(annotationId) => {
|
|
26922
27444
|
deleteAnnotationAndClearSelection(
|
|
26923
27445
|
annotationId,
|
|
@@ -26932,12 +27454,12 @@ function DedicatedIosPdfViewer({
|
|
|
26932
27454
|
maxWidth: resolvedMaxPageWidth,
|
|
26933
27455
|
alignSelf: "center"
|
|
26934
27456
|
} : void 0;
|
|
26935
|
-
return /* @__PURE__ */ (0,
|
|
26936
|
-
/* @__PURE__ */ (0,
|
|
27457
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_react_native5.View, { style: styles5.container, children: [
|
|
27458
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(PdfNoteChooser, { notes: pendingNotes, title: t.annotationNote, cancel: t.cancel, onClose: () => setPendingNotes([]), onSelect: (id) => {
|
|
26937
27459
|
setPendingNotes([]);
|
|
26938
27460
|
setSelectedAnnotation(id);
|
|
26939
27461
|
} }),
|
|
26940
|
-
/* @__PURE__ */ (0,
|
|
27462
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
26941
27463
|
import_engine_native3.PapyrusPdfDocumentView,
|
|
26942
27464
|
{
|
|
26943
27465
|
style: [styles5.viewer, cappedViewerStyle],
|
|
@@ -27006,22 +27528,22 @@ function DedicatedIosPdfViewer({
|
|
|
27006
27528
|
onInkToolPickerVisibilityChange: handleInkToolPickerVisibilityChange
|
|
27007
27529
|
}
|
|
27008
27530
|
),
|
|
27009
|
-
selection && !supportsNativeEditMenu && onDefineSelection && shouldShowDefineSelection(selection.text, defineSelectionMode) && /* @__PURE__ */ (0,
|
|
27531
|
+
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
27532
|
import_react_native5.Pressable,
|
|
27011
27533
|
{
|
|
27012
27534
|
onPress: defineSelection,
|
|
27013
27535
|
style: styles5.fallbackButton,
|
|
27014
27536
|
accessibilityRole: "button",
|
|
27015
27537
|
accessibilityLabel: t.define,
|
|
27016
|
-
children: /* @__PURE__ */ (0,
|
|
27538
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native5.Text, { style: styles5.fallbackButtonText, children: t.define })
|
|
27017
27539
|
}
|
|
27018
27540
|
) }),
|
|
27019
|
-
fallbackDeleteAnnotation && /* @__PURE__ */ (0,
|
|
27541
|
+
fallbackDeleteAnnotation && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
27020
27542
|
import_react_native5.View,
|
|
27021
27543
|
{
|
|
27022
27544
|
style: styles5.annotationDeleteFallback,
|
|
27023
27545
|
pointerEvents: "box-none",
|
|
27024
|
-
children: /* @__PURE__ */ (0,
|
|
27546
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
27025
27547
|
import_react_native5.Pressable,
|
|
27026
27548
|
{
|
|
27027
27549
|
onPress: () => handleDeleteAnnotation(fallbackDeleteAnnotation.id),
|
|
@@ -27029,7 +27551,7 @@ function DedicatedIosPdfViewer({
|
|
|
27029
27551
|
accessibilityRole: "button",
|
|
27030
27552
|
accessibilityLabel: t.deleteAnnotation,
|
|
27031
27553
|
hitSlop: 8,
|
|
27032
|
-
children: /* @__PURE__ */ (0,
|
|
27554
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native5.Text, { style: styles5.annotationDeleteButtonText, children: t.deleteAnnotation })
|
|
27033
27555
|
}
|
|
27034
27556
|
)
|
|
27035
27557
|
}
|
|
@@ -27092,7 +27614,7 @@ var styles5 = import_react_native5.StyleSheet.create({
|
|
|
27092
27614
|
});
|
|
27093
27615
|
|
|
27094
27616
|
// components/NativePdfDocumentViewer.tsx
|
|
27095
|
-
var
|
|
27617
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
27096
27618
|
function NativePdfDocumentViewer({
|
|
27097
27619
|
engine,
|
|
27098
27620
|
documentId,
|
|
@@ -27105,7 +27627,7 @@ function NativePdfDocumentViewer({
|
|
|
27105
27627
|
import_react_native6.Platform.OS
|
|
27106
27628
|
);
|
|
27107
27629
|
if (implementation === "android") {
|
|
27108
|
-
return /* @__PURE__ */ (0,
|
|
27630
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
27109
27631
|
DedicatedAndroidPdfViewer,
|
|
27110
27632
|
{
|
|
27111
27633
|
engine,
|
|
@@ -27118,7 +27640,7 @@ function NativePdfDocumentViewer({
|
|
|
27118
27640
|
);
|
|
27119
27641
|
}
|
|
27120
27642
|
if (implementation === "ios") {
|
|
27121
|
-
return /* @__PURE__ */ (0,
|
|
27643
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
27122
27644
|
DedicatedIosPdfViewer,
|
|
27123
27645
|
{
|
|
27124
27646
|
engine,
|
|
@@ -27172,26 +27694,6 @@ var resolveMobileChromeOffsets = (insets) => ({
|
|
|
27172
27694
|
right: MOBILE_CHROME_METRICS.screenPadding + Math.max(0, insets.right)
|
|
27173
27695
|
});
|
|
27174
27696
|
|
|
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
27697
|
// components/NativeTextDocumentViewer.tsx
|
|
27196
27698
|
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
27197
27699
|
function NativeTextDocumentViewer({
|
|
@@ -27740,6 +28242,7 @@ var scrollViewerListToOffset = (list, offset, animated) => {
|
|
|
27740
28242
|
list.scrollToOffset?.({ offset, animated });
|
|
27741
28243
|
};
|
|
27742
28244
|
var Viewer = ({
|
|
28245
|
+
documentType,
|
|
27743
28246
|
documentId,
|
|
27744
28247
|
engine,
|
|
27745
28248
|
maxPageWidth,
|
|
@@ -29267,14 +29770,8 @@ var Viewer = ({
|
|
|
29267
29770
|
},
|
|
29268
29771
|
[mobilePerf, perfEnabled, scrollPerfSession]
|
|
29269
29772
|
);
|
|
29270
|
-
const handleWebViewScroll = (0, import_react9.useCallback)(
|
|
29271
|
-
|
|
29272
|
-
if (!chromeVisibleRef.current) {
|
|
29273
|
-
setMobileChromeVisible(true, "scroll.webview.recover");
|
|
29274
|
-
}
|
|
29275
|
-
},
|
|
29276
|
-
[setMobileChromeVisible]
|
|
29277
|
-
);
|
|
29773
|
+
const handleWebViewScroll = (0, import_react9.useCallback)((_offsetY) => {
|
|
29774
|
+
}, []);
|
|
29278
29775
|
const handlePageTap = (0, import_react9.useCallback)(() => {
|
|
29279
29776
|
const nextVisible = resolvePageTapChromeVisibility({
|
|
29280
29777
|
chromeVisible: chromeVisibleRef.current,
|
|
@@ -29496,6 +29993,7 @@ var Viewer = ({
|
|
|
29496
29993
|
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
29994
|
WebViewViewer_default,
|
|
29498
29995
|
{
|
|
29996
|
+
documentType,
|
|
29499
29997
|
engine,
|
|
29500
29998
|
documentId,
|
|
29501
29999
|
onDefineSelection,
|
|
@@ -30042,6 +30540,7 @@ var styles9 = import_react_native11.StyleSheet.create({
|
|
|
30042
30540
|
// components/PageJumpModal.tsx
|
|
30043
30541
|
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
30044
30542
|
function PageJumpModal({
|
|
30543
|
+
documentType,
|
|
30045
30544
|
visible,
|
|
30046
30545
|
currentPage,
|
|
30047
30546
|
pageCount,
|
|
@@ -30068,8 +30567,8 @@ function PageJumpModal({
|
|
|
30068
30567
|
isDark,
|
|
30069
30568
|
maxHeight: 300,
|
|
30070
30569
|
showHeader: true,
|
|
30071
|
-
title: "Ir para p\xE1gina",
|
|
30072
|
-
closeAccessibilityLabel: "
|
|
30570
|
+
title: documentType === "epub" ? "Ir para cap\xEDtulo" : "Ir para p\xE1gina",
|
|
30571
|
+
closeAccessibilityLabel: "Fechar navega\xE7\xE3o",
|
|
30073
30572
|
sheetStyle: {
|
|
30074
30573
|
paddingHorizontal: 18,
|
|
30075
30574
|
paddingBottom: 18,
|
|
@@ -30097,7 +30596,7 @@ function PageJumpModal({
|
|
|
30097
30596
|
}
|
|
30098
30597
|
],
|
|
30099
30598
|
onSubmitEditing: confirmJump,
|
|
30100
|
-
accessibilityLabel: "
|
|
30599
|
+
accessibilityLabel: documentType === "epub" ? "N\xFAmero do cap\xEDtulo" : "N\xFAmero da p\xE1gina",
|
|
30101
30600
|
testID: "papyrus-page-jump-input"
|
|
30102
30601
|
}
|
|
30103
30602
|
),
|
|
@@ -30152,6 +30651,7 @@ var styles10 = import_react_native12.StyleSheet.create({
|
|
|
30152
30651
|
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
30153
30652
|
var Topbar = ({
|
|
30154
30653
|
engine,
|
|
30654
|
+
documentType,
|
|
30155
30655
|
onOpenSettings,
|
|
30156
30656
|
onOpenOverflow,
|
|
30157
30657
|
title,
|
|
@@ -30172,6 +30672,12 @@ var Topbar = ({
|
|
|
30172
30672
|
locale
|
|
30173
30673
|
} = (0, import_core12.useViewerStore)();
|
|
30174
30674
|
const inkSession = useNativeInkSession();
|
|
30675
|
+
const chromeVisible = mobileChromeVisible || inkSession.active;
|
|
30676
|
+
const chromeProgress = useNativeInkMotion(chromeVisible, documentType === "epub");
|
|
30677
|
+
const chromeMotion = (0, import_react_native_reanimated2.useAnimatedStyle)(() => {
|
|
30678
|
+
"worklet";
|
|
30679
|
+
return { opacity: chromeProgress.value };
|
|
30680
|
+
});
|
|
30175
30681
|
const t = getStrings(locale);
|
|
30176
30682
|
const progress = useNativeInkMotion(inkSession.active, inkSession.supported);
|
|
30177
30683
|
const settingsMotion = (0, import_react_native_reanimated2.useAnimatedStyle)(() => {
|
|
@@ -30227,26 +30733,30 @@ var Topbar = ({
|
|
|
30227
30733
|
children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(IconSettings, { size: MOBILE_CHROME_METRICS.iconSize, color: isDark ? "#e5e7eb" : "#111827" })
|
|
30228
30734
|
}
|
|
30229
30735
|
);
|
|
30230
|
-
if (!
|
|
30736
|
+
if (!chromeVisible && documentType !== "epub") return null;
|
|
30231
30737
|
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
|
|
30232
30738
|
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
30233
|
-
|
|
30739
|
+
import_react_native_reanimated2.default.View,
|
|
30234
30740
|
{
|
|
30235
30741
|
style: [
|
|
30236
30742
|
styles11.chromeFrame,
|
|
30743
|
+
chromeMotion,
|
|
30237
30744
|
{
|
|
30238
30745
|
paddingTop: insets.top,
|
|
30239
30746
|
paddingLeft: MOBILE_CHROME_METRICS.screenPadding + insets.left,
|
|
30240
30747
|
paddingRight: MOBILE_CHROME_METRICS.screenPadding + insets.right
|
|
30241
30748
|
}
|
|
30242
30749
|
],
|
|
30243
|
-
pointerEvents: "box-none",
|
|
30750
|
+
pointerEvents: chromeVisible ? "box-none" : "none",
|
|
30751
|
+
accessibilityElementsHidden: !chromeVisible,
|
|
30752
|
+
importantForAccessibility: chromeVisible ? "auto" : "no-hide-descendants",
|
|
30244
30753
|
testID: "papyrus-floating-top-controls",
|
|
30245
30754
|
children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
30246
30755
|
import_react_native13.View,
|
|
30247
30756
|
{
|
|
30248
30757
|
style: [
|
|
30249
30758
|
styles11.container,
|
|
30759
|
+
import_react_native13.Platform.OS === "ios" && styles11.containerIos,
|
|
30250
30760
|
isDark && styles11.containerDark,
|
|
30251
30761
|
isLandscape && styles11.containerLandscape
|
|
30252
30762
|
],
|
|
@@ -30386,6 +30896,7 @@ var Topbar = ({
|
|
|
30386
30896
|
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
30387
30897
|
PageJumpModal,
|
|
30388
30898
|
{
|
|
30899
|
+
documentType,
|
|
30389
30900
|
visible: jumpModalOpen,
|
|
30390
30901
|
currentPage,
|
|
30391
30902
|
pageCount,
|
|
@@ -30403,7 +30914,8 @@ var styles11 = import_react_native13.StyleSheet.create({
|
|
|
30403
30914
|
maxWidth: MOBILE_CHROME_METRICS.maxFloatingWidth,
|
|
30404
30915
|
marginTop: 10,
|
|
30405
30916
|
paddingHorizontal: 14,
|
|
30406
|
-
|
|
30917
|
+
height: MOBILE_CHROME_METRICS.topbarHeight,
|
|
30918
|
+
paddingVertical: 0,
|
|
30407
30919
|
backgroundColor: "rgba(255,255,255,0.88)",
|
|
30408
30920
|
borderWidth: 1,
|
|
30409
30921
|
borderColor: "rgba(255,255,255,0.72)",
|
|
@@ -30420,6 +30932,10 @@ var styles11 = import_react_native13.StyleSheet.create({
|
|
|
30420
30932
|
backgroundColor: "rgba(15,17,21,0.88)",
|
|
30421
30933
|
borderColor: "rgba(71,85,105,0.48)"
|
|
30422
30934
|
},
|
|
30935
|
+
containerIos: {
|
|
30936
|
+
height: MOBILE_CHROME_METRICS.topbarHeight,
|
|
30937
|
+
paddingVertical: 0
|
|
30938
|
+
},
|
|
30423
30939
|
containerLandscape: {
|
|
30424
30940
|
maxWidth: void 0,
|
|
30425
30941
|
marginTop: 0
|
|
@@ -32556,10 +33072,10 @@ var import_react_native16 = require("react-native");
|
|
|
32556
33072
|
var import_core15 = require("@papyrus-sdk/core");
|
|
32557
33073
|
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
32558
33074
|
var COLORS = ["#fbbf24", "#fb7185", "#60a5fa", "#34d399", "#c084fc"];
|
|
32559
|
-
var AnnotationEditor = () => {
|
|
33075
|
+
var AnnotationEditor = ({ documentId }) => {
|
|
32560
33076
|
const { annotations, annotationDraft, clearAnnotationDraft, addAnnotation, selectedAnnotationId, updateAnnotation, removeAnnotation, setSelectedAnnotation, uiTheme, locale, accentColor } = (0, import_core15.useViewerStore)();
|
|
32561
33077
|
const annotation = annotationDraft?.id === selectedAnnotationId ? annotationDraft : annotations.find((a) => a.id === selectedAnnotationId);
|
|
32562
|
-
const supported = annotation && annotation.type !== "ink";
|
|
33078
|
+
const supported = annotation && annotation.type !== "ink" && (!documentId || !annotation.anchor?.documentId || annotation.anchor.documentId === documentId);
|
|
32563
33079
|
const [editing, setEditing] = (0, import_react16.useState)(false);
|
|
32564
33080
|
const [draft, setDraft] = (0, import_react16.useState)("");
|
|
32565
33081
|
const [color, setColor] = (0, import_react16.useState)(COLORS[0]);
|
|
@@ -32624,14 +33140,34 @@ var AnnotationEditor = () => {
|
|
|
32624
33140
|
/* @__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
33141
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_native16.View, { style: styles14.header, children: [
|
|
32626
33142
|
/* @__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)(
|
|
33143
|
+
/* @__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
33144
|
] }),
|
|
32629
33145
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_native16.ScrollView, { style: styles14.content, keyboardShouldPersistTaps: "handled", children: [
|
|
32630
33146
|
quote ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native16.Text, { style: [styles14.quote, textStyle], selectable: true, children: quote }) : null,
|
|
32631
33147
|
editing ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
|
|
32632
33148
|
/* @__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
33149
|
/* @__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.
|
|
33150
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native16.View, { style: styles14.markupOptions, children: [
|
|
33151
|
+
["highlight", t.annotationHighlight, IconHighlight],
|
|
33152
|
+
["underline", t.annotationUnderline, IconUnderline],
|
|
33153
|
+
["strikeout", t.annotationStrikeout, IconStrikeout],
|
|
33154
|
+
["none", t.annotationIndicatorOnly, IconComment]
|
|
33155
|
+
].map(([style, label, Icon]) => /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
33156
|
+
import_react_native16.Pressable,
|
|
33157
|
+
{
|
|
33158
|
+
onPress: () => setMarkup(style),
|
|
33159
|
+
accessibilityRole: "button",
|
|
33160
|
+
accessibilityLabel: label,
|
|
33161
|
+
accessibilityState: { selected: markup === style },
|
|
33162
|
+
testID: `annotation-style-${style}`,
|
|
33163
|
+
style: [styles14.markupButton, { backgroundColor: dark ? "#242936" : "#f1f5f9", borderColor: markup === style ? accentColor : "transparent" }],
|
|
33164
|
+
children: [
|
|
33165
|
+
/* @__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 }) }),
|
|
33166
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native16.Text, { style: [styles14.markupLabel, textStyle], children: style === "none" ? locale === "pt-BR" ? "Indicador" : "Indicator" : label })
|
|
33167
|
+
]
|
|
33168
|
+
},
|
|
33169
|
+
style
|
|
33170
|
+
)) })
|
|
32635
33171
|
] }) : /* @__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
33172
|
] }),
|
|
32637
33173
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_native16.View, { style: styles14.actions, children: [
|
|
@@ -32654,7 +33190,7 @@ var AnnotationEditor = () => {
|
|
|
32654
33190
|
] })
|
|
32655
33191
|
] }) });
|
|
32656
33192
|
};
|
|
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 } });
|
|
33193
|
+
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
33194
|
var AnnotationEditor_default = AnnotationEditor;
|
|
32659
33195
|
|
|
32660
33196
|
// components/BottomBar.tsx
|
|
@@ -32669,7 +33205,7 @@ function buildBottomBarLayout({
|
|
|
32669
33205
|
toolDockOpen
|
|
32670
33206
|
}) {
|
|
32671
33207
|
const leftSlots = [];
|
|
32672
|
-
if (documentType === "pdf") {
|
|
33208
|
+
if (documentType === "pdf" || documentType === "epub") {
|
|
32673
33209
|
leftSlots.push({
|
|
32674
33210
|
key: "annotate",
|
|
32675
33211
|
active: toolDockOpen || activeMobileDestination === "annotate"
|
|
@@ -32717,10 +33253,19 @@ var BottomBar = ({
|
|
|
32717
33253
|
documentType,
|
|
32718
33254
|
onOpenInfo,
|
|
32719
33255
|
onOpenSettings,
|
|
32720
|
-
onOpenDestination
|
|
33256
|
+
onOpenDestination,
|
|
33257
|
+
onTurnPage,
|
|
33258
|
+
onNavigateToPage,
|
|
33259
|
+
onOpenPages
|
|
32721
33260
|
}) => {
|
|
32722
33261
|
const {
|
|
32723
33262
|
activeMobileDestination,
|
|
33263
|
+
viewMode,
|
|
33264
|
+
epubReadingMode,
|
|
33265
|
+
epubLocation,
|
|
33266
|
+
comicLayoutMode,
|
|
33267
|
+
currentPage,
|
|
33268
|
+
pageCount,
|
|
32724
33269
|
mobileDockVisible,
|
|
32725
33270
|
setDocumentState,
|
|
32726
33271
|
uiTheme,
|
|
@@ -32735,7 +33280,7 @@ var BottomBar = ({
|
|
|
32735
33280
|
const supportsInkChrome = documentType === "pdf" && inkSession.supported;
|
|
32736
33281
|
const drawing = supportsInkChrome && inkSession.active;
|
|
32737
33282
|
const dockVisible = mobileChromeVisible && mobileDockVisible && !drawing;
|
|
32738
|
-
const dockProgress = useNativeInkMotion(dockVisible, supportsInkChrome);
|
|
33283
|
+
const dockProgress = useNativeInkMotion(dockVisible, supportsInkChrome || documentType === "epub");
|
|
32739
33284
|
const dockMotion = (0, import_react_native_reanimated3.useAnimatedStyle)(() => {
|
|
32740
33285
|
"worklet";
|
|
32741
33286
|
return {
|
|
@@ -32757,6 +33302,15 @@ var BottomBar = ({
|
|
|
32757
33302
|
activeMobileDestination,
|
|
32758
33303
|
toolDockOpen
|
|
32759
33304
|
});
|
|
33305
|
+
const paginated = documentType !== "text" && (documentType === "comic" ? comicLayoutMode === "single" : documentType === "epub" ? epubReadingMode === "paged" : viewMode === "single");
|
|
33306
|
+
if (paginated) {
|
|
33307
|
+
layout.leftSlots.push(...layout.rightSlots.filter((slot) => slot.key === "search"));
|
|
33308
|
+
layout.rightSlots = [];
|
|
33309
|
+
}
|
|
33310
|
+
const turnPage = (direction) => {
|
|
33311
|
+
if (onTurnPage) onTurnPage(direction);
|
|
33312
|
+
else onNavigateToPage?.(currentPage + direction);
|
|
33313
|
+
};
|
|
32760
33314
|
const slotMeta = {
|
|
32761
33315
|
annotate: {
|
|
32762
33316
|
label: t.tools,
|
|
@@ -32817,7 +33371,7 @@ var BottomBar = ({
|
|
|
32817
33371
|
onPress: onOpenSettings
|
|
32818
33372
|
}
|
|
32819
33373
|
};
|
|
32820
|
-
if (!dockVisible && !supportsInkChrome) return null;
|
|
33374
|
+
if (!dockVisible && !supportsInkChrome && documentType !== "epub") return null;
|
|
32821
33375
|
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
32822
33376
|
import_react_native_reanimated3.default.View,
|
|
32823
33377
|
{
|
|
@@ -32882,7 +33436,11 @@ var BottomBar = ({
|
|
|
32882
33436
|
isDark && styles15.islandDark
|
|
32883
33437
|
],
|
|
32884
33438
|
testID: "papyrus-floating-bottom-dock",
|
|
32885
|
-
children:
|
|
33439
|
+
children: paginated ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
|
|
33440
|
+
/* @__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) }) }),
|
|
33441
|
+
/* @__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}` }) }),
|
|
33442
|
+
/* @__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) }) })
|
|
33443
|
+
] }) : layout.rightSlots.map((slot) => {
|
|
32886
33444
|
const meta = slotMeta[slot.key];
|
|
32887
33445
|
const Icon = meta.icon;
|
|
32888
33446
|
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
@@ -32945,8 +33503,9 @@ var styles15 = import_react_native17.StyleSheet.create({
|
|
|
32945
33503
|
island: {
|
|
32946
33504
|
flexDirection: "row",
|
|
32947
33505
|
alignItems: "center",
|
|
32948
|
-
|
|
32949
|
-
|
|
33506
|
+
height: MOBILE_CHROME_METRICS.bottomBarVisualHeight,
|
|
33507
|
+
paddingVertical: 0,
|
|
33508
|
+
paddingHorizontal: 6,
|
|
32950
33509
|
backgroundColor: "rgba(255,255,255,0.9)",
|
|
32951
33510
|
borderWidth: 1,
|
|
32952
33511
|
borderColor: "rgba(255,255,255,0.72)",
|
|
@@ -32972,6 +33531,8 @@ var styles15 = import_react_native17.StyleSheet.create({
|
|
|
32972
33531
|
borderColor: "rgba(71,85,105,0.48)"
|
|
32973
33532
|
},
|
|
32974
33533
|
iconOnlyItem: {
|
|
33534
|
+
minWidth: 44,
|
|
33535
|
+
height: 44,
|
|
32975
33536
|
alignItems: "center",
|
|
32976
33537
|
justifyContent: "center",
|
|
32977
33538
|
paddingHorizontal: MOBILE_CHROME_METRICS.bottomBarItemPaddingHorizontal,
|
|
@@ -33048,10 +33609,12 @@ var SettingsSheet = ({
|
|
|
33048
33609
|
engine,
|
|
33049
33610
|
visible,
|
|
33050
33611
|
onClose,
|
|
33051
|
-
documentType = "pdf"
|
|
33612
|
+
documentType = "pdf",
|
|
33613
|
+
onOpenInfo
|
|
33052
33614
|
}) => {
|
|
33053
33615
|
const {
|
|
33054
33616
|
viewMode,
|
|
33617
|
+
epubReadingMode,
|
|
33055
33618
|
uiTheme,
|
|
33056
33619
|
zoom,
|
|
33057
33620
|
setDocumentState,
|
|
@@ -33063,12 +33626,16 @@ var SettingsSheet = ({
|
|
|
33063
33626
|
comicReadingDirection
|
|
33064
33627
|
} = (0, import_core17.useViewerStore)();
|
|
33065
33628
|
const isDark = uiTheme === "dark";
|
|
33066
|
-
const isPaged = viewMode === "single";
|
|
33629
|
+
const isPaged = documentType === "epub" ? epubReadingMode === "paged" : viewMode === "single";
|
|
33067
33630
|
const isDouble = viewMode === "double";
|
|
33068
33631
|
const t = getStrings(locale);
|
|
33069
33632
|
const { height: windowHeight } = (0, import_react_native18.useWindowDimensions)();
|
|
33070
33633
|
const sheetMaxHeight = getSettingsSheetMaxHeight(windowHeight);
|
|
33071
33634
|
const handleTransition = (mode) => {
|
|
33635
|
+
if (documentType === "epub") {
|
|
33636
|
+
setDocumentState({ epubReadingMode: mode === "paged" ? "paged" : "chapter-scroll" });
|
|
33637
|
+
return;
|
|
33638
|
+
}
|
|
33072
33639
|
if (mode === "paged") {
|
|
33073
33640
|
setDocumentState({ viewMode: "single" });
|
|
33074
33641
|
return;
|
|
@@ -33113,6 +33680,7 @@ var SettingsSheet = ({
|
|
|
33113
33680
|
contentContainerStyle: styles16.sheetContent,
|
|
33114
33681
|
showsVerticalScrollIndicator: false,
|
|
33115
33682
|
children: [
|
|
33683
|
+
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
33684
|
(documentType === "text" || documentType === "epub") && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_react_native18.View, { style: styles16.section, children: [
|
|
33117
33685
|
/* @__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
33686
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_react_native18.View, { style: { flexDirection: "row", alignItems: "center", gap: 12 }, children: [
|
|
@@ -33291,7 +33859,7 @@ var SettingsSheet = ({
|
|
|
33291
33859
|
isDark && styles16.optionTextDark,
|
|
33292
33860
|
(!isPaged || isDouble) && styles16.optionTextActive
|
|
33293
33861
|
],
|
|
33294
|
-
children: t.continuous
|
|
33862
|
+
children: documentType === "epub" && locale === "pt-BR" ? "Rolagem por cap\xEDtulo" : t.continuous
|
|
33295
33863
|
}
|
|
33296
33864
|
)
|
|
33297
33865
|
}
|
|
@@ -33321,7 +33889,7 @@ var SettingsSheet = ({
|
|
|
33321
33889
|
)
|
|
33322
33890
|
] })
|
|
33323
33891
|
] }),
|
|
33324
|
-
documentType
|
|
33892
|
+
documentType === "pdf" && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_react_native18.View, { style: styles16.section, children: [
|
|
33325
33893
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
33326
33894
|
import_react_native18.Text,
|
|
33327
33895
|
{
|
|
@@ -34199,6 +34767,7 @@ var styles20 = import_react_native22.StyleSheet.create({
|
|
|
34199
34767
|
// components/ProgressPill.tsx
|
|
34200
34768
|
var import_react18 = require("react");
|
|
34201
34769
|
var import_react_native23 = require("react-native");
|
|
34770
|
+
var import_react_native_reanimated4 = __toESM(require("react-native-reanimated"));
|
|
34202
34771
|
var import_core21 = require("@papyrus-sdk/core");
|
|
34203
34772
|
|
|
34204
34773
|
// components/progressPillMode.ts
|
|
@@ -34218,9 +34787,11 @@ var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
|
34218
34787
|
var clampPercent = (value) => Math.max(0, Math.min(100, Math.round(value)));
|
|
34219
34788
|
function ProgressPill({
|
|
34220
34789
|
documentType,
|
|
34790
|
+
navigationInDock = false,
|
|
34221
34791
|
onPress,
|
|
34222
34792
|
onOpenPageJump,
|
|
34223
34793
|
onNavigateToPage,
|
|
34794
|
+
onTurnPage,
|
|
34224
34795
|
onScrubbingChange
|
|
34225
34796
|
}) {
|
|
34226
34797
|
const {
|
|
@@ -34230,12 +34801,20 @@ function ProgressPill({
|
|
|
34230
34801
|
textLength,
|
|
34231
34802
|
comicLayoutMode,
|
|
34232
34803
|
viewMode,
|
|
34804
|
+
epubReadingMode,
|
|
34805
|
+
epubLocation,
|
|
34233
34806
|
locale,
|
|
34234
34807
|
uiTheme,
|
|
34235
34808
|
accentColor,
|
|
34236
34809
|
mobileChromeVisible,
|
|
34237
34810
|
mobileProgressPillVisible
|
|
34238
34811
|
} = (0, import_core21.useViewerStore)();
|
|
34812
|
+
const chromeVisible = mobileChromeVisible && mobileProgressPillVisible;
|
|
34813
|
+
const chromeProgress = useNativeInkMotion(chromeVisible, documentType === "epub");
|
|
34814
|
+
const chromeMotion = (0, import_react_native_reanimated4.useAnimatedStyle)(() => {
|
|
34815
|
+
"worklet";
|
|
34816
|
+
return { opacity: chromeProgress.value };
|
|
34817
|
+
});
|
|
34239
34818
|
const t = getStrings(locale);
|
|
34240
34819
|
const isDark = uiTheme === "dark";
|
|
34241
34820
|
const offsets = resolveMobileChromeOffsets(usePapyrusSafeAreaInsets());
|
|
@@ -34280,10 +34859,10 @@ function ProgressPill({
|
|
|
34280
34859
|
return `${displayedPage}/${pageCount || 0}`;
|
|
34281
34860
|
}
|
|
34282
34861
|
if (documentType === "epub") {
|
|
34283
|
-
return `Cap. ${displayedPage} \xB7 ${percent}%`;
|
|
34862
|
+
return `Cap. ${displayedPage} \xB7 ${scrubPreviewPage === null && epubLocation ? clampPercent(epubLocation.progress * 100) : percent}%`;
|
|
34284
34863
|
}
|
|
34285
34864
|
return `${percent}%`;
|
|
34286
|
-
}, [displayedPage, documentType, pageCount]);
|
|
34865
|
+
}, [displayedPage, documentType, pageCount, epubLocation, scrubPreviewPage]);
|
|
34287
34866
|
const thumbTop = resolvePageScrubberThumbTop({
|
|
34288
34867
|
currentPage,
|
|
34289
34868
|
trackHeight,
|
|
@@ -34325,7 +34904,7 @@ function ProgressPill({
|
|
|
34325
34904
|
},
|
|
34326
34905
|
[]
|
|
34327
34906
|
);
|
|
34328
|
-
if (!shouldRenderPageScrubber({
|
|
34907
|
+
if (!(documentType === "epub" && mobileProgressPillVisible) && !shouldRenderPageScrubber({
|
|
34329
34908
|
mobileChromeVisible,
|
|
34330
34909
|
mobileProgressPillVisible,
|
|
34331
34910
|
isScrubbing: isScrubbingRef.current
|
|
@@ -34356,16 +34935,17 @@ function ProgressPill({
|
|
|
34356
34935
|
}
|
|
34357
34936
|
);
|
|
34358
34937
|
}
|
|
34359
|
-
const progressViewMode = documentType === "comic" ? comicLayoutMode === "single" ? "single" : "continuous" : viewMode;
|
|
34938
|
+
const progressViewMode = documentType === "comic" ? comicLayoutMode === "single" ? "single" : "continuous" : documentType === "epub" ? epubReadingMode === "paged" ? "single" : "continuous" : viewMode;
|
|
34360
34939
|
const pillMode = resolveProgressPillMode(progressViewMode, currentPage, pageCount);
|
|
34940
|
+
if (pillMode.kind === "navigation" && navigationInDock) return null;
|
|
34361
34941
|
if (pillMode.kind === "navigation") {
|
|
34362
|
-
const previousDisabled = pillMode.previousPage === null || !onNavigateToPage;
|
|
34363
|
-
const nextDisabled = pillMode.nextPage === null || !onNavigateToPage;
|
|
34942
|
+
const previousDisabled = !onTurnPage && (pillMode.previousPage === null || !onNavigateToPage);
|
|
34943
|
+
const nextDisabled = !onTurnPage && (pillMode.nextPage === null || !onNavigateToPage);
|
|
34364
34944
|
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
34365
34945
|
import_react_native23.View,
|
|
34366
34946
|
{
|
|
34367
34947
|
pointerEvents: "box-none",
|
|
34368
|
-
style: [
|
|
34948
|
+
style: [{ position: "absolute", zIndex: 18, bottom: offsets.bottom + MOBILE_CHROME_METRICS.bottomBarVisualHeight + 12, left: offsets.left, right: offsets.right, alignItems: "center" }],
|
|
34369
34949
|
children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_react_native23.View, { style: [styles21.singlePill, isDark && styles21.pillDark], children: [
|
|
34370
34950
|
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
34371
34951
|
import_react_native23.Pressable,
|
|
@@ -34374,7 +34954,7 @@ function ProgressPill({
|
|
|
34374
34954
|
accessibilityLabel: t.previousPage,
|
|
34375
34955
|
accessibilityState: { disabled: previousDisabled },
|
|
34376
34956
|
disabled: previousDisabled,
|
|
34377
|
-
onPress: () => pillMode.previousPage !== null && onNavigateToPageRef.current?.(pillMode.previousPage),
|
|
34957
|
+
onPress: () => onTurnPage ? onTurnPage(-1) : pillMode.previousPage !== null && onNavigateToPageRef.current?.(pillMode.previousPage),
|
|
34378
34958
|
style: styles21.pageArrowHit,
|
|
34379
34959
|
testID: "papyrus-progress-page-previous",
|
|
34380
34960
|
children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react_native23.Text, { style: [styles21.pageArrow, isDark && styles21.labelDark, previousDisabled && styles21.pageArrowDisabled], children: "\u2039" })
|
|
@@ -34402,7 +34982,7 @@ function ProgressPill({
|
|
|
34402
34982
|
accessibilityLabel: t.nextPage,
|
|
34403
34983
|
accessibilityState: { disabled: nextDisabled },
|
|
34404
34984
|
disabled: nextDisabled,
|
|
34405
|
-
onPress: () => pillMode.nextPage !== null && onNavigateToPageRef.current?.(pillMode.nextPage),
|
|
34985
|
+
onPress: () => onTurnPage ? onTurnPage(1) : pillMode.nextPage !== null && onNavigateToPageRef.current?.(pillMode.nextPage),
|
|
34406
34986
|
style: styles21.pageArrowHit,
|
|
34407
34987
|
testID: "papyrus-progress-page-next",
|
|
34408
34988
|
children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react_native23.Text, { style: [styles21.pageArrow, isDark && styles21.labelDark, nextDisabled && styles21.pageArrowDisabled], children: "\u203A" })
|
|
@@ -34546,11 +35126,14 @@ function ProgressPill({
|
|
|
34546
35126
|
}
|
|
34547
35127
|
const responderPanHandlers = scrubberResponderRef.current?.panHandlers ?? {};
|
|
34548
35128
|
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
34549
|
-
|
|
35129
|
+
import_react_native_reanimated4.default.View,
|
|
34550
35130
|
{
|
|
34551
|
-
pointerEvents: "box-none",
|
|
35131
|
+
pointerEvents: chromeVisible ? "box-none" : "none",
|
|
35132
|
+
accessibilityElementsHidden: !chromeVisible,
|
|
35133
|
+
importantForAccessibility: chromeVisible ? "auto" : "no-hide-descendants",
|
|
34552
35134
|
style: [
|
|
34553
35135
|
styles21.frame,
|
|
35136
|
+
chromeMotion,
|
|
34554
35137
|
resolvePageScrubberOverlayStyle(),
|
|
34555
35138
|
{
|
|
34556
35139
|
top: offsets.progress,
|
|
@@ -35279,15 +35862,10 @@ function ReadingShell({
|
|
|
35279
35862
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
35280
35863
|
Topbar_default,
|
|
35281
35864
|
{
|
|
35865
|
+
documentType,
|
|
35282
35866
|
engine,
|
|
35283
35867
|
title,
|
|
35284
|
-
|
|
35285
|
-
closeMobileDestination();
|
|
35286
|
-
setInfoOpen(false);
|
|
35287
|
-
setActionsOpen(false);
|
|
35288
|
-
setSettingsOpen(false);
|
|
35289
|
-
setOverflowOpen(true);
|
|
35290
|
-
},
|
|
35868
|
+
onOpenSettings: () => openDestination("display"),
|
|
35291
35869
|
onOpenPageJump: () => setPageJumpOpen(true),
|
|
35292
35870
|
showPageNavigationControls: false
|
|
35293
35871
|
}
|
|
@@ -35295,6 +35873,7 @@ function ReadingShell({
|
|
|
35295
35873
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_react_native26.View, { style: styles24.viewerStage, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
35296
35874
|
Viewer_default,
|
|
35297
35875
|
{
|
|
35876
|
+
documentType,
|
|
35298
35877
|
engine,
|
|
35299
35878
|
...viewerProps,
|
|
35300
35879
|
pageScrubActive
|
|
@@ -35303,7 +35882,13 @@ function ReadingShell({
|
|
|
35303
35882
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
35304
35883
|
ProgressPill,
|
|
35305
35884
|
{
|
|
35885
|
+
navigationInDock: true,
|
|
35306
35886
|
documentType,
|
|
35887
|
+
onTurnPage: documentType === "epub" ? (direction) => {
|
|
35888
|
+
const paginatedEngine = engine;
|
|
35889
|
+
void paginatedEngine.turnEpubPage?.(direction).catch(() => {
|
|
35890
|
+
});
|
|
35891
|
+
} : void 0,
|
|
35307
35892
|
onNavigateToPage: navigateToPage,
|
|
35308
35893
|
onPress: () => openDestination(
|
|
35309
35894
|
documentType === "pdf" ? "pages" : documentType === "epub" ? "contents" : "progress"
|
|
@@ -35315,6 +35900,12 @@ function ReadingShell({
|
|
|
35315
35900
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
35316
35901
|
BottomBar_default,
|
|
35317
35902
|
{
|
|
35903
|
+
onNavigateToPage: navigateToPage,
|
|
35904
|
+
onOpenPages: () => setPageJumpOpen(true),
|
|
35905
|
+
onTurnPage: documentType === "epub" ? (direction) => {
|
|
35906
|
+
const paginatedEngine = engine;
|
|
35907
|
+
void paginatedEngine.turnEpubPage?.(direction).catch((error) => console.warn("[Papyrus] page navigation failed", error));
|
|
35908
|
+
} : void 0,
|
|
35318
35909
|
documentType,
|
|
35319
35910
|
onOpenDestination: openDestination,
|
|
35320
35911
|
onOpenInfo: () => openDestination("info"),
|
|
@@ -35394,6 +35985,7 @@ function ReadingShell({
|
|
|
35394
35985
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
35395
35986
|
SettingsSheet_default,
|
|
35396
35987
|
{
|
|
35988
|
+
onOpenInfo: () => openDestination("info"),
|
|
35397
35989
|
engine,
|
|
35398
35990
|
documentType,
|
|
35399
35991
|
visible: settingsOpen,
|
|
@@ -35406,6 +35998,7 @@ function ReadingShell({
|
|
|
35406
35998
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
35407
35999
|
PageJumpModal,
|
|
35408
36000
|
{
|
|
36001
|
+
documentType,
|
|
35409
36002
|
visible: pageJumpOpen,
|
|
35410
36003
|
currentPage,
|
|
35411
36004
|
pageCount,
|