Skip to content

Commit

Permalink
Merge branch 'main' into feat/comms-message-to-address
Browse files Browse the repository at this point in the history
  • Loading branch information
gonpombo8 authored Jan 16, 2025
2 parents a27fb55 + 01f4702 commit fa2b830
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { contextMenu } from 'react-contexify'
import 'react-contexify/dist/ReactContexify.css'
import { analytics, Event } from '../../../lib/logic/analytics'

export const CUSTOM_ASSETS_CONTEXT_MENU_ID = 'custom-assets-context-menu'

Expand All @@ -14,6 +15,20 @@ export function openCustomAssetContextMenu(event: React.MouseEvent, props: Custo
contextMenu.show({
id: CUSTOM_ASSETS_CONTEXT_MENU_ID,
event,
props
props: {
...props,
onDelete: (assetId: string) => {
analytics.track(Event.DELETE_CUSTOM_ITEM, {
itemId: assetId
})
props.onDelete(assetId)
},
onRename: (assetId: string) => {
analytics.track(Event.RENAME_CUSTOM_ITEM, {
itemId: assetId
})
props.onRename(assetId)
}
}
})
}
10 changes: 9 additions & 1 deletion packages/@dcl/inspector/src/lib/data-layer/host/rpc-methods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,15 @@ export async function initRpcMethods(
}
])

return {}
const asset: AssetData = {
id: data.id,
name: data.name,
category: data.category,
tags: data.tags,
composite: JSON.parse(new TextDecoder().decode(composite))
}

