From c8053493e36f3431472d020a69dd6a7fd4cbc3e7 Mon Sep 17 00:00:00 2001 From: zhouhanseng Date: Wed, 5 Jan 2022 17:31:52 +0800 Subject: [PATCH 01/28] feat: asset player render from chain --- .../Collectible/SNSAdaptor/ArticleTab.tsx | 27 +++++-- .../plugins/RedPacket/SNSAdaptor/NftImage.tsx | 68 +++++++++--------- .../plugins/RedPacket/SNSAdaptor/NftList.tsx | 6 +- .../SNSAdaptor/RedPacketERC721Form.tsx | 4 +- .../RedPacket/SNSAdaptor/RedPacketNft.tsx | 41 +++-------- .../SNSAdaptor/RedpacketNftConfirmDialog.tsx | 4 +- .../SNSAdaptor/SelectNftTokenDialog.tsx | 14 ++-- .../src/UI/components/AssetPlayer/index.tsx | 71 +++++++++++-------- packages/shared/src/constants.tsx | 2 +- 9 files changed, 127 insertions(+), 110 deletions(-) diff --git a/packages/mask/src/plugins/Collectible/SNSAdaptor/ArticleTab.tsx b/packages/mask/src/plugins/Collectible/SNSAdaptor/ArticleTab.tsx index 5821a424dd76..df48bd8d7e25 100644 --- a/packages/mask/src/plugins/Collectible/SNSAdaptor/ArticleTab.tsx +++ b/packages/mask/src/plugins/Collectible/SNSAdaptor/ArticleTab.tsx @@ -4,7 +4,7 @@ import { CollectibleState } from '../hooks/useCollectibleState' import { AssetPlayer } from '@masknet/shared' import { useMemo } from 'react' -const useStyles = makeStyles()({ +const useStyles = makeStyles()((theme) => ({ body: { display: 'flex', justifyContent: 'center', @@ -16,11 +16,29 @@ const useStyles = makeStyles()({ }, errorPlaceholder: { padding: '82px 0', + backgroundColor: theme.palette.background.default, + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + borderRadius: 12, + width: '100%', }, loadingPlaceholder: { + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + width: '100%', padding: '74px 0', }, -}) + loadingIcon: { + width: 36, + height: 52, + }, + errorIcon: { + width: 36, + height: 36, + }, +})) export interface ArticleTabProps {} @@ -39,10 +57,7 @@ export function ArticleTab(props: ArticleTabProps) { options={{ playsInline: true, }} - classes={{ - errorPlaceholder: classes.errorPlaceholder, - loadingPlaceholder: classes.loadingPlaceholder, - }} + classes={classes} /> diff --git a/packages/mask/src/plugins/RedPacket/SNSAdaptor/NftImage.tsx b/packages/mask/src/plugins/RedPacket/SNSAdaptor/NftImage.tsx index 650eb12bf802..35dd0a1fd251 100644 --- a/packages/mask/src/plugins/RedPacket/SNSAdaptor/NftImage.tsx +++ b/packages/mask/src/plugins/RedPacket/SNSAdaptor/NftImage.tsx @@ -1,55 +1,59 @@ -import type { ERC721TokenDetailed } from '@masknet/web3-shared-evm' -import { CircularProgress } from '@mui/material' +import classNames from 'classnames' +import type { ChainId } from '@masknet/web3-shared-evm' import { makeStyles, useStylesExtends } from '@masknet/theme' +import { AssetPlayer } from '@masknet/shared' const useStyles = makeStyles()((theme) => ({ - imgWrapper: { + wrapper: { display: 'flex', justifyContent: 'center', alignItems: 'center', - height: 160, + height: '160px !important', width: 120, overflow: 'hidden', }, loadingNftImg: { marginTop: 20, }, - selectWrapperImg: { - maxWidth: '100%', - minHeight: 160, + loadingPlaceholder: { + height: 160, + width: 120, }, - fallbackNftImg: { - width: 64, - height: 64, - transform: 'translateY(10px)', + loadingFailImage: { + height: 160, + width: 120, + }, + loadingIcon: { + width: 36, + height: 52, }, })) -interface NftImageProps extends withClasses<'loadingFailImage'> { - token: ERC721TokenDetailed | undefined +interface NftImageProps extends withClasses<'loadingFailImage' | 'iframe'> { + chainId: ChainId + contractAddress: string + tokenId: string fallbackImage: URL } export function NftImage(props: NftImageProps) { - const { token, fallbackImage } = props + const { chainId, contractAddress, tokenId, fallbackImage } = props const classes = useStylesExtends(useStyles(), props) - + console.log({ props }) return ( -
- {!token?.info.hasTokenDetailed ? ( - - ) : token?.info.mediaUrl ? ( - { - const target = event.currentTarget - target.src = fallbackImage.toString() - target.classList.add(classes.loadingFailImage ?? '') - }} - /> - ) : ( - - )} -
+ ) } diff --git a/packages/mask/src/plugins/RedPacket/SNSAdaptor/NftList.tsx b/packages/mask/src/plugins/RedPacket/SNSAdaptor/NftList.tsx index 0566a6784a10..3603883d723a 100644 --- a/packages/mask/src/plugins/RedPacket/SNSAdaptor/NftList.tsx +++ b/packages/mask/src/plugins/RedPacket/SNSAdaptor/NftList.tsx @@ -4,7 +4,7 @@ import { List, ListItem, ListProps, Skeleton, Typography } from '@mui/material' import classnames from 'classnames' import type { FC, HTMLProps } from 'react' import { useI18N } from '../../../utils' -import { NftImage } from './NftImage' +// import { NftImage } from './NftImage' const useStyles = makeStyles()((theme) => { const smallQuery = `@media (max-width: ${theme.breakpoints.values.sm}px)` @@ -108,13 +108,13 @@ export const NftItem: FC = ({ contract, tokenId, className, claime return (
- + /> */} {result.tokenDetailed.info.name} {claimed && {t('plugin_red_packet_claimed')}}
diff --git a/packages/mask/src/plugins/RedPacket/SNSAdaptor/RedPacketERC721Form.tsx b/packages/mask/src/plugins/RedPacket/SNSAdaptor/RedPacketERC721Form.tsx index 0ad9dc392d13..25e6b7411352 100644 --- a/packages/mask/src/plugins/RedPacket/SNSAdaptor/RedPacketERC721Form.tsx +++ b/packages/mask/src/plugins/RedPacket/SNSAdaptor/RedPacketERC721Form.tsx @@ -313,7 +313,9 @@ export function RedPacketERC721Form(props: RedPacketERC721FormProps) { {existTokenDetailedList.map((value, i) => ( ({ maxWidth: 400, fontSize: '1.5rem', }, + assetPlayerIframe: { + marginBottom: 16, + }, })) export interface RedPacketNftProps { payload: RedPacketNftJSONPayload @@ -257,29 +257,6 @@ export function RedPacketNft({ payload }: RedPacketNftProps) { ) }, [payload]) - const { asyncRetry, tokenDetailed: erc721TokenDetailed } = useERC721TokenDetailed( - availability - ? ({ - type: EthereumTokenType.ERC721, - address: payload.contractAddress, - chainId: payload.chainId, - name: payload.contractName, - symbol: '', - baseURI: '', - iconURL: payload.contractTokenURI, - } as ERC721ContractDetailed) - : undefined, - availability?.claimed_id, - ) - - const { retry: retryERC721TokenDetailed, error: ERC721TokenDetailedError } = asyncRetry - const isFailedToLoading = Boolean(availabilityError || ERC721TokenDetailedError) - - const onErrorRetry = useCallback(() => { - retryAvailability() - retryERC721TokenDetailed() - }, [retryAvailability, retryERC721TokenDetailed]) - useEffect(() => { if (![TransactionStateType.CONFIRMED, TransactionStateType.FAILED].includes(claimState.type)) { return @@ -297,7 +274,6 @@ export function RedPacketNft({ payload }: RedPacketNftProps) { resetCallback() }, [account]) - const previewNftImg = new URL('./assets/nft-preview.png', import.meta.url).toString() const rpNftImg = new URL('./assets/redpacket.nft.png', import.meta.url).toString() //#region on share const postLink = usePostLink() @@ -335,7 +311,7 @@ export function RedPacketNft({ payload }: RedPacketNftProps) { }, [shareLink]) //#endregion - if (isFailedToLoading) + if (Boolean(availabilityError)) return (
@@ -344,7 +320,7 @@ export function RedPacketNft({ payload }: RedPacketNftProps) { {t('loading_failed')}
- {loadingToken || !tokenDetailed ? ( + {loadingToken || !tokenDetailed || !contract ? ( {loadingToken @@ -495,7 +495,9 @@ export function SelectNftTokenDialog(props: SelectNftTokenDialogProps) { ) : ( { + extends withClasses< + 'errorPlaceholder' | 'errorIcon' | 'loadingPlaceholder' | 'loadingIcon' | 'loadingFailImage' | 'iframe' + > { url?: string type?: string options?: { @@ -17,32 +27,12 @@ interface AssetPlayerProps loop?: boolean muted?: boolean } + erc721Token?: ERC721TokenQuery iconProps?: SvgIconProps + fallbackImage?: URL + setERC721TokenName?: (name: string) => void } -const useStyles = makeStyles()((theme) => ({ - errorPlaceholder: { - backgroundColor: theme.palette.background.default, - display: 'flex', - justifyContent: 'center', - alignItems: 'center', - borderRadius: 12, - width: '100%', - }, - errorIcon: { - width: 36, - height: 36, - }, - loadingPlaceholder: { - display: 'flex', - justifyContent: 'center', - alignItems: 'center', - width: '100%', - }, - loadingIcon: { - width: 36, - height: 52, - }, -})) +const useStyles = makeStyles()({}) enum AssetPlayerState { LOADING = 0, @@ -56,7 +46,12 @@ const TIMEOUT = 10000 export const AssetPlayer = memo(({ url, type, options, iconProps, ...props }) => { const ref = useRef(null) const classes = useStylesExtends(useStyles(), props) - const [playerState, setPlayerState] = useState(url ? AssetPlayerState.LOADING : AssetPlayerState.ERROR) + const { RPC: RPC_Entries } = getRPCConstants(props.erc721Token?.chainId) + const rpc = first(RPC_Entries) + const erc721Token = rpc ? ({ ...props.erc721Token, rpc } as ERC721TokenQuery) : undefined + const [playerState, setPlayerState] = useState( + url || erc721Token ? AssetPlayerState.LOADING : AssetPlayerState.ERROR, + ) //#region If onResized is not triggered within the specified time, set player state to error const [, cancel, reset] = useTimeoutFn(() => { @@ -70,7 +65,7 @@ export const AssetPlayer = memo(({ url, type, options, iconPro const setIframe = useCallback(() => { // if iframe isn't be init or the load error has been existed if (!ref.current || playerState === AssetPlayerState.ERROR) return - if (!url) { + if (!url && !erc721Token) { setPlayerState(AssetPlayerState.ERROR) return } @@ -78,19 +73,25 @@ export const AssetPlayer = memo(({ url, type, options, iconPro reset() ref.current.iFrameResizer.sendMessage({ url, + erc721Token, type, ...options, }) return } - }, [url, type, JSON.stringify(options), playerState]) + }, [url, erc721Token, type, JSON.stringify(options), playerState]) //endregion + type ERC721TokenNameMsg = { type: 'name'; name: string } //#region resource loaded error - const onMessage = useCallback(({ message }: { message: { name: string } }) => { + const onMessage = useCallback(({ message }: { message: { name: string } | ERC721TokenNameMsg }) => { if (message?.name === 'Error') { setPlayerState(AssetPlayerState.ERROR) } + + if ((message as ERC721TokenNameMsg).type === 'name') { + props.setERC721TokenName?.((message as ERC721TokenNameMsg).name) + } }, []) //#endregion @@ -106,7 +107,11 @@ export const AssetPlayer = memo(({ url, type, options, iconPro } style={{ display: playerState === AssetPlayerState.NORMAL ? 'none' : undefined }}> {playerState === AssetPlayerState.ERROR ? ( - + props.fallbackImage ? ( + + ) : ( + + ) ) : ( )} @@ -118,12 +123,16 @@ export const AssetPlayer = memo(({ url, type, options, iconPro setPlayerState(AssetPlayerState.INIT) setIframe() }} + className={playerState !== AssetPlayerState.NORMAL ? '' : classes.iframe} onResized={({ type }) => { if (type === 'init') return cancel() setPlayerState(AssetPlayerState.NORMAL) }} - style={{ width: playerState !== AssetPlayerState.NORMAL ? 0 : undefined }} + style={{ + width: playerState !== AssetPlayerState.NORMAL ? 0 : undefined, + height: playerState !== AssetPlayerState.NORMAL ? 0 : undefined, + }} checkOrigin={false} onMessage={onMessage} frameBorder="0" diff --git a/packages/shared/src/constants.tsx b/packages/shared/src/constants.tsx index cd50d3028e19..fe3f68a2a6ca 100644 --- a/packages/shared/src/constants.tsx +++ b/packages/shared/src/constants.tsx @@ -8,4 +8,4 @@ export const SOCIAL_MEDIA_ICON_MAPPING: Record = { 'instagram.com': , } -export const mediaViewerUrl = 'https://dimensiondev.github.io/Media-Viewer/index.html' +export const mediaViewerUrl = 'https://192.168.3.101:8081/index.html' From c77e76cf8d15866b7b403b36d14867921da2c3d6 Mon Sep 17 00:00:00 2001 From: zhouhanseng Date: Wed, 5 Jan 2022 18:14:27 +0800 Subject: [PATCH 02/28] chore: rename --- ...{NftImage.tsx => NFTLuckyDropStyledAssetPlayer.tsx} | 5 ++--- .../mask/src/plugins/RedPacket/SNSAdaptor/NftList.tsx | 10 ++++++---- .../RedPacket/SNSAdaptor/RedPacketERC721Form.tsx | 4 ++-- .../src/plugins/RedPacket/SNSAdaptor/RedPacketNft.tsx | 4 ++-- .../RedPacket/SNSAdaptor/RedpacketNftConfirmDialog.tsx | 4 ++-- .../RedPacket/SNSAdaptor/SelectNftTokenDialog.tsx | 6 +++--- 6 files changed, 17 insertions(+), 16 deletions(-) rename packages/mask/src/plugins/RedPacket/SNSAdaptor/{NftImage.tsx => NFTLuckyDropStyledAssetPlayer.tsx} (88%) diff --git a/packages/mask/src/plugins/RedPacket/SNSAdaptor/NftImage.tsx b/packages/mask/src/plugins/RedPacket/SNSAdaptor/NFTLuckyDropStyledAssetPlayer.tsx similarity index 88% rename from packages/mask/src/plugins/RedPacket/SNSAdaptor/NftImage.tsx rename to packages/mask/src/plugins/RedPacket/SNSAdaptor/NFTLuckyDropStyledAssetPlayer.tsx index 35dd0a1fd251..11c2c6d96caf 100644 --- a/packages/mask/src/plugins/RedPacket/SNSAdaptor/NftImage.tsx +++ b/packages/mask/src/plugins/RedPacket/SNSAdaptor/NFTLuckyDropStyledAssetPlayer.tsx @@ -29,16 +29,15 @@ const useStyles = makeStyles()((theme) => ({ }, })) -interface NftImageProps extends withClasses<'loadingFailImage' | 'iframe'> { +interface NFTLuckyDropStyledAssetPlayerProps extends withClasses<'loadingFailImage' | 'iframe'> { chainId: ChainId contractAddress: string tokenId: string fallbackImage: URL } -export function NftImage(props: NftImageProps) { +export function NFTLuckyDropStyledAssetPlayer(props: NFTLuckyDropStyledAssetPlayerProps) { const { chainId, contractAddress, tokenId, fallbackImage } = props const classes = useStylesExtends(useStyles(), props) - console.log({ props }) return ( { const smallQuery = `@media (max-width: ${theme.breakpoints.values.sm}px)` @@ -108,13 +108,15 @@ export const NftItem: FC = ({ contract, tokenId, className, claime return (
- {/* */} + /> {result.tokenDetailed.info.name} {claimed && {t('plugin_red_packet_claimed')}}
diff --git a/packages/mask/src/plugins/RedPacket/SNSAdaptor/RedPacketERC721Form.tsx b/packages/mask/src/plugins/RedPacket/SNSAdaptor/RedPacketERC721Form.tsx index 25e6b7411352..3496e533e22f 100644 --- a/packages/mask/src/plugins/RedPacket/SNSAdaptor/RedPacketERC721Form.tsx +++ b/packages/mask/src/plugins/RedPacket/SNSAdaptor/RedPacketERC721Form.tsx @@ -21,7 +21,7 @@ import AddCircleOutlineIcon from '@mui/icons-material/AddCircleOutline' import { RedpacketMessagePanel } from './RedpacketMessagePanel' import { SelectNftTokenDialog, OrderedERC721Token } from './SelectNftTokenDialog' import { RedpacketNftConfirmDialog } from './RedpacketNftConfirmDialog' -import { NftImage } from './NftImage' +import { NFTLuckyDropStyledAssetPlayer } from './NFTLuckyDropStyledAssetPlayer' import { NFTSelectOption } from '../types' import { NFT_RED_PACKET_MAX_SHARES } from '../constants' @@ -312,7 +312,7 @@ export function RedPacketERC721Form(props: RedPacketERC721FormProps) { {existTokenDetailedList.map((value, i) => ( - ({ root: { @@ -355,7 +355,7 @@ export function RedPacketNft({ payload }: RedPacketNftProps) { {availability.isClaimed ? ( - ({ root: { @@ -288,7 +288,7 @@ export function RedpacketNftConfirmDialog(props: RedpacketNftConfirmDialogProps) {tokenList.map((value, i) => ( - ) : ( - - Date: Wed, 5 Jan 2022 18:52:42 +0800 Subject: [PATCH 03/28] fix: reduce repeat request --- packages/shared/src/UI/components/AssetPlayer/index.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/shared/src/UI/components/AssetPlayer/index.tsx b/packages/shared/src/UI/components/AssetPlayer/index.tsx index 27c2b9f2d484..ddd6a4a88d30 100644 --- a/packages/shared/src/UI/components/AssetPlayer/index.tsx +++ b/packages/shared/src/UI/components/AssetPlayer/index.tsx @@ -64,12 +64,12 @@ export const AssetPlayer = memo(({ url, type, options, iconPro //#region setup iframe when url and options be changed const setIframe = useCallback(() => { // if iframe isn't be init or the load error has been existed - if (!ref.current || playerState === AssetPlayerState.ERROR) return + if (!ref.current || playerState === AssetPlayerState.ERROR || playerState === AssetPlayerState.NORMAL) return if (!url && !erc721Token) { setPlayerState(AssetPlayerState.ERROR) return } - if (playerState === AssetPlayerState.INIT || playerState === AssetPlayerState.NORMAL) { + if (playerState === AssetPlayerState.INIT) { reset() ref.current.iFrameResizer.sendMessage({ url, @@ -79,7 +79,7 @@ export const AssetPlayer = memo(({ url, type, options, iconPro }) return } - }, [url, erc721Token, type, JSON.stringify(options), playerState]) + }, [url, JSON.stringify(erc721Token), type, JSON.stringify(options), playerState]) //endregion type ERC721TokenNameMsg = { type: 'name'; name: string } @@ -125,7 +125,7 @@ export const AssetPlayer = memo(({ url, type, options, iconPro }} className={playerState !== AssetPlayerState.NORMAL ? '' : classes.iframe} onResized={({ type }) => { - if (type === 'init') return + if (type === 'init' || playerState === AssetPlayerState.NORMAL) return cancel() setPlayerState(AssetPlayerState.NORMAL) }} From c933069327d4d398c7ec69d94d53f7055cbdf98a Mon Sep 17 00:00:00 2001 From: zhouhanseng Date: Thu, 6 Jan 2022 11:57:48 +0800 Subject: [PATCH 04/28] chore: rename --- ...ledAssetPlayer.tsx => NFTCardStyledAssetPlayer.tsx} | 6 +----- .../mask/src/plugins/RedPacket/SNSAdaptor/NftList.tsx | 4 ++-- .../RedPacket/SNSAdaptor/RedPacketERC721Form.tsx | 4 ++-- .../src/plugins/RedPacket/SNSAdaptor/RedPacketNft.tsx | 9 +++++++-- .../RedPacket/SNSAdaptor/RedpacketNftConfirmDialog.tsx | 4 ++-- .../RedPacket/SNSAdaptor/SelectNftTokenDialog.tsx | 10 +++++----- 6 files changed, 19 insertions(+), 18 deletions(-) rename packages/mask/src/plugins/RedPacket/SNSAdaptor/{NFTLuckyDropStyledAssetPlayer.tsx => NFTCardStyledAssetPlayer.tsx} (90%) diff --git a/packages/mask/src/plugins/RedPacket/SNSAdaptor/NFTLuckyDropStyledAssetPlayer.tsx b/packages/mask/src/plugins/RedPacket/SNSAdaptor/NFTCardStyledAssetPlayer.tsx similarity index 90% rename from packages/mask/src/plugins/RedPacket/SNSAdaptor/NFTLuckyDropStyledAssetPlayer.tsx rename to packages/mask/src/plugins/RedPacket/SNSAdaptor/NFTCardStyledAssetPlayer.tsx index 11c2c6d96caf..361910c4e95e 100644 --- a/packages/mask/src/plugins/RedPacket/SNSAdaptor/NFTLuckyDropStyledAssetPlayer.tsx +++ b/packages/mask/src/plugins/RedPacket/SNSAdaptor/NFTCardStyledAssetPlayer.tsx @@ -19,10 +19,6 @@ const useStyles = makeStyles()((theme) => ({ height: 160, width: 120, }, - loadingFailImage: { - height: 160, - width: 120, - }, loadingIcon: { width: 36, height: 52, @@ -35,7 +31,7 @@ interface NFTLuckyDropStyledAssetPlayerProps extends withClasses<'loadingFailIma tokenId: string fallbackImage: URL } -export function NFTLuckyDropStyledAssetPlayer(props: NFTLuckyDropStyledAssetPlayerProps) { +export function NFTCardStyledAssetPlayer(props: NFTLuckyDropStyledAssetPlayerProps) { const { chainId, contractAddress, tokenId, fallbackImage } = props const classes = useStylesExtends(useStyles(), props) return ( diff --git a/packages/mask/src/plugins/RedPacket/SNSAdaptor/NftList.tsx b/packages/mask/src/plugins/RedPacket/SNSAdaptor/NftList.tsx index 230cd8bbaeb4..1f02e1b2e3e0 100644 --- a/packages/mask/src/plugins/RedPacket/SNSAdaptor/NftList.tsx +++ b/packages/mask/src/plugins/RedPacket/SNSAdaptor/NftList.tsx @@ -4,7 +4,7 @@ import { List, ListItem, ListProps, Skeleton, Typography } from '@mui/material' import classnames from 'classnames' import type { FC, HTMLProps } from 'react' import { useI18N } from '../../../utils' -import { NFTLuckyDropStyledAssetPlayer } from './NFTLuckyDropStyledAssetPlayer' +import { NFTCardStyledAssetPlayer } from './NFTCardStyledAssetPlayer' const useStyles = makeStyles()((theme) => { const smallQuery = `@media (max-width: ${theme.breakpoints.values.sm}px)` @@ -108,7 +108,7 @@ export const NftItem: FC = ({ contract, tokenId, className, claime return (
- {existTokenDetailedList.map((value, i) => ( - ({ root: { @@ -223,6 +223,10 @@ const useStyles = makeStyles()((theme) => ({ assetPlayerIframe: { marginBottom: 16, }, + loadingFailImage: { + height: 160, + width: 120, + }, })) export interface RedPacketNftProps { payload: RedPacketNftJSONPayload @@ -355,12 +359,13 @@ export function RedPacketNft({ payload }: RedPacketNftProps) { {availability.isClaimed ? ( - diff --git a/packages/mask/src/plugins/RedPacket/SNSAdaptor/RedpacketNftConfirmDialog.tsx b/packages/mask/src/plugins/RedPacket/SNSAdaptor/RedpacketNftConfirmDialog.tsx index dcaa6ca9a620..34bdef60e7a8 100644 --- a/packages/mask/src/plugins/RedPacket/SNSAdaptor/RedpacketNftConfirmDialog.tsx +++ b/packages/mask/src/plugins/RedPacket/SNSAdaptor/RedpacketNftConfirmDialog.tsx @@ -26,7 +26,7 @@ import { useCompositionContext } from '@masknet/plugin-infra' import { RedPacketNftMetaKey } from '../constants' import { WalletMessages } from '../../Wallet/messages' import { RedPacketRPC } from '../messages' -import { NFTLuckyDropStyledAssetPlayer } from './NFTLuckyDropStyledAssetPlayer' +import { NFTCardStyledAssetPlayer } from './NFTCardStyledAssetPlayer' const useStyles = makeStyles()((theme) => ({ root: { @@ -288,7 +288,7 @@ export function RedpacketNftConfirmDialog(props: RedpacketNftConfirmDialogProps) {tokenList.map((value, i) => ( - ()((theme, props) => ({ minHeight: '0px !important', maxWidth: 'none', transform: 'translateY(10px)', - width: '64px !important', - height: '64px !important', + width: 64, + height: 64, }, selectedTokenAmount: { color: props.isSelectSharesExceed ? '#FF5F5F' : '#1C68F3', @@ -494,7 +494,7 @@ export function SelectNftTokenDialog(props: SelectNftTokenDialogProps) { ) : ( - - Date: Thu, 6 Jan 2022 13:38:53 +0800 Subject: [PATCH 05/28] chore: replace dashboard transfer nft --- .../Wallets/components/Transfer/NFTCard.tsx | 47 +++++++++++------- .../plugins/RedPacket/SNSAdaptor/NftList.tsx | 3 +- .../SNSAdaptor/RedPacketERC721Form.tsx | 3 +- .../RedPacket/SNSAdaptor/RedPacketNft.tsx | 2 +- .../SNSAdaptor/RedpacketNftConfirmDialog.tsx | 3 +- .../SNSAdaptor/SelectNftTokenDialog.tsx | 6 +-- .../NFTCardStyledAssetPlayer/index.tsx} | 11 ++-- .../nft_token_fallback.png | Bin 0 -> 3686 bytes packages/shared/src/UI/components/index.ts | 1 + 9 files changed, 42 insertions(+), 34 deletions(-) rename packages/{mask/src/plugins/RedPacket/SNSAdaptor/NFTCardStyledAssetPlayer.tsx => shared/src/UI/components/NFTCardStyledAssetPlayer/index.tsx} (80%) create mode 100644 packages/shared/src/UI/components/NFTCardStyledAssetPlayer/nft_token_fallback.png diff --git a/packages/dashboard/src/pages/Wallets/components/Transfer/NFTCard.tsx b/packages/dashboard/src/pages/Wallets/components/Transfer/NFTCard.tsx index 3cffd817306e..2efd842ece74 100644 --- a/packages/dashboard/src/pages/Wallets/components/Transfer/NFTCard.tsx +++ b/packages/dashboard/src/pages/Wallets/components/Transfer/NFTCard.tsx @@ -2,7 +2,8 @@ import type { ERC721TokenDetailed } from '@masknet/web3-shared-evm' import { memo, useMemo, useState } from 'react' import { Checkbox, ImageListItem, ImageListItemBar, Box } from '@mui/material' import { getMaskColor, makeStyles, MaskColorVar } from '@masknet/theme' -import { MiniMaskIcon, CheckedBorderIcon, CheckedIcon } from '@masknet/icons' +import { CheckedBorderIcon, CheckedIcon } from '@masknet/icons' +import { NFTCardStyledAssetPlayer } from '@masknet/shared' const useStyles = makeStyles()({ card: { @@ -39,6 +40,23 @@ const useStyles = makeStyles()({ padding: 0, lineHeight: '16px', }, + wrapper: { + borderTopRightRadius: '12px', + borderTopLeftRadius: '12px', + width: '140px !important', + height: '186px !important', + }, + loadingPlaceholder: { + width: '140px !important', + height: '186px !important', + }, + loadingFailImage: { + minHeight: '0px !important', + maxWidth: 'none', + transform: 'translateY(10px)', + width: 64, + height: 64, + }, }) export interface NFTCardProps { @@ -49,7 +67,6 @@ export interface NFTCardProps { export const NFTCard = memo(({ token, selectedTokenId, onSelect }) => { const { classes } = useStyles() - const [loadFailed, setLoadFailed] = useState(false) const [checked, setChecked] = useState(!!selectedTokenId && selectedTokenId === token.tokenId) const isDisabled = useMemo( @@ -77,26 +94,22 @@ export const NFTCard = memo(({ token, selectedTokenId, onSelect }) return ( (theme.palette.mode === 'dark' ? getMaskColor(theme).white : '#F9F9FA'), }} className={isDisabled ? classes.disabled : ''}> - {loadFailed || !token.info.mediaUrl ? ( -
-
- -
-
- ) : ( - setLoadFailed(true)} - src={token.info.mediaUrl} - style={{ width: '100%', height: '100%', borderRadius: '8px 8px 0px 0px', objectFit: 'cover' }} - /> - )} + {NFTNameBar} { const smallQuery = `@media (max-width: ${theme.breakpoints.values.sm}px)` @@ -115,7 +115,6 @@ export const NftItem: FC = ({ contract, tokenId, className, claime tokenId={result.tokenDetailed.tokenId} contractAddress={result.tokenDetailed.contractDetailed.address} chainId={result.tokenDetailed.contractDetailed.chainId} - fallbackImage={new URL('./assets/nft_token_fallback.png', import.meta.url)} /> {result.tokenDetailed.info.name} {claimed && {t('plugin_red_packet_claimed')}} diff --git a/packages/mask/src/plugins/RedPacket/SNSAdaptor/RedPacketERC721Form.tsx b/packages/mask/src/plugins/RedPacket/SNSAdaptor/RedPacketERC721Form.tsx index 21b493924ebc..ac837aacaa20 100644 --- a/packages/mask/src/plugins/RedPacket/SNSAdaptor/RedPacketERC721Form.tsx +++ b/packages/mask/src/plugins/RedPacket/SNSAdaptor/RedPacketERC721Form.tsx @@ -21,7 +21,7 @@ import AddCircleOutlineIcon from '@mui/icons-material/AddCircleOutline' import { RedpacketMessagePanel } from './RedpacketMessagePanel' import { SelectNftTokenDialog, OrderedERC721Token } from './SelectNftTokenDialog' import { RedpacketNftConfirmDialog } from './RedpacketNftConfirmDialog' -import { NFTCardStyledAssetPlayer } from './NFTCardStyledAssetPlayer' +import { NFTCardStyledAssetPlayer } from '@masknet/shared' import { NFTSelectOption } from '../types' import { NFT_RED_PACKET_MAX_SHARES } from '../constants' @@ -319,7 +319,6 @@ export function RedPacketERC721Form(props: RedPacketERC721FormProps) { classes={{ loadingFailImage: classes.loadingFailImage, }} - fallbackImage={new URL('./assets/nft_token_fallback.png', import.meta.url)} />
diff --git a/packages/mask/src/plugins/RedPacket/SNSAdaptor/RedPacketNft.tsx b/packages/mask/src/plugins/RedPacket/SNSAdaptor/RedPacketNft.tsx index 13c9d9599886..f35322f68f04 100644 --- a/packages/mask/src/plugins/RedPacket/SNSAdaptor/RedPacketNft.tsx +++ b/packages/mask/src/plugins/RedPacket/SNSAdaptor/RedPacketNft.tsx @@ -21,7 +21,7 @@ import { usePostLink } from '../../../components/DataSource/usePostInfo' import { activatedSocialNetworkUI } from '../../../social-network' import { isTwitter } from '../../../social-network-adaptor/twitter.com/base' import { isFacebook } from '../../../social-network-adaptor/facebook.com/base' -import { NFTCardStyledAssetPlayer } from './NFTCardStyledAssetPlayer' +import { NFTCardStyledAssetPlayer } from '@masknet/shared' const useStyles = makeStyles()((theme) => ({ root: { diff --git a/packages/mask/src/plugins/RedPacket/SNSAdaptor/RedpacketNftConfirmDialog.tsx b/packages/mask/src/plugins/RedPacket/SNSAdaptor/RedpacketNftConfirmDialog.tsx index 34bdef60e7a8..5313e135004c 100644 --- a/packages/mask/src/plugins/RedPacket/SNSAdaptor/RedpacketNftConfirmDialog.tsx +++ b/packages/mask/src/plugins/RedPacket/SNSAdaptor/RedpacketNftConfirmDialog.tsx @@ -26,7 +26,7 @@ import { useCompositionContext } from '@masknet/plugin-infra' import { RedPacketNftMetaKey } from '../constants' import { WalletMessages } from '../../Wallet/messages' import { RedPacketRPC } from '../messages' -import { NFTCardStyledAssetPlayer } from './NFTCardStyledAssetPlayer' +import { NFTCardStyledAssetPlayer } from '@masknet/shared' const useStyles = makeStyles()((theme) => ({ root: { @@ -295,7 +295,6 @@ export function RedpacketNftConfirmDialog(props: RedpacketNftConfirmDialogProps) classes={{ loadingFailImage: classes.loadingFailImage, }} - fallbackImage={new URL('./assets/nft_token_fallback.png', import.meta.url)} />
diff --git a/packages/mask/src/plugins/RedPacket/SNSAdaptor/SelectNftTokenDialog.tsx b/packages/mask/src/plugins/RedPacket/SNSAdaptor/SelectNftTokenDialog.tsx index 3464f5623c8a..c8e3eb866315 100644 --- a/packages/mask/src/plugins/RedPacket/SNSAdaptor/SelectNftTokenDialog.tsx +++ b/packages/mask/src/plugins/RedPacket/SNSAdaptor/SelectNftTokenDialog.tsx @@ -16,7 +16,7 @@ import { SearchIcon } from '@masknet/icons' import CheckIcon from '@mui/icons-material/Check' import { Trans } from 'react-i18next' import { useUpdate } from 'react-use' -import { NFTCardStyledAssetPlayer } from './NFTCardStyledAssetPlayer' +import { NFTCardStyledAssetPlayer } from '@masknet/shared' import { findLastIndex, uniqBy } from 'lodash-unified' import { NFT_RED_PACKET_MAX_SHARES } from '../constants' @@ -501,7 +501,6 @@ export function SelectNftTokenDialog(props: SelectNftTokenDialogProps) { classes={{ loadingFailImage: classes.loadingFailImage, }} - fallbackImage={new URL('./assets/nft_token_fallback.png', import.meta.url)} />
@@ -650,9 +649,6 @@ export function SelectNftTokenDialog(props: SelectNftTokenDialogProps) { classes={{ loadingFailImage: classes.loadingFailImage, }} - fallbackImage={ - new URL('./assets/nft_token_fallback.png', import.meta.url) - } />
({ wrapper: { display: 'flex', justifyContent: 'center', alignItems: 'center', - height: '160px !important', + height: 160, width: 120, overflow: 'hidden', }, @@ -25,11 +25,12 @@ const useStyles = makeStyles()((theme) => ({ }, })) -interface NFTLuckyDropStyledAssetPlayerProps extends withClasses<'loadingFailImage' | 'iframe'> { +interface NFTLuckyDropStyledAssetPlayerProps + extends withClasses<'loadingFailImage' | 'iframe' | 'wrapper' | 'loadingPlaceholder'> { chainId: ChainId contractAddress: string tokenId: string - fallbackImage: URL + fallbackImage?: URL } export function NFTCardStyledAssetPlayer(props: NFTLuckyDropStyledAssetPlayerProps) { const { chainId, contractAddress, tokenId, fallbackImage } = props @@ -41,7 +42,7 @@ export function NFTCardStyledAssetPlayer(props: NFTLuckyDropStyledAssetPlayerPro contractAddress, tokenId: tokenId, }} - fallbackImage={fallbackImage} + fallbackImage={fallbackImage ?? new URL('./nft_token_fallback.png', import.meta.url)} classes={{ iframe: classNames(classes.wrapper, classes.iframe), errorPlaceholder: classes.wrapper, diff --git a/packages/shared/src/UI/components/NFTCardStyledAssetPlayer/nft_token_fallback.png b/packages/shared/src/UI/components/NFTCardStyledAssetPlayer/nft_token_fallback.png new file mode 100644 index 0000000000000000000000000000000000000000..80895f895a33fa6e26c5db8dcac3afca7e822473 GIT binary patch literal 3686 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 Date: Thu, 6 Jan 2022 18:56:49 +0800 Subject: [PATCH 06/28] chore: query name from media viewer --- .../Wallets/components/Transfer/NFTCard.tsx | 10 +- .../plugins/RedPacket/SNSAdaptor/NftList.tsx | 17 ++-- .../SNSAdaptor/RedPacketERC721Form.tsx | 57 ++++++++---- .../SNSAdaptor/RedpacketNftConfirmDialog.tsx | 48 ++++++---- .../SNSAdaptor/SelectNftTokenDialog.tsx | 92 +++++++++++-------- .../src/UI/components/AssetPlayer/index.tsx | 20 ++-- .../NFTCardStyledAssetPlayer/index.tsx | 4 +- packages/shared/src/constants.tsx | 2 +- .../hooks/useERC721TokenDetailedOwnerList.ts | 17 +--- 9 files changed, 157 insertions(+), 110 deletions(-) diff --git a/packages/dashboard/src/pages/Wallets/components/Transfer/NFTCard.tsx b/packages/dashboard/src/pages/Wallets/components/Transfer/NFTCard.tsx index 2efd842ece74..c6672559f3b4 100644 --- a/packages/dashboard/src/pages/Wallets/components/Transfer/NFTCard.tsx +++ b/packages/dashboard/src/pages/Wallets/components/Transfer/NFTCard.tsx @@ -68,7 +68,7 @@ export interface NFTCardProps { export const NFTCard = memo(({ token, selectedTokenId, onSelect }) => { const { classes } = useStyles() const [checked, setChecked] = useState(!!selectedTokenId && selectedTokenId === token.tokenId) - + const [name, setName] = useState(token.tokenId) const isDisabled = useMemo( () => !!selectedTokenId && selectedTokenId !== token.tokenId, [selectedTokenId, token.tokenId], @@ -85,16 +85,17 @@ export const NFTCard = memo(({ token, selectedTokenId, onSelect }) background: (theme) => (theme.palette.mode === 'dark' ? MaskColorVar.primaryBackground : '#F9F9FA'), }} classes={{ titleWrap: classes.barTitle }} - subtitle={{token.info.name || token.tokenId}} + subtitle={{name}} position="below" /> ) - }, [token.info.name, token.tokenId]) + }, [name]) return ( (theme.palette.mode === 'dark' ? getMaskColor(theme).white : '#F9F9FA'), @@ -104,6 +105,7 @@ export const NFTCard = memo(({ token, selectedTokenId, onSelect }) contractAddress={token.contractDetailed.address} chainId={token.contractDetailed.chainId} tokenId={token.tokenId} + setERC721TokenName={setName} classes={{ loadingFailImage: classes.loadingFailImage, loadingPlaceholder: classes.loadingPlaceholder, diff --git a/packages/mask/src/plugins/RedPacket/SNSAdaptor/NftList.tsx b/packages/mask/src/plugins/RedPacket/SNSAdaptor/NftList.tsx index 59e1bc9bc710..dcdd71ac6938 100644 --- a/packages/mask/src/plugins/RedPacket/SNSAdaptor/NftList.tsx +++ b/packages/mask/src/plugins/RedPacket/SNSAdaptor/NftList.tsx @@ -1,8 +1,8 @@ import { makeStyles, MaskColorVar } from '@masknet/theme' -import { ERC721ContractDetailed, useERC721TokenDetailed } from '@masknet/web3-shared-evm' +import type { ERC721ContractDetailed } from '@masknet/web3-shared-evm' import { List, ListItem, ListProps, Skeleton, Typography } from '@mui/material' import classnames from 'classnames' -import type { FC, HTMLProps } from 'react' +import { FC, HTMLProps, useState } from 'react' import { useI18N } from '../../../utils' import { NFTCardStyledAssetPlayer } from '@masknet/shared' @@ -96,9 +96,9 @@ interface NftItemProps extends HTMLProps { export const NftItem: FC = ({ contract, tokenId, className, claimed, ...rest }) => { const { t } = useI18N() - const result = useERC721TokenDetailed(contract, tokenId) const { classes } = useStyles() - if (!result.tokenDetailed || !contract) { + const [name, setName] = useState('#' + tokenId) + if (!contract) { return (
@@ -112,11 +112,12 @@ export const NftItem: FC = ({ contract, tokenId, className, claime classes={{ loadingFailImage: classes.loadingFailImage, }} - tokenId={result.tokenDetailed.tokenId} - contractAddress={result.tokenDetailed.contractDetailed.address} - chainId={result.tokenDetailed.contractDetailed.chainId} + tokenId={tokenId} + contractAddress={contract.address} + chainId={contract.chainId} + setERC721TokenName={setName} /> - {result.tokenDetailed.info.name} + {name} {claimed && {t('plugin_red_packet_claimed')}}
) diff --git a/packages/mask/src/plugins/RedPacket/SNSAdaptor/RedPacketERC721Form.tsx b/packages/mask/src/plugins/RedPacket/SNSAdaptor/RedPacketERC721Form.tsx index ac837aacaa20..90d8f2f5a7f3 100644 --- a/packages/mask/src/plugins/RedPacket/SNSAdaptor/RedPacketERC721Form.tsx +++ b/packages/mask/src/plugins/RedPacket/SNSAdaptor/RedPacketERC721Form.tsx @@ -311,26 +311,9 @@ export function RedPacketERC721Form(props: RedPacketERC721FormProps) {
{existTokenDetailedList.map((value, i) => ( - - -
- - {value.info.name} - -
-
removeToken(value)}> -
- -
-
-
+
+ +
))} setOpen(true)} @@ -389,3 +372,37 @@ export function RedPacketERC721Form(props: RedPacketERC721FormProps) { ) } + +interface NFTCardProps { + token: OrderedERC721Token + removeToken: (token: ERC721TokenDetailed) => void +} + +function NFTCard(props: NFTCardProps) { + const { token, removeToken } = props + const { classes } = useStyles() + const [name, setName] = useState('#' + token.tokenId) + return ( + + +
+ + {name} + +
+
removeToken(token)}> +
+ +
+
+
+ ) +} diff --git a/packages/mask/src/plugins/RedPacket/SNSAdaptor/RedpacketNftConfirmDialog.tsx b/packages/mask/src/plugins/RedPacket/SNSAdaptor/RedpacketNftConfirmDialog.tsx index 5313e135004c..1147e43da1ad 100644 --- a/packages/mask/src/plugins/RedPacket/SNSAdaptor/RedpacketNftConfirmDialog.tsx +++ b/packages/mask/src/plugins/RedPacket/SNSAdaptor/RedpacketNftConfirmDialog.tsx @@ -287,22 +287,9 @@ export function RedpacketNftConfirmDialog(props: RedpacketNftConfirmDialogProps) {tokenList.map((value, i) => ( - - - -
- - {value.info.name} - -
-
+
+ +
))}
@@ -358,3 +345,32 @@ export function RedpacketNftConfirmDialog(props: RedpacketNftConfirmDialogProps) ) } + +interface NFTCardProps { + token: ERC721TokenDetailed +} + +function NFTCard(props: NFTCardProps) { + const { token } = props + const { classes } = useStyles() + const [name, setName] = useState('#' + token.tokenId) + return ( + + + +
+ + {name} + +
+
+ ) +} diff --git a/packages/mask/src/plugins/RedPacket/SNSAdaptor/SelectNftTokenDialog.tsx b/packages/mask/src/plugins/RedPacket/SNSAdaptor/SelectNftTokenDialog.tsx index c8e3eb866315..f189760a016e 100644 --- a/packages/mask/src/plugins/RedPacket/SNSAdaptor/SelectNftTokenDialog.tsx +++ b/packages/mask/src/plugins/RedPacket/SNSAdaptor/SelectNftTokenDialog.tsx @@ -149,7 +149,7 @@ const useStyles = makeStyles()((theme, props) => ({ overflow: 'hidden', padding: 0, flexDirection: 'column', - borderRadius: 6, + borderRadius: 8, height: 180, userSelect: 'none', width: 120, @@ -633,42 +633,15 @@ export function SelectNftTokenDialog(props: SelectNftTokenDialogProps) { ) return ( - 0 && - !tokenIdFilterList.includes(token.tokenId) - ? classes.hide - : '', - )} - key={i.toString()}> - + -
- - {token?.info.name} - -
- -
- selectToken(token, findToken, event.shiftKey, token.index) - }> - {findToken ? : null} -
-
+
) })} {loadingOwnerList ? ( @@ -741,3 +714,50 @@ export function SelectNftTokenDialog(props: SelectNftTokenDialogProps) { ) } + +interface NFTCardProps { + findToken: OrderedERC721Token | undefined + token: OrderedERC721Token + tokenIdFilterList: string[] + isSelectSharesExceed: boolean + selectToken: ( + token: OrderedERC721Token, + findToken: OrderedERC721Token | undefined, + shiftKey: boolean, + index: number, + ) => void +} + +function NFTCard(props: NFTCardProps) { + const { findToken, token, tokenIdFilterList, isSelectSharesExceed, selectToken } = props + const { classes } = useStyles({ isSelectSharesExceed }) + const [name, setName] = useState('#' + token.tokenId) + return ( + 0 && !tokenIdFilterList.includes(token.tokenId) ? classes.hide : '', + )}> + +
+ + {name} + +
+ +
selectToken(token, findToken, event.shiftKey, token.index)}> + {findToken ? : null} +
+
+ ) +} diff --git a/packages/shared/src/UI/components/AssetPlayer/index.tsx b/packages/shared/src/UI/components/AssetPlayer/index.tsx index ddd6a4a88d30..e3393688beaf 100644 --- a/packages/shared/src/UI/components/AssetPlayer/index.tsx +++ b/packages/shared/src/UI/components/AssetPlayer/index.tsx @@ -32,7 +32,12 @@ interface AssetPlayerProps fallbackImage?: URL setERC721TokenName?: (name: string) => void } -const useStyles = makeStyles()({}) +const useStyles = makeStyles()({ + hidden: { + position: 'absolute', + visibility: 'hidden', + }, +}) enum AssetPlayerState { LOADING = 0, @@ -41,7 +46,7 @@ enum AssetPlayerState { ERROR = 3, } -const TIMEOUT = 10000 +const TIMEOUT = 30000 export const AssetPlayer = memo(({ url, type, options, iconProps, ...props }) => { const ref = useRef(null) @@ -82,15 +87,14 @@ export const AssetPlayer = memo(({ url, type, options, iconPro }, [url, JSON.stringify(erc721Token), type, JSON.stringify(options), playerState]) //endregion - type ERC721TokenNameMsg = { type: 'name'; name: string } + type ERC721TokenNameMsg = { message: { type: 'name'; name: string } } //#region resource loaded error const onMessage = useCallback(({ message }: { message: { name: string } | ERC721TokenNameMsg }) => { - if (message?.name === 'Error') { + if ((message as { name: string })?.name === 'Error') { setPlayerState(AssetPlayerState.ERROR) } - - if ((message as ERC721TokenNameMsg).type === 'name') { - props.setERC721TokenName?.((message as ERC721TokenNameMsg).name) + if ((message as ERC721TokenNameMsg).message?.type === 'name') { + props.setERC721TokenName?.((message as ERC721TokenNameMsg).message.name) } }, []) //#endregion @@ -123,7 +127,7 @@ export const AssetPlayer = memo(({ url, type, options, iconPro setPlayerState(AssetPlayerState.INIT) setIframe() }} - className={playerState !== AssetPlayerState.NORMAL ? '' : classes.iframe} + className={playerState !== AssetPlayerState.NORMAL ? classes.hidden : classes.iframe} onResized={({ type }) => { if (type === 'init' || playerState === AssetPlayerState.NORMAL) return cancel() diff --git a/packages/shared/src/UI/components/NFTCardStyledAssetPlayer/index.tsx b/packages/shared/src/UI/components/NFTCardStyledAssetPlayer/index.tsx index 721036ddc0ad..c13d4b7526a2 100644 --- a/packages/shared/src/UI/components/NFTCardStyledAssetPlayer/index.tsx +++ b/packages/shared/src/UI/components/NFTCardStyledAssetPlayer/index.tsx @@ -31,9 +31,10 @@ interface NFTLuckyDropStyledAssetPlayerProps contractAddress: string tokenId: string fallbackImage?: URL + setERC721TokenName?: (name: string) => void } export function NFTCardStyledAssetPlayer(props: NFTLuckyDropStyledAssetPlayerProps) { - const { chainId, contractAddress, tokenId, fallbackImage } = props + const { chainId, contractAddress, tokenId, fallbackImage, setERC721TokenName } = props const classes = useStylesExtends(useStyles(), props) return ( = { 'instagram.com': , } -export const mediaViewerUrl = 'https://192.168.3.101:8081/index.html' +export const mediaViewerUrl = 'https://dimensiondev.github.io/Media-Viewer/index.html' diff --git a/packages/web3-shared/evm/hooks/useERC721TokenDetailedOwnerList.ts b/packages/web3-shared/evm/hooks/useERC721TokenDetailedOwnerList.ts index 5139159ada39..3652c5c17e97 100644 --- a/packages/web3-shared/evm/hooks/useERC721TokenDetailedOwnerList.ts +++ b/packages/web3-shared/evm/hooks/useERC721TokenDetailedOwnerList.ts @@ -5,7 +5,7 @@ import { useOpenseaAPIConstants } from '../constants' import type { ERC721 } from '@masknet/web3-contracts/types/ERC721' import { safeNonPayableTransactionCall } from '../utils' import type { ERC721ContractDetailed, ERC721TokenDetailed } from '../types' -import { getERC721TokenDetailedFromChain, getERC721TokenAssetFromChain } from './useERC721TokenDetailed' +import { getERC721TokenDetailedFromChain } from './useERC721TokenDetailed' import { useEffect, useRef, useState } from 'react' import { uniqBy } from 'lodash-unified' import { useChainId } from './useChainId' @@ -39,21 +39,6 @@ export function useERC721TokenDetailedOwnerList(contractDetailed: ERC721Contract allListRef.current = uniqBy([...allListRef.current, ...lists], 'tokenId') setRefreshing(false) - - // lazy load token info after set loading status to false - const allRequest = allListRef.current.map(async (nft) => { - // there's no tokenURI or info already loaded. - if (!nft.info.tokenURI || nft.info.hasTokenDetailed) return nft - const info = await getERC721TokenAssetFromChain(nft.info.tokenURI) - if (info) nft.info = { ...info, ...nft.info, hasTokenDetailed: true, name: info.name ?? nft.info.name } - return nft - }) - - allListRef.current = (await Promise.allSettled(allRequest)).map((x, i) => { - if (x.status === 'fulfilled') return x.value - allListRef.current[i].info.hasTokenDetailed = true - return allListRef.current[i] - }) }, [GET_ASSETS_URL, contractDetailed, owner, chainId]) const clearTokenDetailedOwnerList = () => (allListRef.current = []) From 519b3d2b1dc19c0a151b7180d4d51331f73755ed Mon Sep 17 00:00:00 2001 From: zhouhanseng Date: Thu, 6 Jan 2022 19:14:21 +0800 Subject: [PATCH 07/28] chore: accept url --- .../src/plugins/RedPacket/SNSAdaptor/SelectNftTokenDialog.tsx | 3 ++- .../src/UI/components/NFTCardStyledAssetPlayer/index.tsx | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/mask/src/plugins/RedPacket/SNSAdaptor/SelectNftTokenDialog.tsx b/packages/mask/src/plugins/RedPacket/SNSAdaptor/SelectNftTokenDialog.tsx index f189760a016e..8436980dfcfc 100644 --- a/packages/mask/src/plugins/RedPacket/SNSAdaptor/SelectNftTokenDialog.tsx +++ b/packages/mask/src/plugins/RedPacket/SNSAdaptor/SelectNftTokenDialog.tsx @@ -497,6 +497,7 @@ export function SelectNftTokenDialog(props: SelectNftTokenDialogProps) {
- {tokenDetailed?.info.name} + {tokenDetailed.info.name}
diff --git a/packages/shared/src/UI/components/NFTCardStyledAssetPlayer/index.tsx b/packages/shared/src/UI/components/NFTCardStyledAssetPlayer/index.tsx index c13d4b7526a2..4f60b28e1432 100644 --- a/packages/shared/src/UI/components/NFTCardStyledAssetPlayer/index.tsx +++ b/packages/shared/src/UI/components/NFTCardStyledAssetPlayer/index.tsx @@ -30,11 +30,12 @@ interface NFTLuckyDropStyledAssetPlayerProps chainId: ChainId contractAddress: string tokenId: string + url?: string fallbackImage?: URL setERC721TokenName?: (name: string) => void } export function NFTCardStyledAssetPlayer(props: NFTLuckyDropStyledAssetPlayerProps) { - const { chainId, contractAddress, tokenId, fallbackImage, setERC721TokenName } = props + const { chainId, contractAddress, tokenId, fallbackImage, url, setERC721TokenName } = props const classes = useStylesExtends(useStyles(), props) return ( Date: Fri, 7 Jan 2022 13:09:33 +0800 Subject: [PATCH 08/28] chore: ui style --- .../plugins/RedPacket/SNSAdaptor/RedPacketERC721Form.tsx | 7 ++++--- .../RedPacket/SNSAdaptor/RedpacketNftConfirmDialog.tsx | 2 +- .../plugins/RedPacket/SNSAdaptor/SelectNftTokenDialog.tsx | 2 +- packages/shared/src/UI/components/AssetPlayer/index.tsx | 3 ++- .../src/UI/components/NFTCardStyledAssetPlayer/index.tsx | 2 ++ 5 files changed, 10 insertions(+), 6 deletions(-) diff --git a/packages/mask/src/plugins/RedPacket/SNSAdaptor/RedPacketERC721Form.tsx b/packages/mask/src/plugins/RedPacket/SNSAdaptor/RedPacketERC721Form.tsx index 90d8f2f5a7f3..b6e258f97fa9 100644 --- a/packages/mask/src/plugins/RedPacket/SNSAdaptor/RedPacketERC721Form.tsx +++ b/packages/mask/src/plugins/RedPacket/SNSAdaptor/RedPacketERC721Form.tsx @@ -38,7 +38,7 @@ const useStyles = makeStyles()((theme) => { }, nftNameWrapper: { width: '100%', - background: theme.palette.background.default, + background: theme.palette.background.paper, borderBottomRightRadius: 8, borderBottomLeftRadius: 8, paddingTop: 2, @@ -81,10 +81,10 @@ const useStyles = makeStyles()((theme) => { position: 'relative', display: 'flex', flexDirection: 'column', - borderRadius: 6, + borderRadius: 8, padding: 0, marginBottom: theme.spacing(2.5), - background: theme.palette.background.default, + background: theme.palette.mode === 'light' ? '#fff' : '#2F3336', width: 120, height: 180, overflow: 'hidden', @@ -99,6 +99,7 @@ const useStyles = makeStyles()((theme) => { addWrapper: { cursor: 'pointer', alignItems: 'center', + background: theme.palette.background.default, justifyContent: 'center', }, addIcon: { diff --git a/packages/mask/src/plugins/RedPacket/SNSAdaptor/RedpacketNftConfirmDialog.tsx b/packages/mask/src/plugins/RedPacket/SNSAdaptor/RedpacketNftConfirmDialog.tsx index 1147e43da1ad..1b2bf578a650 100644 --- a/packages/mask/src/plugins/RedPacket/SNSAdaptor/RedpacketNftConfirmDialog.tsx +++ b/packages/mask/src/plugins/RedPacket/SNSAdaptor/RedpacketNftConfirmDialog.tsx @@ -92,7 +92,7 @@ const useStyles = makeStyles()((theme) => ({ }, nftNameWrapper: { width: '100%', - background: theme.palette.mode === 'light' ? 'none' : '#2F3336', + background: theme.palette.background.paper, borderBottomRightRadius: 8, borderBottomLeftRadius: 8, paddingTop: 2, diff --git a/packages/mask/src/plugins/RedPacket/SNSAdaptor/SelectNftTokenDialog.tsx b/packages/mask/src/plugins/RedPacket/SNSAdaptor/SelectNftTokenDialog.tsx index 8436980dfcfc..b16386b95d5a 100644 --- a/packages/mask/src/plugins/RedPacket/SNSAdaptor/SelectNftTokenDialog.tsx +++ b/packages/mask/src/plugins/RedPacket/SNSAdaptor/SelectNftTokenDialog.tsx @@ -165,7 +165,7 @@ const useStyles = makeStyles()((theme, props) => ({ }, selectWrapperNftNameWrapper: { width: '100%', - background: theme.palette.background.default, + background: theme.palette.background.paper, borderBottomRightRadius: 8, borderBottomLeftRadius: 8, overflow: 'hidden', diff --git a/packages/shared/src/UI/components/AssetPlayer/index.tsx b/packages/shared/src/UI/components/AssetPlayer/index.tsx index e3393688beaf..99ca1c6adc38 100644 --- a/packages/shared/src/UI/components/AssetPlayer/index.tsx +++ b/packages/shared/src/UI/components/AssetPlayer/index.tsx @@ -27,6 +27,7 @@ interface AssetPlayerProps loop?: boolean muted?: boolean } + loadingIcon?: React.ReactNode erc721Token?: ERC721TokenQuery iconProps?: SvgIconProps fallbackImage?: URL @@ -117,7 +118,7 @@ export const AssetPlayer = memo(({ url, type, options, iconPro ) ) : ( - + props.loadingIcon ?? )} } classes={{ iframe: classNames(classes.wrapper, classes.iframe), errorPlaceholder: classes.wrapper, From 35b955928373f3ef6b49fd2e8e7a84c9a68ae609 Mon Sep 17 00:00:00 2001 From: zhouhanseng Date: Fri, 7 Jan 2022 13:11:43 +0800 Subject: [PATCH 09/28] chore: remove unused resource --- .../SNSAdaptor/assets/nft_token_fallback.png | Bin 3686 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 packages/mask/src/plugins/RedPacket/SNSAdaptor/assets/nft_token_fallback.png diff --git a/packages/mask/src/plugins/RedPacket/SNSAdaptor/assets/nft_token_fallback.png b/packages/mask/src/plugins/RedPacket/SNSAdaptor/assets/nft_token_fallback.png deleted file mode 100644 index 80895f895a33fa6e26c5db8dcac3afca7e822473..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3686 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 Date: Fri, 7 Jan 2022 13:42:30 +0800 Subject: [PATCH 10/28] chore: update dashboard assets --- .../components/CollectibleCard/index.tsx | 30 +++++++++++++++---- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/packages/dashboard/src/pages/Wallets/components/CollectibleCard/index.tsx b/packages/dashboard/src/pages/Wallets/components/CollectibleCard/index.tsx index d93330ba10b8..2e69897cebc0 100644 --- a/packages/dashboard/src/pages/Wallets/components/CollectibleCard/index.tsx +++ b/packages/dashboard/src/pages/Wallets/components/CollectibleCard/index.tsx @@ -1,6 +1,7 @@ import { memo, useEffect, useMemo, useRef, useState } from 'react' import { Box, Button, Link, Tooltip, Typography } from '@mui/material' import { makeStyles, MaskColorVar } from '@masknet/theme' +import { NFTCardStyledAssetPlayer } from '@masknet/shared' import { CollectiblePlaceholder } from '../CollectiblePlaceHolder' import { useHoverDirty } from 'react-use' import { useDashboardI18N } from '../../../../locales' @@ -29,7 +30,7 @@ const useStyles = makeStyles()((theme) => ({ flexDirection: 'column', overflow: 'hidden', }, - imgContainer: { + mediaContainer: { width: '100%', height: 186, backgroundColor: theme.palette.mode === 'dark' ? MaskColorVar.lineLight : '#f6f6f7', @@ -50,6 +51,7 @@ const useStyles = makeStyles()((theme) => ({ top: 8, height: 20, width: 20, + zIndex: 20, }, tip: { padding: theme.spacing(1), @@ -58,6 +60,18 @@ const useStyles = makeStyles()((theme) => ({ tipArrow: { color: '#111432', }, + loadingFailImage: { + minHeight: '0px !important', + maxWidth: 'none', + transform: 'translateY(10px)', + width: 64, + height: 64, + }, + wrapper: { + width: '100%', + height: '100%', + maxHeight: 186, + }, })) export interface CollectibleCardProps { @@ -97,10 +111,16 @@ export const CollectibleCard = memo(({ chainId, token, onS token.tokenId, ) ?? '#' }> -
- +
From 357c81d77e62455903b7cff3429310fdfc702581 Mon Sep 17 00:00:00 2001 From: zhouhanseng Date: Fri, 7 Jan 2022 14:22:16 +0800 Subject: [PATCH 11/28] chore: update maskbox and nft wall --- .../CollectibleList/CollectibleCard.tsx | 95 +++++++------------ 1 file changed, 35 insertions(+), 60 deletions(-) diff --git a/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/CollectibleCard.tsx b/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/CollectibleCard.tsx index fce271edfd8b..5631696326e2 100644 --- a/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/CollectibleCard.tsx +++ b/packages/mask/src/extension/options-page/DashboardComponents/CollectibleList/CollectibleCard.tsx @@ -1,11 +1,9 @@ -import { useAsyncRetry } from 'react-use' -import { Card, CircularProgress, Link } from '@mui/material' +import { Card, Link } from '@mui/material' import { makeStyles } from '@masknet/theme' import { Wallet, ERC721TokenDetailed, resolveCollectibleLink, NonFungibleAssetProvider } from '@masknet/web3-shared-evm' import { MaskSharpIconOfSize } from '../../../../resources/MaskIcon' +import { NFTCardStyledAssetPlayer } from '@masknet/shared' import { ActionsBarNFT } from '../ActionsBarNFT' -import { Video } from '../../../../components/shared/Video' -import { Image } from '../../../../components/shared/Image' const useStyles = makeStyles()((theme) => ({ root: { @@ -31,9 +29,15 @@ const useStyles = makeStyles()((theme) => ({ height: 64, opacity: 0.1, }, - video: { - width: 172, - height: 172, + loadingFailImage: { + minHeight: '0px !important', + maxWidth: 'none', + width: 64, + height: 64, + }, + wrapper: { + width: '172px !important', + height: '172px !important', }, })) @@ -44,63 +48,34 @@ export interface CollectibleCardProps { readonly?: boolean } -const videoTypeRe = /\.(mp4|mp3|m4v|ogg)$/i - export function CollectibleCard(props: CollectibleCardProps) { const { wallet, token, provider, readonly } = props const { classes } = useStyles() - const mediaUrl = token.info.mediaUrl - const { loading, value } = useAsyncRetry(async () => { - if (!mediaUrl) return - - const blob = await (await fetch(mediaUrl)).blob() - return blob - }, [mediaUrl]) - - const mimeType = value?.type || '' - // some video resources response content-type not video, e.g. application/octet-stream - const isVideo = mediaUrl ? videoTypeRe.test(mediaUrl) || mimeType.startsWith('video') : undefined - const isHtml = mimeType.startsWith('text') - return ( - <> - {loading ? ( - - - - ) : ( - - - {readonly || !wallet ? null : ( - - )} - {token.info.mediaUrl ? ( - isVideo ? ( -