From 946cf7f53c14d8f726d43241c3efbfb69e93a223 Mon Sep 17 00:00:00 2001 From: Kimmo Puputti Date: Fri, 13 Apr 2018 16:26:44 +0300 Subject: [PATCH] Use Image variants instead of sizes --- src/components/AddImages/AddImages.js | 6 +- src/components/Avatar/Avatar.example.js | 12 +- src/components/Avatar/Avatar.js | 41 +- .../ImageCarousel/ImageCarousel.example.js | 36 +- src/components/ImageCarousel/ImageCarousel.js | 12 +- src/components/ListingCard/ListingCard.js | 13 +- .../__snapshots__/ListingCard.test.js.snap | 18 +- .../ManageListingCard/ManageListingCard.js | 11 +- .../ManageListingCard.test.js.snap | 18 +- .../ResponsiveImage.example.js | 105 +--- .../ResponsiveImage/ResponsiveImage.js | 59 +- .../SearchMapInfoCard/SearchMapInfoCard.js | 6 +- .../SearchResultsPanel/SearchResultsPanel.js | 11 + .../TransactionPanel/TransactionPanel.js | 12 +- .../TransactionPanel.test.js.snap | 532 ++++++------------ src/components/UserCard/UserCard.example.js | 12 +- src/containers/CheckoutPage/CheckoutPage.js | 12 +- .../__snapshots__/CheckoutPage.test.js.snap | 38 +- .../EditListingPage/EditListingPage.duck.js | 15 +- src/containers/InboxPage/InboxPage.duck.js | 1 + .../ListingPage/ListingPage.duck.js | 11 +- .../ListingPage/ListingPage.test.js | 8 +- src/containers/ListingPage/SectionImages.js | 11 +- .../ManageListingsPage.duck.js | 5 +- .../ManageListingsPage/ManageListingsPage.js | 11 + .../ProfilePage/ProfilePage.duck.js | 19 +- .../ProfileSettingsForm.js | 7 +- .../ProfileSettingsPage.duck.js | 18 +- .../TransactionPage/TransactionPage.duck.js | 24 +- src/ducks/user.duck.js | 7 +- src/util/test-data.js | 9 +- src/util/types.js | 8 - 32 files changed, 454 insertions(+), 654 deletions(-) diff --git a/src/components/AddImages/AddImages.js b/src/components/AddImages/AddImages.js index ac3c298b..b216d097 100644 --- a/src/components/AddImages/AddImages.js +++ b/src/components/AddImages/AddImages.js @@ -55,11 +55,7 @@ const ThumbnailWrapper = props => { rootClassName={css.rootForImage} image={image} alt={savedImageAltText} - nameSet={[ - { name: 'landscape-crop', size: '400w' }, - { name: 'landscape-crop2x', size: '800w' }, - ]} - sizes="100%" + variants={['landscape-crop', 'landscape-crop2x']} /> diff --git a/src/components/Avatar/Avatar.example.js b/src/components/Avatar/Avatar.example.js index 00104452..9e5795c7 100644 --- a/src/components/Avatar/Avatar.example.js +++ b/src/components/Avatar/Avatar.example.js @@ -38,20 +38,20 @@ const userWithProfileImage = { id: new UUID('profile-image'), type: 'image', attributes: { - sizes: [ - { - name: 'square-xlarge2x', + variants: { + 'square-small': { + name: 'square-small', width: 240, height: 240, url: 'https://lorempixel.com/240/240/people/', }, - { - name: 'square-xlarge4x', + 'square-small2x': { + name: 'square-small2x', width: 480, height: 480, url: 'https://lorempixel.com/480/480/people/', }, - ], + }, }, }, }; diff --git a/src/components/Avatar/Avatar.js b/src/components/Avatar/Avatar.js index c7c2b02c..64865e30 100644 --- a/src/components/Avatar/Avatar.js +++ b/src/components/Avatar/Avatar.js @@ -1,5 +1,5 @@ import React from 'react'; -import PropTypes from 'prop-types'; +import { string, oneOfType, bool } from 'prop-types'; import { injectIntl, intlShape } from 'react-intl'; import classNames from 'classnames'; import { propTypes } from '../../util/types'; @@ -13,8 +13,21 @@ import { ResponsiveImage, IconBannedUser, NamedLink } from '../../components/'; import css from './Avatar.css'; +// Responsive image sizes hint +const AVATAR_SIZES = '40px'; +const AVATAR_SIZES_MEDIUM = '60px'; +const AVATAR_SIZES_LARGE = '96px'; + +const AVATAR_IMAGE_VARIANTS = [ + // 240x240 + 'square-small', + + // 480x480 + 'square-small2x', +]; + export const AvatarComponent = props => { - const { rootClassName, className, user, disableProfileLink, intl } = props; + const { rootClassName, className, user, renderSizes, disableProfileLink, intl } = props; const classes = classNames(rootClassName || css.root, className); const userIsCurrentUser = user && user.type === 'currentUser'; @@ -49,10 +62,8 @@ export const AvatarComponent = props => { rootClassName={css.avatarImage} alt={displayName} image={avatarUser.profileImage} - nameSet={[ - { name: 'square-xlarge2x', size: '1x' }, - { name: 'square-xlarge4x', size: '2x' }, - ]} + variants={AVATAR_IMAGE_VARIANTS} + sizes={renderSizes} /> ); @@ -63,10 +74,8 @@ export const AvatarComponent = props => { rootClassName={css.avatarImage} alt={displayName} image={avatarUser.profileImage} - nameSet={[ - { name: 'square-xlarge2x', size: '1x' }, - { name: 'square-xlarge4x', size: '2x' }, - ]} + variants={AVATAR_IMAGE_VARIANTS} + sizes={renderSizes} /> ); @@ -91,16 +100,16 @@ AvatarComponent.defaultProps = { className: null, rootClassName: null, user: null, + renderSizes: AVATAR_SIZES, disableProfileLink: false, }; -const { string, oneOfType, bool } = PropTypes; - AvatarComponent.propTypes = { rootClassName: string, className: string, user: oneOfType([propTypes.user, propTypes.currentUser]), + renderSizes: string, disableProfileLink: bool, // from injectIntl @@ -111,8 +120,12 @@ const Avatar = injectIntl(AvatarComponent); export default Avatar; -export const AvatarMedium = props => ; +export const AvatarMedium = props => ( + +); AvatarMedium.displayName = 'AvatarMedium'; -export const AvatarLarge = props => ; +export const AvatarLarge = props => ( + +); AvatarLarge.displayName = 'AvatarLarge'; diff --git a/src/components/ImageCarousel/ImageCarousel.example.js b/src/components/ImageCarousel/ImageCarousel.example.js index c27faebf..94229a49 100644 --- a/src/components/ImageCarousel/ImageCarousel.example.js +++ b/src/components/ImageCarousel/ImageCarousel.example.js @@ -13,32 +13,32 @@ const imageSquare = { id: new UUID('image-square'), type: 'image', attributes: { - sizes: [ - { + variants: { + [imageName]: { name: imageName, width: 400, height: 400, url: 'https://via.placeholder.com/400x400', }, - { + [imageName2x]: { name: imageName2x, width: 800, height: 800, url: 'https://via.placeholder.com/800x800', }, - { + [imageName4x]: { name: imageName4x, width: 1600, height: 1600, url: 'https://via.placeholder.com/1600x1600', }, - { + [imageName6x]: { name: imageName6x, width: 2400, height: 2400, url: 'https://via.placeholder.com/2400x2400', }, - ], + }, }, }; @@ -46,64 +46,64 @@ const imagePortrait = { id: new UUID('image-portrait'), type: 'image', attributes: { - sizes: [ - { + variants: { + [imageName]: { name: imageName, width: 400, height: 800, url: 'https://via.placeholder.com/400x800', }, - { + [imageName2x]: { name: imageName2x, width: 800, height: 1600, url: 'https://via.placeholder.com/800x1600', }, - { + [imageName4x]: { name: imageName4x, width: 800, height: 1600, url: 'https://via.placeholder.com/800x1600', }, - { + [imageName6x]: { name: imageName6x, width: 1200, height: 2400, url: 'https://via.placeholder.com/1200x2400', }, - ], + }, }, }; const imageLandscape = { id: new UUID('image-landscape'), type: 'image', attributes: { - sizes: [ - { + variants: { + [imageName]: { name: imageName, width: 400, height: 200, url: 'https://via.placeholder.com/400x200', }, - { + [imageName2x]: { name: imageName2x, width: 800, height: 400, url: 'https://via.placeholder.com/800x400', }, - { + [imageName4x]: { name: imageName4x, width: 1600, height: 800, url: 'https://via.placeholder.com/1600x800', }, - { + [imageName6x]: { name: imageName6x, width: 2400, height: 1200, url: 'https://via.placeholder.com/2400x1200', }, - ], + }, }, }; diff --git a/src/components/ImageCarousel/ImageCarousel.js b/src/components/ImageCarousel/ImageCarousel.js index 0e9aa72e..dfe40577 100644 --- a/src/components/ImageCarousel/ImageCarousel.js +++ b/src/components/ImageCarousel/ImageCarousel.js @@ -10,11 +10,6 @@ import css from './ImageCarousel.css'; const KEY_CODE_LEFT_ARROW = 37; const KEY_CODE_RIGHT_ARROW = 39; -const imageScaledSmall = 'scaled-small'; // width 320 -const imageScaledMedium = 'scaled-medium'; // width 750 -const imageScaledLarge = 'scaled-large'; // width 1024 -const imageScaledXLarge = 'scaled-xlarge'; // width 2400 - class ImageCarousel extends Component { constructor(props) { super(props); @@ -112,12 +107,7 @@ class ImageCarousel extends Component { image={images[this.state.selectedImageIndex]} onLoad={markImageLoaded(this.state.selectedImageIndex)} onError={markImageLoaded(this.state.selectedImageIndex)} - nameSet={[ - { name: imageScaledSmall, size: '320w' }, - { name: imageScaledMedium, size: '750w' }, - { name: imageScaledLarge, size: '1024w' }, - { name: imageScaledXLarge, size: '2400w' }, - ]} + variants={['scaled-small', 'scaled-medium', 'scaled-large', 'scaled-xlarge']} sizes="(max-width: 767px) 100vw, 80vw" /> diff --git a/src/components/ListingCard/ListingCard.js b/src/components/ListingCard/ListingCard.js index 66d69918..c80742f6 100644 --- a/src/components/ListingCard/ListingCard.js +++ b/src/components/ListingCard/ListingCard.js @@ -34,7 +34,7 @@ const priceData = (price, intl) => { }; export const ListingCardComponent = props => { - const { className, rootClassName, intl, listing, setActiveListing } = props; + const { className, rootClassName, intl, listing, renderSizes, setActiveListing } = props; const classes = classNames(rootClassName || css.root, className); const currentListing = ensureListing(listing); const id = currentListing.id.uuid; @@ -59,10 +59,8 @@ export const ListingCardComponent = props => { rootClassName={css.rootForImage} alt={title} image={firstImage} - nameSet={[ - { name: 'landscape-crop', size: '1x' }, - { name: 'landscape-crop2x', size: '2x' }, - ]} + variants={['landscape-crop', 'landscape-crop2x']} + sizes={renderSizes} /> @@ -98,6 +96,7 @@ export const ListingCardComponent = props => { ListingCardComponent.defaultProps = { className: null, rootClassName: null, + renderSizes: null, setActiveListing: () => null, }; @@ -106,6 +105,10 @@ ListingCardComponent.propTypes = { rootClassName: string, intl: intlShape.isRequired, listing: propTypes.listing.isRequired, + + // Responsive image sizes hint + renderSizes: string, + setActiveListing: func, }; diff --git a/src/components/ListingCard/__snapshots__/ListingCard.test.js.snap b/src/components/ListingCard/__snapshots__/ListingCard.test.js.snap index 747810e6..bc5d4ac9 100644 --- a/src/components/ListingCard/__snapshots__/ListingCard.test.js.snap +++ b/src/components/ListingCard/__snapshots__/ListingCard.test.js.snap @@ -20,21 +20,15 @@ exports[`ListingCard matches snapshot 1`] = ` alt="listing1 title" className={null} image={null} - nameSet={ - Array [ - Object { - "name": "landscape-crop", - "size": "1x", - }, - Object { - "name": "landscape-crop2x", - "size": "2x", - }, - ] - } noImageMessage={null} rootClassName={null} sizes={null} + variants={ + Array [ + "landscape-crop", + "landscape-crop2x", + ] + } /> diff --git a/src/components/ManageListingCard/ManageListingCard.js b/src/components/ManageListingCard/ManageListingCard.js index b7b87b7f..c087ceb9 100644 --- a/src/components/ManageListingCard/ManageListingCard.js +++ b/src/components/ManageListingCard/ManageListingCard.js @@ -107,6 +107,7 @@ export const ManageListingCardComponent = props => { onCloseListing, onOpenListing, onToggleMenu, + renderSizes, } = props; const classes = classNames(rootClassName || css.root, className); const currentListing = ensureOwnListing(listing); @@ -237,10 +238,8 @@ export const ManageListingCardComponent = props => { rootClassName={css.rootForImage} alt={title} image={firstImage} - nameSet={[ - { name: 'landscape-crop', size: '1x' }, - { name: 'landscape-crop2x', size: '2x' }, - ]} + variants={['landscape-crop', 'landscape-crop2x']} + sizes={renderSizes} />
@@ -323,6 +322,7 @@ ManageListingCardComponent.defaultProps = { className: null, rootClassName: null, actionsInProgressListingId: null, + renderSizes: null, }; const { bool, func, shape, string } = PropTypes; @@ -340,6 +340,9 @@ ManageListingCardComponent.propTypes = { onOpenListing: func.isRequired, onToggleMenu: func.isRequired, + // Responsive image sizes hint + renderSizes: string, + // from withRouter history: shape({ push: func.isRequired, diff --git a/src/components/ManageListingCard/__snapshots__/ManageListingCard.test.js.snap b/src/components/ManageListingCard/__snapshots__/ManageListingCard.test.js.snap index c08714ee..d54462e6 100644 --- a/src/components/ManageListingCard/__snapshots__/ManageListingCard.test.js.snap +++ b/src/components/ManageListingCard/__snapshots__/ManageListingCard.test.js.snap @@ -12,21 +12,15 @@ exports[`ManageListingCard matches snapshot 1`] = ` alt="listing1 title" className={null} image={null} - nameSet={ - Array [ - Object { - "name": "landscape-crop", - "size": "1x", - }, - Object { - "name": "landscape-crop2x", - "size": "2x", - }, - ] - } noImageMessage={null} rootClassName={null} sizes={null} + variants={ + Array [ + "landscape-crop", + "landscape-crop2x", + ] + } />
* // produces: * ListingX + * srcSet="url/to/landscape-crop.jpg 400w, url/to/landscape-crop2x.jpg 800w" /> * * Usage with sizes: * * // produces: @@ -28,10 +28,13 @@ * // This means that below 600px image will take as many pixels there are available on current * // viewport width (100vw) - and above that image will only take 50% of the page width. * // Browser decides which image it will fetch based on current screen size. + * + * NOTE: for all the possible image variant names and their respective + * sizes, see the API documentation. */ import React from 'react'; -import PropTypes from 'prop-types'; +import { arrayOf, string } from 'prop-types'; import classNames from 'classnames'; import { FormattedMessage } from 'react-intl'; import { propTypes } from '../../util/types'; @@ -40,10 +43,10 @@ import NoImageIcon from './NoImageIcon'; import css from './ResponsiveImage.css'; const ResponsiveImage = props => { - const { className, rootClassName, alt, noImageMessage, image, nameSet, sizes, ...rest } = props; + const { className, rootClassName, alt, noImageMessage, image, variants, ...rest } = props; const classes = classNames(rootClassName || css.root, className); - if (image == null || nameSet.length === 0) { + if (image == null || variants.length === 0) { const noImageClasses = classNames(rootClassName || css.root, css.noImageContainer, className); // NoImageMessage is needed for listing images on top the map (those component lose context) @@ -61,43 +64,37 @@ const ResponsiveImage = props => { /* eslint-enable jsx-a11y/img-redundant-alt */ } - const imageSizes = image.attributes.sizes; const imageVariants = image.attributes.variants; - const srcSet = nameSet - .map(v => { - const variant = imageVariants ? imageVariants[v.name] : null; + const srcSet = variants + .map(variantName => { + const variant = imageVariants[variantName]; - // deprecated - // for backwards compatibility only - const size = imageSizes ? imageSizes.find(i => i.name === v.name) : null; - - if (variant || size) { - const url = (variant || size).url; - return `${url} ${v.size}`; - } else { - // Handle case where the requested variant doesn't exist, for - // example because it hasn't been loaded yet. - // Return null, which will be filtered out. + if (!variant) { + // Variant not available (most like just not loaded yet) return null; } + return `${variant.url} ${variant.width}w`; }) .filter(v => v != null) .join(', '); - const sizesProp = sizes ? { sizes } : {}; + const imgProps = { + className: classes, + alt, + srcSet, + ...rest, + }; - return {alt}; + // alt prop already defined above + // eslint-disable-next-line jsx-a11y/alt-text + return ; }; -const { arrayOf, shape, string } = PropTypes; - ResponsiveImage.defaultProps = { className: null, rootClassName: null, image: null, - nameSet: [], - sizes: null, noImageMessage: null, }; @@ -106,13 +103,7 @@ ResponsiveImage.propTypes = { rootClassName: string, alt: string.isRequired, image: propTypes.image, - nameSet: arrayOf( - shape({ - name: string.isRequired, - size: string.isRequired, - }) - ), - sizes: string, + variants: arrayOf(string).isRequired, noImageMessage: string, }; diff --git a/src/components/SearchMapInfoCard/SearchMapInfoCard.js b/src/components/SearchMapInfoCard/SearchMapInfoCard.js index ccaed327..ede8af10 100644 --- a/src/components/SearchMapInfoCard/SearchMapInfoCard.js +++ b/src/components/SearchMapInfoCard/SearchMapInfoCard.js @@ -85,10 +85,8 @@ const ListingCard = props => { alt={title} noImageMessage={intl.formatMessage({ id: 'SearchMapInfoCard.noImage' })} image={firstImage} - nameSet={[ - { name: 'landscape-crop', size: '1x' }, - { name: 'landscape-crop2x', size: '2x' }, - ]} + variants={['landscape-crop', 'landscape-crop2x']} + sizes="250px" />
diff --git a/src/components/SearchResultsPanel/SearchResultsPanel.js b/src/components/SearchResultsPanel/SearchResultsPanel.js index fde4b18b..13386e9c 100644 --- a/src/components/SearchResultsPanel/SearchResultsPanel.js +++ b/src/components/SearchResultsPanel/SearchResultsPanel.js @@ -19,6 +19,16 @@ const SearchResultsPanel = props => { /> ) : null; + // Panel width relative to the viewport + const panelMediumWidth = 50; + const panelLargeWidth = 62.5; + const cardRenderSizes = [ + '(max-width: 767px) 100vw', + `(max-width: 1023px) ${panelMediumWidth}vw`, + `(max-width: 1920px) ${panelLargeWidth / 2}vw`, + `${panelLargeWidth / 3}vw`, + ].join(', '); + return (
@@ -27,6 +37,7 @@ const SearchResultsPanel = props => { className={css.listingCard} key={l.id.uuid} listing={l} + renderSizes={cardRenderSizes} setActiveListing={setActiveListing} /> ))} diff --git a/src/components/TransactionPanel/TransactionPanel.js b/src/components/TransactionPanel/TransactionPanel.js index 21eb14e6..1323068b 100644 --- a/src/components/TransactionPanel/TransactionPanel.js +++ b/src/components/TransactionPanel/TransactionPanel.js @@ -220,11 +220,7 @@ export class TransactionPanelComponent extends Component { rootClassName={css.rootForImage} alt={listingTitle} image={firstImage} - nameSet={[ - { name: 'landscape-crop', size: '400w' }, - { name: 'landscape-crop2x', size: '800w' }, - ]} - sizes="100vw" + variants={['landscape-crop', 'landscape-crop2x']} />
@@ -301,11 +297,7 @@ export class TransactionPanelComponent extends Component { rootClassName={css.rootForImage} alt={listingTitle} image={firstImage} - nameSet={[ - { name: 'landscape-crop', size: '400w' }, - { name: 'landscape-crop2x', size: '800w' }, - ]} - sizes="100%" + variants={['landscape-crop', 'landscape-crop2x']} /> diff --git a/src/components/TransactionPanel/__snapshots__/TransactionPanel.test.js.snap b/src/components/TransactionPanel/__snapshots__/TransactionPanel.test.js.snap index 7d1d30d9..ef904945 100644 --- a/src/components/TransactionPanel/__snapshots__/TransactionPanel.test.js.snap +++ b/src/components/TransactionPanel/__snapshots__/TransactionPanel.test.js.snap @@ -12,21 +12,14 @@ exports[`TransactionPanel - Order accepted matches snapshot 1`] = ` alt="listing1 title" className={null} image={null} - nameSet={ - Array [ - Object { - "name": "landscape-crop", - "size": "400w", - }, - Object { - "name": "landscape-crop2x", - "size": "800w", - }, - ] - } noImageMessage={null} rootClassName={null} - sizes="100vw" + variants={ + Array [ + "landscape-crop", + "landscape-crop2x", + ] + } /> @@ -845,21 +838,14 @@ exports[`TransactionPanel - Order accepted matches snapshot 1`] = ` alt="listing1 title" className={null} image={null} - nameSet={ - Array [ - Object { - "name": "landscape-crop", - "size": "400w", - }, - Object { - "name": "landscape-crop2x", - "size": "800w", - }, - ] - } noImageMessage={null} rootClassName={null} - sizes="100%" + variants={ + Array [ + "landscape-crop", + "landscape-crop2x", + ] + } /> @@ -1172,21 +1158,14 @@ exports[`TransactionPanel - Order autodeclined matches snapshot 1`] = ` alt="listing1 title" className={null} image={null} - nameSet={ - Array [ - Object { - "name": "landscape-crop", - "size": "400w", - }, - Object { - "name": "landscape-crop2x", - "size": "800w", - }, - ] - } noImageMessage={null} rootClassName={null} - sizes="100vw" + variants={ + Array [ + "landscape-crop", + "landscape-crop2x", + ] + } /> @@ -2005,21 +1984,14 @@ exports[`TransactionPanel - Order autodeclined matches snapshot 1`] = ` alt="listing1 title" className={null} image={null} - nameSet={ - Array [ - Object { - "name": "landscape-crop", - "size": "400w", - }, - Object { - "name": "landscape-crop2x", - "size": "800w", - }, - ] - } noImageMessage={null} rootClassName={null} - sizes="100%" + variants={ + Array [ + "landscape-crop", + "landscape-crop2x", + ] + } /> @@ -2332,21 +2304,14 @@ exports[`TransactionPanel - Order canceled matches snapshot 1`] = ` alt="listing1 title" className={null} image={null} - nameSet={ - Array [ - Object { - "name": "landscape-crop", - "size": "400w", - }, - Object { - "name": "landscape-crop2x", - "size": "800w", - }, - ] - } noImageMessage={null} rootClassName={null} - sizes="100vw" + variants={ + Array [ + "landscape-crop", + "landscape-crop2x", + ] + } /> @@ -3165,21 +3130,14 @@ exports[`TransactionPanel - Order canceled matches snapshot 1`] = ` alt="listing1 title" className={null} image={null} - nameSet={ - Array [ - Object { - "name": "landscape-crop", - "size": "400w", - }, - Object { - "name": "landscape-crop2x", - "size": "800w", - }, - ] - } noImageMessage={null} rootClassName={null} - sizes="100%" + variants={ + Array [ + "landscape-crop", + "landscape-crop2x", + ] + } /> @@ -3492,21 +3450,14 @@ exports[`TransactionPanel - Order declined matches snapshot 1`] = ` alt="listing1 title" className={null} image={null} - nameSet={ - Array [ - Object { - "name": "landscape-crop", - "size": "400w", - }, - Object { - "name": "landscape-crop2x", - "size": "800w", - }, - ] - } noImageMessage={null} rootClassName={null} - sizes="100vw" + variants={ + Array [ + "landscape-crop", + "landscape-crop2x", + ] + } /> @@ -4325,21 +4276,14 @@ exports[`TransactionPanel - Order declined matches snapshot 1`] = ` alt="listing1 title" className={null} image={null} - nameSet={ - Array [ - Object { - "name": "landscape-crop", - "size": "400w", - }, - Object { - "name": "landscape-crop2x", - "size": "800w", - }, - ] - } noImageMessage={null} rootClassName={null} - sizes="100%" + variants={ + Array [ + "landscape-crop", + "landscape-crop2x", + ] + } /> @@ -4652,21 +4596,14 @@ exports[`TransactionPanel - Order delivered matches snapshot 1`] = ` alt="listing1 title" className={null} image={null} - nameSet={ - Array [ - Object { - "name": "landscape-crop", - "size": "400w", - }, - Object { - "name": "landscape-crop2x", - "size": "800w", - }, - ] - } noImageMessage={null} rootClassName={null} - sizes="100vw" + variants={ + Array [ + "landscape-crop", + "landscape-crop2x", + ] + } /> @@ -5485,21 +5422,14 @@ exports[`TransactionPanel - Order delivered matches snapshot 1`] = ` alt="listing1 title" className={null} image={null} - nameSet={ - Array [ - Object { - "name": "landscape-crop", - "size": "400w", - }, - Object { - "name": "landscape-crop2x", - "size": "800w", - }, - ] - } noImageMessage={null} rootClassName={null} - sizes="100%" + variants={ + Array [ + "landscape-crop", + "landscape-crop2x", + ] + } /> @@ -5812,21 +5742,14 @@ exports[`TransactionPanel - Order enquired matches snapshot 1`] = ` alt="listing1 title" className={null} image={null} - nameSet={ - Array [ - Object { - "name": "landscape-crop", - "size": "400w", - }, - Object { - "name": "landscape-crop2x", - "size": "800w", - }, - ] - } noImageMessage={null} rootClassName={null} - sizes="100vw" + variants={ + Array [ + "landscape-crop", + "landscape-crop2x", + ] + } /> @@ -6645,21 +6568,14 @@ exports[`TransactionPanel - Order enquired matches snapshot 1`] = ` alt="listing1 title" className={null} image={null} - nameSet={ - Array [ - Object { - "name": "landscape-crop", - "size": "400w", - }, - Object { - "name": "landscape-crop2x", - "size": "800w", - }, - ] - } noImageMessage={null} rootClassName={null} - sizes="100%" + variants={ + Array [ + "landscape-crop", + "landscape-crop2x", + ] + } /> @@ -6972,21 +6888,14 @@ exports[`TransactionPanel - Order preauthorized matches snapshot 1`] = ` alt="listing1 title" className={null} image={null} - nameSet={ - Array [ - Object { - "name": "landscape-crop", - "size": "400w", - }, - Object { - "name": "landscape-crop2x", - "size": "800w", - }, - ] - } noImageMessage={null} rootClassName={null} - sizes="100vw" + variants={ + Array [ + "landscape-crop", + "landscape-crop2x", + ] + } /> @@ -7805,21 +7714,14 @@ exports[`TransactionPanel - Order preauthorized matches snapshot 1`] = ` alt="listing1 title" className={null} image={null} - nameSet={ - Array [ - Object { - "name": "landscape-crop", - "size": "400w", - }, - Object { - "name": "landscape-crop2x", - "size": "800w", - }, - ] - } noImageMessage={null} rootClassName={null} - sizes="100%" + variants={ + Array [ + "landscape-crop", + "landscape-crop2x", + ] + } /> @@ -8132,21 +8034,14 @@ exports[`TransactionPanel - Sale accepted matches snapshot 1`] = ` alt="listing1 title" className={null} image={null} - nameSet={ - Array [ - Object { - "name": "landscape-crop", - "size": "400w", - }, - Object { - "name": "landscape-crop2x", - "size": "800w", - }, - ] - } noImageMessage={null} rootClassName={null} - sizes="100vw" + variants={ + Array [ + "landscape-crop", + "landscape-crop2x", + ] + } /> @@ -8898,21 +8793,14 @@ exports[`TransactionPanel - Sale accepted matches snapshot 1`] = ` alt="listing1 title" className={null} image={null} - nameSet={ - Array [ - Object { - "name": "landscape-crop", - "size": "400w", - }, - Object { - "name": "landscape-crop2x", - "size": "800w", - }, - ] - } noImageMessage={null} rootClassName={null} - sizes="100%" + variants={ + Array [ + "landscape-crop", + "landscape-crop2x", + ] + } /> @@ -9200,21 +9088,14 @@ exports[`TransactionPanel - Sale autodeclined matches snapshot 1`] = ` alt="listing1 title" className={null} image={null} - nameSet={ - Array [ - Object { - "name": "landscape-crop", - "size": "400w", - }, - Object { - "name": "landscape-crop2x", - "size": "800w", - }, - ] - } noImageMessage={null} rootClassName={null} - sizes="100vw" + variants={ + Array [ + "landscape-crop", + "landscape-crop2x", + ] + } /> @@ -9966,21 +9847,14 @@ exports[`TransactionPanel - Sale autodeclined matches snapshot 1`] = ` alt="listing1 title" className={null} image={null} - nameSet={ - Array [ - Object { - "name": "landscape-crop", - "size": "400w", - }, - Object { - "name": "landscape-crop2x", - "size": "800w", - }, - ] - } noImageMessage={null} rootClassName={null} - sizes="100%" + variants={ + Array [ + "landscape-crop", + "landscape-crop2x", + ] + } /> @@ -10268,21 +10142,14 @@ exports[`TransactionPanel - Sale canceled matches snapshot 1`] = ` alt="listing1 title" className={null} image={null} - nameSet={ - Array [ - Object { - "name": "landscape-crop", - "size": "400w", - }, - Object { - "name": "landscape-crop2x", - "size": "800w", - }, - ] - } noImageMessage={null} rootClassName={null} - sizes="100vw" + variants={ + Array [ + "landscape-crop", + "landscape-crop2x", + ] + } /> @@ -11034,21 +10901,14 @@ exports[`TransactionPanel - Sale canceled matches snapshot 1`] = ` alt="listing1 title" className={null} image={null} - nameSet={ - Array [ - Object { - "name": "landscape-crop", - "size": "400w", - }, - Object { - "name": "landscape-crop2x", - "size": "800w", - }, - ] - } noImageMessage={null} rootClassName={null} - sizes="100%" + variants={ + Array [ + "landscape-crop", + "landscape-crop2x", + ] + } /> @@ -11336,21 +11196,14 @@ exports[`TransactionPanel - Sale declined matches snapshot 1`] = ` alt="listing1 title" className={null} image={null} - nameSet={ - Array [ - Object { - "name": "landscape-crop", - "size": "400w", - }, - Object { - "name": "landscape-crop2x", - "size": "800w", - }, - ] - } noImageMessage={null} rootClassName={null} - sizes="100vw" + variants={ + Array [ + "landscape-crop", + "landscape-crop2x", + ] + } /> @@ -12102,21 +11955,14 @@ exports[`TransactionPanel - Sale declined matches snapshot 1`] = ` alt="listing1 title" className={null} image={null} - nameSet={ - Array [ - Object { - "name": "landscape-crop", - "size": "400w", - }, - Object { - "name": "landscape-crop2x", - "size": "800w", - }, - ] - } noImageMessage={null} rootClassName={null} - sizes="100%" + variants={ + Array [ + "landscape-crop", + "landscape-crop2x", + ] + } /> @@ -12404,21 +12250,14 @@ exports[`TransactionPanel - Sale delivered matches snapshot 1`] = ` alt="listing1 title" className={null} image={null} - nameSet={ - Array [ - Object { - "name": "landscape-crop", - "size": "400w", - }, - Object { - "name": "landscape-crop2x", - "size": "800w", - }, - ] - } noImageMessage={null} rootClassName={null} - sizes="100vw" + variants={ + Array [ + "landscape-crop", + "landscape-crop2x", + ] + } /> @@ -13170,21 +13009,14 @@ exports[`TransactionPanel - Sale delivered matches snapshot 1`] = ` alt="listing1 title" className={null} image={null} - nameSet={ - Array [ - Object { - "name": "landscape-crop", - "size": "400w", - }, - Object { - "name": "landscape-crop2x", - "size": "800w", - }, - ] - } noImageMessage={null} rootClassName={null} - sizes="100%" + variants={ + Array [ + "landscape-crop", + "landscape-crop2x", + ] + } /> @@ -13472,21 +13304,14 @@ exports[`TransactionPanel - Sale enquired matches snapshot 1`] = ` alt="listing1 title" className={null} image={null} - nameSet={ - Array [ - Object { - "name": "landscape-crop", - "size": "400w", - }, - Object { - "name": "landscape-crop2x", - "size": "800w", - }, - ] - } noImageMessage={null} rootClassName={null} - sizes="100vw" + variants={ + Array [ + "landscape-crop", + "landscape-crop2x", + ] + } /> @@ -14238,21 +14063,14 @@ exports[`TransactionPanel - Sale enquired matches snapshot 1`] = ` alt="listing1 title" className={null} image={null} - nameSet={ - Array [ - Object { - "name": "landscape-crop", - "size": "400w", - }, - Object { - "name": "landscape-crop2x", - "size": "800w", - }, - ] - } noImageMessage={null} rootClassName={null} - sizes="100%" + variants={ + Array [ + "landscape-crop", + "landscape-crop2x", + ] + } /> @@ -14540,21 +14358,14 @@ exports[`TransactionPanel - Sale preauthorized matches snapshot 1`] = ` alt="listing1 title" className={null} image={null} - nameSet={ - Array [ - Object { - "name": "landscape-crop", - "size": "400w", - }, - Object { - "name": "landscape-crop2x", - "size": "800w", - }, - ] - } noImageMessage={null} rootClassName={null} - sizes="100vw" + variants={ + Array [ + "landscape-crop", + "landscape-crop2x", + ] + } /> @@ -15306,21 +15117,14 @@ exports[`TransactionPanel - Sale preauthorized matches snapshot 1`] = ` alt="listing1 title" className={null} image={null} - nameSet={ - Array [ - Object { - "name": "landscape-crop", - "size": "400w", - }, - Object { - "name": "landscape-crop2x", - "size": "800w", - }, - ] - } noImageMessage={null} rootClassName={null} - sizes="100%" + variants={ + Array [ + "landscape-crop", + "landscape-crop2x", + ] + } /> diff --git a/src/components/UserCard/UserCard.example.js b/src/components/UserCard/UserCard.example.js index 2fa5b9a3..86f79892 100644 --- a/src/components/UserCard/UserCard.example.js +++ b/src/components/UserCard/UserCard.example.js @@ -50,20 +50,20 @@ export const WithProfileImageAndBio = { id: new UUID('profile-image'), type: 'image', attributes: { - sizes: [ - { - name: 'square-xlarge2x', + variants: { + 'square-small': { + name: 'square-small', width: 240, height: 240, url: 'https://lorempixel.com/240/240/people/', }, - { - name: 'square-xlarge4x', + 'square-small2x': { + name: 'square-small2x', width: 480, height: 480, url: 'https://lorempixel.com/480/480/people/', }, - ], + }, }, }, }, diff --git a/src/containers/CheckoutPage/CheckoutPage.js b/src/containers/CheckoutPage/CheckoutPage.js index 6406ecab..447d54a4 100644 --- a/src/containers/CheckoutPage/CheckoutPage.js +++ b/src/containers/CheckoutPage/CheckoutPage.js @@ -340,11 +340,7 @@ export class CheckoutPageComponent extends Component { rootClassName={css.rootForImage} alt={listingTitle} image={firstImage} - nameSet={[ - { name: 'landscape-crop', size: '400w' }, - { name: 'landscape-crop2x', size: '800w' }, - ]} - sizes="100vw" + variants={['landscape-crop', 'landscape-crop2x']} />
@@ -394,11 +390,7 @@ export class CheckoutPageComponent extends Component { rootClassName={css.rootForImage} alt={listingTitle} image={firstImage} - nameSet={[ - { name: 'landscape-crop', size: '400w' }, - { name: 'landscape-crop2x', size: '800w' }, - ]} - sizes="100%" + variants={['landscape-crop', 'landscape-crop2x']} />
diff --git a/src/containers/CheckoutPage/__snapshots__/CheckoutPage.test.js.snap b/src/containers/CheckoutPage/__snapshots__/CheckoutPage.test.js.snap index 2c5342c4..c103a744 100644 --- a/src/containers/CheckoutPage/__snapshots__/CheckoutPage.test.js.snap +++ b/src/containers/CheckoutPage/__snapshots__/CheckoutPage.test.js.snap @@ -28,21 +28,14 @@ exports[`CheckoutPage matches snapshot 1`] = ` alt="listing1 title" className={null} image={null} - nameSet={ - Array [ - Object { - "name": "landscape-crop", - "size": "400w", - }, - Object { - "name": "landscape-crop2x", - "size": "800w", - }, - ] - } noImageMessage={null} rootClassName={null} - sizes="100vw" + variants={ + Array [ + "landscape-crop", + "landscape-crop2x", + ] + } />
diff --git a/src/containers/EditListingPage/EditListingPage.duck.js b/src/containers/EditListingPage/EditListingPage.duck.js index 3036f86c..677d6291 100644 --- a/src/containers/EditListingPage/EditListingPage.duck.js +++ b/src/containers/EditListingPage/EditListingPage.duck.js @@ -275,7 +275,13 @@ export function requestCreateListing(data) { // Modify store to understand that we have created listing and can redirect away dispatch(createListingSuccess(response)); // Fetch listing data so that redirection is smooth - dispatch(requestShowListing({ id, include: ['author', 'images'] })); + dispatch( + requestShowListing({ + id, + include: ['author', 'images'], + 'fields.image': ['variants.landscape-crop', 'variants.landscape-crop2x'], + }) + ); return response; }) .then(response => { @@ -316,7 +322,11 @@ export function requestUpdateListing(tab, data) { .update(data) .then(response => { updateResponse = response; - const payload = { id, include: ['author', 'images'] }; + const payload = { + id, + include: ['author', 'images'], + 'fields.image': ['variants.landscape-crop', 'variants.landscape-crop2x'], + }; return dispatch(requestShowListing(payload)); }) .then(() => { @@ -343,6 +353,7 @@ export function loadData(params) { const payload = { id: new UUID(id), include: ['author', 'images'], + 'fields.image': ['variants.landscape-crop', 'variants.landscape-crop2x'], }; return dispatch(requestShowListing(payload)); }; diff --git a/src/containers/InboxPage/InboxPage.duck.js b/src/containers/InboxPage/InboxPage.duck.js index 1c9a8f08..e5f0e9ec 100644 --- a/src/containers/InboxPage/InboxPage.duck.js +++ b/src/containers/InboxPage/InboxPage.duck.js @@ -91,6 +91,7 @@ export const loadData = (params, search) => (dispatch, getState, sdk) => { const apiQueryParams = { only: onlyFilter, include: ['provider', 'provider.profileImage', 'customer', 'customer.profileImage', 'booking'], + 'fields.image': ['variants.square-small', 'variants.square-small2x'], page, per_page: INBOX_PAGE_SIZE, }; diff --git a/src/containers/ListingPage/ListingPage.duck.js b/src/containers/ListingPage/ListingPage.duck.js index 3ae7305b..2c18d93a 100644 --- a/src/containers/ListingPage/ListingPage.duck.js +++ b/src/containers/ListingPage/ListingPage.duck.js @@ -124,8 +124,8 @@ export const showListing = (listingId, isOwn = false) => (dispatch, getState, sd 'variants.scaled-xlarge', // Avatars - 'variants.square-xlarge2x', - 'variants.square-xlarge4x', + 'variants.square-small', + 'variants.square-small2x', ], }; @@ -143,7 +143,12 @@ export const showListing = (listingId, isOwn = false) => (dispatch, getState, sd export const fetchReviews = listingId => (dispatch, getState, sdk) => { return sdk.reviews - .query({ listing_id: listingId, state: 'public', include: ['author', 'author.profileImage'] }) + .query({ + listing_id: listingId, + state: 'public', + include: ['author', 'author.profileImage'], + 'fields.image': ['variants.square-small', 'variants.square-small2x'], + }) .then(response => { const reviews = denormalisedResponseEntities(response); dispatch(fetchReviewsSuccess(reviews)); diff --git a/src/containers/ListingPage/ListingPage.test.js b/src/containers/ListingPage/ListingPage.test.js index 7013c4d7..fc2ecd4f 100644 --- a/src/containers/ListingPage/ListingPage.test.js +++ b/src/containers/ListingPage/ListingPage.test.js @@ -116,8 +116,8 @@ describe('ListingPage', () => { 'variants.scaled-xlarge', // Avatars - 'variants.square-xlarge2x', - 'variants.square-xlarge4x', + 'variants.square-small', + 'variants.square-small2x', ], }, ], @@ -163,8 +163,8 @@ describe('ListingPage', () => { 'variants.scaled-xlarge', // Avatars - 'variants.square-xlarge2x', - 'variants.square-xlarge4x', + 'variants.square-small', + 'variants.square-small2x', ], }, ], diff --git a/src/containers/ListingPage/SectionImages.js b/src/containers/ListingPage/SectionImages.js index 2bfcc2f9..675e09dc 100644 --- a/src/containers/ListingPage/SectionImages.js +++ b/src/containers/ListingPage/SectionImages.js @@ -46,13 +46,12 @@ const SectionImages = props => { rootClassName={css.rootForImage} alt={title} image={firstImage} - nameSet={[ - { name: 'landscape-crop', size: '400w' }, - { name: 'landscape-crop2x', size: '800w' }, - { name: 'landscape-crop4x', size: '1600w' }, - { name: 'landscape-crop6x', size: '2400w' }, + variants={[ + 'landscape-crop', + 'landscape-crop2x', + 'landscape-crop4x', + 'landscape-crop6x', ]} - sizes="100vw" /> {viewPhotosButton}
diff --git a/src/containers/ManageListingsPage/ManageListingsPage.duck.js b/src/containers/ManageListingsPage/ManageListingsPage.duck.js index 3e63e18a..55e8b609 100644 --- a/src/containers/ManageListingsPage/ManageListingsPage.duck.js +++ b/src/containers/ManageListingsPage/ManageListingsPage.duck.js @@ -216,10 +216,11 @@ export const queryListingsError = e => ({ export const queryOwnListings = queryParams => (dispatch, getState, sdk) => { dispatch(queryListingsRequest(queryParams)); - const { include = [], page, perPage } = queryParams; + const { perPage, ...rest } = queryParams; + const params = { ...rest, per_page: perPage }; return sdk.ownListings - .query({ include, page, per_page: perPage }) + .query(params) .then(response => { dispatch(addOwnEntities(response)); dispatch(queryListingsSuccess(response)); diff --git a/src/containers/ManageListingsPage/ManageListingsPage.js b/src/containers/ManageListingsPage/ManageListingsPage.js index 85f4245e..fb2751fa 100644 --- a/src/containers/ManageListingsPage/ManageListingsPage.js +++ b/src/containers/ManageListingsPage/ManageListingsPage.js @@ -112,6 +112,14 @@ export class ManageListingsPageComponent extends Component { const title = intl.formatMessage({ id: 'ManageListingsPage.title' }); + const panelWidth = 62.5; + // Render hints for responsive image + const renderSizes = [ + `(max-width: 767px) 100vw`, + `(max-width: 1920px) ${panelWidth / 2}vw`, + `${panelWidth / 3}vw`, + ].join(', '); + return ( @@ -137,6 +145,7 @@ export class ManageListingsPageComponent extends Component { onOpenListing={onOpenListing} hasOpeningError={openingErrorListingId.uuid === l.id.uuid} hasClosingError={closingErrorListingId.uuid === l.id.uuid} + renderSizes={renderSizes} /> ))} @@ -234,6 +243,8 @@ ManageListingsPage.loadData = (params, search) => { page, perPage: RESULT_PAGE_SIZE, include: ['images'], + 'fields.image': ['variants.landscape-crop', 'variants.landscape-crop2x'], + 'limit.images': 1, }); }; diff --git a/src/containers/ProfilePage/ProfilePage.duck.js b/src/containers/ProfilePage/ProfilePage.duck.js index 670cdc19..9953951f 100644 --- a/src/containers/ProfilePage/ProfilePage.duck.js +++ b/src/containers/ProfilePage/ProfilePage.duck.js @@ -124,7 +124,11 @@ export const queryReviewsError = e => ({ export const queryUserListings = userId => (dispatch, getState, sdk) => { dispatch(queryListingsRequest(userId)); return sdk.listings - .query({ author_id: userId, include: ['author', 'images'] }) + .query({ + author_id: userId, + include: ['author', 'images'], + 'fields.image': ['variants.landscape-crop', 'variants.landscape-crop2x'], + }) .then(response => { // Pick only the id and type properties from the response listings const listingRefs = response.data.data.map(({ id, type }) => ({ id, type })); @@ -137,7 +141,12 @@ export const queryUserListings = userId => (dispatch, getState, sdk) => { export const queryUserReviews = userId => (dispatch, getState, sdk) => { sdk.reviews - .query({ subject_id: userId, state: 'public', include: ['author', 'author.profileImage'] }) + .query({ + subject_id: userId, + state: 'public', + include: ['author', 'author.profileImage'], + 'fields.image': ['variants.square-small', 'variants.square-small2x'], + }) .then(response => { const reviews = denormalisedResponseEntities(response); dispatch(queryReviewsSuccess(reviews)); @@ -148,7 +157,11 @@ export const queryUserReviews = userId => (dispatch, getState, sdk) => { export const showUser = userId => (dispatch, getState, sdk) => { dispatch(showUserRequest(userId)); return sdk.users - .show({ id: userId, include: ['profileImage'] }) + .show({ + id: userId, + include: ['profileImage'], + 'fields.image': ['variants.square-small', 'variants.square-small2x'], + }) .then(response => { dispatch(addMarketplaceEntities(response)); dispatch(showUserSuccess()); diff --git a/src/containers/ProfileSettingsForm/ProfileSettingsForm.js b/src/containers/ProfileSettingsForm/ProfileSettingsForm.js index c0f6f64f..da04e006 100644 --- a/src/containers/ProfileSettingsForm/ProfileSettingsForm.js +++ b/src/containers/ProfileSettingsForm/ProfileSettingsForm.js @@ -191,7 +191,12 @@ class ProfileSettingsFormComponent extends Component { }); const avatarComponent = !fileUploadInProgress && profileImage.imageId ? ( - + ) : null; const chooseAvatarLabel = diff --git a/src/containers/ProfileSettingsPage/ProfileSettingsPage.duck.js b/src/containers/ProfileSettingsPage/ProfileSettingsPage.duck.js index 65328756..b2683b3a 100644 --- a/src/containers/ProfileSettingsPage/ProfileSettingsPage.duck.js +++ b/src/containers/ProfileSettingsPage/ProfileSettingsPage.duck.js @@ -115,8 +115,16 @@ export function uploadImage(actionPayload) { const id = actionPayload.id; dispatch(uploadImageRequest(actionPayload)); + const bodyParams = { + image: actionPayload.file, + }; + const queryParams = { + expand: true, + 'fields.image': ['variants.square-small', 'variants.square-small2x'], + }; + return sdk.images - .uploadProfileImage({ image: actionPayload.file }, { expand: true }) + .uploadProfileImage(bodyParams, queryParams) .then(resp => { const uploadedImage = resp.data.data; dispatch(uploadImageSuccess({ data: { id, uploadedImage } })); @@ -129,8 +137,14 @@ export const updateProfile = actionPayload => { return (dispatch, getState, sdk) => { dispatch(updateProfileRequest()); + const queryParams = { + expand: true, + include: ['profileImage'], + 'fields.image': ['variants.square-small', 'variants.square-small2x'], + }; + return sdk.currentUser - .updateProfile(actionPayload, { expand: true, include: ['profileImage'] }) + .updateProfile(actionPayload, queryParams) .then(response => { dispatch(updateProfileSuccess(response)); diff --git a/src/containers/TransactionPage/TransactionPage.duck.js b/src/containers/TransactionPage/TransactionPage.duck.js index fdab3ba9..4479a409 100644 --- a/src/containers/TransactionPage/TransactionPage.duck.js +++ b/src/containers/TransactionPage/TransactionPage.duck.js @@ -218,6 +218,7 @@ export const fetchTransaction = id => (dispatch, getState, sdk) => { 'reviews.author', 'reviews.subject', ], + ...IMAGE_VARIANTS, }, { expand: true } ) @@ -235,6 +236,7 @@ export const fetchTransaction = id => (dispatch, getState, sdk) => { return sdk.listings.show({ id: listingId, include: ['author', 'author.profileImage', 'images'], + ...IMAGE_VARIANTS, }); } else { return response; @@ -305,7 +307,12 @@ const fetchMessages = (txId, page) => (dispatch, getState, sdk) => { dispatch(fetchMessagesRequest()); return sdk.messages - .query({ transaction_id: txId, include: ['sender', 'sender.profileImage'], ...paging }) + .query({ + transaction_id: txId, + include: ['sender', 'sender.profileImage'], + ...IMAGE_VARIANTS, + ...paging, + }) .then(response => { const messages = denormalisedResponseEntities(response); const { totalItems, totalPages, page: fetchedPage } = response.data.meta; @@ -375,6 +382,17 @@ export const sendMessage = (txId, message) => (dispatch, getState, sdk) => { }; const REVIEW_TX_INCLUDES = ['reviews', 'reviews.author', 'reviews.subject']; +const IMAGE_VARIANTS = { + 'fields.image': [ + // Profile images + 'variants.square-small', + 'variants.square-small2x', + + // Listing images: + 'variants.landscape-crop', + 'variants.landscape-crop2x', + ], +}; // If other party has already sent a review, we need to make transition to // TRANSITION_REVIEW_2_BY_ @@ -385,7 +403,7 @@ const sendReviewAsSecond = (id, params, role, dispatch, sdk) => { const include = REVIEW_TX_INCLUDES; return sdk.transactions - .transition({ id, transition, params }, { expand: true, include }) + .transition({ id, transition, params }, { expand: true, include, ...IMAGE_VARIANTS }) .then(response => { dispatch(addMarketplaceEntities(response)); dispatch(sendReviewSuccess()); @@ -411,7 +429,7 @@ const sendReviewAsFirst = (id, params, role, dispatch, sdk) => { const include = REVIEW_TX_INCLUDES; return sdk.transactions - .transition({ id, transition, params }, { expand: true, include }) + .transition({ id, transition, params }, { expand: true, include, ...IMAGE_VARIANTS }) .then(response => { dispatch(addMarketplaceEntities(response)); dispatch(sendReviewSuccess()); diff --git a/src/ducks/user.duck.js b/src/ducks/user.duck.js index 45805c41..77398ee0 100644 --- a/src/ducks/user.duck.js +++ b/src/ducks/user.duck.js @@ -332,8 +332,13 @@ export const fetchCurrentUser = () => (dispatch, getState, sdk) => { return Promise.resolve({}); } + const params = { + include: ['profileImage'], + 'fields.image': ['variants.square-small', 'variants.square-small2x'], + }; + return sdk.currentUser - .show({ include: ['profileImage'] }) + .show(params) .then(response => { const entities = denormalisedResponseEntities(response); if (entities.length !== 1) { diff --git a/src/util/test-data.js b/src/util/test-data.js index b9f80707..8d9607f2 100644 --- a/src/util/test-data.js +++ b/src/util/test-data.js @@ -60,20 +60,21 @@ export const createImage = id => ({ id: new UUID(id), type: 'image', attributes: { - sizes: [ - { + variants: { + // TODO: add all possible variants here + square: { name: 'square', height: 408, width: 408, url: 'https://via.placeholder.com/408x408', }, - { + square2x: { name: 'square2x', height: 816, width: 816, url: 'https://via.placeholder.com/816x816', }, - ], + }, }, }); diff --git a/src/util/types.js b/src/util/types.js index a7de323d..5250541f 100644 --- a/src/util/types.js +++ b/src/util/types.js @@ -80,14 +80,6 @@ propTypes.image = shape({ id: propTypes.uuid.isRequired, type: propTypes.value('image').isRequired, attributes: shape({ - sizes: arrayOf( - shape({ - width: number.isRequired, - height: number.isRequired, - name: string.isRequired, - url: string.isRequired, - }) - ), variants: objectOf( shape({ width: number.isRequired,