Skip to content

feat(PdfReader): add thumbnails rotate function#725

Merged
ArgoZhang merged 3 commits intomasterfrom
refactor-rotate
Nov 26, 2025
Merged

feat(PdfReader): add thumbnails rotate function#725
ArgoZhang merged 3 commits intomasterfrom
refactor-rotate

Conversation

@ArgoZhang
Copy link
Copy Markdown
Member

@ArgoZhang ArgoZhang commented Nov 26, 2025

Link issues

fixes #724

Summary By Copilot

Regression?

  • Yes
  • No

Risk

  • High
  • Medium
  • Low

Verification

  • Manual (required)
  • Automated

Packaging changes reviewed?

  • Yes
  • No
  • N/A

☑️ Self Check before Merge

⚠️ Please check all items below before review. ⚠️

  • Doc is updated/provided or not needed
  • Demo is updated/provided or not needed
  • Merge the latest code from the main branch

Summary by Sourcery

Add support for synchronized rotation of PDF thumbnails in the PdfReader component and refactor thumbnail initialization into a reusable helper.

New Features:

  • Rotate page thumbnails in sync with PDF page rotation using a configurable CSS rotation variable.

Enhancements:

  • Extract thumbnail creation and click-handling logic into a reusable resetThumbnailsView helper for the PdfReader.
  • Apply a CSS custom property to control thumbnail rotation, improving styling flexibility.

Copilot AI review requested due to automatic review settings November 26, 2025 10:09
@bb-auto bb-auto Bot added the enhancement New feature or request label Nov 26, 2025
@bb-auto bb-auto Bot added this to the v9.2.0 milestone Nov 26, 2025
@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented Nov 26, 2025

Reviewer's Guide

Adds rotation-aware thumbnail support to the PdfReader by refactoring thumbnail initialization into a helper and wiring page rotation events to a new CSS-driven transform for thumbnail items.

Sequence diagram for PdfReader thumbnail rotation handling

sequenceDiagram
    actor User
    participant PdfReaderUI
    participant eventBus
    participant PdfViewer
    participant DOM_thumbnails as DOM_thumbnailsContainer
    participant CSS

    User->>PdfReaderUI: Click rotate button
    PdfReaderUI->>PdfViewer: Change page rotation
    PdfViewer->>eventBus: Emit rotationchanging(evt)
    eventBus->>PdfReaderUI: rotationchanging listener invoked
    PdfReaderUI->>DOM_thumbnails: Query .bb-view-thumbnails
    alt thumbnailsContainer exists
        PdfReaderUI->>DOM_thumbnails: Set style --thumb-rotate = pagesRotation + deg
        DOM_thumbnails->>CSS: Updated custom property --thumb-rotate
        CSS->>DOM_thumbnails: Apply transform rotate(var(--thumb-rotate)) to .bb-view-thumbnail-item
    else thumbnailsContainer missing
        PdfReaderUI-->>PdfReaderUI: No thumbnail rotation applied
    end
Loading

File-Level Changes

Change Details Files
Refactor thumbnail initialization and click handling into a reusable helper for the thumbnails panel.
  • Extract thumbnail creation and click-selection logic from the pagesloaded event handler into a new resetThumbnailsView function
  • Preserve behavior that marks the current page as active and updates pdfViewer.currentPageNumber on thumbnail click
  • Reuse resetThumbnailsView from the pagesloaded event to populate the thumbnail list when thumbnails are enabled
src/components/BootstrapBlazor.PdfReader/PdfReader.razor.js
Wire PDF viewer rotation events to thumbnail rotation via CSS custom property.
  • Listen for rotationchanging events from the eventBus inside addEventListener
  • On rotation change, update a --thumb-rotate CSS variable on the thumbnails container based on pagesRotation
  • Initialize --thumb-rotate in the thumbnail container CSS and apply transform: rotate(var(--thumb-rotate)) to individual thumbnail items
src/components/BootstrapBlazor.PdfReader/PdfReader.razor.js
src/components/BootstrapBlazor.PdfReader/PdfReader.razor.css

Assessment against linked issues

Issue Objective Addressed Explanation
#724 Implement a thumbnail rotation function in PdfReader so that page thumbnails rotate in sync with the main PDF page rotation.

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey there - I've reviewed your changes - here's some feedback:

  • In resetThumbnailsView, pdfViewer.getPagesOverview().map(...) is used purely for side effects; consider switching to forEach to better reflect intent and avoid implying a returned array is used.
  • resetThumbnailsView assumes .bb-view-thumbnails exists; it would be safer to guard against a null thumbnailsContainer before appending children or attaching event handlers to avoid runtime errors in edge cases.
  • If resetThumbnailsView is intended to be reused, you may want to clear existing thumbnail elements and/or previous click handlers before repopulating to prevent duplicate items and stacked event listeners.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `resetThumbnailsView`, `pdfViewer.getPagesOverview().map(...)` is used purely for side effects; consider switching to `forEach` to better reflect intent and avoid implying a returned array is used.
