diff --git a/src/components/BootstrapBlazor.PdfReader/BootstrapBlazor.PdfReader.csproj b/src/components/BootstrapBlazor.PdfReader/BootstrapBlazor.PdfReader.csproj index b8f6709e..95623e55 100644 --- a/src/components/BootstrapBlazor.PdfReader/BootstrapBlazor.PdfReader.csproj +++ b/src/components/BootstrapBlazor.PdfReader/BootstrapBlazor.PdfReader.csproj @@ -1,9 +1,9 @@  - 10.0.1-beta08 + 10.0.1 - + Bootstrap Blazor WebAssembly wasm UI Components Pdf Reader Bootstrap UI components extensions of PdfReader @@ -16,6 +16,13 @@ + + + + + + + diff --git a/src/components/BootstrapBlazor.PdfReader/Locales/en.json b/src/components/BootstrapBlazor.PdfReader/Locales/en.json new file mode 100644 index 00000000..2208ad32 --- /dev/null +++ b/src/components/BootstrapBlazor.PdfReader/Locales/en.json @@ -0,0 +1,17 @@ +{ + "BootstrapBlazor.Components.PdfReader": { + "ToggleSidebar": "Toggle sidebar", + "ZoomIn": "Zoom in", + "ZoomOut": "Zoom out", + "PageActual": "Fit page actual width", + "FitWidth": "Fit to width", + "FitHeight": "Fit to height", + "RotateLeft": "Rotate left", + "RotateRight": "Rotate right", + "Download": "Download", + "Print": "Print", + "TwoPageView": "Two pages on view", + "PresentationMode": "Presentation mode", + "DocumentProperty": "Document properties" + } +} diff --git a/src/components/BootstrapBlazor.PdfReader/Locales/zh.json b/src/components/BootstrapBlazor.PdfReader/Locales/zh.json new file mode 100644 index 00000000..bb62b23f --- /dev/null +++ b/src/components/BootstrapBlazor.PdfReader/Locales/zh.json @@ -0,0 +1,17 @@ +{ + "BootstrapBlazor.Components.PdfReader": { + "ToggleSidebar": "收起/展开 缩略图", + "ZoomIn": "放大", + "ZoomOut": "缩小", + "PageActual": "页面实际大小", + "FitWidth": "适配宽度", + "FitHeight": "适配高度", + "RotateLeft": "向左旋转 90 度", + "RotateRight": "向右旋转 90 度", + "Download": "下载", + "Print": "打印", + "TwoPageView": "双页视图", + "PresentationMode": "演示模式", + "DocumentProperty": "文档属性" + } +} diff --git a/src/components/BootstrapBlazor.PdfReader/PdfReader.razor b/src/components/BootstrapBlazor.PdfReader/PdfReader.razor index 6d7cc82a..848fa150 100644 --- a/src/components/BootstrapBlazor.PdfReader/PdfReader.razor +++ b/src/components/BootstrapBlazor.PdfReader/PdfReader.razor @@ -5,58 +5,74 @@
@if (ShowToolbar) { -
+
-
+
@_docTitle
/
-
+
-
+
- - + +
-
-
+
+
@if (ShowDownload) { -
+
} @if (ShowPrint) { -
+
} diff --git a/src/components/BootstrapBlazor.PdfReader/PdfReader.razor.cs b/src/components/BootstrapBlazor.PdfReader/PdfReader.razor.cs index 9283384e..9b3b6e5e 100644 --- a/src/components/BootstrapBlazor.PdfReader/PdfReader.razor.cs +++ b/src/components/BootstrapBlazor.PdfReader/PdfReader.razor.cs @@ -3,6 +3,7 @@ // Website: https://www.blazor.zone or https://argozhang.github.io/ using Microsoft.AspNetCore.Components; +using Microsoft.Extensions.Localization; using System.Globalization; namespace BootstrapBlazor.Components; @@ -74,10 +75,10 @@ public partial class PdfReader public bool ShowTwoPagesOneView { get; set; } = true; /// - /// 获得/设置 是否启用双页单视图模式 默认 false + /// 获得/设置 是否显示按钮 默认 true 显示 /// [Parameter] - public bool EnableTwoPagesOneView { get; set; } + public bool ShowPresentationMode { get; set; } = false; /// /// 页面初始化回调方法 @@ -121,6 +122,9 @@ public partial class PdfReader [Parameter] public Func? OnPrintingAsync { get; set; } + [Inject, NotNull] + private IStringLocalizer? Localizer { get; set; } + private string? ClassString => CssBuilder.Default("bb-pdf-reader") .AddClassFromAttributes(AdditionalAttributes) .Build(); @@ -139,9 +143,8 @@ public partial class PdfReader private uint _currentPage; private string? _url; private string? _currentScale; - private bool _enableTwoPagesOneView; - private bool _showTwoPagesOneViewButton; - private string? _twoPagesOneViewIcon; + private string? _dropdownItemCheckIcon; + private string? _dropdownItemDefaultIcon; private string CurrentPageString { @@ -182,14 +185,6 @@ private void SetCurrentScale(string value) } } - private void OnToggleTwoPagesOneView() - { - _enableTwoPagesOneView = !_enableTwoPagesOneView; - EnableTwoPagesOneView = _enableTwoPagesOneView; - - _twoPagesOneViewIcon = _enableTwoPagesOneView ? "fa-solid fa-fw fa-check" : "fa-solid fa-fw"; - } - /// /// /// @@ -198,7 +193,8 @@ protected override void OnParametersSet() base.OnParametersSet(); MoreButtonIcon ??= "fa-solid fa-fw fa-ellipsis-vertical"; - _twoPagesOneViewIcon ??= "fa-solid fa-fw"; + _dropdownItemCheckIcon ??= "dropdown-item-check fa-solid fa-fw fa-check"; + _dropdownItemDefaultIcon ??= "dropdown-item-icon fa-solid fa-fw"; if (CurrentPage == 0) { @@ -222,8 +218,6 @@ protected override async Task OnAfterRenderAsync(bool firstRender) _currentPage = CurrentPage; _url = Url; _currentScale = CurrentScale; - _enableTwoPagesOneView = EnableTwoPagesOneView; - _showTwoPagesOneViewButton = ShowTwoPagesOneView; } if (_url != Url) @@ -247,16 +241,6 @@ protected override async Task OnAfterRenderAsync(bool firstRender) _currentScale = CurrentScale; await InvokeVoidAsync("scale", Id, _currentScale); } - if (_enableTwoPagesOneView != EnableTwoPagesOneView) - { - _enableTwoPagesOneView = EnableTwoPagesOneView; - await InvokeVoidAsync("setPages", Id, _enableTwoPagesOneView); - } - if (_showTwoPagesOneViewButton != ShowTwoPagesOneView) - { - _showTwoPagesOneViewButton = ShowTwoPagesOneView; - await InvokeVoidAsync("setPages", Id, _enableTwoPagesOneView); - } } /// diff --git a/src/components/BootstrapBlazor.PdfReader/PdfReader.razor.css b/src/components/BootstrapBlazor.PdfReader/PdfReader.razor.css index d5421afb..9b1b7eb1 100644 --- a/src/components/BootstrapBlazor.PdfReader/PdfReader.razor.css +++ b/src/components/BootstrapBlazor.PdfReader/PdfReader.razor.css @@ -14,10 +14,6 @@ color: #fff; } - .bb-view-toolbar.init > div { - visibility: hidden; - } - .bb-view-toolbar .btn { --bs-btn-color: #fff; } @@ -26,6 +22,11 @@ content: none; } + .bb-view-toolbar .dropdown-menu { + --bs-dropdown-link-active-bg: transparent; + --bs-dropdown-link-active-color: var(--bs-dropdown-color); + } + .bb-view-title { display: flex; align-items: center; @@ -134,6 +135,18 @@ padding: 7px; } + .bb-view-controls .dropdown-item .dropdown-item-check { + display: none; + } + + .bb-view-controls .dropdown-item.active .dropdown-item-check { + display: inline-block; + } + + .bb-view-controls .dropdown-item.active .dropdown-item-icon { + display: none; + } + .bb-view-main { display: flex; width: 100%; @@ -173,8 +186,19 @@ cursor: pointer; border: 2px solid #28292a; transform: rotate(var(--thumb-rotate)); + margin: 0 auto; } + ::deep .bb-view-thumbnail-item .bb-view-thumbnail-group { + display: flex; + flex-direction: column; + justify-content: center; + } + + ::deep .bb-view-thumbnail-item .bb-view-thumbnail-group label { + color: #fff; + } + .bb-view-content { position: relative; flex: 1 1 auto; diff --git a/src/components/BootstrapBlazor.PdfReader/PdfReader.razor.js b/src/components/BootstrapBlazor.PdfReader/PdfReader.razor.js index ef6a768c..7f64795b 100644 --- a/src/components/BootstrapBlazor.PdfReader/PdfReader.razor.js +++ b/src/components/BootstrapBlazor.PdfReader/PdfReader.razor.js @@ -22,17 +22,15 @@ export async function init(id, invoke, options) { const loadingTask = pdfjsLib.getDocument(options); loadingTask.onProgress = function (progressData) { - console.log(progressData.loaded, progressData.total); + }; loadingTask.onPassword = function (updatePassword, reason) { if (reason === pdfjsLib.PasswordResponses.NEED_PASSWORD) { - const password = prompt("This PDF is password protected. Enter password:"); - updatePassword(password); + } else if (reason === pdfjsLib.PasswordResponses.INCORRECT_PASSWORD) { - const password = prompt("Incorrect password. Please try again:"); - updatePassword(password); + } }; @@ -81,34 +79,6 @@ export function scale(id, scale) { } } -export function setPages(id, enableTwoPagesOneView) { - const { el, pdfViewer } = Data.get(id); - if (pdfViewer) { - if (enableTwoPagesOneView) { - pdfViewer.spreadMode = 1; - } - else { - pdfViewer.spreadMode = 0; - } - } - - resetTwoPagesOneView(el, pdfViewer); -} - -const resetTwoPagesOneView = (el, pdfViewer) => { - const twoPagesOneView = el.querySelector(".dropdown-item-pages"); - if (twoPagesOneView) { - EventHandler.on(twoPagesOneView, "click", e => { - if (pdfViewer.spreadMode === 0) { - pdfViewer.spreadMode = 1; - } - else { - pdfViewer.spreadMode = 0; - } - }); - } -} - const addEventListener = (el, pdfViewer, eventBus, invoke, options) => { eventBus.on("pagesinit", async () => { if (options.fitMode) { @@ -121,11 +91,6 @@ const addEventListener = (el, pdfViewer, eventBus, invoke, options) => { countEl.innerHTML = numPages; } - const toolbarEl = el.querySelector(".bb-view-toolbar"); - if (toolbarEl) { - toolbarEl.classList.remove("init"); - } - if (options.triggerPagesInit === true) { await invoke.invokeMethodAsync("PagesInit", numPages); } @@ -141,10 +106,30 @@ const addEventListener = (el, pdfViewer, eventBus, invoke, options) => { } const controls = el.querySelector(".bb-view-controls"); - EventHandler.on(controls, "click", ".bb-view-print", e => { + EventHandler.on(controls, "click", ".bb-view-print", async e => { printPdf(options.url); await invoke.invokeMethodAsync("Printing"); }); + EventHandler.on(controls, "click", ".dropdown-item-pages", async e => { + e.delegateTarget.classList.toggle("active"); + + if (pdfViewer.spreadMode !== 1) { + pdfViewer.spreadMode = 1; + } + else { + pdfViewer.spreadMode = 0; + } + }); + EventHandler.on(controls, "click", ".dropdown-item-presentation", async e => { + e.delegateTarget.classList.toggle("active"); + + //if (pdfViewer.isInPresentationMode) { + // document.exitFullscreen(); + //} + //else { + // el.requestFullscreen(); + //} + }); }) eventBus.on("pagechanging", async evt => { @@ -179,9 +164,6 @@ const addEventListener = (el, pdfViewer, eventBus, invoke, options) => { const scale = evt.scale * 100; scaleEl.value = `${Math.round(scale, 0)}%`; - const minus = el.querySelector(".bb-page-minus"); - const plus = el.querySelector(".bb-page-plus"); - if (scale === 25) { minus.classList.add("disabled"); } @@ -197,8 +179,6 @@ const addEventListener = (el, pdfViewer, eventBus, invoke, options) => { EventHandler.on(minus, "click", e => updateScale(pdfViewer, e.target, -1)); EventHandler.on(plus, "click", e => updateScale(pdfViewer, e.target, 1)); - resetTwoPagesOneView(el, pdfViewer); - const thumbnailsToggle = el.querySelector(".bb-view-bar"); if (thumbnailsToggle) { EventHandler.on(thumbnailsToggle, "click", e => { @@ -228,9 +208,17 @@ const resetThumbnailsView = (el, pdfViewer) => { const page = await pdfViewer.pdfDocument.getPage(i + 1); const canvas = await makeThumb(page); + const group = document.createElement("div"); + group.classList.add("bb-view-thumbnail-group"); const img = document.createElement("img"); img.src = canvas.toDataURL(); - item.appendChild(img); + group.appendChild(img); + + const label = document.createElement("label"); + label.textContent = `${i + 1}`; + group.appendChild(label); + + item.appendChild(group); }); EventHandler.on(thumbnailsContainer, "click", ".bb-view-thumbnail-item", e => {