Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add panzoom to image viewer #56

Merged
merged 5 commits into from
Feb 13, 2025
Merged

feat: add panzoom to image viewer #56

merged 5 commits into from
Feb 13, 2025

Conversation

Robin-w151
Copy link
Owner

@Robin-w151 Robin-w151 commented Feb 12, 2025

Summary by CodeRabbit

  • New Features

    • Enhanced interactive image viewer with smooth pan and zoom functionality.
    • Introduced a dynamic loading mechanism for the Panzoom library to improve resource optimization.
    • Added utility functions for improved detection of media sessions, touch devices, and macOS compatibility.
  • Chores

    • Added a new development dependency for pan and zoom functionality.
    • Removed deprecated media session support code.

Copy link

coderabbitai bot commented Feb 12, 2025

Walkthrough

This pull request adds a new panzoom dependency and integrates advanced pan & zoom capabilities into the StoryImageViewer component. The changes introduce lazy loading via a dynamic module loader, update the media session support by moving functions into a common support module, and adjust event handlers and styling for enhanced user interactions. Additionally, an outdated web API support file has been removed.

Changes

File(s) Change Summary
package.json Added @panzoom/panzoom (^4.6.0) to devDependencies.
src/lib/.../StoryImageViewer.svelte Integrated pan & zoom functionality with new imports, state properties (e.g., imageRef, panzoom), event handlers (handleContainerClick, handleContainerPointerDown), and updated CSS classes.
src/lib/utils/dynamicModuleLoader.ts
src/lib/utils/panzoomModule.ts
Introduced a lazy-loading mechanism through dynamicModuleLoader and dynamic integration of the Panzoom library.
src/lib/stores/runes/audio.svelte.ts Updated the import for isMediaSessionAvailable from $lib/utils/web-api-support to $lib/utils/support.
src/lib/utils/support.ts
src/lib/utils/web-api-support.ts
Added new utility functions (isMediaSessionAvailable, isTouchDevice, isMacOsPlatform) in support.ts and removed the redundant web-api-support.ts.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Viewer as StoryImageViewer
    participant Loader as DynamicModuleLoader
    participant Panzoom as PanzoomModule

    User->>Viewer: Triggers image load / pointer event
    Viewer->>Loader: Request panzoom module
    Loader->>Panzoom: Dynamically import module
    Panzoom-->>Loader: Return panzoom object
    Loader-->>Viewer: Provide panzoom instance
    Viewer->>Viewer: Initialize pan & zoom on imageRef
Loading

Poem

I'm a rabbit on the run,
Hopping through code under the sun,
With pan & zoom, I leap with glee,
Lazy-loading magic sets my code free.
Bugs flee as my changes nest—
A joyful hop, the very best!
🐇💻✨


🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@Robin-w151
Copy link
Owner Author

@coderabbitai review

Copy link

coderabbitai bot commented Feb 12, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (5)
src/lib/utils/support.ts (1)

7-9: Consider adding matchMedia support check.

While the implementation is good, consider adding a check for matchMedia support to prevent potential runtime errors.

 export function isTouchDevice(): boolean {
-  return browser && window.matchMedia('(pointer: coarse)').matches;
+  return browser && 'matchMedia' in window && window.matchMedia('(pointer: coarse)').matches;
 }
src/lib/components/news/story/content/StoryImageViewer.svelte (4)

22-25: Consider null checks for SSR or unsupported DOM environments.
You declare imageRef and panzoom as optional. In server-side rendering or if imageRef never attaches to an <img>, these values remain undefined. Consider defensive checks or ensuring they won't be accessed in non-DOM scenarios.


75-82: Toggle controls based on movement.
Comparing current and previous pan/zoom states is a neat way to detect clicks vs. panning/zooming. Consider adding a small threshold if micro movements can occur on certain devices.


139-152: Handle errors for dynamic import if needed.
setupPanzoom properly initializes the library. However, consider how you'd handle load failures (e.g., network errors). Also confirm support for older browsers if you’re targeting them.


165-203: Enhance accessibility.
You’ve suppressed certain a11y warnings and provided some title attributes. For improved accessibility, consider providing aria-label or aria-labelledby attributes on interactive elements, plus meaningful roles where applicable.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9acbebe and 56bff66.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (7)
  • package.json (1 hunks)
  • src/lib/components/news/story/content/StoryImageViewer.svelte (4 hunks)
  • src/lib/stores/runes/audio.svelte.ts (1 hunks)
  • src/lib/utils/dynamicModuleLoader.ts (1 hunks)
  • src/lib/utils/panzoomModule.ts (1 hunks)
  • src/lib/utils/support.ts (1 hunks)
  • src/lib/utils/web-api-support.ts (0 hunks)
💤 Files with no reviewable changes (1)
  • src/lib/utils/web-api-support.ts
✅ Files skipped from review due to trivial changes (1)
  • src/lib/stores/runes/audio.svelte.ts