return { asset: { data: Buffer.from(JSON.stringify(asset)) } }
},
async getCustomAssets() {
const paths = await getFilesInDirectory(fs, `${DIRECTORY.CUSTOM}`, [], true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ message CreateCustomAssetRequest {
optional bytes thumbnail = 4;
}

message CreateCustomAssetResponse {
AssetData asset = 1;
}

message GetCustomAssetsResponse {
repeated AssetData assets = 1;
}
Expand Down Expand Up @@ -102,7 +106,7 @@ service DataService {
rpc SetInspectorPreferences(InspectorPreferencesMessage) returns (Empty) {}
rpc CopyFile(CopyFileRequest) returns (Empty) {}
rpc GetFile(GetFileRequest) returns (GetFileResponse) {}
rpc CreateCustomAsset(CreateCustomAssetRequest) returns (Empty) {}
rpc CreateCustomAsset(CreateCustomAssetRequest) returns (CreateCustomAssetResponse) {}
rpc GetCustomAssets(Empty) returns (GetCustomAssetsResponse) {}
rpc DeleteCustomAsset(DeleteCustomAssetRequest) returns (Empty) {}
rpc RenameCustomAsset(RenameCustomAssetRequest) returns (Empty) {}
Expand Down
17 changes: 16 additions & 1 deletion packages/@dcl/inspector/src/lib/logic/analytics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ export enum Event {
SWITCH_BUILDER_MODE = 'Switch Builder Mode',
SET_GROUND = 'Set Ground',
LOCK = 'Lock',
HIDE = 'Hide'
HIDE = 'Hide',
CREATE_CUSTOM_ITEM = 'Create Custom Item',
DELETE_CUSTOM_ITEM = 'Delete Custom Item',
RENAME_CUSTOM_ITEM = 'Rename Custom Item'
}

export type Events = {
Expand Down Expand Up @@ -52,6 +55,18 @@ export type Events = {
[Event.HIDE]: {
value: boolean
}
[Event.CREATE_CUSTOM_ITEM]: {
itemId: string
itemName: string
resourceCount: number
isSmart: boolean
}
[Event.DELETE_CUSTOM_ITEM]: {
itemId: string
}
[Event.RENAME_CUSTOM_ITEM]: {
itemId: string
}
}

const noopAnalytics = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { selectAssetsTab } from '../../ui'
import { AssetsTab } from '../../ui/types'
import { getResourcesFromModels } from '../../../lib/babylon/decentraland/get-resources'
import { transformBase64ResourceToBinary } from '../../../lib/data-layer/host/fs-utils'
import { analytics, Event } from '../../../lib/logic/analytics'

describe('createCustomAssetSaga', () => {
const mockPayload = {
Expand All @@ -34,6 +35,12 @@ describe('createCustomAssetSaga', () => {
it('should successfully create a custom asset', async () => {
const mockResourcesFromModels = ['texture1.png', 'texture2.png']
const gltfResources = mockPayload.resources.filter((r) => r.endsWith('.gltf') || r.endsWith('.glb'))
const mockAsset = {
id: 'test-id',
name: mockPayload.name,
composite: mockPayload.composite,
resources: [...mockPayload.resources, ...mockResourcesFromModels]
}

return expectSaga(createCustomAssetSaga, mockAction)
.provide([
Expand All @@ -46,6 +53,15 @@ describe('createCustomAssetSaga', () => {
resources: [...mockPayload.resources, ...mockResourcesFromModels],
thumbnail: transformBase64ResourceToBinary(mockPayload.thumbnail)
}),
{ asset: { data: Buffer.from(JSON.stringify(mockAsset)) } }
],
[
call([analytics, 'track'], Event.CREATE_CUSTOM_ITEM, {
itemId: mockAsset.id,
itemName: mockPayload.name,
resourceCount: [...mockPayload.resources, ...mockResourcesFromModels].length,
isSmart: false
}),
undefined
]
])
Expand All @@ -58,6 +74,12 @@ describe('createCustomAssetSaga', () => {
const payloadWithoutThumbnail = { ...mockPayload, thumbnail: undefined }
const actionWithoutThumbnail = { ...mockAction, payload: payloadWithoutThumbnail }
const gltfResources = payloadWithoutThumbnail.resources.filter((r) => r.endsWith('.gltf') || r.endsWith('.glb'))
const mockAsset = {
id: 'test-id',
name: payloadWithoutThumbnail.name,
composite: payloadWithoutThumbnail.composite,
resources: payloadWithoutThumbnail.resources
}

return expectSaga(createCustomAssetSaga, actionWithoutThumbnail)
.provide([
Expand All @@ -70,6 +92,15 @@ describe('createCustomAssetSaga', () => {
resources: payloadWithoutThumbnail.resources,
thumbnail: undefined
}),
{ asset: { data: Buffer.from(JSON.stringify(mockAsset)) } }
],
[
call([analytics, 'track'], Event.CREATE_CUSTOM_ITEM, {
itemId: mockAsset.id,
itemName: payloadWithoutThumbnail.name,
resourceCount: payloadWithoutThumbnail.resources.length,
isSmart: false
}),
undefined
]
])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ import { PayloadAction } from '@reduxjs/toolkit'
import { call, put } from 'redux-saga/effects'
import { IDataLayer, error, getAssetCatalog, getDataLayerInterface } from '../index'
import { ErrorType } from '../index'
import { AssetData } from '../../../lib/logic/catalog'
import { AssetData, isSmart } from '../../../lib/logic/catalog'
import { selectAssetsTab } from '../../ui'
import { AssetsTab } from '../../ui/types'
import { getResourcesFromModels } from '../../../lib/babylon/decentraland/get-resources'
import { transformBase64ResourceToBinary } from '../../../lib/data-layer/host/fs-utils'
import { analytics, Event } from '../../../lib/logic/analytics'
import { CreateCustomAssetResponse } from '../../../tooling-entrypoint'

export function* createCustomAssetSaga(
action: PayloadAction<{
Expand All @@ -18,18 +20,34 @@ export function* createCustomAssetSaga(
) {
const dataLayer: IDataLayer = yield call(getDataLayerInterface)
if (!dataLayer) return

try {
const models = action.payload.resources.filter(
(resource) => resource.endsWith('.gltf') || resource.endsWith('.glb')
)
const resourcesFromModels: string[] = yield call(getResourcesFromModels, models)
const resources = [...action.payload.resources, ...resourcesFromModels]
yield call(dataLayer.createCustomAsset, {
const result: CreateCustomAssetResponse = yield call([dataLayer, 'createCustomAsset'], {
name: action.payload.name,
composite: Buffer.from(JSON.stringify(action.payload.composite)),
resources,
thumbnail: action.payload.thumbnail ? transformBase64ResourceToBinary(action.payload.thumbnail) : undefined
})

if (!result.asset?.data) {
throw new Error('Invalid response from createCustomAsset')
}

const asset = JSON.parse(new TextDecoder().decode(result.asset.data)) as AssetData

// Track custom item creation
yield call([analytics, 'track'], Event.CREATE_CUSTOM_ITEM, {
itemId: asset.id,
itemName: action.payload.name,
resourceCount: resources.length,
isSmart: isSmart(asset)
})

// Fetch asset catalog again
yield put(getAssetCatalog())
yield put(selectAssetsTab({ tab: AssetsTab.CustomAssets }))
Expand Down

0 comments on commit fa2b830

Please sign in to comment.