Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Site Editor: Improve loading experience (v1) #42525

Closed
wants to merge 11 commits into from
4 changes: 4 additions & 0 deletions packages/block-editor/README.md
Expand Up @@ -525,6 +525,10 @@ _Related_

- <https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/line-height-control/README.md>

### LoadingScreen

Undocumented declaration.

### MediaPlaceholder

_Related_
Expand Down
1 change: 1 addition & 0 deletions packages/block-editor/src/components/index.js
Expand Up @@ -73,6 +73,7 @@ export { default as __experimentalLinkControlSearchResults } from './link-contro
export { default as __experimentalLinkControlSearchItem } from './link-control/search-item';
export { default as LineHeightControl } from './line-height-control';
export { default as __experimentalListView } from './list-view';
export { default as LoadingScreen } from './loading-screen';
export { default as MediaReplaceFlow } from './media-replace-flow';
export { default as MediaPlaceholder } from './media-placeholder';
export { default as MediaUpload } from './media-upload';
Expand Down
72 changes: 72 additions & 0 deletions packages/block-editor/src/components/loading-screen/index.js
@@ -0,0 +1,72 @@
/**
* WordPress dependencies
*/
import { Suspense, useEffect, useState } from '@wordpress/element';
import { Modal, Spinner } from '@wordpress/components';
import { LoadingScreenContext } from '@wordpress/data';

const SuspenseWithLoadingScreen = ( { children } ) => {
const [ loaded, setLoaded ] = useState( false );

const finishedLoading = () => {
if ( ! loaded ) {
setLoaded( true );
}
};

return (
<LoadingScreenContext.Provider value={ loaded }>
{ loaded ? (
<>
<LoadingScreen autoClose />
{ children }
</>
) : (
<Suspense
fallback={ <LoadingScreen onUnmount={ finishedLoading } /> }
>
{ children }
</Suspense>
) }
</LoadingScreenContext.Provider>
);
};

const LoadingScreen = ( { onUnmount, autoClose } ) => {
const [ visible, setVisible ] = useState( true );

useEffect( () => {
if ( autoClose ) {
setTimeout( () => {
setVisible( false );
}, 1000 );
}

return () => {
if ( onUnmount ) {
onUnmount();
}
};
} );

if ( ! visible ) {
return null;
}

return (
<Modal
isFullScreen
isDismissible={ false }
onRequestClose={ () => {} }
__experimentalHideHeader
className="block-editor-loading-screen-modal"
overlayClassName="block-editor-loading-screen-modal-overlay"
>
<div className="block-editor-loading-screen-wrapper">
<Spinner style={ { width: 64, height: 64 } } />
</div>
</Modal>
);
};

export default SuspenseWithLoadingScreen;
21 changes: 21 additions & 0 deletions packages/block-editor/src/components/loading-screen/style.scss
@@ -0,0 +1,21 @@
.block-editor-loading-screen-modal-overlay {
backdrop-filter: none;
background-color: transparent;
padding-top: $header-height;
}

.block-editor-loading-screen-modal.is-full-screen {
background-color: $white;
box-shadow: 0 0 0 transparent;
width: 100%;
max-width: 100%;
max-height: 100%;
min-height: 100%;
}