- `resetThumbnailsView` assumes `.bb-view-thumbnails` exists; it would be safer to guard against a null `thumbnailsContainer` before appending children or attaching event handlers to avoid runtime errors in edge cases.
- If `resetThumbnailsView` is intended to be reused, you may want to clear existing thumbnail elements and/or previous click handlers before repopulating to prevent duplicate items and stacked event listeners.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@ArgoZhang ArgoZhang merged commit cb616bd into master Nov 26, 2025
2 checks passed
@ArgoZhang ArgoZhang deleted the refactor-rotate branch November 26, 2025 10:14
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds thumbnail rotation functionality to the PdfReader component. When the main PDF view is rotated, the thumbnail images now rotate accordingly using CSS transforms and a custom CSS variable.

Key Changes:

  • Refactored thumbnail initialization logic into a reusable resetThumbnailsView function
  • Added rotationchanging event handler to dynamically update thumbnail rotation via CSS variables
  • Introduced CSS custom property --thumb-rotate to control thumbnail image rotation

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.

File Description
PdfReader.razor.js Extracted thumbnail initialization into resetThumbnailsView function and added rotation event handler to update CSS variable when pages rotate
PdfReader.razor.css Added --thumb-rotate CSS variable and applied transform: rotate() to thumbnail images

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

}

const resetThumbnailsView = (el, pdfViewer) => {
const thumbnailsContainer = el.querySelector(".bb-view-thumbnails");
Copy link

Copilot AI Nov 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The resetThumbnailsView function doesn't clear existing thumbnails before recreating them. If this function is called multiple times (e.g., when rotation changes or PDF is reloaded), it will keep appending new thumbnails to the container, leading to duplicates.

Add thumbnailsContainer.innerHTML = ''; at the beginning of the function to clear existing content before regenerating thumbnails.

Suggested change
const thumbnailsContainer = el.querySelector(".bb-view-thumbnails");
const thumbnailsContainer = el.querySelector(".bb-view-thumbnails");
thumbnailsContainer.innerHTML = '';

Copilot uses AI. Check for mistakes.
}

.bb-view-thumbnails {
--thumb-rotate: 0;
Copy link

Copilot AI Nov 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default value for --thumb-rotate is set to 0 (unitless), but it's used as rotate(var(--thumb-rotate)) which expects a value with units. While CSS is lenient and treats rotate(0) the same as rotate(0deg), for consistency and clarity, consider setting the default to 0deg instead of 0.

Suggested change
--thumb-rotate: 0;
--thumb-rotate: 0deg;

Copilot uses AI. Check for mistakes.
Comment on lines +209 to +211
const thumbnailsContainer = el.querySelector(".bb-view-thumbnails");
if (thumbnailsContainer) {
thumbnailsContainer.style.setProperty('--thumb-rotate', `${evt.pagesRotation}deg`);
Copy link

Copilot AI Nov 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The rotation event handler only updates the CSS variable when thumbnails exist, but it should also check if options.enableThumbnails is true, similar to how other thumbnail-related code does in lines 129-131 and 145-155. Without this check, the handler will attempt to query for thumbnails even when the thumbnails feature is disabled, which is unnecessary overhead.

Consider adding: if (options.enableThumbnails) { ... } around the entire handler body.

Suggested change
const thumbnailsContainer = el.querySelector(".bb-view-thumbnails");
if (thumbnailsContainer) {
thumbnailsContainer.style.setProperty('--thumb-rotate', `${evt.pagesRotation}deg`);
if (options.enableThumbnails) {
const thumbnailsContainer = el.querySelector(".bb-view-thumbnails");
if (thumbnailsContainer) {
thumbnailsContainer.style.setProperty('--thumb-rotate', `${evt.pagesRotation}deg`);
}

Copilot uses AI. Check for mistakes.
Comment on lines +234 to +245
EventHandler.on(thumbnailsContainer, "click", ".bb-view-thumbnail-item", e => {
const active = thumbnailsContainer.querySelector('.active');
if (active) {
active.classList.remove('active');
}

const item = e.delegateTarget;
item.classList.add("active");

const index = parseInt(item.getAttribute("data-bb-page")) || 1;
pdfViewer.currentPageNumber = index;
});
Copy link

Copilot AI Nov 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The event handler is registered each time resetThumbnailsView is called, but it's never removed before re-registration. This will create duplicate event handlers if resetThumbnailsView is called multiple times (e.g., if the PDF is reloaded or thumbnails are regenerated).

Consider either:

  1. Removing the existing handler before registering a new one: EventHandler.off(thumbnailsContainer, "click") before EventHandler.on(...)
  2. Moving this event handler registration outside of resetThumbnailsView to ensure it's only registered once

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(PdfReader): add thumbnails rotate function

2 participants