Skip to content

Commit

Permalink
Site Screenshot block: Update to support latest Interactivity API (#268)
Browse files Browse the repository at this point in the history
* Tools: Build screenshot view script as a viewModule

* Site Screenshot block: Update to latest Interactivity API format

* Move some context to derived state

* Update effects to callbacks

* Fix missing comma

* Make rendering elements declarative

All items will be on the page, and hidden/visible based on loading state.
  • Loading branch information
ryelle authored Feb 1, 2024
1 parent 583e19d commit 9cd94c9
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 126 deletions.
4 changes: 2 additions & 2 deletions source/wp-content/themes/wporg-showcase-2022/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
"extends": "../../../../.stylelintrc"
},
"scripts": {
"build": "wp-scripts build",
"start": "wp-scripts start",
"build": "wp-scripts build --experimental-modules",
"start": "wp-scripts start --experimental-modules",
"lint:js": "wp-scripts lint-js src",
"lint:css": "wp-scripts lint-style *.css src/**/*.scss",
"format": "wp-scripts format src"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
"usesContext": [ "postId" ],
"editorScript": "file:./index.js",
"editorStyle": "file:./index.css",
"viewScript": "file:./view.js",
"viewModule": "file:./view.js",
"style": "file:./style-index.css",
"render": "file:../../src/site-screenshot/render.php"
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,17 +78,18 @@
'isMShots' => $is_mshots,
'isLazyLoad' => $is_lazyload,
'attempts' => 0,
'shouldRetry' => true,
'base64Image' => '',
'hasError' => false,
'src' => esc_url( $screenshot ),
'alt' => the_title_attribute( array( 'echo' => false ) ),
];
$encoded_state = wp_json_encode( [ 'wporg' => [ 'showcase' => [ 'screenshot' => $init_state ] ] ] );
$encoded_state = wp_json_encode( $init_state );

?>
<div
<?php echo get_block_wrapper_attributes( array( 'class' => $classname ) ); // phpcs:ignore ?>
data-wp-interactive
data-wp-interactive="<?php echo esc_attr( '{"namespace":"wporg/showcase/screenshot"}' ); ?>"
data-wp-context="<?php echo esc_attr( $encoded_state ); ?>"
>
<?php if ( $has_link ) : ?>
Expand All @@ -98,10 +99,23 @@
<?php if ( $is_mshots ) : ?>
<div
class="wporg-site-screenshot__mshot-container"
data-wp-init="effects.wporg.showcase.screenshot.init"
data-wp-effect="effects.wporg.showcase.screenshot.update"
data-wp-init="callbacks.init"
data-wp-class--has-loaded="state.hasLoaded"
>
<div class="wporg-site-screenshot__loader"></div>
<div
data-wp-class--wporg-site-screenshot__loader="!state.hasLoaded"
data-wp-class--wporg-site-screenshot__error="state.hasError"
>
<img
data-wp-bind--hidden="!state.base64Image"
data-wp-bind--alt="context.alt"
data-wp-bind--src="state.base64Image"
/>
<span
data-wp-bind--hidden="state.base64Image"
data-wp-text="context.alt"
></span>
</div>
</div>
<?php else : ?>
<img
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@
justify-content: center;
height: 100%;

img,
span {
display: none;
}

