From 0aea4baf7cc90481c6304c96392713416031b1a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20D=C3=ADaz?= Date: Thu, 2 May 2024 14:42:01 -0300 Subject: [PATCH 1/2] chore: Upgrade @dcl/sdk package to version 7.4.21 (#3094) --- package-lock.json | 129 ++++++++++++++++++++++++---------------------- package.json | 2 +- 2 files changed, 68 insertions(+), 63 deletions(-) diff --git a/package-lock.json b/package-lock.json index a061c4c3c..9e1dbf205 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,7 +18,7 @@ "@dcl/hashing": "^3.0.4", "@dcl/mini-rpc": "^1.0.7", "@dcl/schemas": "^11.5.0", - "@dcl/sdk": "7.4.18", + "@dcl/sdk": "^7.4.21", "@dcl/single-sign-on-client": "^0.1.0", "@dcl/ui-env": "^1.5.0", "@sentry/react": "^7.64.0", @@ -1707,6 +1707,11 @@ "resolved": "https://registry.npmjs.org/@dcl/ecs/-/ecs-7.4.15.tgz", "integrity": "sha512-iGetQ19PpHq/NWs5SeqCFShg34iPmYK0IfIch8gmqPjOnLilRIanYg8Q0y1IzsZYs6kJ8sQf435xA76h07btiQ==" }, + "node_modules/@dcl/asset-packs/node_modules/@dcl/explorer": { + "version": "1.0.161749-20240401171209.commit-d6d28f4", + "resolved": "https://registry.npmjs.org/@dcl/explorer/-/explorer-1.0.161749-20240401171209.commit-d6d28f4.tgz", + "integrity": "sha512-5jji07MVmMiNPY9gIHWrL3Wwh4SpdaUKnzMHMiKy830QJ1Nif9jpi5qcISmoDdXhoEJbC2vM1Gyj5D4rQibHew==" + }, "node_modules/@dcl/asset-packs/node_modules/@dcl/hashing": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@dcl/hashing/-/hashing-1.1.3.tgz", @@ -2029,9 +2034,9 @@ } }, "node_modules/@dcl/asset-packs/node_modules/react": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", - "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", "dependencies": { "loose-envify": "^1.1.0" }, @@ -2040,24 +2045,24 @@ } }, "node_modules/@dcl/asset-packs/node_modules/react-reconciler": { - "version": "0.29.0", - "resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.29.0.tgz", - "integrity": "sha512-wa0fGj7Zht1EYMRhKWwoo1H9GApxYLBuhoAuXN0TlltESAjDssB+Apf0T/DngVqaMyPypDmabL37vw/2aRM98Q==", + "version": "0.29.2", + "resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.29.2.tgz", + "integrity": "sha512-zZQqIiYgDCTP/f1N/mAR10nJGrPD2ZR+jDSEsKWJHYC7Cm2wodlwbR3upZRdC3cjIjSlTLNVyO7Iu0Yy7t2AYg==", "dependencies": { "loose-envify": "^1.1.0", - "scheduler": "^0.23.0" + "scheduler": "^0.23.2" }, "engines": { "node": ">=0.10.0" }, "peerDependencies": { - "react": "^18.2.0" + "react": "^18.3.1" } }, "node_modules/@dcl/asset-packs/node_modules/scheduler": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", - "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", "dependencies": { "loose-envify": "^1.1.0" } @@ -2388,9 +2393,9 @@ } }, "node_modules/@dcl/ecs": { - "version": "7.4.18", - "resolved": "https://registry.npmjs.org/@dcl/ecs/-/ecs-7.4.18.tgz", - "integrity": "sha512-YINO0AnUPpppicOBlX4ONXMu8iN0fOtirfn5jS+3wJFGo0JoCCsChM+62ughZnImyQ/9+6K1/xVB3nJ96PgzxQ==" + "version": "7.4.21", + "resolved": "https://registry.npmjs.org/@dcl/ecs/-/ecs-7.4.21.tgz", + "integrity": "sha512-4LbmhogqStmrQ8h3gwchP4poTaFLB0Mf468mlRbinB9XaXvSusqCznLP/N/T18/c23f/riRFZ0xWfe1IGr//gg==" }, "node_modules/@dcl/ecs-math": { "version": "2.0.2", @@ -2398,9 +2403,9 @@ "integrity": "sha512-w01+a3mpHvxGPHepu0hAAX8OfpBSQEqBbC1+U8o+5SBSQVXHiRwt3P4cK20yM8QCgZe3enPttmpqePnjTliTig==" }, "node_modules/@dcl/explorer": { - "version": "1.0.161749-20240401171209.commit-d6d28f4", - "resolved": "https://registry.npmjs.org/@dcl/explorer/-/explorer-1.0.161749-20240401171209.commit-d6d28f4.tgz", - "integrity": "sha512-5jji07MVmMiNPY9gIHWrL3Wwh4SpdaUKnzMHMiKy830QJ1Nif9jpi5qcISmoDdXhoEJbC2vM1Gyj5D4rQibHew==" + "version": "1.0.162830-20240429195817.commit-25498a3", + "resolved": "https://registry.npmjs.org/@dcl/explorer/-/explorer-1.0.162830-20240429195817.commit-25498a3.tgz", + "integrity": "sha512-IJ22cesg57zZb1qy+Iq6vZ4YuqgWeCz9RQCjpe/MBssLmouSq2US88DKxEHDUQviQD8GeNPVKIyhR8vSOzOOVQ==" }, "node_modules/@dcl/hashing": { "version": "3.0.4", @@ -2408,18 +2413,18 @@ "integrity": "sha512-Cg+MoIOn+BYmQV2q8zSFnNYY+GldlnUazwBnfgrq3i66ZxOaZ65h01btd8OUtSAlfWG4VTNIOHDjtKqmuwJNBg==" }, "node_modules/@dcl/inspector": { - "version": "7.4.18", - "resolved": "https://registry.npmjs.org/@dcl/inspector/-/inspector-7.4.18.tgz", - "integrity": "sha512-BLQaMwqSWujmPnbAUpjos77KxDojTAJ4ya5NGZyKuyqp8mWIjfEmAOy7q2BwTAb3kjJEujBn/jwUQT3Dbupy4g==", + "version": "7.4.21", + "resolved": "https://registry.npmjs.org/@dcl/inspector/-/inspector-7.4.21.tgz", + "integrity": "sha512-jXNZqmtMosQ50Fs6YuZJe+AguDlJc/jkJUkZ4PP/Q3FPEIUXxncF61bqe+qFZmwjTGC+URASI/TFbqzj5JKAtQ==", "dependencies": { "@dcl/asset-packs": "1.17.0", "ts-deepmerge": "^7.0.0" } }, "node_modules/@dcl/js-runtime": { - "version": "7.4.18", - "resolved": "https://registry.npmjs.org/@dcl/js-runtime/-/js-runtime-7.4.18.tgz", - "integrity": "sha512-t3NBd4hgLiROp7G+iuKQbXunLoJBjqR6lI3LcZcQMvmpoqHxysRt5tPrOOrkPkHHiM7CuF7pJ4Pgb4k2kr170g==" + "version": "7.4.21", + "resolved": "https://registry.npmjs.org/@dcl/js-runtime/-/js-runtime-7.4.21.tgz", + "integrity": "sha512-ePGlF5MpeqvfewhWM9Olnc+u5WBcmQ9u6sCrjtY2KYrUR7wxBCoamwIiG4BK8MVMPxKc5lAWA91toGJlC6jSMQ==" }, "node_modules/@dcl/linker-dapp": { "version": "0.12.0", @@ -2470,9 +2475,9 @@ "integrity": "sha512-Z0zpNr2HAxn2cLWUadWGlzaG48Z+N3hg2bI20UH+OT8NJtvCJnAwVBshAG83iAn4BTC+CsUsk4A394jrlv2ZIQ==" }, "node_modules/@dcl/protocol": { - "version": "1.0.0-8789372854.commit-f692c7a", - "resolved": "https://registry.npmjs.org/@dcl/protocol/-/protocol-1.0.0-8789372854.commit-f692c7a.tgz", - "integrity": "sha512-emLWfF/8Iciz0nnXFShZXBSbpsdbTHAJuh8st3de5C+4hlNV00Gs5pDBehsxENqHiq9yqL8rDng8EzTXhryAXw==", + "version": "1.0.0-8758013256.commit-44aab53", + "resolved": "https://registry.npmjs.org/@dcl/protocol/-/protocol-1.0.0-8758013256.commit-44aab53.tgz", + "integrity": "sha512-VbrbfUEOLIOiQjN2c53RSg1lNNkvt0+ow+d27c+O7RSyjqDyZZkX2uMW4kdYN1TOk45OrvxCyrrxdYN0ZXW52Q==", "dependencies": { "@dcl/ts-proto": "1.154.0" } @@ -2494,19 +2499,19 @@ "integrity": "sha512-IPB043+NbQB3om2FlmQGmaRxTokHaSM9o3a7sEL0yJgBb60mukCpMdNXxzdIcemixfV3EhIJQ2G8HgK30XKTkA==" }, "node_modules/@dcl/react-ecs": { - "version": "7.4.18", - "resolved": "https://registry.npmjs.org/@dcl/react-ecs/-/react-ecs-7.4.18.tgz", - "integrity": "sha512-EgdMbulO+xw5dDI1g12U0bVM8gkG064CJ8bGmDeDrgg/gqDUygzFIjJVuvl0Xcs6Rdj0zGLVxFFQY1WOt0hPYA==", + "version": "7.4.21", + "resolved": "https://registry.npmjs.org/@dcl/react-ecs/-/react-ecs-7.4.21.tgz", + "integrity": "sha512-iPWrSnHOCtk/X5CXTOS1d2JsQj6x6Dm2Eoint75bUaQcr4xgHAWySQXFIS//aw8WIx8nAxQvdNDE+EjTtu3Kgw==", "dependencies": { - "@dcl/ecs": "7.4.18", + "@dcl/ecs": "7.4.21", "react": "^18.2.0", "react-reconciler": "^0.29.0" } }, "node_modules/@dcl/react-ecs/node_modules/react": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", - "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", "dependencies": { "loose-envify": "^1.1.0" }, @@ -2515,24 +2520,24 @@ } }, "node_modules/@dcl/react-ecs/node_modules/react-reconciler": { - "version": "0.29.0", - "resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.29.0.tgz", - "integrity": "sha512-wa0fGj7Zht1EYMRhKWwoo1H9GApxYLBuhoAuXN0TlltESAjDssB+Apf0T/DngVqaMyPypDmabL37vw/2aRM98Q==", + "version": "0.29.2", + "resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.29.2.tgz", + "integrity": "sha512-zZQqIiYgDCTP/f1N/mAR10nJGrPD2ZR+jDSEsKWJHYC7Cm2wodlwbR3upZRdC3cjIjSlTLNVyO7Iu0Yy7t2AYg==", "dependencies": { "loose-envify": "^1.1.0", - "scheduler": "^0.23.0" + "scheduler": "^0.23.2" }, "engines": { "node": ">=0.10.0" }, "peerDependencies": { - "react": "^18.2.0" + "react": "^18.3.1" } }, "node_modules/@dcl/react-ecs/node_modules/scheduler": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", - "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", "dependencies": { "loose-envify": "^1.1.0" } @@ -2558,31 +2563,31 @@ } }, "node_modules/@dcl/sdk": { - "version": "7.4.18", - "resolved": "https://registry.npmjs.org/@dcl/sdk/-/sdk-7.4.18.tgz", - "integrity": "sha512-wYurMn7i6RKbD2ZYgsHwLoteFxxdhAjQxqUK8p9vmoIhsU49StzwoUueNz5kiJPFR+uFr/Ot0362kU5Mc5k/jQ==", + "version": "7.4.21", + "resolved": "https://registry.npmjs.org/@dcl/sdk/-/sdk-7.4.21.tgz", + "integrity": "sha512-EmIYPS1crLppSf0eD0ebkuQRYfp86lZoHVYICEW+F12MqAdSEPzj821OT7h5zLdjP4FCKm7M1thzCev0X6v9PA==", "dependencies": { - "@dcl/ecs": "7.4.18", + "@dcl/ecs": "7.4.21", "@dcl/ecs-math": "2.0.2", - "@dcl/explorer": "1.0.161749-20240401171209.commit-d6d28f4", - "@dcl/js-runtime": "7.4.18", - "@dcl/react-ecs": "7.4.18", - "@dcl/sdk-commands": "7.4.18", + "@dcl/explorer": "1.0.162830-20240429195817.commit-25498a3", + "@dcl/js-runtime": "7.4.21", + "@dcl/react-ecs": "7.4.21", + "@dcl/sdk-commands": "7.4.21", "text-encoding": "0.7.0" } }, "node_modules/@dcl/sdk-commands": { - "version": "7.4.18", - "resolved": "https://registry.npmjs.org/@dcl/sdk-commands/-/sdk-commands-7.4.18.tgz", - "integrity": "sha512-T7rhRsPhyMUZW3Wx+oDyRDjFkv8XyP7QzbJp21qTynkFxYwWArrEsXie2EUMYPoC6Ndgsjrjnyj/o3AaAlOzwA==", + "version": "7.4.21", + "resolved": "https://registry.npmjs.org/@dcl/sdk-commands/-/sdk-commands-7.4.21.tgz", + "integrity": "sha512-4wJaiQ5xjsD2JJQF/Xh/yf+SdWdiKXR05VAbjLHszFjwBu38W0DsSGzAi/v42ZCbdYuxwGH5gLER/cL0V/u4uA==", "dependencies": { "@dcl/crypto": "^3.4.4", - "@dcl/ecs": "7.4.18", + "@dcl/ecs": "7.4.21", "@dcl/hashing": "1.1.3", - "@dcl/inspector": "7.4.18", + "@dcl/inspector": "7.4.21", "@dcl/linker-dapp": "^0.12.0", "@dcl/mini-comms": "1.0.1-20230216163137.commit-a4c75be", - "@dcl/protocol": "^1.0.0-8691799990.commit-4ba546c", + "@dcl/protocol": "1.0.0-8758013256.commit-44aab53", "@dcl/quests-client": "^1.0.3", "@dcl/quests-manager": "^0.1.4", "@dcl/rpc": "^1.1.1", @@ -19009,9 +19014,9 @@ } }, "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", - "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz", + "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==", "engines": { "node": "14 || >=16.14" } @@ -23267,9 +23272,9 @@ } }, "node_modules/ts-proto": { - "version": "1.172.0", - "resolved": "https://registry.npmjs.org/ts-proto/-/ts-proto-1.172.0.tgz", - "integrity": "sha512-+4myxp5H+qD4r3sQUwvewN3zpdKpApeuUI0+lxfdznvkd2TUFVaeOD0q6dHszEYKTzR7DHu96Z1pqpNSOXF8iQ==", + "version": "1.174.0", + "resolved": "https://registry.npmjs.org/ts-proto/-/ts-proto-1.174.0.tgz", + "integrity": "sha512-hptQp5Nu5Vj3Mrj70fx5ccw3rTwPPpKXpa5RJ/WlmWiliVMqNPGYzUuBvd9N/EKsxiSQHiw62aGlZezzF19fKA==", "dependencies": { "case-anything": "^2.1.13", "protobufjs": "^7.2.4", diff --git a/package.json b/package.json index df84cd8b0..a2da60427 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "@dcl/hashing": "^3.0.4", "@dcl/mini-rpc": "^1.0.7", "@dcl/schemas": "^11.5.0", - "@dcl/sdk": "7.4.18", + "@dcl/sdk": "^7.4.21", "@dcl/single-sign-on-client": "^0.1.0", "@dcl/ui-env": "^1.5.0", "@sentry/react": "^7.64.0", From 462f533815d4cef139386962b5002bf9f28d043d Mon Sep 17 00:00:00 2001 From: Lautaro Petaccio <1120791+LautaroPetaccio@users.noreply.github.com> Date: Fri, 3 May 2024 17:19:40 -0300 Subject: [PATCH 2/2] feat: Add wearable utility (#3096) * feat: Add wearable utility * fix: Add missing translations * fix: Build * fix: Only show utility if the item has a utility --- package-lock.json | 27 +++------ package.json | 4 +- .../ItemDetailPage.container.ts | 2 + .../ItemDetailPage/ItemDetailPage.css | 6 ++ .../ItemDetailPage/ItemDetailPage.tsx | 44 +++++++++------ .../ItemDetailPage/ItemDetailPage.types.ts | 6 +- .../ItemEditorPage/RightPanel/Input/Input.css | 2 +- .../RightPanel/Input/Input.types.ts | 1 - .../RightPanel/MultiSelect/MultiSelect.css | 2 +- .../RightPanel/RightPanel.container.ts | 5 +- .../ItemEditorPage/RightPanel/RightPanel.css | 20 ++++++- .../ItemEditorPage/RightPanel/RightPanel.tsx | 56 ++++++++++++++----- .../RightPanel/RightPanel.types.ts | 3 + .../RightPanel/Select/Select.css | 2 +- .../ItemEditorPage/RightPanel/Tags/Tags.css | 2 +- src/components/ItemImage/ItemImage.css | 6 +- src/components/ItemImage/ItemImage.tsx | 5 +- src/components/ItemImage/ItemImage.types.ts | 1 + src/lib/api/builder.ts | 3 + src/modules/features/selectors.spec.ts | 6 +- src/modules/features/selectors.ts | 8 +++ src/modules/features/types.ts | 3 +- src/modules/item/types.ts | 2 + src/modules/translation/languages/en.json | 5 +- src/modules/translation/languages/es.json | 5 +- src/modules/translation/languages/zh.json | 5 +- 26 files changed, 157 insertions(+), 74 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9e1dbf205..a19b39892 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,7 +17,7 @@ "@dcl/crypto": "^3.4.5", "@dcl/hashing": "^3.0.4", "@dcl/mini-rpc": "^1.0.7", - "@dcl/schemas": "^11.5.0", + "@dcl/schemas": "^11.7.0", "@dcl/sdk": "^7.4.21", "@dcl/single-sign-on-client": "^0.1.0", "@dcl/ui-env": "^1.5.0", @@ -48,7 +48,7 @@ "decentraland-ecs": "6.12.4-7784644013.commit-f770b3e", "decentraland-experiments": "^1.0.2", "decentraland-transactions": "^2.6.1", - "decentraland-ui": "^5.17.1", + "decentraland-ui": "^5.21.0", "ethers": "^5.6.8", "file-saver": "^2.0.1", "graphql": "^15.8.0", @@ -2552,9 +2552,9 @@ } }, "node_modules/@dcl/schemas": { - "version": "11.5.0", - "resolved": "https://registry.npmjs.org/@dcl/schemas/-/schemas-11.5.0.tgz", - "integrity": "sha512-FkDAsZm6Ydu5PEROup2dLjOcqNwOiUISGhVYQAg6bWIp3kDnAjxguutOXIfxuZrVZELEcIi6+ntbvvfR28FAwg==", + "version": "11.7.0", + "resolved": "https://registry.npmjs.org/@dcl/schemas/-/schemas-11.7.0.tgz", + "integrity": "sha512-Gsv4FFnr6vL56k5ozzxH1CcOCzOUHMj602IL5y69q/Iy0rtn+7OF2TckgTDHGeifzakhaVwDOiGFYeJcaMaEXg==", "dependencies": { "ajv": "^8.11.0", "ajv-errors": "^3.0.0", @@ -11478,9 +11478,9 @@ } }, "node_modules/decentraland-ui": { - "version": "5.17.1", - "resolved": "https://registry.npmjs.org/decentraland-ui/-/decentraland-ui-5.17.1.tgz", - "integrity": "sha512-AnRW5wU2z4f2bkHOnHiT1yDurHn8oLOkSLw/Do+hFu0SKpJG7ZyfZCW5QHYquBq65nLwCRStC0CyN9N3CncmiQ==", + "version": "5.21.0", + "resolved": "https://registry.npmjs.org/decentraland-ui/-/decentraland-ui-5.21.0.tgz", + "integrity": "sha512-enRnOEwrJwNksLd0EReDjsEoG2QQq2a/g8hGpInfd6Tc05Ie40VtaOO0/CrzRA0yI82FEDfdxyFRkl5Wj2YTQg==", "dependencies": { "@dcl/schemas": "^11.4.0", "@dcl/ui-env": "^1.4.0", @@ -11519,17 +11519,6 @@ } } }, - "node_modules/decentraland-ui/node_modules/@dcl/schemas": { - "version": "11.4.0", - "resolved": "https://registry.npmjs.org/@dcl/schemas/-/schemas-11.4.0.tgz", - "integrity": "sha512-pCMENllY9vcl4HS1ta/TpVqjWUov/oa9xab+Ki1iMur48nE5+xXfa7+laCPhWLOKSZEkC59i5S6zQGTSWFPYew==", - "dependencies": { - "ajv": "^8.11.0", - "ajv-errors": "^3.0.0", - "ajv-keywords": "^5.1.0", - "mitt": "^3.0.1" - } - }, "node_modules/decentraland-ui/node_modules/uuid": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", diff --git a/package.json b/package.json index a2da60427..a49e15807 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "@dcl/crypto": "^3.4.5", "@dcl/hashing": "^3.0.4", "@dcl/mini-rpc": "^1.0.7", - "@dcl/schemas": "^11.5.0", + "@dcl/schemas": "^11.7.0", "@dcl/sdk": "^7.4.21", "@dcl/single-sign-on-client": "^0.1.0", "@dcl/ui-env": "^1.5.0", @@ -42,7 +42,7 @@ "decentraland-ecs": "6.12.4-7784644013.commit-f770b3e", "decentraland-experiments": "^1.0.2", "decentraland-transactions": "^2.6.1", - "decentraland-ui": "^5.17.1", + "decentraland-ui": "^5.21.0", "ethers": "^5.6.8", "file-saver": "^2.0.1", "graphql": "^15.8.0", diff --git a/src/components/ItemDetailPage/ItemDetailPage.container.ts b/src/components/ItemDetailPage/ItemDetailPage.container.ts index 999e97e0a..30e5cb28b 100644 --- a/src/components/ItemDetailPage/ItemDetailPage.container.ts +++ b/src/components/ItemDetailPage/ItemDetailPage.container.ts @@ -10,6 +10,7 @@ import { openModal } from 'decentraland-dapps/dist/modules/modal/actions' import { FETCH_ITEMS_REQUEST, DELETE_ITEM_REQUEST, deleteItemRequest, saveItemRequest, SAVE_ITEM_REQUEST } from 'modules/item/actions' import { MapStateProps, MapDispatchProps, MapDispatch } from './ItemDetailPage.types' import ItemDetailPage from './ItemDetailPage' +import { getIsWearableUtilityEnabled } from 'modules/features/selectors' const mapState = (state: RootState): MapStateProps => { const itemId = getItemId(state) @@ -25,6 +26,7 @@ const mapState = (state: RootState): MapStateProps => { item, collection, status, + isWearableUtilityEnabled: getIsWearableUtilityEnabled(state), isLoading: isLoadingType(getLoading(state), FETCH_ITEMS_REQUEST) || isLoadingType(getLoading(state), DELETE_ITEM_REQUEST) || diff --git a/src/components/ItemDetailPage/ItemDetailPage.css b/src/components/ItemDetailPage/ItemDetailPage.css index b21916115..f4ec56972 100644 --- a/src/components/ItemDetailPage/ItemDetailPage.css +++ b/src/components/ItemDetailPage/ItemDetailPage.css @@ -35,6 +35,12 @@ height: 256px; } +.ItemDetailPage .item-data .attribute-row { + display: flex; + flex-direction: row; + margin-top: 10px; +} + .ItemDetailPage .item-data .subtitle { color: var(--secondary-text); font-size: 13px; diff --git a/src/components/ItemDetailPage/ItemDetailPage.tsx b/src/components/ItemDetailPage/ItemDetailPage.tsx index 68ec19275..43a558db7 100644 --- a/src/components/ItemDetailPage/ItemDetailPage.tsx +++ b/src/components/ItemDetailPage/ItemDetailPage.tsx @@ -127,7 +127,7 @@ export default class ItemDetailPage extends React.PureComponent { } renderPage(item: Item, collection: Collection | null) { - const { onNavigate } = this.props + const { onNavigate, isWearableUtilityEnabled } = this.props const data = item.data const isLocked = collection && isCollectionLocked(collection) const hasActions = !isLocked @@ -144,7 +144,7 @@ export default class ItemDetailPage extends React.PureComponent {
- +
- {item.description && ( - <> -
{t('global.description')}
-
{item.description}
- - )} +
+ {item.description && ( +
+
{t('global.description')}
+
{item.description}
+
+ )} + {item.utility && isWearableUtilityEnabled && ( +
+
{t('global.utility')}
+
{item.utility}
+
+ )} +
{item.data.tags.length ? ( - <> -
{t('item_detail_page.tags.title')}
-
- {item.data.tags.map(tag => ( - - {tag} - - ))} +
+
+
{t('item_detail_page.tags.title')}
+
+ {item.data.tags.map(tag => ( + + {tag} + + ))} +
- +
) : null}
diff --git a/src/components/ItemDetailPage/ItemDetailPage.types.ts b/src/components/ItemDetailPage/ItemDetailPage.types.ts index f00fb48a6..30b09ddd3 100644 --- a/src/components/ItemDetailPage/ItemDetailPage.types.ts +++ b/src/components/ItemDetailPage/ItemDetailPage.types.ts @@ -19,6 +19,7 @@ export type Props = { collection: Collection | null status: SyncStatus | null isLoading: boolean + isWearableUtilityEnabled: boolean onNavigate: (path: string, locationState?: LocationStateProps) => void onOpenModal: typeof openModal onDelete: typeof deleteItemRequest @@ -26,6 +27,9 @@ export type Props = { hasAccess: boolean } -export type MapStateProps = Pick +export type MapStateProps = Pick< + Props, + 'wallet' | 'itemId' | 'item' | 'collection' | 'status' | 'isLoading' | 'hasAccess' | 'isWearableUtilityEnabled' +> export type MapDispatchProps = Pick export type MapDispatch = Dispatch diff --git a/src/components/ItemEditorPage/RightPanel/Input/Input.css b/src/components/ItemEditorPage/RightPanel/Input/Input.css index af8f20f64..faccebad8 100644 --- a/src/components/ItemEditorPage/RightPanel/Input/Input.css +++ b/src/components/ItemEditorPage/RightPanel/Input/Input.css @@ -1,6 +1,6 @@ .Input { height: 38px; - border: 1px solid var(--gray); + border: 1px solid var(--text-area-border); border-radius: 6px; display: flex; align-items: center; diff --git a/src/components/ItemEditorPage/RightPanel/Input/Input.types.ts b/src/components/ItemEditorPage/RightPanel/Input/Input.types.ts index 0a941c803..b8f4c7480 100644 --- a/src/components/ItemEditorPage/RightPanel/Input/Input.types.ts +++ b/src/components/ItemEditorPage/RightPanel/Input/Input.types.ts @@ -1,5 +1,4 @@ export type Props = { - itemId: string label: string disabled?: boolean maxLength?: number diff --git a/src/components/ItemEditorPage/RightPanel/MultiSelect/MultiSelect.css b/src/components/ItemEditorPage/RightPanel/MultiSelect/MultiSelect.css index 77ecc6337..6e3f7af12 100644 --- a/src/components/ItemEditorPage/RightPanel/MultiSelect/MultiSelect.css +++ b/src/components/ItemEditorPage/RightPanel/MultiSelect/MultiSelect.css @@ -1,5 +1,5 @@ .MultiSelect.ui.dropdown.inline { - border: 1px solid var(--gray); + border: 1px solid var(--text-area-border); border-radius: 6px; display: flex; align-items: center; diff --git a/src/components/ItemEditorPage/RightPanel/RightPanel.container.ts b/src/components/ItemEditorPage/RightPanel/RightPanel.container.ts index 3d60f887a..4ca6000f6 100644 --- a/src/components/ItemEditorPage/RightPanel/RightPanel.container.ts +++ b/src/components/ItemEditorPage/RightPanel/RightPanel.container.ts @@ -8,7 +8,7 @@ import { isOwner } from 'modules/item/utils' import { getSelectedItemId } from 'modules/location/selectors' import { getCollection, hasViewAndEditRights } from 'modules/collection/selectors' import { isWalletCommitteeMember } from 'modules/committee/selectors' -import { getIsCampaignEnabled, getIsVrmOptOutEnabled } from 'modules/features/selectors' +import { getIsCampaignEnabled, getIsVrmOptOutEnabled, getIsWearableUtilityEnabled } from 'modules/features/selectors' import { MapStateProps, MapDispatchProps, MapDispatch } from './RightPanel.types' import RightPanel from './RightPanel' @@ -35,7 +35,8 @@ const mapState = (state: RootState): MapStateProps => { isDownloading: isDownloading(state), isCommitteeMember: isWalletCommitteeMember(state), isCampaignEnabled: getIsCampaignEnabled(state), - isVrmOptOutEnabled: getIsVrmOptOutEnabled(state) + isVrmOptOutEnabled: getIsVrmOptOutEnabled(state), + isWearableUtilityEnabled: getIsWearableUtilityEnabled(state) } } diff --git a/src/components/ItemEditorPage/RightPanel/RightPanel.css b/src/components/ItemEditorPage/RightPanel/RightPanel.css index 4b9f5bd82..c6277710e 100644 --- a/src/components/ItemEditorPage/RightPanel/RightPanel.css +++ b/src/components/ItemEditorPage/RightPanel/RightPanel.css @@ -31,9 +31,27 @@ flex: 1; } +.dcl.text-area { + margin-top: 10px; + margin-bottom: 10px; +} + +.dcl.text-area > textarea::placeholder { + color: var(--secondary-text); +} + +.RightPanel .dcl.text-area > textarea { + font-size: 14px; + border: 1px solid var(--text-area-border); +} + +.RightPanel .dcl.text-area > p { + display: none; +} + .RightPanel .details { display: flex; - border: 1px solid var(--gray); + border: 1px solid var(--text-area-border); border-radius: 6px; padding: 8px; align-items: stretch; diff --git a/src/components/ItemEditorPage/RightPanel/RightPanel.tsx b/src/components/ItemEditorPage/RightPanel/RightPanel.tsx index e0e9a4a8b..a1f957023 100644 --- a/src/components/ItemEditorPage/RightPanel/RightPanel.tsx +++ b/src/components/ItemEditorPage/RightPanel/RightPanel.tsx @@ -1,6 +1,6 @@ import * as React from 'react' import equal from 'fast-deep-equal' -import { Loader, Dropdown, Button, Checkbox, CheckboxProps } from 'decentraland-ui' +import { Loader, Dropdown, Button, Checkbox, CheckboxProps, TextAreaField, TextAreaProps } from 'decentraland-ui' import { BodyPartCategory, EmoteCategory, Rarity, EmoteDataADR74, HideableWearableCategory, Network, WearableCategory } from '@dcl/schemas' import { NetworkButton } from 'decentraland-dapps/dist/containers' import { t } from 'decentraland-dapps/dist/modules/translation/utils' @@ -30,7 +30,8 @@ import { THUMBNAIL_PATH, WearableData, VIDEO_PATH, - SyncStatus + SyncStatus, + ITEM_UTILITY_MAX_LENGTH } from 'modules/item/types' import { dataURLToBlob } from 'modules/media/utils' import Collapsable from 'components/Collapsable' @@ -93,6 +94,7 @@ export default class RightPanel extends React.PureComponent { video: '', name: item.name, description: item.description, + utility: item.utility || '', rarity: item.rarity, data: item.data, hasItem: true, @@ -104,6 +106,7 @@ export default class RightPanel extends React.PureComponent { return { name: '', description: '', + utility: '', thumbnail: '', video: '', rarity: undefined, @@ -143,10 +146,16 @@ export default class RightPanel extends React.PureComponent { this.setState({ name, isDirty: this.isDirty({ name }) }) } - handleChangeDescription = (description: string) => { + handleChangeDescription = (_event: React.ChangeEvent, data: TextAreaProps) => { + const description = (data.value as string | undefined) ?? '' this.setState({ description, isDirty: this.isDirty({ description }) }) } + handleChangeUtility = (_event: React.ChangeEvent, data: TextAreaProps) => { + const utility = (data.value as string | undefined) ?? '' + this.setState({ utility, isDirty: this.isDirty({ utility }) }) + } + handleChangeRarity = (rarity: Rarity) => { this.setState({ rarity, isDirty: this.isDirty({ rarity }) }) } @@ -240,7 +249,7 @@ export default class RightPanel extends React.PureComponent { handleOnSaveItem = async () => { const { selectedItem, itemStatus, onSaveItem } = this.props - const { name, description, rarity, contents, data, isDirty } = this.state + const { name, description, utility, rarity, contents, data, isDirty } = this.state if (isDirty && selectedItem) { let itemData = data @@ -265,7 +274,8 @@ export default class RightPanel extends React.PureComponent { description, rarity, data: itemData as WearableData, - contents: itemContents + contents: itemContents, + utility: utility ?? undefined } if (itemStatus && [SyncStatus.UNPUBLISHED, SyncStatus.UNDER_REVIEW].includes(itemStatus)) { @@ -353,7 +363,11 @@ export default class RightPanel extends React.PureComponent { hasStateItemChanged(state: Partial, item: Item) { return ( - state.name !== item.name || state.description !== item.description || state.rarity !== item.rarity || !equal(state.data, item.data) + state.name !== item.name || + state.description !== item.description || + state.utility !== item.utility || + state.rarity !== item.rarity || + !equal(state.data, item.data) ) } @@ -498,8 +512,8 @@ export default class RightPanel extends React.PureComponent { } render() { - const { selectedItemId, address, isConnected, error, isCampaignEnabled, isVrmOptOutEnabled } = this.props - const { name, description, rarity, data, isDirty, hasItem } = this.state + const { selectedItemId, address, isWearableUtilityEnabled, isConnected, error, isCampaignEnabled, isVrmOptOutEnabled } = this.props + const { name, description, utility, rarity, data, isDirty, hasItem } = this.state const rarities = Rarity.getRarities() const playModes = getEmotePlayModes() @@ -552,22 +566,34 @@ export default class RightPanel extends React.PureComponent { {item ? ( <> - - + {isWearableUtilityEnabled ? ( + + ) : null} itemId={item.id} label={t('global.category')} diff --git a/src/components/ItemEditorPage/RightPanel/RightPanel.types.ts b/src/components/ItemEditorPage/RightPanel/RightPanel.types.ts index 5211c2b01..97aeec68b 100644 --- a/src/components/ItemEditorPage/RightPanel/RightPanel.types.ts +++ b/src/components/ItemEditorPage/RightPanel/RightPanel.types.ts @@ -27,6 +27,7 @@ export type Props = { isCommitteeMember: boolean isCampaignEnabled: boolean isVrmOptOutEnabled: boolean + isWearableUtilityEnabled: boolean onSaveItem: typeof saveItemRequest onDeleteItem: typeof deleteItemRequest onOpenModal: typeof openModal @@ -37,6 +38,7 @@ export type Props = { export type State = { name: string description: string + utility: string thumbnail: string video: string rarity?: Rarity @@ -60,6 +62,7 @@ export type MapStateProps = Pick< | 'canEditSelectedItem' | 'isCampaignEnabled' | 'isVrmOptOutEnabled' + | 'isWearableUtilityEnabled' > export type MapDispatchProps = Pick export type MapDispatch = Dispatch< diff --git a/src/components/ItemEditorPage/RightPanel/Select/Select.css b/src/components/ItemEditorPage/RightPanel/Select/Select.css index fcfdd6838..f39ff67f1 100644 --- a/src/components/ItemEditorPage/RightPanel/Select/Select.css +++ b/src/components/ItemEditorPage/RightPanel/Select/Select.css @@ -1,6 +1,6 @@ .Select.ui.dropdown.inline { height: 38px; - border: 1px solid var(--gray); + border: 1px solid var(--text-area-border); border-radius: 6px; display: flex; align-items: center; diff --git a/src/components/ItemEditorPage/RightPanel/Tags/Tags.css b/src/components/ItemEditorPage/RightPanel/Tags/Tags.css index b8b811e5f..4253bb518 100644 --- a/src/components/ItemEditorPage/RightPanel/Tags/Tags.css +++ b/src/components/ItemEditorPage/RightPanel/Tags/Tags.css @@ -1,5 +1,5 @@ .Tags { - border: 1px solid var(--gray); + border: 1px solid var(--text-area-border); border-radius: 6px; padding: 8px 12px 2px; margin-bottom: 8px; diff --git a/src/components/ItemImage/ItemImage.css b/src/components/ItemImage/ItemImage.css index f596bf933..742fb4c9c 100644 --- a/src/components/ItemImage/ItemImage.css +++ b/src/components/ItemImage/ItemImage.css @@ -15,7 +15,6 @@ background-color: #37333d; width: 24px; height: 24px; - margin-left: 8px; } .ItemImage .ItemBadge::before { @@ -26,13 +25,10 @@ height: 24px; } -.ItemImage .SmartBadge.small { - margin-left: 8px; -} - .ItemImage .badges-container { position: absolute; display: flex; + gap: 8px; bottom: 9px; left: 9px; } diff --git a/src/components/ItemImage/ItemImage.tsx b/src/components/ItemImage/ItemImage.tsx index 1c2aa2538..df8d6ac6f 100644 --- a/src/components/ItemImage/ItemImage.tsx +++ b/src/components/ItemImage/ItemImage.tsx @@ -1,6 +1,8 @@ import * as React from 'react' import classNames from 'classnames' +import { IconBadge } from 'decentraland-ui' import { RarityBadge } from 'decentraland-dapps/dist/containers/RarityBadge' +import { t } from 'decentraland-dapps/dist/modules/translation/utils' import { getBackgroundStyle, getThumbnailURL } from 'modules/item/utils' import ItemBadge from 'components/ItemBadge' @@ -15,7 +17,7 @@ export default class ItemImage extends React.PureComponent { } render() { - const { className, item, src, badgeSize, hasBadge, hasRarityBadge, hasRarityBackground } = this.props + const { className, item, src, badgeSize, hasBadge, hasUtilityBadge, hasRarityBadge, hasRarityBackground } = this.props return (
{ ) : null} {hasBadge ? : null} + {hasUtilityBadge && !!item.utility ? : null}
) diff --git a/src/components/ItemImage/ItemImage.types.ts b/src/components/ItemImage/ItemImage.types.ts index 7922b42a9..045402c3c 100644 --- a/src/components/ItemImage/ItemImage.types.ts +++ b/src/components/ItemImage/ItemImage.types.ts @@ -6,6 +6,7 @@ export type Props = { item: Item src?: string hasBadge?: boolean + hasUtilityBadge?: boolean hasRarityBadge?: boolean badgeSize?: BadgeProps['size'] hasRarityBackground?: boolean diff --git a/src/lib/api/builder.ts b/src/lib/api/builder.ts index 7c4812fc4..696ff11ab 100644 --- a/src/lib/api/builder.ts +++ b/src/lib/api/builder.ts @@ -75,6 +75,7 @@ export type RemoteItem = { content_hash: string | null created_at: Date updated_at: Date + utility: string | null local_content_hash: string | null catalyst_content_hash: string | null } @@ -348,6 +349,7 @@ function toRemoteItem(item: Item): Omit is_published: false, is_approved: false, in_catalyst: item.inCatalyst || false, + utility: item.utility || null, type: item.type, data: item.data, metrics: item.metrics, @@ -382,6 +384,7 @@ function fromRemoteItem(remoteItem: RemoteItem) { } if (remoteItem.collection_id) item.collectionId = remoteItem.collection_id + if (remoteItem.utility) item.utility = remoteItem.utility if (remoteItem.blockchain_item_id) item.tokenId = remoteItem.blockchain_item_id if (remoteItem.price) item.price = remoteItem.price if (remoteItem.urn) item.urn = remoteItem.urn diff --git a/src/modules/features/selectors.spec.ts b/src/modules/features/selectors.spec.ts index dd531defe..06ad3ae03 100644 --- a/src/modules/features/selectors.spec.ts +++ b/src/modules/features/selectors.spec.ts @@ -6,7 +6,8 @@ import { getIsMaintenanceEnabled, getIsPublishCollectionsWertEnabled, getIsSDK7TemplatesEnabled, - getIsVrmOptOutEnabled + getIsVrmOptOutEnabled, + getIsWearableUtilityEnabled } from './selectors' import { FeatureName } from './types' @@ -63,7 +64,8 @@ const ffSelectors = [ { selector: getIsSDK7TemplatesEnabled, app: ApplicationName.BUILDER, feature: FeatureName.SDK7_TEMPLATES }, { selector: getIsCreateSceneOnlySDK7Enabled, app: ApplicationName.BUILDER, feature: FeatureName.CREATE_SCENE_ONLY_SDK7 }, { selector: getIsPublishCollectionsWertEnabled, app: ApplicationName.BUILDER, feature: FeatureName.PUBLISH_COLLECTIONS_WERT }, - { selector: getIsVrmOptOutEnabled, app: ApplicationName.BUILDER, feature: FeatureName.VRM_OPTOUT } + { selector: getIsVrmOptOutEnabled, app: ApplicationName.BUILDER, feature: FeatureName.VRM_OPTOUT }, + { selector: getIsWearableUtilityEnabled, app: ApplicationName.DAPPS, feature: FeatureName.WEARABLE_UTILITY } ] ffSelectors.forEach(({ selector, app, feature }) => { diff --git a/src/modules/features/selectors.ts b/src/modules/features/selectors.ts index 97e194d43..d7b9e3313 100644 --- a/src/modules/features/selectors.ts +++ b/src/modules/features/selectors.ts @@ -53,3 +53,11 @@ export const getIsVrmOptOutEnabled = (state: RootState) => { return false } } + +export const getIsWearableUtilityEnabled = (state: RootState) => { + try { + return getIsFeatureEnabled(state, ApplicationName.DAPPS, FeatureName.WEARABLE_UTILITY) + } catch (e) { + return false + } +} diff --git a/src/modules/features/types.ts b/src/modules/features/types.ts index 62fd5a507..c3e5f1686 100644 --- a/src/modules/features/types.ts +++ b/src/modules/features/types.ts @@ -5,5 +5,6 @@ export enum FeatureName { CREATE_SCENE_ONLY_SDK7 = 'create-scene-only-sdk7', ENS_ADDRESS = 'ens-address', PUBLISH_COLLECTIONS_WERT = 'publish-collections-wert', - VRM_OPTOUT = 'vrm-optout' + VRM_OPTOUT = 'vrm-optout', + WEARABLE_UTILITY = 'wearable-utility' } diff --git a/src/modules/item/types.ts b/src/modules/item/types.ts index be858cbcd..1c21f7471 100644 --- a/src/modules/item/types.ts +++ b/src/modules/item/types.ts @@ -102,6 +102,7 @@ export type Item = Omit & { urn?: string beneficiary?: string totalSupply?: number + utility?: string isPublished: boolean isApproved: boolean inCatalyst: boolean @@ -143,6 +144,7 @@ export const SCENE_PATH = 'scene.json' export const SCENE_LOGIC_PATH = 'bin/game.js' export const ITEM_NAME_MAX_LENGTH = 32 export const ITEM_DESCRIPTION_MAX_LENGTH = 64 +export const ITEM_UTILITY_MAX_LENGTH = 64 export const MODEL_EXTENSIONS = ['.zip', '.gltf', '.glb'] export const IMAGE_EXTENSIONS = ['.zip', '.png'] export const VIDEO_EXTENSIONS = ['.mp4'] diff --git a/src/modules/translation/languages/en.json b/src/modules/translation/languages/en.json index 6ab385b1d..5d7faac19 100644 --- a/src/modules/translation/languages/en.json +++ b/src/modules/translation/languages/en.json @@ -869,7 +869,8 @@ "estate_plural": "Estates", "role": "Role", "none": "None", - "emote": "Emote" + "emote": "Emote", + "utility": "Utility" }, "roles": { "1": "Owner", @@ -1959,6 +1960,8 @@ "request_for_changes": "Request for changes", "request_for_changes_explanation": "If you want to make changes to {name} please ask a committee member for authorization in the forum", "required_permissions": "Permissions", + "description_placeholder": "What makes your Item special?", + "utility_placeholder": "Describe your Item functionality", "copyright": { "title": "VRM Export Permission", "vrm_export": "Allow VRM Export", diff --git a/src/modules/translation/languages/es.json b/src/modules/translation/languages/es.json index d068f4b8b..6b2f1d6a1 100644 --- a/src/modules/translation/languages/es.json +++ b/src/modules/translation/languages/es.json @@ -868,7 +868,8 @@ "estate_plural": "Estates", "role": "Rol", "none": "Ninguno", - "emote": "Animación" + "emote": "Animación", + "utility": "Utilidad" }, "roles": { "1": "Dueño", @@ -1978,6 +1979,8 @@ "request_for_changes": "Solicitud de cambios", "request_for_changes_explanation": "Si desea realizar cambios en {name}, solicite autorización a un miembro del comité en el foro", "required_permissions": "Permisos", + "description_placeholder": "¿Qué hace a tu Item especial?", + "utility_placeholder": "Describe la funcionalida de tu Item", "copyright": { "title": "Permiso de exportación de VRM", "vrm_export": "Permitir la exportación de VRM", diff --git a/src/modules/translation/languages/zh.json b/src/modules/translation/languages/zh.json index 3f4019bc2..9d1b1a062 100644 --- a/src/modules/translation/languages/zh.json +++ b/src/modules/translation/languages/zh.json @@ -862,7 +862,8 @@ "estate_plural": "庄园", "role": "角色", "none": "没有任何", - "emote": "表情" + "emote": "表情", + "utility": "物品效用" }, "roles": { "1": "持有者", @@ -1961,6 +1962,8 @@ "request_for_changes": "要求变更", "request_for_changes_explanation": "如果您想更改{name},请在论坛中请求委员会成员的授权", "required_permissions": "权限", + "description_placeholder": "是什么让您的物品与众不同?", + "utility_placeholder": "描述您的物品功能", "copyright": { "title": "VRM出口许可", "vrm_export": "允许VRM导出",