@page "/envelope/{EnvelopeKey}" @using EnvelopeGenerator.ReceiverUI.Services @using Microsoft.Extensions.Options @using EnvelopeGenerator.ReceiverUI.Options @using Microsoft.JSInterop @inject DocumentService DocumentService @inject NavigationManager Navigation @inject IOptions AppOptions @inject IJSRuntime JSRuntime @implements IAsyncDisposable
Dokumentenansicht
ID: @EnvelopeKey
@if (_isLoading) {
L�dt...

Dokument wird geladen...

} else if (_errorMessage is not null) {
Fehler beim Laden des Dokuments

@_errorMessage

} else if (!string.IsNullOrWhiteSpace(_pdfDataUrl)) {
@if (_pdfLoaded) {
/ @_totalPages
@(_currentZoom)%
}
} else {
Dokument konnte nicht geladen werden.
}
@code { [Parameter] public string? EnvelopeKey { get; set; } bool _isLoading = true; string? _errorMessage; string? _pdfDataUrl; bool _pdfLoaded = false; int _currentPage = 1; int _totalPages = 0; int _currentZoom = 150; DotNetObjectReference? _dotNetRef; protected override async Task OnInitializedAsync() { if (string.IsNullOrWhiteSpace(EnvelopeKey)) { _errorMessage = "Envelope-Schlüssel fehlt."; _isLoading = false; return; } try { var (pdfBytes, statusCode) = await DocumentService.GetDocumentAsync(EnvelopeKey); if (pdfBytes is { Length: > 0 }) { var base64 = Convert.ToBase64String(pdfBytes); _pdfDataUrl = $"data:application/pdf;base64,{base64}"; } else { _errorMessage = $"Dokument konnte nicht geladen werden. HTTP Status: {statusCode}"; } } catch (Exception ex) { _errorMessage = $"Fehler: {ex.Message}"; } _isLoading = false; await InvokeAsync(StateHasChanged); } protected override async Task OnAfterRenderAsync(bool firstRender) { if (!_pdfLoaded && !string.IsNullOrWhiteSpace(_pdfDataUrl)) { await Task.Delay(500); try { _dotNetRef = DotNetObjectReference.Create(this); var success = await JSRuntime.InvokeAsync("pdfViewer.initialize", "pdf-canvas", _pdfDataUrl, _dotNetRef); if (success) { _pdfLoaded = true; _totalPages = await JSRuntime.InvokeAsync("pdfViewer.getTotalPages"); _currentPage = await JSRuntime.InvokeAsync("pdfViewer.getCurrentPage"); await InvokeAsync(StateHasChanged); } } catch (Exception ex) { _errorMessage = $"PDF.js Fehler: {ex.Message}"; await InvokeAsync(StateHasChanged); } } } [JSInvokable] public async Task OnZoomChanged(double scale) { _currentZoom = (int)(scale * 100); await InvokeAsync(StateHasChanged); } async Task NextPage() { if (await JSRuntime.InvokeAsync("pdfViewer.nextPage")) { _currentPage = await JSRuntime.InvokeAsync("pdfViewer.getCurrentPage"); } } async Task PreviousPage() { if (await JSRuntime.InvokeAsync("pdfViewer.previousPage")) { _currentPage = await JSRuntime.InvokeAsync("pdfViewer.getCurrentPage"); } } async Task ZoomIn() { if (_currentZoom >= 300) return; await JSRuntime.InvokeVoidAsync("pdfViewer.zoomIn"); var scale = await JSRuntime.InvokeAsync("pdfViewer.getScale"); _currentZoom = (int)(scale * 100); } async Task ZoomOut() { if (_currentZoom <= 50) return; await JSRuntime.InvokeVoidAsync("pdfViewer.zoomOut"); var scale = await JSRuntime.InvokeAsync("pdfViewer.getScale"); _currentZoom = (int)(scale * 100); } async Task SetZoom(int percentage) { var scale = percentage / 100.0; await JSRuntime.InvokeVoidAsync("pdfViewer.setScale", scale); _currentZoom = percentage; } async Task OnZoomSliderChanged(ChangeEventArgs e) { if (int.TryParse(e.Value?.ToString(), out var zoom)) { await SetZoom(zoom); } } async Task OnPageInputChanged(ChangeEventArgs e) { if (int.TryParse(e.Value?.ToString(), out var pageNum) && pageNum >= 1 && pageNum <= _totalPages) { if (await JSRuntime.InvokeAsync("pdfViewer.goToPage", pageNum)) { _currentPage = pageNum; } } } async Task FitToWidth() { await JSRuntime.InvokeVoidAsync("pdfViewer.fitToWidth"); var scale = await JSRuntime.InvokeAsync("pdfViewer.getScale"); _currentZoom = (int)(scale * 100); } public async ValueTask DisposeAsync() { if (_pdfLoaded) { try { await JSRuntime.InvokeVoidAsync("pdfViewer.dispose"); } catch { // Ignore errors during disposal } } _dotNetRef?.Dispose(); } }