@papyrus-sdk/ui-react-native 0.2.20 → 0.2.22
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/README.md +12 -1
- package/dist/index.d.mts +17 -1
- package/dist/index.d.ts +17 -1
- package/dist/index.js +1025 -265
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1151 -387
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/runtime/comicRuntime.js +107 -0
- package/runtime/comicRuntime.test.ts +90 -0
- package/runtime/index.html +829 -248
- package/runtime/runtime.js +744 -3
- package/runtime/syncComicRuntime.mjs +41 -0
package/dist/index.mjs
CHANGED
|
@@ -20395,9 +20395,121 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
20395
20395
|
]).default;
|
|
20396
20396
|
});
|
|
20397
20397
|
</script>
|
|
20398
|
+
<!-- @papyrus-comic-runtime:start -->
|
|
20399
|
+
<script>
|
|
20400
|
+
(function (root, factory) {
|
|
20401
|
+
if (typeof module === "object" && module.exports) {
|
|
20402
|
+
module.exports = factory();
|
|
20403
|
+
} else {
|
|
20404
|
+
root.PapyrusComicRuntime = Object.assign(
|
|
20405
|
+
factory(),
|
|
20406
|
+
root.PapyrusComicRuntime || {}
|
|
20407
|
+
);
|
|
20408
|
+
}
|
|
20409
|
+
})(typeof self === "object" ? self : this, function () {
|
|
20410
|
+
var IMAGE_EXTENSIONS = /\\.(?:gif|jpe?g|png|svg|webp)$/i;
|
|
20411
|
+
|
|
20412
|
+
function isComicImageName(name) {
|
|
20413
|
+
return typeof name === "string" && IMAGE_EXTENSIONS.test(name);
|
|
20414
|
+
}
|
|
20415
|
+
|
|
20416
|
+
function naturalCompare(left, right) {
|
|
20417
|
+
var leftParts = String(left).split(/(\\d+)/);
|
|
20418
|
+
var rightParts = String(right).split(/(\\d+)/);
|
|
20419
|
+
var length = Math.max(leftParts.length, rightParts.length);
|
|
20420
|
+
|
|
20421
|
+
for (var index = 0; index < length; index += 1) {
|
|
20422
|
+
var leftPart = leftParts[index] || "";
|
|
20423
|
+
var rightPart = rightParts[index] || "";
|
|
20424
|
+
if (leftPart === rightPart) continue;
|
|
20425
|
+
|
|
20426
|
+
var leftNumber = /^\\d+$/.test(leftPart) ? Number(leftPart) : null;
|
|
20427
|
+
var rightNumber = /^\\d+$/.test(rightPart) ? Number(rightPart) : null;
|
|
20428
|
+
if (leftNumber !== null && rightNumber !== null) {
|
|
20429
|
+
return leftNumber - rightNumber;
|
|
20430
|
+
}
|
|
20431
|
+
return leftPart.localeCompare(rightPart, undefined, {
|
|
20432
|
+
numeric: true,
|
|
20433
|
+
sensitivity: "base",
|
|
20434
|
+
});
|
|
20435
|
+
}
|
|
20436
|
+
|
|
20437
|
+
return 0;
|
|
20438
|
+
}
|
|
20439
|
+
|
|
20440
|
+
function sortComicPageNames(names) {
|
|
20441
|
+
return names.slice().sort(naturalCompare);
|
|
20442
|
+
}
|
|
20443
|
+
|
|
20444
|
+
function patchCbrWorkerSource(workerSource, wasmUrl) {
|
|
20445
|
+
return workerSource.replace(
|
|
20446
|
+
/new URL\\("libarchive\\.wasm",import\\.meta\\.url\\)\\.href/g,
|
|
20447
|
+
JSON.stringify(wasmUrl)
|
|
20448
|
+
);
|
|
20449
|
+
}
|
|
20450
|
+
|
|
20451
|
+
function getComicPreviewSize(width, height, maxWidth, maxHeight) {
|
|
20452
|
+
var safeWidth = Math.max(1, Number(width) || 1);
|
|
20453
|
+
var safeHeight = Math.max(1, Number(height) || 1);
|
|
20454
|
+
var widthLimit = maxWidth || 240;
|
|
20455
|
+
var heightLimit = maxHeight || 360;
|
|
20456
|
+
var scale = Math.min(1, widthLimit / safeWidth, heightLimit / safeHeight);
|
|
20457
|
+
return {
|
|
20458
|
+
width: Math.max(1, Math.round(safeWidth * scale)),
|
|
20459
|
+
height: Math.max(1, Math.round(safeHeight * scale)),
|
|
20460
|
+
};
|
|
20461
|
+
}
|
|
20462
|
+
|
|
20463
|
+
function getComicPageAspectRatio(width, height) {
|
|
20464
|
+
var safeWidth = Math.max(1, Number(width) || 1);
|
|
20465
|
+
var safeHeight = Math.max(1, Number(height) || 1);
|
|
20466
|
+
return safeWidth + " / " + safeHeight;
|
|
20467
|
+
}
|
|
20468
|
+
|
|
20469
|
+
function getProtectedComicPageIndexes(
|
|
20470
|
+
currentPage,
|
|
20471
|
+
visiblePageIndexes,
|
|
20472
|
+
loadingPageIndexes
|
|
20473
|
+
) {
|
|
20474
|
+
var protectedIndexes = new Set([
|
|
20475
|
+
currentPage - 1,
|
|
20476
|
+
currentPage,
|
|
20477
|
+
currentPage - 2,
|
|
20478
|
+
]);
|
|
20479
|
+
(visiblePageIndexes || []).forEach(function (pageIndex) {
|
|
20480
|
+
protectedIndexes.add(pageIndex);
|
|
20481
|
+
});
|
|
20482
|
+
(loadingPageIndexes || []).forEach(function (pageIndex) {
|
|
20483
|
+
protectedIndexes.add(pageIndex);
|
|
20484
|
+
});
|
|
20485
|
+
return protectedIndexes;
|
|
20486
|
+
}
|
|
20487
|
+
|
|
20488
|
+
function isCurrentComicPageLoad(
|
|
20489
|
+
loadGeneration,
|
|
20490
|
+
currentGeneration,
|
|
20491
|
+
entry,
|
|
20492
|
+
currentEntry
|
|
20493
|
+
) {
|
|
20494
|
+
return loadGeneration === currentGeneration && entry === currentEntry;
|
|
20495
|
+
}
|
|
20496
|
+
|
|
20497
|
+
return {
|
|
20498
|
+
isComicImageName: isComicImageName,
|
|
20499
|
+
sortComicPageNames: sortComicPageNames,
|
|
20500
|
+
patchCbrWorkerSource: patchCbrWorkerSource,
|
|
20501
|
+
getComicPreviewSize: getComicPreviewSize,
|
|
20502
|
+
getComicPageAspectRatio: getComicPageAspectRatio,
|
|
20503
|
+
getProtectedComicPageIndexes: getProtectedComicPageIndexes,
|
|
20504
|
+
isCurrentComicPageLoad: isCurrentComicPageLoad,
|
|
20505
|
+
};
|
|
20506
|
+
});
|
|
20507
|
+
|
|
20508
|
+
</script>
|
|
20509
|
+
<!-- @papyrus-comic-runtime:end -->
|
|
20398
20510
|
<script>
|
|
20399
20511
|
(function () {
|
|
20400
|
-
const viewer = document.getElementById(
|
|
20512
|
+
const viewer = document.getElementById('viewer');
|
|
20401
20513
|
const DEFAULT_FONT_SIZE = 16;
|
|
20402
20514
|
const TEXT_PAGE_CHUNK = 1600;
|
|
20403
20515
|
|
|
@@ -20410,27 +20522,116 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
20410
20522
|
let currentPage = 1;
|
|
20411
20523
|
let pageCount = 0;
|
|
20412
20524
|
let zoom = 1.0;
|
|
20525
|
+
let rotation = 0;
|
|
20526
|
+
let comicArchive = null;
|
|
20527
|
+
let comicEntries = [];
|
|
20528
|
+
let comicContainer = null;
|
|
20529
|
+
let comicPages = [];
|
|
20530
|
+
let comicObserver = null;
|
|
20531
|
+
let comicScrollFrame = null;
|
|
20532
|
+
const comicObjectUrls = new Map();
|
|
20533
|
+
const comicLoading = new Map();
|
|
20534
|
+
const comicDimensions = new Map();
|
|
20535
|
+
const comicPreviewCache = new Map();
|
|
20536
|
+
const comicPreviewLoading = new Map();
|
|
20537
|
+
const COMIC_CACHE_LIMIT = 16;
|
|
20538
|
+
const COMIC_PREVIEW_CACHE_LIMIT = 8;
|
|
20539
|
+
const comicHelpers = window.PapyrusComicRuntime || {};
|
|
20540
|
+
const runtimeConfig = window.__PAPYRUS_RUNTIME_CONFIG__ || {};
|
|
20541
|
+
let comicDispose = null;
|
|
20542
|
+
let comicGeneration = 0;
|
|
20413
20543
|
|
|
20414
20544
|
const sendMessage = (payload) => {
|
|
20415
|
-
if (
|
|
20416
|
-
window.ReactNativeWebView &&
|
|
20417
|
-
window.ReactNativeWebView.postMessage
|
|
20418
|
-
) {
|
|
20545
|
+
if (window.ReactNativeWebView && window.ReactNativeWebView.postMessage) {
|
|
20419
20546
|
window.ReactNativeWebView.postMessage(JSON.stringify(payload));
|
|
20420
20547
|
return;
|
|
20421
20548
|
}
|
|
20422
20549
|
if (window.parent && window.parent !== window) {
|
|
20423
|
-
window.parent.postMessage(payload,
|
|
20550
|
+
window.parent.postMessage(payload, '*');
|
|
20424
20551
|
}
|
|
20425
20552
|
};
|
|
20426
20553
|
|
|
20427
20554
|
const sendResponse = (id, ok, data, error) => {
|
|
20428
|
-
sendMessage({ type:
|
|
20555
|
+
sendMessage({ type: 'response', id, ok, data, error });
|
|
20556
|
+
};
|
|
20557
|
+
|
|
20558
|
+
const runtimeAssetRequests = new Map();
|
|
20559
|
+
const fileChunkRequests = new Map();
|
|
20560
|
+
|
|
20561
|
+
const requestRuntimeAsset = (url, encoding) =>
|
|
20562
|
+
new Promise((resolve, reject) => {
|
|
20563
|
+
const id = \`runtime-asset-\${Date.now()}-\${Math.random()}\`;
|
|
20564
|
+
const timeout = setTimeout(() => {
|
|
20565
|
+
runtimeAssetRequests.delete(id);
|
|
20566
|
+
reject(new Error(\`Tempo esgotado ao carregar asset CBR: \${url}\`));
|
|
20567
|
+
}, 15000);
|
|
20568
|
+
runtimeAssetRequests.set(id, {resolve, reject, timeout});
|
|
20569
|
+
sendMessage({type: 'asset-request', id, url, encoding});
|
|
20570
|
+
});
|
|
20571
|
+
|
|
20572
|
+
const encodeArrayBufferAsDataUrl = async (buffer) => {
|
|
20573
|
+
const bytes = new Uint8Array(buffer);
|
|
20574
|
+
let binary = '';
|
|
20575
|
+
const chunkSize = 0x8000;
|
|
20576
|
+
for (let offset = 0; offset < bytes.length; offset += chunkSize) {
|
|
20577
|
+
binary += String.fromCharCode(
|
|
20578
|
+
...bytes.subarray(offset, Math.min(offset + chunkSize, bytes.length)),
|
|
20579
|
+
);
|
|
20580
|
+
}
|
|
20581
|
+
return \`data:application/wasm;base64,\${btoa(binary)}\`;
|
|
20582
|
+
};
|
|
20583
|
+
|
|
20584
|
+
const fetchRuntimeAsset = async (url, encoding) => {
|
|
20585
|
+
try {
|
|
20586
|
+
const response = await fetch(url);
|
|
20587
|
+
if (!response.ok) throw new Error(\`status \${response.status}\`);
|
|
20588
|
+
if (encoding === 'text') return await response.text();
|
|
20589
|
+
return await encodeArrayBufferAsDataUrl(await response.arrayBuffer());
|
|
20590
|
+
} catch {
|
|
20591
|
+
return await requestRuntimeAsset(url, encoding);
|
|
20592
|
+
}
|
|
20593
|
+
};
|
|
20594
|
+
|
|
20595
|
+
const requestLocalFileChunk = (uri, offset, length) =>
|
|
20596
|
+
new Promise((resolve, reject) => {
|
|
20597
|
+
const id = \`file-chunk-\${Date.now()}-\${Math.random()}\`;
|
|
20598
|
+
const timeout = setTimeout(() => {
|
|
20599
|
+
fileChunkRequests.delete(id);
|
|
20600
|
+
reject(new Error(\`Tempo esgotado ao ler arquivo local: \${uri}\`));
|
|
20601
|
+
}, 30000);
|
|
20602
|
+
fileChunkRequests.set(id, {resolve, reject, timeout});
|
|
20603
|
+
sendMessage({type: 'file-chunk-request', id, uri, offset, length});
|
|
20604
|
+
});
|
|
20605
|
+
|
|
20606
|
+
const readLocalFile = async (uri) => {
|
|
20607
|
+
const chunkSize = 1024 * 1024;
|
|
20608
|
+
const chunks = [];
|
|
20609
|
+
let offset = 0;
|
|
20610
|
+
let totalLength = 0;
|
|
20611
|
+
while (true) {
|
|
20612
|
+
const result = await requestLocalFileChunk(uri, offset, chunkSize);
|
|
20613
|
+
const bytes = decodeBase64(result.data || '');
|
|
20614
|
+
if (bytes.length === 0 && !result.done) {
|
|
20615
|
+
throw new Error('Leitura nativa retornou um chunk vazio.');
|
|
20616
|
+
}
|
|
20617
|
+
chunks.push(bytes);
|
|
20618
|
+
totalLength += bytes.length;
|
|
20619
|
+
offset += bytes.length;
|
|
20620
|
+
if (result.done) break;
|
|
20621
|
+
}
|
|
20622
|
+
|
|
20623
|
+
const output = new Uint8Array(totalLength);
|
|
20624
|
+
let outputOffset = 0;
|
|
20625
|
+
chunks.forEach((chunk) => {
|
|
20626
|
+
output.set(chunk, outputOffset);
|
|
20627
|
+
outputOffset += chunk.length;
|
|
20628
|
+
});
|
|
20629
|
+
return output.buffer;
|
|
20429
20630
|
};
|
|
20430
20631
|
|
|
20431
20632
|
const sendState = (extra) => {
|
|
20432
20633
|
sendMessage({
|
|
20433
|
-
type:
|
|
20634
|
+
type: 'state',
|
|
20434
20635
|
payload: {
|
|
20435
20636
|
pageCount,
|
|
20436
20637
|
currentPage,
|
|
@@ -20441,70 +20642,66 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
20441
20642
|
};
|
|
20442
20643
|
|
|
20443
20644
|
const sendEvent = (name, payload) => {
|
|
20444
|
-
sendMessage({ type:
|
|
20445
|
-
};
|
|
20446
|
-
|
|
20447
|
-
const log = (...args) => {
|
|
20448
|
-
sendEvent("RUNTIME_LOG", {
|
|
20449
|
-
message: args.map((value) => String(value)).join(" "),
|
|
20450
|
-
});
|
|
20645
|
+
sendMessage({ type: 'event', name, payload });
|
|
20451
20646
|
};
|
|
20452
20647
|
|
|
20453
20648
|
const reportError = (error, context) => {
|
|
20454
|
-
const message =
|
|
20455
|
-
error && error.message ? error.message : String(error);
|
|
20649
|
+
const message = error && error.message ? error.message : String(error);
|
|
20456
20650
|
const stack = error && error.stack ? error.stack : null;
|
|
20457
|
-
sendEvent(
|
|
20458
|
-
};
|
|
20459
|
-
|
|
20460
|
-
const EPUB_OPEN_TIMEOUT_MS = 180000;
|
|
20461
|
-
const EPUB_READY_TIMEOUT_MS = 180000;
|
|
20462
|
-
const EPUB_DISPLAY_TIMEOUT_MS = 30000;
|
|
20463
|
-
|
|
20464
|
-
const withTimeout = async (promise, ms, label) => {
|
|
20465
|
-
let timer = null;
|
|
20466
|
-
try {
|
|
20467
|
-
return await Promise.race([
|
|
20468
|
-
promise,
|
|
20469
|
-
new Promise((_, reject) => {
|
|
20470
|
-
timer = setTimeout(
|
|
20471
|
-
() => reject(new Error(\`Timeout: \${label}\`)),
|
|
20472
|
-
ms
|
|
20473
|
-
);
|
|
20474
|
-
}),
|
|
20475
|
-
]);
|
|
20476
|
-
} finally {
|
|
20477
|
-
if (timer) {
|
|
20478
|
-
clearTimeout(timer);
|
|
20479
|
-
}
|
|
20480
|
-
}
|
|
20651
|
+
sendEvent('RUNTIME_ERROR', { message, context, stack });
|
|
20481
20652
|
};
|
|
20482
20653
|
|
|
20483
20654
|
const shouldIgnoreError = (error) => {
|
|
20484
|
-
const message =
|
|
20485
|
-
|
|
20486
|
-
return message.includes("ResizeObserver loop");
|
|
20655
|
+
const message = error && error.message ? error.message : String(error || '');
|
|
20656
|
+
return message.includes('ResizeObserver loop');
|
|
20487
20657
|
};
|
|
20488
20658
|
|
|
20489
|
-
window.addEventListener(
|
|
20659
|
+
window.addEventListener('error', (event) => {
|
|
20490
20660
|
const error = event.error || event.message;
|
|
20491
20661
|
if (shouldIgnoreError(error)) return;
|
|
20492
|
-
reportError(error,
|
|
20662
|
+
reportError(error, 'window.error');
|
|
20493
20663
|
});
|
|
20494
20664
|
|
|
20495
|
-
window.addEventListener(
|
|
20665
|
+
window.addEventListener('unhandledrejection', (event) => {
|
|
20496
20666
|
if (shouldIgnoreError(event.reason)) return;
|
|
20497
|
-
reportError(event.reason,
|
|
20667
|
+
reportError(event.reason, 'unhandledrejection');
|
|
20498
20668
|
});
|
|
20499
20669
|
|
|
20670
|
+
const clearComicState = () => {
|
|
20671
|
+
comicGeneration += 1;
|
|
20672
|
+
if (comicObserver) {
|
|
20673
|
+
comicObserver.disconnect();
|
|
20674
|
+
comicObserver = null;
|
|
20675
|
+
}
|
|
20676
|
+
if (comicScrollFrame !== null) {
|
|
20677
|
+
cancelAnimationFrame(comicScrollFrame);
|
|
20678
|
+
comicScrollFrame = null;
|
|
20679
|
+
}
|
|
20680
|
+
comicObjectUrls.forEach((url) => URL.revokeObjectURL(url));
|
|
20681
|
+
comicObjectUrls.clear();
|
|
20682
|
+
comicLoading.clear();
|
|
20683
|
+
comicDimensions.clear();
|
|
20684
|
+
comicPreviewCache.clear();
|
|
20685
|
+
comicPreviewLoading.clear();
|
|
20686
|
+
if (comicDispose) {
|
|
20687
|
+
void comicDispose();
|
|
20688
|
+
comicDispose = null;
|
|
20689
|
+
}
|
|
20690
|
+
comicArchive = null;
|
|
20691
|
+
comicEntries = [];
|
|
20692
|
+
comicContainer = null;
|
|
20693
|
+
comicPages = [];
|
|
20694
|
+
};
|
|
20695
|
+
|
|
20500
20696
|
const clearViewer = () => {
|
|
20697
|
+
clearComicState();
|
|
20501
20698
|
while (viewer.firstChild) {
|
|
20502
20699
|
viewer.removeChild(viewer.firstChild);
|
|
20503
20700
|
}
|
|
20504
20701
|
};
|
|
20505
20702
|
|
|
20506
20703
|
const decodeBase64 = (value) => {
|
|
20507
|
-
const clean = value.replace(/\\s/g,
|
|
20704
|
+
const clean = value.replace(/\\s/g, '');
|
|
20508
20705
|
const binary = atob(clean);
|
|
20509
20706
|
const len = binary.length;
|
|
20510
20707
|
const bytes = new Uint8Array(len);
|
|
@@ -20516,41 +20713,438 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
20516
20713
|
|
|
20517
20714
|
const decodeBase64ToText = (value) => {
|
|
20518
20715
|
const bytes = decodeBase64(value);
|
|
20519
|
-
return new TextDecoder(
|
|
20716
|
+
return new TextDecoder('utf-8').decode(bytes);
|
|
20717
|
+
};
|
|
20718
|
+
|
|
20719
|
+
const sourceToArrayBuffer = async (source) => {
|
|
20720
|
+
if (source.kind === 'uri') {
|
|
20721
|
+
if (/^(?:file|content):\\/\\//i.test(source.uri)) {
|
|
20722
|
+
return readLocalFile(source.uri);
|
|
20723
|
+
}
|
|
20724
|
+
const response = await fetch(source.uri);
|
|
20725
|
+
if (!response.ok && response.status !== 0) {
|
|
20726
|
+
throw new Error(\`Falha ao carregar quadrinho (\${response.status})\`);
|
|
20727
|
+
}
|
|
20728
|
+
return response.arrayBuffer();
|
|
20729
|
+
}
|
|
20730
|
+
if (source.kind === 'base64') {
|
|
20731
|
+
return decodeBase64(source.data).buffer;
|
|
20732
|
+
}
|
|
20733
|
+
throw new Error('Fonte de quadrinho inv\xE1lida.');
|
|
20734
|
+
};
|
|
20735
|
+
|
|
20736
|
+
const comicMimeType = (name) => {
|
|
20737
|
+
const extension = name.split('.').pop()?.toLowerCase();
|
|
20738
|
+
if (extension === 'png') return 'image/png';
|
|
20739
|
+
if (extension === 'gif') return 'image/gif';
|
|
20740
|
+
if (extension === 'svg') return 'image/svg+xml';
|
|
20741
|
+
if (extension === 'webp') return 'image/webp';
|
|
20742
|
+
return 'image/jpeg';
|
|
20743
|
+
};
|
|
20744
|
+
|
|
20745
|
+
const updateComicCurrentPage = () => {
|
|
20746
|
+
if (!comicContainer || comicPages.length === 0) return;
|
|
20747
|
+
const viewportTop = comicContainer.scrollTop;
|
|
20748
|
+
let closestIndex = currentPage - 1;
|
|
20749
|
+
let closestDistance = Number.POSITIVE_INFINITY;
|
|
20750
|
+
comicPages.forEach((page, index) => {
|
|
20751
|
+
const distance = Math.abs(page.offsetTop - viewportTop);
|
|
20752
|
+
if (distance < closestDistance) {
|
|
20753
|
+
closestDistance = distance;
|
|
20754
|
+
closestIndex = index;
|
|
20755
|
+
}
|
|
20756
|
+
});
|
|
20757
|
+
const nextPage = Math.max(1, Math.min(pageCount, closestIndex + 1));
|
|
20758
|
+
if (nextPage !== currentPage) {
|
|
20759
|
+
currentPage = nextPage;
|
|
20760
|
+
sendState();
|
|
20761
|
+
}
|
|
20520
20762
|
};
|
|
20521
20763
|
|
|
20522
|
-
const
|
|
20523
|
-
|
|
20524
|
-
|
|
20525
|
-
|
|
20526
|
-
|
|
20527
|
-
|
|
20764
|
+
const scheduleComicCurrentPage = () => {
|
|
20765
|
+
if (comicScrollFrame !== null) return;
|
|
20766
|
+
comicScrollFrame = requestAnimationFrame(() => {
|
|
20767
|
+
comicScrollFrame = null;
|
|
20768
|
+
updateComicCurrentPage();
|
|
20769
|
+
});
|
|
20770
|
+
};
|
|
20771
|
+
|
|
20772
|
+
const evictComicUrls = () => {
|
|
20773
|
+
if (comicObjectUrls.size <= COMIC_CACHE_LIMIT) return;
|
|
20774
|
+
const protectedIndexes = new Set([
|
|
20775
|
+
currentPage - 1,
|
|
20776
|
+
currentPage,
|
|
20777
|
+
currentPage - 2,
|
|
20778
|
+
]);
|
|
20779
|
+
for (const [index, url] of comicObjectUrls) {
|
|
20780
|
+
if (comicObjectUrls.size <= COMIC_CACHE_LIMIT) break;
|
|
20781
|
+
if (protectedIndexes.has(index)) continue;
|
|
20782
|
+
URL.revokeObjectURL(url);
|
|
20783
|
+
comicObjectUrls.delete(index);
|
|
20784
|
+
const image = comicPages[index]?.querySelector('img');
|
|
20785
|
+
const page = comicPages[index];
|
|
20786
|
+
const dimensions = comicDimensions.get(index);
|
|
20787
|
+
const width = dimensions?.width || image?.naturalWidth || 0;
|
|
20788
|
+
const height = dimensions?.height || image?.naturalHeight || 0;
|
|
20789
|
+
if (page && width > 0 && height > 0) {
|
|
20790
|
+
page.style.aspectRatio = comicHelpers.getComicPageAspectRatio(
|
|
20791
|
+
width,
|
|
20792
|
+
height
|
|
20793
|
+
);
|
|
20794
|
+
}
|
|
20795
|
+
if (image) image.removeAttribute('src');
|
|
20796
|
+
}
|
|
20797
|
+
};
|
|
20798
|
+
|
|
20799
|
+
const ensureComicPage = async (pageIndex) => {
|
|
20800
|
+
if (comicObjectUrls.has(pageIndex)) {
|
|
20801
|
+
const image = comicPages[pageIndex]?.querySelector('img');
|
|
20802
|
+
if (image && !image.src) image.src = comicObjectUrls.get(pageIndex);
|
|
20803
|
+
return comicObjectUrls.get(pageIndex);
|
|
20804
|
+
}
|
|
20805
|
+
if (comicLoading.has(pageIndex)) return comicLoading.get(pageIndex);
|
|
20806
|
+
|
|
20807
|
+
const entry = comicEntries[pageIndex];
|
|
20808
|
+
if (!entry) throw new Error(\`P\xE1gina de quadrinho inv\xE1lida: \${pageIndex}\`);
|
|
20809
|
+
const loadGeneration = comicGeneration;
|
|
20810
|
+
const pending = entry.async('blob').then((blob) => {
|
|
20811
|
+
if (
|
|
20812
|
+
!comicHelpers.isCurrentComicPageLoad(
|
|
20813
|
+
loadGeneration,
|
|
20814
|
+
comicGeneration,
|
|
20815
|
+
entry,
|
|
20816
|
+
comicEntries[pageIndex]
|
|
20817
|
+
)
|
|
20818
|
+
) {
|
|
20819
|
+
return null;
|
|
20820
|
+
}
|
|
20821
|
+
const url = URL.createObjectURL(
|
|
20822
|
+
new Blob([blob], { type: comicMimeType(entry.name) })
|
|
20528
20823
|
);
|
|
20824
|
+
comicObjectUrls.set(pageIndex, url);
|
|
20825
|
+
const image = comicPages[pageIndex]?.querySelector('img');
|
|
20826
|
+
if (image) image.src = url;
|
|
20827
|
+
evictComicUrls();
|
|
20828
|
+
return url;
|
|
20829
|
+
});
|
|
20830
|
+
comicLoading.set(pageIndex, pending);
|
|
20831
|
+
try {
|
|
20832
|
+
return await pending;
|
|
20833
|
+
} finally {
|
|
20834
|
+
if (comicLoading.get(pageIndex) === pending) {
|
|
20835
|
+
comicLoading.delete(pageIndex);
|
|
20836
|
+
}
|
|
20529
20837
|
}
|
|
20530
|
-
|
|
20531
|
-
|
|
20838
|
+
};
|
|
20839
|
+
|
|
20840
|
+
const renderComicPage = (pageIndex) => {
|
|
20841
|
+
const image = comicPages[pageIndex]?.querySelector('img');
|
|
20842
|
+
if (!image) return;
|
|
20843
|
+
image.style.width = \`\${Math.max(40, Math.round(100 * zoom))}%\`;
|
|
20844
|
+
image.style.transform = \`rotate(\${rotation}deg)\`;
|
|
20845
|
+
};
|
|
20846
|
+
|
|
20847
|
+
const applyComicLayout = () => {
|
|
20848
|
+
comicPages.forEach((_, pageIndex) => renderComicPage(pageIndex));
|
|
20849
|
+
};
|
|
20850
|
+
|
|
20851
|
+
const loadComic = async (source, format) => {
|
|
20852
|
+
clearViewer();
|
|
20853
|
+
let entries;
|
|
20854
|
+
if (format === 'cbr') {
|
|
20855
|
+
const clientUrl = runtimeConfig.cbrClientUrl;
|
|
20856
|
+
const workerUrl = runtimeConfig.cbrWorkerUrl;
|
|
20857
|
+
const wasmUrl = runtimeConfig.cbrWasmUrl;
|
|
20858
|
+
if (!clientUrl || !workerUrl || !wasmUrl) {
|
|
20859
|
+
throw new Error(
|
|
20860
|
+
'CBR no mobile exige o pacote opcional de runtime libarchive.'
|
|
20861
|
+
);
|
|
20862
|
+
}
|
|
20863
|
+
|
|
20864
|
+
const [clientSource, workerSource, wasmSource] = await Promise.all([
|
|
20865
|
+
fetchRuntimeAsset(clientUrl, 'text'),
|
|
20866
|
+
fetchRuntimeAsset(workerUrl, 'text'),
|
|
20867
|
+
runtimeConfig.cbrWasmDataUrl ||
|
|
20868
|
+
fetchRuntimeAsset(wasmUrl, 'base64'),
|
|
20869
|
+
]);
|
|
20870
|
+
const patchedWorkerSource = comicHelpers.patchCbrWorkerSource(
|
|
20871
|
+
workerSource,
|
|
20872
|
+
wasmSource
|
|
20873
|
+
);
|
|
20874
|
+
const workerObjectUrl = URL.createObjectURL(
|
|
20875
|
+
new Blob([patchedWorkerSource], {type: 'text/javascript'})
|
|
20876
|
+
);
|
|
20877
|
+
const clientObjectUrl = URL.createObjectURL(
|
|
20878
|
+
new Blob([clientSource], { type: 'text/javascript' })
|
|
20879
|
+
);
|
|
20880
|
+
try {
|
|
20881
|
+
const archiveModule = await import(clientObjectUrl);
|
|
20882
|
+
const createCbrWorker = () => {
|
|
20883
|
+
const worker = new Worker(workerObjectUrl, {type: 'module'});
|
|
20884
|
+
worker.addEventListener('error', (event) => {
|
|
20885
|
+
sendEvent('RUNTIME_ERROR', {
|
|
20886
|
+
message: \`CBR worker: \${event?.message || 'falha ao executar o worker'}\`,
|
|
20887
|
+
context: 'comic.worker',
|
|
20888
|
+
});
|
|
20889
|
+
});
|
|
20890
|
+
worker.addEventListener('messageerror', () => {
|
|
20891
|
+
sendEvent('RUNTIME_ERROR', {
|
|
20892
|
+
message: 'CBR worker: falha ao transferir mensagem',
|
|
20893
|
+
context: 'comic.worker',
|
|
20894
|
+
});
|
|
20895
|
+
});
|
|
20896
|
+
return worker;
|
|
20897
|
+
};
|
|
20898
|
+
archiveModule.Archive.init({getWorker: createCbrWorker});
|
|
20899
|
+
const bytes = await sourceToArrayBuffer(source);
|
|
20900
|
+
const file = new Blob([bytes], {
|
|
20901
|
+
type: 'application/vnd.comicbook-rar',
|
|
20902
|
+
});
|
|
20903
|
+
const archive = await archiveModule.Archive.open(file);
|
|
20904
|
+
const files = await archive.getFilesArray();
|
|
20905
|
+
entries = files
|
|
20906
|
+
.filter(
|
|
20907
|
+
(item) => {
|
|
20908
|
+
const name = \`\${item?.path || ''}\${item?.file?.name || ''}\`;
|
|
20909
|
+
return item?.file && comicHelpers.isComicImageName(name);
|
|
20910
|
+
}
|
|
20911
|
+
)
|
|
20912
|
+
.map((item) => {
|
|
20913
|
+
const name = \`\${item.path || ''}\${item.file.name}\`;
|
|
20914
|
+
return {
|
|
20915
|
+
name,
|
|
20916
|
+
async: async () => item.file.extract(),
|
|
20917
|
+
};
|
|
20918
|
+
});
|
|
20919
|
+
comicDispose = async () => {
|
|
20920
|
+
await archive.close();
|
|
20921
|
+
URL.revokeObjectURL(workerObjectUrl);
|
|
20922
|
+
URL.revokeObjectURL(clientObjectUrl);
|
|
20923
|
+
};
|
|
20924
|
+
} catch (error) {
|
|
20925
|
+
URL.revokeObjectURL(workerObjectUrl);
|
|
20926
|
+
URL.revokeObjectURL(clientObjectUrl);
|
|
20927
|
+
throw error;
|
|
20928
|
+
}
|
|
20929
|
+
} else {
|
|
20930
|
+
if (!window.JSZip) {
|
|
20931
|
+
throw new Error('O runtime ZIP do leitor mobile n\xE3o foi carregado.');
|
|
20932
|
+
}
|
|
20933
|
+
|
|
20934
|
+
const bytes = await sourceToArrayBuffer(source);
|
|
20935
|
+
comicArchive = await window.JSZip.loadAsync(bytes);
|
|
20936
|
+
entries = Object.keys(comicArchive.files)
|
|
20937
|
+
.filter((name) => {
|
|
20938
|
+
const entry = comicArchive.files[name];
|
|
20939
|
+
return !entry.dir && comicHelpers.isComicImageName(name);
|
|
20940
|
+
})
|
|
20941
|
+
.map((name) => comicArchive.files[name]);
|
|
20942
|
+
}
|
|
20943
|
+
|
|
20944
|
+
const names = comicHelpers.sortComicPageNames(
|
|
20945
|
+
entries.map((entry) => entry.name)
|
|
20946
|
+
);
|
|
20947
|
+
const entriesByName = new Map(entries.map((entry) => [entry.name, entry]));
|
|
20948
|
+
comicEntries = names.map((name) => entriesByName.get(name));
|
|
20949
|
+
if (comicEntries.length === 0) {
|
|
20950
|
+
if (comicDispose) {
|
|
20951
|
+
await comicDispose();
|
|
20952
|
+
comicDispose = null;
|
|
20953
|
+
}
|
|
20954
|
+
throw new Error('O arquivo n\xE3o cont\xE9m p\xE1ginas de imagem.');
|
|
20532
20955
|
}
|
|
20533
|
-
|
|
20534
|
-
|
|
20956
|
+
|
|
20957
|
+
comicContainer = document.createElement('div');
|
|
20958
|
+
comicContainer.style.width = '100%';
|
|
20959
|
+
comicContainer.style.height = '100%';
|
|
20960
|
+
comicContainer.style.overflow = 'auto';
|
|
20961
|
+
comicContainer.style.padding = '16px 0 120px';
|
|
20962
|
+
comicContainer.style.boxSizing = 'border-box';
|
|
20963
|
+
comicContainer.style.background = '#ffffff';
|
|
20964
|
+
comicContainer.addEventListener('scroll', scheduleComicCurrentPage, {
|
|
20965
|
+
passive: true,
|
|
20966
|
+
});
|
|
20967
|
+
viewer.style.overflow = 'hidden';
|
|
20968
|
+
viewer.appendChild(comicContainer);
|
|
20969
|
+
|
|
20970
|
+
comicPages = comicEntries.map((entry, pageIndex) => {
|
|
20971
|
+
const page = document.createElement('div');
|
|
20972
|
+
page.dataset.pageIndex = String(pageIndex);
|
|
20973
|
+
page.style.width = '100%';
|
|
20974
|
+
page.style.minHeight = '80px';
|
|
20975
|
+
page.style.display = 'flex';
|
|
20976
|
+
page.style.justifyContent = 'center';
|
|
20977
|
+
page.style.alignItems = 'flex-start';
|
|
20978
|
+
page.style.padding = '0 12px 20px';
|
|
20979
|
+
page.style.boxSizing = 'border-box';
|
|
20980
|
+
|
|
20981
|
+
const image = document.createElement('img');
|
|
20982
|
+
image.alt = \`P\xE1gina \${pageIndex + 1}\`;
|
|
20983
|
+
image.draggable = false;
|
|
20984
|
+
image.decoding = 'async';
|
|
20985
|
+
image.loading = 'lazy';
|
|
20986
|
+
image.style.display = 'block';
|
|
20987
|
+
image.style.maxWidth = 'none';
|
|
20988
|
+
image.style.height = 'auto';
|
|
20989
|
+
image.style.userSelect = 'none';
|
|
20990
|
+
image.addEventListener('load', () => {
|
|
20991
|
+
if (image.naturalWidth > 0 && image.naturalHeight > 0) {
|
|
20992
|
+
comicDimensions.set(pageIndex, {
|
|
20993
|
+
width: image.naturalWidth,
|
|
20994
|
+
height: image.naturalHeight,
|
|
20995
|
+
});
|
|
20996
|
+
page.style.aspectRatio = comicHelpers.getComicPageAspectRatio(
|
|
20997
|
+
image.naturalWidth,
|
|
20998
|
+
image.naturalHeight
|
|
20999
|
+
);
|
|
21000
|
+
}
|
|
21001
|
+
});
|
|
21002
|
+
page.appendChild(image);
|
|
21003
|
+
comicContainer.appendChild(page);
|
|
21004
|
+
return page;
|
|
21005
|
+
});
|
|
21006
|
+
|
|
21007
|
+
if (typeof IntersectionObserver === 'function') {
|
|
21008
|
+
comicObserver = new IntersectionObserver(
|
|
21009
|
+
(observations) => {
|
|
21010
|
+
observations.forEach((observation) => {
|
|
21011
|
+
if (!observation.isIntersecting) return;
|
|
21012
|
+
const pageIndex = Number(observation.target.dataset.pageIndex);
|
|
21013
|
+
void ensureComicPage(pageIndex).catch((error) =>
|
|
21014
|
+
sendEvent('RUNTIME_ERROR', {
|
|
21015
|
+
message: error?.message || String(error),
|
|
21016
|
+
context: 'comic.page',
|
|
21017
|
+
})
|
|
21018
|
+
);
|
|
21019
|
+
});
|
|
21020
|
+
scheduleComicCurrentPage();
|
|
21021
|
+
},
|
|
21022
|
+
{ root: comicContainer, rootMargin: '600px 0px' }
|
|
21023
|
+
);
|
|
21024
|
+
comicPages.forEach((page) => comicObserver.observe(page));
|
|
21025
|
+
} else {
|
|
21026
|
+
for (let pageIndex = 0; pageIndex < Math.min(3, comicPages.length); pageIndex += 1) {
|
|
21027
|
+
void ensureComicPage(pageIndex);
|
|
21028
|
+
}
|
|
21029
|
+
}
|
|
21030
|
+
pageCount = comicPages.length;
|
|
21031
|
+
currentPage = 1;
|
|
21032
|
+
await ensureComicPage(0);
|
|
21033
|
+
applyComicLayout();
|
|
21034
|
+
return { pageCount };
|
|
21035
|
+
};
|
|
21036
|
+
|
|
21037
|
+
const readComicBlobAsDataUrl = (blob, mimeType) =>
|
|
21038
|
+
new Promise((resolve, reject) => {
|
|
20535
21039
|
const reader = new FileReader();
|
|
20536
|
-
reader.onerror = () =>
|
|
20537
|
-
reject(new Error("Failed to read epub blob"));
|
|
21040
|
+
reader.onerror = () => reject(new Error('Falha ao gerar preview.'));
|
|
20538
21041
|
reader.onload = () => resolve(reader.result);
|
|
20539
|
-
reader.
|
|
21042
|
+
reader.readAsDataURL(new Blob([blob], { type: mimeType }));
|
|
20540
21043
|
});
|
|
21044
|
+
|
|
21045
|
+
const createComicPagePreview = async (pageIndex) => {
|
|
21046
|
+
const entry = comicEntries[pageIndex];
|
|
21047
|
+
if (!entry) return null;
|
|
21048
|
+
const mimeType = comicMimeType(entry.name);
|
|
21049
|
+
const sourceUrl = await ensureComicPage(pageIndex);
|
|
21050
|
+
if (!sourceUrl) return null;
|
|
21051
|
+
try {
|
|
21052
|
+
const image = new Image();
|
|
21053
|
+
image.decoding = 'async';
|
|
21054
|
+
await new Promise((resolve, reject) => {
|
|
21055
|
+
image.onload = resolve;
|
|
21056
|
+
image.onerror = () => reject(new Error('Falha ao decodificar preview.'));
|
|
21057
|
+
image.src = sourceUrl;
|
|
21058
|
+
});
|
|
21059
|
+
const size = comicHelpers.getComicPreviewSize(
|
|
21060
|
+
image.naturalWidth || image.width,
|
|
21061
|
+
image.naturalHeight || image.height
|
|
21062
|
+
);
|
|
21063
|
+
const canvas = document.createElement('canvas');
|
|
21064
|
+
canvas.width = size.width;
|
|
21065
|
+
canvas.height = size.height;
|
|
21066
|
+
const context = canvas.getContext('2d');
|
|
21067
|
+
if (!context) throw new Error('Canvas indispon\xEDvel para preview.');
|
|
21068
|
+
context.fillStyle = '#ffffff';
|
|
21069
|
+
context.fillRect(0, 0, size.width, size.height);
|
|
21070
|
+
context.drawImage(image, 0, 0, size.width, size.height);
|
|
21071
|
+
return canvas.toDataURL('image/jpeg', 0.78);
|
|
21072
|
+
} catch {
|
|
21073
|
+
try {
|
|
21074
|
+
const response = await fetch(sourceUrl);
|
|
21075
|
+
const blob = await response.blob();
|
|
21076
|
+
return await readComicBlobAsDataUrl(blob, mimeType);
|
|
21077
|
+
} catch {
|
|
21078
|
+
return null;
|
|
21079
|
+
}
|
|
21080
|
+
}
|
|
21081
|
+
};
|
|
21082
|
+
|
|
21083
|
+
const getComicPagePreview = async (pageIndex) => {
|
|
21084
|
+
const entry = comicEntries[pageIndex];
|
|
21085
|
+
if (!entry) return null;
|
|
21086
|
+
if (comicPreviewCache.has(pageIndex)) {
|
|
21087
|
+
return comicPreviewCache.get(pageIndex);
|
|
21088
|
+
}
|
|
21089
|
+
if (comicPreviewLoading.has(pageIndex)) {
|
|
21090
|
+
return comicPreviewLoading.get(pageIndex);
|
|
21091
|
+
}
|
|
21092
|
+
const loadGeneration = comicGeneration;
|
|
21093
|
+
const pending = createComicPagePreview(pageIndex).then((preview) => {
|
|
21094
|
+
if (
|
|
21095
|
+
!comicHelpers.isCurrentComicPageLoad(
|
|
21096
|
+
loadGeneration,
|
|
21097
|
+
comicGeneration,
|
|
21098
|
+
entry,
|
|
21099
|
+
comicEntries[pageIndex]
|
|
21100
|
+
)
|
|
21101
|
+
) {
|
|
21102
|
+
return null;
|
|
21103
|
+
}
|
|
21104
|
+
comicPreviewCache.set(pageIndex, preview);
|
|
21105
|
+
while (comicPreviewCache.size > COMIC_PREVIEW_CACHE_LIMIT) {
|
|
21106
|
+
comicPreviewCache.delete(comicPreviewCache.keys().next().value);
|
|
21107
|
+
}
|
|
21108
|
+
return preview;
|
|
21109
|
+
});
|
|
21110
|
+
comicPreviewLoading.set(pageIndex, pending);
|
|
21111
|
+
try {
|
|
21112
|
+
return await pending;
|
|
21113
|
+
} finally {
|
|
21114
|
+
if (comicPreviewLoading.get(pageIndex) === pending) {
|
|
21115
|
+
comicPreviewLoading.delete(pageIndex);
|
|
21116
|
+
}
|
|
21117
|
+
}
|
|
21118
|
+
};
|
|
21119
|
+
|
|
21120
|
+
const getComicPageDimensions = async (pageIndex) => {
|
|
21121
|
+
const known = comicDimensions.get(pageIndex);
|
|
21122
|
+
if (known) return known;
|
|
21123
|
+
await ensureComicPage(pageIndex);
|
|
21124
|
+
const image = comicPages[pageIndex]?.querySelector('img');
|
|
21125
|
+
if (image && !image.complete) {
|
|
21126
|
+
await new Promise((resolve) => {
|
|
21127
|
+
image.addEventListener('load', resolve, { once: true });
|
|
21128
|
+
image.addEventListener('error', resolve, { once: true });
|
|
21129
|
+
});
|
|
21130
|
+
}
|
|
21131
|
+
return (
|
|
21132
|
+
comicDimensions.get(pageIndex) || {
|
|
21133
|
+
width: image?.naturalWidth || 0,
|
|
21134
|
+
height: image?.naturalHeight || 0,
|
|
21135
|
+
}
|
|
21136
|
+
);
|
|
20541
21137
|
};
|
|
20542
21138
|
|
|
20543
21139
|
const normalizeHref = (href) => {
|
|
20544
|
-
if (!href) return
|
|
20545
|
-
return href.split(
|
|
21140
|
+
if (!href) return '';
|
|
21141
|
+
return href.split('#')[0];
|
|
20546
21142
|
};
|
|
20547
21143
|
|
|
20548
21144
|
const getSpineIndexByHref = (href) => {
|
|
20549
21145
|
const normalized = normalizeHref(href);
|
|
20550
21146
|
if (!normalized) return -1;
|
|
20551
|
-
return spineItems.findIndex(
|
|
20552
|
-
(item) => normalizeHref(item.href) === normalized
|
|
20553
|
-
);
|
|
21147
|
+
return spineItems.findIndex((item) => normalizeHref(item.href) === normalized);
|
|
20554
21148
|
};
|
|
20555
21149
|
|
|
20556
21150
|
const buildOutline = async () => {
|
|
@@ -20559,11 +21153,9 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
20559
21153
|
const toc = nav && nav.toc ? nav.toc : [];
|
|
20560
21154
|
|
|
20561
21155
|
const mapItem = (item) => {
|
|
20562
|
-
const title = item.label || item.title ||
|
|
20563
|
-
const pageIndex = getSpineIndexByHref(item.href ||
|
|
20564
|
-
const children = Array.isArray(item.subitems)
|
|
20565
|
-
? item.subitems.map(mapItem)
|
|
20566
|
-
: [];
|
|
21156
|
+
const title = item.label || item.title || '';
|
|
21157
|
+
const pageIndex = getSpineIndexByHref(item.href || '');
|
|
21158
|
+
const children = Array.isArray(item.subitems) ? item.subitems.map(mapItem) : [];
|
|
20567
21159
|
const outlineItem = { title, pageIndex };
|
|
20568
21160
|
if (children.length > 0) outlineItem.children = children;
|
|
20569
21161
|
return outlineItem;
|
|
@@ -20575,10 +21167,10 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
20575
21167
|
const applyEpubZoom = () => {
|
|
20576
21168
|
if (!rendition || !rendition.themes) return;
|
|
20577
21169
|
const fontSize = \`\${Math.round(zoom * 100)}%\`;
|
|
20578
|
-
if (typeof rendition.themes.fontSize ===
|
|
21170
|
+
if (typeof rendition.themes.fontSize === 'function') {
|
|
20579
21171
|
rendition.themes.fontSize(fontSize);
|
|
20580
|
-
} else if (typeof rendition.themes.override ===
|
|
20581
|
-
rendition.themes.override(
|
|
21172
|
+
} else if (typeof rendition.themes.override === 'function') {
|
|
21173
|
+
rendition.themes.override('font-size', fontSize);
|
|
20582
21174
|
}
|
|
20583
21175
|
};
|
|
20584
21176
|
|
|
@@ -20589,14 +21181,13 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
20589
21181
|
};
|
|
20590
21182
|
|
|
20591
21183
|
const renderTextPage = (pageIndex) => {
|
|
20592
|
-
const text = textPages[pageIndex] ||
|
|
21184
|
+
const text = textPages[pageIndex] || '';
|
|
20593
21185
|
if (!textContainer) {
|
|
20594
|
-
textContainer = document.createElement(
|
|
20595
|
-
textContainer.style.padding =
|
|
20596
|
-
textContainer.style.lineHeight =
|
|
20597
|
-
textContainer.style.whiteSpace =
|
|
20598
|
-
textContainer.style.fontFamily =
|
|
20599
|
-
'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace';
|
|
21186
|
+
textContainer = document.createElement('div');
|
|
21187
|
+
textContainer.style.padding = '24px';
|
|
21188
|
+
textContainer.style.lineHeight = '1.6';
|
|
21189
|
+
textContainer.style.whiteSpace = 'pre-wrap';
|
|
21190
|
+
textContainer.style.fontFamily = 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace';
|
|
20600
21191
|
viewer.appendChild(textContainer);
|
|
20601
21192
|
}
|
|
20602
21193
|
textContainer.textContent = text;
|
|
@@ -20608,18 +21199,18 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
20608
21199
|
for (let i = 0; i < text.length; i += TEXT_PAGE_CHUNK) {
|
|
20609
21200
|
pages.push(text.slice(i, i + TEXT_PAGE_CHUNK));
|
|
20610
21201
|
}
|
|
20611
|
-
return pages.length > 0 ? pages : [
|
|
21202
|
+
return pages.length > 0 ? pages : [''];
|
|
20612
21203
|
};
|
|
20613
21204
|
|
|
20614
21205
|
const loadText = async (source) => {
|
|
20615
|
-
let text =
|
|
20616
|
-
if (source.kind ===
|
|
21206
|
+
let text = '';
|
|
21207
|
+
if (source.kind === 'uri') {
|
|
20617
21208
|
const res = await fetch(source.uri);
|
|
20618
21209
|
text = await res.text();
|
|
20619
|
-
} else if (source.kind ===
|
|
21210
|
+
} else if (source.kind === 'base64') {
|
|
20620
21211
|
text = decodeBase64ToText(source.data);
|
|
20621
|
-
} else if (source.kind ===
|
|
20622
|
-
text = source.text ||
|
|
21212
|
+
} else if (source.kind === 'text') {
|
|
21213
|
+
text = source.text || '';
|
|
20623
21214
|
}
|
|
20624
21215
|
|
|
20625
21216
|
clearViewer();
|
|
@@ -20632,44 +21223,25 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
20632
21223
|
};
|
|
20633
21224
|
|
|
20634
21225
|
const loadEpub = async (source) => {
|
|
20635
|
-
|
|
20636
|
-
if (rendition && typeof rendition.destroy === "function") {
|
|
21226
|
+
if (rendition && typeof rendition.destroy === 'function') {
|
|
20637
21227
|
rendition.destroy();
|
|
20638
21228
|
}
|
|
20639
|
-
if (book && typeof book.destroy ===
|
|
21229
|
+
if (book && typeof book.destroy === 'function') {
|
|
20640
21230
|
book.destroy();
|
|
20641
21231
|
}
|
|
20642
21232
|
|
|
20643
|
-
|
|
20644
|
-
|
|
20645
|
-
|
|
20646
|
-
|
|
20647
|
-
|
|
20648
|
-
|
|
20649
|
-
);
|
|
20650
|
-
|
|
20651
|
-
log("epub.load:fetch-uri");
|
|
20652
|
-
const data = await withTimeout(
|
|
20653
|
-
fetchUriAsArrayBuffer(source.uri),
|
|
20654
|
-
EPUB_OPEN_TIMEOUT_MS,
|
|
20655
|
-
"epub.fetch"
|
|
20656
|
-
);
|
|
20657
|
-
const input = data instanceof Uint8Array ? data.buffer : data;
|
|
20658
|
-
book = ePub(input, { openAs: "epub" });
|
|
20659
|
-
} else {
|
|
20660
|
-
let data = null;
|
|
20661
|
-
if (source.kind === "text") {
|
|
20662
|
-
const encoder = new TextEncoder();
|
|
20663
|
-
data = encoder.encode(source.text || "").buffer;
|
|
20664
|
-
}
|
|
20665
|
-
const input = data instanceof Uint8Array ? data.buffer : data;
|
|
20666
|
-
book = ePub(input, { openAs: "epub" });
|
|
20667
|
-
}
|
|
20668
|
-
if (book && book.opened) {
|
|
20669
|
-
await withTimeout(book.opened, EPUB_OPEN_TIMEOUT_MS, "epub.opened");
|
|
21233
|
+
let data = null;
|
|
21234
|
+
if (source.kind === 'uri') {
|
|
21235
|
+
data = source.uri;
|
|
21236
|
+
} else if (source.kind === 'base64') {
|
|
21237
|
+
data = decodeBase64(source.data);
|
|
21238
|
+
} else if (source.kind === 'text') {
|
|
21239
|
+
const encoder = new TextEncoder();
|
|
21240
|
+
data = encoder.encode(source.text || '').buffer;
|
|
20670
21241
|
}
|
|
20671
|
-
|
|
20672
|
-
|
|
21242
|
+
|
|
21243
|
+
book = ePub(data);
|
|
21244
|
+
await book.ready;
|
|
20673
21245
|
|
|
20674
21246
|
spineItems = book.spine && book.spine.items ? book.spine.items : [];
|
|
20675
21247
|
pageCount = spineItems.length;
|
|
@@ -20677,64 +21249,38 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
20677
21249
|
|
|
20678
21250
|
clearViewer();
|
|
20679
21251
|
rendition = book.renderTo(viewer, {
|
|
20680
|
-
width:
|
|
20681
|
-
height:
|
|
20682
|
-
flow:
|
|
20683
|
-
spread:
|
|
21252
|
+
width: '100%',
|
|
21253
|
+
height: '100%',
|
|
21254
|
+
flow: 'paginated',
|
|
21255
|
+
spread: 'none',
|
|
20684
21256
|
});
|
|
20685
21257
|
|
|
20686
21258
|
if (rendition && rendition.hooks && rendition.hooks.content) {
|
|
20687
21259
|
rendition.hooks.content.register((contents) => {
|
|
20688
|
-
const frame =
|
|
20689
|
-
contents && contents.document
|
|
20690
|
-
? contents.document.defaultView.frameElement
|
|
20691
|
-
: null;
|
|
21260
|
+
const frame = contents && contents.document ? contents.document.defaultView.frameElement : null;
|
|
20692
21261
|
if (frame) {
|
|
20693
|
-
frame.setAttribute(
|
|
20694
|
-
"sandbox",
|
|
20695
|
-
"allow-scripts allow-same-origin"
|
|
20696
|
-
);
|
|
21262
|
+
frame.setAttribute('sandbox', 'allow-scripts allow-same-origin');
|
|
20697
21263
|
}
|
|
20698
21264
|
});
|
|
20699
21265
|
}
|
|
20700
21266
|
|
|
20701
|
-
if (rendition && typeof rendition.on ===
|
|
20702
|
-
rendition.on(
|
|
20703
|
-
const selection =
|
|
20704
|
-
|
|
20705
|
-
? contents.window.getSelection()
|
|
20706
|
-
: null;
|
|
20707
|
-
const text = selection ? selection.toString().trim() : "";
|
|
21267
|
+
if (rendition && typeof rendition.on === 'function') {
|
|
21268
|
+
rendition.on('selected', (cfiRange, contents) => {
|
|
21269
|
+
const selection = contents && contents.window ? contents.window.getSelection() : null;
|
|
21270
|
+
const text = selection ? selection.toString().trim() : '';
|
|
20708
21271
|
if (text) {
|
|
20709
|
-
sendEvent(
|
|
20710
|
-
text,
|
|
20711
|
-
pageIndex: Math.max(0, currentPage - 1),
|
|
20712
|
-
});
|
|
21272
|
+
sendEvent('TEXT_SELECTED', { text, pageIndex: Math.max(0, currentPage - 1) });
|
|
20713
21273
|
}
|
|
20714
|
-
if (
|
|
20715
|
-
rendition
|
|
20716
|
-
rendition.annotations &&
|
|
20717
|
-
typeof rendition.annotations.remove === "function"
|
|
20718
|
-
) {
|
|
20719
|
-
rendition.annotations.remove(cfiRange, "highlight");
|
|
21274
|
+
if (rendition && rendition.annotations && typeof rendition.annotations.remove === 'function') {
|
|
21275
|
+
rendition.annotations.remove(cfiRange, 'highlight');
|
|
20720
21276
|
}
|
|
20721
21277
|
});
|
|
20722
21278
|
}
|
|
20723
21279
|
|
|
20724
|
-
|
|
20725
|
-
await withTimeout(
|
|
20726
|
-
displayEpubPage(0),
|
|
20727
|
-
EPUB_DISPLAY_TIMEOUT_MS,
|
|
20728
|
-
"epub.display"
|
|
20729
|
-
);
|
|
20730
|
-
log("epub.load:displayed");
|
|
20731
|
-
} catch (err) {
|
|
20732
|
-
reportError(err, "epub.display");
|
|
20733
|
-
}
|
|
21280
|
+
await displayEpubPage(0);
|
|
20734
21281
|
applyEpubZoom();
|
|
20735
21282
|
|
|
20736
21283
|
const outline = await buildOutline();
|
|
20737
|
-
log("epub.load:outline", outline.length);
|
|
20738
21284
|
return { pageCount, outline };
|
|
20739
21285
|
};
|
|
20740
21286
|
|
|
@@ -20749,41 +21295,34 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
20749
21295
|
};
|
|
20750
21296
|
|
|
20751
21297
|
const getTextContent = async (pageIndex) => {
|
|
20752
|
-
if (currentType ===
|
|
20753
|
-
const text = textPages[pageIndex] ||
|
|
20754
|
-
return [
|
|
20755
|
-
|
|
20756
|
-
|
|
20757
|
-
|
|
20758
|
-
|
|
20759
|
-
|
|
20760
|
-
|
|
20761
|
-
|
|
20762
|
-
},
|
|
20763
|
-
];
|
|
21298
|
+
if (currentType === 'text') {
|
|
21299
|
+
const text = textPages[pageIndex] || '';
|
|
21300
|
+
return [{
|
|
21301
|
+
str: text,
|
|
21302
|
+
dir: 'ltr',
|
|
21303
|
+
width: 0,
|
|
21304
|
+
height: 0,
|
|
21305
|
+
transform: [1, 0, 0, 1, 0, 0],
|
|
21306
|
+
fontName: 'default',
|
|
21307
|
+
}];
|
|
20764
21308
|
}
|
|
20765
21309
|
|
|
20766
|
-
if (currentType ===
|
|
21310
|
+
if (currentType === 'epub') {
|
|
20767
21311
|
if (!book) return [];
|
|
20768
21312
|
const item = spineItems[pageIndex];
|
|
20769
21313
|
if (!item) return [];
|
|
20770
21314
|
try {
|
|
20771
21315
|
const section = book.spine.get(item.idref || item.href);
|
|
20772
|
-
const text =
|
|
20773
|
-
section && typeof section.text === "function"
|
|
20774
|
-
? await section.text()
|
|
20775
|
-
: "";
|
|
21316
|
+
const text = section && typeof section.text === 'function' ? await section.text() : '';
|
|
20776
21317
|
if (!text) return [];
|
|
20777
|
-
return [
|
|
20778
|
-
|
|
20779
|
-
|
|
20780
|
-
|
|
20781
|
-
|
|
20782
|
-
|
|
20783
|
-
|
|
20784
|
-
|
|
20785
|
-
},
|
|
20786
|
-
];
|
|
21318
|
+
return [{
|
|
21319
|
+
str: text,
|
|
21320
|
+
dir: 'ltr',
|
|
21321
|
+
width: 0,
|
|
21322
|
+
height: 0,
|
|
21323
|
+
transform: [1, 0, 0, 1, 0, 0],
|
|
21324
|
+
fontName: 'default',
|
|
21325
|
+
}];
|
|
20787
21326
|
} catch (err) {
|
|
20788
21327
|
return [];
|
|
20789
21328
|
}
|
|
@@ -20794,7 +21333,7 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
20794
21333
|
|
|
20795
21334
|
const getPageText = async (pageIndex) => {
|
|
20796
21335
|
const items = await getTextContent(pageIndex);
|
|
20797
|
-
return items.map((item) => item.str).join(
|
|
21336
|
+
return items.map((item) => item.str).join(' ');
|
|
20798
21337
|
};
|
|
20799
21338
|
|
|
20800
21339
|
const searchText = async (query) => {
|
|
@@ -20810,11 +21349,7 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
20810
21349
|
while (pos !== -1) {
|
|
20811
21350
|
const start = Math.max(0, pos - 20);
|
|
20812
21351
|
const end = Math.min(text.length, pos + query.length + 20);
|
|
20813
|
-
results.push({
|
|
20814
|
-
pageIndex: i,
|
|
20815
|
-
text: text.substring(start, end),
|
|
20816
|
-
matchIndex,
|
|
20817
|
-
});
|
|
21352
|
+
results.push({ pageIndex: i, text: text.substring(start, end), matchIndex });
|
|
20818
21353
|
matchIndex += 1;
|
|
20819
21354
|
pos = lower.indexOf(normalized, pos + 1);
|
|
20820
21355
|
}
|
|
@@ -20830,11 +21365,11 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
20830
21365
|
|
|
20831
21366
|
const getPageIndex = (dest) => {
|
|
20832
21367
|
if (!dest) return null;
|
|
20833
|
-
if (typeof dest ===
|
|
20834
|
-
if (typeof dest !==
|
|
20835
|
-
if (dest.kind ===
|
|
20836
|
-
if (dest.kind ===
|
|
20837
|
-
if (dest.kind ===
|
|
21368
|
+
if (typeof dest === 'string') return getSpineIndexByHref(dest);
|
|
21369
|
+
if (typeof dest !== 'object') return null;
|
|
21370
|
+
if (dest.kind === 'href') return getSpineIndexByHref(dest.value);
|
|
21371
|
+
if (dest.kind === 'pageIndex') return dest.value;
|
|
21372
|
+
if (dest.kind === 'pageNumber') return Math.max(0, dest.value - 1);
|
|
20838
21373
|
return null;
|
|
20839
21374
|
};
|
|
20840
21375
|
|
|
@@ -20848,53 +21383,70 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
20848
21383
|
};
|
|
20849
21384
|
|
|
20850
21385
|
const applyZoom = () => {
|
|
20851
|
-
if (currentType ===
|
|
21386
|
+
if (currentType === 'text') {
|
|
20852
21387
|
applyTextZoom();
|
|
20853
|
-
} else if (currentType ===
|
|
21388
|
+
} else if (currentType === 'epub') {
|
|
20854
21389
|
applyEpubZoom();
|
|
21390
|
+
} else if (currentType === 'comic') {
|
|
21391
|
+
applyComicLayout();
|
|
20855
21392
|
}
|
|
20856
21393
|
};
|
|
20857
21394
|
|
|
20858
21395
|
const handleCommand = async (message) => {
|
|
20859
21396
|
const { id, kind, payload } = message;
|
|
20860
|
-
log("command", kind);
|
|
20861
21397
|
|
|
20862
21398
|
try {
|
|
20863
|
-
if (kind ===
|
|
21399
|
+
if (kind === 'load') {
|
|
20864
21400
|
currentType = payload.type;
|
|
20865
21401
|
zoom = 1.0;
|
|
20866
21402
|
|
|
20867
|
-
if (currentType ===
|
|
21403
|
+
if (currentType === 'text') {
|
|
20868
21404
|
const result = await loadText(payload.source);
|
|
20869
21405
|
sendState();
|
|
20870
21406
|
sendResponse(id, true, result);
|
|
20871
21407
|
return;
|
|
20872
21408
|
}
|
|
20873
21409
|
|
|
20874
|
-
if (currentType ===
|
|
21410
|
+
if (currentType === 'epub') {
|
|
20875
21411
|
const result = await loadEpub(payload.source);
|
|
20876
21412
|
sendState({ outline: result.outline || [] });
|
|
20877
21413
|
sendResponse(id, true, result);
|
|
20878
21414
|
return;
|
|
20879
21415
|
}
|
|
20880
21416
|
|
|
20881
|
-
|
|
21417
|
+
if (currentType === 'comic') {
|
|
21418
|
+
const result = await loadComic(payload.source, payload.format || 'cbz');
|
|
21419
|
+
sendState();
|
|
21420
|
+
sendResponse(id, true, result);
|
|
21421
|
+
return;
|
|
21422
|
+
}
|
|
21423
|
+
|
|
21424
|
+
throw new Error('Unsupported document type');
|
|
20882
21425
|
}
|
|
20883
21426
|
|
|
20884
|
-
if (kind ===
|
|
21427
|
+
if (kind === 'go-to-page') {
|
|
20885
21428
|
const page = Math.max(1, payload.page || 1);
|
|
20886
|
-
if (currentType ===
|
|
21429
|
+
if (currentType === 'text') {
|
|
20887
21430
|
currentPage = page;
|
|
20888
21431
|
renderTextPage(page - 1);
|
|
20889
21432
|
sendState();
|
|
20890
|
-
} else if (currentType ===
|
|
21433
|
+
} else if (currentType === 'epub') {
|
|
20891
21434
|
await displayEpubPage(page - 1);
|
|
21435
|
+
} else if (currentType === 'comic') {
|
|
21436
|
+
currentPage = page;
|
|
21437
|
+
const target = comicPages[page - 1];
|
|
21438
|
+
if (target) {
|
|
21439
|
+
await ensureComicPage(page - 1);
|
|
21440
|
+
target.scrollIntoView({ block: 'start' });
|
|
21441
|
+
renderComicPage(page - 1);
|
|
21442
|
+
sendState();
|
|
21443
|
+
}
|
|
20892
21444
|
}
|
|
20893
21445
|
sendResponse(id, true, { currentPage });
|
|
20894
21446
|
return;
|
|
20895
21447
|
}
|
|
20896
21448
|
|
|
20897
|
-
if (kind ===
|
|
21449
|
+
if (kind === 'set-zoom') {
|
|
20898
21450
|
zoom = Math.max(0.5, Math.min(4.0, payload.zoom || 1.0));
|
|
20899
21451
|
applyZoom();
|
|
20900
21452
|
sendState();
|
|
@@ -20902,103 +21454,132 @@ https://github.com/nodeca/pako/blob/main/LICENSE
|
|
|
20902
21454
|
return;
|
|
20903
21455
|
}
|
|
20904
21456
|
|
|
20905
|
-
if (kind ===
|
|
21457
|
+
if (kind === 'set-rotation') {
|
|
21458
|
+
rotation = ((payload.rotation || 0) % 360 + 360) % 360;
|
|
21459
|
+
if (currentType === 'comic') applyComicLayout();
|
|
20906
21460
|
sendResponse(id, true, {});
|
|
20907
21461
|
return;
|
|
20908
21462
|
}
|
|
20909
21463
|
|
|
20910
|
-
if (kind ===
|
|
21464
|
+
if (kind === 'get-text-content') {
|
|
20911
21465
|
const items = await getTextContent(payload.pageIndex || 0);
|
|
20912
21466
|
sendResponse(id, true, items);
|
|
20913
21467
|
return;
|
|
20914
21468
|
}
|
|
20915
21469
|
|
|
20916
|
-
if (kind ===
|
|
20917
|
-
|
|
21470
|
+
if (kind === 'get-page-dimensions') {
|
|
21471
|
+
if (currentType === 'comic') {
|
|
21472
|
+
sendResponse(
|
|
21473
|
+
id,
|
|
21474
|
+
true,
|
|
21475
|
+
await getComicPageDimensions(payload.pageIndex || 0)
|
|
21476
|
+
);
|
|
21477
|
+
} else {
|
|
21478
|
+
sendResponse(id, true, getPageDimensions());
|
|
21479
|
+
}
|
|
21480
|
+
return;
|
|
21481
|
+
}
|
|
21482
|
+
|
|
21483
|
+
if (kind === 'get-page-preview') {
|
|
21484
|
+
if (currentType !== 'comic') {
|
|
21485
|
+
sendResponse(id, true, null);
|
|
21486
|
+
return;
|
|
21487
|
+
}
|
|
21488
|
+
sendResponse(
|
|
21489
|
+
id,
|
|
21490
|
+
true,
|
|
21491
|
+
await getComicPagePreview(payload.pageIndex || 0)
|
|
21492
|
+
);
|
|
20918
21493
|
return;
|
|
20919
21494
|
}
|
|
20920
21495
|
|
|
20921
|
-
if (kind ===
|
|
20922
|
-
const results = await searchText(payload.query ||
|
|
21496
|
+
if (kind === 'search-text') {
|
|
21497
|
+
const results = await searchText(payload.query || '');
|
|
20923
21498
|
sendResponse(id, true, results);
|
|
20924
21499
|
return;
|
|
20925
21500
|
}
|
|
20926
21501
|
|
|
20927
|
-
if (kind ===
|
|
21502
|
+
if (kind === 'select-text') {
|
|
20928
21503
|
const selection = await selectText(payload.pageIndex || 0);
|
|
20929
21504
|
sendResponse(id, true, selection);
|
|
20930
21505
|
return;
|
|
20931
21506
|
}
|
|
20932
21507
|
|
|
20933
|
-
if (kind ===
|
|
21508
|
+
if (kind === 'get-outline') {
|
|
20934
21509
|
const outline = await buildOutline();
|
|
20935
21510
|
sendResponse(id, true, outline);
|
|
20936
21511
|
return;
|
|
20937
21512
|
}
|
|
20938
21513
|
|
|
20939
|
-
if (kind ===
|
|
21514
|
+
if (kind === 'get-page-index') {
|
|
20940
21515
|
const index = getPageIndex(payload.dest);
|
|
20941
21516
|
sendResponse(id, true, index);
|
|
20942
21517
|
return;
|
|
20943
21518
|
}
|
|
20944
21519
|
|
|
20945
|
-
if (kind ===
|
|
21520
|
+
if (kind === 'destroy') {
|
|
20946
21521
|
clearViewer();
|
|
20947
21522
|
sendResponse(id, true, {});
|
|
20948
21523
|
return;
|
|
20949
21524
|
}
|
|
20950
21525
|
|
|
20951
|
-
sendResponse(id, false, null,
|
|
21526
|
+
sendResponse(id, false, null, 'Unknown command');
|
|
20952
21527
|
} catch (err) {
|
|
20953
|
-
sendResponse(
|
|
20954
|
-
id,
|
|
20955
|
-
false,
|
|
20956
|
-
null,
|
|
20957
|
-
err && err.message ? err.message : String(err)
|
|
20958
|
-
);
|
|
21528
|
+
sendResponse(id, false, null, err && err.message ? err.message : String(err));
|
|
20959
21529
|
}
|
|
20960
21530
|
};
|
|
20961
21531
|
|
|
20962
21532
|
const onMessage = (event) => {
|
|
20963
21533
|
let message = null;
|
|
20964
|
-
const raw = event && typeof event ===
|
|
21534
|
+
const raw = event && typeof event === 'object' ? event.data : null;
|
|
20965
21535
|
|
|
20966
|
-
if (raw && typeof raw ===
|
|
21536
|
+
if (raw && typeof raw === 'object' && (raw.kind || raw.type) && raw.id) {
|
|
20967
21537
|
message = raw;
|
|
20968
|
-
} else if (typeof raw ===
|
|
20969
|
-
if (raw.startsWith(
|
|
20970
|
-
return;
|
|
20971
|
-
}
|
|
21538
|
+
} else if (typeof raw === 'string') {
|
|
21539
|
+
if (raw.startsWith('setImmediate$')) return;
|
|
20972
21540
|
const trimmed = raw.trim();
|
|
20973
|
-
if (
|
|
20974
|
-
!trimmed ||
|
|
20975
|
-
(!trimmed.startsWith("{") && !trimmed.startsWith("["))
|
|
20976
|
-
) {
|
|
21541
|
+
if (!trimmed || (!trimmed.startsWith('{') && !trimmed.startsWith('['))) {
|
|
20977
21542
|
return;
|
|
20978
21543
|
}
|
|
20979
21544
|
try {
|
|
20980
21545
|
message = JSON.parse(trimmed);
|
|
20981
21546
|
} catch (err) {
|
|
20982
|
-
sendEvent("RUNTIME_ERROR", {
|
|
20983
|
-
message: "Failed to parse message",
|
|
20984
|
-
context: "runtime.onMessage",
|
|
20985
|
-
stack: err && err.stack ? err.stack : null,
|
|
20986
|
-
preview: trimmed.slice(0, 200),
|
|
20987
|
-
});
|
|
20988
21547
|
return;
|
|
20989
21548
|
}
|
|
20990
21549
|
} else {
|
|
20991
21550
|
return;
|
|
20992
21551
|
}
|
|
20993
21552
|
|
|
20994
|
-
|
|
20995
|
-
|
|
21553
|
+
if (!message || message.id == null) return;
|
|
21554
|
+
|
|
21555
|
+
if (message.type === 'asset-response') {
|
|
21556
|
+
const pending = runtimeAssetRequests.get(message.id);
|
|
21557
|
+
if (!pending) return;
|
|
21558
|
+
runtimeAssetRequests.delete(message.id);
|
|
21559
|
+
clearTimeout(pending.timeout);
|
|
21560
|
+
if (message.ok) pending.resolve(message.data);
|
|
21561
|
+
else pending.reject(new Error(message.error || 'Falha ao carregar asset CBR.'));
|
|
21562
|
+
return;
|
|
21563
|
+
}
|
|
21564
|
+
|
|
21565
|
+
if (message.type === 'file-chunk-response') {
|
|
21566
|
+
const pending = fileChunkRequests.get(message.id);
|
|
21567
|
+
if (!pending) return;
|
|
21568
|
+
fileChunkRequests.delete(message.id);
|
|
21569
|
+
clearTimeout(pending.timeout);
|
|
21570
|
+
if (message.ok) pending.resolve(message);
|
|
21571
|
+
else pending.reject(new Error(message.error || 'Falha ao ler arquivo local.'));
|
|
21572
|
+
return;
|
|
21573
|
+
}
|
|
21574
|
+
|
|
21575
|
+
if (!message.kind) return;
|
|
21576
|
+
handleCommand(message);
|
|
20996
21577
|
};
|
|
20997
21578
|
|
|
20998
|
-
window.addEventListener(
|
|
20999
|
-
document.addEventListener(
|
|
21579
|
+
window.addEventListener('message', onMessage);
|
|
21580
|
+
document.addEventListener('message', onMessage);
|
|
21000
21581
|
|
|
21001
|
-
sendMessage({ type:
|
|
21582
|
+
sendMessage({ type: 'ready' });
|
|
21002
21583
|
})();
|
|
21003
21584
|
</script>
|
|
21004
21585
|
</body>
|
|
@@ -21013,7 +21594,7 @@ import {
|
|
|
21013
21594
|
useRef as useRef4,
|
|
21014
21595
|
useEffect as useEffect4,
|
|
21015
21596
|
useCallback as useCallback3,
|
|
21016
|
-
useState as
|
|
21597
|
+
useState as useState4
|
|
21017
21598
|
} from "react";
|
|
21018
21599
|
import {
|
|
21019
21600
|
FlatList,
|
|
@@ -21036,6 +21617,7 @@ import {
|
|
|
21036
21617
|
} from "react";
|
|
21037
21618
|
import {
|
|
21038
21619
|
View,
|
|
21620
|
+
Text,
|
|
21039
21621
|
StyleSheet,
|
|
21040
21622
|
Pressable,
|
|
21041
21623
|
PanResponder,
|
|
@@ -21045,7 +21627,10 @@ import {
|
|
|
21045
21627
|
} from "react-native";
|
|
21046
21628
|
import { Gesture, GestureDetector } from "react-native-gesture-handler";
|
|
21047
21629
|
import Svg, { Path as SvgPath } from "react-native-svg";
|
|
21048
|
-
import { useViewerStore } from "@papyrus-sdk/core";
|
|
21630
|
+
import { papyrusEvents, useViewerStore } from "@papyrus-sdk/core";
|
|
21631
|
+
import {
|
|
21632
|
+
PapyrusEventType
|
|
21633
|
+
} from "@papyrus-sdk/types";
|
|
21049
21634
|
import {
|
|
21050
21635
|
PapyrusPageView
|
|
21051
21636
|
} from "@papyrus-sdk/engine-native";
|
|
@@ -21316,6 +21901,14 @@ var resolvePdfBasePageWidth = ({
|
|
|
21316
21901
|
horizontalPadding
|
|
21317
21902
|
}) => Math.max(0, viewportWidth - horizontalPadding * 2);
|
|
21318
21903
|
|
|
21904
|
+
// components/selectionEvent.ts
|
|
21905
|
+
var notifyTextSelection = (handler, payload) => {
|
|
21906
|
+
const text = payload.text.replace(/\s+/g, " ").trim();
|
|
21907
|
+
if (!text) return false;
|
|
21908
|
+
handler?.({ ...payload, text });
|
|
21909
|
+
return Boolean(handler);
|
|
21910
|
+
};
|
|
21911
|
+
|
|
21319
21912
|
// components/PageRenderer.tsx
|
|
21320
21913
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
21321
21914
|
var TEXT_MARKUP_TOOLS = /* @__PURE__ */ new Set([
|
|
@@ -21390,6 +21983,8 @@ var PageRenderer = ({
|
|
|
21390
21983
|
horizontalPadding = 16,
|
|
21391
21984
|
spacing = 24,
|
|
21392
21985
|
onSelectionDragActiveChange,
|
|
21986
|
+
onTextSelected,
|
|
21987
|
+
onDefineSelection,
|
|
21393
21988
|
gestureScrollLockActive = false,
|
|
21394
21989
|
lastPinchEndedAt = null,
|
|
21395
21990
|
requestSelectionVerticalAutoscroll
|
|
@@ -21735,6 +22330,17 @@ var PageRenderer = ({
|
|
|
21735
22330
|
return;
|
|
21736
22331
|
}
|
|
21737
22332
|
const selectedText = selection.text || "";
|
|
22333
|
+
const normalizedText = selectedText.replace(/\s+/g, " ").trim();
|
|
22334
|
+
if (normalizedText) {
|
|
22335
|
+
papyrusEvents.emit(PapyrusEventType.TEXT_SELECTED, {
|
|
22336
|
+
text: normalizedText,
|
|
22337
|
+
pageIndex
|
|
22338
|
+
});
|
|
22339
|
+
}
|
|
22340
|
+
notifyTextSelection(onTextSelected, {
|
|
22341
|
+
text: normalizedText,
|
|
22342
|
+
pageIndex
|
|
22343
|
+
});
|
|
21738
22344
|
logSelectionPerf("selection.ready", {
|
|
21739
22345
|
tool: activeTool,
|
|
21740
22346
|
sourceRectCount: selection.rects.length,
|
|
@@ -22670,6 +23276,20 @@ var PageRenderer = ({
|
|
|
22670
23276
|
}
|
|
22671
23277
|
],
|
|
22672
23278
|
children: [
|
|
23279
|
+
onDefineSelection ? /* @__PURE__ */ jsx(
|
|
23280
|
+
Pressable,
|
|
23281
|
+
{
|
|
23282
|
+
onPress: (event) => {
|
|
23283
|
+
stopPressPropagation(event);
|
|
23284
|
+
onDefineSelection({
|
|
23285
|
+
text: selectionText,
|
|
23286
|
+
pageIndex
|
|
23287
|
+
});
|
|
23288
|
+
},
|
|
23289
|
+
style: [styles.selectionAction, styles.defineSelectionAction],
|
|
23290
|
+
children: /* @__PURE__ */ jsx(Text, { style: styles.defineSelectionText, children: "Definir" })
|
|
23291
|
+
}
|
|
23292
|
+
) : null,
|
|
22673
23293
|
/* @__PURE__ */ jsx(
|
|
22674
23294
|
Pressable,
|
|
22675
23295
|
{
|
|
@@ -22969,6 +23589,15 @@ var styles = StyleSheet.create({
|
|
|
22969
23589
|
justifyContent: "center",
|
|
22970
23590
|
marginRight: 10
|
|
22971
23591
|
},
|
|
23592
|
+
defineSelectionAction: {
|
|
23593
|
+
width: 58,
|
|
23594
|
+
paddingHorizontal: 6
|
|
23595
|
+
},
|
|
23596
|
+
defineSelectionText: {
|
|
23597
|
+
color: "#FFFFFF",
|
|
23598
|
+
fontSize: 11,
|
|
23599
|
+
fontWeight: "700"
|
|
23600
|
+
},
|
|
22972
23601
|
selectionActionLast: {
|
|
22973
23602
|
marginRight: 0
|
|
22974
23603
|
},
|
|
@@ -23000,37 +23629,108 @@ var styles = StyleSheet.create({
|
|
|
23000
23629
|
borderRadius: 3
|
|
23001
23630
|
}
|
|
23002
23631
|
});
|
|
23003
|
-
var arePageRendererPropsEqual = (previous, next) => previous.engine === next.engine && previous.pageIndex === next.pageIndex && previous.scale === next.scale && previous.PageViewComponent === next.PageViewComponent && previous.availableWidth === next.availableWidth && 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;
|
|
23632
|
+
var arePageRendererPropsEqual = (previous, next) => previous.engine === next.engine && previous.pageIndex === next.pageIndex && previous.scale === next.scale && previous.PageViewComponent === next.PageViewComponent && previous.availableWidth === next.availableWidth && previous.pageViewportWidth === next.pageViewportWidth && previous.horizontalPadding === next.horizontalPadding && previous.spacing === next.spacing && previous.onSelectionDragActiveChange === next.onSelectionDragActiveChange && previous.onTextSelected === next.onTextSelected && previous.onDefineSelection === next.onDefineSelection && previous.gestureScrollLockActive === next.gestureScrollLockActive && previous.lastPinchEndedAt === next.lastPinchEndedAt && previous.requestSelectionVerticalAutoscroll === next.requestSelectionVerticalAutoscroll;
|
|
23004
23633
|
var PageRenderer_default = memo(PageRenderer, arePageRendererPropsEqual);
|
|
23005
23634
|
|
|
23006
23635
|
// components/WebViewViewer.tsx
|
|
23007
|
-
import { useEffect as useEffect2, useMemo as useMemo2, useRef as useRef2 } from "react";
|
|
23636
|
+
import { useEffect as useEffect2, useMemo as useMemo2, useRef as useRef2, useState as useState2 } from "react";
|
|
23008
23637
|
import { Image, StyleSheet as StyleSheet2, View as View2 } from "react-native";
|
|
23009
23638
|
import WebView from "react-native-webview";
|
|
23010
23639
|
import { useViewerStore as useViewerStore2 } from "@papyrus-sdk/core";
|
|
23640
|
+
|
|
23641
|
+
// components/webViewState.ts
|
|
23642
|
+
var parseWebViewState = (raw) => {
|
|
23643
|
+
try {
|
|
23644
|
+
const message = JSON.parse(raw);
|
|
23645
|
+
if (!message || typeof message !== "object") return null;
|
|
23646
|
+
const typedMessage = message;
|
|
23647
|
+
if (typedMessage.type !== "state") return null;
|
|
23648
|
+
if (!typedMessage.payload || typeof typedMessage.payload !== "object") {
|
|
23649
|
+
return null;
|
|
23650
|
+
}
|
|
23651
|
+
const payload = typedMessage.payload;
|
|
23652
|
+
const update = {};
|
|
23653
|
+
if (typeof payload.currentPage === "number" && Number.isInteger(payload.currentPage) && payload.currentPage >= 1) {
|
|
23654
|
+
update.currentPage = payload.currentPage;
|
|
23655
|
+
}
|
|
23656
|
+
if (typeof payload.pageCount === "number" && Number.isInteger(payload.pageCount) && payload.pageCount >= 0) {
|
|
23657
|
+
update.pageCount = payload.pageCount;
|
|
23658
|
+
}
|
|
23659
|
+
return Object.keys(update).length > 0 ? update : null;
|
|
23660
|
+
} catch {
|
|
23661
|
+
return null;
|
|
23662
|
+
}
|
|
23663
|
+
};
|
|
23664
|
+
|
|
23665
|
+
// components/WebViewViewer.tsx
|
|
23011
23666
|
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
23012
23667
|
var runtimeAsset = require_runtime();
|
|
23013
|
-
var
|
|
23014
|
-
if (typeof
|
|
23015
|
-
return { html:
|
|
23668
|
+
var resolveRuntimeSource = (asset) => {
|
|
23669
|
+
if (typeof asset === "string") {
|
|
23670
|
+
return { html: asset };
|
|
23016
23671
|
}
|
|
23017
|
-
if (typeof
|
|
23018
|
-
const resolved = Image.resolveAssetSource(
|
|
23672
|
+
if (typeof asset === "number") {
|
|
23673
|
+
const resolved = Image.resolveAssetSource(asset);
|
|
23019
23674
|
if (resolved?.uri) {
|
|
23020
23675
|
return { uri: resolved.uri };
|
|
23021
23676
|
}
|
|
23022
23677
|
}
|
|
23023
|
-
if (
|
|
23024
|
-
const uri =
|
|
23678
|
+
if (asset && typeof asset === "object" && "uri" in asset) {
|
|
23679
|
+
const uri = asset.uri;
|
|
23025
23680
|
if (uri) return { uri };
|
|
23026
23681
|
}
|
|
23027
23682
|
return { html: "" };
|
|
23028
|
-
}
|
|
23683
|
+
};
|
|
23029
23684
|
var WebViewViewer = ({ engine }) => {
|
|
23030
23685
|
const webViewRef = useRef2(null);
|
|
23031
23686
|
const { pageTheme } = useViewerStore2();
|
|
23687
|
+
const bridgeEngine = engine;
|
|
23688
|
+
const runtimeSource = useMemo2(
|
|
23689
|
+
() => resolveRuntimeSource(
|
|
23690
|
+
bridgeEngine.getWebViewRuntimeSource?.() ?? runtimeAsset
|
|
23691
|
+
),
|
|
23692
|
+
[bridgeEngine]
|
|
23693
|
+
);
|
|
23694
|
+
const [runtimeHtml, setRuntimeHtml] = useState2(null);
|
|
23695
|
+
useEffect2(() => {
|
|
23696
|
+
let active = true;
|
|
23697
|
+
if ("html" in runtimeSource) {
|
|
23698
|
+
setRuntimeHtml(runtimeSource.html);
|
|
23699
|
+
return () => {
|
|
23700
|
+
active = false;
|
|
23701
|
+
};
|
|
23702
|
+
}
|
|
23703
|
+
setRuntimeHtml(null);
|
|
23704
|
+
void fetch(runtimeSource.uri).then((response) => {
|
|
23705
|
+
if (!response.ok) throw new Error(`status ${response.status}`);
|
|
23706
|
+
return response.text();
|
|
23707
|
+
}).then((html) => {
|
|
23708
|
+
if (active) setRuntimeHtml(html);
|
|
23709
|
+
}).catch(() => {
|
|
23710
|
+
if (active) setRuntimeHtml(null);
|
|
23711
|
+
});
|
|
23712
|
+
return () => {
|
|
23713
|
+
active = false;
|
|
23714
|
+
};
|
|
23715
|
+
}, [runtimeSource]);
|
|
23716
|
+
const webViewSource = useMemo2(() => {
|
|
23717
|
+
if (runtimeHtml !== null) {
|
|
23718
|
+
return {
|
|
23719
|
+
html: runtimeHtml,
|
|
23720
|
+
baseUrl: "http://localhost:3005/"
|
|
23721
|
+
};
|
|
23722
|
+
}
|
|
23723
|
+
if ("uri" in runtimeSource) return { html: "" };
|
|
23724
|
+
return runtimeSource;
|
|
23725
|
+
}, [runtimeHtml, runtimeSource]);
|
|
23726
|
+
const runtimeConfig = bridgeEngine.getWebViewRuntimeConfig?.();
|
|
23727
|
+
const runtimeConfigScript = useMemo2(() => {
|
|
23728
|
+
if (!runtimeConfig) return void 0;
|
|
23729
|
+
return `window.__PAPYRUS_RUNTIME_CONFIG__=${JSON.stringify(
|
|
23730
|
+
runtimeConfig
|
|
23731
|
+
)};true;`;
|
|
23732
|
+
}, [runtimeConfig]);
|
|
23032
23733
|
useEffect2(() => {
|
|
23033
|
-
const bridgeEngine = engine;
|
|
23034
23734
|
bridgeEngine.attachWebView?.({
|
|
23035
23735
|
postMessage: (message) => {
|
|
23036
23736
|
if (__DEV__) {
|
|
@@ -23040,9 +23740,22 @@ var WebViewViewer = ({ engine }) => {
|
|
|
23040
23740
|
webViewRef.current?.postMessage(message);
|
|
23041
23741
|
}
|
|
23042
23742
|
});
|
|
23043
|
-
}, [
|
|
23743
|
+
}, [bridgeEngine]);
|
|
23044
23744
|
const handleMessage = (event) => {
|
|
23045
|
-
const
|
|
23745
|
+
const state = parseWebViewState(event.nativeEvent.data);
|
|
23746
|
+
if (state) {
|
|
23747
|
+
const viewerState = useViewerStore2.getState();
|
|
23748
|
+
const nextState = {};
|
|
23749
|
+
if (state.currentPage !== void 0 && state.currentPage !== viewerState.currentPage) {
|
|
23750
|
+
nextState.currentPage = state.currentPage;
|
|
23751
|
+
}
|
|
23752
|
+
if (state.pageCount !== void 0 && state.pageCount !== viewerState.pageCount) {
|
|
23753
|
+
nextState.pageCount = state.pageCount;
|
|
23754
|
+
}
|
|
23755
|
+
if (Object.keys(nextState).length > 0) {
|
|
23756
|
+
viewerState.setDocumentState(nextState);
|
|
23757
|
+
}
|
|
23758
|
+
}
|
|
23046
23759
|
if (__DEV__) {
|
|
23047
23760
|
console.log("[Papyrus WebView] message", event.nativeEvent.data);
|
|
23048
23761
|
}
|
|
@@ -23082,11 +23795,12 @@ var WebViewViewer = ({ engine }) => {
|
|
|
23082
23795
|
WebView,
|
|
23083
23796
|
{
|
|
23084
23797
|
ref: webViewRef,
|
|
23085
|
-
source:
|
|
23798
|
+
source: webViewSource,
|
|
23086
23799
|
originWhitelist: ["*"],
|
|
23087
23800
|
onMessage: handleMessage,
|
|
23088
23801
|
onLoadEnd: handleLoadEnd,
|
|
23089
23802
|
onError: handleError,
|
|
23803
|
+
injectedJavaScriptBeforeContentLoaded: runtimeConfigScript,
|
|
23090
23804
|
javaScriptEnabled: true,
|
|
23091
23805
|
domStorageEnabled: true,
|
|
23092
23806
|
scalesPageToFit: true,
|
|
@@ -23136,7 +23850,7 @@ var styles2 = StyleSheet2.create({
|
|
|
23136
23850
|
var WebViewViewer_default = WebViewViewer;
|
|
23137
23851
|
|
|
23138
23852
|
// components/DedicatedAndroidPdfViewer.tsx
|
|
23139
|
-
import { useCallback as useCallback2, useEffect as useEffect3, useRef as useRef3, useState as
|
|
23853
|
+
import { useCallback as useCallback2, useEffect as useEffect3, useRef as useRef3, useState as useState3 } from "react";
|
|
23140
23854
|
import { Pressable as Pressable2, StyleSheet as StyleSheet3, View as View3 } from "react-native";
|
|
23141
23855
|
import { useViewerStore as useViewerStore3 } from "@papyrus-sdk/core";
|
|
23142
23856
|
import { PapyrusPdfDocumentView } from "@papyrus-sdk/engine-native";
|
|
@@ -23782,7 +24496,7 @@ function DedicatedAndroidPdfViewer({
|
|
|
23782
24496
|
const addAnnotation = useViewerStore3((state) => state.addAnnotation);
|
|
23783
24497
|
const setSelectedAnnotation = useViewerStore3((state) => state.setSelectedAnnotation);
|
|
23784
24498
|
const engineId = getDedicatedAndroidPdfEngineId(engine);
|
|
23785
|
-
const [selection, setSelection] =
|
|
24499
|
+
const [selection, setSelection] = useState3(null);
|
|
23786
24500
|
const selectionRef = useRef3(null);
|
|
23787
24501
|
const lastVisiblePagesKeyRef = useRef3("");
|
|
23788
24502
|
const lastScrollOffsetYRef = useRef3(0);
|
|
@@ -24078,7 +24792,9 @@ var Viewer = ({
|
|
|
24078
24792
|
maxToRenderPerBatch,
|
|
24079
24793
|
removeClippedSubviews,
|
|
24080
24794
|
useDedicatedAndroidPdfViewer,
|
|
24081
|
-
viewerMode
|
|
24795
|
+
viewerMode,
|
|
24796
|
+
onTextSelected,
|
|
24797
|
+
onDefineSelection
|
|
24082
24798
|
}) => {
|
|
24083
24799
|
const pageCount = useViewerStore4((state) => state.pageCount);
|
|
24084
24800
|
const currentPage = useViewerStore4((state) => state.currentPage);
|
|
@@ -24135,13 +24851,13 @@ var Viewer = ({
|
|
|
24135
24851
|
const lastScrollOffsetYRef = useRef4(0);
|
|
24136
24852
|
const scrollDownAccumRef = useRef4(0);
|
|
24137
24853
|
const scrollUpAccumRef = useRef4(0);
|
|
24138
|
-
const [layoutRevision, setLayoutRevision] =
|
|
24139
|
-
const [selectionDragActive, setSelectionDragActive] =
|
|
24854
|
+
const [layoutRevision, setLayoutRevision] = useState4(0);
|
|
24855
|
+
const [selectionDragActive, setSelectionDragActive] = useState4(false);
|
|
24140
24856
|
const selectionDragActiveRef = useRef4(false);
|
|
24141
|
-
const [gestureScrollLockActive, setGestureScrollLockActive] =
|
|
24857
|
+
const [gestureScrollLockActive, setGestureScrollLockActive] = useState4(false);
|
|
24142
24858
|
const gestureScrollLockActiveRef = useRef4(false);
|
|
24143
|
-
const [pinchPreviewScale, setPinchPreviewScale] =
|
|
24144
|
-
const [lastPinchEndedAt, setLastPinchEndedAt] =
|
|
24859
|
+
const [pinchPreviewScale, setPinchPreviewScale] = useState4(1);
|
|
24860
|
+
const [lastPinchEndedAt, setLastPinchEndedAt] = useState4(null);
|
|
24145
24861
|
const pinchGestureActiveRef = useRef4(false);
|
|
24146
24862
|
const pinchStartZoomRef = useRef4(1);
|
|
24147
24863
|
const pinchPreviewZoomRef = useRef4(1);
|
|
@@ -25214,6 +25930,8 @@ var Viewer = ({
|
|
|
25214
25930
|
pageViewportWidth: columnWidth,
|
|
25215
25931
|
spacing: DOUBLE_PAGE_SPACING,
|
|
25216
25932
|
onSelectionDragActiveChange: setSelectionDragActive,
|
|
25933
|
+
onTextSelected,
|
|
25934
|
+
onDefineSelection,
|
|
25217
25935
|
gestureScrollLockActive,
|
|
25218
25936
|
lastPinchEndedAt,
|
|
25219
25937
|
requestSelectionVerticalAutoscroll: handleSelectionVerticalAutoscroll
|
|
@@ -25230,6 +25948,8 @@ var Viewer = ({
|
|
|
25230
25948
|
pageViewportWidth: columnWidth,
|
|
25231
25949
|
spacing: DOUBLE_PAGE_SPACING,
|
|
25232
25950
|
onSelectionDragActiveChange: setSelectionDragActive,
|
|
25951
|
+
onTextSelected,
|
|
25952
|
+
onDefineSelection,
|
|
25233
25953
|
gestureScrollLockActive,
|
|
25234
25954
|
lastPinchEndedAt,
|
|
25235
25955
|
requestSelectionVerticalAutoscroll: handleSelectionVerticalAutoscroll
|
|
@@ -25249,6 +25969,8 @@ var Viewer = ({
|
|
|
25249
25969
|
pageViewportWidth: documentSurfaceWidth,
|
|
25250
25970
|
spacing: CONTINUOUS_PAGE_SPACING,
|
|
25251
25971
|
onSelectionDragActiveChange: setSelectionDragActive,
|
|
25972
|
+
onTextSelected,
|
|
25973
|
+
onDefineSelection,
|
|
25252
25974
|
gestureScrollLockActive,
|
|
25253
25975
|
lastPinchEndedAt,
|
|
25254
25976
|
requestSelectionVerticalAutoscroll: handleSelectionVerticalAutoscroll
|
|
@@ -25338,6 +26060,8 @@ var Viewer = ({
|
|
|
25338
26060
|
pageViewportWidth: documentSurfaceWidth,
|
|
25339
26061
|
spacing: 32,
|
|
25340
26062
|
onSelectionDragActiveChange: setSelectionDragActive,
|
|
26063
|
+
onTextSelected,
|
|
26064
|
+
onDefineSelection,
|
|
25341
26065
|
gestureScrollLockActive,
|
|
25342
26066
|
lastPinchEndedAt,
|
|
25343
26067
|
requestSelectionVerticalAutoscroll: handleSelectionVerticalAutoscroll
|
|
@@ -25474,8 +26198,8 @@ var styles4 = StyleSheet4.create({
|
|
|
25474
26198
|
var Viewer_default = Viewer;
|
|
25475
26199
|
|
|
25476
26200
|
// components/Topbar.tsx
|
|
25477
|
-
import { useState as
|
|
25478
|
-
import { View as View6, Text as
|
|
26201
|
+
import { useState as useState6 } from "react";
|
|
26202
|
+
import { View as View6, Text as Text3, Pressable as Pressable4, StyleSheet as StyleSheet6, useWindowDimensions as useWindowDimensions3 } from "react-native";
|
|
25479
26203
|
import { useViewerStore as useViewerStore5 } from "@papyrus-sdk/core";
|
|
25480
26204
|
|
|
25481
26205
|
// components/mobileChromeMetrics.ts
|
|
@@ -25497,8 +26221,8 @@ var MOBILE_CHROME_METRICS = {
|
|
|
25497
26221
|
};
|
|
25498
26222
|
|
|
25499
26223
|
// components/PageJumpModal.tsx
|
|
25500
|
-
import { useEffect as useEffect5, useState as
|
|
25501
|
-
import { Modal, Pressable as Pressable3, StyleSheet as StyleSheet5, Text, TextInput, View as View5 } from "react-native";
|
|
26224
|
+
import { useEffect as useEffect5, useState as useState5 } from "react";
|
|
26225
|
+
import { Modal, Pressable as Pressable3, StyleSheet as StyleSheet5, Text as Text2, TextInput, View as View5 } from "react-native";
|
|
25502
26226
|
|
|
25503
26227
|
// components/pageJumpModel.ts
|
|
25504
26228
|
var resolvePageJumpTarget = (value, pageCount) => {
|
|
@@ -25519,7 +26243,7 @@ function PageJumpModal({
|
|
|
25519
26243
|
onClose,
|
|
25520
26244
|
onConfirm
|
|
25521
26245
|
}) {
|
|
25522
|
-
const [value, setValue] =
|
|
26246
|
+
const [value, setValue] = useState5(`${currentPage}`);
|
|
25523
26247
|
useEffect5(() => {
|
|
25524
26248
|
if (visible) setValue(`${currentPage}`);
|
|
25525
26249
|
}, [currentPage, visible]);
|
|
@@ -25541,7 +26265,7 @@ function PageJumpModal({
|
|
|
25541
26265
|
style: [styles5.card, isDark && styles5.cardDark],
|
|
25542
26266
|
onPress: (event) => event.stopPropagation(),
|
|
25543
26267
|
children: [
|
|
25544
|
-
/* @__PURE__ */ jsx6(
|
|
26268
|
+
/* @__PURE__ */ jsx6(Text2, { style: [styles5.title, isDark && styles5.titleDark], children: "Ir para pagina" }),
|
|
25545
26269
|
/* @__PURE__ */ jsx6(
|
|
25546
26270
|
TextInput,
|
|
25547
26271
|
{
|
|
@@ -25568,7 +26292,7 @@ function PageJumpModal({
|
|
|
25568
26292
|
styles5.actionCancel,
|
|
25569
26293
|
isDark && styles5.actionCancelDark
|
|
25570
26294
|
],
|
|
25571
|
-
children: /* @__PURE__ */ jsx6(
|
|
26295
|
+
children: /* @__PURE__ */ jsx6(Text2, { style: [styles5.actionText, isDark && styles5.actionTextDark], children: "Cancelar" })
|
|
25572
26296
|
}
|
|
25573
26297
|
),
|
|
25574
26298
|
/* @__PURE__ */ jsx6(
|
|
@@ -25576,7 +26300,7 @@ function PageJumpModal({
|
|
|
25576
26300
|
{
|
|
25577
26301
|
onPress: confirmJump,
|
|
25578
26302
|
style: [styles5.actionButton, { backgroundColor: accentColor }],
|
|
25579
|
-
children: /* @__PURE__ */ jsx6(
|
|
26303
|
+
children: /* @__PURE__ */ jsx6(Text2, { style: [styles5.actionText, styles5.actionTextPrimary], children: "Ir" })
|
|
25580
26304
|
}
|
|
25581
26305
|
)
|
|
25582
26306
|
] })
|
|
@@ -25680,7 +26404,7 @@ var Topbar = ({
|
|
|
25680
26404
|
accentColor,
|
|
25681
26405
|
mobileChromeVisible
|
|
25682
26406
|
} = useViewerStore5();
|
|
25683
|
-
const [jumpModalOpen, setJumpModalOpen] =
|
|
26407
|
+
const [jumpModalOpen, setJumpModalOpen] = useState6(false);
|
|
25684
26408
|
const isDark = uiTheme === "dark";
|
|
25685
26409
|
const navIconColor = isDark ? "#e5e7eb" : "#111827";
|
|
25686
26410
|
const { width, height } = useWindowDimensions3();
|
|
@@ -25701,7 +26425,7 @@ var Topbar = ({
|
|
|
25701
26425
|
}
|
|
25702
26426
|
setJumpModalOpen(true);
|
|
25703
26427
|
};
|
|
25704
|
-
const defaultLogo = /* @__PURE__ */ jsx7(View6, { style: [styles6.logoBadge, { backgroundColor: accentColor }], children: /* @__PURE__ */ jsx7(
|
|
26428
|
+
const defaultLogo = /* @__PURE__ */ jsx7(View6, { style: [styles6.logoBadge, { backgroundColor: accentColor }], children: /* @__PURE__ */ jsx7(Text3, { style: styles6.logoText, children: "P" }) });
|
|
25705
26429
|
const logoElement = logo ?? defaultLogo;
|
|
25706
26430
|
if (!mobileChromeVisible) return null;
|
|
25707
26431
|
return /* @__PURE__ */ jsxs7(Fragment2, { children: [
|
|
@@ -25731,7 +26455,7 @@ var Topbar = ({
|
|
|
25731
26455
|
style: styles6.titleHit,
|
|
25732
26456
|
accessibilityLabel: "Open page jump",
|
|
25733
26457
|
children: /* @__PURE__ */ jsx7(
|
|
25734
|
-
|
|
26458
|
+
Text3,
|
|
25735
26459
|
{
|
|
25736
26460
|
numberOfLines: 1,
|
|
25737
26461
|
style: [styles6.brandText, isDark && styles6.brandTextDark],
|
|
@@ -25763,7 +26487,7 @@ var Topbar = ({
|
|
|
25763
26487
|
style: styles6.pageIndicatorHit,
|
|
25764
26488
|
accessibilityLabel: "Page jump",
|
|
25765
26489
|
children: /* @__PURE__ */ jsxs7(
|
|
25766
|
-
|
|
26490
|
+
Text3,
|
|
25767
26491
|
{
|
|
25768
26492
|
style: [
|
|
25769
26493
|
styles6.pageIndicator,
|
|
@@ -25983,10 +26707,10 @@ var styles6 = StyleSheet6.create({
|
|
|
25983
26707
|
var Topbar_default = Topbar;
|
|
25984
26708
|
|
|
25985
26709
|
// components/ToolDock.tsx
|
|
25986
|
-
import React7, { useEffect as useEffect6, useMemo as useMemo4, useRef as useRef5, useState as
|
|
26710
|
+
import React7, { useEffect as useEffect6, useMemo as useMemo4, useRef as useRef5, useState as useState7 } from "react";
|
|
25987
26711
|
import {
|
|
25988
26712
|
View as View7,
|
|
25989
|
-
Text as
|
|
26713
|
+
Text as Text4,
|
|
25990
26714
|
Pressable as Pressable5,
|
|
25991
26715
|
StyleSheet as StyleSheet7,
|
|
25992
26716
|
ScrollView as ScrollView2,
|
|
@@ -26221,8 +26945,8 @@ var OpacitySlider = React7.memo(function OpacitySlider2({
|
|
|
26221
26945
|
isDark,
|
|
26222
26946
|
onCommit
|
|
26223
26947
|
}) {
|
|
26224
|
-
const [trackWidth, setTrackWidth] =
|
|
26225
|
-
const [draftValue, setDraftValue] =
|
|
26948
|
+
const [trackWidth, setTrackWidth] = useState7(0);
|
|
26949
|
+
const [draftValue, setDraftValue] = useState7(value);
|
|
26226
26950
|
const dragValueRef = useRef5(draftValue);
|
|
26227
26951
|
const isDraggingRef = useRef5(false);
|
|
26228
26952
|
const frameRef = useRef5(null);
|
|
@@ -26331,8 +27055,8 @@ var ToolDock = () => {
|
|
|
26331
27055
|
undoAnnotations,
|
|
26332
27056
|
redoAnnotations
|
|
26333
27057
|
} = useViewerStore6();
|
|
26334
|
-
const [paletteExpanded, setPaletteExpanded] =
|
|
26335
|
-
const [extrasExpanded, setExtrasExpanded] =
|
|
27058
|
+
const [paletteExpanded, setPaletteExpanded] = useState7(false);
|
|
27059
|
+
const [extrasExpanded, setExtrasExpanded] = useState7(false);
|
|
26336
27060
|
const isDark = uiTheme === "dark";
|
|
26337
27061
|
const { width: windowWidth } = useWindowDimensions4();
|
|
26338
27062
|
const t = getStrings(locale);
|
|
@@ -26640,7 +27364,7 @@ var ToolDock = () => {
|
|
|
26640
27364
|
}
|
|
26641
27365
|
],
|
|
26642
27366
|
children: /* @__PURE__ */ jsx8(
|
|
26643
|
-
|
|
27367
|
+
Text4,
|
|
26644
27368
|
{
|
|
26645
27369
|
style: [
|
|
26646
27370
|
styles7.utilityLabel,
|
|
@@ -26756,7 +27480,7 @@ var ToolDock = () => {
|
|
|
26756
27480
|
}
|
|
26757
27481
|
],
|
|
26758
27482
|
children: /* @__PURE__ */ jsx8(
|
|
26759
|
-
|
|
27483
|
+
Text4,
|
|
26760
27484
|
{
|
|
26761
27485
|
style: [
|
|
26762
27486
|
styles7.utilityLabel,
|
|
@@ -27055,13 +27779,14 @@ var withInkAlpha = (hex, alpha) => {
|
|
|
27055
27779
|
var ToolDock_default = ToolDock;
|
|
27056
27780
|
|
|
27057
27781
|
// components/RightSheet.tsx
|
|
27058
|
-
import { useCallback as useCallback4, useEffect as useEffect7, useMemo as useMemo5, useRef as useRef6, useState as
|
|
27782
|
+
import { useCallback as useCallback4, useEffect as useEffect7, useMemo as useMemo5, useRef as useRef6, useState as useState8 } from "react";
|
|
27059
27783
|
import {
|
|
27060
27784
|
Dimensions,
|
|
27785
|
+
Image as Image2,
|
|
27061
27786
|
Platform as Platform3,
|
|
27062
27787
|
Pressable as Pressable7,
|
|
27063
27788
|
StyleSheet as StyleSheet9,
|
|
27064
|
-
Text as
|
|
27789
|
+
Text as Text6,
|
|
27065
27790
|
UIManager,
|
|
27066
27791
|
View as View9,
|
|
27067
27792
|
findNodeHandle as findNodeHandle2
|
|
@@ -27082,7 +27807,7 @@ import {
|
|
|
27082
27807
|
Pressable as Pressable6,
|
|
27083
27808
|
ScrollView as ScrollView3,
|
|
27084
27809
|
StyleSheet as StyleSheet8,
|
|
27085
|
-
Text as
|
|
27810
|
+
Text as Text5,
|
|
27086
27811
|
View as View8
|
|
27087
27812
|
} from "react-native";
|
|
27088
27813
|
import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
@@ -27138,7 +27863,7 @@ function NativeSheet({
|
|
|
27138
27863
|
}
|
|
27139
27864
|
),
|
|
27140
27865
|
/* @__PURE__ */ jsx9(
|
|
27141
|
-
|
|
27866
|
+
Text5,
|
|
27142
27867
|
{
|
|
27143
27868
|
style: [styles8.title, isDark && styles8.titleDark],
|
|
27144
27869
|
numberOfLines: 1,
|
|
@@ -27248,11 +27973,13 @@ var PageThumbnail = ({
|
|
|
27248
27973
|
frameHeight,
|
|
27249
27974
|
accentColor,
|
|
27250
27975
|
useNativePreview,
|
|
27976
|
+
useImagePreview,
|
|
27251
27977
|
shouldRenderPreview,
|
|
27252
27978
|
onPress
|
|
27253
27979
|
}) => {
|
|
27254
27980
|
const viewRef = useRef6(null);
|
|
27255
|
-
const [layoutReady, setLayoutReady] =
|
|
27981
|
+
const [layoutReady, setLayoutReady] = useState8(false);
|
|
27982
|
+
const [previewUri, setPreviewUri] = useState8(null);
|
|
27256
27983
|
useEffect7(() => {
|
|
27257
27984
|
if (!layoutReady || !useNativePreview || !shouldRenderPreview) return;
|
|
27258
27985
|
const viewTag = findNodeHandle2(viewRef.current);
|
|
@@ -27268,6 +27995,24 @@ var PageThumbnail = ({
|
|
|
27268
27995
|
useNativePreview,
|
|
27269
27996
|
zoom
|
|
27270
27997
|
]);
|
|
27998
|
+
useEffect7(() => {
|
|
27999
|
+
if (!useImagePreview || !shouldRenderPreview) {
|
|
28000
|
+
setPreviewUri(null);
|
|
28001
|
+
return;
|
|
28002
|
+
}
|
|
28003
|
+
let active = true;
|
|
28004
|
+
const previewEngine = engine;
|
|
28005
|
+
const request = previewEngine.getPagePreview?.(pageIndex);
|
|
28006
|
+
if (!request) return;
|
|
28007
|
+
void request.then((uri) => {
|
|
28008
|
+
if (active) setPreviewUri(uri);
|
|
28009
|
+
}).catch(() => {
|
|
28010
|
+
if (active) setPreviewUri(null);
|
|
28011
|
+
});
|
|
28012
|
+
return () => {
|
|
28013
|
+
active = false;
|
|
28014
|
+
};
|
|
28015
|
+
}, [engine, pageIndex, shouldRenderPreview, useImagePreview]);
|
|
27271
28016
|
const handleLayout = (event) => {
|
|
27272
28017
|
if (event.nativeEvent.layout.width && event.nativeEvent.layout.height) {
|
|
27273
28018
|
setLayoutReady(true);
|
|
@@ -27290,8 +28035,15 @@ var PageThumbnail = ({
|
|
|
27290
28035
|
{
|
|
27291
28036
|
onLayout: handleLayout,
|
|
27292
28037
|
style: [styles9.thumbFrame, { width: frameWidth, height: frameHeight }],
|
|
27293
|
-
children: useNativePreview && shouldRenderPreview ? /* @__PURE__ */ jsx10(PapyrusPageView2, { ref: viewRef, style: styles9.thumbView }) :
|
|
27294
|
-
|
|
28038
|
+
children: useNativePreview && shouldRenderPreview ? /* @__PURE__ */ jsx10(PapyrusPageView2, { ref: viewRef, style: styles9.thumbView }) : useImagePreview && shouldRenderPreview && previewUri ? /* @__PURE__ */ jsx10(
|
|
28039
|
+
Image2,
|
|
28040
|
+
{
|
|
28041
|
+
source: { uri: previewUri },
|
|
28042
|
+
resizeMode: "contain",
|
|
28043
|
+
style: styles9.thumbImage
|
|
28044
|
+
}
|
|
28045
|
+
) : /* @__PURE__ */ jsx10(View9, { style: [styles9.thumbFallback, isDark && styles9.thumbFallbackDark], children: /* @__PURE__ */ jsx10(
|
|
28046
|
+
Text6,
|
|
27295
28047
|
{
|
|
27296
28048
|
style: [
|
|
27297
28049
|
styles9.thumbFallbackText,
|
|
@@ -27302,7 +28054,7 @@ var PageThumbnail = ({
|
|
|
27302
28054
|
) })
|
|
27303
28055
|
}
|
|
27304
28056
|
),
|
|
27305
|
-
/* @__PURE__ */ jsx10(
|
|
28057
|
+
/* @__PURE__ */ jsx10(Text6, { style: [styles9.thumbLabel, isDark && styles9.thumbLabelDark], children: pageIndex + 1 })
|
|
27306
28058
|
]
|
|
27307
28059
|
}
|
|
27308
28060
|
);
|
|
@@ -27319,7 +28071,7 @@ var OutlineNode = ({ item, depth = 0, isDark, onSelect, untitledLabel }) => {
|
|
|
27319
28071
|
},
|
|
27320
28072
|
style: [styles9.outlineRow, { paddingLeft: 12 + depth * 12 }],
|
|
27321
28073
|
children: /* @__PURE__ */ jsx10(
|
|
27322
|
-
|
|
28074
|
+
Text6,
|
|
27323
28075
|
{
|
|
27324
28076
|
style: [
|
|
27325
28077
|
styles9.outlineText,
|
|
@@ -27367,9 +28119,14 @@ var RightSheet = ({
|
|
|
27367
28119
|
locale,
|
|
27368
28120
|
accentColor
|
|
27369
28121
|
} = useViewerStore7();
|
|
27370
|
-
const [pagesMode, setPagesMode] =
|
|
27371
|
-
documentType === "pdf" ? "thumbnails" : "summary"
|
|
28122
|
+
const [pagesMode, setPagesMode] = useState8(
|
|
28123
|
+
documentType === "pdf" || documentType === "comic" ? "thumbnails" : "summary"
|
|
27372
28124
|
);
|
|
28125
|
+
useEffect7(() => {
|
|
28126
|
+
setPagesMode(
|
|
28127
|
+
documentType === "pdf" || documentType === "comic" ? "thumbnails" : "summary"
|
|
28128
|
+
);
|
|
28129
|
+
}, [documentType]);
|
|
27373
28130
|
const isDark = uiTheme === "dark";
|
|
27374
28131
|
const t = getStrings(locale);
|
|
27375
28132
|
const showingNotes = sidebarRightTab === "annotations";
|
|
@@ -27387,11 +28144,12 @@ var RightSheet = ({
|
|
|
27387
28144
|
UIManager.getViewManagerConfig?.("PapyrusPageView")
|
|
27388
28145
|
);
|
|
27389
28146
|
const useNativePreview = renderTarget !== "webview" && hasNativePageView;
|
|
28147
|
+
const useImagePreview = documentType === "comic" && renderTarget === "webview" && typeof engine.getPagePreview === "function";
|
|
27390
28148
|
const thumbnailDimensionsCacheRef = useRef6(/* @__PURE__ */ new Map());
|
|
27391
28149
|
const thumbnailDimensionsPendingRef = useRef6(/* @__PURE__ */ new Set());
|
|
27392
28150
|
const thumbnailRefreshTimeoutRef = useRef6(null);
|
|
27393
|
-
const [thumbnailLayoutRevision, setThumbnailLayoutRevision] =
|
|
27394
|
-
const [visibleThumbnailPages, setVisibleThumbnailPages] =
|
|
28151
|
+
const [thumbnailLayoutRevision, setThumbnailLayoutRevision] = useState8(0);
|
|
28152
|
+
const [visibleThumbnailPages, setVisibleThumbnailPages] = useState8(
|
|
27395
28153
|
() => /* @__PURE__ */ new Set()
|
|
27396
28154
|
);
|
|
27397
28155
|
const resolvedThumbsInitialCount = useMemo5(
|
|
@@ -27543,7 +28301,7 @@ var RightSheet = ({
|
|
|
27543
28301
|
);
|
|
27544
28302
|
const renderThumbnailItem = useCallback4(
|
|
27545
28303
|
({ item }) => {
|
|
27546
|
-
const shouldRenderPreview = useNativePreview && (visibleThumbnailPages.has(item) || item < resolvedThumbsPrewarmCount || Math.abs(item + 1 - currentPage) <= 1);
|
|
28304
|
+
const shouldRenderPreview = (useNativePreview || useImagePreview) && (visibleThumbnailPages.has(item) || item < resolvedThumbsPrewarmCount || Math.abs(item + 1 - currentPage) <= 1);
|
|
27547
28305
|
return /* @__PURE__ */ jsx10(
|
|
27548
28306
|
PageThumbnail,
|
|
27549
28307
|
{
|
|
@@ -27557,6 +28315,7 @@ var RightSheet = ({
|
|
|
27557
28315
|
frameHeight: getThumbnailFrameHeight(item),
|
|
27558
28316
|
accentColor,
|
|
27559
28317
|
useNativePreview,
|
|
28318
|
+
useImagePreview,
|
|
27560
28319
|
shouldRenderPreview,
|
|
27561
28320
|
onPress: () => jumpToPage(item)
|
|
27562
28321
|
}
|
|
@@ -27573,6 +28332,7 @@ var RightSheet = ({
|
|
|
27573
28332
|
jumpToPage,
|
|
27574
28333
|
resolvedThumbsPrewarmCount,
|
|
27575
28334
|
useNativePreview,
|
|
28335
|
+
useImagePreview,
|
|
27576
28336
|
visibleThumbnailPages,
|
|
27577
28337
|
zoom
|
|
27578
28338
|
]
|
|
@@ -27587,7 +28347,7 @@ var RightSheet = ({
|
|
|
27587
28347
|
maxHeight: sheetHeight,
|
|
27588
28348
|
children: /* @__PURE__ */ jsxs10(View9, { style: styles9.sheet, children: [
|
|
27589
28349
|
/* @__PURE__ */ jsxs10(View9, { style: styles9.header, children: [
|
|
27590
|
-
/* @__PURE__ */ jsx10(
|
|
28350
|
+
/* @__PURE__ */ jsx10(Text6, { style: [styles9.sheetTitle, isDark && styles9.sheetTitleDark], children: showingNotes ? t.notes : navigationTitle }),
|
|
27591
28351
|
!showingNotes ? /* @__PURE__ */ jsx10(
|
|
27592
28352
|
Pressable7,
|
|
27593
28353
|
{
|
|
@@ -27595,7 +28355,7 @@ var RightSheet = ({
|
|
|
27595
28355
|
disabled: showingProgress || pageCount <= 0,
|
|
27596
28356
|
style: styles9.pageStatusHit,
|
|
27597
28357
|
accessibilityLabel: "Open page jump",
|
|
27598
|
-
children: /* @__PURE__ */ jsx10(
|
|
28358
|
+
children: /* @__PURE__ */ jsx10(Text6, { style: [styles9.pageStatus, isDark && styles9.pageStatusDark], children: showingProgress ? `${Math.round(currentPage / Math.max(pageCount, 1) * 100)}%` : `${currentPage}/${pageCount}` })
|
|
27599
28359
|
}
|
|
27600
28360
|
) : null
|
|
27601
28361
|
] }),
|
|
@@ -27613,7 +28373,7 @@ var RightSheet = ({
|
|
|
27613
28373
|
}
|
|
27614
28374
|
],
|
|
27615
28375
|
children: /* @__PURE__ */ jsx10(
|
|
27616
|
-
|
|
28376
|
+
Text6,
|
|
27617
28377
|
{
|
|
27618
28378
|
style: [
|
|
27619
28379
|
styles9.segmentText,
|
|
@@ -27637,7 +28397,7 @@ var RightSheet = ({
|
|
|
27637
28397
|
}
|
|
27638
28398
|
],
|
|
27639
28399
|
children: /* @__PURE__ */ jsx10(
|
|
27640
|
-
|
|
28400
|
+
Text6,
|
|
27641
28401
|
{
|
|
27642
28402
|
style: [
|
|
27643
28403
|
styles9.segmentText,
|
|
@@ -27686,7 +28446,7 @@ var RightSheet = ({
|
|
|
27686
28446
|
],
|
|
27687
28447
|
children: [
|
|
27688
28448
|
/* @__PURE__ */ jsxs10(
|
|
27689
|
-
|
|
28449
|
+
Text6,
|
|
27690
28450
|
{
|
|
27691
28451
|
style: [
|
|
27692
28452
|
styles9.progressLabel,
|
|
@@ -27699,7 +28459,7 @@ var RightSheet = ({
|
|
|
27699
28459
|
}
|
|
27700
28460
|
),
|
|
27701
28461
|
/* @__PURE__ */ jsxs10(
|
|
27702
|
-
|
|
28462
|
+
Text6,
|
|
27703
28463
|
{
|
|
27704
28464
|
style: [
|
|
27705
28465
|
styles9.progressMeta,
|
|
@@ -27723,7 +28483,7 @@ var RightSheet = ({
|
|
|
27723
28483
|
{
|
|
27724
28484
|
contentContainerStyle: styles9.summaryContent,
|
|
27725
28485
|
showsVerticalScrollIndicator: false,
|
|
27726
|
-
children: outline.length === 0 ? /* @__PURE__ */ jsx10(
|
|
28486
|
+
children: outline.length === 0 ? /* @__PURE__ */ jsx10(Text6, { style: [styles9.emptyText, isDark && styles9.emptyTextDark], children: t.noSummary }) : outline.map((item, index) => /* @__PURE__ */ jsx10(
|
|
27727
28487
|
OutlineNode,
|
|
27728
28488
|
{
|
|
27729
28489
|
item,
|
|
@@ -27740,7 +28500,7 @@ var RightSheet = ({
|
|
|
27740
28500
|
{
|
|
27741
28501
|
contentContainerStyle: styles9.content,
|
|
27742
28502
|
showsVerticalScrollIndicator: false,
|
|
27743
|
-
children: annotations.length === 0 ? /* @__PURE__ */ jsx10(
|
|
28503
|
+
children: annotations.length === 0 ? /* @__PURE__ */ jsx10(Text6, { style: [styles9.emptyText, isDark && styles9.emptyTextDark], children: t.noAnnotations }) : /* @__PURE__ */ jsx10(View9, { children: annotations.map((ann) => /* @__PURE__ */ jsxs10(
|
|
27744
28504
|
Pressable7,
|
|
27745
28505
|
{
|
|
27746
28506
|
onPress: () => {
|
|
@@ -27758,7 +28518,7 @@ var RightSheet = ({
|
|
|
27758
28518
|
}
|
|
27759
28519
|
),
|
|
27760
28520
|
/* @__PURE__ */ jsxs10(
|
|
27761
|
-
|
|
28521
|
+
Text6,
|
|
27762
28522
|
{
|
|
27763
28523
|
style: [styles9.noteTitle, isDark && styles9.noteTitleDark],
|
|
27764
28524
|
children: [
|
|
@@ -27770,7 +28530,7 @@ var RightSheet = ({
|
|
|
27770
28530
|
)
|
|
27771
28531
|
] }),
|
|
27772
28532
|
/* @__PURE__ */ jsx10(
|
|
27773
|
-
|
|
28533
|
+
Text6,
|
|
27774
28534
|
{
|
|
27775
28535
|
style: [
|
|
27776
28536
|
styles9.noteType,
|
|
@@ -27781,7 +28541,7 @@ var RightSheet = ({
|
|
|
27781
28541
|
}
|
|
27782
28542
|
),
|
|
27783
28543
|
ann.content ? /* @__PURE__ */ jsx10(
|
|
27784
|
-
|
|
28544
|
+
Text6,
|
|
27785
28545
|
{
|
|
27786
28546
|
style: [
|
|
27787
28547
|
styles9.noteContent,
|
|
@@ -27904,6 +28664,10 @@ var styles9 = StyleSheet9.create({
|
|
|
27904
28664
|
width: "100%",
|
|
27905
28665
|
height: "100%"
|
|
27906
28666
|
},
|
|
28667
|
+
thumbImage: {
|
|
28668
|
+
width: "100%",
|
|
28669
|
+
height: "100%"
|
|
28670
|
+
},
|
|
27907
28671
|
thumbFallback: {
|
|
27908
28672
|
flex: 1,
|
|
27909
28673
|
alignItems: "center",
|
|
@@ -28044,11 +28808,11 @@ var styles9 = StyleSheet9.create({
|
|
|
28044
28808
|
var RightSheet_default = RightSheet;
|
|
28045
28809
|
|
|
28046
28810
|
// components/AnnotationEditor.tsx
|
|
28047
|
-
import { useEffect as useEffect8, useState as
|
|
28811
|
+
import { useEffect as useEffect8, useState as useState9 } from "react";
|
|
28048
28812
|
import {
|
|
28049
28813
|
Modal as Modal3,
|
|
28050
28814
|
View as View10,
|
|
28051
|
-
Text as
|
|
28815
|
+
Text as Text7,
|
|
28052
28816
|
TextInput as TextInput2,
|
|
28053
28817
|
Pressable as Pressable8,
|
|
28054
28818
|
StyleSheet as StyleSheet10
|
|
@@ -28067,7 +28831,7 @@ var AnnotationEditor = () => {
|
|
|
28067
28831
|
} = useViewerStore8();
|
|
28068
28832
|
const annotation = annotations.find((ann) => ann.id === selectedAnnotationId);
|
|
28069
28833
|
const isEditable = annotation && (annotation.type === "text" || annotation.type === "comment");
|
|
28070
|
-
const [draft, setDraft] =
|
|
28834
|
+
const [draft, setDraft] = useState9("");
|
|
28071
28835
|
const isDark = uiTheme === "dark";
|
|
28072
28836
|
const t = getStrings(locale);
|
|
28073
28837
|
useEffect8(() => {
|
|
@@ -28089,7 +28853,7 @@ var AnnotationEditor = () => {
|
|
|
28089
28853
|
animationType: "fade",
|
|
28090
28854
|
onRequestClose: handleClose,
|
|
28091
28855
|
children: /* @__PURE__ */ jsx11(View10, { style: styles10.overlay, children: /* @__PURE__ */ jsxs11(View10, { style: [styles10.card, isDark && styles10.cardDark], children: [
|
|
28092
|
-
/* @__PURE__ */ jsx11(
|
|
28856
|
+
/* @__PURE__ */ jsx11(Text7, { style: [styles10.title, isDark && styles10.titleDark], children: t.editNote }),
|
|
28093
28857
|
/* @__PURE__ */ jsx11(
|
|
28094
28858
|
TextInput2,
|
|
28095
28859
|
{
|
|
@@ -28107,7 +28871,7 @@ var AnnotationEditor = () => {
|
|
|
28107
28871
|
{
|
|
28108
28872
|
onPress: handleClose,
|
|
28109
28873
|
style: [styles10.actionButton, styles10.actionCancel],
|
|
28110
|
-
children: /* @__PURE__ */ jsx11(
|
|
28874
|
+
children: /* @__PURE__ */ jsx11(Text7, { style: styles10.actionText, children: t.cancel })
|
|
28111
28875
|
}
|
|
28112
28876
|
),
|
|
28113
28877
|
/* @__PURE__ */ jsx11(
|
|
@@ -28119,7 +28883,7 @@ var AnnotationEditor = () => {
|
|
|
28119
28883
|
styles10.actionSave,
|
|
28120
28884
|
{ backgroundColor: accentColor }
|
|
28121
28885
|
],
|
|
28122
|
-
children: /* @__PURE__ */ jsx11(
|
|
28886
|
+
children: /* @__PURE__ */ jsx11(Text7, { style: [styles10.actionText, styles10.actionTextLight], children: t.save })
|
|
28123
28887
|
}
|
|
28124
28888
|
)
|
|
28125
28889
|
] })
|
|
@@ -28485,7 +29249,7 @@ var styles11 = StyleSheet11.create({
|
|
|
28485
29249
|
var BottomBar_default = BottomBar;
|
|
28486
29250
|
|
|
28487
29251
|
// components/SettingsSheet.tsx
|
|
28488
|
-
import { Dimensions as Dimensions2, View as View12, Text as
|
|
29252
|
+
import { Dimensions as Dimensions2, View as View12, Text as Text8, Pressable as Pressable10, StyleSheet as StyleSheet12 } from "react-native";
|
|
28489
29253
|
import { useViewerStore as useViewerStore10 } from "@papyrus-sdk/core";
|
|
28490
29254
|
import { jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
28491
29255
|
var PAGE_THEME_OPTIONS = [
|
|
@@ -28576,7 +29340,7 @@ var SettingsSheet = ({
|
|
|
28576
29340
|
children: [
|
|
28577
29341
|
/* @__PURE__ */ jsxs13(View12, { style: styles12.section, children: [
|
|
28578
29342
|
/* @__PURE__ */ jsx13(
|
|
28579
|
-
|
|
29343
|
+
Text8,
|
|
28580
29344
|
{
|
|
28581
29345
|
style: [styles12.sectionTitle, isDark && styles12.sectionTitleDark],
|
|
28582
29346
|
children: t.appearance
|
|
@@ -28594,7 +29358,7 @@ var SettingsSheet = ({
|
|
|
28594
29358
|
uiTheme === "light" && { backgroundColor: accentColor }
|
|
28595
29359
|
],
|
|
28596
29360
|
children: /* @__PURE__ */ jsx13(
|
|
28597
|
-
|
|
29361
|
+
Text8,
|
|
28598
29362
|
{
|
|
28599
29363
|
style: [
|
|
28600
29364
|
styles12.optionText,
|
|
@@ -28617,7 +29381,7 @@ var SettingsSheet = ({
|
|
|
28617
29381
|
uiTheme === "dark" && { backgroundColor: accentColor }
|
|
28618
29382
|
],
|
|
28619
29383
|
children: /* @__PURE__ */ jsx13(
|
|
28620
|
-
|
|
29384
|
+
Text8,
|
|
28621
29385
|
{
|
|
28622
29386
|
style: [
|
|
28623
29387
|
styles12.optionText,
|
|
@@ -28633,7 +29397,7 @@ var SettingsSheet = ({
|
|
|
28633
29397
|
] }),
|
|
28634
29398
|
/* @__PURE__ */ jsxs13(View12, { style: styles12.section, children: [
|
|
28635
29399
|
/* @__PURE__ */ jsx13(
|
|
28636
|
-
|
|
29400
|
+
Text8,
|
|
28637
29401
|
{
|
|
28638
29402
|
style: [styles12.sectionTitle, isDark && styles12.sectionTitleDark],
|
|
28639
29403
|
children: t.pageTheme
|
|
@@ -28654,7 +29418,7 @@ var SettingsSheet = ({
|
|
|
28654
29418
|
children: [
|
|
28655
29419
|
/* @__PURE__ */ jsx13(ThemeSwatch, { value: option.value }),
|
|
28656
29420
|
/* @__PURE__ */ jsx13(
|
|
28657
|
-
|
|
29421
|
+
Text8,
|
|
28658
29422
|
{
|
|
28659
29423
|
style: [
|
|
28660
29424
|
styles12.themeOptionLabel,
|
|
@@ -28672,7 +29436,7 @@ var SettingsSheet = ({
|
|
|
28672
29436
|
] }),
|
|
28673
29437
|
/* @__PURE__ */ jsxs13(View12, { style: styles12.section, children: [
|
|
28674
29438
|
/* @__PURE__ */ jsx13(
|
|
28675
|
-
|
|
29439
|
+
Text8,
|
|
28676
29440
|
{
|
|
28677
29441
|
style: [styles12.sectionTitle, isDark && styles12.sectionTitleDark],
|
|
28678
29442
|
children: t.pageTransition
|
|
@@ -28690,7 +29454,7 @@ var SettingsSheet = ({
|
|
|
28690
29454
|
(!isPaged || isDouble) && { backgroundColor: accentColor }
|
|
28691
29455
|
],
|
|
28692
29456
|
children: /* @__PURE__ */ jsx13(
|
|
28693
|
-
|
|
29457
|
+
Text8,
|
|
28694
29458
|
{
|
|
28695
29459
|
style: [
|
|
28696
29460
|
styles12.optionText,
|
|
@@ -28713,7 +29477,7 @@ var SettingsSheet = ({
|
|
|
28713
29477
|
isPaged && { backgroundColor: accentColor }
|
|
28714
29478
|
],
|
|
28715
29479
|
children: /* @__PURE__ */ jsx13(
|
|
28716
|
-
|
|
29480
|
+
Text8,
|
|
28717
29481
|
{
|
|
28718
29482
|
style: [
|
|
28719
29483
|
styles12.optionText,
|
|
@@ -28729,7 +29493,7 @@ var SettingsSheet = ({
|
|
|
28729
29493
|
] }),
|
|
28730
29494
|
/* @__PURE__ */ jsxs13(View12, { style: styles12.section, children: [
|
|
28731
29495
|
/* @__PURE__ */ jsx13(
|
|
28732
|
-
|
|
29496
|
+
Text8,
|
|
28733
29497
|
{
|
|
28734
29498
|
style: [styles12.sectionTitle, isDark && styles12.sectionTitleDark],
|
|
28735
29499
|
children: t.layout
|
|
@@ -28747,7 +29511,7 @@ var SettingsSheet = ({
|
|
|
28747
29511
|
!isDouble && { backgroundColor: accentColor }
|
|
28748
29512
|
],
|
|
28749
29513
|
children: /* @__PURE__ */ jsx13(
|
|
28750
|
-
|
|
29514
|
+
Text8,
|
|
28751
29515
|
{
|
|
28752
29516
|
style: [
|
|
28753
29517
|
styles12.optionText,
|
|
@@ -28770,7 +29534,7 @@ var SettingsSheet = ({
|
|
|
28770
29534
|
isDouble && { backgroundColor: accentColor }
|
|
28771
29535
|
],
|
|
28772
29536
|
children: /* @__PURE__ */ jsx13(
|
|
28773
|
-
|
|
29537
|
+
Text8,
|
|
28774
29538
|
{
|
|
28775
29539
|
style: [
|
|
28776
29540
|
styles12.optionText,
|
|
@@ -28786,7 +29550,7 @@ var SettingsSheet = ({
|
|
|
28786
29550
|
] }),
|
|
28787
29551
|
/* @__PURE__ */ jsxs13(View12, { style: styles12.section, children: [
|
|
28788
29552
|
/* @__PURE__ */ jsx13(
|
|
28789
|
-
|
|
29553
|
+
Text8,
|
|
28790
29554
|
{
|
|
28791
29555
|
style: [styles12.sectionTitle, isDark && styles12.sectionTitleDark],
|
|
28792
29556
|
children: t.rotate
|
|
@@ -28799,7 +29563,7 @@ var SettingsSheet = ({
|
|
|
28799
29563
|
onPress: () => handleRotate("counterclockwise"),
|
|
28800
29564
|
style: [styles12.optionButton, isDark && styles12.optionButtonDark],
|
|
28801
29565
|
children: /* @__PURE__ */ jsx13(
|
|
28802
|
-
|
|
29566
|
+
Text8,
|
|
28803
29567
|
{
|
|
28804
29568
|
style: [styles12.optionText, isDark && styles12.optionTextDark],
|
|
28805
29569
|
children: t.counterclockwise
|
|
@@ -28813,7 +29577,7 @@ var SettingsSheet = ({
|
|
|
28813
29577
|
onPress: () => handleRotate("clockwise"),
|
|
28814
29578
|
style: [styles12.optionButton, isDark && styles12.optionButtonDark],
|
|
28815
29579
|
children: /* @__PURE__ */ jsx13(
|
|
28816
|
-
|
|
29580
|
+
Text8,
|
|
28817
29581
|
{
|
|
28818
29582
|
style: [styles12.optionText, isDark && styles12.optionTextDark],
|
|
28819
29583
|
children: t.clockwise
|
|
@@ -28825,7 +29589,7 @@ var SettingsSheet = ({
|
|
|
28825
29589
|
] }),
|
|
28826
29590
|
/* @__PURE__ */ jsxs13(View12, { style: styles12.section, children: [
|
|
28827
29591
|
/* @__PURE__ */ jsx13(
|
|
28828
|
-
|
|
29592
|
+
Text8,
|
|
28829
29593
|
{
|
|
28830
29594
|
style: [styles12.sectionTitle, isDark && styles12.sectionTitleDark],
|
|
28831
29595
|
children: t.zoom
|
|
@@ -28840,7 +29604,7 @@ var SettingsSheet = ({
|
|
|
28840
29604
|
children: /* @__PURE__ */ jsx13(IconZoomOut, { size: 16, color: isDark ? "#e5e7eb" : "#111827" })
|
|
28841
29605
|
}
|
|
28842
29606
|
),
|
|
28843
|
-
/* @__PURE__ */ jsx13(View12, { style: styles12.zoomValue, children: /* @__PURE__ */ jsxs13(
|
|
29607
|
+
/* @__PURE__ */ jsx13(View12, { style: styles12.zoomValue, children: /* @__PURE__ */ jsxs13(Text8, { style: [styles12.zoomText, isDark && styles12.zoomTextDark], children: [
|
|
28844
29608
|
Math.round(zoom * 100),
|
|
28845
29609
|
"%"
|
|
28846
29610
|
] }) }),
|
|
@@ -28856,7 +29620,7 @@ var SettingsSheet = ({
|
|
|
28856
29620
|
] }),
|
|
28857
29621
|
/* @__PURE__ */ jsxs13(View12, { style: styles12.section, children: [
|
|
28858
29622
|
/* @__PURE__ */ jsx13(
|
|
28859
|
-
|
|
29623
|
+
Text8,
|
|
28860
29624
|
{
|
|
28861
29625
|
style: [styles12.sectionTitle, isDark && styles12.sectionTitleDark],
|
|
28862
29626
|
children: t.language
|
|
@@ -28874,7 +29638,7 @@ var SettingsSheet = ({
|
|
|
28874
29638
|
locale === "en" && { backgroundColor: accentColor }
|
|
28875
29639
|
],
|
|
28876
29640
|
children: /* @__PURE__ */ jsx13(
|
|
28877
|
-
|
|
29641
|
+
Text8,
|
|
28878
29642
|
{
|
|
28879
29643
|
style: [
|
|
28880
29644
|
styles12.optionText,
|
|
@@ -28897,7 +29661,7 @@ var SettingsSheet = ({
|
|
|
28897
29661
|
locale === "pt-BR" && { backgroundColor: accentColor }
|
|
28898
29662
|
],
|
|
28899
29663
|
children: /* @__PURE__ */ jsx13(
|
|
28900
|
-
|
|
29664
|
+
Text8,
|
|
28901
29665
|
{
|
|
28902
29666
|
style: [
|
|
28903
29667
|
styles12.optionText,
|
|
@@ -29050,11 +29814,11 @@ var styles12 = StyleSheet12.create({
|
|
|
29050
29814
|
var SettingsSheet_default = SettingsSheet;
|
|
29051
29815
|
|
|
29052
29816
|
// components/CoverPreview.tsx
|
|
29053
|
-
import { useEffect as useEffect9, useMemo as useMemo6, useRef as useRef7, useState as
|
|
29817
|
+
import { useEffect as useEffect9, useMemo as useMemo6, useRef as useRef7, useState as useState10 } from "react";
|
|
29054
29818
|
import {
|
|
29055
29819
|
ActivityIndicator,
|
|
29056
29820
|
StyleSheet as StyleSheet13,
|
|
29057
|
-
Text as
|
|
29821
|
+
Text as Text9,
|
|
29058
29822
|
UIManager as UIManager2,
|
|
29059
29823
|
View as View13,
|
|
29060
29824
|
findNodeHandle as findNodeHandle3
|
|
@@ -29108,11 +29872,11 @@ var CoverPreview = ({
|
|
|
29108
29872
|
onLoadEnd,
|
|
29109
29873
|
onError
|
|
29110
29874
|
}) => {
|
|
29111
|
-
const [engine, setEngine] =
|
|
29112
|
-
const [layoutReady, setLayoutReady] =
|
|
29113
|
-
const [loaded, setLoaded] =
|
|
29114
|
-
const [loading, setLoading] =
|
|
29115
|
-
const [error, setError] =
|
|
29875
|
+
const [engine, setEngine] = useState10(null);
|
|
29876
|
+
const [layoutReady, setLayoutReady] = useState10(false);
|
|
29877
|
+
const [loaded, setLoaded] = useState10(false);
|
|
29878
|
+
const [loading, setLoading] = useState10(false);
|
|
29879
|
+
const [error, setError] = useState10(null);
|
|
29116
29880
|
const viewRef = useRef7(null);
|
|
29117
29881
|
const resolvedType = useMemo6(() => inferDocumentType(source, type), [source, type]);
|
|
29118
29882
|
const isPdf = resolvedType === "pdf";
|
|
@@ -29177,12 +29941,12 @@ var CoverPreview = ({
|
|
|
29177
29941
|
}
|
|
29178
29942
|
};
|
|
29179
29943
|
if (!shouldRender || !canRender) {
|
|
29180
|
-
return /* @__PURE__ */ jsx14(View13, { style: [styles13.container, style], children: placeholder ?? /* @__PURE__ */ jsx14(View13, { style: styles13.placeholder, children: /* @__PURE__ */ jsx14(
|
|
29944
|
+
return /* @__PURE__ */ jsx14(View13, { style: [styles13.container, style], children: placeholder ?? /* @__PURE__ */ jsx14(View13, { style: styles13.placeholder, children: /* @__PURE__ */ jsx14(Text9, { style: styles13.placeholderText, children: "Preview" }) }) });
|
|
29181
29945
|
}
|
|
29182
29946
|
return /* @__PURE__ */ jsxs14(View13, { style: [styles13.container, style], onLayout: handleLayout, children: [
|
|
29183
29947
|
/* @__PURE__ */ jsx14(View13, { style: styles13.previewFrame, pointerEvents: allowInteraction ? "auto" : "none", children: isPdf ? /* @__PURE__ */ jsx14(PapyrusPageView3, { ref: viewRef, style: styles13.pageView }) : engine && /* @__PURE__ */ jsx14(WebViewViewer_default, { engine }) }),
|
|
29184
29948
|
showLoading && loading && /* @__PURE__ */ jsx14(View13, { pointerEvents: "none", style: styles13.loadingOverlay, children: loadingIndicator ?? /* @__PURE__ */ jsx14(ActivityIndicator, { size: "small", color: "#2563eb" }) }),
|
|
29185
|
-
error && /* @__PURE__ */ jsx14(View13, { pointerEvents: "none", style: styles13.errorOverlay, children: /* @__PURE__ */ jsx14(
|
|
29949
|
+
error && /* @__PURE__ */ jsx14(View13, { pointerEvents: "none", style: styles13.errorOverlay, children: /* @__PURE__ */ jsx14(Text9, { style: styles13.errorText, children: "Preview unavailable" }) })
|
|
29186
29950
|
] });
|
|
29187
29951
|
};
|
|
29188
29952
|
var styles13 = StyleSheet13.create({
|
|
@@ -29232,7 +29996,7 @@ var styles13 = StyleSheet13.create({
|
|
|
29232
29996
|
var CoverPreview_default = CoverPreview;
|
|
29233
29997
|
|
|
29234
29998
|
// components/ReadingShell.tsx
|
|
29235
|
-
import React13, { useState as
|
|
29999
|
+
import React13, { useState as useState12 } from "react";
|
|
29236
30000
|
import { Keyboard as Keyboard2, View as View20, StyleSheet as StyleSheet20 } from "react-native";
|
|
29237
30001
|
import { useViewerStore as useViewerStore17 } from "@papyrus-sdk/core";
|
|
29238
30002
|
|
|
@@ -29241,7 +30005,7 @@ import {
|
|
|
29241
30005
|
Modal as Modal4,
|
|
29242
30006
|
Pressable as Pressable11,
|
|
29243
30007
|
StyleSheet as StyleSheet14,
|
|
29244
|
-
Text as
|
|
30008
|
+
Text as Text10,
|
|
29245
30009
|
View as View14
|
|
29246
30010
|
} from "react-native";
|
|
29247
30011
|
import { useViewerStore as useViewerStore11 } from "@papyrus-sdk/core";
|
|
@@ -29258,12 +30022,12 @@ function DocumentActionsSheet({
|
|
|
29258
30022
|
onPress: (event) => event.stopPropagation(),
|
|
29259
30023
|
style: [styles14.card, isDark && styles14.cardDark],
|
|
29260
30024
|
children: [
|
|
29261
|
-
/* @__PURE__ */ jsx15(
|
|
30025
|
+
/* @__PURE__ */ jsx15(Text10, { style: [styles14.eyebrow, isDark && styles14.eyebrowDark], children: "Document actions" }),
|
|
29262
30026
|
/* @__PURE__ */ jsxs15(View14, { style: styles14.actionList, children: [
|
|
29263
|
-
/* @__PURE__ */ jsx15(View14, { style: [styles14.actionItem, isDark && styles14.actionItemDark], children: /* @__PURE__ */ jsx15(
|
|
29264
|
-
/* @__PURE__ */ jsx15(View14, { style: [styles14.actionItem, isDark && styles14.actionItemDark], children: /* @__PURE__ */ jsx15(
|
|
30027
|
+
/* @__PURE__ */ jsx15(View14, { style: [styles14.actionItem, isDark && styles14.actionItemDark], children: /* @__PURE__ */ jsx15(Text10, { style: [styles14.actionText, isDark && styles14.actionTextDark], children: "Share" }) }),
|
|
30028
|
+
/* @__PURE__ */ jsx15(View14, { style: [styles14.actionItem, isDark && styles14.actionItemDark], children: /* @__PURE__ */ jsx15(Text10, { style: [styles14.actionText, isDark && styles14.actionTextDark], children: "Export" }) })
|
|
29265
30029
|
] }),
|
|
29266
|
-
/* @__PURE__ */ jsx15(Pressable11, { onPress: onClose, style: styles14.closeButton, accessibilityLabel: "Close actions sheet", children: /* @__PURE__ */ jsx15(
|
|
30030
|
+
/* @__PURE__ */ jsx15(Pressable11, { onPress: onClose, style: styles14.closeButton, accessibilityLabel: "Close actions sheet", children: /* @__PURE__ */ jsx15(Text10, { style: styles14.closeText, children: "Close" }) })
|
|
29267
30031
|
]
|
|
29268
30032
|
}
|
|
29269
30033
|
) }) });
|
|
@@ -29334,7 +30098,7 @@ import {
|
|
|
29334
30098
|
Pressable as Pressable12,
|
|
29335
30099
|
ScrollView as ScrollView4,
|
|
29336
30100
|
StyleSheet as StyleSheet15,
|
|
29337
|
-
Text as
|
|
30101
|
+
Text as Text11,
|
|
29338
30102
|
View as View15
|
|
29339
30103
|
} from "react-native";
|
|
29340
30104
|
import { useViewerStore as useViewerStore12 } from "@papyrus-sdk/core";
|
|
@@ -29493,7 +30257,7 @@ function InfoSheet({
|
|
|
29493
30257
|
}
|
|
29494
30258
|
),
|
|
29495
30259
|
/* @__PURE__ */ jsx16(
|
|
29496
|
-
|
|
30260
|
+
Text11,
|
|
29497
30261
|
{
|
|
29498
30262
|
style: [styles15.headerTitle, isDark && styles15.headerTitleDark],
|
|
29499
30263
|
numberOfLines: 1,
|
|
@@ -29510,7 +30274,7 @@ function InfoSheet({
|
|
|
29510
30274
|
showsVerticalScrollIndicator: false,
|
|
29511
30275
|
children: [
|
|
29512
30276
|
/* @__PURE__ */ jsx16(
|
|
29513
|
-
|
|
30277
|
+
Text11,
|
|
29514
30278
|
{
|
|
29515
30279
|
style: [styles15.sectionTitle, isDark && styles15.sectionTitleDark],
|
|
29516
30280
|
children: locale === "pt-BR" ? "Informa\xE7\xF5es" : "Information"
|
|
@@ -29521,9 +30285,9 @@ function InfoSheet({
|
|
|
29521
30285
|
{
|
|
29522
30286
|
style: [styles15.row, isDark && styles15.rowDark],
|
|
29523
30287
|
children: [
|
|
29524
|
-
/* @__PURE__ */ jsx16(
|
|
30288
|
+
/* @__PURE__ */ jsx16(Text11, { style: [styles15.label, isDark && styles15.labelDark], children: row.label }),
|
|
29525
30289
|
/* @__PURE__ */ jsx16(
|
|
29526
|
-
|
|
30290
|
+
Text11,
|
|
29527
30291
|
{
|
|
29528
30292
|
style: [styles15.value, isDark && styles15.valueDark],
|
|
29529
30293
|
selectable: true,
|
|
@@ -29646,7 +30410,7 @@ var styles15 = StyleSheet15.create({
|
|
|
29646
30410
|
});
|
|
29647
30411
|
|
|
29648
30412
|
// components/OverflowSheet.tsx
|
|
29649
|
-
import { Modal as Modal6, Pressable as Pressable13, StyleSheet as StyleSheet16, Text as
|
|
30413
|
+
import { Modal as Modal6, Pressable as Pressable13, StyleSheet as StyleSheet16, Text as Text12, View as View16 } from "react-native";
|
|
29650
30414
|
import { useViewerStore as useViewerStore13 } from "@papyrus-sdk/core";
|
|
29651
30415
|
import { jsx as jsx17, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
29652
30416
|
var actionLabels = [{ key: "actions", label: "Document actions" }];
|
|
@@ -29681,7 +30445,7 @@ function OverflowSheet({
|
|
|
29681
30445
|
style: [styles16.actionButton, { borderColor: accentColor }],
|
|
29682
30446
|
accessibilityLabel: action.label,
|
|
29683
30447
|
children: /* @__PURE__ */ jsx17(
|
|
29684
|
-
|
|
30448
|
+
Text12,
|
|
29685
30449
|
{
|
|
29686
30450
|
style: [styles16.actionText, isDark && styles16.actionTextDark],
|
|
29687
30451
|
children: action.label
|
|
@@ -29738,7 +30502,7 @@ var styles16 = StyleSheet16.create({
|
|
|
29738
30502
|
|
|
29739
30503
|
// components/ProgressPill.tsx
|
|
29740
30504
|
import { useMemo as useMemo7 } from "react";
|
|
29741
|
-
import { Pressable as Pressable14, StyleSheet as StyleSheet17, Text as
|
|
30505
|
+
import { Pressable as Pressable14, StyleSheet as StyleSheet17, Text as Text13, View as View17 } from "react-native";
|
|
29742
30506
|
import { useViewerStore as useViewerStore14 } from "@papyrus-sdk/core";
|
|
29743
30507
|
import { jsx as jsx18, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
29744
30508
|
var clampPercent = (value) => Math.max(0, Math.min(100, Math.round(value)));
|
|
@@ -29802,7 +30566,7 @@ function ProgressPill({
|
|
|
29802
30566
|
onLongPress: onOpenPageJump,
|
|
29803
30567
|
style: styles17.labelHit,
|
|
29804
30568
|
accessibilityLabel: "Open page jump",
|
|
29805
|
-
children: /* @__PURE__ */ jsx18(
|
|
30569
|
+
children: /* @__PURE__ */ jsx18(Text13, { style: [styles17.label, isDark && styles17.labelDark], children: label })
|
|
29806
30570
|
}
|
|
29807
30571
|
)
|
|
29808
30572
|
]
|
|
@@ -29857,12 +30621,12 @@ var styles17 = StyleSheet17.create({
|
|
|
29857
30621
|
});
|
|
29858
30622
|
|
|
29859
30623
|
// components/SearchOverlay.tsx
|
|
29860
|
-
import { useEffect as useEffect10, useMemo as useMemo8, useState as
|
|
30624
|
+
import { useEffect as useEffect10, useMemo as useMemo8, useState as useState11 } from "react";
|
|
29861
30625
|
import {
|
|
29862
30626
|
Keyboard,
|
|
29863
30627
|
Pressable as Pressable15,
|
|
29864
30628
|
StyleSheet as StyleSheet18,
|
|
29865
|
-
Text as
|
|
30629
|
+
Text as Text14,
|
|
29866
30630
|
TextInput as TextInput3,
|
|
29867
30631
|
View as View18
|
|
29868
30632
|
} from "react-native";
|
|
@@ -29886,8 +30650,8 @@ function SearchOverlay({
|
|
|
29886
30650
|
uiTheme,
|
|
29887
30651
|
accentColor
|
|
29888
30652
|
} = useViewerStore15();
|
|
29889
|
-
const [draft, setDraft] =
|
|
29890
|
-
const [isSearching, setIsSearching] =
|
|
30653
|
+
const [draft, setDraft] = useState11(searchQuery);
|
|
30654
|
+
const [isSearching, setIsSearching] = useState11(false);
|
|
29891
30655
|
const isDark = uiTheme === "dark";
|
|
29892
30656
|
const t = getStrings(locale);
|
|
29893
30657
|
const searchService = useMemo8(() => new SearchService(engine), [engine]);
|
|
@@ -29947,7 +30711,7 @@ function SearchOverlay({
|
|
|
29947
30711
|
onPress: handleClose,
|
|
29948
30712
|
style: [styles18.closeButton, isDark && styles18.closeButtonDark],
|
|
29949
30713
|
accessibilityLabel: "Close search",
|
|
29950
|
-
children: /* @__PURE__ */ jsx19(
|
|
30714
|
+
children: /* @__PURE__ */ jsx19(Text14, { style: [styles18.closeText, isDark && styles18.closeTextDark], children: t.cancel })
|
|
29951
30715
|
}
|
|
29952
30716
|
)
|
|
29953
30717
|
] }),
|
|
@@ -29966,7 +30730,7 @@ function SearchOverlay({
|
|
|
29966
30730
|
children: /* @__PURE__ */ jsx19(IconChevronLeft, { size: 16, color: isDark ? "#e5e7eb" : "#111827" })
|
|
29967
30731
|
}
|
|
29968
30732
|
),
|
|
29969
|
-
/* @__PURE__ */ jsx19(
|
|
30733
|
+
/* @__PURE__ */ jsx19(Text14, { style: [styles18.metaText, isDark && styles18.metaTextDark], children: isSearching ? t.searching : `${currentCount}/${searchResults.length} ${targetLabel}` }),
|
|
29970
30734
|
/* @__PURE__ */ jsx19(
|
|
29971
30735
|
Pressable15,
|
|
29972
30736
|
{
|
|
@@ -29989,7 +30753,7 @@ function SearchOverlay({
|
|
|
29989
30753
|
onPress: handleSubmit,
|
|
29990
30754
|
style: [styles18.primaryAction, { backgroundColor: accentColor }],
|
|
29991
30755
|
accessibilityLabel: "Run search",
|
|
29992
|
-
children: /* @__PURE__ */ jsx19(
|
|
30756
|
+
children: /* @__PURE__ */ jsx19(Text14, { style: styles18.primaryActionText, children: t.searchGo })
|
|
29993
30757
|
}
|
|
29994
30758
|
),
|
|
29995
30759
|
/* @__PURE__ */ jsx19(
|
|
@@ -30004,7 +30768,7 @@ function SearchOverlay({
|
|
|
30004
30768
|
],
|
|
30005
30769
|
accessibilityLabel: "Open all results",
|
|
30006
30770
|
children: /* @__PURE__ */ jsx19(
|
|
30007
|
-
|
|
30771
|
+
Text14,
|
|
30008
30772
|
{
|
|
30009
30773
|
style: [
|
|
30010
30774
|
styles18.secondaryActionText,
|
|
@@ -30166,7 +30930,7 @@ import {
|
|
|
30166
30930
|
Pressable as Pressable16,
|
|
30167
30931
|
ScrollView as ScrollView5,
|
|
30168
30932
|
StyleSheet as StyleSheet19,
|
|
30169
|
-
Text as
|
|
30933
|
+
Text as Text15,
|
|
30170
30934
|
View as View19
|
|
30171
30935
|
} from "react-native";
|
|
30172
30936
|
import { useViewerStore as useViewerStore16 } from "@papyrus-sdk/core";
|
|
@@ -30206,14 +30970,14 @@ function SearchResultsSheet({
|
|
|
30206
30970
|
/* @__PURE__ */ jsxs20(View19, { style: [styles19.sheet, isDark && styles19.sheetDark], children: [
|
|
30207
30971
|
/* @__PURE__ */ jsx20(View19, { style: [styles19.handle, isDark && styles19.handleDark] }),
|
|
30208
30972
|
/* @__PURE__ */ jsxs20(View19, { style: styles19.header, children: [
|
|
30209
|
-
/* @__PURE__ */ jsx20(
|
|
30210
|
-
/* @__PURE__ */ jsxs20(
|
|
30973
|
+
/* @__PURE__ */ jsx20(Text15, { style: [styles19.title, isDark && styles19.titleDark], children: t.allResults }),
|
|
30974
|
+
/* @__PURE__ */ jsxs20(Text15, { style: [styles19.meta, isDark && styles19.metaDark], children: [
|
|
30211
30975
|
searchResults.length,
|
|
30212
30976
|
" ",
|
|
30213
30977
|
t.results
|
|
30214
30978
|
] })
|
|
30215
30979
|
] }),
|
|
30216
|
-
/* @__PURE__ */ jsx20(ScrollView5, { contentContainerStyle: styles19.content, children: searchResults.length === 0 ? /* @__PURE__ */ jsx20(
|
|
30980
|
+
/* @__PURE__ */ jsx20(ScrollView5, { contentContainerStyle: styles19.content, children: searchResults.length === 0 ? /* @__PURE__ */ jsx20(Text15, { style: [styles19.emptyText, isDark && styles19.emptyTextDark], children: t.noResults }) : searchResults.map((result, index) => {
|
|
30217
30981
|
const isActive = index === activeSearchIndex;
|
|
30218
30982
|
return /* @__PURE__ */ jsxs20(
|
|
30219
30983
|
Pressable16,
|
|
@@ -30235,9 +30999,9 @@ function SearchResultsSheet({
|
|
|
30235
30999
|
}
|
|
30236
31000
|
],
|
|
30237
31001
|
children: [
|
|
30238
|
-
/* @__PURE__ */ jsx20(
|
|
31002
|
+
/* @__PURE__ */ jsx20(Text15, { style: [styles19.resultLabel, { color: accentColor }], children: getResultLabel(result.pageIndex) }),
|
|
30239
31003
|
/* @__PURE__ */ jsx20(
|
|
30240
|
-
|
|
31004
|
+
Text15,
|
|
30241
31005
|
{
|
|
30242
31006
|
style: [
|
|
30243
31007
|
styles19.resultText,
|
|
@@ -30378,12 +31142,12 @@ function ReadingShell({
|
|
|
30378
31142
|
uiTheme,
|
|
30379
31143
|
accentColor
|
|
30380
31144
|
} = useViewerStore17();
|
|
30381
|
-
const [overflowOpen, setOverflowOpen] =
|
|
30382
|
-
const [infoOpen, setInfoOpen] =
|
|
30383
|
-
const [actionsOpen, setActionsOpen] =
|
|
30384
|
-
const [settingsOpen, setSettingsOpen] =
|
|
30385
|
-
const [searchResultsOpen, setSearchResultsOpen] =
|
|
30386
|
-
const [pageJumpOpen, setPageJumpOpen] =
|
|
31145
|
+
const [overflowOpen, setOverflowOpen] = useState12(false);
|
|
31146
|
+
const [infoOpen, setInfoOpen] = useState12(false);
|
|
31147
|
+
const [actionsOpen, setActionsOpen] = useState12(false);
|
|
31148
|
+
const [settingsOpen, setSettingsOpen] = useState12(false);
|
|
31149
|
+
const [searchResultsOpen, setSearchResultsOpen] = useState12(false);
|
|
31150
|
+
const [pageJumpOpen, setPageJumpOpen] = useState12(false);
|
|
30387
31151
|
const isDark = uiTheme === "dark";
|
|
30388
31152
|
React13.useEffect(() => {
|
|
30389
31153
|
const showSubscription = Keyboard2.addListener("keyboardDidShow", () => {
|