.block-editor-loading-screen-wrapper {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
}
1 change: 1 addition & 0 deletions packages/block-editor/src/style.scss
Expand Up @@ -39,6 +39,7 @@
@import "./components/justify-content-control/style.scss";
@import "./components/link-control/style.scss";
@import "./components/list-view/style.scss";
@import "./components/loading-screen/style.scss";
@import "./components/media-replace-flow/style.scss";
@import "./components/media-placeholder/style.scss";
@import "./components/multi-selection-inspector/style.scss";
Expand Down
4 changes: 2 additions & 2 deletions packages/block-library/src/audio/edit.js
Expand Up @@ -27,7 +27,7 @@ import {
} from '@wordpress/block-editor';
import { useEffect } from '@wordpress/element';
import { __, _x } from '@wordpress/i18n';
import { useDispatch, useSelect } from '@wordpress/data';
import { useDispatch, useSuspenseSelect } from '@wordpress/data';
import { audio as icon } from '@wordpress/icons';
import { createBlock, getDefaultBlockName } from '@wordpress/blocks';
import { store as noticesStore } from '@wordpress/notices';
Expand All @@ -49,7 +49,7 @@ function AudioEdit( {
} ) {
const { id, autoplay, caption, loop, preload, src } = attributes;
const isTemporaryAudio = ! id && isBlobURL( src );
const mediaUpload = useSelect( ( select ) => {
const mediaUpload = useSuspenseSelect( ( select ) => {
const { getSettings } = select( blockEditorStore );
return getSettings().mediaUpload;
}, [] );
Expand Down
6 changes: 3 additions & 3 deletions packages/block-library/src/avatar/hooks.js
Expand Up @@ -4,7 +4,7 @@
import { store as blockEditorStore } from '@wordpress/block-editor';
import { store as coreStore, useEntityProp } from '@wordpress/core-data';
import { __, sprintf } from '@wordpress/i18n';
import { useSelect } from '@wordpress/data';
import { useSuspenseSelect } from '@wordpress/data';

function getAvatarSizes( sizes ) {
const minSize = sizes ? sizes[ 0 ] : 24;
Expand All @@ -17,7 +17,7 @@ function getAvatarSizes( sizes ) {
}

function useDefaultAvatar() {
const { avatarURL: defaultAvatarUrl } = useSelect( ( select ) => {
const { avatarURL: defaultAvatarUrl } = useSuspenseSelect( ( select ) => {
const { getSettings } = select( blockEditorStore );
const { __experimentalDiscussionSettings } = getSettings();
return __experimentalDiscussionSettings;
Expand Down Expand Up @@ -56,7 +56,7 @@ export function useCommentAvatar( { commentId } ) {
}

export function useUserAvatar( { userId, postId, postType } ) {
const { authorDetails } = useSelect(
const { authorDetails } = useSuspenseSelect(
( select ) => {
const { getEditedEntityRecord, getUser } = select( coreStore );
if ( userId ) {
Expand Down
4 changes: 2 additions & 2 deletions packages/block-library/src/avatar/user-control.js
Expand Up @@ -3,7 +3,7 @@
*/
import { __ } from '@wordpress/i18n';
import { ComboboxControl } from '@wordpress/components';
import { useSelect } from '@wordpress/data';
import { useSuspenseSelect } from '@wordpress/data';
import { store as coreStore } from '@wordpress/core-data';
import { useState } from '@wordpress/element';

Expand All @@ -16,7 +16,7 @@ const AUTHORS_QUERY = {

function UserControl( { value, onChange } ) {
const [ filteredAuthorsList, setFilteredAuthorsList ] = useState();
const authorsList = useSelect( ( select ) => {
const authorsList = useSuspenseSelect( ( select ) => {
const { getUsers } = select( coreStore );
return getUsers( AUTHORS_QUERY );
}, [] );
Expand Down
4 changes: 2 additions & 2 deletions packages/block-library/src/block/edit.js
@@ -1,7 +1,7 @@
/**
* WordPress dependencies
*/
import { useDispatch, useSelect } from '@wordpress/data';
import { useDispatch, useSuspenseSelect } from '@wordpress/data';
import {
useEntityBlockEditor,
useEntityProp,
Expand Down Expand Up @@ -39,7 +39,7 @@ export default function ReusableBlockEdit( { attributes: { ref }, clientId } ) {
);
const isMissing = hasResolved && ! record;

const canRemove = useSelect(
const canRemove = useSuspenseSelect(
( select ) => select( blockEditorStore ).canRemoveBlock( clientId ),
[ clientId ]
);
Expand Down
4 changes: 2 additions & 2 deletions packages/block-library/src/buttons/edit.js
Expand Up @@ -11,7 +11,7 @@ import {
useInnerBlocksProps,
store as blockEditorStore,
} from '@wordpress/block-editor';
import { useSelect } from '@wordpress/data';
import { useSuspenseSelect } from '@wordpress/data';

/**
* Internal dependencies
Expand Down Expand Up @@ -42,7 +42,7 @@ function ButtonsEdit( { attributes, className } ) {
'has-custom-font-size': fontSize || style?.typography?.fontSize,
} ),
} );
const preferredStyle = useSelect( ( select ) => {
const preferredStyle = useSuspenseSelect( ( select ) => {
const preferredStyleVariations =
select( blockEditorStore ).getSettings()
.__experimentalPreferredStyleVariations;
Expand Down
7 changes: 6 additions & 1 deletion packages/block-library/src/buttons/edit.native.js
Expand Up @@ -76,7 +76,12 @@ export default function ButtonsEdit( {
return preferredStyleVariations?.value?.[ buttonBlockName ];
}, [] );

const { getBlockOrder } = useSelect( blockEditorStore );
const { getBlockOrder } = useSelect( ( select ) => {
return {
getBlockOrder: select( blockEditorStore ).getBlockOrder,
};
}, [] );

const { insertBlock, removeBlock, selectBlock } =
useDispatch( blockEditorStore );

Expand Down
77 changes: 41 additions & 36 deletions packages/block-library/src/calendar/edit.js
Expand Up @@ -8,7 +8,7 @@ import memoize from 'memize';
*/
import { calendar as icon } from '@wordpress/icons';
import { Disabled, Placeholder, Spinner } from '@wordpress/components';
import { useSelect } from '@wordpress/data';
import { useSuspenseSelect } from '@wordpress/data';
import ServerSideRender from '@wordpress/server-side-render';
import { useBlockProps } from '@wordpress/block-editor';
import { store as coreStore } from '@wordpress/core-data';
Expand All @@ -35,46 +35,51 @@ const getYearMonth = memoize( ( date ) => {

export default function CalendarEdit( { attributes } ) {
const blockProps = useBlockProps();
const { date, hasPosts, hasPostsResolved } = useSelect( ( select ) => {
const { getEntityRecords, hasFinishedResolution } = select( coreStore );
const { date, hasPosts, hasPostsResolved } = useSuspenseSelect(
( select ) => {
const { getEntityRecords, hasFinishedResolution } =
select( coreStore );

const singlePublishedPostQuery = {
status: 'publish',
per_page: 1,
};
const posts = getEntityRecords(
'postType',
'post',
singlePublishedPostQuery
);
const postsResolved = hasFinishedResolution( 'getEntityRecords', [
'postType',
'post',
singlePublishedPostQuery,
] );
const singlePublishedPostQuery = {
status: 'publish',
per_page: 1,
};
const posts = getEntityRecords(
'postType',
'post',
singlePublishedPostQuery
);
const postsResolved = hasFinishedResolution( 'getEntityRecords', [
'postType',
'post',
singlePublishedPostQuery,
] );

let _date;
let _date;

// FIXME: @wordpress/block-library should not depend on @wordpress/editor.
// Blocks can be loaded into a *non-post* block editor.
// eslint-disable-next-line @wordpress/data-no-store-string-literals
const editorSelectors = select( 'core/editor' );
if ( editorSelectors ) {
const postType = editorSelectors.getEditedPostAttribute( 'type' );
// Dates are used to overwrite year and month used on the calendar.
// This overwrite should only happen for 'post' post types.
// For other post types the calendar always displays the current month.
if ( postType === 'post' ) {
_date = editorSelectors.getEditedPostAttribute( 'date' );
// FIXME: @wordpress/block-library should not depend on @wordpress/editor.
// Blocks can be loaded into a *non-post* block editor.
// eslint-disable-next-line @wordpress/data-no-store-string-literals
const editorSelectors = select( 'core/editor' );
if ( editorSelectors ) {
const postType =
editorSelectors.getEditedPostAttribute( 'type' );
// Dates are used to overwrite year and month used on the calendar.
// This overwrite should only happen for 'post' post types.
// For other post types the calendar always displays the current month.
if ( postType === 'post' ) {
_date = editorSelectors.getEditedPostAttribute( 'date' );
}
}
}

return {
date: _date,
hasPostsResolved: postsResolved,
hasPosts: postsResolved && posts?.length === 1,
};
}, [] );
return {
date: _date,
hasPostsResolved: postsResolved,
hasPosts: postsResolved && posts?.length === 1,
};
},
[]
);

if ( ! hasPosts ) {
return (
Expand Down
4 changes: 2 additions & 2 deletions packages/block-library/src/column/edit.js
Expand Up @@ -21,7 +21,7 @@ import {
PanelBody,
__experimentalUnitControl as UnitControl,
} from '@wordpress/components';
import { useSelect, useDispatch } from '@wordpress/data';
import { useSuspenseSelect, useDispatch } from '@wordpress/data';
import { sprintf, __ } from '@wordpress/i18n';

function ColumnEdit( {
Expand All @@ -43,7 +43,7 @@ function ColumnEdit( {
],
} );

const { columnsIds, hasChildBlocks, rootClientId } = useSelect(
const { columnsIds, hasChildBlocks, rootClientId } = useSuspenseSelect(
( select ) => {
const { getBlockOrder, getBlockRootClientId } =
select( blockEditorStore );
Expand Down
8 changes: 4 additions & 4 deletions packages/block-library/src/columns/edit.js
Expand Up @@ -24,7 +24,7 @@ import {
useBlockProps,
store as blockEditorStore,
} from '@wordpress/block-editor';
import { withDispatch, useDispatch, useSelect } from '@wordpress/data';
import { withDispatch, useDispatch, useSuspenseSelect } from '@wordpress/data';
import {
createBlock,
createBlocksFromInnerBlocksTemplate,
Expand Down Expand Up @@ -61,7 +61,7 @@ function ColumnsEditContainer( {
} ) {
const { isStackedOnMobile, verticalAlignment } = attributes;

const { count } = useSelect(
const { count } = useSuspenseSelect(
( select ) => {
return {
count: select( blockEditorStore ).getBlockCount( clientId ),
Expand Down Expand Up @@ -224,7 +224,7 @@ const ColumnsEditContainerWrapper = withDispatch(
)( ColumnsEditContainer );

function Placeholder( { clientId, name, setAttributes } ) {
const { blockType, defaultVariation, variations } = useSelect(
const { blockType, defaultVariation, variations } = useSuspenseSelect(
( select ) => {
const {
getBlockVariations,
Expand Down Expand Up @@ -271,7 +271,7 @@ function Placeholder( { clientId, name, setAttributes } ) {

const ColumnsEdit = ( props ) => {
const { clientId } = props;
const hasInnerBlocks = useSelect(
const hasInnerBlocks = useSuspenseSelect(
( select ) =>
select( blockEditorStore ).getBlocks( clientId ).length > 0,
[ clientId ]
Expand Down