diff --git a/packages/playground/website/src/components/ensure-playground-site/ensure-playground-site-is-selected.tsx b/packages/playground/website/src/components/ensure-playground-site/ensure-playground-site-is-selected.tsx index a4f4a5594d..cee55232a6 100644 --- a/packages/playground/website/src/components/ensure-playground-site/ensure-playground-site-is-selected.tsx +++ b/packages/playground/website/src/components/ensure-playground-site/ensure-playground-site-is-selected.tsx @@ -3,7 +3,7 @@ import { resolveBlueprintFromURL } from '../../lib/state/url/resolve-blueprint-f import { useCurrentUrl } from '../../lib/state/url/router-hooks'; import { opfsSiteStorage } from '../../lib/state/opfs/opfs-site-storage'; import { - siteListingLoaded, + OPFSSitesLoaded, selectSiteBySlug, setTemporarySiteSpec, deriveSiteNameFromSlug, @@ -36,7 +36,7 @@ export function EnsurePlaygroundSiteIsSelected({ children: React.ReactNode; }) { const siteListingStatus = useAppSelector( - (state) => state.sites.loadingState + (state) => state.sites.opfsSitesLoadingState ); const activeSite = useAppSelector((state) => selectActiveSite(state)); const dispatch = useAppDispatch(); @@ -60,14 +60,14 @@ export function EnsurePlaygroundSiteIsSelected({ useEffect(() => { if (!opfsSiteStorage) { logger.error('Error loading sites: OPFS not available'); - dispatch(siteListingLoaded([])); + dispatch(OPFSSitesLoaded([])); return; } opfsSiteStorage.list().then( - (sites) => dispatch(siteListingLoaded(sites)), + (sites) => dispatch(OPFSSitesLoaded(sites)), (error) => { logger.error('Error loading sites:', error); - dispatch(siteListingLoaded([])); + dispatch(OPFSSitesLoaded([])); } ); }, [dispatch]); diff --git a/packages/playground/website/src/components/playground-viewport/index.tsx b/packages/playground/website/src/components/playground-viewport/index.tsx index 6863d2c3ef..2b080a3ea7 100644 --- a/packages/playground/website/src/components/playground-viewport/index.tsx +++ b/packages/playground/website/src/components/playground-viewport/index.tsx @@ -14,12 +14,11 @@ import { SiteError } from '../../lib/state/redux/slice-ui'; import { Button, Spinner } from '@wordpress/components'; import { removeSite, - selectAllSites, selectSiteBySlug, + selectSitesLoaded, selectTemporarySites, } from '../../lib/state/redux/slice-sites'; import classNames from 'classnames'; -import { PlaygroundRoute, redirectTo } from '../../lib/state/url/router'; export const supportedDisplayModes = [ 'browser-full-screen', @@ -59,8 +58,6 @@ export const PlaygroundViewport = ({ * as there's no risk of data loss */ export const KeepAliveTemporarySitesViewport = () => { - const allSites = useAppSelector(selectAllSites); - const temporarySites = useAppSelector(selectTemporarySites); const activeSite = useActiveSite(); const siteSlugsToRender = useMemo(() => { @@ -120,9 +117,7 @@ export const KeepAliveTemporarySitesViewport = () => { ]); }, [siteSlugsToRender]); - const sitesFinishedLoading = useAppSelector((state) => - ['error', 'loaded'].includes(state.sites.loadingState) - ); + const sitesFinishedLoading = useAppSelector(selectSitesLoaded); if (!sitesFinishedLoading) { return (
{ ); } - if (!allSites.length) { - // @TODO: Use the dedicated design for this - // (the one in Figma with white background and pretty fonts.) - return ( -
-
-
-

You don't have any Playgrounds right now

- -
-
-
- ); - } - return ( <> {!activeSite && ( diff --git a/packages/playground/website/src/lib/state/redux/slice-sites.ts b/packages/playground/website/src/lib/state/redux/slice-sites.ts index e159050038..ad6d39a38f 100644 --- a/packages/playground/website/src/lib/state/redux/slice-sites.ts +++ b/packages/playground/website/src/lib/state/redux/slice-sites.ts @@ -37,7 +37,8 @@ const sitesAdapter = createEntityAdapter({ // Define the initial state using the adapter and include the loading state const initialState = sitesAdapter.getInitialState({ - loadingState: 'loading' as LoadingState, + opfsSitesLoadingState: 'loading' as LoadingState, + firstTemporarySiteCreated: false, }); // Create the slice @@ -67,15 +68,19 @@ const sitesSlice = createSlice({ }, setSites: sitesAdapter.setAll, - - // New reducers for managing loading state - setLoadingState: (state, action: PayloadAction) => { - state.loadingState = action.payload; + setOPFSSitesLoadingState: ( + state, + action: PayloadAction + ) => { + state.opfsSitesLoadingState = action.payload; + }, + setFirstTemporarySiteCreated: (state) => { + state.firstTemporarySiteCreated = true; }, }, }); -export const siteListingLoaded = (sites: SiteInfo[]) => { +export const OPFSSitesLoaded = (sites: SiteInfo[]) => { return ( dispatch: PlaygroundDispatch, getState: () => PlaygroundReduxState @@ -86,14 +91,14 @@ export const siteListingLoaded = (sites: SiteInfo[]) => { allSites[site.slug] = site; }); dispatch(sitesSlice.actions.setSites(allSites)); - dispatch(setLoadingState('loaded')); + dispatch(setOPFSSitesLoadingState('loaded')); }; }; // New selector for loading state export const getSitesLoadingState = (state: { sites: ReturnType; -}) => state.sites.loadingState; +}) => state.sites.opfsSitesLoadingState; export function deriveSlugFromSiteName(name: string) { return name.toLowerCase().replaceAll(' ', '-'); @@ -268,10 +273,11 @@ export function setTemporarySiteSpec( }), }; dispatch(sitesSlice.actions.addSite(newSiteInfo)); + dispatch(sitesSlice.actions.setFirstTemporarySiteCreated()); return newSiteInfo; }; } -export const { setLoadingState } = sitesSlice.actions; +export const { setOPFSSitesLoadingState } = sitesSlice.actions; export const { selectAll: selectAllSites, @@ -304,4 +310,16 @@ export const selectTemporarySites = createSelector( } ); +export const selectSitesLoaded = createSelector( + [ + (state: { sites: ReturnType }) => + state.sites.opfsSitesLoadingState, + (state: { sites: ReturnType }) => + state.sites.firstTemporarySiteCreated, + ], + (opfsSitesLoadingState, firstTemporarySiteCreated) => + ['loaded', 'error'].includes(opfsSitesLoadingState) && + firstTemporarySiteCreated +); + export default sitesSlice.reducer;