Skip to content

Commit

Permalink
Signup: DSS: Render DssScreenshot with pure props
Browse files Browse the repository at this point in the history
Removes the dependence on stores within DssScreenshot
  • Loading branch information
sirbrillig committed Dec 3, 2015
1 parent eec5860 commit 0e20b77
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 51 deletions.
23 changes: 22 additions & 1 deletion client/signup/steps/dss/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import StepWrapper from 'signup/step-wrapper';
import ThemeHelper from 'lib/themes/helpers';
import DynamicScreenshotsActions from 'lib/dss/actions';
import DSSImageStore from 'lib/dss/image-store';
import ThemePreviewStore from 'lib/dss/preview-store';
import ImagePreloader from 'components/image-preloader';

const debug = debugFactory( 'calypso:dss' );
Expand Down Expand Up @@ -43,22 +44,39 @@ export default React.createClass( {
return {
isLoading: false,
renderComplete: false,
markupAndStyles: {},
dssImage: null
};
},

componentWillMount() {
ThemePreviewStore.on( 'change', this.updateMarkup );
DSSImageStore.on( 'change', this.updateScreenshot );
this.loadThemePreviews();
},

componentWillUnmount() {
ThemePreviewStore.off( 'change', this.updateMarkup );
DSSImageStore.off( 'change', this.updateScreenshot );
},

componentWillReceiveProps() {
this.loadThemePreviews();
},

loadThemePreviews() {
debug( 'loading theme previews for these themes', this.props.themes );
this.props.themes.map( theme => DynamicScreenshotsActions.fetchThemePreview( 'pub/' + ThemeHelper.getSlugFromName( theme ) ) );
},

updateMarkup() {
this.setState( { markupAndStyles: ThemePreviewStore.get() } );
},

updateScreenshot() {
const { isLoading, lastKey, imageResultsByKey } = DSSImageStore.get();
if ( ! imageResultsByKey[ lastKey ] ) {
return this.setState( Object.assign( {}, this.getInitialState(), { isLoading } ) );
return this.setState( { isLoading, renderComplete: false, dssImage: null } );
}
const dssImage = imageResultsByKey[ lastKey ];
this.setState( { isLoading, dssImage } );
Expand Down Expand Up @@ -114,6 +132,9 @@ export default React.createClass( {
themeName={ theme }
themeSlug={ ThemeHelper.getSlugFromName( theme ) }
themeRepoSlug={ 'pub/' + ThemeHelper.getSlugFromName( theme ) }
isLoading={ this.state.isLoading }
dssImage={ this.state.dssImage }
markupAndStyles={ this.state.markupAndStyles[ 'pub/' + ThemeHelper.getSlugFromName( theme ) ] }
renderComplete={ this.state.renderComplete }
{ ...this.props }/>;
} ) }
Expand Down
68 changes: 18 additions & 50 deletions client/signup/steps/dss/screenshot.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,8 @@
* External dependencies
*/
import React from 'react';
import debugFactory from 'debug';
import classnames from 'classnames';

/**
* Internal dependencies
*/
import DynamicScreenshotsActions from 'lib/dss/actions';
import ThemePreviewStore from 'lib/dss/preview-store';
import DSSImageStore from 'lib/dss/image-store';

const debug = debugFactory( 'calypso:dss:screenshot' );

function replaceMarkupWithImage( markup, imageUrl ) {
return markup.replace( /(<img [^>]+)src=['"][^'"]+['"]([^>]*>)/g, ( ...imgMatches ) => {
if ( imgMatches.length < 3 ) {
Expand All @@ -34,67 +24,45 @@ export default React.createClass( {
screenshotUrl: React.PropTypes.string.isRequired,
themeRepoSlug: React.PropTypes.string.isRequired,
themeSlug: React.PropTypes.string.isRequired,
isLoading: React.PropTypes.bool,
dssImage: React.PropTypes.object,
markupAndStyles: React.PropTypes.object,
renderComplete: React.PropTypes.bool
},

getInitialState() {
return {
isLoading: false,
markup: '',
styles: '',
dssImage: null
};
},

componentWillMount() {
ThemePreviewStore.on( 'change', this.updateScreenshot );
DSSImageStore.on( 'change', this.updateScreenshot );
DynamicScreenshotsActions.fetchThemePreview( this.props.themeRepoSlug );
},

componentWillUnmount() {
ThemePreviewStore.off( 'change', this.updateScreenshot );
DSSImageStore.off( 'change', this.updateScreenshot );
},

getAdditionalStyles( imageUrl ) {
return `#theme-${this.props.themeSlug} .hero.with-featured-image{background-image:url(${imageUrl});}`;
},

getMarkupAndStyles() {
if ( ! this.state.markup || ! this.state.styles ) {
return ThemePreviewStore.get()[ this.props.themeRepoSlug ] || { markup: null, styles: null };
}
return { markup: this.state.markup, styles: this.state.styles };
getPreviewStyles() {
return { __html: this.props.markupAndStyles.styles };
},

updateScreenshot() {
const { isLoading, lastKey, imageResultsByKey } = DSSImageStore.get();
if ( ! imageResultsByKey[ lastKey ] ) {
return this.setState( Object.assign( {}, this.getInitialState(), { isLoading } ) );
}
const dssImage = imageResultsByKey[ lastKey ];
debug( 'replacing images in ' + this.props.themeRepoSlug + ' screenshot with', dssImage.url );
const { markup, styles } = this.getMarkupAndStyles();
return this.setState( { dssImage, markup, styles, isLoading } );
getPreviewAdditionalStyles() {
return { __html: this.props.dssImage ? this.getAdditionalStyles( this.props.dssImage.url ) : '' };
},

getPreviewMarkup() {
return { __html: this.props.dssImage ? replaceMarkupWithImage( this.props.markupAndStyles.markup, this.props.dssImage.url ) : this.props.markupAndStyles.markup };
},

render() {
const { markup, styles } = this.props.markupAndStyles || { markup: null, styles: null };
const containerClassNames = classnames( 'dss-screenshot', {
'is-loading': this.state.isLoading,
'is-preview-ready': this.state.markup && this.state.styles && this.props.renderComplete
'is-loading': this.props.isLoading,
'is-preview-ready': markup && styles && this.props.renderComplete
} );

if ( this.state.markup && this.state.styles ) {
if ( markup && styles ) {
return (
<div className={ containerClassNames }>
<div className="dss-screenshot__original">
<img src={ this.props.screenshotUrl } alt={ this.translate( 'Loading…' ) } />
</div>
<div className="dss-screenshot__dynamic">
<style dangerouslySetInnerHTML={{ __html: this.state.styles }} />
<style dangerouslySetInnerHTML={{ __html: this.state.dssImage ? this.getAdditionalStyles( this.state.dssImage.url ) : '' }} />
<div className="dss-screenshot__markup" dangerouslySetInnerHTML={{ __html: this.state.dssImage ? replaceMarkupWithImage( this.state.markup, this.state.dssImage.url ) : this.state.markup }} />
<style dangerouslySetInnerHTML={ this.getPreviewStyles() } />
<style dangerouslySetInnerHTML={ this.getPreviewAdditionalStyles() } />
<div className="dss-screenshot__markup" dangerouslySetInnerHTML={ this.getPreviewMarkup() } />
</div>
</div>
);
Expand Down
3 changes: 3 additions & 0 deletions client/signup/steps/dss/theme-thumbnail.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ export default React.createClass( {
themeSlug={ this.props.themeSlug }
themeRepoSlug={ this.props.themeRepoSlug }
screenshotUrl={ this.getThumbnailUrl() }
isLoading={ this.props.isLoading }
dssImage={ this.props.dssImage }
markupAndStyles={ this.props.markupAndStyles }
renderComplete={ this.props.renderComplete }
/>
<span className="dss-theme-thumbnail__name">{ this.props.themeName }</span>
Expand Down

0 comments on commit 0e20b77

Please sign in to comment.