From dd0a7bba5d59880e8671eb95507c5eb355a11d8a Mon Sep 17 00:00:00 2001 From: nileshgulia1 Date: Thu, 13 Jul 2023 16:27:48 +0530 Subject: [PATCH 1/4] feat: image scales from restapi refs#254622 --- src/helpers.js | 55 +++++++++++++++++++++++++++++++++++ src/hocs/withCachedImages.jsx | 3 +- 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/src/helpers.js b/src/helpers.js index 0954929..3bd1c95 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -2,6 +2,7 @@ import isArray from 'lodash/isArray'; import isObject from 'lodash/isObject'; import isString from 'lodash/isString'; import { isInternalURL, flattenToAppURL } from '@plone/volto/helpers'; +import config from '@plone/volto/registry'; export const getFieldURL = (data) => { let url = data; @@ -17,3 +18,57 @@ export const getFieldURL = (data) => { if (isString(url) && isInternalURL(url)) return flattenToAppURL(url); return url; }; + +export function getImageScaleParams(image, size) { + const imageScale = + config.blocks.blocksConfig['teaser'].imageScale || size || 'preview'; + + if (isString(image)) + return isInternalURL(image) + ? flattenToAppURL(`${image}/@@images/image/${imageScale}`) + : image; + + if (image) { + if (isInternalURL(getFieldURL(image))) { + if (image?.image_scales?.[image?.image_field]) { + const scale = + image.image_scales[image.image_field]?.[0].scales?.[imageScale] || + image.image_scales[image.image_field]?.[0]; + + const download = flattenToAppURL( + `${getFieldURL(image)}/${scale?.download}`, + ); + const width = scale?.width; + const height = scale?.height; + + return { + download, + width, + height, + }; + } else if (image?.image?.scales) { + const scale = image.image?.scales?.[imageScale] || image.image; + const download = flattenToAppURL(scale?.download); + const width = scale?.width; + const height = scale?.height; + + return { + download, + width, + height, + }; + } else { + //fallback if we do not have scales + return { + download: flattenToAppURL( + `${getFieldURL(image)}/@@images/${ + image.image_field || 'image' + }/${imageScale}`, + ), + }; + } + } else { + return { download: getFieldURL(image) }; + } + } +} diff --git a/src/hocs/withCachedImages.jsx b/src/hocs/withCachedImages.jsx index 99ff94b..b388104 100644 --- a/src/hocs/withCachedImages.jsx +++ b/src/hocs/withCachedImages.jsx @@ -1,5 +1,6 @@ import React from 'react'; import { isEmpty } from 'lodash'; +import { getImageScaleParams } from '@eeacms/volto-block-style/helpers'; export default function withCachedImages(WrappedComponent, config = {}) { return (props) => { @@ -13,7 +14,7 @@ export default function withCachedImages(WrappedComponent, config = {}) { if (!mounted.current) mounted.current = true; if (image && !images[image]) { const newImage = new Image(); - newImage.src = `${image}/@@images/image`; + newImage.src = getImageScaleParams(image)?.download; setImages({ ...images, [image]: null }); newImage.onload = () => { if (mounted.current) { From 99b24e95025c50e778613bb8ddbac0f194c06d3f Mon Sep 17 00:00:00 2001 From: nileshgulia1 Date: Thu, 13 Jul 2023 19:50:33 +0530 Subject: [PATCH 2/4] fix :jest undefined error --- src/helpers.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/helpers.js b/src/helpers.js index 3bd1c95..21fc4e3 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -21,7 +21,7 @@ export const getFieldURL = (data) => { export function getImageScaleParams(image, size) { const imageScale = - config.blocks.blocksConfig['teaser'].imageScale || size || 'preview'; + config.blocks.blocksConfig?.['teaser']?.imageScale || size || 'preview'; if (isString(image)) return isInternalURL(image) From 944dd2f185291ad8ad1ba20b61b53044da8ba8cb Mon Sep 17 00:00:00 2001 From: nileshgulia1 Date: Thu, 20 Jul 2023 13:55:50 +0530 Subject: [PATCH 3/4] fix: url when string --- src/helpers.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/helpers.js b/src/helpers.js index 21fc4e3..e745c7b 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -25,8 +25,8 @@ export function getImageScaleParams(image, size) { if (isString(image)) return isInternalURL(image) - ? flattenToAppURL(`${image}/@@images/image/${imageScale}`) - : image; + ? { download: flattenToAppURL(`${image}/@@images/image/${imageScale}`) } + : { download: image }; if (image) { if (isInternalURL(getFieldURL(image))) { From d3c4357dc052dfad8a46bf1dc383ac61de787e3d Mon Sep 17 00:00:00 2001 From: nileshgulia1 Date: Fri, 10 Nov 2023 12:35:24 +0530 Subject: [PATCH 4/4] specs: new method tests --- src/helpers.test.js | 145 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 144 insertions(+), 1 deletion(-) diff --git a/src/helpers.test.js b/src/helpers.test.js index 35e19a7..f46ff26 100644 --- a/src/helpers.test.js +++ b/src/helpers.test.js @@ -1,5 +1,148 @@ -import { getFieldURL } from './helpers'; +import { getFieldURL, getImageScaleParams } from './helpers'; +import { flattenToAppURL, isInternalURL } from '@plone/volto/helpers'; +jest.mock('@plone/volto/helpers', () => ({ + flattenToAppURL: jest.fn((url) => url), + isInternalURL: jest.fn((url) => true), +})); + +describe('getImageScaleParams', () => { + it('returns expected image scale URL obj when image_field and image_scales properties are passed', () => { + const image = { + '@id': 'http://localhost:3000/image', + image_field: 'image', + image_scales: { + image: [ + { + download: '@@images/image.png', + width: 400, + height: 400, + scales: { + preview: { + download: '@@images/image-400.png', + width: 400, + height: 400, + }, + }, + }, + ], + }, + }; + + const expectedUrlObj = { + download: 'http://localhost:3000/image/@@images/image-400.png', + width: 400, + height: 400, + }; + expect(getImageScaleParams(image, 'preview')).toEqual(expectedUrlObj); + }); + + it('returns expected image scale URL obj when image_field and image_scales properties are passed but with no scales', () => { + const image = { + '@id': 'http://localhost:3000/image', + image_field: 'image', + image_scales: { + image: [ + { + download: '@@images/image.png', + width: 400, + height: 400, + }, + ], + }, + }; + + const expectedUrlObj = { + download: 'http://localhost:3000/image/@@images/image.png', + width: 400, + height: 400, + }; + expect(getImageScaleParams(image, 'preview')).toEqual(expectedUrlObj); + }); + + it('returns expected image scale URL obj when image properties are passed', () => { + const image = { + '@id': 'http://localhost:3000/image', + image: { + download: 'http://localhost:3000/image/@@images/image.png', + width: 400, + height: 400, + scales: { + preview: { + download: 'http://localhost:3000/image/@@images/image-400.png', + width: 400, + height: 400, + }, + }, + }, + }; + const expectedUrlObj = { + download: 'http://localhost:3000/image/@@images/image-400.png', + width: 400, + height: 400, + }; + expect(getImageScaleParams(image, 'preview')).toEqual(expectedUrlObj); + }); + + it('calls flattenToAppURL when internalUrl', () => { + const url = 'http://localhost:3000/image'; + const size = 'large'; + getImageScaleParams(url, size); + expect(flattenToAppURL).toHaveBeenCalledWith('http://localhost:3000/image'); + }); + + it('returns expected image scale URL string when image url (string) is passed', () => { + const image = 'http://localhost:3000/image/@@images/image.png'; + expect(getImageScaleParams(image, 'preview')).toEqual({ + download: `${image}/@@images/image/preview`, + }); + }); + + it('returns image URL string when external image url (string) is passed', () => { + isInternalURL.mockReturnValue(false); + const image = 'http://external-url.com'; + expect(getImageScaleParams(image)).toEqual({ + download: image, + }); + }); + + it('returns image URL string when image url (object) with no scales is passed', () => { + isInternalURL.mockReturnValue(true); + const image = { + '@id': 'http://localhost:3000/image', + image: { + download: 'http://localhost:3000/image/@@images/image.png', + width: 400, + height: 400, + }, + }; + expect(getImageScaleParams(image)).toEqual({ + download: `${image['@id']}/@@images/image/preview`, + }); + }); + + it('returns image URL string when external image url (object) is passed', () => { + isInternalURL.mockReturnValue(false); + const image = { + '@id': 'http://external-url.com', + image: { + download: 'http://external-url.com', + width: 400, + height: 400, + scales: { + preview: { + download: 'hhttp://external-url.com', + width: 400, + height: 400, + }, + }, + }, + }; + expect(getImageScaleParams(image)).toEqual({ + download: image['@id'], + }); + }); +}); describe('getFieldURL', () => { it('handles a URL type object with type and value', () => { const data = {