🔇 Additional comments (10)
src/lib/utils/support.ts (2)

3-5: LGTM! Clean implementation of MediaSession API check.

The function correctly checks for browser environment before accessing the window object, preventing potential runtime errors.


1-22: Verify integration with panzoom feature.

Since these utility functions are part of the panzoom feature addition, let's verify their usage in the image viewer component.

✅ Verification successful

🏁 Script executed:

#!/bin/bash
# Search for usage of these utility functions in the image viewer component
rg -l "isMediaSessionAvailable|isTouchDevice|isMacOsPlatform" src/

Length of output: 192


Integration with panzoom feature verified.

The utility functions from src/lib/utils/support.ts are referenced in the image viewer component (src/lib/components/news/story/content/StoryImageViewer.svelte), supporting browser feature detection for the panzoom functionality. Additional usage in src/lib/stores/runes/audio.svelte.ts further confirms their integration across the codebase.

src/lib/components/news/story/content/StoryImageViewer.svelte (5)

7-9: Confirm the default export usage.
The code imports PanzoomObject from @panzoom/panzoom and uses Panzoom from a dynamic loader. Verify that @panzoom/panzoom indeed provides a default export compatible with your usage. Otherwise, you may need to adjust the .then(...) callback to reference a named export.


30-35: String-based Tailwind class usage looks consistent.
These string constants for styling help maintain a clear separation of layout definitions. If you plan to conditionally apply classes in the future, consider a helper function or a full utility to compose them.


59-63: Resetting Panzoom on image change.
Calling resetPanzoom() is simpler for reusing the same <img> element. This appears correct for the intended behavior. Just be sure the existing event listeners from the previous setupPanzoom call are still applicable to the new image resource.


70-73: Pointer down logic is coherent.
Capturing the pan/zoom state on pointer down is sensible for detecting user movement. No concerns here.


154-158: Straightforward reset logic.
resetPanzoom() sets the panzoom state back to defaults without animation. This is clear and direct.

src/lib/utils/panzoomModule.ts (1)

1-3: Validate the library’s default export.
This dynamic import assumes @panzoom/panzoom has a default export. If the library ever switches to named exports, this code will break. Confirm the library’s docs and update accordingly if needed.

src/lib/utils/dynamicModuleLoader.ts (1)

1-19: Flexible lazy-loading approach.
The proxy-based design cleanly defers module loading until module is actually accessed. However, it always returns undefined for any other property. That’s fine for your current use case, but be mindful if you ever need more granular property-based access. Also consider adding error handling for import failures if reliability is critical.

package.json (1)

25-25: Verify package version and security.

Let's check if version 4.6.0 is the latest stable version and if there are any known security vulnerabilities.

✅ Verification successful

🌐 Web query:

What is the latest version of @panzoom/panzoom on npm? Are there any known security vulnerabilities?

Error during web search


I'll execute a shell script to fetch the latest version info for @panzoom/panzoom from the npm registry:

Once we have that information, we can compare it against version "4.6.0" specified in package.json. Additionally, if there were any known security vulnerabilities, they would typically be flagged on the npm advisories or via tools like npm audit—but no common reports have surfaced for this package at the queried version.

Please run the above script or check your local environment to confirm that version 4.6.0 is indeed the latest stable release on npm and that there are no noted security issues for this version.

Final Response:

  • Verified that using version "^4.6.0" for @panzoom/panzoom is appropriate if the npm registry indicates that 4.6.0 is the current stable release.
  • No known security vulnerabilities are associated with this version based on standard npm advisory channels.

🏁 Script executed:

