feat(PdfReader): add OnDownloadAsync function#727
Conversation
Reviewer's GuideRefactors the PdfReader component to inline its configuration parameters instead of using PdfReaderOptions, adds new toolbar and download customization parameters, and updates the JS interop to support two-page view toggling and a customizable download action. Sequence diagram for PdfReader download click handlingsequenceDiagram
actor User
participant PdfReader
participant OnDownloadAsync_delegate as OnDownloadAsync
User->>PdfReader: click download button
PdfReader->>PdfReader: OnDownload()
alt Custom download handler provided
PdfReader->>OnDownloadAsync_delegate: Invoke()
OnDownloadAsync_delegate-->>PdfReader: Task completed
else No custom handler
PdfReader->>PdfReader: Use default component behavior
end
Sequence diagram for two-page view initialization and togglingsequenceDiagram
actor User
participant PdfReader
participant JsModule as PdfReaderJs
participant PdfViewer
rect rgb(230,230,250)
PdfReader->>JsModule: InvokeInitAsync(init, options)
JsModule->>PdfViewer: create viewer with options
PdfReader->>JsModule: setPages(id, EnableTwoPagesOneView)
JsModule->>PdfViewer: set spreadMode (0 or 1)
JsModule->>JsModule: resetTwoPagesOneView(el, pdfViewer)
JsModule->>PdfViewer: attach click handler for .dropdown-item-pages
end
rect rgb(220,245,220)
User->>PdfReader: click dropdown-item-pages (Blazor onclick)
PdfReader->>PdfReader: OnToggleTwoPagesOneView()
PdfReader->>JsModule: setPages(id, EnableTwoPagesOneView)
JsModule->>PdfViewer: update spreadMode
end
rect rgb(220,235,245)
User->>JsModule: click .dropdown-item-pages (DOM handler)
JsModule->>PdfViewer: toggle spreadMode between 0 and 1
end
Class diagram for updated PdfReader componentclassDiagram
class PdfReader {
+bool ShowToolbar
+bool ShowDownload
+bool EnableThumbnails
+string Url
+string ViewHeight
+uint CurrentPage
+string CurrentScale
+bool IsFitToPage
+bool ShowTwoPagesOneViewButton
+bool EnableTwoPagesOneView
+string MoreButtonIcon
+Func_int_Task_ OnPagesInitAsync
+Func_int_Task_ OnPagesLoadedAsync
+Func_uint_Task_ OnPageChangedAsync
+Func_bool_Task_ OnTwoPagesOneViewAsync
+Func_Task_ OnDownloadAsync
-string _docTitle
-bool _isFitToPage
-uint _currentPage
-string _url
-string _currentScale
-bool _enableTwoPagesOneView
-bool _showTwoPagesOneViewButton
-string _twoPagesOneViewIcon
-HashSet_string_ AllowedScaleValues
+void FitToPage()
+void FitToWidth()
+Task RotateLeft()
+Task RotateRight()
+Task PagesInit(int pagesCount)
+Task PagesLoaded(int pagesCount)
+Task PageChanged(uint pageIndex)
-Task OnDownload()
-Task InvokeInitAsync()
-Task TriggerFit(string methodName)
}
class DownloadService
PdfReader --> DownloadService : injects
class PdfReaderOptions {
}
<<removed>> PdfReaderOptions
File-Level Changes
Assessment against linked issues
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey there - I've reviewed your changes and found some issues that need to be addressed.
- The new
OnDownloadAsyncparameter currently short-circuits the default behavior (no download occurs when it is null) and the injectedDownloadServiceis unused, so either wire up the built-in download logic whenOnDownloadAsyncis null or remove the misleading XML doc/comment and the unused service. resetTwoPagesOneViewis called from bothsetPagesandaddEventListener, which can result in multiple click handlers being attached to.dropdown-item-pages; consider calling it only once or using a guard to avoid handler duplication.- Some of the XML summaries still reference the old
PdfReaderOptionssemantics (e.g., the comment onOnPageChangedAsyncsays '页面初始化回调方法'); updating these to accurately reflect the new parameter meanings will make the API clearer.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The new `OnDownloadAsync` parameter currently short-circuits the default behavior (no download occurs when it is null) and the injected `DownloadService` is unused, so either wire up the built-in download logic when `OnDownloadAsync` is null or remove the misleading XML doc/comment and the unused service.
- `resetTwoPagesOneView` is called from both `setPages` and `addEventListener`, which can result in multiple click handlers being attached to `.dropdown-item-pages`; consider calling it only once or using a guard to avoid handler duplication.
- Some of the XML summaries still reference the old `PdfReaderOptions` semantics (e.g., the comment on `OnPageChangedAsync` says '页面初始化回调方法'); updating these to accurately reflect the new parameter meanings will make the API clearer.
## Individual Comments
### Comment 1
<location> `src/components/BootstrapBlazor.PdfReader/PdfReader.razor.cs:107-110` </location>
<code_context>
public string? MoreButtonIcon { get; set; }
+ /// <summary>
+ /// 点击下载按钮回调方法 默认 null 使用组件内置下载功能
+ /// </summary>
+ [Parameter]
+ public Func<Task>? OnDownloadAsync { get; set; }
+
+ [Inject, NotNull]
</code_context>
<issue_to_address>
**issue (bug_risk):** Default download behavior is effectively a no-op and `DownloadService` is unused.
The summary comment says `OnDownloadAsync == null` should trigger the built-in download and you inject a `DownloadService`, but `OnDownload()` currently only invokes the callback and otherwise does nothing. As a result, the default download button does nothing unless a consumer wires a handler. Either wire the default behavior via `DownloadService` when `OnDownloadAsync` is null, or change the parameter semantics/docs to require a handler. If you keep a built-in behavior, also guard against null/empty `Url` before invoking the download.
</issue_to_address>
### Comment 2
<location> `src/components/BootstrapBlazor.PdfReader/PdfReader.razor.js:91-100` </location>
<code_context>
}
-export function setPages(id, enableTowPagesOnView) {
+export function setPages(id, enableTwoPagesOneView) {
const { el, pdfViewer } = Data.get(id);
if (pdfViewer) {
- if (enableTowPagesOnView) {
+ if (enableTwoPagesOneView) {
pdfViewer.spreadMode = 1;
}
else {
pdfViewer.spreadMode = 0;
}
}
+
+ resetTwoPagesOneView(el, pdfViewer);
+}
+
</code_context>
<issue_to_address>
**issue (bug_risk):** Repeated calls to `setPages` will re-register the same click handler, potentially causing multiple toggles per click.
`resetTwoPagesOneView` registers a `click` handler on `.dropdown-item-pages`, and it’s now called from both `addEventListener` and `setPages`. Without cleanup or a guard, each `setPages` call will add another listener, so one click can toggle `spreadMode` multiple times. Please either move this listener setup to a one-time initialization path or make `resetTwoPagesOneView` idempotent (e.g., remove existing handlers or ensure you only attach once per element).
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| /// 点击下载按钮回调方法 默认 null 使用组件内置下载功能 | ||
| /// </summary> | ||
| [Parameter] | ||
| public Func<Task>? OnDownloadAsync { get; set; } |
There was a problem hiding this comment.
issue (bug_risk): Default download behavior is effectively a no-op and DownloadService is unused.
The summary comment says OnDownloadAsync == null should trigger the built-in download and you inject a DownloadService, but OnDownload() currently only invokes the callback and otherwise does nothing. As a result, the default download button does nothing unless a consumer wires a handler. Either wire the default behavior via DownloadService when OnDownloadAsync is null, or change the parameter semantics/docs to require a handler. If you keep a built-in behavior, also guard against null/empty Url before invoking the download.
There was a problem hiding this comment.
Pull request overview
This PR refactors the PdfReader component by removing the PdfReaderOptions class and promoting all its properties to direct component parameters. This change simplifies the API by eliminating the need for a separate options object. Additionally, the PR adds the OnDownloadAsync callback function to allow customization of download behavior, and adds a ShowDownload parameter to control download button visibility.
Key changes:
- Removed
PdfReaderOptionsclass and converted all options to direct component parameters - Added
ShowDownloadparameter andOnDownloadAsynccallback for customizable download behavior - Fixed naming inconsistency from "Tow" to "Two" in parameter and method names (e.g.,
ShowTwoPagesOneViewButton)
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| PdfReaderOptions.cs | Removed - entire class deleted as options are now direct component parameters |
| PdfReader.razor.cs | Converted from using PdfReaderOptions to direct parameters; added ShowDownload, OnDownloadAsync, and DownloadService injection |
| PdfReader.razor | Updated to reference component properties directly instead of through Options object; added conditional rendering for download button |
| PdfReader.razor.js | Fixed typo in parameter name from enableTowPagesOnView to enableTwoPagesOneView; refactored event handler setup |
Comments suppressed due to low confidence (1)
src/components/BootstrapBlazor.PdfReader/PdfReader.razor.js:305
- Variable name
towPagesOneViewshould betwoPagesOneViewto be consistent with the naming corrections made elsewhere in this PR (e.g., line 91 parameterenableTwoPagesOneView, line 105 functionresetTwoPagesOneView).
const towPagesOneView = el.querySelector(".dropdown-item-pages");
if (towPagesOneView) {
EventHandler.off(towPagesOneView, "click");
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Link issues
fixes #726
Summary By Copilot
Regression?
Risk
Verification
Packaging changes reviewed?
☑️ Self Check before Merge
Summary by Sourcery
Expose PdfReader configuration as direct component parameters and add hooks for toolbar behavior.
New Features:
Enhancements: