mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
parent
a0e97f4681
commit
be65eb7339
@ -36,6 +36,7 @@ export default class AppStateController extends EventEmitter {
|
|||||||
trezorModel: null,
|
trezorModel: null,
|
||||||
...initState,
|
...initState,
|
||||||
qrHardware: {},
|
qrHardware: {},
|
||||||
|
collectiblesDropdownState: {},
|
||||||
});
|
});
|
||||||
this.timer = null;
|
this.timer = null;
|
||||||
|
|
||||||
@ -282,4 +283,15 @@ export default class AppStateController extends EventEmitter {
|
|||||||
enableEIP1559V2NoticeDismissed,
|
enableEIP1559V2NoticeDismissed,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A setter for the `collectiblesDropdownState` property
|
||||||
|
*
|
||||||
|
* @param collectiblesDropdownState
|
||||||
|
*/
|
||||||
|
updateCollectibleDropDownState(collectiblesDropdownState) {
|
||||||
|
this.store.updateState({
|
||||||
|
collectiblesDropdownState,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1271,6 +1271,9 @@ export default class MetamaskController extends EventEmitter {
|
|||||||
setEnableEIP1559V2NoticeDismissed: appStateController.setEnableEIP1559V2NoticeDismissed.bind(
|
setEnableEIP1559V2NoticeDismissed: appStateController.setEnableEIP1559V2NoticeDismissed.bind(
|
||||||
appStateController,
|
appStateController,
|
||||||
),
|
),
|
||||||
|
updateCollectibleDropDownState: appStateController.updateCollectibleDropDownState.bind(
|
||||||
|
appStateController,
|
||||||
|
),
|
||||||
// EnsController
|
// EnsController
|
||||||
tryReverseResolveAddress: ensController.reverseResolveAddress.bind(
|
tryReverseResolveAddress: ensController.reverseResolveAddress.bind(
|
||||||
ensController,
|
ensController,
|
||||||
|
@ -30,6 +30,7 @@ import {
|
|||||||
getSelectedIdentity,
|
getSelectedIdentity,
|
||||||
} from '../../../selectors';
|
} from '../../../selectors';
|
||||||
import AssetNavigation from '../../../pages/asset/components/asset-navigation';
|
import AssetNavigation from '../../../pages/asset/components/asset-navigation';
|
||||||
|
import Copy from '../../ui/icon/copy-icon.component';
|
||||||
import { getCollectibleContracts } from '../../../ducks/metamask/metamask';
|
import { getCollectibleContracts } from '../../../ducks/metamask/metamask';
|
||||||
import { DEFAULT_ROUTE, SEND_ROUTE } from '../../../helpers/constants/routes';
|
import { DEFAULT_ROUTE, SEND_ROUTE } from '../../../helpers/constants/routes';
|
||||||
import {
|
import {
|
||||||
@ -52,10 +53,12 @@ import { ASSET_TYPES, updateSendAsset } from '../../../ducks/send';
|
|||||||
import InfoTooltip from '../../ui/info-tooltip';
|
import InfoTooltip from '../../ui/info-tooltip';
|
||||||
import { ERC721 } from '../../../helpers/constants/common';
|
import { ERC721 } from '../../../helpers/constants/common';
|
||||||
import { usePrevious } from '../../../hooks/usePrevious';
|
import { usePrevious } from '../../../hooks/usePrevious';
|
||||||
|
import { useCopyToClipboard } from '../../../hooks/useCopyToClipboard';
|
||||||
|
|
||||||
export default function CollectibleDetails({ collectible }) {
|
export default function CollectibleDetails({ collectible }) {
|
||||||
const {
|
const {
|
||||||
image,
|
image,
|
||||||
|
imageOriginal,
|
||||||
name,
|
name,
|
||||||
description,
|
description,
|
||||||
address,
|
address,
|
||||||
@ -70,6 +73,7 @@ export default function CollectibleDetails({ collectible }) {
|
|||||||
const ipfsGateway = useSelector(getIpfsGateway);
|
const ipfsGateway = useSelector(getIpfsGateway);
|
||||||
const collectibleContracts = useSelector(getCollectibleContracts);
|
const collectibleContracts = useSelector(getCollectibleContracts);
|
||||||
const currentNetwork = useSelector(getCurrentChainId);
|
const currentNetwork = useSelector(getCurrentChainId);
|
||||||
|
const [copied, handleCopy] = useCopyToClipboard();
|
||||||
|
|
||||||
const collectibleContractName = collectibleContracts.find(
|
const collectibleContractName = collectibleContracts.find(
|
||||||
({ address: contractAddress }) =>
|
({ address: contractAddress }) =>
|
||||||
@ -78,7 +82,10 @@ export default function CollectibleDetails({ collectible }) {
|
|||||||
const selectedAccountName = useSelector(
|
const selectedAccountName = useSelector(
|
||||||
(state) => getSelectedIdentity(state).name,
|
(state) => getSelectedIdentity(state).name,
|
||||||
);
|
);
|
||||||
const collectibleImageURL = getAssetImageURL(image, ipfsGateway);
|
const collectibleImageURL = getAssetImageURL(
|
||||||
|
imageOriginal ?? image,
|
||||||
|
ipfsGateway,
|
||||||
|
);
|
||||||
|
|
||||||
const onRemove = () => {
|
const onRemove = () => {
|
||||||
dispatch(removeAndIgnoreCollectible(address, tokenId));
|
dispatch(removeAndIgnoreCollectible(address, tokenId));
|
||||||
@ -171,10 +178,7 @@ export default function CollectibleDetails({ collectible }) {
|
|||||||
justifyContent={JUSTIFY_CONTENT.CENTER}
|
justifyContent={JUSTIFY_CONTENT.CENTER}
|
||||||
className="collectible-details__card"
|
className="collectible-details__card"
|
||||||
>
|
>
|
||||||
<img
|
<img className="collectible-details__image" src={image} />
|
||||||
className="collectible-details__image"
|
|
||||||
src={collectibleImageURL}
|
|
||||||
/>
|
|
||||||
</Card>
|
</Card>
|
||||||
<Box
|
<Box
|
||||||
flexDirection={FLEX_DIRECTION.COLUMN}
|
flexDirection={FLEX_DIRECTION.COLUMN}
|
||||||
@ -252,7 +256,7 @@ export default function CollectibleDetails({ collectible }) {
|
|||||||
href={collectibleImageURL}
|
href={collectibleImageURL}
|
||||||
title={collectibleImageURL}
|
title={collectibleImageURL}
|
||||||
>
|
>
|
||||||
{image}
|
{collectibleImageURL}
|
||||||
</a>
|
</a>
|
||||||
</Typography>
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
@ -270,31 +274,49 @@ export default function CollectibleDetails({ collectible }) {
|
|||||||
>
|
>
|
||||||
{t('contractAddress')}
|
{t('contractAddress')}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography
|
<Box
|
||||||
color={COLORS.PRIMARY1}
|
display={DISPLAY.FLEX}
|
||||||
variant={TYPOGRAPHY.H6}
|
flexDirection={FLEX_DIRECTION.ROW}
|
||||||
overflowWrap={OVERFLOW_WRAP.BREAK_WORD}
|
className="collectible-details__contract-wrapper"
|
||||||
boxProps={{
|
|
||||||
margin: 0,
|
|
||||||
marginBottom: 4,
|
|
||||||
}}
|
|
||||||
className="collectible-details__contract-link"
|
|
||||||
>
|
>
|
||||||
<a
|
<Typography
|
||||||
target="_blank"
|
color={COLORS.PRIMARY1}
|
||||||
rel="noopener noreferrer"
|
variant={TYPOGRAPHY.H6}
|
||||||
href={getTokenTrackerLink(
|
overflowWrap={OVERFLOW_WRAP.BREAK_WORD}
|
||||||
address,
|
boxProps={{
|
||||||
currentNetwork,
|
margin: 0,
|
||||||
null,
|
marginBottom: 4,
|
||||||
null,
|
}}
|
||||||
rpcPrefs,
|
className="collectible-details__contract-link"
|
||||||
)}
|
|
||||||
title={address}
|
|
||||||
>
|
>
|
||||||
{inPopUp ? shortenAddress(address) : address}
|
<a
|
||||||
</a>
|
target="_blank"
|
||||||
</Typography>
|
rel="noopener noreferrer"
|
||||||
|
href={getTokenTrackerLink(
|
||||||
|
address,
|
||||||
|
currentNetwork,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
rpcPrefs,
|
||||||
|
)}
|
||||||
|
title={address}
|
||||||
|
>
|
||||||
|
{inPopUp ? shortenAddress(address) : address}
|
||||||
|
</a>
|
||||||
|
</Typography>
|
||||||
|
<button
|
||||||
|
className="collectible-details__contract-copy-button"
|
||||||
|
onClick={() => {
|
||||||
|
handleCopy(address);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{copied ? (
|
||||||
|
t('copiedExclamation')
|
||||||
|
) : (
|
||||||
|
<Copy size={15} color="#6a737d" />
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
{inPopUp ? renderSendButton() : null}
|
{inPopUp ? renderSendButton() : null}
|
||||||
</Box>
|
</Box>
|
||||||
@ -314,6 +336,7 @@ CollectibleDetails.propTypes = {
|
|||||||
standard: PropTypes.string,
|
standard: PropTypes.string,
|
||||||
imageThumbnail: PropTypes.string,
|
imageThumbnail: PropTypes.string,
|
||||||
imagePreview: PropTypes.string,
|
imagePreview: PropTypes.string,
|
||||||
|
imageOriginal: PropTypes.string,
|
||||||
creator: PropTypes.shape({
|
creator: PropTypes.shape({
|
||||||
address: PropTypes.string,
|
address: PropTypes.string,
|
||||||
config: PropTypes.string,
|
config: PropTypes.string,
|
||||||
|
@ -53,18 +53,40 @@ $spacer-break-small: 16px;
|
|||||||
overflow-wrap: break-word;
|
overflow-wrap: break-word;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__contract-link,
|
&__contract-wrapper {
|
||||||
&__image-link {
|
max-width: calc(100% - #{$link-title-width});
|
||||||
word-break: break-all;
|
}
|
||||||
|
|
||||||
@media screen and (max-width: $break-small) {
|
&__contract-copy-button {
|
||||||
overflow: hidden;
|
@include H6;
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
width: 80px;
|
||||||
width: 90%;
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: center;
|
||||||
|
background-color: transparent;
|
||||||
|
cursor: pointer;
|
||||||
|
color: var(--ui-4);
|
||||||
|
border: 0;
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
transform: scale(0.97);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&__contract-link {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__image-link {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
max-width: 332px;
|
||||||
|
}
|
||||||
|
|
||||||
&__link-title {
|
&__link-title {
|
||||||
flex: 0 0 $link-title-width;
|
flex: 0 0 $link-title-width;
|
||||||
max-width: 0 0 $link-title-width;
|
max-width: 0 0 $link-title-width;
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
import { useHistory } from 'react-router-dom';
|
import { useHistory } from 'react-router-dom';
|
||||||
import Box from '../../ui/box';
|
import Box from '../../ui/box';
|
||||||
import Typography from '../../ui/typography/typography';
|
import Typography from '../../ui/typography/typography';
|
||||||
|
import Card from '../../ui/card';
|
||||||
import {
|
import {
|
||||||
COLORS,
|
COLORS,
|
||||||
TYPOGRAPHY,
|
TYPOGRAPHY,
|
||||||
@ -19,6 +20,9 @@ import { getEnvironmentType } from '../../../../app/scripts/lib/util';
|
|||||||
import { getIpfsGateway } from '../../../selectors';
|
import { getIpfsGateway } from '../../../selectors';
|
||||||
import { ASSET_ROUTE } from '../../../helpers/constants/routes';
|
import { ASSET_ROUTE } from '../../../helpers/constants/routes';
|
||||||
import { getAssetImageURL } from '../../../helpers/utils/util';
|
import { getAssetImageURL } from '../../../helpers/utils/util';
|
||||||
|
import { updateCollectibleDropDownState } from '../../../store/actions';
|
||||||
|
import { usePrevious } from '../../../hooks/usePrevious';
|
||||||
|
import { getCollectiblesDropdownState } from '../../../ducks/metamask/metamask';
|
||||||
|
|
||||||
const width =
|
const width =
|
||||||
getEnvironmentType() === ENVIRONMENT_TYPE_POPUP
|
getEnvironmentType() === ENVIRONMENT_TYPE_POPUP
|
||||||
@ -31,20 +35,30 @@ export default function CollectiblesItems({
|
|||||||
collections = {},
|
collections = {},
|
||||||
previouslyOwnedCollection = {},
|
previouslyOwnedCollection = {},
|
||||||
}) {
|
}) {
|
||||||
|
const dispatch = useDispatch();
|
||||||
const collectionsKeys = Object.keys(collections);
|
const collectionsKeys = Object.keys(collections);
|
||||||
|
const collectiblesDropdownState = useSelector(getCollectiblesDropdownState);
|
||||||
|
const previousCollectionKeys = usePrevious(collectionsKeys);
|
||||||
|
|
||||||
// if there is only one collection present set it to open when component mounts
|
useEffect(() => {
|
||||||
const [dropdownState, setDropdownState] = useState(() => {
|
if (
|
||||||
return collectionsKeys.length === 1
|
!Object.keys(collectiblesDropdownState).length &&
|
||||||
? {
|
previousCollectionKeys !== collectionsKeys
|
||||||
[PREVIOUSLY_OWNED_KEY]: false,
|
) {
|
||||||
[collectionsKeys[0]]: true,
|
const initState = {};
|
||||||
}
|
collectionsKeys.forEach((key) => {
|
||||||
: { [PREVIOUSLY_OWNED_KEY]: false };
|
initState[key] = true;
|
||||||
});
|
});
|
||||||
|
dispatch(updateCollectibleDropDownState(initState));
|
||||||
|
}
|
||||||
|
}, [
|
||||||
|
collectionsKeys,
|
||||||
|
previousCollectionKeys,
|
||||||
|
collectiblesDropdownState,
|
||||||
|
dispatch,
|
||||||
|
]);
|
||||||
|
|
||||||
const ipfsGateway = useSelector(getIpfsGateway);
|
const ipfsGateway = useSelector(getIpfsGateway);
|
||||||
|
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
|
|
||||||
const renderCollectionImage = (
|
const renderCollectionImage = (
|
||||||
@ -81,46 +95,50 @@ export default function CollectiblesItems({
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const isExpanded = dropdownState[key];
|
const isExpanded = collectiblesDropdownState[key];
|
||||||
return (
|
return (
|
||||||
<div
|
<div className="collectibles-items__collection" key={`collection-${key}`}>
|
||||||
className="collectibles-items__collection"
|
<button
|
||||||
key={`collection-${key}`}
|
onClick={() => {
|
||||||
onClick={() => {
|
dispatch(
|
||||||
setDropdownState((_dropdownState) => ({
|
updateCollectibleDropDownState({
|
||||||
..._dropdownState,
|
...collectiblesDropdownState,
|
||||||
[key]: !isExpanded,
|
[key]: !isExpanded,
|
||||||
}));
|
}),
|
||||||
}}
|
);
|
||||||
>
|
}}
|
||||||
<Box
|
className="collectibles-items__collection-wrapper"
|
||||||
marginBottom={2}
|
|
||||||
display={DISPLAY.FLEX}
|
|
||||||
alignItems={ALIGN_ITEMS.CENTER}
|
|
||||||
justifyContent={JUSTIFY_CONTENT.SPACE_BETWEEN}
|
|
||||||
className="collectibles-items__collection-accordion-title"
|
|
||||||
>
|
>
|
||||||
<Box
|
<Box
|
||||||
|
marginBottom={2}
|
||||||
|
display={DISPLAY.FLEX}
|
||||||
alignItems={ALIGN_ITEMS.CENTER}
|
alignItems={ALIGN_ITEMS.CENTER}
|
||||||
className="collectibles-items__collection-header"
|
justifyContent={JUSTIFY_CONTENT.SPACE_BETWEEN}
|
||||||
|
className="collectibles-items__collection-accordion-title"
|
||||||
>
|
>
|
||||||
{renderCollectionImage(
|
<Box
|
||||||
isPreviouslyOwnedCollection,
|
alignItems={ALIGN_ITEMS.CENTER}
|
||||||
collectionImage,
|
className="collectibles-items__collection-header"
|
||||||
collectionName,
|
|
||||||
)}
|
|
||||||
<Typography
|
|
||||||
color={COLORS.BLACK}
|
|
||||||
variant={TYPOGRAPHY.H5}
|
|
||||||
margin={[0, 0, 0, 2]}
|
|
||||||
>
|
>
|
||||||
{`${collectionName} (${collectibles.length})`}
|
{renderCollectionImage(
|
||||||
</Typography>
|
isPreviouslyOwnedCollection,
|
||||||
|
collectionImage,
|
||||||
|
collectionName,
|
||||||
|
)}
|
||||||
|
<Typography
|
||||||
|
color={COLORS.BLACK}
|
||||||
|
variant={TYPOGRAPHY.H5}
|
||||||
|
margin={[0, 0, 0, 2]}
|
||||||
|
>
|
||||||
|
{`${collectionName} (${collectibles.length})`}
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
<Box alignItems={ALIGN_ITEMS.FLEX_END}>
|
||||||
|
<i className={`fa fa-chevron-${isExpanded ? 'down' : 'right'}`} />
|
||||||
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
<Box alignItems={ALIGN_ITEMS.FLEX_END}>
|
</button>
|
||||||
<i className={`fa fa-chevron-${isExpanded ? 'down' : 'right'}`} />
|
|
||||||
</Box>
|
|
||||||
</Box>
|
|
||||||
{isExpanded ? (
|
{isExpanded ? (
|
||||||
<Box display={DISPLAY.FLEX} flexWrap={FLEX_WRAP.WRAP} gap={4}>
|
<Box display={DISPLAY.FLEX} flexWrap={FLEX_WRAP.WRAP} gap={4}>
|
||||||
{collectibles.map((collectible, i) => {
|
{collectibles.map((collectible, i) => {
|
||||||
@ -132,20 +150,22 @@ export default function CollectiblesItems({
|
|||||||
key={`collectible-${i}`}
|
key={`collectible-${i}`}
|
||||||
className="collectibles-items__collection-item-wrapper"
|
className="collectibles-items__collection-item-wrapper"
|
||||||
>
|
>
|
||||||
<div
|
<Card padding={0} justifyContent={JUSTIFY_CONTENT.CENTER}>
|
||||||
className="collectibles-items__collection-item"
|
<div
|
||||||
style={{
|
className="collectibles-items__collection-item"
|
||||||
backgroundColor,
|
style={{
|
||||||
}}
|
backgroundColor,
|
||||||
>
|
}}
|
||||||
<img
|
>
|
||||||
onClick={() =>
|
<img
|
||||||
history.push(`${ASSET_ROUTE}/${address}/${tokenId}`)
|
onClick={() =>
|
||||||
}
|
history.push(`${ASSET_ROUTE}/${address}/${tokenId}`)
|
||||||
className="collectibles-items__collection-item-image"
|
}
|
||||||
src={collectibleImage}
|
className="collectibles-items__collection-item-image"
|
||||||
/>
|
src={collectibleImage}
|
||||||
</div>
|
/>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
@ -6,6 +6,12 @@
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&-wrapper {
|
||||||
|
background-color: transparent;
|
||||||
|
border: 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
&-image {
|
&-image {
|
||||||
width: 32px;
|
width: 32px;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
|
@ -136,6 +136,11 @@ const COLLECTIBLES_CONTRACTS = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const collectiblesDropdownState = {
|
||||||
|
0x495f947276749ce646f68ac8c248420045cb7b5e: true,
|
||||||
|
0xdc7382eb0bc9c352a4cba23c909bda01e0206414: true,
|
||||||
|
};
|
||||||
|
|
||||||
const ACCOUNT_1 = '0x123';
|
const ACCOUNT_1 = '0x123';
|
||||||
const ACCOUNT_2 = '0x456';
|
const ACCOUNT_2 = '0x456';
|
||||||
|
|
||||||
@ -164,6 +169,7 @@ const render = ({
|
|||||||
selectedAddress,
|
selectedAddress,
|
||||||
collectiblesDetectionNoticeDismissed,
|
collectiblesDetectionNoticeDismissed,
|
||||||
useCollectibleDetection,
|
useCollectibleDetection,
|
||||||
|
collectiblesDropdownState,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
return renderWithProvider(<CollectiblesTab onAddNFT={onAddNFT} />, store);
|
return renderWithProvider(<CollectiblesTab onAddNFT={onAddNFT} />, store);
|
||||||
|
@ -707,6 +707,7 @@
|
|||||||
|
|
||||||
&__label {
|
&__label {
|
||||||
margin-right: 0.25rem;
|
margin-right: 0.25rem;
|
||||||
|
min-width: 52px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,6 +264,10 @@ export function getCollectiblesDetectionNoticeDismissed(state) {
|
|||||||
return state.metamask.collectiblesDetectionNoticeDismissed;
|
return state.metamask.collectiblesDetectionNoticeDismissed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getCollectiblesDropdownState(state) {
|
||||||
|
return state.metamask.collectiblesDropdownState;
|
||||||
|
}
|
||||||
|
|
||||||
export function getEnableEIP1559V2NoticeDismissed(state) {
|
export function getEnableEIP1559V2NoticeDismissed(state) {
|
||||||
return state.metamask.enableEIP1559V2NoticeDismissed;
|
return state.metamask.enableEIP1559V2NoticeDismissed;
|
||||||
}
|
}
|
||||||
|
@ -1491,6 +1491,19 @@ export function updateSendAsset({ type, details }) {
|
|||||||
dispatch(displayWarning(err.message));
|
dispatch(displayWarning(err.message));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (details.standard === undefined) {
|
||||||
|
const { standard } = await getTokenStandardAndDetails(
|
||||||
|
details.address,
|
||||||
|
userAddress,
|
||||||
|
);
|
||||||
|
details.standard = standard;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (details.standard === ERC1155) {
|
||||||
|
throw new Error('Sends of ERC1155 tokens are not currently supported');
|
||||||
|
}
|
||||||
|
|
||||||
if (isCurrentOwner) {
|
if (isCurrentOwner) {
|
||||||
error = null;
|
error = null;
|
||||||
balance = '0x1';
|
balance = '0x1';
|
||||||
|
@ -4,7 +4,7 @@ import SendRowWrapper from '../send-row-wrapper';
|
|||||||
import Identicon from '../../../../components/ui/identicon';
|
import Identicon from '../../../../components/ui/identicon';
|
||||||
import TokenBalance from '../../../../components/ui/token-balance';
|
import TokenBalance from '../../../../components/ui/token-balance';
|
||||||
import UserPreferencedCurrencyDisplay from '../../../../components/app/user-preferenced-currency-display';
|
import UserPreferencedCurrencyDisplay from '../../../../components/app/user-preferenced-currency-display';
|
||||||
import { ERC20, PRIMARY } from '../../../../helpers/constants/common';
|
import { ERC20, ERC721, PRIMARY } from '../../../../helpers/constants/common';
|
||||||
import { ASSET_TYPES } from '../../../../ducks/send';
|
import { ASSET_TYPES } from '../../../../ducks/send';
|
||||||
import { isEqualCaseInsensitive } from '../../../../helpers/utils/util';
|
import { isEqualCaseInsensitive } from '../../../../helpers/utils/util';
|
||||||
|
|
||||||
@ -57,7 +57,8 @@ export default class SendAssetRow extends Component {
|
|||||||
async componentDidMount() {
|
async componentDidMount() {
|
||||||
const sendableTokens = this.props.tokens.filter((token) => !token.isERC721);
|
const sendableTokens = this.props.tokens.filter((token) => !token.isERC721);
|
||||||
const sendableCollectibles = this.props.collectibles.filter(
|
const sendableCollectibles = this.props.collectibles.filter(
|
||||||
(collectible) => collectible.isCurrentlyOwned,
|
(collectible) =>
|
||||||
|
collectible.isCurrentlyOwned && collectible.standard === ERC721,
|
||||||
);
|
);
|
||||||
this.setState({ sendableTokens, sendableCollectibles });
|
this.setState({ sendableTokens, sendableCollectibles });
|
||||||
}
|
}
|
||||||
|
@ -64,10 +64,11 @@ export default class ExperimentalTab extends PureComponent {
|
|||||||
useCollectibleDetection,
|
useCollectibleDetection,
|
||||||
setUseCollectibleDetection,
|
setUseCollectibleDetection,
|
||||||
openSeaEnabled,
|
openSeaEnabled,
|
||||||
|
setOpenSeaEnabled,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="settings-page__content-row">
|
<div className="settings-page__content-row--dependent">
|
||||||
<div className="settings-page__content-item">
|
<div className="settings-page__content-item">
|
||||||
<span>{t('useCollectibleDetection')}</span>
|
<span>{t('useCollectibleDetection')}</span>
|
||||||
<div className="settings-page__content-description">
|
<div className="settings-page__content-description">
|
||||||
@ -77,7 +78,6 @@ export default class ExperimentalTab extends PureComponent {
|
|||||||
<div className="settings-page__content-item">
|
<div className="settings-page__content-item">
|
||||||
<div className="settings-page__content-item-col">
|
<div className="settings-page__content-item-col">
|
||||||
<ToggleButton
|
<ToggleButton
|
||||||
disabled={!openSeaEnabled}
|
|
||||||
value={useCollectibleDetection}
|
value={useCollectibleDetection}
|
||||||
onToggle={(value) => {
|
onToggle={(value) => {
|
||||||
this.context.metricsEvent({
|
this.context.metricsEvent({
|
||||||
@ -87,6 +87,9 @@ export default class ExperimentalTab extends PureComponent {
|
|||||||
name: 'Collectible Detection',
|
name: 'Collectible Detection',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
if (!value && !openSeaEnabled) {
|
||||||
|
setOpenSeaEnabled(!value);
|
||||||
|
}
|
||||||
setUseCollectibleDetection(!value);
|
setUseCollectibleDetection(!value);
|
||||||
}}
|
}}
|
||||||
offLabel={t('off')}
|
offLabel={t('off')}
|
||||||
@ -103,10 +106,15 @@ export default class ExperimentalTab extends PureComponent {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const { t } = this.context;
|
const { t } = this.context;
|
||||||
const { openSeaEnabled, setOpenSeaEnabled } = this.props;
|
const {
|
||||||
|
openSeaEnabled,
|
||||||
|
setOpenSeaEnabled,
|
||||||
|
useCollectibleDetection,
|
||||||
|
setUseCollectibleDetection,
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="settings-page__content-row">
|
<div className="settings-page__content-row--parent">
|
||||||
<div className="settings-page__content-item">
|
<div className="settings-page__content-item">
|
||||||
<span>{t('enableOpenSeaAPI')}</span>
|
<span>{t('enableOpenSeaAPI')}</span>
|
||||||
<div className="settings-page__content-description">
|
<div className="settings-page__content-description">
|
||||||
@ -126,6 +134,9 @@ export default class ExperimentalTab extends PureComponent {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
setOpenSeaEnabled(!value);
|
setOpenSeaEnabled(!value);
|
||||||
|
if (value && !useCollectibleDetection) {
|
||||||
|
setUseCollectibleDetection(true);
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
offLabel={t('off')}
|
offLabel={t('off')}
|
||||||
onLabel={t('on')}
|
onLabel={t('on')}
|
||||||
|
@ -168,6 +168,15 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
padding: 10px 0 20px;
|
padding: 10px 0 20px;
|
||||||
|
|
||||||
|
&--parent {
|
||||||
|
padding: 10px 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--dependent {
|
||||||
|
margin-left: 48px;
|
||||||
|
padding: 0 0 20px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__content-item {
|
&__content-item {
|
||||||
|
@ -1829,6 +1829,13 @@ export function hideAlert() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function updateCollectibleDropDownState(value) {
|
||||||
|
return async (dispatch) => {
|
||||||
|
await promisifiedBackground.updateCollectibleDropDownState(value);
|
||||||
|
await forceUpdateMetamaskState(dispatch);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This action will receive two types of values via qrCodeData
|
* This action will receive two types of values via qrCodeData
|
||||||
* an object with the following structure {type, values}
|
* an object with the following structure {type, values}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user