From 7901f676a8e452ee336d223d56a20e7cf5baeae6 Mon Sep 17 00:00:00 2001 From: lw Date: Thu, 6 Jun 2024 10:45:20 +0700 Subject: [PATCH 1/2] [Issue-102] Update import NFT feature for evm chains --- .../extension-base/src/koni/api/nft/config.ts | 59 ++++++++++--------- .../Popup/Home/Nfts/NftCollectionDetail.tsx | 28 +++++---- .../src/Popup/Home/Nfts/NftCollections.tsx | 51 +++++++++++++--- .../src/Popup/Home/Nfts/NftImport.tsx | 12 ++-- .../src/Popup/Home/Nfts/NftItemDetail.tsx | 28 +++++---- .../extension-koni-ui/src/Popup/router.tsx | 6 +- 6 files changed, 116 insertions(+), 68 deletions(-) diff --git a/packages/extension-base/src/koni/api/nft/config.ts b/packages/extension-base/src/koni/api/nft/config.ts index 2056c62246b..27861fa7e61 100644 --- a/packages/extension-base/src/koni/api/nft/config.ts +++ b/packages/extension-base/src/koni/api/nft/config.ts @@ -141,42 +141,47 @@ if (isFirefox) { }); } -if (!RuntimeInfo?.protocol || - (!RuntimeInfo?.protocol.startsWith('http') || RuntimeInfo?.protocol.startsWith('https'))) { +if (RuntimeInfo.protocol && RuntimeInfo.protocol.startsWith('http')) { + // This is for https + if (RuntimeInfo.protocol.startsWith('https')) { + RANDOM_IPFS_GATEWAY_SETTING.push({ + provider: IPFS_FLEEK, + weight: 4 + }, + { + provider: IPFS_GATEWAY_4EVERLAND, + weight: 2 + }, + { + provider: IPFS_W3S_LINK, + weight: 1 + }, + { + provider: CF_IPFS_GATEWAY, + weight: 4 + }, + { + provider: PINATA_IPFS_GATEWAY, + weight: 1 // Rate limit too low + }, + { + provider: IPFS_IO, + weight: 5 + } + ); + } +} else { + // This is for extension env or other RANDOM_IPFS_GATEWAY_SETTING.push({ - provider: IPFS_FLEEK, - weight: 4 - }, - { - provider: IPFS_GATEWAY_4EVERLAND, - weight: 2 - }, - { - provider: IPFS_W3S_LINK, - weight: 1 - }, - { - provider: CF_IPFS_GATEWAY, - weight: 4 - }, - { - provider: PINATA_IPFS_GATEWAY, - weight: 1 // Rate limit too low - }, - { provider: NFT_STORAGE_GATEWAY, weight: 50 }, - { - provider: GATEWAY_IPFS_IO, - weight: 5 - }, { provider: DWEB_LINK, weight: 5 }, { - provider: IPFS_IO, + provider: GATEWAY_IPFS_IO, weight: 5 } ); diff --git a/packages/extension-koni-ui/src/Popup/Home/Nfts/NftCollectionDetail.tsx b/packages/extension-koni-ui/src/Popup/Home/Nfts/NftCollectionDetail.tsx index b6f7bc550b0..d2efdefc72b 100644 --- a/packages/extension-koni-ui/src/Popup/Home/Nfts/NftCollectionDetail.tsx +++ b/packages/extension-koni-ui/src/Popup/Home/Nfts/NftCollectionDetail.tsx @@ -48,18 +48,22 @@ function Component ({ className = '' }: Props): React.ReactElement { const routingParams = { collectionInfo, nftItem } as INftItemDetail; if (nftItem.description) { - const ordinalNftItem = JSON.parse(nftItem.description) as OrdinalRemarkData; - - if ('p' in ordinalNftItem && 'op' in ordinalNftItem && 'tick' in ordinalNftItem && 'amt' in ordinalNftItem) { - return ( - - ); + try { + const ordinalNftItem = JSON.parse(nftItem.description) as OrdinalRemarkData; + + if ('p' in ordinalNftItem && 'op' in ordinalNftItem && 'tick' in ordinalNftItem && 'amt' in ordinalNftItem) { + return ( + + ); + } + } catch (e) { + } } diff --git a/packages/extension-koni-ui/src/Popup/Home/Nfts/NftCollections.tsx b/packages/extension-koni-ui/src/Popup/Home/Nfts/NftCollections.tsx index 344d67642e3..0bcfec8102a 100644 --- a/packages/extension-koni-ui/src/Popup/Home/Nfts/NftCollections.tsx +++ b/packages/extension-koni-ui/src/Popup/Home/Nfts/NftCollections.tsx @@ -11,18 +11,28 @@ import { INftCollectionDetail } from '@subwallet/extension-koni-ui/Popup/Home/Nf import { ThemeProps } from '@subwallet/extension-koni-ui/types'; import { ActivityIndicator, ButtonProps, Icon, SwList } from '@subwallet/react-ui'; import CN from 'classnames'; -import { ArrowClockwise, Image } from 'phosphor-react'; -import React, { useCallback, useContext } from 'react'; +import { ArrowClockwise, Image, Plus, PlusCircle } from 'phosphor-react'; +import React, { useCallback, useContext, useMemo } from 'react'; import { useNavigate } from 'react-router-dom'; import styled from 'styled-components'; type Props = ThemeProps -const reloadIcon = ; +const reloadIcon = ( + +); + +const rightIcon = ( + +); function Component ({ className = '' }: Props): React.ReactElement { useSetCurrentPage('/home/nfts/collections'); @@ -55,6 +65,12 @@ function Component ({ className = '' }: Props): React.ReactElement { }) .catch(console.error); } + }, + { + icon: rightIcon, + onClick: () => { + navigate('/settings/tokens/import-nft', { state: { isExternalRequest: false } }); + } } ]; @@ -110,15 +126,33 @@ function Component ({ className = '' }: Props): React.ReactElement { ); }, [getNftsByCollection, handleOnClickCollection]); + const emptyButtonProps = useMemo((): ButtonProps => { + return { + icon: ( + + ), + children: t('Add collectible'), + shape: 'circle', + size: 'xs', + onClick: () => { + navigate('/settings/tokens/import-nft', { state: { isExternalRequest: false } }); + } + }; + }, [navigate, t]); + const emptyNft = useCallback(() => { return ( ); - }, [t]); + }, [emptyButtonProps, t]); return ( { displayGrid={true} enableSearchInput={true} gridGap={'14px'} + key={nftCollections.length} // fix render issue of flat-list list={nftCollections} minColumnWidth={'160px'} renderItem={renderNftCollection} diff --git a/packages/extension-koni-ui/src/Popup/Home/Nfts/NftImport.tsx b/packages/extension-koni-ui/src/Popup/Home/Nfts/NftImport.tsx index 3d97e878aed..de7c4515597 100644 --- a/packages/extension-koni-ui/src/Popup/Home/Nfts/NftImport.tsx +++ b/packages/extension-koni-ui/src/Popup/Home/Nfts/NftImport.tsx @@ -143,7 +143,7 @@ function Component ({ className = '' }: Props): React.ReactElement { .then((result) => { if (result) { showNotification({ - message: t('Imported NFT successfully') + message: t('Imported collectible successfully') }); goBack(); } else { @@ -195,7 +195,7 @@ function Component ({ className = '' }: Props): React.ReactElement { setLoading(false); if (validationResult.isExist) { - reject(t('Existed NFT')); + reject(t('Existed collectible')); } if (validationResult.contractError) { @@ -242,7 +242,7 @@ function Component ({ className = '' }: Props): React.ReactElement { onClick: form.submit, children: t('Import') }} - title={t('Import NFT')} + title={t('Import collectible')} >
{ disabled={!selectedChain} items={nftTypeOptions} label={t('Type')} - placeholder={t('Select NFT type')} - title={t('Select NFT type')} + placeholder={t('Select collectible type')} + title={t('Select collectible type')} /> @@ -304,7 +304,7 @@ function Component ({ className = '' }: Props): React.ReactElement { > ('NFT collection name')} + label={t('Collection name')} /> diff --git a/packages/extension-koni-ui/src/Popup/Home/Nfts/NftItemDetail.tsx b/packages/extension-koni-ui/src/Popup/Home/Nfts/NftItemDetail.tsx index bd9f5557b71..010641cd08f 100644 --- a/packages/extension-koni-ui/src/Popup/Home/Nfts/NftItemDetail.tsx +++ b/packages/extension-koni-ui/src/Popup/Home/Nfts/NftItemDetail.tsx @@ -28,12 +28,14 @@ type Props = ThemeProps const NFT_DESCRIPTION_MAX_LENGTH = 70; -const modalCloseButton = ; +const modalCloseButton = ( + +); function Component ({ className = '' }: Props): React.ReactElement { const location = useLocation(); @@ -137,14 +139,16 @@ function Component ({ className = '' }: Props): React.ReactElement { }, [nftItem.externalUrl]); const show3DModel = SHOW_3D_MODELS_CHAIN.includes(nftItem.chain); - const ordinalNftItem = nftItem.description && JSON.parse(nftItem.description) as OrdinalRemarkData; + const isInscription = useMemo(() => { - if (ordinalNftItem && 'p' in ordinalNftItem && 'op' in ordinalNftItem && 'tick' in ordinalNftItem && 'amt' in ordinalNftItem) { - return true; - } + try { + const ordinalNftItem = nftItem.description && JSON.parse(nftItem.description) as OrdinalRemarkData; - return false; - }, [ordinalNftItem]); + return !!(ordinalNftItem && 'p' in ordinalNftItem && 'op' in ordinalNftItem && 'tick' in ordinalNftItem && 'amt' in ordinalNftItem); + } catch (e) { + return false; + } + }, [nftItem.description]); return ( import('@subwall const NftItemDetail = new LazyLoader('NftItemDetail', () => import('@subwallet/extension-koni-ui/Popup/Home/Nfts/NftItemDetail')); const NftCollections = new LazyLoader('NftCollections', () => import('@subwallet/extension-koni-ui/Popup/Home/Nfts/NftCollections')); const NftCollectionDetail = new LazyLoader('NftCollectionDetail', () => import('@subwallet/extension-koni-ui/Popup/Home/Nfts/NftCollectionDetail')); -// const NftImport = new LazyLoader('NftImport', () => import('@subwallet/extension-koni-ui/Popup/Home/Nfts/NftImport')); +const NftImport = new LazyLoader('NftImport', () => import('@subwallet/extension-koni-ui/Popup/Home/Nfts/NftImport')); const History = new LazyLoader('History', () => import('@subwallet/extension-koni-ui/Popup/Home/History')); const Home = new LazyLoader('Home', () => import('@subwallet/extension-koni-ui/Popup/Home')); @@ -229,8 +229,8 @@ export const router = createHashRouter([ children: [ ManageTokens.generateRouterObject('manage'), FungibleTokenImport.generateRouterObject('import-token'), - TokenDetail.generateRouterObject('detail') - // NftImport.generateRouterObject('import-nft') + TokenDetail.generateRouterObject('detail'), + NftImport.generateRouterObject('import-nft') ] } ] From 46e4b0875dab1f1877e59bed31f30351f13a3f54 Mon Sep 17 00:00:00 2001 From: lw Date: Fri, 7 Jun 2024 15:02:41 +0700 Subject: [PATCH 2/2] [Collectible] Update fallback image for Collectible detail screen --- .../src/Popup/Home/Nfts/NftItemDetail.tsx | 1 + patches/@subwallet+react-ui+5.1.2-b74.patch | 42 +++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/packages/extension-koni-ui/src/Popup/Home/Nfts/NftItemDetail.tsx b/packages/extension-koni-ui/src/Popup/Home/Nfts/NftItemDetail.tsx index 010641cd08f..365c2043e0d 100644 --- a/packages/extension-koni-ui/src/Popup/Home/Nfts/NftItemDetail.tsx +++ b/packages/extension-koni-ui/src/Popup/Home/Nfts/NftItemDetail.tsx @@ -175,6 +175,7 @@ function Component ({ className = '' }: Props): React.ReactElement { {!isInscription && ( extends React.FC

{ + PreviewGroup: typeof PreviewGroup; +diff --git a/node_modules/@subwallet/react-ui/es/image/index.js b/node_modules/@subwallet/react-ui/es/image/index.js +index 2b8275d..25a0579 100644 +--- a/node_modules/@subwallet/react-ui/es/image/index.js ++++ b/node_modules/@subwallet/react-ui/es/image/index.js +@@ -36,9 +36,10 @@ const Image = _a => { + modelViewerProps, + onLoad, + onError, +- src ++ src, ++ fallbackSrc + } = _a, +- otherProps = __rest(_a, ["prefixCls", "preview", "rootClassName", "shape", "width", "height", "responsive", "isLoading", "activityIndicatorSize", "modelViewerProps", "onLoad", "onError", "src"]); ++ otherProps = __rest(_a, ["prefixCls", "preview", "rootClassName", "shape", "width", "height", "responsive", "isLoading", "activityIndicatorSize", "modelViewerProps", "onLoad", "onError", "src", "fallbackSrc"]); + const { + getPrefixCls, + locale: contextLocale = defaultLocale, +@@ -165,10 +166,10 @@ const Image = _a => { + preview: false, + prefixCls: `${prefixCls}`, + rootClassName: mergedRootClassName, +- fallback: FAULT_TOLERANT, ++ fallback: fallbackSrc || FAULT_TOLERANT, + onLoad: handleOnLoad, + onError: handleImageError, +- src: FAULT_TOLERANT ++ src: fallbackSrc || FAULT_TOLERANT + }, otherProps)); + }; + if (shape === 'squircle') { diff --git a/node_modules/@subwallet/react-ui/es/number/index.js b/node_modules/@subwallet/react-ui/es/number/index.js index 895129b..0081551 100644 --- a/node_modules/@subwallet/react-ui/es/number/index.js