Skip to content

Commit

Permalink
Add objects installed from the asset store in selected folder (#7287)
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexandreSi authored Jan 15, 2025
1 parent 2ab2466 commit b04c15f
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 23 deletions.
37 changes: 23 additions & 14 deletions newIDE/app/src/AssetStore/AssetPackInstallDialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import {
useFetchAssets,
} from './NewObjectDialog';
import { type InstallAssetOutput } from './InstallAsset';
import { type ObjectFolderOrObjectWithContext } from '../ObjectsList/EnumerateObjectFolderOrObject';

// We limit the number of assets that can be installed at once to avoid
// timeouts especially with premium packs.
Expand All @@ -45,10 +46,11 @@ type Props = {|
assetShortHeaders: Array<AssetShortHeader>,
addedAssetIds: Set<string>,
onClose: () => void,
onAssetsAdded: () => void,
onAssetsAdded: (createdObjects: gdObject[]) => void,
project: gdProject,
objectsContainer: ?gdObjectsContainer,
resourceManagementProps: ResourceManagementProps,
targetObjectFolderOrObjectWithContext?: ?ObjectFolderOrObjectWithContext,
|};

const AssetPackInstallDialog = ({
Expand All @@ -60,6 +62,7 @@ const AssetPackInstallDialog = ({
project,
objectsContainer,
resourceManagementProps,
targetObjectFolderOrObjectWithContext,
}: Props) => {
const missingAssetShortHeaders = assetShortHeaders.filter(
assetShortHeader => !addedAssetIds.has(assetShortHeader.id)
Expand Down Expand Up @@ -168,20 +171,22 @@ const AssetPackInstallDialog = ({
});

// Use a pool to avoid installing an unbounded amount of assets at the same time.
const { errors } = await PromisePool.withConcurrency(6)
const { errors, results } = await PromisePool.withConcurrency(6)
.for(assets)
.process<InstallAssetOutput>(async asset => {
const installOutput = isPrivateAsset(asset)
? await installPrivateAsset({
asset,
project,
objectsContainer: targetObjectsContainer,
})
: await installPublicAsset({
asset,
project,
objectsContainer: targetObjectsContainer,
});
const doInstall = isPrivateAsset(asset)
? installPrivateAsset
: installPublicAsset;
const installOutput = await doInstall({
asset,
project,
objectsContainer: targetObjectsContainer,
targetObjectFolderOrObject:
targetObjectFolderOrObjectWithContext &&
!targetObjectFolderOrObjectWithContext.global
? targetObjectFolderOrObjectWithContext.objectFolderOrObject
: null,
});

if (!installOutput) {
throw new Error('Unable to install the asset.');
Expand All @@ -200,7 +205,10 @@ const AssetPackInstallDialog = ({
await resourceManagementProps.onFetchNewlyAddedResources();

setAreAssetsBeingInstalled(false);
onAssetsAdded();
const createdObjects = results
.map(result => result.createdObjects)
.flat();
onAssetsAdded(createdObjects);
} catch (error) {
setAreAssetsBeingInstalled(false);
console.error('Error while installing the assets', error);
Expand All @@ -221,6 +229,7 @@ const AssetPackInstallDialog = ({
onAssetsAdded,
installPrivateAsset,
targetObjectsContainer,
targetObjectFolderOrObjectWithContext,
]
);

Expand Down
7 changes: 6 additions & 1 deletion newIDE/app/src/AssetStore/NewObjectDialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ function NewObjectDialog({
project,
objectsContainer,
resourceManagementProps,
targetObjectFolderOrObjectWithContext,
});

const onInstallAsset = React.useCallback(
Expand Down Expand Up @@ -566,12 +567,16 @@ function NewObjectDialog({
assetShortHeaders={displayedAssetShortHeaders}
addedAssetIds={existingAssetStoreIds}
onClose={() => setIsAssetPackDialogInstallOpen(false)}
onAssetsAdded={() => {
onAssetsAdded={createdObjects => {
setIsAssetPackDialogInstallOpen(false);
onObjectsAddedFromAssets(createdObjects);
}}
project={project}
objectsContainer={objectsContainer}
resourceManagementProps={resourceManagementProps}
targetObjectFolderOrObjectWithContext={
targetObjectFolderOrObjectWithContext
}
/>
)}
</>
Expand Down
31 changes: 23 additions & 8 deletions newIDE/app/src/ObjectsList/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -638,27 +638,42 @@ const ObjectsList = React.forwardRef<Props, ObjectsListInterface>(

const onObjectsAddedFromAssets = React.useCallback(
(objects: Array<gdObject>) => {
if (objects.length === 0) return;

objects.forEach(object => {
onObjectCreated(object);
});
if (treeViewRef.current)
treeViewRef.current.openItems([sceneObjectsRootFolderId]);

// Here, the last object in the array might not be the last object
// in the tree view, given the fact that assets are added in parallel
// See (AssetPackInstallDialog.onInstallAssets).
const lastObject = objects[objects.length - 1];
// A new object is always added to the scene (layout) by default.
const object = objectsContainer
.getRootFolder()
.getObjectChild(lastObject.getName());

if (newObjectDialogOpen && newObjectDialogOpen.from) {
const {
objectFolderOrObject: selectedObjectFolderOrObject,
} = newObjectDialogOpen.from;
if (treeViewRef.current) {
treeViewRef.current.openItems(
getFoldersAscendanceWithoutRootFolder(
selectedObjectFolderOrObject
).map(folder => getObjectFolderTreeViewItemId(folder))
);
}
} else {
if (treeViewRef.current) {
treeViewRef.current.openItems([sceneObjectsRootFolderId]);
}
}
// Scroll to the new object.
// Ideally, we'd wait for the list to be updated to scroll, but
// to simplify the code, we just wait a few ms for a new render
// to be done.
setTimeout(() => {
scrollToItem(getObjectTreeViewItemId(object.getObject()));
scrollToItem(getObjectTreeViewItemId(lastObject));
}, 100); // A few ms is enough for a new render to be done.
},
[objectsContainer, onObjectCreated, scrollToItem]
[onObjectCreated, scrollToItem, newObjectDialogOpen]
);

const swapObjectAsset = React.useCallback(
Expand Down

0 comments on commit b04c15f

Please sign in to comment.