feat: use WebP original for full-screen product image viewer
This commit is contained in:
@@ -22,6 +22,7 @@ import { fetchPublicProduct } from '@/entities/product/api/product-api'
|
|||||||
import { fetchPublicProductReviews } from '@/entities/product/api/reviews-api'
|
import { fetchPublicProductReviews } from '@/entities/product/api/reviews-api'
|
||||||
import { ToggleCartIcon } from '@/features/cart/toggle-cart-icon'
|
import { ToggleCartIcon } from '@/features/cart/toggle-cart-icon'
|
||||||
import { formatPriceRub } from '@/shared/lib/format-price'
|
import { formatPriceRub } from '@/shared/lib/format-price'
|
||||||
|
import { getOriginalWebpUrl } from '@/shared/lib/get-original-webp-url'
|
||||||
import { reviewsCountRu } from '@/shared/lib/reviews-count-ru'
|
import { reviewsCountRu } from '@/shared/lib/reviews-count-ru'
|
||||||
import { $user } from '@/shared/model/auth'
|
import { $user } from '@/shared/model/auth'
|
||||||
import { OptimizedImage } from '@/shared/ui/OptimizedImage'
|
import { OptimizedImage } from '@/shared/ui/OptimizedImage'
|
||||||
@@ -282,7 +283,7 @@ export function ProductPage() {
|
|||||||
<SwiperSlide key={`fs:${url}`}>
|
<SwiperSlide key={`fs:${url}`}>
|
||||||
<Box
|
<Box
|
||||||
component="img"
|
component="img"
|
||||||
src={url}
|
src={getOriginalWebpUrl(url)}
|
||||||
alt={p.title}
|
alt={p.title}
|
||||||
sx={{ width: '100%', height: '100%', objectFit: 'contain', display: 'block' }}
|
sx={{ width: '100%', height: '100%', objectFit: 'contain', display: 'block' }}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
/** Extract UUID and subdir from a /uploads/... URL */
|
||||||
|
function parseUploadUrl(src: string): { uuid: string; ext: string; subdir: string } | null {
|
||||||
|
const match = src.match(/^\/uploads(?:\/(reviews))?\/([^.\\/]+)\.(png|jpe?g|webp)/i)
|
||||||
|
if (!match) return null
|
||||||
|
return { subdir: match[1] || '', uuid: match[2], ext: match[3].toLowerCase() }
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get the original WebP URL for full-screen display (no resize) */
|
||||||
|
export function getOriginalWebpUrl(src: string): string {
|
||||||
|
const parsed = parseUploadUrl(src)
|
||||||
|
if (!parsed) return src
|
||||||
|
const pathPrefix = parsed.subdir ? `${parsed.subdir}/` : ''
|
||||||
|
return `/uploads/${pathPrefix}${parsed.uuid}.webp`
|
||||||
|
}
|
||||||
@@ -35,14 +35,6 @@ function buildFallbackSrc(src: string, width: number): string {
|
|||||||
return `/uploads-resized/${pathPrefix}${parsed.uuid}.webp?w=${width}`
|
return `/uploads-resized/${pathPrefix}${parsed.uuid}.webp?w=${width}`
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Get the original WebP URL for full-screen display (no resize) */
|
|
||||||
export function getOriginalWebpUrl(src: string): string {
|
|
||||||
const parsed = parseUploadUrl(src)
|
|
||||||
if (!parsed) return src
|
|
||||||
const pathPrefix = parsed.subdir ? `${parsed.subdir}/` : ''
|
|
||||||
return `/uploads/${pathPrefix}${parsed.uuid}.webp`
|
|
||||||
}
|
|
||||||
|
|
||||||
export function OptimizedImage({
|
export function OptimizedImage({
|
||||||
src,
|
src,
|
||||||
alt,
|
alt,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { render, screen } from '@testing-library/react'
|
import { render, screen } from '@testing-library/react'
|
||||||
import { describe, it, expect } from 'vitest'
|
import { describe, it, expect } from 'vitest'
|
||||||
import { OptimizedImage, getOriginalWebpUrl } from '@/shared/ui/OptimizedImage'
|
import { getOriginalWebpUrl } from '@/shared/lib/get-original-webp-url'
|
||||||
|
import { OptimizedImage } from '@/shared/ui/OptimizedImage'
|
||||||
|
|
||||||
describe('OptimizedImage', () => {
|
describe('OptimizedImage', () => {
|
||||||
it('renders a plain img for non-upload URLs', () => {
|
it('renders a plain img for non-upload URLs', () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user