Skip to content

Commit

Permalink
feat: remove match selector
Browse files Browse the repository at this point in the history
  • Loading branch information
meelrossi committed Jun 10, 2024
1 parent 876452f commit d7496bc
Show file tree
Hide file tree
Showing 16 changed files with 89 additions and 120 deletions.
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
import { connect } from 'react-redux'
import { Dispatch } from 'redux'
import { isLoadingType } from 'decentraland-dapps/dist/modules/loading/selectors'
import { getAddress as getAddressFromUrl } from '../../../modules/account/selectors'
import { RootState } from '../../../modules/reducer'
import { goBack } from '../../../modules/routing/actions'
import { getViewAsGuest } from '../../../modules/routing/selectors'
import { fetchStoreRequest, FETCH_STORE_REQUEST } from '../../../modules/store/actions'
import { getStoresByOwner, getLocalStore, getLoading as getStoreLoading } from '../../../modules/store/selectors'
import { Store } from '../../../modules/store/types'
import { getAddress as getAddressFromWallet } from '../../../modules/wallet/selectors'
import { getAccountUrlParams } from '../../../utils/routing'
import AccountBanner from './AccountBanner'
import { MapStateProps, MapDispatchProps } from './AccountBanner.types'

const mapState = (state: RootState): MapStateProps => {
const viewAsGuest = getViewAsGuest(state)
const address = getAddressFromUrl(state) || getAddressFromWallet(state)
const addressFromUrl = getAccountUrlParams()?.address
const address = addressFromUrl || getAddressFromWallet(state)
const isLoading = isLoadingType(getStoreLoading(state), FETCH_STORE_REQUEST)

let store: Store | undefined = address ? getStoresByOwner(state)[address] : undefined
Expand Down
6 changes: 1 addition & 5 deletions webapp/src/components/AssetList/utils.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import { matchPath } from 'react-router-dom'
import { locations } from '../../modules/routing/locations'

function matchAppRoute<T extends Record<string, string>>(path: string, route: string) {
return matchPath<T>(path, { path: route, strict: true, exact: true })
}
import { matchAppRoute } from '../../utils/routing'

export function getLastVisitedElementId(currentLocation: string, lastVisitedLocation: string) {
const matchLands = matchAppRoute(currentLocation, locations.lands())
Expand Down
31 changes: 13 additions & 18 deletions webapp/src/components/AssetProvider/AssetProvider.container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,10 @@ import { Asset, AssetType } from '../../modules/asset/types'
import { getContract } from '../../modules/contract/selectors'
import { isLoadingFeatureFlags as getIsLoadingFeatureFlags } from '../../modules/features/selectors'
import { clearItemErrors, fetchItemRequest } from '../../modules/item/actions'
import {
getContractAddress as getItemContractAddress,
getTokenId as getItemTokenId,
isFetchingItem,
getError as getItemsError,
getData as getItems
} from '../../modules/item/selectors'
import { isFetchingItem, getError as getItemsError, getData as getItems } from '../../modules/item/selectors'
import { getItem } from '../../modules/item/utils'
import { fetchNFTRequest, FETCH_NFT_REQUEST, clearNFTErrors } from '../../modules/nft/actions'
import {
getContractAddress as getNFTContractAddress,
getTokenId as getNFTTokenId,
getLoading as getNFTLoading,
getError as getNFTError,
getData as getNFTs
} from '../../modules/nft/selectors'
import { getLoading as getNFTLoading, getError as getNFTError, getData as getNFTs } from '../../modules/nft/selectors'
import { getNFT } from '../../modules/nft/utils'
import { getData as getOrders } from '../../modules/order/selectors'
import { getActiveOrder } from '../../modules/order/utils'
Expand All @@ -33,6 +21,12 @@ import { getOpenRentalId } from '../../modules/rental/utils'
import { FetchOneOptions } from '../../modules/vendor'
import { ContractName } from '../../modules/vendor/decentraland'
import { convertToOutputString } from '../../utils/output'
import {
getItemContractAddressFromUrl,
getItemTokenIdFromUrl,
getNFTContractAddressFromUrl,
getNFTTokenIdFromUrl
} from '../../utils/routing'
import AssetProvider from './AssetProvider'
import { MapDispatch, MapDispatchProps, MapStateProps, OwnProps } from './AssetProvider.types'

Expand All @@ -47,17 +41,17 @@ const mapState = (state: RootState, ownProps: OwnProps): MapStateProps => {
switch (ownProps.type) {
case AssetType.NFT: {
const nfts = getNFTs(state)
contractAddress = contractAddress || getNFTContractAddress(state)
tokenId = tokenId || getNFTTokenId(state)
contractAddress = contractAddress || getNFTContractAddressFromUrl()
tokenId = tokenId || getNFTTokenIdFromUrl()
asset = getNFT(contractAddress, tokenId, nfts)
isLoading = isLoadingType(getNFTLoading(state), FETCH_NFT_REQUEST)
error = getNFTError(state)
break
}
case AssetType.ITEM: {
const items = getItems(state)
contractAddress = contractAddress || getItemContractAddress(state)
tokenId = tokenId || getItemTokenId(state)
contractAddress = contractAddress || getItemContractAddressFromUrl()
tokenId = tokenId || getItemTokenIdFromUrl()
asset = getItem(contractAddress, tokenId, items)
isLoading = isFetchingItem(state, contractAddress!, tokenId!)
error = getItemsError(state)
Expand All @@ -66,6 +60,7 @@ const mapState = (state: RootState, ownProps: OwnProps): MapStateProps => {
default:
throw new Error(`Invalid Asset type ${convertToOutputString(ownProps.type)}`)
}

const order = getActiveOrder(asset, orders)
const openRentalId = getOpenRentalId(asset)
const rental = openRentalId ? getRentalById(state, openRentalId) : null
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import { connect } from 'react-redux'
import { Dispatch } from 'redux'
import { getContractAddress } from '../../modules/collection/selectors'
import { RootState } from '../../modules/reducer'
import { goBack } from '../../modules/routing/actions'
import { getAddress } from '../../modules/wallet/selectors'
import CollectionPage from './CollectionPage'
import { MapDispatchProps, MapStateProps } from './CollectionPage.types'

const mapState = (state: RootState): MapStateProps => ({
contractAddress: getContractAddress(state),
currentAddress: getAddress(state)
})

Expand Down
4 changes: 3 additions & 1 deletion webapp/src/components/CollectionPage/CollectionPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { t } from 'decentraland-dapps/dist/modules/translation/utils'
import { Back, Column, Page, Row, Section, Header, Badge, Icon, Color, Button, Loader, useMobileMediaQuery } from 'decentraland-ui'
import { formatWeiMANA } from '../../lib/mana'
import { getBuilderCollectionDetailUrl } from '../../modules/collection/utils'
import { getCollectionContractAddressFromUrl } from '../../utils/routing'
import CollectionProvider from '../CollectionProvider'
import { Mana } from '../Mana'
import AssetCell from '../OnSaleOrRentList/AssetCell'
Expand All @@ -18,7 +19,8 @@ const WEARABLES_TAB = 'wearables'
const EMOTES_TAB = 'emotes'

const CollectionPage = (props: Props) => {
const { contractAddress, currentAddress, onBack } = props
const { currentAddress, onBack } = props
const contractAddress = getCollectionContractAddressFromUrl()

const isMobile = useMobileMediaQuery()

Expand Down
3 changes: 1 addition & 2 deletions webapp/src/components/CollectionPage/CollectionPage.types.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
export type Props = {
contractAddress: string | null
currentAddress?: string
onBack: () => void
}

export type MapStateProps = Pick<Props, 'contractAddress' | 'currentAddress'>
export type MapStateProps = Pick<Props, 'currentAddress'>
export type MapDispatchProps = Pick<Props, 'onBack'>
12 changes: 10 additions & 2 deletions webapp/src/components/StoreSettings/StoreSettings.container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,13 @@ import {
updateStoreRequest,
UPDATE_STORE_REQUEST
} from '../../modules/store/actions'
import { getStoresByOwner, getLocalStore, getLoading as getStoreLoading, getError } from '../../modules/store/selectors'
import {
getStoresByOwner,
getLocalStore,
getLoading as getStoreLoading,
getError,
getIsLocalStoreDirty
} from '../../modules/store/selectors'
import { Store } from '../../modules/store/types'
import { getEmptyStore } from '../../modules/store/utils'
import StoreSettings from './StoreSettings'
Expand All @@ -28,14 +34,16 @@ const mapState = (state: RootState): MapStateProps => {
const isLoading = isLoadingType(getStoreLoading(state), FETCH_STORE_REQUEST)
const isSaving = isLoadingType(getStoreLoading(state), UPDATE_STORE_REQUEST)
const error = getError(state)
const isDirty = getIsLocalStoreDirty(state)

return {
address,
store,
error,
canSubmit,
isLoading,
isSaving
isSaving,
isDirty
}
}

Expand Down
22 changes: 21 additions & 1 deletion webapp/src/components/StoreSettings/StoreSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,19 @@ import './StoreSettings.css'

const MAX_FILE_SIZE = 1000000

const StoreSettings = ({ address, store, canSubmit, error, isLoading, isSaving, onChange, onRevert, onSave, onFetchStore }: Props) => {
const StoreSettings = ({
address,
store,
canSubmit,
error,
isLoading,
isSaving,
isDirty,
onChange,
onRevert,
onSave,
onFetchStore
}: Props) => {
const { cover, description, website, facebook, twitter, discord } = store

const [coverSize, setCoverSize] = useState<number>()
Expand Down Expand Up @@ -52,6 +64,14 @@ const StoreSettings = ({ address, store, canSubmit, error, isLoading, isSaving,
}
}, [coverSize, website])

useEffect(() => {
return () => {
if (isDirty) {
onRevert(address)
}
}
}, [location])

const hasErrors = useMemo(() => Object.values(errors).some(error => !!error), [errors])

const getInputValue = useCallback((type: LinkType) => store[type].replace(linkStartsWith[type], ''), [store])
Expand Down
3 changes: 2 additions & 1 deletion webapp/src/components/StoreSettings/StoreSettings.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ export type Props = {
canSubmit: boolean
isLoading: boolean
isSaving: boolean
isDirty: boolean
onChange: (store: Store) => void
onRevert: (address: string) => void
onSave: (store: Store) => void
onFetchStore: (address: string) => void
}

export type MapStateProps = Pick<Props, 'store' | 'canSubmit' | 'address' | 'isLoading' | 'isSaving' | 'error'>
export type MapStateProps = Pick<Props, 'store' | 'canSubmit' | 'address' | 'isLoading' | 'isSaving' | 'error' | 'isDirty'>
export type MapDispatchProps = Pick<Props, 'onChange' | 'onRevert' | 'onSave' | 'onFetchStore'>
9 changes: 0 additions & 9 deletions webapp/src/modules/account/selectors.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { createMatchSelector } from 'connected-react-router'
import { createSelector } from 'reselect'
import { Network } from '@dcl/schemas'
import { RootState } from '../reducer'
import { locations } from '../routing/locations'
import { AccountMetrics } from './types'
import { sumAccountMetrics } from './utils'

Expand All @@ -14,13 +12,6 @@ export const getMetricsByNetworkByAddress = (state: RootState) => getState(state
export const getLoading = (state: RootState) => getState(state).loading
export const getError = (state: RootState) => getState(state).error

const accountMatchSelector = createMatchSelector<RootState, { address: string }>(locations.account(':address'))

export const getAddress = createSelector<RootState, ReturnType<typeof accountMatchSelector>, string | undefined>(
accountMatchSelector,
match => match?.params.address?.toLowerCase()
)

export const getMetricsByAddressByNetwork = createSelector(getMetricsByNetworkByAddress, metrics => {
const addresses = new Set([...Object.keys(metrics.ETHEREUM), ...Object.keys(metrics.MATIC)])

Expand Down
9 changes: 0 additions & 9 deletions webapp/src/modules/collection/selectors.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { createMatchSelector } from 'connected-react-router'
import { AnyAction } from 'redux'
import { createSelector } from 'reselect'
import { Collection } from '@dcl/schemas'
import { RootState } from '../reducer'
import { locations } from '../routing/locations'
import {
FETCH_COLLECTIONS_REQUEST,
FETCH_SINGLE_COLLECTION_REQUEST,
Expand Down Expand Up @@ -45,10 +43,3 @@ export const getCollectionsByAddress = createSelector<RootState, ReturnType<type
{} as Record<string, Collection>
)
)

const CollectionDetailMatchSelector = createMatchSelector<RootState, { contractAddress: string }>(locations.collection(':contractAddress'))

export const getContractAddress = createSelector<RootState, ReturnType<typeof CollectionDetailMatchSelector>, string | null>(
CollectionDetailMatchSelector,
match => match?.params.contractAddress.toLowerCase() || null
)
20 changes: 0 additions & 20 deletions webapp/src/modules/item/selectors.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import { createMatchSelector } from 'connected-react-router'
import { AnyAction } from 'redux'
import { createSelector } from 'reselect'
import { Item } from '@dcl/schemas'
import { AuthorizationStepStatus } from 'decentraland-dapps/dist/containers/withAuthorizedAction/AuthorizationModal'
import { isLoadingType } from 'decentraland-dapps/dist/modules/loading/selectors'
import { RootState } from '../reducer'
import { locations } from '../routing/locations'
import {
BUY_ITEM_REQUEST,
FETCH_COLLECTION_ITEMS_REQUEST,
Expand Down Expand Up @@ -46,24 +44,6 @@ export const isFetchingItemsOfCollection = (state: RootState, contractAddress: s

export const getItems = createSelector<RootState, ReturnType<typeof getData>, Item[]>(getData, itemsById => Object.values(itemsById))

const ItemDetailMatchSelector = createMatchSelector<
RootState,
{
contractAddress: string
tokenId: string
}
>(locations.item(':contractAddress', ':tokenId'))

export const getContractAddress = createSelector<RootState, ReturnType<typeof ItemDetailMatchSelector>, string | null>(
ItemDetailMatchSelector,
match => match?.params.contractAddress.toLowerCase() || null
)

export const getTokenId = createSelector<RootState, ReturnType<typeof ItemDetailMatchSelector>, string | null>(
ItemDetailMatchSelector,
match => match?.params.tokenId || null
)

export const getItemsByContractAddress = createSelector(getItems, items =>
items.reduce(
(acc, item) => {
Expand Down
31 changes: 7 additions & 24 deletions webapp/src/modules/nft/selectors.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { createMatchSelector } from 'connected-react-router'
import { AnyAction } from 'redux'
import { createSelector } from 'reselect'
import { getAddress } from 'decentraland-dapps/dist/modules/wallet/selectors'
import { getNFTContractAddressFromUrl, getNFTTokenIdFromUrl } from '../../utils/routing'
import { RootState } from '../reducer'
import { locations } from '../routing/locations'
import { View } from '../ui/types'
import { FETCH_NFTS_REQUEST, FetchNFTsRequestAction } from './actions'
import { NFTState } from './reducer'
Expand All @@ -15,34 +14,18 @@ export const getData = (state: RootState) => getState(state).data
export const getLoading = (state: RootState) => getState(state).loading
export const getError = (state: RootState) => getState(state).error

const nftDetailMatchSelector = createMatchSelector<
RootState,
{
contractAddress: string
tokenId: string
}
>(locations.nft(':contractAddress', ':tokenId'))

const isFetchNftsRequestAction = (action: AnyAction): action is FetchNFTsRequestAction => action.type === FETCH_NFTS_REQUEST

export const isLoadingNftsByView = (state: RootState, view: View | undefined) =>
getLoading(state).filter((action: AnyAction) => isFetchNftsRequestAction(action) && action.payload?.options?.view === view)

export const getContractAddress = createSelector<RootState, ReturnType<typeof nftDetailMatchSelector>, string | null>(
nftDetailMatchSelector,
match => match?.params.contractAddress.toLowerCase() || null
)

export const getTokenId = createSelector<RootState, ReturnType<typeof nftDetailMatchSelector>, string | null>(
nftDetailMatchSelector,
match => match?.params.tokenId || null
)

export const getCurrentNFT = createSelector<RootState, string | null, string | null, NFTState['data'], NFT | null>(
state => getContractAddress(state),
state => getTokenId(state),
export const getCurrentNFT = createSelector<RootState, NFTState['data'], NFT | null>(
state => getData(state),
(contractAddress, tokenId, nfts) => getNFT(contractAddress, tokenId, nfts)
nfts => {
const contractAddress = getNFTContractAddressFromUrl()
const tokenId = getNFTTokenIdFromUrl()
return getNFT(contractAddress, tokenId, nfts)
}
)

export const getNFTsByOwner = createSelector<RootState, NFTState['data'], Record<string, NFT[]>>(
Expand Down
7 changes: 3 additions & 4 deletions webapp/src/modules/routing/selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { EmotePlayMode, GenderFilterOption, Network, Rarity } from '@dcl/schemas
import { t } from 'decentraland-dapps/dist/modules/translation/utils'
import { isOfEnumType } from '../../utils/enums'
import { AssetStatusFilter } from '../../utils/filters'
import { getAddress as getAccountAddress } from '../account/selectors'
import { getAccountAddressFromUrl } from '../../utils/routing'
import { AssetType } from '../asset/types'
import { RootState } from '../reducer'
import { getView } from '../ui/browse/selectors'
Expand Down Expand Up @@ -328,14 +328,13 @@ export const getEmoteHasGeometry = createSelector<RootState, string, boolean>(
export const getCurrentLocationAddress = createSelector<RootState, string, string | undefined, string | undefined, string | undefined>(
getPathName,
getWalletAddress,
getAccountAddress,
(pathname, walletAddress, accountAddress) => {
(pathname, walletAddress) => {
let address: string | undefined

if (pathname === locations.currentAccount()) {
address = walletAddress
} else {
address = accountAddress
address = getAccountAddressFromUrl()
}

return address ? address.toLowerCase() : undefined
Expand Down
Loading

0 comments on commit d7496bc

Please sign in to comment.