Skip to content

Commit b522ea2

Browse files
feat: Link Linked Wearables collections to contracts (#3144)
* feat: Link Linked Wearables collections to contracts * fix: Revert config
1 parent 78fdbb9 commit b522ea2

17 files changed

+230
-203
lines changed

src/components/MappingEditor/MappingEditor.tsx

+25-71
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,10 @@ import { SyntheticEvent, useCallback, useMemo } from 'react'
22
import { DropdownProps, Field, InputOnChangeData, SelectField, TextAreaField, TextAreaProps } from 'decentraland-ui'
33
import { MappingType, MultipleMapping } from '@dcl/schemas'
44
import { t } from 'decentraland-dapps/dist/modules/translation'
5-
import { LinkedContractProtocol } from 'modules/thirdParty/types'
6-
import { shorten } from 'lib/address'
75
import allIcon from '../../icons/all.svg'
86
import multipleIcon from '../../icons/multiple.svg'
97
import singleIcon from '../../icons/single.svg'
108
import rangeIcon from '../../icons/range.svg'
11-
import ethereumSvg from '../../icons/ethereum.svg'
12-
import polygonSvg from '../../icons/polygon.svg'
139
import { Props } from './MappingEditor.types'
1410
import styles from './MappingEditor.module.css'
1511

@@ -19,25 +15,9 @@ const mappingTypeIcons = {
1915
[MappingType.SINGLE]: singleIcon,
2016
[MappingType.RANGE]: rangeIcon
2117
}
22-
const imgSrcByNetwork = {
23-
[LinkedContractProtocol.MAINNET]: ethereumSvg,
24-
[LinkedContractProtocol.MATIC]: polygonSvg,
25-
[LinkedContractProtocol.SEPOLIA]: ethereumSvg,
26-
[LinkedContractProtocol.AMOY]: polygonSvg
27-
}
2818

2919
export const MappingEditor = (props: Props) => {
30-
const { mapping, error, disabled, contract, contracts, onChange } = props
31-
const linkedContractsOptions = useMemo(
32-
() =>
33-
contracts.map((contract, index) => ({
34-
value: index,
35-
key: index,
36-
image: imgSrcByNetwork[contract.network],
37-
text: shorten(contract.address, 14, 14)
38-
})),
39-
[contracts, imgSrcByNetwork]
40-
)
20+
const { mapping, error, disabled, onChange } = props
4121

4222
const [mappingType, mappingValue] = useMemo(() => {
4323
switch (mapping.type) {
@@ -68,82 +48,56 @@ export const MappingEditor = (props: Props) => {
6848
const mappingType = value as MappingType
6949
switch (mappingType) {
7050
case MappingType.ANY:
71-
onChange({ type: mappingType }, contract)
51+
onChange({ type: mappingType })
7252
break
7353
case MappingType.MULTIPLE:
74-
onChange({ type: mappingType, ids: [] }, contract)
54+
onChange({ type: mappingType, ids: [] })
7555
break
7656
case MappingType.SINGLE:
77-
onChange({ type: mappingType, id: '' }, contract)
57+
onChange({ type: mappingType, id: '' })
7858
break
7959
case MappingType.RANGE:
80-
onChange({ type: mappingType, to: '', from: '' }, contract)
60+
onChange({ type: mappingType, to: '', from: '' })
8161
break
8262
}
8363
},
84-
[contract, onChange]
64+
[onChange]
8565
)
8666

87-
const handleSingleMappingValueChange = useCallback(
88-
(_: React.ChangeEvent<HTMLInputElement>, data: InputOnChangeData) => {
89-
onChange({ type: MappingType.SINGLE, id: data.value }, contract)
90-
},
91-
[contract]
92-
)
67+
const handleSingleMappingValueChange = useCallback((_: React.ChangeEvent<HTMLInputElement>, data: InputOnChangeData) => {
68+
onChange({ type: MappingType.SINGLE, id: data.value })
69+
}, [])
9370

94-
const handleMultipleMappingValueChange = useCallback(
95-
(_: React.ChangeEvent<HTMLTextAreaElement>, data: TextAreaProps) => {
96-
const ids =
97-
data.value
98-
?.toString()
99-
.replaceAll(/[^0-9,\s]/g, '')
100-
.split(',')
101-
.map(value => value.trim()) ?? []
71+
const handleMultipleMappingValueChange = useCallback((_: React.ChangeEvent<HTMLTextAreaElement>, data: TextAreaProps) => {
72+
const ids =
73+
data.value
74+
?.toString()
75+
.replaceAll(/[^0-9,\s]/g, '')
76+
.split(',')
77+
.map(value => value.trim()) ?? []
10278

103-
onChange(
104-
{
105-
type: MappingType.MULTIPLE,
106-
ids
107-
},
108-
contract
109-
)
110-
},
111-
[contract]
112-
)
79+
onChange({
80+
type: MappingType.MULTIPLE,
81+
ids
82+
})
83+
}, [])
11384

11485
const handleFromMappingValueChange = useCallback(
11586
(_: React.ChangeEvent<HTMLInputElement>, data: InputOnChangeData) => {
116-
onChange({ type: MappingType.RANGE, from: data.value, to: mappingValue.split(',')[1] }, contract)
87+
onChange({ type: MappingType.RANGE, from: data.value, to: mappingValue.split(',')[1] })
11788
},
118-
[mappingValue, contract]
89+
[mappingValue]
11990
)
12091

12192
const handleToMappingValueChange = useCallback(
12293
(_: React.ChangeEvent<HTMLInputElement>, data: InputOnChangeData) => {
123-
onChange({ type: MappingType.RANGE, from: mappingValue.split(',')[0], to: data.value }, contract)
94+
onChange({ type: MappingType.RANGE, from: mappingValue.split(',')[0], to: data.value })
12495
},
125-
[mappingValue, contract]
126-
)
127-
128-
const handleLinkedContractChange = useCallback(
129-
(_: SyntheticEvent<HTMLElement, Event>, { value }: DropdownProps) => {
130-
onChange(mapping, contracts[value as number])
131-
},
132-
[mapping, contracts]
96+
[mappingValue]
13397
)
13498

13599
return (
136100
<div className={styles.main}>
137-
<SelectField
138-
label={t('create_linked_wearable_collection_modal.linked_contract_field.label')}
139-
className={styles.linkedContractSelect}
140-
disabled={linkedContractsOptions.length === 0}
141-
value={contract ? contracts.indexOf(contract) : undefined}
142-
options={linkedContractsOptions}
143-
search={false}
144-
onChange={handleLinkedContractChange}
145-
message={linkedContractsOptions.length === 0 ? t('create_linked_wearable_collection_modal.linked_contract_field.message') : ''}
146-
/>
147101
<SelectField
148102
label={t('mapping_editor.mapping_type_label')}
149103
onChange={handleMappingTypeChange}
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
import { Mapping } from '@dcl/schemas'
2-
import { LinkedContract } from 'modules/thirdParty/types'
32

43
export type Props = {
54
mapping: Mapping
6-
contracts: LinkedContract[]
7-
contract: LinkedContract
85
error?: string
96
disabled?: boolean
10-
onChange: (mapping: Mapping, contract: LinkedContract) => void
7+
onChange: (mapping: Mapping) => void
118
}

src/components/Modals/CreateCollectionSelectorModal/CreateCollectionSelectorModal.module.css

+8-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
.modalContent {
22
display: flex;
33
flex-direction: row;
4-
gap: 16px;
4+
gap: 15px;
5+
padding: 10px;
56
}
67

78
.collectionSelection {
@@ -27,8 +28,8 @@
2728
}
2829

2930
.collectionSelection img {
30-
width: 133px;
31-
height: 133px;
31+
width: 227px;
32+
height: 110px;
3233
}
3334

3435
.collectionSelection .content {
@@ -42,6 +43,10 @@
4243
margin-top: 32px;
4344
}
4445

46+
.collectionSelection .content .text p {
47+
color: #cfcdd4;
48+
}
49+
4550
.collectionSelection .actions {
4651
display: flex;
4752
flex-direction: column;

src/components/Modals/CreateCollectionSelectorModal/CreateCollectionSelectorModal.tsx

+5-5
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import classNames from 'classnames'
33
import Modal from 'decentraland-dapps/dist/containers/Modal'
44
import { t } from 'decentraland-dapps/dist/modules/translation'
55
import { config } from 'config'
6-
import ethereumSvg from '../../../icons/ethereum.svg'
7-
import polygonSvg from '../../../icons/polygon.svg'
6+
import collectionsImage from '../../../images/collections.png'
7+
import linkedCollectionsImage from '../../../images/linked-collections.png'
88
import { Props } from './CreateCollectionSelectorModal.types'
99
import styles from './CreateCollectionSelectorModal.module.css'
1010
import { CREATE_BUTTON_TEST_ID, DISABLED_DATA_TEST_ID } from './constants'
@@ -52,7 +52,7 @@ export const CreateCollectionSelectorModal = (props: Props) => {
5252
const { onClose, onCreateCollection, onCreateThirdPartyCollection, name, isThirdPartyManager, isLoadingThirdParties } = props
5353

5454
return (
55-
<Modal name={name} onClose={onClose} size="small">
55+
<Modal name={name} onClose={onClose} size="medium">
5656
<ModalNavigation
5757
title={t('create_collection_selector_modal.title')}
5858
subtitle={t('create_collection_selector_modal.subtitle')}
@@ -62,15 +62,15 @@ export const CreateCollectionSelectorModal = (props: Props) => {
6262
<div className={styles.modalContent}>
6363
<CollectionSelection
6464
// Temporary image for the collections
65-
image={ethereumSvg}
65+
image={collectionsImage}
6666
title={t('create_collection_selector_modal.collection.title')}
6767
subtitle={t('create_collection_selector_modal.collection.subtitle')}
6868
onCreate={onCreateCollection}
6969
learnMoreUrl={COLLECTIONS_LEARN_MORE_URL}
7070
/>
7171
<CollectionSelection
7272
// Temporary image for the linked wearables collections
73-
image={polygonSvg}
73+
image={linkedCollectionsImage}
7474
title={t('create_collection_selector_modal.linked_collection.title')}
7575
subtitle={t('create_collection_selector_modal.linked_collection.subtitle')}
7676
onCreate={onCreateThirdPartyCollection}

src/components/Modals/CreateSingleItemModal/CreateSingleItemModal.container.ts

-4
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ import { Collection } from 'modules/collection/types'
77
import { getIsLinkedWearablesV2Enabled } from 'modules/features/selectors'
88
import { saveItemRequest, SAVE_ITEM_REQUEST } from 'modules/item/actions'
99
import { getLoading, getError, getStatusByItemId } from 'modules/item/selectors'
10-
import { getCollectionThirdParty } from 'modules/thirdParty/selectors'
11-
import { isThirdPartyCollection } from 'modules/collection/utils'
1210
import { MapStateProps, MapDispatchProps, MapDispatch, OwnProps } from './CreateSingleItemModal.types'
1311
import CreateSingleItemModal from './CreateSingleItemModal'
1412

@@ -17,14 +15,12 @@ const mapState = (state: RootState, ownProps: OwnProps): MapStateProps => {
1715
const collection: Collection | null = collectionId ? getCollection(state, collectionId) : null
1816
const statusByItemId = getStatusByItemId(state)
1917
const itemStatus = ownProps.metadata.item ? statusByItemId[ownProps.metadata.item.id] : null
20-
const contracts = collection && isThirdPartyCollection(collection) ? getCollectionThirdParty(state, collection)?.contracts ?? [] : []
2118

2219
return {
2320
collection,
2421
address: getAddress(state),
2522
error: getError(state),
2623
isThirdPartyV2Enabled: getIsLinkedWearablesV2Enabled(state),
27-
contracts,
2824
itemStatus,
2925
isLoading: isLoadingType(getLoading(state), SAVE_ITEM_REQUEST)
3026
}

0 commit comments

Comments
 (0)