@medialane/ui 0.260.0 → 0.261.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/asset-access-cards.cjs +23 -32
- package/dist/components/asset-access-cards.cjs.map +1 -1
- package/dist/components/asset-access-cards.d.cts +3 -3
- package/dist/components/asset-access-cards.d.ts +3 -3
- package/dist/components/asset-access-cards.js +22 -31
- package/dist/components/asset-access-cards.js.map +1 -1
- package/dist/components/asset-marketplace-panel.cjs +38 -40
- package/dist/components/asset-marketplace-panel.cjs.map +1 -1
- package/dist/components/asset-marketplace-panel.js +39 -41
- package/dist/components/asset-marketplace-panel.js.map +1 -1
- package/dist/components/asset-overview-content.cjs +12 -1
- package/dist/components/asset-overview-content.cjs.map +1 -1
- package/dist/components/asset-overview-content.d.cts +3 -1
- package/dist/components/asset-overview-content.d.ts +3 -1
- package/dist/components/asset-overview-content.js +13 -2
- package/dist/components/asset-overview-content.js.map +1 -1
- package/dist/components/asset-page.cjs +8 -6
- package/dist/components/asset-page.cjs.map +1 -1
- package/dist/components/asset-page.js +8 -6
- package/dist/components/asset-page.js.map +1 -1
- package/dist/components/asset-top-sections.cjs +1 -9
- package/dist/components/asset-top-sections.cjs.map +1 -1
- package/dist/components/asset-top-sections.d.cts +1 -2
- package/dist/components/asset-top-sections.d.ts +1 -2
- package/dist/components/asset-top-sections.js +1 -9
- package/dist/components/asset-top-sections.js.map +1 -1
- package/dist/components/badge.d.cts +1 -1
- package/dist/components/badge.d.ts +1 -1
- package/dist/components/button.d.cts +1 -1
- package/dist/components/button.d.ts +1 -1
- package/dist/components/fast-mint/fast-mint.d.cts +2 -2
- package/dist/components/fast-mint/fast-mint.d.ts +2 -2
- package/dist/components/launchpad/edition-mint-schema.d.cts +2 -2
- package/dist/components/launchpad/edition-mint-schema.d.ts +2 -2
- package/dist/components/markdown-text.cjs +53 -0
- package/dist/components/markdown-text.cjs.map +1 -0
- package/dist/components/markdown-text.d.cts +7 -0
- package/dist/components/markdown-text.d.ts +7 -0
- package/dist/components/markdown-text.js +19 -0
- package/dist/components/markdown-text.js.map +1 -0
- package/dist/components/sheet.d.cts +1 -1
- package/dist/components/sheet.d.ts +1 -1
- package/package.json +3 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/asset-marketplace-panel.tsx"],"sourcesContent":["\"use client\";\n\nimport { Children, type ReactNode } from \"react\";\nimport {\n ArrowRightLeft, CheckCircle, Clock, GitBranch, HandCoins, Handshake, Loader2,\n Tag, X,\n} from \"lucide-react\";\nimport { CurrencyIcon, CurrencyAmount } from \"./currency-icon.js\";\nimport { AddressDisplay } from \"./address-display.js\";\nimport { ActionButton } from \"./action-button.js\";\nimport { formatDisplayPrice } from \"../utils/format.js\";\nimport { isExpired, timeUntil } from \"../utils/time.js\";\nimport { isSameAddress } from \"../utils/same-address.js\";\nimport { cn } from \"../utils/cn.js\";\nimport { AssetAccessCards, CompanionAppCard } from \"./asset-access-cards.js\";\nimport { useMedialaneApp, type AssetRef } from \"./medialane-app.js\";\nimport { HelpIcon } from \"./help-icon.js\";\n\nexport interface ApiOrderLike {\n orderHash: string;\n offerer: string;\n endTime: string;\n price: { formatted: string | null; currency: string | null };\n}\n\nexport interface AssetMarketplacePanelProps<T extends ApiOrderLike = ApiOrderLike> {\n asset: AssetRef;\n compact?: boolean;\n cheapest?: T;\n isOwner: boolean;\n isProcessing: boolean;\n isERC1155: boolean;\n canListMoreEditions?: boolean;\n isMarketLoading?: boolean;\n myListing: T | null;\n activeBids: T[];\n remixEnabled?: boolean;\n showDealOption?: boolean;\n\n usdValue?: string | null;\n\n onCancelClick: (order: T) => void;\n onAcceptBid: (order: T) => void;\n onOpenListing: () => void;\n onOpenTransfer: () => void;\n onOpenPurchase: (order: T) => void;\n onOpenOffer: () => void;\n onOpenRemix?: () => void;\n onProposeDeal?: () => void;\n\n showSponsorOption?: boolean;\n onOpenSponsorProposal?: () => void;\n\n showSponsorSolicitOption?: boolean;\n onOpenSponsorSolicit?: () => void;\n\n\n}\n\nfunction ActionRow({ children }: { children: ReactNode }) {\n const odd = Children.toArray(children).length % 2 === 1;\n return <div className={cn(\"grid grid-cols-2 gap-2\", odd && \"[&>*:first-child]:col-span-2\")}>{children}</div>;\n}\n\nfunction PriceLine({ label, order, usdValue }: { label: string; order: ApiOrderLike; usdValue?: string | null }) {\n return (\n <div className=\"flex flex-wrap items-center gap-x-2 gap-y-1 text-sm text-muted-foreground\">\n <span>{label}</span>\n <CurrencyAmount amount={formatDisplayPrice(order.price.formatted)} symbol={order.price.currency ?? \"\"} iconSize={14} amountClassName=\"text-base font-bold text-foreground tabular-nums\" />\n <span className=\"font-semibold text-foreground\">{order.price.currency}</span>\n {usdValue ? <span className=\"tabular-nums\">· {usdValue}</span> : null}\n <HelpIcon content={`Expires ${timeUntil(order.endTime)}`} />\n </div>\n );\n}\n\nexport function AssetMarketplacePanel<T extends ApiOrderLike = ApiOrderLike>({\n asset,\n compact = false,\n cheapest,\n isOwner,\n isProcessing,\n isERC1155,\n canListMoreEditions,\n isMarketLoading = false,\n myListing,\n activeBids,\n remixEnabled = false,\n showDealOption = false,\n showSponsorOption = false,\n onOpenSponsorProposal,\n showSponsorSolicitOption = false,\n onOpenSponsorSolicit,\n usdValue,\n onCancelClick,\n onAcceptBid,\n onOpenListing,\n onOpenTransfer,\n onOpenPurchase,\n onOpenOffer,\n onOpenRemix,\n onProposeDeal,\n}: AssetMarketplacePanelProps<T>) {\n const { walletAddress } = useMedialaneApp();\n const isSignedIn = !!walletAddress;\n const liveBids = activeBids.filter((bid) => !isExpired(bid.endTime));\n const liveCheapest = cheapest && !isExpired(cheapest.endTime) ? cheapest : undefined;\n const liveMyListing = myListing && !isExpired(myListing.endTime) ? myListing : null;\n\n const myBid = !isOwner && walletAddress\n ? liveBids.find((bid) => isSameAddress(bid.offerer, walletAddress)) ?? null\n : null;\n\n const canBuyMore =\n isERC1155 && isOwner && !!liveCheapest && !!walletAddress &&\n !isSameAddress(liveCheapest.offerer, walletAddress);\n\n if (isMarketLoading && !liveCheapest) {\n return (\n <div className=\"space-y-4\">\n <div className=\"h-9 w-32 rounded-md bg-muted animate-pulse\" />\n <div className=\"h-12 w-full rounded-2xl bg-muted animate-pulse\" />\n </div>\n );\n }\n\n const remixButton = remixEnabled && onOpenRemix ? (\n <ActionButton\n action=\"remix\"\n icon={<GitBranch className=\"h-4 w-4\" />}\n onClick={onOpenRemix}\n helpContent=\"Create your own attributed derivative of this work.\"\n >\n Remix\n </ActionButton>\n ) : null;\n\n const offerButton = (\n <ActionButton action=\"offer\" icon={<HandCoins className=\"h-4 w-4\" />} onClick={onOpenOffer}>\n Make offer\n </ActionButton>\n );\n\n const buyButton = liveCheapest && (!isOwner || canBuyMore) ? (\n <ActionButton action=\"buy\" onClick={() => onOpenPurchase(liveCheapest)}>\n <span>Buy</span>\n <CurrencyAmount amount={formatDisplayPrice(liveCheapest.price.formatted)} symbol={liveCheapest.price.currency ?? \"\"} iconSize={14} amountClassName=\"tabular-nums\" />\n {usdValue ? <span className=\"font-normal text-muted-foreground tabular-nums\">· {usdValue}</span> : null}\n </ActionButton>\n ) : null;\n\n const listedPrice = !isOwner && !isSignedIn && liveCheapest ? (\n <PriceLine label=\"Price\" order={liveCheapest} usdValue={usdValue} />\n ) : null;\n\n return (\n <div className=\"relative\">\n\n <div className=\"relative space-y-4\">\n {listedPrice}\n\n {isOwner ? (\n <div className=\"space-y-3\">\n <ActionRow>\n {liveMyListing ? (\n <ActionButton\n icon={isProcessing ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <X className=\"h-4 w-4\" />}\n onClick={() => onCancelClick(liveMyListing)}\n disabled={isProcessing}\n tone=\"red\"\n helpContent={`Expires ${timeUntil(liveMyListing.endTime)}`}\n >\n <span>Cancel listing</span>\n <CurrencyAmount amount={formatDisplayPrice(liveMyListing.price.formatted)} symbol={liveMyListing.price.currency ?? \"\"} iconSize={14} amountClassName=\"tabular-nums\" />\n {liveMyListing.orderHash === liveCheapest?.orderHash && usdValue ? <span className=\"font-normal text-muted-foreground tabular-nums\">· {usdValue}</span> : null}\n </ActionButton>\n ) : null}\n {!liveMyListing || (isERC1155 && canListMoreEditions !== false) ? (\n <ActionButton tone=\"blue\" icon={<Tag className=\"h-4 w-4\" />} onClick={onOpenListing}>\n {liveMyListing ? \"List more\" : \"List for sale\"}\n </ActionButton>\n ) : null}\n <ActionButton tone=\"orange\" icon={<ArrowRightLeft className=\"h-4 w-4\" />} onClick={onOpenTransfer}>Transfer</ActionButton>\n {remixButton}\n {showSponsorSolicitOption && onOpenSponsorSolicit ? (\n <ActionButton\n tone=\"blue\"\n icon={<Handshake className=\"h-4 w-4\" />}\n onClick={onOpenSponsorSolicit}\n helpContent=\"Let sponsors bid on a license for this asset.\"\n >\n Open for sponsorship\n </ActionButton>\n ) : null}\n </ActionRow>\n {buyButton ? <ActionRow>{buyButton}</ActionRow> : null}\n </div>\n ) : isSignedIn ? (\n <div className=\"space-y-3\">\n <ActionRow>\n {buyButton}\n {offerButton}\n {remixButton}\n {showDealOption && onProposeDeal ? (\n <ActionButton\n action=\"license\"\n icon={<HandCoins className=\"h-4 w-4\" />}\n onClick={onProposeDeal}\n helpContent=\"Propose a license deal to the creator to use this work.\"\n >\n License\n </ActionButton>\n ) : null}\n {showSponsorOption && onOpenSponsorProposal ? (\n <ActionButton\n tone=\"blue\"\n icon={<Handshake className=\"h-4 w-4\" />}\n onClick={onOpenSponsorProposal}\n helpContent=\"Propose to sponsor this creator's work — pay them directly for a license, no escrow.\"\n >\n Sponsor\n </ActionButton>\n ) : null}\n </ActionRow>\n </div>\n ) : (\n <AssetAccessCards asset={asset} stacked={compact} />\n )}\n\n {myBid ? (\n <div className=\"rounded-xl bg-amber-500/8 px-4 py-3 flex items-center justify-between gap-3\">\n <div className=\"min-w-0 flex items-center gap-2.5\">\n <HandCoins className=\"h-4 w-4 text-amber-500 shrink-0\" />\n <div className=\"min-w-0\">\n <p className=\"text-xs font-semibold text-amber-500\">Your active offer</p>\n <p className=\"text-xs text-muted-foreground flex items-center gap-1.5 mt-0.5\">\n <span className=\"font-bold text-foreground inline-flex items-center gap-1\">\n {formatDisplayPrice(myBid.price.formatted)}\n <CurrencyIcon symbol={myBid.price.currency ?? \"\"} size={12} />\n </span>\n <span>·</span>\n <Clock className=\"h-3 w-3\" />\n {timeUntil(myBid.endTime)}\n </p>\n </div>\n </div>\n <button\n className=\"shrink-0 text-xs font-semibold text-red-400 hover:text-red-300 transition-colors flex items-center gap-1\"\n onClick={() => onCancelClick(myBid)}\n >\n <X className=\"h-3.5 w-3.5\" />\n Cancel\n </button>\n </div>\n ) : null}\n\n {isOwner && liveBids.length > 0 ? (\n <div className=\"space-y-2\">\n <p className=\"text-xs font-semibold text-muted-foreground\">\n Incoming offers ({liveBids.length})\n </p>\n <div className=\"divide-y divide-border/40\">\n {liveBids.map((bid) => (\n <div key={bid.orderHash} className=\"flex items-center justify-between gap-3 py-2.5\">\n <div className=\"min-w-0\">\n <p className=\"text-sm font-bold\">\n <span className=\"inline-flex items-center gap-1.5\">\n {formatDisplayPrice(bid.price.formatted)}\n <CurrencyIcon symbol={bid.price.currency ?? \"\"} size={14} />\n </span>\n </p>\n <div className=\"flex items-center gap-2 mt-0.5\">\n <AddressDisplay address={bid.offerer} chars={4} showCopy={false} className=\"text-xs text-muted-foreground\" />\n <span className=\"text-xs text-muted-foreground\">·</span>\n <div className=\"flex items-center gap-1 text-xs text-muted-foreground\">\n <Clock className=\"h-3 w-3\" />\n {timeUntil(bid.endTime)}\n </div>\n </div>\n </div>\n <button\n disabled={isProcessing}\n onClick={() => onAcceptBid(bid)}\n className=\"inline-flex items-center gap-1.5 rounded-lg bg-primary px-3 py-1.5 text-xs font-semibold text-primary-foreground disabled:opacity-50\"\n >\n <CheckCircle className=\"h-3.5 w-3.5\" />\n Accept\n </button>\n </div>\n ))}\n </div>\n </div>\n ) : null}\n\n {isSignedIn ? <CompanionAppCard asset={asset} /> : null}\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/components/asset-marketplace-panel.tsx"],"sourcesContent":["\"use client\";\n\nimport { Children, type ReactNode } from \"react\";\nimport {\n ArrowRightLeft, CheckCircle, Clock, GitBranch, HandCoins, Handshake, Loader2,\n Tag, X,\n} from \"lucide-react\";\nimport { CurrencyIcon, CurrencyAmount } from \"./currency-icon.js\";\nimport { AddressDisplay } from \"./address-display.js\";\nimport { ActionButton } from \"./action-button.js\";\nimport { formatDisplayPrice } from \"../utils/format.js\";\nimport { isExpired, timeUntil } from \"../utils/time.js\";\nimport { isSameAddress } from \"../utils/same-address.js\";\nimport { cn } from \"../utils/cn.js\";\nimport { HelpIcon } from \"./help-icon.js\";\nimport { AssetAccessButtons, CompanionAppButton } from \"./asset-access-cards.js\";\nimport { useMedialaneApp, type AssetRef } from \"./medialane-app.js\";\n\nexport interface ApiOrderLike {\n orderHash: string;\n offerer: string;\n endTime: string;\n price: { formatted: string | null; currency: string | null };\n}\n\nexport interface AssetMarketplacePanelProps<T extends ApiOrderLike = ApiOrderLike> {\n asset: AssetRef;\n compact?: boolean;\n cheapest?: T;\n isOwner: boolean;\n isProcessing: boolean;\n isERC1155: boolean;\n canListMoreEditions?: boolean;\n isMarketLoading?: boolean;\n myListing: T | null;\n activeBids: T[];\n remixEnabled?: boolean;\n showDealOption?: boolean;\n\n usdValue?: string | null;\n\n onCancelClick: (order: T) => void;\n onAcceptBid: (order: T) => void;\n onOpenListing: () => void;\n onOpenTransfer: () => void;\n onOpenPurchase: (order: T) => void;\n onOpenOffer: () => void;\n onOpenRemix?: () => void;\n onProposeDeal?: () => void;\n\n showSponsorOption?: boolean;\n onOpenSponsorProposal?: () => void;\n\n showSponsorSolicitOption?: boolean;\n onOpenSponsorSolicit?: () => void;\n\n\n}\n\nfunction ActionRow({ children }: { children: ReactNode }) {\n const odd = Children.toArray(children).length % 2 === 1;\n return <div className={cn(\"grid grid-cols-2 gap-2\", odd && \"[&>*:first-child]:col-span-2\")}>{children}</div>;\n}\n\nfunction PriceBlock({ order, usdValue }: { order: ApiOrderLike; usdValue?: string | null }) {\n return (\n <div className=\"flex flex-wrap items-center gap-x-2 gap-y-1\">\n <CurrencyAmount amount={formatDisplayPrice(order.price.formatted)} symbol={order.price.currency ?? \"\"} iconSize={26} amountClassName=\"text-3xl font-bold text-foreground tabular-nums\" />\n <span className=\"text-lg font-semibold text-foreground\">{order.price.currency}</span>\n {usdValue ? <span className=\"text-sm tabular-nums text-muted-foreground\">{usdValue}</span> : null}\n <HelpIcon content={`Expires ${timeUntil(order.endTime)}`} />\n </div>\n );\n}\n\nexport function AssetMarketplacePanel<T extends ApiOrderLike = ApiOrderLike>({\n asset,\n compact = false,\n cheapest,\n isOwner,\n isProcessing,\n isERC1155,\n canListMoreEditions,\n isMarketLoading = false,\n myListing,\n activeBids,\n remixEnabled = false,\n showDealOption = false,\n showSponsorOption = false,\n onOpenSponsorProposal,\n showSponsorSolicitOption = false,\n onOpenSponsorSolicit,\n usdValue,\n onCancelClick,\n onAcceptBid,\n onOpenListing,\n onOpenTransfer,\n onOpenPurchase,\n onOpenOffer,\n onOpenRemix,\n onProposeDeal,\n}: AssetMarketplacePanelProps<T>) {\n const { walletAddress } = useMedialaneApp();\n const isSignedIn = !!walletAddress;\n const liveBids = activeBids.filter((bid) => !isExpired(bid.endTime));\n const liveCheapest = cheapest && !isExpired(cheapest.endTime) ? cheapest : undefined;\n const liveMyListing = myListing && !isExpired(myListing.endTime) ? myListing : null;\n\n const myBid = !isOwner && walletAddress\n ? liveBids.find((bid) => isSameAddress(bid.offerer, walletAddress)) ?? null\n : null;\n\n const canBuyMore =\n isERC1155 && isOwner && !!liveCheapest && !!walletAddress &&\n !isSameAddress(liveCheapest.offerer, walletAddress);\n\n if (isMarketLoading && !liveCheapest) {\n return (\n <div className=\"space-y-4\">\n <div className=\"h-9 w-32 rounded-md bg-muted animate-pulse\" />\n <div className=\"h-12 w-full rounded-2xl bg-muted animate-pulse\" />\n </div>\n );\n }\n\n const remixButton = remixEnabled && onOpenRemix ? (\n <ActionButton\n action=\"remix\"\n icon={<GitBranch className=\"h-4 w-4\" />}\n onClick={onOpenRemix}\n helpContent=\"Create your own attributed derivative of this work.\"\n >\n Remix\n </ActionButton>\n ) : null;\n\n const offerButton = (\n <ActionButton action=\"offer\" icon={<HandCoins className=\"h-4 w-4\" />} onClick={onOpenOffer}>\n Make offer\n </ActionButton>\n );\n\n const buyButton = liveCheapest && (!isOwner || canBuyMore) ? (\n isOwner ? (\n <ActionButton action=\"buy\" onClick={() => onOpenPurchase(liveCheapest)}>\n <span>Buy</span>\n <CurrencyAmount amount={formatDisplayPrice(liveCheapest.price.formatted)} symbol={liveCheapest.price.currency ?? \"\"} iconSize={14} amountClassName=\"tabular-nums\" />\n {usdValue ? <span className=\"font-normal text-muted-foreground tabular-nums\">· {usdValue}</span> : null}\n </ActionButton>\n ) : (\n <ActionButton action=\"buy\" onClick={() => onOpenPurchase(liveCheapest)}>\n Buy now\n </ActionButton>\n )\n ) : null;\n\n const listedPrice = !isOwner && liveCheapest ? <PriceBlock order={liveCheapest} usdValue={usdValue} /> : null;\n\n return (\n <div className=\"relative\">\n\n <div className=\"relative space-y-4\">\n {isOwner ? (\n <div className=\"space-y-3\">\n <ActionRow>\n {liveMyListing ? (\n <ActionButton\n icon={isProcessing ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <X className=\"h-4 w-4\" />}\n onClick={() => onCancelClick(liveMyListing)}\n disabled={isProcessing}\n tone=\"red\"\n helpContent={`Expires ${timeUntil(liveMyListing.endTime)}`}\n >\n <span>Cancel listing</span>\n <CurrencyAmount amount={formatDisplayPrice(liveMyListing.price.formatted)} symbol={liveMyListing.price.currency ?? \"\"} iconSize={14} amountClassName=\"tabular-nums\" />\n {liveMyListing.orderHash === liveCheapest?.orderHash && usdValue ? <span className=\"font-normal text-muted-foreground tabular-nums\">· {usdValue}</span> : null}\n </ActionButton>\n ) : null}\n {!liveMyListing || (isERC1155 && canListMoreEditions !== false) ? (\n <ActionButton tone=\"blue\" icon={<Tag className=\"h-4 w-4\" />} onClick={onOpenListing}>\n {liveMyListing ? \"List more\" : \"List for sale\"}\n </ActionButton>\n ) : null}\n <ActionButton tone=\"orange\" icon={<ArrowRightLeft className=\"h-4 w-4\" />} onClick={onOpenTransfer}>Transfer</ActionButton>\n {remixButton}\n {showSponsorSolicitOption && onOpenSponsorSolicit ? (\n <ActionButton\n tone=\"blue\"\n icon={<Handshake className=\"h-4 w-4\" />}\n onClick={onOpenSponsorSolicit}\n helpContent=\"Let sponsors bid on a license for this asset.\"\n >\n Open for sponsorship\n </ActionButton>\n ) : null}\n </ActionRow>\n {buyButton ? <ActionRow>{buyButton}</ActionRow> : null}\n </div>\n ) : (\n <div className=\"space-y-4\">\n {listedPrice}\n {isSignedIn ? (\n <ActionRow>\n {buyButton}\n {offerButton}\n {remixButton}\n {showDealOption && onProposeDeal ? (\n <ActionButton\n action=\"license\"\n icon={<HandCoins className=\"h-4 w-4\" />}\n onClick={onProposeDeal}\n helpContent=\"Propose a license deal to the creator to use this work.\"\n >\n License\n </ActionButton>\n ) : null}\n {showSponsorOption && onOpenSponsorProposal ? (\n <ActionButton\n tone=\"blue\"\n icon={<Handshake className=\"h-4 w-4\" />}\n onClick={onOpenSponsorProposal}\n helpContent=\"Propose to sponsor this creator's work — pay them directly for a license, no escrow.\"\n >\n Sponsor\n </ActionButton>\n ) : null}\n </ActionRow>\n ) : (\n <AssetAccessButtons asset={asset} stacked={compact} />\n )}\n </div>\n )}\n\n {myBid ? (\n <div className=\"rounded-xl bg-amber-500/8 px-4 py-3 flex items-center justify-between gap-3\">\n <div className=\"min-w-0 flex items-center gap-2.5\">\n <HandCoins className=\"h-4 w-4 text-amber-500 shrink-0\" />\n <div className=\"min-w-0\">\n <p className=\"text-xs font-semibold text-amber-500\">Your active offer</p>\n <p className=\"text-xs text-muted-foreground flex items-center gap-1.5 mt-0.5\">\n <span className=\"font-bold text-foreground inline-flex items-center gap-1\">\n {formatDisplayPrice(myBid.price.formatted)}\n <CurrencyIcon symbol={myBid.price.currency ?? \"\"} size={12} />\n </span>\n <span>·</span>\n <Clock className=\"h-3 w-3\" />\n {timeUntil(myBid.endTime)}\n </p>\n </div>\n </div>\n <button\n className=\"shrink-0 text-xs font-semibold text-red-400 hover:text-red-300 transition-colors flex items-center gap-1\"\n onClick={() => onCancelClick(myBid)}\n >\n <X className=\"h-3.5 w-3.5\" />\n Cancel\n </button>\n </div>\n ) : null}\n\n {isOwner && liveBids.length > 0 ? (\n <div className=\"space-y-2\">\n <p className=\"text-xs font-semibold text-muted-foreground\">\n Incoming offers ({liveBids.length})\n </p>\n <div className=\"divide-y divide-border/40\">\n {liveBids.map((bid) => (\n <div key={bid.orderHash} className=\"flex items-center justify-between gap-3 py-2.5\">\n <div className=\"min-w-0\">\n <p className=\"text-sm font-bold\">\n <span className=\"inline-flex items-center gap-1.5\">\n {formatDisplayPrice(bid.price.formatted)}\n <CurrencyIcon symbol={bid.price.currency ?? \"\"} size={14} />\n </span>\n </p>\n <div className=\"flex items-center gap-2 mt-0.5\">\n <AddressDisplay address={bid.offerer} chars={4} showCopy={false} className=\"text-xs text-muted-foreground\" />\n <span className=\"text-xs text-muted-foreground\">·</span>\n <div className=\"flex items-center gap-1 text-xs text-muted-foreground\">\n <Clock className=\"h-3 w-3\" />\n {timeUntil(bid.endTime)}\n </div>\n </div>\n </div>\n <button\n disabled={isProcessing}\n onClick={() => onAcceptBid(bid)}\n className=\"inline-flex items-center gap-1.5 rounded-lg bg-primary px-3 py-1.5 text-xs font-semibold text-primary-foreground disabled:opacity-50\"\n >\n <CheckCircle className=\"h-3.5 w-3.5\" />\n Accept\n </button>\n </div>\n ))}\n </div>\n </div>\n ) : null}\n\n {isSignedIn ? <CompanionAppButton asset={asset} /> : null}\n </div>\n </div>\n );\n}\n"],"mappings":";AA6DS,cAKL,YALK;AA3DT,SAAS,gBAAgC;AACzC;AAAA,EACE;AAAA,EAAgB;AAAA,EAAa;AAAA,EAAO;AAAA,EAAW;AAAA,EAAW;AAAA,EAAW;AAAA,EACrE;AAAA,EAAK;AAAA,OACA;AACP,SAAS,cAAc,sBAAsB;AAC7C,SAAS,sBAAsB;AAC/B,SAAS,oBAAoB;AAC7B,SAAS,0BAA0B;AACnC,SAAS,WAAW,iBAAiB;AACrC,SAAS,qBAAqB;AAC9B,SAAS,UAAU;AACnB,SAAS,gBAAgB;AACzB,SAAS,oBAAoB,0BAA0B;AACvD,SAAS,uBAAsC;AA2C/C,SAAS,UAAU,EAAE,SAAS,GAA4B;AACxD,QAAM,MAAM,SAAS,QAAQ,QAAQ,EAAE,SAAS,MAAM;AACtD,SAAO,oBAAC,SAAI,WAAW,GAAG,0BAA0B,OAAO,8BAA8B,GAAI,UAAS;AACxG;AAEA,SAAS,WAAW,EAAE,OAAO,SAAS,GAAsD;AAC1F,SACE,qBAAC,SAAI,WAAU,+CACb;AAAA,wBAAC,kBAAe,QAAQ,mBAAmB,MAAM,MAAM,SAAS,GAAG,QAAQ,MAAM,MAAM,YAAY,IAAI,UAAU,IAAI,iBAAgB,mDAAkD;AAAA,IACvL,oBAAC,UAAK,WAAU,yCAAyC,gBAAM,MAAM,UAAS;AAAA,IAC7E,WAAW,oBAAC,UAAK,WAAU,8CAA8C,oBAAS,IAAU;AAAA,IAC7F,oBAAC,YAAS,SAAS,WAAW,UAAU,MAAM,OAAO,CAAC,IAAI;AAAA,KAC5D;AAEJ;AAEO,SAAS,sBAA6D;AAAA,EAC3E;AAAA,EACA,UAAU;AAAA,EACV;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,kBAAkB;AAAA,EAClB;AAAA,EACA;AAAA,EACA,eAAe;AAAA,EACf,iBAAiB;AAAA,EACjB,oBAAoB;AAAA,EACpB;AAAA,EACA,2BAA2B;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAkC;AAChC,QAAM,EAAE,cAAc,IAAI,gBAAgB;AAC1C,QAAM,aAAa,CAAC,CAAC;AACrB,QAAM,WAAW,WAAW,OAAO,CAAC,QAAQ,CAAC,UAAU,IAAI,OAAO,CAAC;AACnE,QAAM,eAAe,YAAY,CAAC,UAAU,SAAS,OAAO,IAAI,WAAW;AAC3E,QAAM,gBAAgB,aAAa,CAAC,UAAU,UAAU,OAAO,IAAI,YAAY;AAE/E,QAAM,QAAQ,CAAC,WAAW,gBACtB,SAAS,KAAK,CAAC,QAAQ,cAAc,IAAI,SAAS,aAAa,CAAC,KAAK,OACrE;AAEJ,QAAM,aACJ,aAAa,WAAW,CAAC,CAAC,gBAAgB,CAAC,CAAC,iBAC5C,CAAC,cAAc,aAAa,SAAS,aAAa;AAEpD,MAAI,mBAAmB,CAAC,cAAc;AACpC,WACE,qBAAC,SAAI,WAAU,aACb;AAAA,0BAAC,SAAI,WAAU,8CAA6C;AAAA,MAC5D,oBAAC,SAAI,WAAU,kDAAiD;AAAA,OAClE;AAAA,EAEJ;AAEA,QAAM,cAAc,gBAAgB,cAClC;AAAA,IAAC;AAAA;AAAA,MACC,QAAO;AAAA,MACP,MAAM,oBAAC,aAAU,WAAU,WAAU;AAAA,MACrC,SAAS;AAAA,MACT,aAAY;AAAA,MACb;AAAA;AAAA,EAED,IACE;AAEJ,QAAM,cACJ,oBAAC,gBAAa,QAAO,SAAQ,MAAM,oBAAC,aAAU,WAAU,WAAU,GAAI,SAAS,aAAa,wBAE5F;AAGF,QAAM,YAAY,iBAAiB,CAAC,WAAW,cAC7C,UACE,qBAAC,gBAAa,QAAO,OAAM,SAAS,MAAM,eAAe,YAAY,GACnE;AAAA,wBAAC,UAAK,iBAAG;AAAA,IACT,oBAAC,kBAAe,QAAQ,mBAAmB,aAAa,MAAM,SAAS,GAAG,QAAQ,aAAa,MAAM,YAAY,IAAI,UAAU,IAAI,iBAAgB,gBAAe;AAAA,IACjK,WAAW,qBAAC,UAAK,WAAU,kDAAiD;AAAA;AAAA,MAAG;AAAA,OAAS,IAAU;AAAA,KACrG,IAEA,oBAAC,gBAAa,QAAO,OAAM,SAAS,MAAM,eAAe,YAAY,GAAG,qBAExE,IAEA;AAEJ,QAAM,cAAc,CAAC,WAAW,eAAe,oBAAC,cAAW,OAAO,cAAc,UAAoB,IAAK;AAEzG,SACE,oBAAC,SAAI,WAAU,YAEb,+BAAC,SAAI,WAAU,sBACZ;AAAA,cACC,qBAAC,SAAI,WAAU,aACb;AAAA,2BAAC,aACE;AAAA,wBACC;AAAA,UAAC;AAAA;AAAA,YACC,MAAM,eAAe,oBAAC,WAAQ,WAAU,wBAAuB,IAAK,oBAAC,KAAE,WAAU,WAAU;AAAA,YAC3F,SAAS,MAAM,cAAc,aAAa;AAAA,YAC1C,UAAU;AAAA,YACV,MAAK;AAAA,YACL,aAAa,WAAW,UAAU,cAAc,OAAO,CAAC;AAAA,YAExD;AAAA,kCAAC,UAAK,4BAAc;AAAA,cACpB,oBAAC,kBAAe,QAAQ,mBAAmB,cAAc,MAAM,SAAS,GAAG,QAAQ,cAAc,MAAM,YAAY,IAAI,UAAU,IAAI,iBAAgB,gBAAe;AAAA,cACnK,cAAc,cAAc,cAAc,aAAa,WAAW,qBAAC,UAAK,WAAU,kDAAiD;AAAA;AAAA,gBAAG;AAAA,iBAAS,IAAU;AAAA;AAAA;AAAA,QAC5J,IACE;AAAA,QACH,CAAC,iBAAkB,aAAa,wBAAwB,QACvD,oBAAC,gBAAa,MAAK,QAAO,MAAM,oBAAC,OAAI,WAAU,WAAU,GAAI,SAAS,eACnE,0BAAgB,cAAc,iBACjC,IACE;AAAA,QACJ,oBAAC,gBAAa,MAAK,UAAS,MAAM,oBAAC,kBAAe,WAAU,WAAU,GAAI,SAAS,gBAAgB,sBAAQ;AAAA,QAC1G;AAAA,QACA,4BAA4B,uBAC3B;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,MAAM,oBAAC,aAAU,WAAU,WAAU;AAAA,YACrC,SAAS;AAAA,YACT,aAAY;AAAA,YACb;AAAA;AAAA,QAED,IACE;AAAA,SACN;AAAA,MACC,YAAY,oBAAC,aAAW,qBAAU,IAAe;AAAA,OACpD,IAEA,qBAAC,SAAI,WAAU,aACZ;AAAA;AAAA,MACA,aACC,qBAAC,aACE;AAAA;AAAA,QACA;AAAA,QACA;AAAA,QACA,kBAAkB,gBACjB;AAAA,UAAC;AAAA;AAAA,YACC,QAAO;AAAA,YACP,MAAM,oBAAC,aAAU,WAAU,WAAU;AAAA,YACrC,SAAS;AAAA,YACT,aAAY;AAAA,YACb;AAAA;AAAA,QAED,IACE;AAAA,QACH,qBAAqB,wBACpB;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,MAAM,oBAAC,aAAU,WAAU,WAAU;AAAA,YACrC,SAAS;AAAA,YACT,aAAY;AAAA,YACb;AAAA;AAAA,QAED,IACE;AAAA,SACN,IAEA,oBAAC,sBAAmB,OAAc,SAAS,SAAS;AAAA,OAExD;AAAA,IAGD,QACC,qBAAC,SAAI,WAAU,+EACb;AAAA,2BAAC,SAAI,WAAU,qCACb;AAAA,4BAAC,aAAU,WAAU,mCAAkC;AAAA,QACvD,qBAAC,SAAI,WAAU,WACb;AAAA,8BAAC,OAAE,WAAU,wCAAuC,+BAAiB;AAAA,UACrE,qBAAC,OAAE,WAAU,kEACX;AAAA,iCAAC,UAAK,WAAU,4DACb;AAAA,iCAAmB,MAAM,MAAM,SAAS;AAAA,cACzC,oBAAC,gBAAa,QAAQ,MAAM,MAAM,YAAY,IAAI,MAAM,IAAI;AAAA,eAC9D;AAAA,YACA,oBAAC,UAAK,kBAAC;AAAA,YACP,oBAAC,SAAM,WAAU,WAAU;AAAA,YAC1B,UAAU,MAAM,OAAO;AAAA,aAC1B;AAAA,WACF;AAAA,SACF;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,WAAU;AAAA,UACV,SAAS,MAAM,cAAc,KAAK;AAAA,UAElC;AAAA,gCAAC,KAAE,WAAU,eAAc;AAAA,YAAE;AAAA;AAAA;AAAA,MAE/B;AAAA,OACF,IACE;AAAA,IAEH,WAAW,SAAS,SAAS,IAC5B,qBAAC,SAAI,WAAU,aACb;AAAA,2BAAC,OAAE,WAAU,+CAA8C;AAAA;AAAA,QACvC,SAAS;AAAA,QAAO;AAAA,SACpC;AAAA,MACA,oBAAC,SAAI,WAAU,6BACZ,mBAAS,IAAI,CAAC,QACb,qBAAC,SAAwB,WAAU,kDACjC;AAAA,6BAAC,SAAI,WAAU,WACb;AAAA,8BAAC,OAAE,WAAU,qBACX,+BAAC,UAAK,WAAU,oCACb;AAAA,+BAAmB,IAAI,MAAM,SAAS;AAAA,YACvC,oBAAC,gBAAa,QAAQ,IAAI,MAAM,YAAY,IAAI,MAAM,IAAI;AAAA,aAC5D,GACF;AAAA,UACA,qBAAC,SAAI,WAAU,kCACb;AAAA,gCAAC,kBAAe,SAAS,IAAI,SAAS,OAAO,GAAG,UAAU,OAAO,WAAU,iCAAgC;AAAA,YAC3G,oBAAC,UAAK,WAAU,iCAAgC,kBAAC;AAAA,YACjD,qBAAC,SAAI,WAAU,yDACb;AAAA,kCAAC,SAAM,WAAU,WAAU;AAAA,cAC1B,UAAU,IAAI,OAAO;AAAA,eACxB;AAAA,aACF;AAAA,WACF;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,UAAU;AAAA,YACV,SAAS,MAAM,YAAY,GAAG;AAAA,YAC9B,WAAU;AAAA,YAEV;AAAA,kCAAC,eAAY,WAAU,eAAc;AAAA,cAAE;AAAA;AAAA;AAAA,QAEzC;AAAA,WAxBQ,IAAI,SAyBd,CACD,GACH;AAAA,OACF,IACE;AAAA,IAEH,aAAa,oBAAC,sBAAmB,OAAc,IAAK;AAAA,KACvD,GACF;AAEJ;","names":[]}
|
|
@@ -26,6 +26,7 @@ var import_jsx_runtime = require("react/jsx-runtime");
|
|
|
26
26
|
var import_lucide_react = require("lucide-react");
|
|
27
27
|
var import_ip_type_display = require("./ip-type-display.js");
|
|
28
28
|
var import_address_display = require("./address-display.js");
|
|
29
|
+
var import_markdown_text = require("./markdown-text.js");
|
|
29
30
|
var import_license_summary = require("../utils/license-summary.js");
|
|
30
31
|
const isAddressLike = (v) => typeof v === "string" && /^0x[0-9a-fA-F]{16,}$/.test(v.trim());
|
|
31
32
|
function Cell({
|
|
@@ -51,7 +52,9 @@ function Cell({
|
|
|
51
52
|
function AssetOverviewContent({
|
|
52
53
|
attributes,
|
|
53
54
|
hasTemplateData,
|
|
54
|
-
isDisplayAttr
|
|
55
|
+
isDisplayAttr,
|
|
56
|
+
content,
|
|
57
|
+
link
|
|
55
58
|
}) {
|
|
56
59
|
const attr = (trait) => attributes.find((attribute) => attribute.trait_type === trait)?.value;
|
|
57
60
|
const licenseType = attr("License");
|
|
@@ -73,6 +76,14 @@ function AssetOverviewContent({
|
|
|
73
76
|
{ icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Percent, { className: "h-4 w-4" }), label: "Royalty", value: royalty }
|
|
74
77
|
].filter((row) => !!row.value);
|
|
75
78
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "mt-4 space-y-7", children: [
|
|
79
|
+
content ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "space-y-3", children: [
|
|
80
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { className: "text-sm font-semibold text-muted-foreground", children: "Content" }),
|
|
81
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_markdown_text.MarkdownText, { text: content })
|
|
82
|
+
] }) : null,
|
|
83
|
+
link ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("a", { href: link, target: "_blank", rel: "noopener noreferrer", className: "inline-flex items-center gap-1.5 text-sm text-primary hover:underline", children: [
|
|
84
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ExternalLink, { className: "h-3.5 w-3.5" }),
|
|
85
|
+
"Open link"
|
|
86
|
+
] }) : null,
|
|
76
87
|
hasTemplateData ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ip_type_display.IPTypeDisplay, { attributes }) : null,
|
|
77
88
|
hasLicenseData ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "space-y-3", children: [
|
|
78
89
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { className: "text-sm font-semibold text-muted-foreground", children: "Rights" }),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/asset-overview-content.tsx"],"sourcesContent":["\"use client\";\n\nimport type { ReactNode } from \"react\";\nimport { Bot, DollarSign, GitBranch, Globe, Percent, UserCheck } from \"lucide-react\";\nimport { IPTypeDisplay } from \"./ip-type-display.js\";\nimport { AddressDisplay } from \"./address-display.js\";\nimport { licenseSummary } from \"../utils/license-summary.js\";\n\ninterface AssetAttribute {\n trait_type?: string;\n value?: string;\n}\n\ninterface AssetOverviewContentProps {\n attributes: AssetAttribute[];\n hasTemplateData: boolean;\n isDisplayAttr: (attribute: AssetAttribute) => boolean;\n}\n\nconst isAddressLike = (v?: unknown): boolean =>\n typeof v === \"string\" && /^0x[0-9a-fA-F]{16,}$/.test(v.trim());\n\nfunction Cell({\n icon,\n label,\n value,\n wide,\n}: {\n icon?: ReactNode;\n label: string;\n value: ReactNode;\n wide?: boolean;\n}) {\n return (\n <div\n className={`flex flex-col justify-between gap-2 rounded-xl bg-muted/25 ring-1 ring-border/40 p-3.5 ${\n wide ? \"col-span-2\" : \"\"\n }`}\n >\n {icon ? <span className=\"text-primary/70\">{icon}</span> : null}\n <div className=\"space-y-0.5\">\n <p className=\"text-2xs font-medium text-muted-foreground truncate\" title={label}>\n {label}\n </p>\n <div className=\"text-sm font-bold text-foreground truncate\">{value}</div>\n </div>\n </div>\n );\n}\n\nexport function AssetOverviewContent({\n attributes,\n hasTemplateData,\n isDisplayAttr,\n}: AssetOverviewContentProps) {\n const attr = (trait: string) => attributes.find((attribute) => attribute.trait_type === trait)?.value;\n const licenseType = attr(\"License\");\n const commercialUse = attr(\"Commercial Use\");\n const derivatives = attr(\"Derivatives\");\n const attribution = attr(\"Attribution\");\n const territory = attr(\"Territory\");\n const aiPolicy = attr(\"AI Policy\");\n const royalty = attr(\"Royalty\");\n const summary = licenseSummary(attributes);\n const hasLicenseData = !!(licenseType || commercialUse || derivatives || attribution);\n const displayAttributes = attributes.filter((attribute) => isDisplayAttr(attribute));\n\n const facts = [\n { icon: <DollarSign className=\"h-4 w-4\" />, label: \"Commercial use\", value: commercialUse },\n { icon: <GitBranch className=\"h-4 w-4\" />, label: \"Derivatives\", value: derivatives },\n { icon: <UserCheck className=\"h-4 w-4\" />, label: \"Attribution\", value: attribution },\n { icon: <Globe className=\"h-4 w-4\" />, label: \"Territory\", value: territory },\n { icon: <Bot className=\"h-4 w-4\" />, label: \"AI & data mining\", value: aiPolicy },\n { icon: <Percent className=\"h-4 w-4\" />, label: \"Royalty\", value: royalty },\n ].filter((row) => !!row.value);\n\n return (\n <div className=\"mt-4 space-y-7\">\n {hasTemplateData ? <IPTypeDisplay attributes={attributes} /> : null}\n\n {hasLicenseData ? (\n <section className=\"space-y-3\">\n <h3 className=\"text-sm font-semibold text-muted-foreground\">Rights</h3>\n <div className=\"relative\">\n\n <div className=\"relative grid grid-cols-2 sm:grid-cols-4 gap-3 [grid-auto-flow:dense] auto-rows-[minmax(6rem,auto)]\">\n\n <div className=\"col-span-2 sm:row-span-2 flex flex-col justify-between gap-4 rounded-2xl bg-gradient-to-br from-primary/10 via-primary/5 to-accent/10 ring-1 ring-primary/15 p-5\">\n {licenseType ? (\n <span className=\"pill-badge self-start text-2xs\">{licenseType}</span>\n ) : null}\n {summary ? (\n <p className=\"text-base sm:text-lg font-semibold leading-snug text-foreground\">{summary}</p>\n ) : null}\n </div>\n\n {facts.map(({ icon, label, value }) => (\n <Cell key={label} icon={icon} label={label} value={value} />\n ))}\n </div>\n </div>\n <p className=\"text-xs text-muted-foreground/70\">\n Kept in permanent, tamper-proof storage · recognized under international copyright law\n </p>\n </section>\n ) : null}\n\n {displayAttributes.length > 0 ? (\n <section className=\"space-y-3\">\n <h3 className=\"text-sm font-semibold text-muted-foreground\">Details</h3>\n <div className=\"grid grid-cols-2 sm:grid-cols-4 gap-3 [grid-auto-flow:dense] auto-rows-[minmax(6rem,auto)]\">\n {displayAttributes.map((attribute, index) => (\n <Cell\n key={index}\n label={attribute.trait_type ?? \"Trait\"}\n wide={isAddressLike(attribute.value)}\n value={\n isAddressLike(attribute.value) ? (\n <AddressDisplay address={attribute.value!} chars={4} className=\"text-sm font-bold\" />\n ) : (\n attribute.value ?? \"—\"\n )\n }\n />\n ))}\n </div>\n </section>\n ) : null}\n\n {!hasTemplateData && !hasLicenseData && displayAttributes.length === 0 ? (\n <p className=\"text-sm text-muted-foreground\">No additional details available.</p>\n ) : null}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
1
|
+
{"version":3,"sources":["../../src/components/asset-overview-content.tsx"],"sourcesContent":["\"use client\";\n\nimport type { ReactNode } from \"react\";\nimport { Bot, DollarSign, ExternalLink, GitBranch, Globe, Percent, UserCheck } from \"lucide-react\";\nimport { IPTypeDisplay } from \"./ip-type-display.js\";\nimport { AddressDisplay } from \"./address-display.js\";\nimport { MarkdownText } from \"./markdown-text.js\";\nimport { licenseSummary } from \"../utils/license-summary.js\";\n\ninterface AssetAttribute {\n trait_type?: string;\n value?: string;\n}\n\ninterface AssetOverviewContentProps {\n attributes: AssetAttribute[];\n hasTemplateData: boolean;\n isDisplayAttr: (attribute: AssetAttribute) => boolean;\n content?: string | null;\n link?: string | null;\n}\n\nconst isAddressLike = (v?: unknown): boolean =>\n typeof v === \"string\" && /^0x[0-9a-fA-F]{16,}$/.test(v.trim());\n\nfunction Cell({\n icon,\n label,\n value,\n wide,\n}: {\n icon?: ReactNode;\n label: string;\n value: ReactNode;\n wide?: boolean;\n}) {\n return (\n <div\n className={`flex flex-col justify-between gap-2 rounded-xl bg-muted/25 ring-1 ring-border/40 p-3.5 ${\n wide ? \"col-span-2\" : \"\"\n }`}\n >\n {icon ? <span className=\"text-primary/70\">{icon}</span> : null}\n <div className=\"space-y-0.5\">\n <p className=\"text-2xs font-medium text-muted-foreground truncate\" title={label}>\n {label}\n </p>\n <div className=\"text-sm font-bold text-foreground truncate\">{value}</div>\n </div>\n </div>\n );\n}\n\nexport function AssetOverviewContent({\n attributes,\n hasTemplateData,\n isDisplayAttr,\n content,\n link,\n}: AssetOverviewContentProps) {\n const attr = (trait: string) => attributes.find((attribute) => attribute.trait_type === trait)?.value;\n const licenseType = attr(\"License\");\n const commercialUse = attr(\"Commercial Use\");\n const derivatives = attr(\"Derivatives\");\n const attribution = attr(\"Attribution\");\n const territory = attr(\"Territory\");\n const aiPolicy = attr(\"AI Policy\");\n const royalty = attr(\"Royalty\");\n const summary = licenseSummary(attributes);\n const hasLicenseData = !!(licenseType || commercialUse || derivatives || attribution);\n const displayAttributes = attributes.filter((attribute) => isDisplayAttr(attribute));\n\n const facts = [\n { icon: <DollarSign className=\"h-4 w-4\" />, label: \"Commercial use\", value: commercialUse },\n { icon: <GitBranch className=\"h-4 w-4\" />, label: \"Derivatives\", value: derivatives },\n { icon: <UserCheck className=\"h-4 w-4\" />, label: \"Attribution\", value: attribution },\n { icon: <Globe className=\"h-4 w-4\" />, label: \"Territory\", value: territory },\n { icon: <Bot className=\"h-4 w-4\" />, label: \"AI & data mining\", value: aiPolicy },\n { icon: <Percent className=\"h-4 w-4\" />, label: \"Royalty\", value: royalty },\n ].filter((row) => !!row.value);\n\n return (\n <div className=\"mt-4 space-y-7\">\n {content ? (\n <section className=\"space-y-3\">\n <h3 className=\"text-sm font-semibold text-muted-foreground\">Content</h3>\n <MarkdownText text={content} />\n </section>\n ) : null}\n\n {link ? (\n <a href={link} target=\"_blank\" rel=\"noopener noreferrer\" className=\"inline-flex items-center gap-1.5 text-sm text-primary hover:underline\">\n <ExternalLink className=\"h-3.5 w-3.5\" />\n Open link\n </a>\n ) : null}\n\n {hasTemplateData ? <IPTypeDisplay attributes={attributes} /> : null}\n\n {hasLicenseData ? (\n <section className=\"space-y-3\">\n <h3 className=\"text-sm font-semibold text-muted-foreground\">Rights</h3>\n <div className=\"relative\">\n\n <div className=\"relative grid grid-cols-2 sm:grid-cols-4 gap-3 [grid-auto-flow:dense] auto-rows-[minmax(6rem,auto)]\">\n\n <div className=\"col-span-2 sm:row-span-2 flex flex-col justify-between gap-4 rounded-2xl bg-gradient-to-br from-primary/10 via-primary/5 to-accent/10 ring-1 ring-primary/15 p-5\">\n {licenseType ? (\n <span className=\"pill-badge self-start text-2xs\">{licenseType}</span>\n ) : null}\n {summary ? (\n <p className=\"text-base sm:text-lg font-semibold leading-snug text-foreground\">{summary}</p>\n ) : null}\n </div>\n\n {facts.map(({ icon, label, value }) => (\n <Cell key={label} icon={icon} label={label} value={value} />\n ))}\n </div>\n </div>\n <p className=\"text-xs text-muted-foreground/70\">\n Kept in permanent, tamper-proof storage · recognized under international copyright law\n </p>\n </section>\n ) : null}\n\n {displayAttributes.length > 0 ? (\n <section className=\"space-y-3\">\n <h3 className=\"text-sm font-semibold text-muted-foreground\">Details</h3>\n <div className=\"grid grid-cols-2 sm:grid-cols-4 gap-3 [grid-auto-flow:dense] auto-rows-[minmax(6rem,auto)]\">\n {displayAttributes.map((attribute, index) => (\n <Cell\n key={index}\n label={attribute.trait_type ?? \"Trait\"}\n wide={isAddressLike(attribute.value)}\n value={\n isAddressLike(attribute.value) ? (\n <AddressDisplay address={attribute.value!} chars={4} className=\"text-sm font-bold\" />\n ) : (\n attribute.value ?? \"—\"\n )\n }\n />\n ))}\n </div>\n </section>\n ) : null}\n\n {!hasTemplateData && !hasLicenseData && displayAttributes.length === 0 ? (\n <p className=\"text-sm text-muted-foreground\">No additional details available.</p>\n ) : null}\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -8,7 +8,9 @@ interface AssetOverviewContentProps {
|
|
|
8
8
|
attributes: AssetAttribute[];
|
|
9
9
|
hasTemplateData: boolean;
|
|
10
10
|
isDisplayAttr: (attribute: AssetAttribute) => boolean;
|
|
11
|
+
content?: string | null;
|
|
12
|
+
link?: string | null;
|
|
11
13
|
}
|
|
12
|
-
declare function AssetOverviewContent({ attributes, hasTemplateData, isDisplayAttr, }: AssetOverviewContentProps): react_jsx_runtime.JSX.Element;
|
|
14
|
+
declare function AssetOverviewContent({ attributes, hasTemplateData, isDisplayAttr, content, link, }: AssetOverviewContentProps): react_jsx_runtime.JSX.Element;
|
|
13
15
|
|
|
14
16
|
export { AssetOverviewContent };
|
|
@@ -8,7 +8,9 @@ interface AssetOverviewContentProps {
|
|
|
8
8
|
attributes: AssetAttribute[];
|
|
9
9
|
hasTemplateData: boolean;
|
|
10
10
|
isDisplayAttr: (attribute: AssetAttribute) => boolean;
|
|
11
|
+
content?: string | null;
|
|
12
|
+
link?: string | null;
|
|
11
13
|
}
|
|
12
|
-
declare function AssetOverviewContent({ attributes, hasTemplateData, isDisplayAttr, }: AssetOverviewContentProps): react_jsx_runtime.JSX.Element;
|
|
14
|
+
declare function AssetOverviewContent({ attributes, hasTemplateData, isDisplayAttr, content, link, }: AssetOverviewContentProps): react_jsx_runtime.JSX.Element;
|
|
13
15
|
|
|
14
16
|
export { AssetOverviewContent };
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { Bot, DollarSign, GitBranch, Globe, Percent, UserCheck } from "lucide-react";
|
|
3
|
+
import { Bot, DollarSign, ExternalLink, GitBranch, Globe, Percent, UserCheck } from "lucide-react";
|
|
4
4
|
import { IPTypeDisplay } from "./ip-type-display.js";
|
|
5
5
|
import { AddressDisplay } from "./address-display.js";
|
|
6
|
+
import { MarkdownText } from "./markdown-text.js";
|
|
6
7
|
import { licenseSummary } from "../utils/license-summary.js";
|
|
7
8
|
const isAddressLike = (v) => typeof v === "string" && /^0x[0-9a-fA-F]{16,}$/.test(v.trim());
|
|
8
9
|
function Cell({
|
|
@@ -28,7 +29,9 @@ function Cell({
|
|
|
28
29
|
function AssetOverviewContent({
|
|
29
30
|
attributes,
|
|
30
31
|
hasTemplateData,
|
|
31
|
-
isDisplayAttr
|
|
32
|
+
isDisplayAttr,
|
|
33
|
+
content,
|
|
34
|
+
link
|
|
32
35
|
}) {
|
|
33
36
|
const attr = (trait) => attributes.find((attribute) => attribute.trait_type === trait)?.value;
|
|
34
37
|
const licenseType = attr("License");
|
|
@@ -50,6 +53,14 @@ function AssetOverviewContent({
|
|
|
50
53
|
{ icon: /* @__PURE__ */ jsx(Percent, { className: "h-4 w-4" }), label: "Royalty", value: royalty }
|
|
51
54
|
].filter((row) => !!row.value);
|
|
52
55
|
return /* @__PURE__ */ jsxs("div", { className: "mt-4 space-y-7", children: [
|
|
56
|
+
content ? /* @__PURE__ */ jsxs("section", { className: "space-y-3", children: [
|
|
57
|
+
/* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold text-muted-foreground", children: "Content" }),
|
|
58
|
+
/* @__PURE__ */ jsx(MarkdownText, { text: content })
|
|
59
|
+
] }) : null,
|
|
60
|
+
link ? /* @__PURE__ */ jsxs("a", { href: link, target: "_blank", rel: "noopener noreferrer", className: "inline-flex items-center gap-1.5 text-sm text-primary hover:underline", children: [
|
|
61
|
+
/* @__PURE__ */ jsx(ExternalLink, { className: "h-3.5 w-3.5" }),
|
|
62
|
+
"Open link"
|
|
63
|
+
] }) : null,
|
|
53
64
|
hasTemplateData ? /* @__PURE__ */ jsx(IPTypeDisplay, { attributes }) : null,
|
|
54
65
|
hasLicenseData ? /* @__PURE__ */ jsxs("section", { className: "space-y-3", children: [
|
|
55
66
|
/* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold text-muted-foreground", children: "Rights" }),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/asset-overview-content.tsx"],"sourcesContent":["\"use client\";\n\nimport type { ReactNode } from \"react\";\nimport { Bot, DollarSign, GitBranch, Globe, Percent, UserCheck } from \"lucide-react\";\nimport { IPTypeDisplay } from \"./ip-type-display.js\";\nimport { AddressDisplay } from \"./address-display.js\";\nimport { licenseSummary } from \"../utils/license-summary.js\";\n\ninterface AssetAttribute {\n trait_type?: string;\n value?: string;\n}\n\ninterface AssetOverviewContentProps {\n attributes: AssetAttribute[];\n hasTemplateData: boolean;\n isDisplayAttr: (attribute: AssetAttribute) => boolean;\n}\n\nconst isAddressLike = (v?: unknown): boolean =>\n typeof v === \"string\" && /^0x[0-9a-fA-F]{16,}$/.test(v.trim());\n\nfunction Cell({\n icon,\n label,\n value,\n wide,\n}: {\n icon?: ReactNode;\n label: string;\n value: ReactNode;\n wide?: boolean;\n}) {\n return (\n <div\n className={`flex flex-col justify-between gap-2 rounded-xl bg-muted/25 ring-1 ring-border/40 p-3.5 ${\n wide ? \"col-span-2\" : \"\"\n }`}\n >\n {icon ? <span className=\"text-primary/70\">{icon}</span> : null}\n <div className=\"space-y-0.5\">\n <p className=\"text-2xs font-medium text-muted-foreground truncate\" title={label}>\n {label}\n </p>\n <div className=\"text-sm font-bold text-foreground truncate\">{value}</div>\n </div>\n </div>\n );\n}\n\nexport function AssetOverviewContent({\n attributes,\n hasTemplateData,\n isDisplayAttr,\n}: AssetOverviewContentProps) {\n const attr = (trait: string) => attributes.find((attribute) => attribute.trait_type === trait)?.value;\n const licenseType = attr(\"License\");\n const commercialUse = attr(\"Commercial Use\");\n const derivatives = attr(\"Derivatives\");\n const attribution = attr(\"Attribution\");\n const territory = attr(\"Territory\");\n const aiPolicy = attr(\"AI Policy\");\n const royalty = attr(\"Royalty\");\n const summary = licenseSummary(attributes);\n const hasLicenseData = !!(licenseType || commercialUse || derivatives || attribution);\n const displayAttributes = attributes.filter((attribute) => isDisplayAttr(attribute));\n\n const facts = [\n { icon: <DollarSign className=\"h-4 w-4\" />, label: \"Commercial use\", value: commercialUse },\n { icon: <GitBranch className=\"h-4 w-4\" />, label: \"Derivatives\", value: derivatives },\n { icon: <UserCheck className=\"h-4 w-4\" />, label: \"Attribution\", value: attribution },\n { icon: <Globe className=\"h-4 w-4\" />, label: \"Territory\", value: territory },\n { icon: <Bot className=\"h-4 w-4\" />, label: \"AI & data mining\", value: aiPolicy },\n { icon: <Percent className=\"h-4 w-4\" />, label: \"Royalty\", value: royalty },\n ].filter((row) => !!row.value);\n\n return (\n <div className=\"mt-4 space-y-7\">\n {hasTemplateData ? <IPTypeDisplay attributes={attributes} /> : null}\n\n {hasLicenseData ? (\n <section className=\"space-y-3\">\n <h3 className=\"text-sm font-semibold text-muted-foreground\">Rights</h3>\n <div className=\"relative\">\n\n <div className=\"relative grid grid-cols-2 sm:grid-cols-4 gap-3 [grid-auto-flow:dense] auto-rows-[minmax(6rem,auto)]\">\n\n <div className=\"col-span-2 sm:row-span-2 flex flex-col justify-between gap-4 rounded-2xl bg-gradient-to-br from-primary/10 via-primary/5 to-accent/10 ring-1 ring-primary/15 p-5\">\n {licenseType ? (\n <span className=\"pill-badge self-start text-2xs\">{licenseType}</span>\n ) : null}\n {summary ? (\n <p className=\"text-base sm:text-lg font-semibold leading-snug text-foreground\">{summary}</p>\n ) : null}\n </div>\n\n {facts.map(({ icon, label, value }) => (\n <Cell key={label} icon={icon} label={label} value={value} />\n ))}\n </div>\n </div>\n <p className=\"text-xs text-muted-foreground/70\">\n Kept in permanent, tamper-proof storage · recognized under international copyright law\n </p>\n </section>\n ) : null}\n\n {displayAttributes.length > 0 ? (\n <section className=\"space-y-3\">\n <h3 className=\"text-sm font-semibold text-muted-foreground\">Details</h3>\n <div className=\"grid grid-cols-2 sm:grid-cols-4 gap-3 [grid-auto-flow:dense] auto-rows-[minmax(6rem,auto)]\">\n {displayAttributes.map((attribute, index) => (\n <Cell\n key={index}\n label={attribute.trait_type ?? \"Trait\"}\n wide={isAddressLike(attribute.value)}\n value={\n isAddressLike(attribute.value) ? (\n <AddressDisplay address={attribute.value!} chars={4} className=\"text-sm font-bold\" />\n ) : (\n attribute.value ?? \"—\"\n )\n }\n />\n ))}\n </div>\n </section>\n ) : null}\n\n {!hasTemplateData && !hasLicenseData && displayAttributes.length === 0 ? (\n <p className=\"text-sm text-muted-foreground\">No additional details available.</p>\n ) : null}\n </div>\n );\n}\n"],"mappings":";
|
|
1
|
+
{"version":3,"sources":["../../src/components/asset-overview-content.tsx"],"sourcesContent":["\"use client\";\n\nimport type { ReactNode } from \"react\";\nimport { Bot, DollarSign, ExternalLink, GitBranch, Globe, Percent, UserCheck } from \"lucide-react\";\nimport { IPTypeDisplay } from \"./ip-type-display.js\";\nimport { AddressDisplay } from \"./address-display.js\";\nimport { MarkdownText } from \"./markdown-text.js\";\nimport { licenseSummary } from \"../utils/license-summary.js\";\n\ninterface AssetAttribute {\n trait_type?: string;\n value?: string;\n}\n\ninterface AssetOverviewContentProps {\n attributes: AssetAttribute[];\n hasTemplateData: boolean;\n isDisplayAttr: (attribute: AssetAttribute) => boolean;\n content?: string | null;\n link?: string | null;\n}\n\nconst isAddressLike = (v?: unknown): boolean =>\n typeof v === \"string\" && /^0x[0-9a-fA-F]{16,}$/.test(v.trim());\n\nfunction Cell({\n icon,\n label,\n value,\n wide,\n}: {\n icon?: ReactNode;\n label: string;\n value: ReactNode;\n wide?: boolean;\n}) {\n return (\n <div\n className={`flex flex-col justify-between gap-2 rounded-xl bg-muted/25 ring-1 ring-border/40 p-3.5 ${\n wide ? \"col-span-2\" : \"\"\n }`}\n >\n {icon ? <span className=\"text-primary/70\">{icon}</span> : null}\n <div className=\"space-y-0.5\">\n <p className=\"text-2xs font-medium text-muted-foreground truncate\" title={label}>\n {label}\n </p>\n <div className=\"text-sm font-bold text-foreground truncate\">{value}</div>\n </div>\n </div>\n );\n}\n\nexport function AssetOverviewContent({\n attributes,\n hasTemplateData,\n isDisplayAttr,\n content,\n link,\n}: AssetOverviewContentProps) {\n const attr = (trait: string) => attributes.find((attribute) => attribute.trait_type === trait)?.value;\n const licenseType = attr(\"License\");\n const commercialUse = attr(\"Commercial Use\");\n const derivatives = attr(\"Derivatives\");\n const attribution = attr(\"Attribution\");\n const territory = attr(\"Territory\");\n const aiPolicy = attr(\"AI Policy\");\n const royalty = attr(\"Royalty\");\n const summary = licenseSummary(attributes);\n const hasLicenseData = !!(licenseType || commercialUse || derivatives || attribution);\n const displayAttributes = attributes.filter((attribute) => isDisplayAttr(attribute));\n\n const facts = [\n { icon: <DollarSign className=\"h-4 w-4\" />, label: \"Commercial use\", value: commercialUse },\n { icon: <GitBranch className=\"h-4 w-4\" />, label: \"Derivatives\", value: derivatives },\n { icon: <UserCheck className=\"h-4 w-4\" />, label: \"Attribution\", value: attribution },\n { icon: <Globe className=\"h-4 w-4\" />, label: \"Territory\", value: territory },\n { icon: <Bot className=\"h-4 w-4\" />, label: \"AI & data mining\", value: aiPolicy },\n { icon: <Percent className=\"h-4 w-4\" />, label: \"Royalty\", value: royalty },\n ].filter((row) => !!row.value);\n\n return (\n <div className=\"mt-4 space-y-7\">\n {content ? (\n <section className=\"space-y-3\">\n <h3 className=\"text-sm font-semibold text-muted-foreground\">Content</h3>\n <MarkdownText text={content} />\n </section>\n ) : null}\n\n {link ? (\n <a href={link} target=\"_blank\" rel=\"noopener noreferrer\" className=\"inline-flex items-center gap-1.5 text-sm text-primary hover:underline\">\n <ExternalLink className=\"h-3.5 w-3.5\" />\n Open link\n </a>\n ) : null}\n\n {hasTemplateData ? <IPTypeDisplay attributes={attributes} /> : null}\n\n {hasLicenseData ? (\n <section className=\"space-y-3\">\n <h3 className=\"text-sm font-semibold text-muted-foreground\">Rights</h3>\n <div className=\"relative\">\n\n <div className=\"relative grid grid-cols-2 sm:grid-cols-4 gap-3 [grid-auto-flow:dense] auto-rows-[minmax(6rem,auto)]\">\n\n <div className=\"col-span-2 sm:row-span-2 flex flex-col justify-between gap-4 rounded-2xl bg-gradient-to-br from-primary/10 via-primary/5 to-accent/10 ring-1 ring-primary/15 p-5\">\n {licenseType ? (\n <span className=\"pill-badge self-start text-2xs\">{licenseType}</span>\n ) : null}\n {summary ? (\n <p className=\"text-base sm:text-lg font-semibold leading-snug text-foreground\">{summary}</p>\n ) : null}\n </div>\n\n {facts.map(({ icon, label, value }) => (\n <Cell key={label} icon={icon} label={label} value={value} />\n ))}\n </div>\n </div>\n <p className=\"text-xs text-muted-foreground/70\">\n Kept in permanent, tamper-proof storage · recognized under international copyright law\n </p>\n </section>\n ) : null}\n\n {displayAttributes.length > 0 ? (\n <section className=\"space-y-3\">\n <h3 className=\"text-sm font-semibold text-muted-foreground\">Details</h3>\n <div className=\"grid grid-cols-2 sm:grid-cols-4 gap-3 [grid-auto-flow:dense] auto-rows-[minmax(6rem,auto)]\">\n {displayAttributes.map((attribute, index) => (\n <Cell\n key={index}\n label={attribute.trait_type ?? \"Trait\"}\n wide={isAddressLike(attribute.value)}\n value={\n isAddressLike(attribute.value) ? (\n <AddressDisplay address={attribute.value!} chars={4} className=\"text-sm font-bold\" />\n ) : (\n attribute.value ?? \"—\"\n )\n }\n />\n ))}\n </div>\n </section>\n ) : null}\n\n {!hasTemplateData && !hasLicenseData && displayAttributes.length === 0 ? (\n <p className=\"text-sm text-muted-foreground\">No additional details available.</p>\n ) : null}\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -63,6 +63,7 @@ var import_use_comments = require("../utils/use-comments.js");
|
|
|
63
63
|
var import_use_full_token_data = require("../utils/use-full-token-data.js");
|
|
64
64
|
var import_asset_market_state = require("../utils/asset-market-state.js");
|
|
65
65
|
var import_asset_attributes = require("../utils/asset-attributes.js");
|
|
66
|
+
var import_external_link = require("../utils/external-link.js");
|
|
66
67
|
var import_asset_accents = require("../utils/asset-accents.js");
|
|
67
68
|
var import_living_render_collections = require("../data/living-render-collections.js");
|
|
68
69
|
var import_explorer_url = require("../utils/explorer-url.js");
|
|
@@ -171,12 +172,14 @@ function AssetPageView({
|
|
|
171
172
|
const marketCount = market.activeListings.length + market.activeBids.length;
|
|
172
173
|
const { Panel } = config;
|
|
173
174
|
const postContent = traitText(attributes, "Content");
|
|
174
|
-
const
|
|
175
|
+
const description = token.metadata?.description?.trim() || null;
|
|
175
176
|
const video = (token.metadata?.ipType ?? "").toLowerCase() === "video" ? (0, import_asset_video.videoEmbed)(attributes) : null;
|
|
176
177
|
const audio = (token.metadata?.ipType ?? "").toLowerCase() === "audio" ? (0, import_asset_audio.audioEmbed)(attributes) : null;
|
|
177
|
-
const isPublication = !!
|
|
178
|
+
const isPublication = !!description && PUBLICATION_TYPES.has((token.metadata?.ipType ?? "").toLowerCase());
|
|
178
179
|
const publisherName = collection?.name ?? contract.slice(0, 8) + "\u2026";
|
|
179
|
-
const
|
|
180
|
+
const overviewAttributes = postContent ? attributes.filter((a) => a.trait_type !== "Content") : attributes;
|
|
181
|
+
const overview = video || audio ? (0, import_asset_attributes.assetAttributes)(overviewAttributes.filter((a) => !import_asset_video.VIDEO_EMBED_TRAITS.has(a.trait_type ?? "") && !import_asset_audio.AUDIO_EMBED_TRAITS.has(a.trait_type ?? ""))) : { attributes: overviewAttributes, hasTemplateData, isDisplayAttr };
|
|
182
|
+
const overviewLink = isPublication || video || audio ? null : (0, import_external_link.externalLink)(token.metadata?.externalUrl);
|
|
180
183
|
const marketBlock = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
181
184
|
Panel ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Panel, { contract, tokenId, quantityOwned: market.quantityOwned }) : null,
|
|
182
185
|
config.market ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
@@ -323,7 +326,7 @@ function AssetPageView({
|
|
|
323
326
|
import_asset_publication.AssetPublication,
|
|
324
327
|
{
|
|
325
328
|
name,
|
|
326
|
-
text:
|
|
329
|
+
text: description,
|
|
327
330
|
image,
|
|
328
331
|
imgError,
|
|
329
332
|
onImageError: () => setImgError(true),
|
|
@@ -365,7 +368,6 @@ function AssetPageView({
|
|
|
365
368
|
{
|
|
366
369
|
name,
|
|
367
370
|
description: token.metadata?.description,
|
|
368
|
-
externalUrl: token.metadata?.externalUrl,
|
|
369
371
|
ipType: token.metadata?.ipType,
|
|
370
372
|
parentContract,
|
|
371
373
|
parentTokenId,
|
|
@@ -393,7 +395,7 @@ function AssetPageView({
|
|
|
393
395
|
history.length > 0 && `(${history.length})`
|
|
394
396
|
] })
|
|
395
397
|
] }),
|
|
396
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_tabs.TabsContent, { value: "overview", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_asset_overview_content.AssetOverviewContent, { attributes: overview.attributes, hasTemplateData: overview.hasTemplateData, isDisplayAttr: overview.isDisplayAttr }) }),
|
|
398
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_tabs.TabsContent, { value: "overview", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_asset_overview_content.AssetOverviewContent, { attributes: overview.attributes, hasTemplateData: overview.hasTemplateData, isDisplayAttr: overview.isDisplayAttr, content: postContent, link: overviewLink }) }),
|
|
397
399
|
config.market ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_tabs.TabsContent, { value: "markets", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
398
400
|
import_asset_markets_tab.AssetMarketsTab,
|
|
399
401
|
{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/asset-page.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useRef, useState, type ComponentType, type ReactNode } from \"react\";\nimport { motion, useReducedMotion } from \"framer-motion\";\nimport { Award } from \"lucide-react\";\nimport { assetHref, collectionHref, getDerivativesTerm, getService, resolveRemixPolicy, type ApiActivity, type ApiCollection, type ApiOrder, type ApiToken, type Chain } from \"@medialane/sdk\";\nimport { useRouter } from \"./router.js\";\nimport { PageContainer } from \"./page-container.js\";\nimport { PageBackdrop } from \"./media-header.js\";\nimport { AssetHeaderBlock, AssetMediaColumn, AssetOwnerRow } from \"./asset-top-sections.js\";\nimport { AssetPublication } from \"./asset-publication.js\";\nimport { IpTypeBadge } from \"./ip-type-badge.js\";\nimport { AssetRelatedList, AssetVideo, VIDEO_EMBED_TRAITS, videoEmbed } from \"./asset-video.js\";\nimport { AssetAudio, AUDIO_EMBED_TRAITS, audioEmbed } from \"./asset-audio.js\";\nimport { AssetUtilityIcons } from \"./asset-utility-icons.js\";\nimport { AssetMarketplacePanel } from \"./asset-marketplace-panel.js\";\nimport { AssetOwnersPanel } from \"./asset-owners-panel.js\";\nimport { AssetCollectionBar } from \"./asset-collection-bar.js\";\nimport { AssetOverviewContent } from \"./asset-overview-content.js\";\nimport { AssetMarketsTab } from \"./asset-markets-tab.js\";\nimport { AssetProvenanceTab } from \"./asset-provenance-tab.js\";\nimport { AssetLightbox } from \"./asset-lightbox.js\";\nimport { AssetUnavailable } from \"./asset-unavailable.js\";\nimport { HiddenContentBanner } from \"./hidden-content-banner.js\";\nimport { DropTokenLink } from \"./drop/drop-token-link.js\";\nimport { FloatingCommentsButton } from \"./floating-comments-button.js\";\nimport { AssetCommentsDialog } from \"./asset-comments-dialog.js\";\nimport { PopBurnButton } from \"./pop-burn-button.js\";\nimport { MembershipPanel, TicketPanel, type AssetTypePanelProps } from \"./asset-type-panels.js\";\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from \"./tabs.js\";\nimport { Skeleton } from \"./skeleton.js\";\nimport { useMedialaneApp } from \"./medialane-app.js\";\nimport { useToken, useTokenBalance, useTokenHistory } from \"../utils/use-tokens.js\";\nimport { useCollection, useNearbyCollectionTokens } from \"../utils/use-collections.js\";\nimport { useTokenListings } from \"../utils/use-orders.js\";\nimport { useTokenRemixes } from \"../utils/use-remix-offers.js\";\nimport { useComments } from \"../utils/use-comments.js\";\nimport { useFullTokenData } from \"../utils/use-full-token-data.js\";\nimport { useAssetMarketState } from \"../utils/asset-market-state.js\";\nimport { assetAttributes } from \"../utils/asset-attributes.js\";\nimport { ASSET_ACCENTS } from \"../utils/asset-accents.js\";\nimport { isLivingRenderCollection } from \"../data/living-render-collections.js\";\nimport { EXPLORER_URL } from \"../utils/explorer-url.js\";\nimport { profileHref } from \"@medialane/sdk\";\nimport { useImageUrl } from \"../utils/use-image-url.js\";\n\nexport type AssetKind = \"standard\" | \"edition\" | \"ticket\" | \"membership\" | \"pop\";\n\nexport interface AssetMarketContext {\n contract: string;\n tokenId: string;\n tokenName: string;\n tokenImage: string | null;\n tokenStandard: \"ERC721\" | \"ERC1155\" | \"UNKNOWN\";\n activeListings: ApiOrder[];\n quantityOwned?: string;\n mutateListings: () => void;\n}\n\nexport interface AssetMarketActions {\n isProcessing: boolean;\n buy: (order: ApiOrder) => void;\n list: () => void;\n offer: () => void;\n transfer: () => void;\n cancel: (order: ApiOrder) => void;\n acceptBid: (order: ApiOrder) => void;\n dialogs: ReactNode;\n}\n\ninterface KindConfig {\n namePrefix: string;\n accents: (typeof ASSET_ACCENTS)[keyof typeof ASSET_ACCENTS];\n market: boolean;\n remix: boolean;\n Panel?: ComponentType<AssetTypePanelProps>;\n}\n\nconst KINDS: Record<AssetKind, KindConfig> = {\n standard: { namePrefix: \"Token\", accents: ASSET_ACCENTS.standard, market: true, remix: true },\n edition: { namePrefix: \"Edition\", accents: ASSET_ACCENTS.edition, market: true, remix: false },\n ticket: { namePrefix: \"Ticket\", accents: ASSET_ACCENTS.ticket, market: true, remix: false, Panel: TicketPanel },\n membership: { namePrefix: \"Membership\", accents: ASSET_ACCENTS.membership, market: true, remix: false, Panel: MembershipPanel },\n pop: { namePrefix: \"POP\", accents: ASSET_ACCENTS.standard, market: false, remix: false },\n};\n\nconst PUBLICATION_TYPES = new Set([\"publications\", \"posts\"]);\n\ntype TraitList = { trait_type?: string | null; value?: string | number | boolean | null }[];\n\nfunction traitText(attributes: TraitList, trait: string): string | null {\n const value = attributes.find((a) => a.trait_type === trait)?.value;\n return typeof value === \"string\" && value.trim() !== \"\" ? value.trim() : null;\n}\n\nfunction publicationAuthor(attributes: TraitList, metadataAuthor?: string | null): string | null {\n return traitText(attributes, \"Author\") ?? metadataAuthor ?? traitText(attributes, \"Creator\");\n}\n\nconst VARIANT_KINDS: Partial<Record<string, AssetKind>> = { edition: \"edition\", ticket: \"ticket\", club: \"membership\", pop: \"pop\" };\n\nexport function detectAssetKind(service: string | null | undefined, standard: string | null | undefined): AssetKind {\n const variant = getService(service)?.uiVariant;\n if (variant) return VARIANT_KINDS[variant] ?? \"standard\";\n return standard === \"ERC1155\" ? \"edition\" : \"standard\";\n}\n\nexport function AssetPageSkeleton() {\n return (\n <PageContainer className=\"pt-20 pb-8\">\n <div className=\"grid grid-cols-1 lg:grid-cols-2 lg:gap-10 gap-6 items-start\">\n <Skeleton className=\"aspect-square w-full rounded-3xl\" />\n <div className=\"space-y-6\">\n <div className=\"space-y-3\">\n <Skeleton className=\"h-5 w-24 rounded-full\" />\n <Skeleton className=\"h-9 w-3/4\" />\n <Skeleton className=\"h-4 w-full\" />\n <Skeleton className=\"h-4 w-2/3\" />\n </div>\n <Skeleton className=\"h-[54px] w-full rounded-2xl\" />\n <div className=\"flex gap-2\">\n {Array.from({ length: 3 }).map((_, i) => <Skeleton key={i} className=\"h-[46px] flex-1 rounded-[13px]\" />)}\n </div>\n <Skeleton className=\"h-16 w-full rounded-2xl\" />\n </div>\n </div>\n </PageContainer>\n );\n}\n\nexport interface AssetPageProps {\n contract: string;\n tokenId: string;\n useMarketActions: (context: AssetMarketContext) => AssetMarketActions;\n}\n\nexport function AssetPage({ contract, tokenId, useMarketActions }: AssetPageProps) {\n const { token, isLoading, isIndexing } = useToken(contract, tokenId);\n const { collection, isLoading: collectionLoading } = useCollection(contract);\n if (isLoading || collectionLoading) return <AssetPageSkeleton />;\n if (!token) return <AssetUnavailable isIndexing={isIndexing} />;\n const kind = detectAssetKind(collection?.service, collection?.standard ?? token.standard);\n return <AssetPageView contract={contract} tokenId={tokenId} token={token} collection={collection ?? null} kind={kind} useMarketActions={useMarketActions} />;\n}\n\nfunction AssetPageView({\n contract,\n tokenId,\n token,\n collection,\n kind,\n useMarketActions,\n}: {\n contract: string;\n tokenId: string;\n token: ApiToken & { isHidden?: boolean };\n collection: ApiCollection | null;\n kind: AssetKind;\n useMarketActions: AssetPageProps[\"useMarketActions\"];\n}) {\n const resolveImage = useImageUrl();\n const config = KINDS[kind];\n const router = useRouter();\n const shouldReduce = useReducedMotion();\n const { walletAddress, ReportDialog } = useMedialaneApp();\n\n const { listings, mutate: mutateListings, isLoading: listingsLoading } = useTokenListings(contract, tokenId);\n const { history } = useTokenHistory(contract, tokenId);\n const { tokens: collectionTokens } = useNearbyCollectionTokens(contract, tokenId);\n const { total: commentTotal } = useComments(contract, tokenId);\n const { total: remixCount } = useTokenRemixes(contract, tokenId);\n const { data: fullTokenData } = useFullTokenData(contract, tokenId);\n const { amount: walletBalance } = useTokenBalance(contract, tokenId, walletAddress);\n const market = useAssetMarketState({ token, collection, listings, history: history as ApiActivity[], walletAddress, walletBalance });\n\n const [reportOpen, setReportOpen] = useState(false);\n const [commentOpen, setCommentOpen] = useState(false);\n const [lightboxOpen, setLightboxOpen] = useState(false);\n const [imgError, setImgError] = useState(false);\n\n const name = token.metadata?.name || `${config.namePrefix} #${token.tokenId}`;\n const image = resolveImage(token.metadata?.image);\n const tokenStandard = kind === \"standard\" || kind === \"pop\"\n ? ((token.standard ?? collection?.standard ?? \"UNKNOWN\") as AssetMarketContext[\"tokenStandard\"])\n : \"ERC1155\";\n\n const actions = useMarketActions({\n contract,\n tokenId,\n tokenName: name,\n tokenImage: image,\n tokenStandard,\n activeListings: market.activeListings,\n quantityOwned: market.quantityOwned,\n mutateListings,\n });\n\n const autoActionRef = useRef(false);\n useEffect(() => {\n if (autoActionRef.current || !config.market || !market.isOwner) return;\n const action = new URLSearchParams(window.location.search).get(\"action\");\n if (action === \"list\") actions.list();\n else if (action === \"transfer\") actions.transfer();\n else return;\n autoActionRef.current = true;\n }, [config.market, market.isOwner, actions]);\n\n const { attributes, hasTemplateData, isDisplayAttr, parentContract, parentTokenId } = assetAttributes(token.metadata?.attributes);\n const remixPolicy = resolveRemixPolicy({\n parentNoDerivatives: getDerivativesTerm(token.metadata?.attributes) === \"Not Allowed\",\n viewerIsParentOwner: market.isOwner,\n dealAvailable: !!getService(collection?.service),\n });\n const holders = token.balances ?? [];\n const ownerAddress = !market.isERC1155 ? (holders[0]?.owner ?? token.owner ?? null) : null;\n const marketCount = market.activeListings.length + market.activeBids.length;\n const { Panel } = config;\n\n const postContent = traitText(attributes, \"Content\");\n const articleText = postContent ?? (token.metadata?.description?.trim() || null);\n const video = (token.metadata?.ipType ?? \"\").toLowerCase() === \"video\" ? videoEmbed(attributes) : null;\n const audio = (token.metadata?.ipType ?? \"\").toLowerCase() === \"audio\" ? audioEmbed(attributes) : null;\n const isPublication = !!articleText && PUBLICATION_TYPES.has((token.metadata?.ipType ?? \"\").toLowerCase());\n const publisherName = collection?.name ?? contract.slice(0, 8) + \"…\";\n const overview = isPublication\n ? { attributes, hasTemplateData, isDisplayAttr: (a: Parameters<typeof isDisplayAttr>[0]) => isDisplayAttr(a) && !(postContent && a.trait_type === \"Content\") }\n : video || audio\n ? assetAttributes(attributes.filter((a) => !VIDEO_EMBED_TRAITS.has(a.trait_type ?? \"\") && !AUDIO_EMBED_TRAITS.has(a.trait_type ?? \"\")))\n : { attributes, hasTemplateData, isDisplayAttr };\n\n const marketBlock = (\n <>\n {Panel ? <Panel contract={contract} tokenId={tokenId} quantityOwned={market.quantityOwned} /> : null}\n\n {config.market ? (\n <AssetMarketplacePanel\n asset={token}\n compact={isPublication || !!video || !!audio}\n cheapest={market.cheapest}\n usdValue={market.cheapestUsd}\n isOwner={market.isOwner}\n isProcessing={actions.isProcessing}\n isERC1155={market.isERC1155}\n canListMoreEditions={market.canListMoreEditions}\n isMarketLoading={listingsLoading}\n myListing={market.myListing}\n activeBids={market.activeBids}\n remixEnabled={config.remix && remixPolicy.canRemixDirect}\n showDealOption={config.remix && remixPolicy.showDealOption}\n onCancelClick={actions.cancel}\n onAcceptBid={actions.acceptBid}\n onOpenListing={actions.list}\n onOpenTransfer={actions.transfer}\n onOpenPurchase={actions.buy}\n onOpenOffer={actions.offer}\n onOpenRemix={() => router.push(`/create/remix/${contract}/${tokenId}`)}\n />\n ) : null}\n\n {kind === \"pop\" && market.isOwner ? <PopBurnButton collectionAddress={contract} tokenId={tokenId} /> : null}\n\n {market.isERC1155 && holders.length > 0 ? (\n <AssetOwnersPanel balances={holders} total={token.holderCount} editions={Number(token.supply ?? 0)} />\n ) : null}\n </>\n );\n\n const detailsBlock = (\n <div className=\"pt-5 space-y-5\">\n {ownerAddress ? <AssetOwnerRow ownerAddress={ownerAddress} ownerHref={profileHref({ address: ownerAddress })} /> : null}\n {collection?.service === \"drop-collection\" ? <DropTokenLink contract={contract} name={collection.name ?? null} /> : null}\n <AssetCollectionBar\n collectionName={publisherName}\n collectionImage={resolveImage(collection?.image)}\n collectionHref={collectionHref(\"STARKNET\", contract)}\n currentTokenId={tokenId}\n siblingTokens={collectionTokens.map((t) => ({\n tokenId: t.tokenId,\n image: resolveImage(t.metadata?.image),\n }))}\n onNavigate={(id) => router.push(assetHref(\"STARKNET\", contract, id))}\n floorPriceRaw={collection?.floorPrice}\n />\n <div className=\"-ml-3\">\n <AssetUtilityIcons\n contractExplorerHref={`${EXPLORER_URL}/contract/${token.contractAddress}`}\n shareTitle={name}\n onReportClick={() => setReportOpen(true)}\n />\n </div>\n </div>\n );\n\n return (\n <div className=\"relative z-0 min-h-screen\">\n {token.isHidden ? <HiddenContentBanner /> : null}\n <PageBackdrop image={image} />\n\n <PageContainer className={isPublication ? \"pt-20 space-y-8 pb-8 lg:px-16 xl:px-24\" : \"pt-20 space-y-8 pb-8\"}>\n {video ? (\n <div className=\"grid grid-cols-1 lg:grid-cols-[minmax(0,2fr)_minmax(0,1fr)] lg:gap-12 gap-8 items-start\">\n <AssetVideo\n name={name}\n embedSrc={video.src}\n embedLabel={video.label}\n description={token.metadata?.description}\n collectionName={publisherName}\n collectionImage={resolveImage(collection?.image)}\n collectionHref={collectionHref(\"STARKNET\", contract)}\n utilities={\n <AssetUtilityIcons\n contractExplorerHref={`${EXPLORER_URL}/contract/${token.contractAddress}`}\n shareTitle={name}\n onReportClick={() => setReportOpen(true)}\n />\n }\n />\n <aside className=\"space-y-6 min-w-0\">\n <IpTypeBadge ipType={token.metadata?.ipType ?? \"Video\"} size=\"md\" showLabel />\n {marketBlock}\n {ownerAddress ? <AssetOwnerRow ownerAddress={ownerAddress} ownerHref={profileHref({ address: ownerAddress })} /> : null}\n <AssetRelatedList\n title={publisherName}\n titleHref={collectionHref(\"STARKNET\", contract)}\n items={collectionTokens\n .filter((t) => String(t.tokenId) !== String(tokenId))\n .map((t) => ({\n tokenId: t.tokenId,\n name: t.metadata?.name || `${config.namePrefix} #${t.tokenId}`,\n image: resolveImage(t.metadata?.image),\n href: assetHref(\"STARKNET\", contract, t.tokenId),\n }))}\n />\n </aside>\n </div>\n ) : audio ? (\n <div className=\"grid grid-cols-1 lg:grid-cols-[minmax(0,2fr)_minmax(0,1fr)] lg:gap-12 gap-8 items-start\">\n <AssetAudio\n name={name}\n image={image}\n embedSrc={audio.src}\n embedLabel={audio.label}\n description={token.metadata?.description}\n collectionName={publisherName}\n collectionImage={resolveImage(collection?.image)}\n collectionHref={collectionHref(\"STARKNET\", contract)}\n utilities={\n <AssetUtilityIcons\n contractExplorerHref={`${EXPLORER_URL}/contract/${token.contractAddress}`}\n shareTitle={name}\n onReportClick={() => setReportOpen(true)}\n />\n }\n />\n <aside className=\"space-y-6 min-w-0\">\n <IpTypeBadge ipType={token.metadata?.ipType ?? \"Audio\"} size=\"md\" showLabel />\n {marketBlock}\n {ownerAddress ? <AssetOwnerRow ownerAddress={ownerAddress} ownerHref={profileHref({ address: ownerAddress })} /> : null}\n <AssetRelatedList\n title={publisherName}\n titleHref={collectionHref(\"STARKNET\", contract)}\n shape=\"square\"\n items={collectionTokens\n .filter((t) => String(t.tokenId) !== String(tokenId))\n .map((t) => ({\n tokenId: t.tokenId,\n name: t.metadata?.name || `${config.namePrefix} #${t.tokenId}`,\n image: resolveImage(t.metadata?.image),\n href: assetHref(\"STARKNET\", contract, t.tokenId),\n }))}\n />\n </aside>\n </div>\n ) : isPublication ? (\n <div className=\"grid grid-cols-1 lg:grid-cols-[minmax(0,2fr)_minmax(0,1fr)] lg:gap-20 gap-8 items-start\">\n <AssetPublication\n name={name}\n text={articleText!}\n image={image}\n imgError={imgError}\n onImageError={() => setImgError(true)}\n onZoom={() => setLightboxOpen(true)}\n author={publicationAuthor(attributes, token.metadata?.author)}\n externalUrl={token.metadata?.externalUrl}\n />\n <aside className=\"space-y-6 min-w-0 lg:sticky lg:top-16\">\n <IpTypeBadge ipType={token.metadata?.ipType ?? \"Publications\"} size=\"md\" showLabel />\n {marketBlock}\n {detailsBlock}\n </aside>\n </div>\n ) : (\n <div className=\"grid grid-cols-1 lg:grid-cols-2 lg:gap-10 gap-8 items-start\">\n <AssetMediaColumn\n shouldReduce={Boolean(shouldReduce)}\n image={image}\n imageAlt={name}\n imgError={imgError}\n onImageError={() => setImgError(true)}\n onZoom={() => setLightboxOpen(true)}\n animationUrl={token.metadata?.animationUrl}\n live={isLivingRenderCollection(token.chain as Chain, token.contractAddress)}\n fallback={<div className=\"aspect-square bg-muted\" />}\n />\n\n <motion.div\n initial={shouldReduce ? false : { opacity: 0, y: 16 }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ duration: 0.5, delay: 0.2 }}\n className=\"space-y-6\"\n >\n <AssetHeaderBlock\n name={name}\n description={token.metadata?.description}\n externalUrl={token.metadata?.externalUrl}\n ipType={token.metadata?.ipType}\n parentContract={parentContract}\n parentTokenId={parentTokenId}\n badges={kind === \"pop\" ? (\n <span className=\"inline-flex items-center gap-1 text-2xs font-semibold px-2.5 py-1 rounded-full border border-emerald-500/30 bg-emerald-500/10 text-emerald-500\">\n <Award className=\"h-3 w-3\" />\n POP\n </span>\n ) : null}\n />\n\n {marketBlock}\n\n {detailsBlock}\n </motion.div>\n </div>\n )}\n\n <Tabs defaultValue=\"overview\">\n <TabsList>\n <TabsTrigger value=\"overview\">Overview</TabsTrigger>\n {config.market ? <TabsTrigger value=\"markets\">Markets {marketCount > 0 && `(${marketCount})`}</TabsTrigger> : null}\n <TabsTrigger value=\"provenance\">Provenance {history.length > 0 && `(${history.length})`}</TabsTrigger>\n </TabsList>\n\n <TabsContent value=\"overview\">\n <AssetOverviewContent attributes={overview.attributes} hasTemplateData={overview.hasTemplateData} isDisplayAttr={overview.isDisplayAttr} />\n </TabsContent>\n\n {config.market ? (\n <TabsContent value=\"markets\">\n <AssetMarketsTab\n activeListings={market.activeListings}\n activeBids={market.activeBids}\n walletAddress={walletAddress ?? undefined}\n isOwner={market.isOwner}\n isProcessing={actions.isProcessing}\n onBuyClick={actions.buy}\n onCancelClick={actions.cancel}\n onAcceptClick={actions.acceptBid}\n />\n </TabsContent>\n ) : null}\n\n <TabsContent value=\"provenance\">\n <AssetProvenanceTab\n history={history as ApiActivity[]}\n contract={contract}\n tokenId={tokenId}\n remixCount={remixCount}\n originalCreator={fullTokenData?.originalCreator}\n registeredAt={fullTokenData?.registeredAt}\n />\n </TabsContent>\n </Tabs>\n </PageContainer>\n\n <AssetLightbox open={lightboxOpen} onOpenChange={setLightboxOpen} image={image} alt={name} />\n <FloatingCommentsButton onClick={() => setCommentOpen(true)} commentTotal={commentTotal} />\n <AssetCommentsDialog\n open={commentOpen}\n onOpenChange={setCommentOpen}\n contract={contract}\n tokenId={tokenId}\n name={name}\n imageUrl={image}\n commentTotal={commentTotal}\n {...config.accents}\n />\n {ReportDialog ? <ReportDialog open={reportOpen} onOpenChange={setReportOpen} target={{ type: \"TOKEN\", contract: token.contractAddress, tokenId: token.tokenId, name }} /> : null}\n {actions.dialogs}\n </div>\n );\n}\n"],"mappings":"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","names":["import_sdk"]}
|
|
1
|
+
{"version":3,"sources":["../../src/components/asset-page.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useRef, useState, type ComponentType, type ReactNode } from \"react\";\nimport { motion, useReducedMotion } from \"framer-motion\";\nimport { Award } from \"lucide-react\";\nimport { assetHref, collectionHref, getDerivativesTerm, getService, resolveRemixPolicy, type ApiActivity, type ApiCollection, type ApiOrder, type ApiToken, type Chain } from \"@medialane/sdk\";\nimport { useRouter } from \"./router.js\";\nimport { PageContainer } from \"./page-container.js\";\nimport { PageBackdrop } from \"./media-header.js\";\nimport { AssetHeaderBlock, AssetMediaColumn, AssetOwnerRow } from \"./asset-top-sections.js\";\nimport { AssetPublication } from \"./asset-publication.js\";\nimport { IpTypeBadge } from \"./ip-type-badge.js\";\nimport { AssetRelatedList, AssetVideo, VIDEO_EMBED_TRAITS, videoEmbed } from \"./asset-video.js\";\nimport { AssetAudio, AUDIO_EMBED_TRAITS, audioEmbed } from \"./asset-audio.js\";\nimport { AssetUtilityIcons } from \"./asset-utility-icons.js\";\nimport { AssetMarketplacePanel } from \"./asset-marketplace-panel.js\";\nimport { AssetOwnersPanel } from \"./asset-owners-panel.js\";\nimport { AssetCollectionBar } from \"./asset-collection-bar.js\";\nimport { AssetOverviewContent } from \"./asset-overview-content.js\";\nimport { AssetMarketsTab } from \"./asset-markets-tab.js\";\nimport { AssetProvenanceTab } from \"./asset-provenance-tab.js\";\nimport { AssetLightbox } from \"./asset-lightbox.js\";\nimport { AssetUnavailable } from \"./asset-unavailable.js\";\nimport { HiddenContentBanner } from \"./hidden-content-banner.js\";\nimport { DropTokenLink } from \"./drop/drop-token-link.js\";\nimport { FloatingCommentsButton } from \"./floating-comments-button.js\";\nimport { AssetCommentsDialog } from \"./asset-comments-dialog.js\";\nimport { PopBurnButton } from \"./pop-burn-button.js\";\nimport { MembershipPanel, TicketPanel, type AssetTypePanelProps } from \"./asset-type-panels.js\";\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from \"./tabs.js\";\nimport { Skeleton } from \"./skeleton.js\";\nimport { useMedialaneApp } from \"./medialane-app.js\";\nimport { useToken, useTokenBalance, useTokenHistory } from \"../utils/use-tokens.js\";\nimport { useCollection, useNearbyCollectionTokens } from \"../utils/use-collections.js\";\nimport { useTokenListings } from \"../utils/use-orders.js\";\nimport { useTokenRemixes } from \"../utils/use-remix-offers.js\";\nimport { useComments } from \"../utils/use-comments.js\";\nimport { useFullTokenData } from \"../utils/use-full-token-data.js\";\nimport { useAssetMarketState } from \"../utils/asset-market-state.js\";\nimport { assetAttributes } from \"../utils/asset-attributes.js\";\nimport { externalLink } from \"../utils/external-link.js\";\nimport { ASSET_ACCENTS } from \"../utils/asset-accents.js\";\nimport { isLivingRenderCollection } from \"../data/living-render-collections.js\";\nimport { EXPLORER_URL } from \"../utils/explorer-url.js\";\nimport { profileHref } from \"@medialane/sdk\";\nimport { useImageUrl } from \"../utils/use-image-url.js\";\n\nexport type AssetKind = \"standard\" | \"edition\" | \"ticket\" | \"membership\" | \"pop\";\n\nexport interface AssetMarketContext {\n contract: string;\n tokenId: string;\n tokenName: string;\n tokenImage: string | null;\n tokenStandard: \"ERC721\" | \"ERC1155\" | \"UNKNOWN\";\n activeListings: ApiOrder[];\n quantityOwned?: string;\n mutateListings: () => void;\n}\n\nexport interface AssetMarketActions {\n isProcessing: boolean;\n buy: (order: ApiOrder) => void;\n list: () => void;\n offer: () => void;\n transfer: () => void;\n cancel: (order: ApiOrder) => void;\n acceptBid: (order: ApiOrder) => void;\n dialogs: ReactNode;\n}\n\ninterface KindConfig {\n namePrefix: string;\n accents: (typeof ASSET_ACCENTS)[keyof typeof ASSET_ACCENTS];\n market: boolean;\n remix: boolean;\n Panel?: ComponentType<AssetTypePanelProps>;\n}\n\nconst KINDS: Record<AssetKind, KindConfig> = {\n standard: { namePrefix: \"Token\", accents: ASSET_ACCENTS.standard, market: true, remix: true },\n edition: { namePrefix: \"Edition\", accents: ASSET_ACCENTS.edition, market: true, remix: false },\n ticket: { namePrefix: \"Ticket\", accents: ASSET_ACCENTS.ticket, market: true, remix: false, Panel: TicketPanel },\n membership: { namePrefix: \"Membership\", accents: ASSET_ACCENTS.membership, market: true, remix: false, Panel: MembershipPanel },\n pop: { namePrefix: \"POP\", accents: ASSET_ACCENTS.standard, market: false, remix: false },\n};\n\nconst PUBLICATION_TYPES = new Set([\"publications\", \"posts\"]);\n\ntype TraitList = { trait_type?: string | null; value?: string | number | boolean | null }[];\n\nfunction traitText(attributes: TraitList, trait: string): string | null {\n const value = attributes.find((a) => a.trait_type === trait)?.value;\n return typeof value === \"string\" && value.trim() !== \"\" ? value.trim() : null;\n}\n\nfunction publicationAuthor(attributes: TraitList, metadataAuthor?: string | null): string | null {\n return traitText(attributes, \"Author\") ?? metadataAuthor ?? traitText(attributes, \"Creator\");\n}\n\nconst VARIANT_KINDS: Partial<Record<string, AssetKind>> = { edition: \"edition\", ticket: \"ticket\", club: \"membership\", pop: \"pop\" };\n\nexport function detectAssetKind(service: string | null | undefined, standard: string | null | undefined): AssetKind {\n const variant = getService(service)?.uiVariant;\n if (variant) return VARIANT_KINDS[variant] ?? \"standard\";\n return standard === \"ERC1155\" ? \"edition\" : \"standard\";\n}\n\nexport function AssetPageSkeleton() {\n return (\n <PageContainer className=\"pt-20 pb-8\">\n <div className=\"grid grid-cols-1 lg:grid-cols-2 lg:gap-10 gap-6 items-start\">\n <Skeleton className=\"aspect-square w-full rounded-3xl\" />\n <div className=\"space-y-6\">\n <div className=\"space-y-3\">\n <Skeleton className=\"h-5 w-24 rounded-full\" />\n <Skeleton className=\"h-9 w-3/4\" />\n <Skeleton className=\"h-4 w-full\" />\n <Skeleton className=\"h-4 w-2/3\" />\n </div>\n <Skeleton className=\"h-[54px] w-full rounded-2xl\" />\n <div className=\"flex gap-2\">\n {Array.from({ length: 3 }).map((_, i) => <Skeleton key={i} className=\"h-[46px] flex-1 rounded-[13px]\" />)}\n </div>\n <Skeleton className=\"h-16 w-full rounded-2xl\" />\n </div>\n </div>\n </PageContainer>\n );\n}\n\nexport interface AssetPageProps {\n contract: string;\n tokenId: string;\n useMarketActions: (context: AssetMarketContext) => AssetMarketActions;\n}\n\nexport function AssetPage({ contract, tokenId, useMarketActions }: AssetPageProps) {\n const { token, isLoading, isIndexing } = useToken(contract, tokenId);\n const { collection, isLoading: collectionLoading } = useCollection(contract);\n if (isLoading || collectionLoading) return <AssetPageSkeleton />;\n if (!token) return <AssetUnavailable isIndexing={isIndexing} />;\n const kind = detectAssetKind(collection?.service, collection?.standard ?? token.standard);\n return <AssetPageView contract={contract} tokenId={tokenId} token={token} collection={collection ?? null} kind={kind} useMarketActions={useMarketActions} />;\n}\n\nfunction AssetPageView({\n contract,\n tokenId,\n token,\n collection,\n kind,\n useMarketActions,\n}: {\n contract: string;\n tokenId: string;\n token: ApiToken & { isHidden?: boolean };\n collection: ApiCollection | null;\n kind: AssetKind;\n useMarketActions: AssetPageProps[\"useMarketActions\"];\n}) {\n const resolveImage = useImageUrl();\n const config = KINDS[kind];\n const router = useRouter();\n const shouldReduce = useReducedMotion();\n const { walletAddress, ReportDialog } = useMedialaneApp();\n\n const { listings, mutate: mutateListings, isLoading: listingsLoading } = useTokenListings(contract, tokenId);\n const { history } = useTokenHistory(contract, tokenId);\n const { tokens: collectionTokens } = useNearbyCollectionTokens(contract, tokenId);\n const { total: commentTotal } = useComments(contract, tokenId);\n const { total: remixCount } = useTokenRemixes(contract, tokenId);\n const { data: fullTokenData } = useFullTokenData(contract, tokenId);\n const { amount: walletBalance } = useTokenBalance(contract, tokenId, walletAddress);\n const market = useAssetMarketState({ token, collection, listings, history: history as ApiActivity[], walletAddress, walletBalance });\n\n const [reportOpen, setReportOpen] = useState(false);\n const [commentOpen, setCommentOpen] = useState(false);\n const [lightboxOpen, setLightboxOpen] = useState(false);\n const [imgError, setImgError] = useState(false);\n\n const name = token.metadata?.name || `${config.namePrefix} #${token.tokenId}`;\n const image = resolveImage(token.metadata?.image);\n const tokenStandard = kind === \"standard\" || kind === \"pop\"\n ? ((token.standard ?? collection?.standard ?? \"UNKNOWN\") as AssetMarketContext[\"tokenStandard\"])\n : \"ERC1155\";\n\n const actions = useMarketActions({\n contract,\n tokenId,\n tokenName: name,\n tokenImage: image,\n tokenStandard,\n activeListings: market.activeListings,\n quantityOwned: market.quantityOwned,\n mutateListings,\n });\n\n const autoActionRef = useRef(false);\n useEffect(() => {\n if (autoActionRef.current || !config.market || !market.isOwner) return;\n const action = new URLSearchParams(window.location.search).get(\"action\");\n if (action === \"list\") actions.list();\n else if (action === \"transfer\") actions.transfer();\n else return;\n autoActionRef.current = true;\n }, [config.market, market.isOwner, actions]);\n\n const { attributes, hasTemplateData, isDisplayAttr, parentContract, parentTokenId } = assetAttributes(token.metadata?.attributes);\n const remixPolicy = resolveRemixPolicy({\n parentNoDerivatives: getDerivativesTerm(token.metadata?.attributes) === \"Not Allowed\",\n viewerIsParentOwner: market.isOwner,\n dealAvailable: !!getService(collection?.service),\n });\n const holders = token.balances ?? [];\n const ownerAddress = !market.isERC1155 ? (holders[0]?.owner ?? token.owner ?? null) : null;\n const marketCount = market.activeListings.length + market.activeBids.length;\n const { Panel } = config;\n\n const postContent = traitText(attributes, \"Content\");\n const description = token.metadata?.description?.trim() || null;\n const video = (token.metadata?.ipType ?? \"\").toLowerCase() === \"video\" ? videoEmbed(attributes) : null;\n const audio = (token.metadata?.ipType ?? \"\").toLowerCase() === \"audio\" ? audioEmbed(attributes) : null;\n const isPublication = !!description && PUBLICATION_TYPES.has((token.metadata?.ipType ?? \"\").toLowerCase());\n const publisherName = collection?.name ?? contract.slice(0, 8) + \"…\";\n const overviewAttributes = postContent ? attributes.filter((a) => a.trait_type !== \"Content\") : attributes;\n const overview = video || audio\n ? assetAttributes(overviewAttributes.filter((a) => !VIDEO_EMBED_TRAITS.has(a.trait_type ?? \"\") && !AUDIO_EMBED_TRAITS.has(a.trait_type ?? \"\")))\n : { attributes: overviewAttributes, hasTemplateData, isDisplayAttr };\n const overviewLink = isPublication || video || audio ? null : externalLink(token.metadata?.externalUrl);\n\n const marketBlock = (\n <>\n {Panel ? <Panel contract={contract} tokenId={tokenId} quantityOwned={market.quantityOwned} /> : null}\n\n {config.market ? (\n <AssetMarketplacePanel\n asset={token}\n compact={isPublication || !!video || !!audio}\n cheapest={market.cheapest}\n usdValue={market.cheapestUsd}\n isOwner={market.isOwner}\n isProcessing={actions.isProcessing}\n isERC1155={market.isERC1155}\n canListMoreEditions={market.canListMoreEditions}\n isMarketLoading={listingsLoading}\n myListing={market.myListing}\n activeBids={market.activeBids}\n remixEnabled={config.remix && remixPolicy.canRemixDirect}\n showDealOption={config.remix && remixPolicy.showDealOption}\n onCancelClick={actions.cancel}\n onAcceptBid={actions.acceptBid}\n onOpenListing={actions.list}\n onOpenTransfer={actions.transfer}\n onOpenPurchase={actions.buy}\n onOpenOffer={actions.offer}\n onOpenRemix={() => router.push(`/create/remix/${contract}/${tokenId}`)}\n />\n ) : null}\n\n {kind === \"pop\" && market.isOwner ? <PopBurnButton collectionAddress={contract} tokenId={tokenId} /> : null}\n\n {market.isERC1155 && holders.length > 0 ? (\n <AssetOwnersPanel balances={holders} total={token.holderCount} editions={Number(token.supply ?? 0)} />\n ) : null}\n </>\n );\n\n const detailsBlock = (\n <div className=\"pt-5 space-y-5\">\n {ownerAddress ? <AssetOwnerRow ownerAddress={ownerAddress} ownerHref={profileHref({ address: ownerAddress })} /> : null}\n {collection?.service === \"drop-collection\" ? <DropTokenLink contract={contract} name={collection.name ?? null} /> : null}\n <AssetCollectionBar\n collectionName={publisherName}\n collectionImage={resolveImage(collection?.image)}\n collectionHref={collectionHref(\"STARKNET\", contract)}\n currentTokenId={tokenId}\n siblingTokens={collectionTokens.map((t) => ({\n tokenId: t.tokenId,\n image: resolveImage(t.metadata?.image),\n }))}\n onNavigate={(id) => router.push(assetHref(\"STARKNET\", contract, id))}\n floorPriceRaw={collection?.floorPrice}\n />\n <div className=\"-ml-3\">\n <AssetUtilityIcons\n contractExplorerHref={`${EXPLORER_URL}/contract/${token.contractAddress}`}\n shareTitle={name}\n onReportClick={() => setReportOpen(true)}\n />\n </div>\n </div>\n );\n\n return (\n <div className=\"relative z-0 min-h-screen\">\n {token.isHidden ? <HiddenContentBanner /> : null}\n <PageBackdrop image={image} />\n\n <PageContainer className={isPublication ? \"pt-20 space-y-8 pb-8 lg:px-16 xl:px-24\" : \"pt-20 space-y-8 pb-8\"}>\n {video ? (\n <div className=\"grid grid-cols-1 lg:grid-cols-[minmax(0,2fr)_minmax(0,1fr)] lg:gap-12 gap-8 items-start\">\n <AssetVideo\n name={name}\n embedSrc={video.src}\n embedLabel={video.label}\n description={token.metadata?.description}\n collectionName={publisherName}\n collectionImage={resolveImage(collection?.image)}\n collectionHref={collectionHref(\"STARKNET\", contract)}\n utilities={\n <AssetUtilityIcons\n contractExplorerHref={`${EXPLORER_URL}/contract/${token.contractAddress}`}\n shareTitle={name}\n onReportClick={() => setReportOpen(true)}\n />\n }\n />\n <aside className=\"space-y-6 min-w-0\">\n <IpTypeBadge ipType={token.metadata?.ipType ?? \"Video\"} size=\"md\" showLabel />\n {marketBlock}\n {ownerAddress ? <AssetOwnerRow ownerAddress={ownerAddress} ownerHref={profileHref({ address: ownerAddress })} /> : null}\n <AssetRelatedList\n title={publisherName}\n titleHref={collectionHref(\"STARKNET\", contract)}\n items={collectionTokens\n .filter((t) => String(t.tokenId) !== String(tokenId))\n .map((t) => ({\n tokenId: t.tokenId,\n name: t.metadata?.name || `${config.namePrefix} #${t.tokenId}`,\n image: resolveImage(t.metadata?.image),\n href: assetHref(\"STARKNET\", contract, t.tokenId),\n }))}\n />\n </aside>\n </div>\n ) : audio ? (\n <div className=\"grid grid-cols-1 lg:grid-cols-[minmax(0,2fr)_minmax(0,1fr)] lg:gap-12 gap-8 items-start\">\n <AssetAudio\n name={name}\n image={image}\n embedSrc={audio.src}\n embedLabel={audio.label}\n description={token.metadata?.description}\n collectionName={publisherName}\n collectionImage={resolveImage(collection?.image)}\n collectionHref={collectionHref(\"STARKNET\", contract)}\n utilities={\n <AssetUtilityIcons\n contractExplorerHref={`${EXPLORER_URL}/contract/${token.contractAddress}`}\n shareTitle={name}\n onReportClick={() => setReportOpen(true)}\n />\n }\n />\n <aside className=\"space-y-6 min-w-0\">\n <IpTypeBadge ipType={token.metadata?.ipType ?? \"Audio\"} size=\"md\" showLabel />\n {marketBlock}\n {ownerAddress ? <AssetOwnerRow ownerAddress={ownerAddress} ownerHref={profileHref({ address: ownerAddress })} /> : null}\n <AssetRelatedList\n title={publisherName}\n titleHref={collectionHref(\"STARKNET\", contract)}\n shape=\"square\"\n items={collectionTokens\n .filter((t) => String(t.tokenId) !== String(tokenId))\n .map((t) => ({\n tokenId: t.tokenId,\n name: t.metadata?.name || `${config.namePrefix} #${t.tokenId}`,\n image: resolveImage(t.metadata?.image),\n href: assetHref(\"STARKNET\", contract, t.tokenId),\n }))}\n />\n </aside>\n </div>\n ) : isPublication ? (\n <div className=\"grid grid-cols-1 lg:grid-cols-[minmax(0,2fr)_minmax(0,1fr)] lg:gap-20 gap-8 items-start\">\n <AssetPublication\n name={name}\n text={description!}\n image={image}\n imgError={imgError}\n onImageError={() => setImgError(true)}\n onZoom={() => setLightboxOpen(true)}\n author={publicationAuthor(attributes, token.metadata?.author)}\n externalUrl={token.metadata?.externalUrl}\n />\n <aside className=\"space-y-6 min-w-0 lg:sticky lg:top-16\">\n <IpTypeBadge ipType={token.metadata?.ipType ?? \"Publications\"} size=\"md\" showLabel />\n {marketBlock}\n {detailsBlock}\n </aside>\n </div>\n ) : (\n <div className=\"grid grid-cols-1 lg:grid-cols-2 lg:gap-10 gap-8 items-start\">\n <AssetMediaColumn\n shouldReduce={Boolean(shouldReduce)}\n image={image}\n imageAlt={name}\n imgError={imgError}\n onImageError={() => setImgError(true)}\n onZoom={() => setLightboxOpen(true)}\n animationUrl={token.metadata?.animationUrl}\n live={isLivingRenderCollection(token.chain as Chain, token.contractAddress)}\n fallback={<div className=\"aspect-square bg-muted\" />}\n />\n\n <motion.div\n initial={shouldReduce ? false : { opacity: 0, y: 16 }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ duration: 0.5, delay: 0.2 }}\n className=\"space-y-6\"\n >\n <AssetHeaderBlock\n name={name}\n description={token.metadata?.description}\n ipType={token.metadata?.ipType}\n parentContract={parentContract}\n parentTokenId={parentTokenId}\n badges={kind === \"pop\" ? (\n <span className=\"inline-flex items-center gap-1 text-2xs font-semibold px-2.5 py-1 rounded-full border border-emerald-500/30 bg-emerald-500/10 text-emerald-500\">\n <Award className=\"h-3 w-3\" />\n POP\n </span>\n ) : null}\n />\n\n {marketBlock}\n\n {detailsBlock}\n </motion.div>\n </div>\n )}\n\n <Tabs defaultValue=\"overview\">\n <TabsList>\n <TabsTrigger value=\"overview\">Overview</TabsTrigger>\n {config.market ? <TabsTrigger value=\"markets\">Markets {marketCount > 0 && `(${marketCount})`}</TabsTrigger> : null}\n <TabsTrigger value=\"provenance\">Provenance {history.length > 0 && `(${history.length})`}</TabsTrigger>\n </TabsList>\n\n <TabsContent value=\"overview\">\n <AssetOverviewContent attributes={overview.attributes} hasTemplateData={overview.hasTemplateData} isDisplayAttr={overview.isDisplayAttr} content={postContent} link={overviewLink} />\n </TabsContent>\n\n {config.market ? (\n <TabsContent value=\"markets\">\n <AssetMarketsTab\n activeListings={market.activeListings}\n activeBids={market.activeBids}\n walletAddress={walletAddress ?? undefined}\n isOwner={market.isOwner}\n isProcessing={actions.isProcessing}\n onBuyClick={actions.buy}\n onCancelClick={actions.cancel}\n onAcceptClick={actions.acceptBid}\n />\n </TabsContent>\n ) : null}\n\n <TabsContent value=\"provenance\">\n <AssetProvenanceTab\n history={history as ApiActivity[]}\n contract={contract}\n tokenId={tokenId}\n remixCount={remixCount}\n originalCreator={fullTokenData?.originalCreator}\n registeredAt={fullTokenData?.registeredAt}\n />\n </TabsContent>\n </Tabs>\n </PageContainer>\n\n <AssetLightbox open={lightboxOpen} onOpenChange={setLightboxOpen} image={image} alt={name} />\n <FloatingCommentsButton onClick={() => setCommentOpen(true)} commentTotal={commentTotal} />\n <AssetCommentsDialog\n open={commentOpen}\n onOpenChange={setCommentOpen}\n contract={contract}\n tokenId={tokenId}\n name={name}\n imageUrl={image}\n commentTotal={commentTotal}\n {...config.accents}\n />\n {ReportDialog ? <ReportDialog open={reportOpen} onOpenChange={setReportOpen} target={{ type: \"TOKEN\", contract: token.contractAddress, tokenId: token.tokenId, name }} /> : null}\n {actions.dialogs}\n </div>\n );\n}\n"],"mappings":"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","names":["import_sdk"]}
|
|
@@ -38,6 +38,7 @@ import { useComments } from "../utils/use-comments.js";
|
|
|
38
38
|
import { useFullTokenData } from "../utils/use-full-token-data.js";
|
|
39
39
|
import { useAssetMarketState } from "../utils/asset-market-state.js";
|
|
40
40
|
import { assetAttributes } from "../utils/asset-attributes.js";
|
|
41
|
+
import { externalLink } from "../utils/external-link.js";
|
|
41
42
|
import { ASSET_ACCENTS } from "../utils/asset-accents.js";
|
|
42
43
|
import { isLivingRenderCollection } from "../data/living-render-collections.js";
|
|
43
44
|
import { EXPLORER_URL } from "../utils/explorer-url.js";
|
|
@@ -146,12 +147,14 @@ function AssetPageView({
|
|
|
146
147
|
const marketCount = market.activeListings.length + market.activeBids.length;
|
|
147
148
|
const { Panel } = config;
|
|
148
149
|
const postContent = traitText(attributes, "Content");
|
|
149
|
-
const
|
|
150
|
+
const description = token.metadata?.description?.trim() || null;
|
|
150
151
|
const video = (token.metadata?.ipType ?? "").toLowerCase() === "video" ? videoEmbed(attributes) : null;
|
|
151
152
|
const audio = (token.metadata?.ipType ?? "").toLowerCase() === "audio" ? audioEmbed(attributes) : null;
|
|
152
|
-
const isPublication = !!
|
|
153
|
+
const isPublication = !!description && PUBLICATION_TYPES.has((token.metadata?.ipType ?? "").toLowerCase());
|
|
153
154
|
const publisherName = collection?.name ?? contract.slice(0, 8) + "\u2026";
|
|
154
|
-
const
|
|
155
|
+
const overviewAttributes = postContent ? attributes.filter((a) => a.trait_type !== "Content") : attributes;
|
|
156
|
+
const overview = video || audio ? assetAttributes(overviewAttributes.filter((a) => !VIDEO_EMBED_TRAITS.has(a.trait_type ?? "") && !AUDIO_EMBED_TRAITS.has(a.trait_type ?? ""))) : { attributes: overviewAttributes, hasTemplateData, isDisplayAttr };
|
|
157
|
+
const overviewLink = isPublication || video || audio ? null : externalLink(token.metadata?.externalUrl);
|
|
155
158
|
const marketBlock = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
156
159
|
Panel ? /* @__PURE__ */ jsx(Panel, { contract, tokenId, quantityOwned: market.quantityOwned }) : null,
|
|
157
160
|
config.market ? /* @__PURE__ */ jsx(
|
|
@@ -298,7 +301,7 @@ function AssetPageView({
|
|
|
298
301
|
AssetPublication,
|
|
299
302
|
{
|
|
300
303
|
name,
|
|
301
|
-
text:
|
|
304
|
+
text: description,
|
|
302
305
|
image,
|
|
303
306
|
imgError,
|
|
304
307
|
onImageError: () => setImgError(true),
|
|
@@ -340,7 +343,6 @@ function AssetPageView({
|
|
|
340
343
|
{
|
|
341
344
|
name,
|
|
342
345
|
description: token.metadata?.description,
|
|
343
|
-
externalUrl: token.metadata?.externalUrl,
|
|
344
346
|
ipType: token.metadata?.ipType,
|
|
345
347
|
parentContract,
|
|
346
348
|
parentTokenId,
|
|
@@ -368,7 +370,7 @@ function AssetPageView({
|
|
|
368
370
|
history.length > 0 && `(${history.length})`
|
|
369
371
|
] })
|
|
370
372
|
] }),
|
|
371
|
-
/* @__PURE__ */ jsx(TabsContent, { value: "overview", children: /* @__PURE__ */ jsx(AssetOverviewContent, { attributes: overview.attributes, hasTemplateData: overview.hasTemplateData, isDisplayAttr: overview.isDisplayAttr }) }),
|
|
373
|
+
/* @__PURE__ */ jsx(TabsContent, { value: "overview", children: /* @__PURE__ */ jsx(AssetOverviewContent, { attributes: overview.attributes, hasTemplateData: overview.hasTemplateData, isDisplayAttr: overview.isDisplayAttr, content: postContent, link: overviewLink }) }),
|
|
372
374
|
config.market ? /* @__PURE__ */ jsx(TabsContent, { value: "markets", children: /* @__PURE__ */ jsx(
|
|
373
375
|
AssetMarketsTab,
|
|
374
376
|
{
|