Skip to content

Commit

Permalink
Merge pull request #246 from openbitdev/koni/dev/issue-220v1
Browse files Browse the repository at this point in the history
[Issue: 220] Add support for Ordinals with some content type
  • Loading branch information
saltict authored Jul 16, 2024
2 parents 790b592 + 65110ff commit 66c935b
Show file tree
Hide file tree
Showing 6 changed files with 350 additions and 77 deletions.
7 changes: 3 additions & 4 deletions packages/extension-base/src/koni/api/nft/inscription/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,11 @@ export class InscriptionApi extends BaseNftApi {
}

private parseInsUrl (id: string, type: string) {
if (type.startsWith('audio/') || type.startsWith('text/html') || type.startsWith('image/svg') || type.startsWith('model/gltf')) {
if (type.startsWith('image/svg') || type.startsWith('model/gltf') || type.startsWith('image/gif')) {
return this.createIframePreviewUrl(id);
}

if (type.startsWith('video/')) {
if (type.startsWith('video/') || type.startsWith('audio/') || type.startsWith('text/html') || type.startsWith('image/png') || type.startsWith('image/jpeg') || type.startsWith('image/webp') || type.startsWith('image/gif')) {
return `https://ordinals.com/content/${id}`;
}

Expand All @@ -63,8 +63,7 @@ export class InscriptionApi extends BaseNftApi {
}

if (type.startsWith('image/')) {
return `${HIRO_API.list_of_incriptions}/${id}/content`;
// return getPreviewUrl(id);
return `https://ordinals.com/content/${id}`;
}

return undefined;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,11 +120,12 @@ function Component ({ className = '' }: Props): React.ReactElement<Props> {

return (
<NftGalleryWrapper
fallbackImage={collectionInfo.image}
fallbackImage={{ image: collectionInfo.image }}
handleOnClick={handleOnClickNft}
have3dViewer={SHOW_3D_MODELS_CHAIN.includes(nftItem.chain)}
image={nftItem.image}
key={`${nftItem.chain}_${nftItem.collectionId}_${nftItem.id}`}
nftItem={nftItem}
routingParams={routingParams}
title={nftItem.name || nftItem.id}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { DataContext } from '@subwallet/extension-koni-ui/contexts/DataContext';
import { useGetNftByAccount, useNotification, useSetCurrentPage, useTranslation } from '@subwallet/extension-koni-ui/hooks';
import { reloadCron } from '@subwallet/extension-koni-ui/messaging';
import { NftGalleryWrapper } from '@subwallet/extension-koni-ui/Popup/Home/Nfts/component/NftGalleryWrapper';
import { getTotalCollectionItems, INftCollectionDetail } from '@subwallet/extension-koni-ui/Popup/Home/Nfts/utils';
import { ContentType, determineContentType, getContentType, getTotalCollectionItems, INftCollectionDetail } from '@subwallet/extension-koni-ui/Popup/Home/Nfts/utils';
import { RootState } from '@subwallet/extension-koni-ui/stores';
import { ThemeProps } from '@subwallet/extension-koni-ui/types';
import { ActivityIndicator, ButtonProps, Icon, SwList } from '@subwallet/react-ui';
Expand Down Expand Up @@ -90,11 +90,13 @@ function Component ({ className = '' }: Props): React.ReactElement<Props> {
const renderNftCollection = useCallback((nftCollection: NftCollection) => {
const nftList = getNftsByCollection(nftCollection);

let fallbackImage: string | undefined;
let fallbackImage: { image: string; contentType?: ContentType } | undefined;

for (const nft of nftList) { // fallback to any nft image
const contentType = determineContentType(getContentType(nft?.properties));

if (nft.image) {
fallbackImage = nft.image;
fallbackImage = { image: nft.image, contentType: contentType };
break;
}
}
Expand Down
143 changes: 125 additions & 18 deletions packages/extension-koni-ui/src/Popup/Home/Nfts/NftItemDetail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import useDefaultNavigate from '@subwallet/extension-koni-ui/hooks/router/useDef
import useGetChainInfo from '@subwallet/extension-koni-ui/hooks/screen/common/useFetchChainInfo';
import useGetAccountInfoByAddress from '@subwallet/extension-koni-ui/hooks/screen/common/useGetAccountInfoByAddress';
import InscriptionImage from '@subwallet/extension-koni-ui/Popup/Home/Nfts/component/InscriptionImage';
import { INftItemDetail, isValidJson } from '@subwallet/extension-koni-ui/Popup/Home/Nfts/utils';
import { ContentType, determineContentType, getContentType, INftItemDetail, isValidJson } from '@subwallet/extension-koni-ui/Popup/Home/Nfts/utils';
import { RootState } from '@subwallet/extension-koni-ui/stores';
import { Theme, ThemeProps } from '@subwallet/extension-koni-ui/types';
import { BackgroundIcon, Field, Icon, Image, Logo, ModalContext, SwModal } from '@subwallet/react-ui';
Expand Down Expand Up @@ -146,6 +146,87 @@ function Component ({ className = '' }: Props): React.ReactElement<Props> {
return false;
}, [ordinalNftItem]);

const renderAppJsonContent = () => {
const ordinalNftDescription = nftItem?.description && isValidJson(nftItem.description)
? JSON.parse(nftItem.description) as Record<string, unknown>
: undefined;

if (!ordinalNftDescription || Object.keys(ordinalNftDescription).length === 0) {
return (
<Image
className={CN({ clickable: nftItem.externalUrl })}
fallbackSrc={DefaultLogosMap.default_placeholder}
height={358}
modelViewerProps={show3DModel ? { ...DEFAULT_MODEL_VIEWER_PROPS, ...CAMERA_CONTROLS_MODEL_VIEWER_PROPS } : undefined}
onClick={onImageClick}
src={nftItem.image || DefaultLogosMap.default_placeholder}
width={show3DModel ? 358 : undefined}
/>
);
}

return (
<div className='nft-container'>
<pre>
<code>
{JSON.stringify(ordinalNftDescription, null, 2)}
</code>
</pre>
</div>
);
};

const renderNftContent = () => {
const contentType = determineContentType(getContentType(nftItem.properties));

switch (contentType) {
case ContentType.Audio:
return (
<div className='-nft-audio'>
<audio controls>
<source
src={nftItem.image}
type={getContentType(nftItem?.properties)}
/>
</audio>
</div>
);

case ContentType.AppJson:
return renderAppJsonContent();

case ContentType.TextHTML:
case ContentType.ImageSVG:
case ContentType.ModelGltf:
case ContentType.ImageGIF:
return (
<div className='-nft-text-html-wrapper'>
<iframe
className='-nft-text-html'
src={nftItem.image}
/>
</div>
);

default:
if (!isBRC20Inscription) {
return (
<Image
className={CN({ clickable: nftItem.externalUrl })}
fallbackSrc={DefaultLogosMap.default_placeholder}
height={358}
modelViewerProps={show3DModel ? { ...DEFAULT_MODEL_VIEWER_PROPS, ...CAMERA_CONTROLS_MODEL_VIEWER_PROPS } : undefined}
onClick={onImageClick}
src={nftItem.image || DefaultLogosMap.default_placeholder}
width={show3DModel ? 358 : undefined}
/>
);
}

return null;
}
};

return (
<PageWrapper
className={`${className}`}
Expand All @@ -162,23 +243,15 @@ function Component ({ className = '' }: Props): React.ReactElement<Props> {
>
<div className={'nft_item_detail__container'}>
<div className={'nft_item_detail__nft_image'}>
{isBRC20Inscription && nftItem.description && (
<InscriptionImage
alone={true}
properties={JSON.parse(nftItem.description) as OrdinalRemarkData}
/>
)}
{!isBRC20Inscription && (
<Image
className={CN({ clickable: nftItem.externalUrl })}
fallbackSrc={DefaultLogosMap.default_placeholder}
height={358}
modelViewerProps={show3DModel ? { ...DEFAULT_MODEL_VIEWER_PROPS, ...CAMERA_CONTROLS_MODEL_VIEWER_PROPS } : undefined}
onClick={onImageClick}
src={nftItem.image || DefaultLogosMap.default_placeholder}
width={show3DModel ? 358 : undefined}
/>
)}
<>
{isBRC20Inscription && nftItem.description && (
<InscriptionImage
alone={true}
properties={JSON.parse(nftItem.description) as OrdinalRemarkData}
/>
)}
{renderNftContent()}
</>
</div>

<div className={'nft_item_detail__info_container'}>
Expand Down Expand Up @@ -307,6 +380,40 @@ const NftItemDetail = styled(Component)<Props>(({ theme: { token } }: Props) =>
'.clickable': {
cursor: 'pointer'
},
'.-nft-audio': {
display: 'flex',
alignItems: 'center'
},
'.-nft-text-html': {
width: 358,
height: 358,
border: 'none',
overflow: 'hidden'
},
'.nft-container': {
width: 358,
height: 358,
backgroundColor: token.colorTextTertiary,
padding: token.padding,
gap: 8,
display: 'flex',
flexDirection: 'column',
overflow: 'hidden'
},
'.__nft-item': {
fontSize: token.fontSize,
lineHeight: token.lineHeight,
color: token.colorTextDark1,
justifyContent: 'space-between',
display: 'flex',
gap: 4

},
'.__nft-item-value': {
color: token.colorTextDark4,
overflow: 'hidden',
textOverflow: 'ellipsis'
},

'.nft_item_detail__info_container': {
display: 'flex',
Expand Down
Loading

1 comment on commit 66c935b

@saltict
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.