&::after {
content: "";
display: inline-block;
Expand Down
194 changes: 76 additions & 118 deletions source/wp-content/themes/wporg-showcase-2022/src/site-screenshot/view.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,142 +2,100 @@
/**
* WordPress dependencies
*/
import { store as wpStore } from '@wordpress/interactivity';
import { getContext, store } from '@wordpress/interactivity';

/**
* Module constants
*/
const MAX_ATTEMPTS = 10;
const RETRY_DELAY = 2000;

/**
* Helper to update the "attempts" value.
*
* @param {Object} store
*/
function increaseAttempts( store ) {
store.context.wporg.showcase.screenshot.attempts++;
}

/**
* Helper to update the "shouldRetry" value.
*
* @param {boolean} value
* @param {Object} store
*/
function setShouldRetry( value, store ) {
store.context.wporg.showcase.screenshot.shouldRetry = value;
}

/**
* Helper to update the "hasError" value.
*
* @param {boolean} value
* @param {Object} store
*/
function setHasError( value, store ) {
store.context.wporg.showcase.screenshot.hasError = value;
}
const { actions, state } = store( 'wporg/showcase/screenshot', {
state: {
get attempts() {
return getContext().attempts;
},
get shouldRetry() {
return getContext().shouldRetry;
},
get base64Image() {
return getContext().base64Image;
},
get hasError() {
return getContext().hasError;
},
get hasLoaded() {
return state.base64Image || state.hasError;
},
},
actions: {
increaseAttempts() {
const context = getContext();
context.attempts++;
},

/**
* Helper to update the "base64Image" value.
*
* @param {string} value
* @param {Object} store
*/
function setBase64Image( value, store ) {
store.context.wporg.showcase.screenshot.base64Image = value;
}
setShouldRetry( value ) {
const context = getContext();
context.shouldRetry = value;
},

/**
* Make a request to the mShots URL, update state values.
*
* @param {string} fullUrl
* @param {Object} store
*/
const fetchImage = async ( fullUrl, store ) => {
try {
const res = await fetch( fullUrl );
increaseAttempts( store );
setHasError( value ) {
const context = getContext();
context.hasError = value;
},

if ( res.redirected ) {
setShouldRetry( true, store );
} else if ( res.status === 200 && ! res.redirected ) {
const blob = await res.blob();
setBase64Image( value ) {
const context = getContext();
context.base64Image = value;
},

const reader = new FileReader();
reader.onload = ( event ) => {
setBase64Image( event.target.result, store );
};
reader.readAsDataURL( blob );
*fetchImage( fullUrl ) {
try {
const res = yield fetch( fullUrl );
actions.increaseAttempts();

setShouldRetry( false, store );
}
} catch ( error ) {
setHasError( true, store );
setShouldRetry( false, store );
}
};
if ( res.redirected ) {
actions.setShouldRetry( true );
} else if ( res.status === 200 && ! res.redirected ) {
const blob = yield res.blob();

wpStore( {
effects: {
wporg: {
showcase: {
screenshot: {
// Run on init, starts the image fetch process.
init: async ( store ) => {
const { context } = store;
const { base64Image, isMShots, src } = context.wporg.showcase.screenshot;
const value = yield new Promise( ( resolve ) => {
const reader = new FileReader();
reader.onloadend = () => resolve( reader.result );
reader.readAsDataURL( blob );
} );

if ( isMShots && ! base64Image ) {
// Initial fetch.
await fetchImage( src, store );
actions.setBase64Image( value );
actions.setShouldRetry( false );
}
} catch ( error ) {
actions.setHasError( true );
actions.setShouldRetry( false );
}
},
},

// Set up the function to retry every RETRY_DELAY (2 seconds).
const intervalId = setInterval(
async ( _context ) => {
const { attempts, base64Image: _base64Image, shouldRetry } = _context;
if ( shouldRetry ) {
await fetchImage( src, store );
}
if ( attempts >= MAX_ATTEMPTS ) {
clearInterval( intervalId );
if ( ! _base64Image ) {
setHasError( true, store );
}
}
},
RETRY_DELAY,
context.wporg.showcase.screenshot
);
}
},
callbacks: {
// Run on init, starts the image fetch process.
*init() {
const { isMShots, src } = getContext();

// Run as an effect, when the context changes.
update: ( store ) => {
const { context, ref } = store;
const { alt, base64Image, hasError, isMShots } = context.wporg.showcase.screenshot;
if ( isMShots && ! state.base64Image ) {
// Initial fetch.
yield actions.fetchImage( src );

if ( ! isMShots ) {
return;
}
while ( state.shouldRetry ) {
yield new Promise( ( resolve ) => {
setTimeout( () => resolve(), RETRY_DELAY );
} );
yield actions.fetchImage( src );

if ( hasError ) {
const spinner = ref.querySelector( 'div' );
spinner.classList.remove( 'wporg-site-screenshot__loader' );
spinner.classList.add( 'wporg-site-screenshot__error' );
spinner.innerText = alt;
ref.parentElement.classList.remove( 'has-loaded' );
} else if ( base64Image ) {
const img = document.createElement( 'img' );
img.src = base64Image;
img.alt = alt;
ref.replaceChildren( img );
ref.parentElement.classList.add( 'has-loaded' );
}
},
},
},
if ( state.attempts >= MAX_ATTEMPTS ) {
actions.setHasError( true );
actions.setShouldRetry( false );
}
}
}
},
},
} );

0 comments on commit 9cd94c9

Please sign in to comment.