From f8fb1e94cff950e25b169c91e795ea26adb8eea6 Mon Sep 17 00:00:00 2001 From: tbradsha <32492176+tbradsha@users.noreply.github.com> Date: Mon, 16 Dec 2024 14:52:01 -0700 Subject: [PATCH 01/27] Sync newspack-blocks to 4.5.2 --- .../blocks/carousel/create-swiper.js | 4 +- ...s-wp-rest-newspack-articles-controller.php | 7 +- .../blocks/homepage-articles/edit.tsx | 76 +++-- .../blocks/homepage-articles/store.js | 12 +- .../homepage-articles/templates/article.php | 5 +- .../blocks/homepage-articles/utils.ts | 19 ++ .../blocks/homepage-articles/view.js | 123 +++++--- .../blocks/homepage-articles/view.php | 22 +- .../class-newspack-blocks-api.php | 1 + .../class-newspack-blocks.php | 290 +++++------------- .../components/query-controls.js | 6 +- .../synced-newspack-blocks/shared/js/utils.js | 4 +- .../synced-newspack-blocks/types/index.d.ts | 4 +- .../synced-newspack-blocks/version.txt | 2 +- 14 files changed, 269 insertions(+), 306 deletions(-) diff --git a/projects/packages/jetpack-mu-wpcom/src/features/newspack-blocks/synced-newspack-blocks/blocks/carousel/create-swiper.js b/projects/packages/jetpack-mu-wpcom/src/features/newspack-blocks/synced-newspack-blocks/blocks/carousel/create-swiper.js index 151b9a0000201..2116f2692dc4a 100644 --- a/projects/packages/jetpack-mu-wpcom/src/features/newspack-blocks/synced-newspack-blocks/blocks/carousel/create-swiper.js +++ b/projects/packages/jetpack-mu-wpcom/src/features/newspack-blocks/synced-newspack-blocks/blocks/carousel/create-swiper.js @@ -62,7 +62,7 @@ function deactivateSlide( slide ) { * @param {Element} els.play - Play button element * @param {Element} els.pause - Pause button element * @param {Element} els.pagination - Pagination element - * @param {Object} config - Swiper config + * @param {object} config Swiper config * @return {Object} Swiper instance */ export default function createSwiper( els, config = {} ) { @@ -163,7 +163,7 @@ export default function createSwiper( els, config = {} ) { ${ alt ? /* translators: the title of the image. */ sprintf( - __( 'Image: %s, ', 'jetpack-mu-wpcom' ), + __( 'Image: %s,', 'jetpack-mu-wpcom' ), alt ) : '' diff --git a/projects/packages/jetpack-mu-wpcom/src/features/newspack-blocks/synced-newspack-blocks/blocks/homepage-articles/class-wp-rest-newspack-articles-controller.php b/projects/packages/jetpack-mu-wpcom/src/features/newspack-blocks/synced-newspack-blocks/blocks/homepage-articles/class-wp-rest-newspack-articles-controller.php index d35a74895283f..5fc926b59d606 100644 --- a/projects/packages/jetpack-mu-wpcom/src/features/newspack-blocks/synced-newspack-blocks/blocks/homepage-articles/class-wp-rest-newspack-articles-controller.php +++ b/projects/packages/jetpack-mu-wpcom/src/features/newspack-blocks/synced-newspack-blocks/blocks/homepage-articles/class-wp-rest-newspack-articles-controller.php @@ -129,7 +129,7 @@ public function register_routes() { * @return WP_REST_Response */ public function get_items( $request ) { - $page = $request->get_param( 'page' ) ?? 1; + $page = (int) $request->get_param( 'page' ) ?? 1; $exclude_ids = $request->get_param( 'exclude_ids' ) ?? array(); $next_page = $page + 1; $attributes = wp_parse_args( @@ -137,6 +137,11 @@ public function get_items( $request ) { wp_list_pluck( $this->get_attribute_schema(), 'default' ) ); + $deduplicate = $request->get_param( 'deduplicate' ) ?? 1; + if ( ! $deduplicate ) { + $exclude_ids = array(); + } + $article_query_args = Newspack_Blocks::build_articles_query( $attributes, apply_filters( 'newspack_blocks_block_name', 'newspack-blocks/homepage-articles' ) ); // If using exclude_ids, don't worry about pagination. Just get the next postsToShow number of results without the excluded posts. Otherwise, use standard WP pagination. diff --git a/projects/packages/jetpack-mu-wpcom/src/features/newspack-blocks/synced-newspack-blocks/blocks/homepage-articles/edit.tsx b/projects/packages/jetpack-mu-wpcom/src/features/newspack-blocks/synced-newspack-blocks/blocks/homepage-articles/edit.tsx index f0b03e754c1d1..155431b68da41 100644 --- a/projects/packages/jetpack-mu-wpcom/src/features/newspack-blocks/synced-newspack-blocks/blocks/homepage-articles/edit.tsx +++ b/projects/packages/jetpack-mu-wpcom/src/features/newspack-blocks/synced-newspack-blocks/blocks/homepage-articles/edit.tsx @@ -111,6 +111,7 @@ class Edit extends Component< HomepageArticlesProps > { showCaption, showCredit, showExcerpt, + showFullContent, showReadMore, readMoreLabel, showSubtitle, @@ -206,11 +207,16 @@ class Edit extends Component< HomepageArticlesProps > { { post.meta.newspack_post_subtitle || '' } ) } - { showExcerpt && ( + { showExcerpt && ! showFullContent && ( { post.excerpt.rendered } ) } + { ! showExcerpt && showFullContent && ( + + { post.full_content } + + ) } { showReadMore && post.post_link && ( { readMoreLabel } @@ -280,7 +286,9 @@ class Edit extends Component< HomepageArticlesProps > { mobileStack, minHeight, moreButton, + infiniteScroll, showExcerpt, + showFullContent, showReadMore, readMoreLabel, excerptLength, @@ -434,11 +442,20 @@ class Edit extends Component< HomepageArticlesProps > { ) : ( ! specificMode && ( - setAttributes( { moreButton: ! moreButton } ) } - /> + <> + setAttributes( { moreButton: ! moreButton } ) } + /> + { moreButton && ( + setAttributes( { infiniteScroll: ! infiniteScroll } ) } + /> + ) } + ) ) } { setAttributes( { showExcerpt: ! showExcerpt } ) } + onChange={ () => { + setAttributes( { + showExcerpt: ! showExcerpt, + showFullContent: showFullContent ? false : showFullContent, + } ); + } } /> { showExcerpt && ( - setAttributes( { excerptLength: value } ) } - min={ 10 } - max={ 100 } - /> + + setAttributes( { excerptLength: value } ) } + min={ 10 } + max={ 100 } + /> + ) } - setAttributes( { showReadMore: ! showReadMore } ) } - /> + + { + setAttributes( { + showFullContent: ! showFullContent, + showExcerpt: showExcerpt ? false : showExcerpt, + } ); + } } + /> + + + setAttributes( { showReadMore: ! showReadMore } ) } + /> + { showReadMore && ( { yield put( { type: 'DISABLE_UI' } ); - // Ensure innerBlocks are populated for widget area blocks. - // See https://github.com/WordPress/gutenberg/issues/32607#issuecomment-890728216. - const blocks = getBlocks().map( block => { - const innerBlocks = select( 'core/block-editor' ).getBlocks( block.clientId ); - return { - ...block, - innerBlocks, - }; - } ); + const blocks = recursivelyGetBlocks( getBlocks ); const blockQueries = getBlockQueries( blocks, blockNames ); diff --git a/projects/packages/jetpack-mu-wpcom/src/features/newspack-blocks/synced-newspack-blocks/blocks/homepage-articles/templates/article.php b/projects/packages/jetpack-mu-wpcom/src/features/newspack-blocks/synced-newspack-blocks/blocks/homepage-articles/templates/article.php index 2a0f2e109f2e0..857dc9acd61fe 100644 --- a/projects/packages/jetpack-mu-wpcom/src/features/newspack-blocks/synced-newspack-blocks/blocks/homepage-articles/templates/article.php +++ b/projects/packages/jetpack-mu-wpcom/src/features/newspack-blocks/synced-newspack-blocks/blocks/homepage-articles/templates/article.php @@ -147,9 +147,12 @@ class="" diff --git a/projects/packages/jetpack-mu-wpcom/src/features/newspack-blocks/synced-newspack-blocks/blocks/homepage-articles/utils.ts b/projects/packages/jetpack-mu-wpcom/src/features/newspack-blocks/synced-newspack-blocks/blocks/homepage-articles/utils.ts index cfeb040771de9..f02bfaa17616d 100644 --- a/projects/packages/jetpack-mu-wpcom/src/features/newspack-blocks/synced-newspack-blocks/blocks/homepage-articles/utils.ts +++ b/projects/packages/jetpack-mu-wpcom/src/features/newspack-blocks/synced-newspack-blocks/blocks/homepage-articles/utils.ts @@ -166,6 +166,7 @@ const generatePreviewPost = ( id: PostId ) => { excerpt: { rendered: '

' + __( 'The post excerpt.', 'jetpack-mu-wpcom' ) + '

', }, + full_content: __( 'Full post content.', 'jetpack-mu-wpcom' ), post_link: '/', featured_media: '1', id, @@ -281,3 +282,21 @@ export const postsBlockDispatch = ( triggerReflow: isEditorBlock ? dispatch( STORE_NAMESPACE ).reflow : () => undefined, }; }; + +// Ensure innerBlocks are populated for some blocks (e.g. `widget-area` and `post-content`). +// See https://github.com/WordPress/gutenberg/issues/32607#issuecomment-890728216. +// See https://github.com/Automattic/wp-calypso/issues/91839. +export const recursivelyGetBlocks = ( + getBlocks: ( clientId?: string ) => Block[], + blocks: Block[] = getBlocks() +) => { + return blocks.map( block => { + let innerBlocks = + block.innerBlocks.length === 0 ? getBlocks( block.clientId ) : block.innerBlocks; + innerBlocks = recursivelyGetBlocks( getBlocks, innerBlocks ); + return { + ...block, + innerBlocks, + }; + } ); +}; diff --git a/projects/packages/jetpack-mu-wpcom/src/features/newspack-blocks/synced-newspack-blocks/blocks/homepage-articles/view.js b/projects/packages/jetpack-mu-wpcom/src/features/newspack-blocks/synced-newspack-blocks/blocks/homepage-articles/view.js index 92dabb4c5f45b..bba76ba0d954f 100644 --- a/projects/packages/jetpack-mu-wpcom/src/features/newspack-blocks/synced-newspack-blocks/blocks/homepage-articles/view.js +++ b/projects/packages/jetpack-mu-wpcom/src/features/newspack-blocks/synced-newspack-blocks/blocks/homepage-articles/view.js @@ -35,18 +35,27 @@ function buildLoadMoreHandler( blockWrapperEl ) { return; } const postsContainerEl = blockWrapperEl.querySelector( '[data-posts]' ); + const isInfiniteScroll = btnEl.getAttribute( 'data-infinite-scroll' ); // Set initial state flags. - let isFetching = false; + window.newspackBlocksIsFetching = window.newspackBlocksIsFetching || false; + window.newspackBlocksFetchQueue = window.newspackBlocksFetchQueue || []; let isEndOfData = false; + let isPending = false; - btnEl.addEventListener( 'click', () => { - // Early return if still fetching or no more posts to render. - if ( isFetching || isEndOfData ) { - return false; + const maybeLoadMore = () => { + if ( isPending ) { + return; } + isPending = true; + loadMore(); + }; - isFetching = true; + const loadMore = () => { + // Early return if no more posts to render. + if ( isEndOfData ) { + return false; + } blockWrapperEl.classList.remove( 'is-error' ); blockWrapperEl.classList.add( 'is-loading' ); @@ -55,48 +64,86 @@ function buildLoadMoreHandler( blockWrapperEl ) { const requestURL = btnEl.getAttribute( 'data-next' ) + '&exclude_ids=' + getRenderedPostsIds().join( ',' ); + // If there's already a fetch in progress, queue this one to run after it ends. + if ( window.newspackBlocksIsFetching ) { + window.newspackBlocksFetchQueue.push( loadMore ); + return false; + } + + window.newspackBlocksIsFetching = true; fetchWithRetry( { url: requestURL, onSuccess, onError }, fetchRetryCount ); + }; - /** - * @param {object} data - Post data - */ - function onSuccess( data ) { - // Validate received data. - if ( ! isPostsDataValid( data ) ) { - return onError(); - } + /** + * @param {object} data - Post data + */ + function onSuccess( data ) { + // Validate received data. + if ( ! isPostsDataValid( data ) ) { + return onError(); + } - if ( data.items.length ) { - // Render posts' HTML from string. - const postsHTML = data.items.map( item => item.html ).join( '' ); - postsContainerEl.insertAdjacentHTML( 'beforeend', postsHTML ); - } + if ( data.items.length ) { + // Render posts' HTML from string. + const postsHTML = data.items.map( item => item.html ).join( '' ); + postsContainerEl.insertAdjacentHTML( 'beforeend', postsHTML ); + } - if ( data.next ) { - // Save next URL as button's attribute. - btnEl.setAttribute( 'data-next', data.next ); - } + if ( data.next ) { + // Save next URL as button's attribute. + btnEl.setAttribute( 'data-next', data.next ); + } - if ( ! data.items.length || ! data.next ) { - isEndOfData = true; - blockWrapperEl.classList.remove( 'has-more-button' ); - } + if ( ! data.items.length || ! data.next ) { + isEndOfData = true; + blockWrapperEl.classList.remove( 'has-more-button' ); + } - isFetching = false; + onEnd(); + } - blockWrapperEl.classList.remove( 'is-loading' ); - } + /** + * Handle fetching error + */ + function onError() { + blockWrapperEl.classList.add( 'is-error' ); + onEnd(); + } - /** - * Handle fetching error - */ - function onError() { - isFetching = false; + /** + * Callback to run after a fetch request is completed. + */ + function onEnd() { + window.newspackBlocksIsFetching = false; + blockWrapperEl.classList.remove( 'is-loading' ); - blockWrapperEl.classList.remove( 'is-loading' ); - blockWrapperEl.classList.add( 'is-error' ); + // If there are queued fetches, run the next one. + if ( window.newspackBlocksFetchQueue.length ) { + window.newspackBlocksFetchQueue.shift()(); } - } ); + isPending = false; + } + + btnEl.addEventListener( 'click', maybeLoadMore ); + + if ( isInfiniteScroll ) { + // Create an intersection observer instance + const btnObserver = new IntersectionObserver( + entries => { + entries.forEach( entry => { + if ( entry.isIntersecting ) { + maybeLoadMore(); + } + } ); + }, + { + root: null, + rootMargin: '0px', + threshold: 1, + } + ); + btnObserver.observe( btnEl ); + } } /** diff --git a/projects/packages/jetpack-mu-wpcom/src/features/newspack-blocks/synced-newspack-blocks/blocks/homepage-articles/view.php b/projects/packages/jetpack-mu-wpcom/src/features/newspack-blocks/synced-newspack-blocks/blocks/homepage-articles/view.php index 8e540d87bd481..83cd9940adedd 100644 --- a/projects/packages/jetpack-mu-wpcom/src/features/newspack-blocks/synced-newspack-blocks/blocks/homepage-articles/view.php +++ b/projects/packages/jetpack-mu-wpcom/src/features/newspack-blocks/synced-newspack-blocks/blocks/homepage-articles/view.php @@ -134,34 +134,34 @@ function newspack_blocks_get_homepage_articles_css_string( $attrs ) { ob_start(); ?> - .wpnbha article .entry-title { + .wp-block-newspack-blocks-homepage-articles article .entry-title { font-size: 1.2em; } - .wpnbha .entry-meta { + .wp-block-newspack-blocks-homepage-articles .entry-meta { display: flex; flex-wrap: wrap; align-items: center; margin-top: 0.5em; } - .wpnbha article .entry-meta { + .wp-block-newspack-blocks-homepage-articles article .entry-meta { font-size: 0.8em; } - .wpnbha article .avatar { + .wp-block-newspack-blocks-homepage-articles article .avatar { height: 25px; width: 25px; } - .wpnbha .post-thumbnail{ + .wp-block-newspack-blocks-homepage-articles .post-thumbnail{ margin: 0; margin-bottom: 0.25em; } - .wpnbha .post-thumbnail img { + .wp-block-newspack-blocks-homepage-articles .post-thumbnail img { height: auto; width: 100%; } - .wpnbha .post-thumbnail figcaption { + .wp-block-newspack-blocks-homepage-articles .post-thumbnail figcaption { margin-bottom: 0.5em; } - .wpnbha p { + .wp-block-newspack-blocks-homepage-articles p { margin: 0.5em 0; } @@ -383,8 +383,12 @@ class="" -