Skip to content

Commit

Permalink
Replace design screenshots with mShots in New Onboarding (#43428)
Browse files Browse the repository at this point in the history
Co-authored-by: Andrew Serong <[email protected]>
Co-authored-by: Julian de Bhal <[email protected]>
Co-authored-by: Louis Laugesen <[email protected]>
  • Loading branch information
4 people authored Jan 22, 2021
1 parent af234ca commit fcadad2
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 32 deletions.
48 changes: 22 additions & 26 deletions client/landing/gutenboarding/available-designs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { addQueryArgs } from '@wordpress/url';
* Internal dependencies
*/
import { isEnabled } from '../../config';
import { mshotsUrl } from './components/mshots-image';
import type { Design } from './stores/onboard/types';
const availableDesignsConfig = require( './available-designs-config.json' );

Expand All @@ -26,45 +27,40 @@ function getCanUseWebP() {
return false;
}

const canUseWebP = getCanUseWebP();

export const getDesignImageUrl = ( design: Design ) => {
// We temporarily show pre-generated screenshots until we can generate tall versions dynamically using mshots.
// See `bin/generate-gutenboarding-design-thumbnails.js` for generating screenshots.
// https://github.com/Automattic/mShots/issues/16
// https://github.com/Automattic/wp-calypso/issues/40564
if ( ! isEnabled( 'gutenboarding/mshot-preview' ) ) {
// When we update the static images, bump the version for cache busting
return `/calypso/images/design-screenshots/${ design.slug }_${ design.template }_${
design.theme
}.${ canUseWebP ? 'webp' : 'jpg' }?v=3`;
}
export const getDesignUrl = ( design: Design, locale: string ): string => {
const theme = encodeURIComponent( design.theme );
const template = encodeURIComponent( design.template );

const mshotsUrl = 'https://s.wordpress.com/mshots/v1/';
const designsEndpoint = 'https://public-api.wordpress.com/rest/v1/template/demo/';
const previewUrl = addQueryArgs(
`${ designsEndpoint }${ encodeURIComponent( design.theme ) }/${ encodeURIComponent(
design.template
) }`,
return addQueryArgs(
`https://public-api.wordpress.com/rest/v1/template/demo/${ theme }/${ template }`,
{
font_headings: design.fonts.headings,
font_base: design.fonts.base,
site_title: design.title,
viewport_height: 700, // todo: this is part of the issue with rockfield, a value of 3072 here fixes the background image
language: locale,
}
);
return mshotsUrl + encodeURIComponent( previewUrl );
};

/**
* Asynchronously load available design images
*/
export function prefetchDesignThumbs() {
const canUseWebP = getCanUseWebP();

export const getDesignImageUrl = ( design: Design ): string => {
return `/calypso/images/design-screenshots/${ design.slug }_${ design.template }_${
design.theme
}.${ canUseWebP ? 'webp' : 'jpg' }?v=3`;
};

// Asynchronously load available design images
export function prefetchDesignThumbs( locale: string ): void {
if ( typeof window !== 'undefined' ) {
getAvailableDesigns().featured.forEach( ( design: Design ) => {
const href = getDesignImageUrl( design );
const href = mshotsUrl( getDesignUrl( design, locale ) );
const link = document.createElement( 'link' );
link.rel = 'prefetch';
link.as = 'image';
link.href = href;
link.crossOrigin = 'anonymous';
document.head.appendChild( link );
} );
}
Expand All @@ -73,7 +69,7 @@ export function prefetchDesignThumbs() {
export function getAvailableDesigns(
includeAlphaDesigns: boolean = isEnabled( 'gutenboarding/alpha-templates' ),
useFseDesigns: boolean = isEnabled( 'gutenboarding/site-editor' )
) {
): AvailableDesigns {
let designs = availableDesigns;

if ( ! includeAlphaDesigns ) {
Expand Down
72 changes: 72 additions & 0 deletions client/landing/gutenboarding/components/mshots-image/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/**
* External dependencies
*/
import React, { useState } from 'react';
import classnames from 'classnames';
import { addQueryArgs } from '@wordpress/url';

/**
* Style dependencies
*/
import './style.scss';

interface MShotsImageProps {
url: string;
alt: string;
'aria-labelledby': string;
}

const mShotsParams = {
// viewport size (how much of the source page to capture)
vpw: 1200,
vph: 3072,
// size of the resulting image
w: 700,
h: 1800,
};

export function mshotsUrl( url: string, count = 0 ): string {
const mshotsUrl = 'https://s0.wp.com/mshots/v1/';
const mshotsRequest = addQueryArgs( mshotsUrl + encodeURIComponent( url ), {
...mShotsParams,
// this doesn't seem to work:
// requeue: true, // Uncomment this line to force the screenshots to be regenerated
count,
} );
return mshotsRequest;
}

const MShotsImage = ( {
url,
'aria-labelledby': labelledby,
alt,
}: MShotsImageProps ): JSX.Element => {
const [ count, setCount ] = React.useState( 0 );
const [ visible, setVisible ] = useState( false );
return (
<div className="mshots-image__container">
{ ! visible && <div className="mshots-image__loader"></div> }
<img
className={ classnames( 'mshots-image' ) }
style={ { opacity: visible ? 1 : 0 } }
alt={ alt }
aria-labelledby={ labelledby }
src={ mshotsUrl( url, count ) }
onLoad={ ( e ) => {
// Test against mshots h value
if ( e.currentTarget.naturalHeight !== mShotsParams.h ) {
// Only refresh 10 times.
if ( count < 10 ) {
// Triggers a target.src change
setTimeout( () => setCount( count + 1 ), 1000 );
}
} else {
setVisible( true );
}
} }
/>
</div>
);
};

export default MShotsImage;
19 changes: 19 additions & 0 deletions client/landing/gutenboarding/components/mshots-image/style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
@import '../../mixins.scss';

.mshots-image {
opacity: 0;
transition: 0.3s opacity;
}

.mshots-image__loader {
@include onboarding-placeholder();
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
}

.mshots-image-visible {
opacity: 1;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import { Tooltip } from '@wordpress/components';
import { useDispatch, useSelect } from '@wordpress/data';
import { useI18n } from '@automattic/react-i18n';
import { useLocale } from '@automattic/i18n-utils';
import React from 'react';
import { Title, SubTitle, ActionButtons, BackButton } from '@automattic/onboarding';

Expand All @@ -15,10 +16,12 @@ import { STORE_KEY as ONBOARD_STORE } from '../../stores/onboard';
import { useTrackStep } from '../../hooks/use-track-step';
import useStepNavigation from '../../hooks/use-step-navigation';
import Badge from '../../components/badge';
import { getDesignImageUrl } from '../../available-designs';
import MShotsImage from '../../components/mshots-image';
import { getDesignImageUrl, getDesignUrl } from '../../available-designs';
import JetpackLogo from 'calypso/components/jetpack-logo'; // @TODO: extract to @automattic package
import type { Design } from '../../stores/onboard/types';
import { useIsAnchorFm } from '../../path';
import { isEnabled } from 'calypso/config';

/**
* Style dependencies
Expand All @@ -29,6 +32,7 @@ const makeOptionId = ( { slug }: Design ): string => `design-selector__option-na

const DesignSelector: React.FunctionComponent = () => {
const { __ } = useI18n();
const locale = useLocale();
const { goBack, goNext } = useStepNavigation();

const { setSelectedDesign, setFonts } = useDispatch( ONBOARD_STORE );
Expand Down Expand Up @@ -85,11 +89,19 @@ const DesignSelector: React.FunctionComponent = () => {
} }
>
<span className="design-selector__image-frame">
<img
alt=""
aria-labelledby={ makeOptionId( design ) }
src={ getDesignImageUrl( design ) }
/>
{ isEnabled( 'gutenboarding/mshot-preview' ) ? (
<MShotsImage
url={ getDesignUrl( design, locale ) }
aria-labelledby={ makeOptionId( design ) }
alt=""
/>
) : (
<img
alt=""
aria-labelledby={ makeOptionId( design ) }
src={ getDesignImageUrl( design ) }
/>
) }
</span>
<span className="design-selector__option-overlay">
<span id={ makeOptionId( design ) } className="design-selector__option-meta">
Expand Down

0 comments on commit fcadad2

Please sign in to comment.