From c6d5656fce60ad58ae069a958530db624d59be87 Mon Sep 17 00:00:00 2001 From: TekH Date: Sat, 6 Jun 2026 00:03:01 +0200 Subject: [PATCH] EnvelopeViewer updates and known issue documentation Updated EnvelopeViewer with layout fixes, unlimited zoom, and thumbnail navigation. Added global mouse wheel zoom (`Ctrl+Wheel`) and retry logic for thumbnail rendering. Refactored layout for responsiveness and documented a critical issue causing a blank screen and infinite render loop. Proposed next steps for resolution and provided a temporary workaround using the legacy ReportViewer. --- COPILOT_CONTEXT_EN.md | 82 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/COPILOT_CONTEXT_EN.md b/COPILOT_CONTEXT_EN.md index 3e271c0c..5069e1eb 100644 --- a/COPILOT_CONTEXT_EN.md +++ b/COPILOT_CONTEXT_EN.md @@ -267,6 +267,8 @@ return report; | **PDF.js: `display: flex` on `.pdf-frame`** | **Prevents left-edge scroll when canvas exceeds container** | | **PDF.js: `max-width: 100%` on canvas** | **Limits zoom; user expects unlimited zoom capability** | | **Mouse wheel on `.pdf-frame` only** | **Only works when mouse over PDF; should work anywhere on page** | +| **OnAfterRenderAsync without `firstRender` guard** | **Creates infinite loop when `StateHasChanged` is called repeatedly** | +| **Conditional rendering with `@if (_pdfLoaded)` wrapping canvas** | **Canvas not in DOM when initialize called, causing perpetual failure** | --- @@ -298,4 +300,84 @@ Our use case is **visual/image stamping** at specific page coordinates | **11** | **2025-01-XX** | **Fixed scroll issues: removed `display: flex`, used `text-align: center` + `inline-block`** | | **11** | **2025-01-XX** | **Removed canvas `max-width` restriction for unlimited zoom** | | **11** | **2025-01-XX** | **Added global mouse wheel zoom: `Ctrl+Wheel` on `document.body`, JSInterop callback to Blazor** | +| **11** | **2025-01-XX** | **Added PDF thumbnail sidebar (left panel) with page previews and navigation** | +| **11** | **2025-01-XX** | **Implemented thumbnail rendering system with sequential loading (50ms delay between pages)** | +| **11** | **2025-01-XX** | **Fixed thumbnail rendering: retry logic (10x 100ms) for canvas availability** | +| **11** | **2025-01-XX** | **Refactored layout: Side-by-side flex design (thumbnails left, PDF right), responsive mobile (horizontal scroll thumbnails)** | | **11** | **2025-01-XX** | **Updated COPILOT_CONTEXT_EN.md: EnvelopeViewer replaces ReportViewer for read-only viewing** | +| **11** | **2025-01-XX** | **?? UNRESOLVED: Infinite render loop causing blank screen — Canvas not found error repeating, `_pdfLoaded` never becomes true** | + +--- + +## Known Issues + +### EnvelopeViewer — Blank Screen / Infinite Loop (UNRESOLVED) + +**Symptoms:** +- Browser console shows: `Canvas not found: pdf-canvas` (repeating 20+ times) +- UI displays error: "Fehler beim Laden des Dokuments - PDF konnte nicht initialisiert werden" +- Blank purple gradient screen, no PDF or thumbnails visible +- `OnAfterRenderAsync` triggers continuously in loop + +**Root Cause:** +- `OnAfterRenderAsync` runs on every render cycle (not just `firstRender`) +- PDF canvas element is not in DOM when `pdfViewer.initialize` is called +- Because `_pdfLoaded = false`, thumbnail/toolbar sections don't render (`@if (_pdfLoaded)` condition) +- Each failed initialize triggers `StateHasChanged` ? new render ? `OnAfterRenderAsync` again ? **infinite loop** + +**Attempted Fixes (Failed):** +1. **Adding `firstRender` check:** + ```csharp + protected override async Task OnAfterRenderAsync(bool firstRender) { + if (firstRender && !_pdfLoaded && ...) { + // Initialize PDF + } + } + ``` + **Result:** Didn't stop the loop, still blank screen + +2. **PDF.js availability check:** + ```csharp + var pdfJsLoaded = await JSRuntime.InvokeAsync("eval", "typeof window.pdfjsLib !== 'undefined'"); + ``` + **Result:** Didn't resolve canvas not found issue + +3. **Increased delays:** + - `Task.Delay(300)` before initialize + - `Task.Delay(200)` before thumbnails + **Result:** No improvement + +4. **JavaScript validation:** + - Added checks for `uint8Array.length`, `totalPages > 0` + **Result:** Didn't prevent initialization failure + +**Possible Next Steps:** +1. **DOM Ready Strategy:** + - Wait for specific element existence before initialize + - Use `MutationObserver` in JS to detect canvas availability + - Try `IntersectionObserver` to ensure canvas is in viewport + +2. **Conditional Rendering:** + - Always render canvas element (even before `_pdfLoaded`) + - Move toolbar/thumbnails outside `@if (_pdfLoaded)` block + - Use CSS `visibility: hidden` instead of conditional rendering + +3. **Blazor Lifecycle:** + - Try `OnAfterRenderAsync` with `IJSRuntime` timeout guard + - Use `Task.Run` with cancellation token to prevent overlapping calls + - Investigate if WASM-specific render cycle differs from Server + +4. **Debugging:** + - Add `Console.WriteLine` in C# to track render count + - Log `firstRender`, `_pdfLoaded`, `_pdfDataUrl` state on each call + - Check if PDF data is actually loaded (`_pdfDataUrl` not null/empty) + - Verify PDF.js CDN loads successfully (Network tab) + +**Test Case:** +- Route: `/envelope/NTE3Ym15SyUtNjA4M...` (valid envelope key) +- Expected: PDF loads, thumbnails appear, toolbar shows +- Actual: Blank screen, console error spam, no PDF rendering + +**Workaround:** +- Use legacy `ReportViewer.razor` (`/receiver/{key}`) for now +- EnvelopeViewer development paused until root cause identified