Fixed error while loading file
This commit is contained in:
@@ -12,6 +12,11 @@
|
|||||||
<button class="btn secondary" @onclick="Download" disabled="@(!HasPdf)">Download</button>
|
<button class="btn secondary" @onclick="Download" disabled="@(!HasPdf)">Download</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@if (!string.IsNullOrWhiteSpace(ErrorMessage))
|
||||||
|
{
|
||||||
|
<div class="error-banner">@ErrorMessage</div>
|
||||||
|
}
|
||||||
|
|
||||||
@if (!HasPdf)
|
@if (!HasPdf)
|
||||||
{
|
{
|
||||||
<div class="drop-hint">Drop or select a PDF to start.</div>
|
<div class="drop-hint">Drop or select a PDF to start.</div>
|
||||||
@@ -96,6 +101,7 @@
|
|||||||
private double StartLeft;
|
private double StartLeft;
|
||||||
private double StartTop;
|
private double StartTop;
|
||||||
private string TextValue = "Text";
|
private string TextValue = "Text";
|
||||||
|
private string? ErrorMessage;
|
||||||
|
|
||||||
private bool HasPdf => !string.IsNullOrWhiteSpace(PdfBase64);
|
private bool HasPdf => !string.IsNullOrWhiteSpace(PdfBase64);
|
||||||
private int DisplayPage => PageIndex + 1;
|
private int DisplayPage => PageIndex + 1;
|
||||||
@@ -117,22 +123,41 @@
|
|||||||
|
|
||||||
private async Task HandleFileSelected(InputFileChangeEventArgs e)
|
private async Task HandleFileSelected(InputFileChangeEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.FileCount == 0)
|
ErrorMessage = null;
|
||||||
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
return;
|
if (e.FileCount == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var file = e.File;
|
||||||
|
await using var stream = file.OpenReadStream(maxAllowedSize: 20 * 1024 * 1024);
|
||||||
|
using var ms = new MemoryStream();
|
||||||
|
await stream.CopyToAsync(ms);
|
||||||
|
PdfBase64 = Convert.ToBase64String(ms.ToArray());
|
||||||
|
|
||||||
|
// Show the canvas before we start rendering
|
||||||
|
await InvokeAsync(StateHasChanged);
|
||||||
|
await Task.Yield();
|
||||||
|
|
||||||
|
// Make sure pdf.js is ready
|
||||||
|
await JS.InvokeVoidAsync("pdfInterop.ensureReady");
|
||||||
|
|
||||||
|
var result = await JS.InvokeAsync<RenderResult>("pdfInterop.loadPdf", PdfBase64);
|
||||||
|
PageCount = result.Pages;
|
||||||
|
PageIndex = 0;
|
||||||
|
|
||||||
|
await RenderPage();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
ErrorMessage = $"Fehler beim Laden der PDF: {ex.Message}";
|
||||||
|
PdfBase64 = null;
|
||||||
|
PageCount = 0;
|
||||||
|
PageIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
var file = e.File;
|
|
||||||
await using var stream = file.OpenReadStream(maxAllowedSize: 20 * 1024 * 1024);
|
|
||||||
using var ms = new MemoryStream();
|
|
||||||
await stream.CopyToAsync(ms);
|
|
||||||
PdfBase64 = Convert.ToBase64String(ms.ToArray());
|
|
||||||
|
|
||||||
var result = await JS.InvokeAsync<RenderResult>("pdfInterop.loadPdf", PdfBase64);
|
|
||||||
PageCount = result.Pages;
|
|
||||||
PageIndex = 0;
|
|
||||||
|
|
||||||
await RenderPage();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task RenderPage()
|
private async Task RenderPage()
|
||||||
@@ -142,10 +167,17 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var viewport = await JS.InvokeAsync<ViewportInfo>("pdfInterop.renderPage", PageIndex, "pdf-canvas", ViewportWidthPx);
|
try
|
||||||
ViewportWidthPx = viewport.Width;
|
{
|
||||||
ViewportHeightPx = viewport.Height;
|
var viewport = await JS.InvokeAsync<ViewportInfo>("pdfInterop.renderPage", PageIndex, "pdf-canvas", ViewportWidthPx);
|
||||||
StateHasChanged();
|
ViewportWidthPx = viewport.Width;
|
||||||
|
ViewportHeightPx = viewport.Height;
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
ErrorMessage = $"Fehler beim Rendern: {ex.Message}";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Reset()
|
private void Reset()
|
||||||
|
|||||||
@@ -76,6 +76,15 @@ h1 {
|
|||||||
color: rgba(226, 232, 240, 0.8);
|
color: rgba(226, 232, 240, 0.8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.error-banner {
|
||||||
|
margin-top: 8px;
|
||||||
|
padding: 10px 12px;
|
||||||
|
border-radius: 8px;
|
||||||
|
background: rgba(239, 68, 68, 0.12);
|
||||||
|
border: 1px solid rgba(239, 68, 68, 0.3);
|
||||||
|
color: #fecdd3;
|
||||||
|
}
|
||||||
|
|
||||||
.document-shell {
|
.document-shell {
|
||||||
position: relative;
|
position: relative;
|
||||||
margin-top: 12px;
|
margin-top: 12px;
|
||||||
|
|||||||
@@ -6,9 +6,10 @@
|
|||||||
<title>Receiver UI (Blazor)</title>
|
<title>Receiver UI (Blazor)</title>
|
||||||
<base href="/" />
|
<base href="/" />
|
||||||
<link rel="stylesheet" href="css/app.css" />
|
<link rel="stylesheet" href="css/app.css" />
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/4.0.269/pdf.min.js" integrity="sha512-tAqK8Nw4WnAnX/d+Q/FI+jTYfCLMVSX39kT9rCec8NLwlY+jIUUQx7TKfQvHr2SgVXmvGZtxPRQSf0oYAI7gCA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
<!-- pdf.js 3.11 UMD + classic worker for compatibility; SRI removed to avoid digest mismatches -->
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/4.0.269/pdf.worker.min.js" integrity="sha512-xS2zAkrE3zGZFNE2hCpL25O9P+hxKpADcDxpfoSr8q/kBDL/6Ht8OZODBM96KghAe8/powBPh6UT7aY4AsF38g==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.min.js"></script>
|
||||||
<script src="https://unpkg.com/pdf-lib/dist/pdf-lib.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.worker.min.js"></script>
|
||||||
|
<script src="https://unpkg.com/pdf-lib/dist/pdf-lib.min.js"></script>
|
||||||
<script src="js/pdfInterop.js"></script>
|
<script src="js/pdfInterop.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
@@ -1,8 +1,13 @@
|
|||||||
(function () {
|
(function () {
|
||||||
|
// Stick to pdf.js 3.11 UMD + classic worker for compatibility.
|
||||||
|
const PDF_JS_SRC = "https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.min.js";
|
||||||
|
const WORKER_SRC = "https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.worker.min.js";
|
||||||
|
|
||||||
const state = {
|
const state = {
|
||||||
pdfDoc: null,
|
pdfDoc: null,
|
||||||
pdfBytes: null,
|
pdfBytes: null,
|
||||||
lastViewport: null,
|
lastViewport: null,
|
||||||
|
pdfJsReady: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
function base64ToUint8(base64) {
|
function base64ToUint8(base64) {
|
||||||
@@ -32,17 +37,73 @@
|
|||||||
|
|
||||||
const pointerPads = new Map();
|
const pointerPads = new Map();
|
||||||
|
|
||||||
window.pdfInterop = {
|
function loadScriptOnce(url) {
|
||||||
ensureReady: () => {
|
return new Promise((resolve, reject) => {
|
||||||
if (pdfjsLib && pdfjsLib.GlobalWorkerOptions) {
|
// If already present, resolve immediately
|
||||||
// worker is already loaded via CDN include
|
const existing = Array.from(document.getElementsByTagName('script')).find(s => s.src === url);
|
||||||
|
if (existing && existing.dataset.loaded === "true") {
|
||||||
|
resolve();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const script = existing || document.createElement('script');
|
||||||
|
script.src = url;
|
||||||
|
script.defer = true;
|
||||||
|
script.onload = () => {
|
||||||
|
script.dataset.loaded = "true";
|
||||||
|
resolve();
|
||||||
|
};
|
||||||
|
script.onerror = (e) => reject(new Error(`Script load failed: ${url}`));
|
||||||
|
|
||||||
|
if (!existing) {
|
||||||
|
document.head.appendChild(script);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function ensurePdfJsLoaded() {
|
||||||
|
if (typeof pdfjsLib !== "undefined") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!state.pdfJsReady) {
|
||||||
|
state.pdfJsReady = loadScriptOnce(PDF_JS_SRC);
|
||||||
|
}
|
||||||
|
|
||||||
|
await state.pdfJsReady;
|
||||||
|
|
||||||
|
if (typeof pdfjsLib === "undefined") {
|
||||||
|
throw new Error("pdfjsLib could not be loaded");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.pdfInterop = {
|
||||||
|
ensureReady: async () => {
|
||||||
|
// Ensure pdf.js is present and the worker path is set explicitly.
|
||||||
|
await ensurePdfJsLoaded();
|
||||||
|
if (pdfjsLib && pdfjsLib.GlobalWorkerOptions) {
|
||||||
|
if (pdfjsLib.GlobalWorkerOptions.workerSrc !== WORKER_SRC) {
|
||||||
|
pdfjsLib.GlobalWorkerOptions.workerSrc = WORKER_SRC;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new Error("pdf.js not available after load");
|
||||||
|
}
|
||||||
},
|
},
|
||||||
loadPdf: async (base64) => {
|
loadPdf: async (base64) => {
|
||||||
return await reloadFromBase64(base64);
|
await ensurePdfJsLoaded();
|
||||||
|
try {
|
||||||
|
const result = await reloadFromBase64(base64);
|
||||||
|
if (!result || !result.pages) {
|
||||||
|
throw new Error("PDF has keine Seiten erkannt");
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
} catch (err) {
|
||||||
|
console.error("pdfInterop.loadPdf failed", err);
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
renderPage: async (pageIndex, canvasId, targetWidth) => {
|
renderPage: async (pageIndex, canvasId, targetWidth) => {
|
||||||
|
await ensurePdfJsLoaded();
|
||||||
if (!state.pdfDoc) {
|
if (!state.pdfDoc) {
|
||||||
throw new Error('PDF not loaded');
|
throw new Error('PDF not loaded');
|
||||||
}
|
}
|
||||||
@@ -51,8 +112,14 @@
|
|||||||
const scale = targetWidth / rawViewport.width;
|
const scale = targetWidth / rawViewport.width;
|
||||||
const viewport = page.getViewport({ scale });
|
const viewport = page.getViewport({ scale });
|
||||||
|
|
||||||
const canvas = document.getElementById(canvasId);
|
let canvas = document.getElementById(canvasId);
|
||||||
if (!canvas) {
|
if (!canvas) {
|
||||||
|
// give the UI a tiny delay to render the canvas into the DOM
|
||||||
|
await new Promise(r => setTimeout(r, 40));
|
||||||
|
canvas = document.getElementById(canvasId);
|
||||||
|
}
|
||||||
|
if (!canvas) {
|
||||||
|
console.error("renderPage: canvas not found", canvasId);
|
||||||
throw new Error('Canvas not found');
|
throw new Error('Canvas not found');
|
||||||
}
|
}
|
||||||
const ctx = canvas.getContext('2d');
|
const ctx = canvas.getContext('2d');
|
||||||
|
|||||||
Reference in New Issue
Block a user