diff --git a/newIDE/app/src/AssetStore/AssetStoreNavigator.js b/newIDE/app/src/AssetStore/AssetStoreNavigator.js index 3a81ccac1fe5..46feff0c6337 100644 --- a/newIDE/app/src/AssetStore/AssetStoreNavigator.js +++ b/newIDE/app/src/AssetStore/AssetStoreNavigator.js @@ -19,6 +19,7 @@ export type AssetStorePageState = {| openedPrivateGameTemplateListingData: ?PrivateGameTemplateListingData, selectedFolders: Array, filtersState: FiltersState, + pageBreakIndex?: ?number, scrollPosition?: ?number, displayAssets: boolean, searchText?: string, diff --git a/newIDE/app/src/AssetStore/AssetsList.js b/newIDE/app/src/AssetStore/AssetsList.js index 3c6f00c4a881..84e2ff4cd3ca 100644 --- a/newIDE/app/src/AssetStore/AssetsList.js +++ b/newIDE/app/src/AssetStore/AssetsList.js @@ -36,7 +36,7 @@ import PrivateAssetPackAudioFilesDownloadButton from './PrivateAssets/PrivateAss import { CorsAwareImage } from '../UI/CorsAwareImage'; import { Column, LargeSpacer, Line } from '../UI/Grid'; import Text from '../UI/Text'; -import { ResponsiveLineStackLayout } from '../UI/Layout'; +import { ResponsiveLineStackLayout, LineStackLayout } from '../UI/Layout'; import { getUserPublicProfile, type UserPublicProfile, @@ -48,6 +48,8 @@ import Breadcrumbs from '../UI/Breadcrumbs'; import { getFolderTagsFromAssetShortHeaders } from './TagsHelper'; import { PrivateGameTemplateStoreContext } from './PrivateGameTemplates/PrivateGameTemplateStoreContext'; import { type AssetStorePageState } from './AssetStoreNavigator'; +import RaisedButton from '../UI/RaisedButton'; +import FlatButton from '../UI/FlatButton'; const ASSETS_DISPLAY_LIMIT = 250; @@ -93,20 +95,38 @@ const getAssetFoldersColumns = (windowWidth: WidthType) => { } }; +const getPageBreakAssetLowerIndex = (pageBreakIndex: number) => + ASSETS_DISPLAY_LIMIT * pageBreakIndex; +const getPageBreakAssetUpperIndex = (pageBreakIndex: number) => + ASSETS_DISPLAY_LIMIT * (pageBreakIndex + 1); + export const getAssetShortHeadersToDisplay = ( allAssetShortHeaders: AssetShortHeader[], - selectedFolders: string[] + selectedFolders: string[], + pageBreakIndex: number = 0 ): AssetShortHeader[] => { - return allAssetShortHeaders - .filter(assetShortHeader => { - if (!selectedFolders.length) return true; - const allAssetTags = assetShortHeader.tags; - // Check that the asset has all the selected folders tags. - return selectedFolders.every(folderTag => - allAssetTags.includes(folderTag) - ); - }) - .splice(0, ASSETS_DISPLAY_LIMIT); // Limit the number of displayed assets to avoid performance issues + let assetShortHeaders = allAssetShortHeaders.filter(assetShortHeader => { + if (!selectedFolders.length) return true; + const allAssetTags = assetShortHeader.tags; + // Check that the asset has all the selected folders tags. + return selectedFolders.every(folderTag => allAssetTags.includes(folderTag)); + }); + // Limit the number of displayed assets to avoid performance issues + const pageBreakAssetLowerIndex = getPageBreakAssetLowerIndex(pageBreakIndex); + const pageBreakAssetUpperIndex = Math.min( + getPageBreakAssetUpperIndex(pageBreakIndex), + assetShortHeaders.length + ); + if ( + pageBreakAssetLowerIndex !== 0 || + pageBreakAssetUpperIndex !== assetShortHeaders.length + ) { + assetShortHeaders = assetShortHeaders.slice( + pageBreakAssetLowerIndex, + pageBreakAssetUpperIndex + ); + } + return assetShortHeaders; }; const cellSpacing = 8; @@ -130,6 +150,56 @@ const styles = { }, }; +type PageBreakNavigationProps = {| + currentPage: AssetStorePageState, + pageBreakIndex: number, + setPageBreakIndex: number => void, + assetShortHeaders: Array, + scrollView: ?ScrollViewInterface, +|}; + +const PageBreakNavigation = ({ + currentPage, + pageBreakIndex, + setPageBreakIndex, + assetShortHeaders, + scrollView, +}: PageBreakNavigationProps) => { + return ( + + + Show previous assets} + onClick={() => { + currentPage.pageBreakIndex = Math.max( + 0, + (currentPage.pageBreakIndex || 0) - 1 + ); + setPageBreakIndex(currentPage.pageBreakIndex); + scrollView && scrollView.scrollToPosition(0); + }} + disabled={pageBreakIndex <= 0} + /> + Show next assets} + onClick={() => { + currentPage.pageBreakIndex = (currentPage.pageBreakIndex || 0) + 1; + setPageBreakIndex(currentPage.pageBreakIndex); + scrollView && scrollView.scrollToPosition(0); + }} + disabled={ + assetShortHeaders.length < + getPageBreakAssetUpperIndex(pageBreakIndex) + } + /> + + + ); +}; + export type AssetsListInterface = {| getScrollPosition: () => number, scrollToPosition: (y: number) => void, @@ -345,7 +415,8 @@ const AssetsList = React.forwardRef( if ( !allPrivateAssetPackListingDatas || !openedAssetPack || - !openedAssetPack.id // public pack selected. + // public pack selected. + !openedAssetPack.id ) return null; @@ -359,14 +430,21 @@ const AssetsList = React.forwardRef( [allPrivateAssetPackListingDatas, openedAssetPack] ); + const [pageBreakIndex, setPageBreakIndex] = React.useState( + (currentPage && currentPage.pageBreakIndex) || 0 + ); + const assetTiles = React.useMemo( () => { - if (!assetShortHeaders) return null; // Loading - if (hasAssetPackFiltersApplied && !openedAssetPack) return []; // Don't show assets if filtering on asset packs.) + // Loading + if (!assetShortHeaders) return null; + // Don't show assets if filtering on asset packs.) + if (hasAssetPackFiltersApplied && !openedAssetPack) return []; return getAssetShortHeadersToDisplay( assetShortHeaders, - selectedFolders + selectedFolders, + pageBreakIndex ).map(assetShortHeader => ( ( }, [ assetShortHeaders, - onOpenDetails, - windowWidth, - selectedFolders, hasAssetPackFiltersApplied, openedAssetPack, + selectedFolders, + pageBreakIndex, + windowWidth, + onOpenDetails, ] ); @@ -392,7 +471,8 @@ const AssetsList = React.forwardRef( if ( !publicAssetPacks || !onPublicAssetPackSelection || - hasAssetFiltersApplied // Don't show public packs if filtering on assets. + // Don't show public packs if filtering on assets. + hasAssetFiltersApplied ) return []; return publicAssetPacks.map((assetPack, index) => ( @@ -416,7 +496,8 @@ const AssetsList = React.forwardRef( if ( !privateAssetPackListingDatas || !receivedAssetPacks || - hasAssetFiltersApplied // Don't show private packs if filtering on assets. + // Don't show private packs if filtering on assets. + hasAssetFiltersApplied ) { return { allStandAlonePackTiles: [], @@ -490,8 +571,10 @@ const AssetsList = React.forwardRef( if ( !privateGameTemplateListingDatas || !onPrivateGameTemplateSelection || - hasAssetFiltersApplied || // Don't show private game templates if filtering on assets. - hasAssetPackFiltersApplied // Don't show private game templates if filtering on asset packs. + // Don't show private game templates if filtering on assets. + hasAssetFiltersApplied || + // Don't show private game templates if filtering on asset packs. + hasAssetPackFiltersApplied ) return []; @@ -594,7 +677,21 @@ const AssetsList = React.forwardRef( )} - {!openedAssetPack && gameTemplateTiles.length ? ( + {currentPage && + assetShortHeaders && + assetShortHeaders.length > getPageBreakAssetUpperIndex(0) && + pageBreakIndex > 0 && ( + + )} + {!openedAssetPack && + gameTemplateTiles.length && + pageBreakIndex === 0 ? ( ( ) : null} - {!openedAssetPack && allBundlePackTiles.length ? ( + {!openedAssetPack && + allBundlePackTiles.length && + pageBreakIndex === 0 ? ( ( ) : null} - {!openedAssetPack && allStandAlonePackTiles.length ? ( + {!openedAssetPack && + allStandAlonePackTiles.length && + pageBreakIndex === 0 ? ( ( assetPack={openedAssetPack} /> ) : null} - {assetTiles && // loading is finished. - !assetTiles.length && // No assets to show. - !allBundlePackTiles.length && // No bundles to show. - !allStandAlonePackTiles.length && // No packs to show. - !gameTemplateTiles.length && // no templates to show. - (!openedAssetPack || - !openedAssetPack.content || - !isAssetPackAudioOnly(openedAssetPack)) && // It's not an audio pack. + {// loading is finished. + assetTiles && + // No assets to show. + !assetTiles.length && + // No bundles to show. + !allBundlePackTiles.length && + // No packs to show. + !allStandAlonePackTiles.length && + // no templates to show. + !gameTemplateTiles.length && + (!openedAssetPack || + !openedAssetPack.content || + // It's not an audio pack. + !isAssetPackAudioOnly(openedAssetPack)) && noResultComponent} {onPrivateAssetPackSelection && openAuthorPublicProfileDialog && @@ -789,6 +896,18 @@ const AssetsList = React.forwardRef( }} /> )} + + {currentPage && + assetShortHeaders && + assetShortHeaders.length > getPageBreakAssetUpperIndex(0) && ( + + )} ); }