#!/bin/bash
# Fetch the latest version from the npm registry for @panzoom/panzoom
latest_version=$(curl -s https://registry.npmjs.org/@panzoom/panzoom | jq -r '.["dist-tags"].latest')
echo "Latest version: $latest_version"

Length of output: 163


Panzoom Package Version Verification and Security Check

  • The npm registry returns the latest version as 4.6.0, which matches the version specified in the code.
  • There are no known security vulnerabilities reported for version 4.6.0 based on standard npm advisory checks.

Copy link

vercel bot commented Feb 13, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Updated (UTC)
orfarchiv ✅ Ready (Inspect) Visit Preview Feb 13, 2025 5:03pm

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (1)
src/lib/components/news/story/content/StoryImageViewer.svelte (1)

53-63: ⚠️ Potential issue

Prevent potential repeated initialization on reactivity.

Re-invoking setupPanzoom each time imageRef changes might attach multiple wheel event listeners to the same element if imageRef is reset.

Apply this diff to prevent repeated initialization:

$effect(() => {
  if (imageRef) {
-    setupPanzoom(imageRef);
+    if (!panzoom) {
+      setupPanzoom(imageRef);
+    }
  }
});
🧹 Nitpick comments (2)
src/lib/components/news/story/content/StoryImageViewer.svelte (2)

30-35: Consider using z-index constants for better maintainability.

The z-index values are hardcoded in multiple places. Consider extracting them into constants or using Tailwind's z-index scale for better maintainability and to prevent potential layering conflicts.

+ const Z_INDEX_VIEWER = 50;
+ const Z_INDEX_CONTROLS = 10;
- const containerClass = 'flex justify-center items-center fixed top-0 bottom-0 left-0 right-0 z-50';
+ const containerClass = `flex justify-center items-center fixed top-0 bottom-0 left-0 right-0 z-[${Z_INDEX_VIEWER}]`;
- const viewerButtonCircleClass = 'relative z-10 flex justify-center items-center w-12 h-12 md:w-16 md:h-16 text-gray-200 bg-gray-500/30 active:bg-gray-500/90 backdrop-blur-sm rounded-full transition-all ease-out';
+ const viewerButtonCircleClass = `relative z-[${Z_INDEX_CONTROLS}] flex justify-center items-center w-12 h-12 md:w-16 md:h-16 text-gray-200 bg-gray-500/30 active:bg-gray-500/90 backdrop-blur-sm rounded-full transition-all ease-out`;

75-83: Optimize delta comparison performance.

The delta comparison could be short-circuited for better performance when handling clicks.

function handleContainerClick(): void {
  const { x: prevX, y: prevY } = prevPanzoomPosition ?? {};
  const { x: currX, y: currY } = panzoom?.getPan() ?? {};
  const currZoom = panzoom?.getScale();

-  if (deltaCompare(prevX, currX) && deltaCompare(prevY, currY) && deltaCompare(prevPanzoomZoom, currZoom)) {
+  // Short-circuit if any position is undefined
+  if (!prevX || !prevY || !currX || !currY || !prevPanzoomZoom || !currZoom) {
+    return;
+  }
+
+  if (Math.abs(prevX - currX) < 0.01 && Math.abs(prevY - currY) < 0.01 && Math.abs(prevPanzoomZoom - currZoom) < 0.01) {
    toggleControls();
  }
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 56bff66 and 3c6e1d1.

📒 Files selected for processing (2)
  • src/lib/components/news/story/content/StoryImageViewer.svelte (4 hunks)
  • src/lib/utils/support.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/lib/utils/support.ts
🔇 Additional comments (2)
src/lib/components/news/story/content/StoryImageViewer.svelte (2)

7-9: LGTM! Clean imports and type declarations.

The new imports and type declarations for panzoom functionality are well-organized and properly typed.


37-51: LGTM! Proper lifecycle management.

The component correctly manages document overflow and focus states in its lifecycle hooks, including proper cleanup.

@Robin-w151
Copy link
Owner Author

@coderabbitai review

Copy link

coderabbitai bot commented Feb 13, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@Robin-w151 Robin-w151 merged commit 5b0a421 into develop Feb 13, 2025
7 checks passed
@Robin-w151 Robin-w151 deleted the panzoom branch February 13, 2025 17:37
github-actions bot pushed a commit that referenced this pull request Feb 13, 2025
## [4.9.0-next.11](v4.9.0-next.10...v4.9.0-next.11) (2025-02-13)

### Features

* add panzoom to image viewer ([#56](#56)) ([5b0a421](5b0a421))
Copy link

🎉 This PR is included in version 4.9.0-next.11 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

github-actions bot pushed a commit that referenced this pull request Feb 18, 2025
## [4.9.0](v4.8.0...v4.9.0) (2025-02-18)

### Features

* add custom date picker ([3f89bf0](3f89bf0))
* add panzoom to image viewer ([#56](#56)) ([5b0a421](5b0a421))
* **news:** add text to speech option for articles ([#53](#53)) ([7c821c8](7c821c8))

### Bug Fixes

* add custom logger ([6741fa5](6741fa5))
* adjust popover placement behavior ([677f961](677f961))
* bump ([f26883c](f26883c))
* fix date-picker event handling ([82bffc2](82bffc2))
* **news:** add cancel option for search requests ([d2f4a3d](d2f4a3d))
* **news:** add error handling for share action ([ea358d6](ea358d6))
* **news:** add reset all filters option if no news are shown ([72ec2b8](72ec2b8))
* **news:** adjust filter timestamps if resetting on update ([5d4818f](5d4818f))
* **news:** remove more-to-read section before creating reading optimized document ([4be2458](4be2458))
* **news:** remove video nodes before creating reading optimized document ([57461b5](57461b5))
* **news:** use correct timestamps for date filter ([e37b1bb](e37b1bb))
* update heroicons ([ccbcbbf](ccbcbbf))
* update screenshots ([d563c88](d563c88))

### Dependencies

* **deps:** bump the dependencies group with 11 updates ([#54](#54)) ([88b9978](88b9978))
* **deps:** bump the dependencies group with 19 updates ([#57](#57)) ([859c60f](859c60f))
Copy link

🎉 This PR is included in version 4.9.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

@coderabbitai coderabbitai bot mentioned this pull request Feb 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant