Skip to content

image format conversion#1590

Merged
ragnep merged 8 commits intomainfrom
image-format-conversion
Oct 31, 2025
Merged

image format conversion#1590
ragnep merged 8 commits intomainfrom
image-format-conversion

Conversation

@ragnep
Copy link
Copy Markdown
Contributor

@ragnep ragnep commented Oct 31, 2025

Summary by CodeRabbit

  • New Features

    • Added support for modern image formats (AVIF, WebP) to optimize page loading and performance
    • Enabled image optimization for staging environments
  • Improvements

    • Enhanced image display consistency and scaling across components
    • Improved responsive image handling for better visual presentation
    • Replaced animation effects with optimized CSS-based approach for smoother rendering

Signed-off-by: ragnep <ragneinfo@gmail.com>
Signed-off-by: ragnep <ragneinfo@gmail.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Oct 31, 2025

Warning

Rate limit exceeded

@ragnep has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 1 minutes and 33 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 0bee86e and a308186.

📒 Files selected for processing (4)
  • components/brain/my-stream/votes/MyStreamWaveMyVote.tsx (2 hunks)
  • components/common/FallbackImage.tsx (2 hunks)
  • components/drops/view/item/content/media/DropListItemContentMediaImage.tsx (2 hunks)
  • components/drops/view/item/content/media/MediaDisplayImage.tsx (2 hunks)

Walkthrough

This PR implements wave media image optimization by migrating image components to Next.js Image with a FallbackImage wrapper, introducing dynamic image scaling (AUTOx600), replacing inline animations with Tailwind classes, and updating Next.js configuration to support additional image formats and staging environment.

Changes

Cohort / File(s) Summary
Test Updates for Image Mocking
__tests__/components/common/FallbackImage.test.tsx, __tests__/components/drops/view/item/content/media/MediaDisplayImage.test.tsx, __tests__/components/waves/WavePicture.test.tsx
Updated tests to mock Next.js Image component via forwardRef with typed props; modified assertions to use accessible role queries and containment checks for src attributes; aligned test expectations with new FallbackImage and image scaling behavior.
Core FallbackImage Refactoring
components/common/FallbackImage.tsx
Migrated from plain img to Next.js Image component; extended props to derive from ImageProps and added optional alt and optimize props; implemented skipOptimization logic via useMemo to detect animated GIFs, IPFS/CloudFront sources, and honor optimize flag; replaced img with Image component using unoptimized flag.
Image Scaling and MediaDisplay
components/drops/view/item/content/media/MediaDisplay.tsx, MediaDisplayImage.tsx, DropListItemContentMedia.tsx
Introduced imageScale?: ImageScale prop with default AUTOx600 on MediaDisplay and MediaDisplayImage; changed DropListItemContentMedia default from AUTOx450 to AUTOx800; wired imageScale through component chain for dynamic image URL scaling.
Image Layout and Responsive Sizing
components/drops/view/item/content/media/DropListItemContentMediaImage.tsx
Added runtime-determined alignment controls (imageObjectClass, imageObjectPosition) based on competition drop; replaced decoding with fill and sizes attributes for responsive image loading; updated object-fit and object-position styling; applied changes to both main and in-view fallback rendering paths.
FallbackImage Integration in Components
components/waves/WavePicture.tsx, components/brain/my-stream/votes/MyStreamWaveMyVote.tsx
Replaced direct img elements with FallbackImage component; added imageScale prop (AUTOx450) to propagate scaling configuration; maintained existing styling and overlay behavior.
Animation Refactoring
components/waves/drops/ArtistActiveSubmissionContent.tsx, ArtistWinningArtworksContent.tsx
Replaced inline keyframes-based animations with CSS class-based tw-animate-fade-in-out; removed internal style blocks; simplified JSX structure and className templates.
Layout and Styling Adjustments
components/waves/drops/ArtistPreviewModal.tsx, WaveDropAuthorPfp.tsx, WaveDropPartContentMedias.tsx, components/waves/leaderboard/WaveLeaderboardTime.tsx, WaveleaderboardHeader.tsx, WaveSmallLeaderboardItemContent.tsx
Applied minor responsive height adjustments, padding/margin tweaks, and added imageScale prop forwarding to WaveDropPartContentMedias; removed redundant styling classes; no functional logic changes.
Image Scaling Enum Extension
helpers/image.helpers.ts
Added new ImageScale enum member AUTOx600 = "AUTOx600" to support additional image scale option.
Next.js Image Optimization Configuration
next.config.mjs
Added staging.6529.io to image domains; enabled AVIF and WebP formats in image optimizer settings for enhanced format support.
Tailwind Animation Token
tailwind.config.js
Added new fade-in-out keyframes animation (opacity 0.8 → 0.4) with 2s ease-in-out infinite alternate timing.
Documentation
codex/STATE.md, codex/tickets/TKT-0036.md
Added ticket TKT-0036 "Improve wave media image optimisation" to STATE.md; created comprehensive ticket document describing context, plan, acceptance criteria, and implementation log for image optimization initiative.

Sequence Diagram

sequenceDiagram
    participant User
    participant MediaDisplayImage
    participant FallbackImage
    participant NextImage
    participant CDN

    User->>MediaDisplayImage: Render with imageScale prop
    MediaDisplayImage->>FallbackImage: Pass primarySrc (scaled URL) + fallbackSrc
    
    rect rgb(220, 240, 255)
    Note over FallbackImage: Optimization Decision
    FallbackImage->>FallbackImage: Check animated GIF?
    FallbackImage->>FallbackImage: Check IPFS/CloudFront?
    FallbackImage->>FallbackImage: Check optimize prop?
    FallbackImage->>FallbackImage: Determine skipOptimization flag
    end

    alt skipOptimization = true
        FallbackImage->>NextImage: Render with unoptimized={true}
    else skipOptimization = false
        FallbackImage->>NextImage: Render with unoptimized={false}
    end

    NextImage->>CDN: Request primarySrc (AUTOx600 scaled)
    
    alt Success
        CDN-->>NextImage: Image loaded
        NextImage-->>MediaDisplayImage: onLoad triggered
        MediaDisplayImage-->>User: Display optimized image
    else Error
        CDN--xNextImage: Request failed
        NextImage->>CDN: Fallback to fallbackSrc
        CDN-->>NextImage: Fallback image loaded
        NextImage-->>MediaDisplayImage: onError handled
        MediaDisplayImage-->>User: Display fallback image
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Areas requiring extra attention:

  • FallbackImage optimization logic (components/common/FallbackImage.tsx): Review the skipOptimization useMemo logic, particularly the URL parsing fallback for detecting CloudFront domains and the conditional handling of animated GIFs and IPFS sources.
  • Image layout changes (components/drops/view/item/content/media/DropListItemContentMediaImage.tsx): Verify that the fill layout with responsive sizes attribute and computed object-fit positioning work correctly across different drop types (competition vs. non-competition).
  • Image scaling propagation: Trace imageScale prop forwarding through MediaDisplay → MediaDisplayImage → FallbackImage and validate that all call sites pass appropriate scale values (AUTOx450, AUTOx600, AUTOx800).
  • Test mocking setup: Confirm that the Next.js Image mock in test files correctly simulates the component behavior and that assertions align with the new FallbackImage rendering expectations.

Possibly related PRs

Suggested reviewers

  • simo6529

Poem

🐰 Images now scale with Tailwind grace,
From AVIF formats—a faster race!
Animations hop without inline strife,
FallbackImage brings optimization to life,
Wave media shines, CDN-assisted, so bright! 📸✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "image format conversion" is clearly related to substantive changes in the pull request. Specifically, the PR adds AVIF and WebP format support to the next.config.mjs file for image optimization, which directly aligns with the title's reference to image format conversion. However, the PR's scope encompasses broader image optimization and refactoring work beyond format conversion alone—including switching to Next.js Image component, improving FallbackImage with optimization logic, standardizing imageScale values across components, and updating test infrastructure. While the title captures a real and important aspect of the changeset, it does not fully represent the primary objective, which appears to be comprehensive image optimization and media handling improvements as indicated by the ticket TKT-0036 ("Improve wave media image optimisation").

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Comment thread components/common/FallbackImage.tsx Fixed
Signed-off-by: ragnep <ragneinfo@gmail.com>
Signed-off-by: ragnep <ragneinfo@gmail.com>
Signed-off-by: ragnep <ragneinfo@gmail.com>
Copy link
Copy Markdown

@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: 0

♻️ Duplicate comments (1)
components/common/FallbackImage.tsx (1)

72-74: Critical security issue: incomplete hostname validation allows arbitrary domains.

The CloudFront hostname check is vulnerable because hostname === "cloudfront.net" matches any URL containing "cloudfront.net" anywhere in the hostname (e.g., evil-cloudfront.net.attacker.com). This was already flagged by the security scanner.

Apply this diff to fix the validation:

-        const isCloudfrontHost =
-          hostname === "cloudfront.net" ||
-          hostname.endsWith(".cloudfront.net");
+        const isCloudfrontHost = hostname.endsWith(".cloudfront.net");

Note: Remove the exact match for cloudfront.net since it's not a valid CloudFront distribution domain. CloudFront distributions are always subdomains like d3lqz0a4bldqgf.cloudfront.net.

🧹 Nitpick comments (3)
__tests__/components/common/FallbackImage.test.tsx (1)

4-17: Consider centralizing the Next Image mock

This MockNextImageProps + forwardRef mock shows up here and in MediaDisplayImage.test.tsx. Dropping it into a shared test helper (e.g., __tests__/test-utils/mockNextImage.ts) would keep the setup single-sourced and easier to tweak next time.

components/drops/view/item/content/media/DropListItemContentMediaImage.tsx (1)

284-292: Remove redundant Tailwind classes when using inline styles.

The code mixes Tailwind utility classes (tw-object-contain, imageObjectClass) with inline style prop (objectFit, objectPosition). Inline styles have higher specificity and override the Tailwind classes, making them ineffective and potentially confusing.

Apply this diff to use only inline styles:

-            className={`tw-object-contain tw-max-w-full tw-max-h-full ${
-              !loaded ? "tw-opacity-0" : "tw-opacity-100"
-            } tw-cursor-pointer ${imageObjectClass}`}
-            style={{
-              objectFit: "contain",
-              objectPosition: imageObjectPosition,
-            }}
+            className={`tw-max-w-full tw-max-h-full ${
+              !loaded ? "tw-opacity-0" : "tw-opacity-100"
+            } tw-cursor-pointer`}
+            style={{
+              objectFit: "contain",
+              objectPosition: imageObjectPosition,
+            }}

Alternatively, if you prefer Tailwind classes, remove the inline style and keep only the classes (though this limits object-position values to Tailwind's predefined options).

components/drops/view/item/content/media/MediaDisplayImage.tsx (1)

52-55: Consider removing redundant inline styles on fill image.

The inline maxWidth: "100%" and maxHeight: "100%" styles may be redundant when using the fill prop with Next.js Image. The fill prop already makes the image fill its parent container absolutely, and tw-object-contain handles aspect ratio preservation. These explicit max-width/height constraints might conflict with the intended fill behavior.

Apply this diff to remove the potentially redundant styles:

-          style={{
-            maxWidth: "100%",
-            maxHeight: "100%",
-          }}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cbd81c9 and 0bee86e.

📒 Files selected for processing (23)
  • __tests__/components/common/FallbackImage.test.tsx (1 hunks)
  • __tests__/components/drops/view/item/content/media/MediaDisplayImage.test.tsx (1 hunks)
  • __tests__/components/waves/WavePicture.test.tsx (1 hunks)
  • codex/STATE.md (1 hunks)
  • codex/tickets/TKT-0036.md (1 hunks)
  • components/brain/my-stream/votes/MyStreamWaveMyVote.tsx (2 hunks)
  • components/common/FallbackImage.tsx (2 hunks)
  • components/drops/view/item/content/media/DropListItemContentMedia.tsx (1 hunks)
  • components/drops/view/item/content/media/DropListItemContentMediaImage.tsx (2 hunks)
  • components/drops/view/item/content/media/MediaDisplay.tsx (4 hunks)
  • components/drops/view/item/content/media/MediaDisplayImage.tsx (3 hunks)
  • components/waves/WavePicture.tsx (3 hunks)
  • components/waves/drops/ArtistActiveSubmissionContent.tsx (2 hunks)
  • components/waves/drops/ArtistPreviewModal.tsx (1 hunks)
  • components/waves/drops/ArtistWinningArtworksContent.tsx (2 hunks)
  • components/waves/drops/WaveDropAuthorPfp.tsx (1 hunks)
  • components/waves/drops/WaveDropPartContentMedias.tsx (1 hunks)
  • components/waves/leaderboard/WaveLeaderboardTime.tsx (1 hunks)
  • components/waves/leaderboard/header/WaveleaderboardHeader.tsx (1 hunks)
  • components/waves/small-leaderboard/WaveSmallLeaderboardItemContent.tsx (2 hunks)
  • helpers/image.helpers.ts (1 hunks)
  • next.config.mjs (1 hunks)
  • tailwind.config.js (2 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx}: Do not include any comments in the code
Use react-query for data fetching
Always add readonly before props

Files:

  • components/waves/leaderboard/header/WaveleaderboardHeader.tsx
  • components/waves/drops/WaveDropAuthorPfp.tsx
  • components/waves/WavePicture.tsx
  • __tests__/components/waves/WavePicture.test.tsx
  • components/waves/drops/ArtistPreviewModal.tsx
  • __tests__/components/common/FallbackImage.test.tsx
  • components/drops/view/item/content/media/DropListItemContentMediaImage.tsx
  • components/drops/view/item/content/media/MediaDisplay.tsx
  • components/waves/small-leaderboard/WaveSmallLeaderboardItemContent.tsx
  • components/common/FallbackImage.tsx
  • components/waves/drops/WaveDropPartContentMedias.tsx
  • components/waves/drops/ArtistActiveSubmissionContent.tsx
  • helpers/image.helpers.ts
  • components/waves/leaderboard/WaveLeaderboardTime.tsx
  • components/drops/view/item/content/media/DropListItemContentMedia.tsx
  • __tests__/components/drops/view/item/content/media/MediaDisplayImage.test.tsx
  • components/brain/my-stream/votes/MyStreamWaveMyVote.tsx
  • components/waves/drops/ArtistWinningArtworksContent.tsx
  • components/drops/view/item/content/media/MediaDisplayImage.tsx
**/*.tsx

📄 CodeRabbit inference engine (.cursorrules)

**/*.tsx: Use FontAwesome for icons
Use TailwindCSS for styling

Files:

  • components/waves/leaderboard/header/WaveleaderboardHeader.tsx
  • components/waves/drops/WaveDropAuthorPfp.tsx
  • components/waves/WavePicture.tsx
  • __tests__/components/waves/WavePicture.test.tsx
  • components/waves/drops/ArtistPreviewModal.tsx
  • __tests__/components/common/FallbackImage.test.tsx
  • components/drops/view/item/content/media/DropListItemContentMediaImage.tsx
  • components/drops/view/item/content/media/MediaDisplay.tsx
  • components/waves/small-leaderboard/WaveSmallLeaderboardItemContent.tsx
  • components/common/FallbackImage.tsx
  • components/waves/drops/WaveDropPartContentMedias.tsx
  • components/waves/drops/ArtistActiveSubmissionContent.tsx
  • components/waves/leaderboard/WaveLeaderboardTime.tsx
  • components/drops/view/item/content/media/DropListItemContentMedia.tsx
  • __tests__/components/drops/view/item/content/media/MediaDisplayImage.test.tsx
  • components/brain/my-stream/votes/MyStreamWaveMyVote.tsx
  • components/waves/drops/ArtistWinningArtworksContent.tsx
  • components/drops/view/item/content/media/MediaDisplayImage.tsx
__tests__/**

📄 CodeRabbit inference engine (tests/AGENTS.md)

Place Jest test suites under the __tests__ directory mirroring source folders (e.g., components, contexts, hooks, utils)

Files:

  • __tests__/components/waves/WavePicture.test.tsx
  • __tests__/components/common/FallbackImage.test.tsx
  • __tests__/components/drops/view/item/content/media/MediaDisplayImage.test.tsx
__tests__/components/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (tests/AGENTS.md)

Use @testing-library/react and @testing-library/user-event for React component tests

Files:

  • __tests__/components/waves/WavePicture.test.tsx
  • __tests__/components/common/FallbackImage.test.tsx
  • __tests__/components/drops/view/item/content/media/MediaDisplayImage.test.tsx
🧠 Learnings (12)
📚 Learning: 2025-09-28T12:33:07.561Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __mocks__/AGENTS.md:0-0
Timestamp: 2025-09-28T12:33:07.561Z
Learning: Applies to __mocks__/**/__mocks__/**/*.{js,jsx,ts,tsx} : Keep mock implementations minimal—only what’s necessary for the test scenarios

Applied to files:

  • __tests__/components/common/FallbackImage.test.tsx
  • __tests__/components/drops/view/item/content/media/MediaDisplayImage.test.tsx
📚 Learning: 2025-09-28T12:33:07.561Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __mocks__/AGENTS.md:0-0
Timestamp: 2025-09-28T12:33:07.561Z
Learning: Applies to __mocks__/**/__mocks__/**/*.{js,jsx,ts,tsx} : Keep mocks up to date with the real implementations they represent

Applied to files:

  • __tests__/components/common/FallbackImage.test.tsx
  • __tests__/components/drops/view/item/content/media/MediaDisplayImage.test.tsx
📚 Learning: 2025-09-28T12:33:07.561Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __mocks__/AGENTS.md:0-0
Timestamp: 2025-09-28T12:33:07.561Z
Learning: Applies to __mocks__/**/__mocks__/**/*.{js,jsx,ts,tsx} : Document non-obvious expected behaviour directly in the mock file

Applied to files:

  • __tests__/components/common/FallbackImage.test.tsx
  • __tests__/components/drops/view/item/content/media/MediaDisplayImage.test.tsx
📚 Learning: 2025-09-28T12:33:07.561Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __mocks__/AGENTS.md:0-0
Timestamp: 2025-09-28T12:33:07.561Z
Learning: Applies to __mocks__/**/__mocks__/**/*.{js,jsx,ts,tsx} : Mock only external dependencies or heavy functionality; avoid over-mocking internal logic

Applied to files:

  • __tests__/components/common/FallbackImage.test.tsx
  • __tests__/components/drops/view/item/content/media/MediaDisplayImage.test.tsx
📚 Learning: 2025-09-28T12:33:07.561Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __mocks__/AGENTS.md:0-0
Timestamp: 2025-09-28T12:33:07.561Z
Learning: Applies to __mocks__/**/__mocks__/**/*.{js,jsx,ts,tsx} : Organise mocks to mirror the real module structure so import paths remain consistent

Applied to files:

  • __tests__/components/common/FallbackImage.test.tsx
  • __tests__/components/drops/view/item/content/media/MediaDisplayImage.test.tsx
📚 Learning: 2025-09-28T12:33:30.950Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-09-28T12:33:30.950Z
Learning: Applies to __tests__/components/**/*.{ts,tsx,js,jsx} : Use `testing-library/react` and `testing-library/user-event` for React component tests

Applied to files:

  • __tests__/components/common/FallbackImage.test.tsx
  • __tests__/components/drops/view/item/content/media/MediaDisplayImage.test.tsx
📚 Learning: 2025-09-28T12:33:07.561Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __mocks__/AGENTS.md:0-0
Timestamp: 2025-09-28T12:33:07.561Z
Learning: Applies to __mocks__/**/*.{test,spec}.{js,jsx,ts,tsx} : In tests, use jest.mock('module') with a bare module specifier to load the corresponding manual mock

Applied to files:

  • __tests__/components/common/FallbackImage.test.tsx
📚 Learning: 2025-09-28T12:33:07.561Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __mocks__/AGENTS.md:0-0
Timestamp: 2025-09-28T12:33:07.561Z
Learning: Applies to __mocks__/**/__mocks__/**/*.{js,jsx,ts,tsx} : Name mock files to mirror the real module names so jest.mock('module') can pick them up automatically

Applied to files:

  • __tests__/components/common/FallbackImage.test.tsx
📚 Learning: 2025-09-28T12:33:07.561Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __mocks__/AGENTS.md:0-0
Timestamp: 2025-09-28T12:33:07.561Z
Learning: Applies to __mocks__/**/__mocks__/**/*.{js,jsx,ts,tsx} : Review mocks periodically and remove unused mock modules

Applied to files:

  • __tests__/components/common/FallbackImage.test.tsx
📚 Learning: 2025-09-28T12:33:07.561Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __mocks__/AGENTS.md:0-0
Timestamp: 2025-09-28T12:33:07.561Z
Learning: Use Jest’s built-in mocking for module replacement; keep manual mocks simple and lightweight

Applied to files:

  • __tests__/components/common/FallbackImage.test.tsx
📚 Learning: 2025-09-28T12:33:07.561Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __mocks__/AGENTS.md:0-0
Timestamp: 2025-09-28T12:33:07.561Z
Learning: Applies to __mocks__/**/__mocks__/**/*.{js,jsx,ts,tsx} : Place manual mock modules under a __mocks__ directory so Jest can auto-resolve them

Applied to files:

  • __tests__/components/common/FallbackImage.test.tsx
📚 Learning: 2025-09-28T12:29:11.651Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: .cursorrules:0-0
Timestamp: 2025-09-28T12:29:11.651Z
Learning: Applies to {app,pages}/**/*.{ts,tsx} : Use NextJS features that match the current version

Applied to files:

  • components/common/FallbackImage.tsx
🧬 Code graph analysis (3)
components/waves/WavePicture.tsx (1)
components/common/FallbackImage.tsx (1)
  • FallbackImage (16-92)
__tests__/components/drops/view/item/content/media/MediaDisplayImage.test.tsx (1)
helpers/image.helpers.ts (1)
  • getScaledImageUri (17-45)
components/drops/view/item/content/media/MediaDisplayImage.tsx (2)
components/common/FallbackImage.tsx (1)
  • FallbackImage (16-92)
helpers/image.helpers.ts (1)
  • getScaledImageUri (17-45)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (23)
components/waves/drops/WaveDropPartContentMedias.tsx (1)

38-38: LGTM! Consistent imageScale propagation.

The addition ensures both the disabled and enabled media interaction branches receive the imageScale prop, maintaining consistency in image scaling behavior across all rendering paths.

components/waves/leaderboard/WaveLeaderboardTime.tsx (1)

131-131: LGTM! Minor styling adjustment.

Removal of the bottom margin is a straightforward styling change with no functional impact.

next.config.mjs (2)

117-117: LGTM! Staging domain support added.

Adding staging.6529.io to the image domains list enables Next.js image optimization for the staging environment, which is essential for consistent image handling across environments.


125-125: LGTM! Modern image format support enabled.

Enabling AVIF and WebP formats allows Next.js to serve optimized, modern image formats that provide better compression and quality. This directly supports the PR's image optimization objectives.

components/brain/my-stream/votes/MyStreamWaveMyVote.tsx (1)

13-13: LGTM! Image scaling integration complete.

The import and usage of ImageScale.AUTOx450 properly integrates this component with the new centralized image scaling system. The AUTOx450 scale is appropriate for the artwork display in vote items.

Also applies to: 94-94

codex/STATE.md (1)

42-42: LGTM! Ticket tracking entry added.

The ticket entry is properly formatted with all required fields and correctly positioned in alphabetical order.

components/waves/drops/ArtistPreviewModal.tsx (1)

111-111: Modal height now consistent across breakpoints.

The removal of the sm:tw-max-h-[85vh] override means small screens now get the same 90vh max-height as larger screens. This provides more space for media content but could potentially cause layout issues if content overflows.

Please verify the modal displays correctly on small screens with maximum content to ensure no overflow or scroll issues occur.

components/waves/drops/WaveDropAuthorPfp.tsx (1)

1-1: LGTM! Formatting adjustment.

The "use client" directive formatting has no functional impact.

components/waves/leaderboard/header/WaveleaderboardHeader.tsx (1)

36-37: LGTM! Layout styling refinements.

The addition of top padding and removal of the background color are straightforward styling adjustments that refine the visual presentation of the leaderboard header.

tailwind.config.js (1)

119-134: Consistent fade transition utility

The new fade-in-out keyframes and animation give us a reusable token for the loading states you touched elsewhere—great way to keep the behavior centralized.

components/waves/drops/ArtistActiveSubmissionContent.tsx (1)

83-89: Nice wrapper simplification

Swapping the fragment for a single wrapper with scoped scroll styling keeps the layout predictable and matches the new animation class usage—looks great.

components/waves/drops/ArtistWinningArtworksContent.tsx (1)

31-37: Loading state aligns with shared animation

Hooking the loading message into tw-animate-fade-in-out ties it back to the shared Tailwind token—nice consistency boost.

__tests__/components/drops/view/item/content/media/MediaDisplayImage.test.tsx (1)

39-60: Great coverage of scaling behavior

Verifying the placeholder teardown and the getScaledImageUri(..., "AUTOx600") call catches the key regression risks from the new scaling path—nice work.

helpers/image.helpers.ts (1)

5-5: LGTM!

The new AUTOx600 scale follows the existing enum pattern and integrates cleanly with the image scaling logic.

components/waves/small-leaderboard/WaveSmallLeaderboardItemContent.tsx (1)

8-8: LGTM!

The ImageScale.AUTOx450 is appropriately sized for small leaderboard item thumbnails, and the prop is correctly passed to the media component.

Also applies to: 41-41

__tests__/components/waves/WavePicture.test.tsx (1)

8-10: LGTM!

The test updates correctly use accessible name queries and validate the src attribute with toContain, which properly handles Next.js Image URL transformations.

components/drops/view/item/content/media/DropListItemContentMedia.tsx (1)

29-29: LGTM!

The increased default scale from AUTOx450 to AUTOx800 provides higher resolution for drop list items, aligning with the optimization improvements in this PR.

components/waves/WavePicture.tsx (2)

70-79: LGTM!

The migration to FallbackImage with fill layout is correct. The parent container has tw-relative positioning, and sizes="64px" matches the fixed container dimensions.


109-116: LGTM!

Contributor avatars correctly use FallbackImage with fill layout and appropriate sizing. The clip-path styling is preserved from the original implementation.

components/drops/view/item/content/media/DropListItemContentMediaImage.tsx (1)

260-261: LGTM!

The conditional alignment based on isCompetitionDrop provides appropriate positioning for different drop types.

components/drops/view/item/content/media/MediaDisplayImage.tsx (2)

4-5: LGTM! Clean migration to Next.js Image with proper fallback handling.

The transition from a standard img to FallbackImage (wrapping Next.js Image) provides better optimization and automatic format conversion. The scaling logic via getScaledImageUri with the imageScale prop is well-integrated, and the fallback mechanism ensures robustness when scaled images fail to load.

Also applies to: 13-13, 43-58


48-48: Verify that the sizes attribute matches typical usage patterns.

The sizes="(max-width: 768px) 100vw, 600px" attribute helps Next.js determine which image size to load for optimal performance. Please confirm that 600px aligns with the typical rendered width of this component on desktop viewports to ensure efficient image delivery.

components/drops/view/item/content/media/MediaDisplay.tsx (1)

6-6: LGTM! Proper prop threading for image scaling.

The imageScale prop is correctly defined with a sensible default (AUTOx600), properly typed with readonly, and forwarded to MediaDisplayImage only in the IMAGE case. This maintains backward compatibility while enabling configurable image scaling.

Also applies to: 31-31, 36-36, 61-61

Signed-off-by: ragnep <ragneinfo@gmail.com>
Signed-off-by: ragnep <ragneinfo@gmail.com>
@sonarqubecloud
Copy link
Copy Markdown

@ragnep ragnep merged commit 25c8675 into main Oct 31, 2025
8 checks passed
@ragnep ragnep deleted the image-format-conversion branch October 31, 2025 14:47
This was referenced Nov 3, 2025
@coderabbitai coderabbitai Bot mentioned this pull request Dec 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants