Skip to content

Commit

Permalink
feat: add remove orders logic (#3202)
Browse files Browse the repository at this point in the history
  • Loading branch information
Melisa Anabella Rossi authored Oct 8, 2024
1 parent 8c3a394 commit 95c0ba9
Show file tree
Hide file tree
Showing 21 changed files with 360 additions and 56 deletions.
17 changes: 9 additions & 8 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"@dcl/crypto": "^3.4.5",
"@dcl/hashing": "^3.0.4",
"@dcl/mini-rpc": "^1.0.7",
"@dcl/schemas": "^14.0.0",
"@dcl/schemas": "^14.1.0",
"@dcl/sdk": "7.5.5",
"@dcl/single-sign-on-client": "^0.1.0",
"@dcl/ui-env": "^1.5.0",
Expand Down Expand Up @@ -41,7 +41,7 @@
"decentraland-dapps": "^23.6.1",
"decentraland-ecs": "6.12.4-7784644013.commit-f770b3e",
"decentraland-experiments": "^1.0.2",
"decentraland-transactions": "^2.15.0",
"decentraland-transactions": "^2.16.0",
"decentraland-ui": "^6.9.2",
"ethers": "^5.6.8",
"file-saver": "^2.0.1",
Expand Down
5 changes: 5 additions & 0 deletions src/components/CollectionDetailPage/CollectionDetailPage.css
Original file line number Diff line number Diff line change
Expand Up @@ -357,3 +357,8 @@
.CollectionDetailPage.popup-mint:before {
background-color: var(--smart-grey) !important;
}

.toast-info .body {
max-width: 450px;
overflow: hidden;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,40 @@ import { connect } from 'react-redux'
import { getAddress } from 'decentraland-dapps/dist/modules/wallet/selectors'
import { RootState } from 'modules/common/types'
import { openModal } from 'decentraland-dapps/dist/modules/modal/actions'
import { deleteItemRequest } from 'modules/item/actions'
import { getStatusByItemId } from 'modules/item/selectors'
import {
CANCEL_ITEM_ORDER_TRADE_REQUEST,
cancelItemOrderTradeRequest,
CancelItemOrderTradeRequestAction,
deleteItemRequest
} from 'modules/item/actions'
import { getLoading, getStatusByItemId } from 'modules/item/selectors'
import { setItems } from 'modules/editor/actions'
import { MapStateProps, MapDispatch, MapDispatchProps, OwnProps } from './CollectionItem.types'
import CollectionItem from './CollectionItem'
import { getIsOffchainPublicItemOrdersEnabled } from 'modules/features/selectors'
import { getWallet } from 'modules/wallet/selectors'
import { isLoadingType } from 'decentraland-dapps/dist/modules/loading'

const mapState = (state: RootState, ownProps: OwnProps): MapStateProps => {
const statusByItemId = getStatusByItemId(state)

const loadingTradeIds = getLoading(state)
.filter(action => action.type === CANCEL_ITEM_ORDER_TRADE_REQUEST)
.map(action => (action as CancelItemOrderTradeRequestAction).payload.tradeId)
return {
ethAddress: getAddress(state),
status: statusByItemId[ownProps.item.id],
wallet: getWallet(state),
isOffchainPublicItemOrdersEnabled: getIsOffchainPublicItemOrdersEnabled(state)
isOffchainPublicItemOrdersEnabled: getIsOffchainPublicItemOrdersEnabled(state),
isCancellingItemOrder: isLoadingType(getLoading(state), CANCEL_ITEM_ORDER_TRADE_REQUEST),
loadingTradeIds
}
}

const mapDispatch = (dispatch: MapDispatch): MapDispatchProps => ({
onOpenModal: (name, metadata) => dispatch(openModal(name, metadata)),
onDeleteItem: item => dispatch(deleteItemRequest(item)),
onSetItems: items => dispatch(setItems(items))
onSetItems: items => dispatch(setItems(items)),
onRemoveFromSale: tradeId => dispatch(cancelItemOrderTradeRequest(tradeId, true))
})

export default connect(mapState, mapDispatch)(CollectionItem)
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,29 @@ const LENGTH_LIMIT = 25
export default function CollectionItem({
onOpenModal,
onSetItems,
onRemoveFromSale,
item,
isOffchainPublicItemOrdersEnabled,
collection,
status,
ethAddress,
wallet
wallet,
loadingTradeIds,
isCancellingItemOrder
}: Props) {
analytics = getAnalytics()
const history = useHistory()
const isOnSaleLegacy = wallet && isOnSale(collection, wallet)
const isEnableForSaleOffchainMarketplace = wallet && isOffchainPublicItemOrdersEnabled && isEnableForSaleOffchain(collection, wallet)
const shouldAllowPriceEdition = !isOffchainPublicItemOrdersEnabled || isEnableForSaleOffchainMarketplace || isOnSaleLegacy
const shouldAllowPriceEdition =
!isOffchainPublicItemOrdersEnabled || (isEnableForSaleOffchainMarketplace && item.tradeId) || isOnSaleLegacy

const handleEditPriceAndBeneficiary = useCallback(() => {
if (isOffchainPublicItemOrdersEnabled && isEnableForSaleOffchainMarketplace) {
onOpenModal('PutForSaleOffchainModal', { itemId: item.id })
return
}

onOpenModal('EditPriceAndBeneficiaryModal', { itemId: item.id })
}, [item, onOpenModal])

Expand Down Expand Up @@ -69,6 +78,13 @@ export default function CollectionItem({
onOpenModal('PutForSaleOffchainModal', { itemId: item.id })
}, [])

const handleRemoveFromSale = useCallback(() => {
if (!item.tradeId) {
return
}
onRemoveFromSale(item.tradeId)
}, [item])

const renderPrice = useCallback(() => {
if (!item.price) {
return (
Expand All @@ -78,20 +94,20 @@ export default function CollectionItem({
)
}

if (isFree(item)) {
return <span>{t('global.free')}</span>
if (item.price === ethers.constants.MaxUint256.toString() || (isOffchainPublicItemOrdersEnabled && !isOnSaleLegacy && !item.tradeId)) {
return <span>-</span>
}

if (item.price === ethers.constants.MaxUint256.toString()) {
return <span>-</span>
if (isFree(item)) {
return <span>{t('global.free')}</span>
}

return (
<Mana className={styles.mana} network={Network.MATIC} showTooltip>
{ethers.utils.formatEther(item.price)}
</Mana>
)
}, [item, handleEditPriceAndBeneficiary])
}, [item, isOnSaleLegacy, isOffchainPublicItemOrdersEnabled, handleEditPriceAndBeneficiary])

const renderItemStatus = useCallback(() => {
return status === SyncStatus.UNSYNCED ? (
Expand Down Expand Up @@ -214,13 +230,25 @@ export default function CollectionItem({
</Table.Cell>
) : null}
<Table.Cell>{renderItemStatus()}</Table.Cell>
{isOffchainPublicItemOrdersEnabled && !isOnSaleLegacy && (
{isOffchainPublicItemOrdersEnabled && !isOnSaleLegacy && !item.tradeId && (
<Table.Cell>
<Button primary size="tiny" disabled={!isEnableForSaleOffchainMarketplace} onClick={handlePutForSale}>
{t('collection_item.put_for_sale')}
</Button>
</Table.Cell>
)}
{isOffchainPublicItemOrdersEnabled && item.tradeId && (
<Table.Cell>
<Button
secondary
size="tiny"
onClick={handleRemoveFromSale}
loading={isCancellingItemOrder && loadingTradeIds.includes(item.tradeId)}
>
{t('collection_item.remove_from_sale')}
</Button>
</Table.Cell>
)}
<Table.Cell className={styles.contextMenuButton}>{renderItemContextMenu()}</Table.Cell>
</Table.Row>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Dispatch } from 'redux'
import { Collection } from 'modules/collection/types'
import { Item, SyncStatus } from 'modules/item/types'
import { openModal, OpenModalAction } from 'decentraland-dapps/dist/modules/modal/actions'
import { deleteItemRequest, DeleteItemRequestAction } from 'modules/item/actions'
import { CancelItemOrderTradeRequestAction, deleteItemRequest, DeleteItemRequestAction } from 'modules/item/actions'
import { setItems, SetItemsAction } from 'modules/editor/actions'
import { Wallet } from 'decentraland-dapps/dist/modules/wallet'

Expand All @@ -13,12 +13,18 @@ export type Props = {
status: SyncStatus
isOffchainPublicItemOrdersEnabled: boolean
wallet: Wallet | null
isCancellingItemOrder: boolean
loadingTradeIds: string[]
onOpenModal: typeof openModal
onDeleteItem: typeof deleteItemRequest
onSetItems: typeof setItems
onRemoveFromSale: (tradeId: string) => void
}

export type MapStateProps = Pick<Props, 'ethAddress' | 'status' | 'isOffchainPublicItemOrdersEnabled' | 'wallet'>
export type MapDispatchProps = Pick<Props, 'onOpenModal' | 'onDeleteItem' | 'onSetItems'>
export type MapDispatch = Dispatch<OpenModalAction | DeleteItemRequestAction | SetItemsAction>
export type MapStateProps = Pick<
Props,
'ethAddress' | 'status' | 'isOffchainPublicItemOrdersEnabled' | 'wallet' | 'isCancellingItemOrder' | 'loadingTradeIds'
>
export type MapDispatchProps = Pick<Props, 'onOpenModal' | 'onDeleteItem' | 'onSetItems' | 'onRemoveFromSale'>
export type MapDispatch = Dispatch<OpenModalAction | DeleteItemRequestAction | SetItemsAction | CancelItemOrderTradeRequestAction>
export type OwnProps = Pick<Props, 'item'>
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ export default class CreateSingleItemModal extends React.PureComponent<Props, St

if ((hasScreenshotTaken || type !== ItemType.EMOTE) && isOffchainPublicItemOrdersEnabled) {
item.price = ethers.constants.MaxUint256.toString()
item.beneficiary = ethers.constants.AddressZero
item.beneficiary = item.beneficiary || address
return onSave(item as Item, sortedContents.all)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ export default class EditPriceAndBeneficiaryModal extends React.PureComponent<Pr

getItemPrice() {
const { item } = this.props
return item.price ? ethers.utils.formatEther(item.price) : undefined
return item.price && item.price !== ethers.constants.MaxUint256.toString() ? ethers.utils.formatEther(item.price) : undefined
}

isDisabled() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@ import { RootState } from 'modules/common/types'
import { getAuthorizedItems, getError, getLoading } from 'modules/item/selectors'
import { OwnProps, MapStateProps, MapDispatch, MapDispatchProps } from './PutForSaleOffchainModal.types'
import PutForSaleOffchainModal from './PutForSaleOffchainModal'
import { CREATE_ITEM_ORDER_TRADE_REQUEST, createItemOrderTradeRequest } from 'modules/item/actions'
import {
CANCEL_ITEM_ORDER_TRADE_REQUEST,
cancelItemOrderTradeRequest,
CREATE_ITEM_ORDER_TRADE_REQUEST,
createItemOrderTradeRequest
} from 'modules/item/actions'
import { Item } from 'modules/item/types'
import { isLoadingType } from 'decentraland-dapps/dist/modules/loading'
import { getAuthorizedCollections } from 'modules/collection/selectors'
Expand All @@ -21,13 +26,15 @@ const mapState = (state: RootState, ownProps: OwnProps): MapStateProps => {
item,
collection,
isLoading: isLoadingType(getLoading(state), CREATE_ITEM_ORDER_TRADE_REQUEST),
isLoadingCancel: isLoadingType(getLoading(state), CANCEL_ITEM_ORDER_TRADE_REQUEST),
error: getError(state)
}
}

const mapDispatch = (dispatch: MapDispatch): MapDispatchProps => ({
onCreateItemOrder: (item: Item, priceInWei: string, beneficiary: string, collection: Collection, expiresAt: Date) =>
dispatch(createItemOrderTradeRequest(item, priceInWei, beneficiary, collection, expiresAt))
dispatch(createItemOrderTradeRequest(item, priceInWei, beneficiary, collection, expiresAt)),
onRemoveFromSale: (tradeId: string) => dispatch(cancelItemOrderTradeRequest(tradeId))
})

export default connect(mapState, mapDispatch)(PutForSaleOffchainModal)
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
.modalTitle {
font-size: 20px;
font-weight: 700;
line-height: 32px;
text-align: center;
}

.modalSubtitle {
font-size: 16px;
line-height: 24px;
text-align: center;
}

:global(.PutForSaleOffchainModal.ui.modal > .content) {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}

.modalContent {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
max-width: 500px;
padding: 40px 0;
}

.modalIcon {
background: var(--secondary-text);
border-radius: 50%;
width: 80px;
height: 80px;
display: flex;
align-items: center;
justify-content: center;
}

.modalIcon :global(i.icon) {
margin: 0;
}

.error {
max-width: 100%;
overflow: hidden;
color: var(--error);
}
Loading

0 comments on commit 95c0ba9

Please sign in to comment.