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导出",