@medialane/ui 0.256.0 → 0.258.0

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.
Files changed (107) hide show
  1. package/dist/components/account/add-guardian-dialog.cjs +1 -1
  2. package/dist/components/account/add-guardian-dialog.cjs.map +1 -1
  3. package/dist/components/account/add-guardian-dialog.js +1 -1
  4. package/dist/components/account/add-guardian-dialog.js.map +1 -1
  5. package/dist/components/account/device-approval-dialog.cjs +2 -2
  6. package/dist/components/account/device-approval-dialog.cjs.map +1 -1
  7. package/dist/components/account/device-approval-dialog.js +2 -2
  8. package/dist/components/account/device-approval-dialog.js.map +1 -1
  9. package/dist/components/account/devices-section.cjs +1 -1
  10. package/dist/components/account/devices-section.cjs.map +1 -1
  11. package/dist/components/account/devices-section.js +1 -1
  12. package/dist/components/account/devices-section.js.map +1 -1
  13. package/dist/components/account/guardian-recovery-section.cjs +1 -1
  14. package/dist/components/account/guardian-recovery-section.cjs.map +1 -1
  15. package/dist/components/account/guardian-recovery-section.js +1 -1
  16. package/dist/components/account/guardian-recovery-section.js.map +1 -1
  17. package/dist/components/account/input-otp.d.cts +2 -2
  18. package/dist/components/account/input-otp.d.ts +2 -2
  19. package/dist/components/asset-page.cjs +8 -7
  20. package/dist/components/asset-page.cjs.map +1 -1
  21. package/dist/components/asset-page.js +8 -7
  22. package/dist/components/asset-page.js.map +1 -1
  23. package/dist/components/asset-publication.cjs +1 -3
  24. package/dist/components/asset-publication.cjs.map +1 -1
  25. package/dist/components/asset-publication.js +1 -3
  26. package/dist/components/asset-publication.js.map +1 -1
  27. package/dist/components/button.d.cts +2 -2
  28. package/dist/components/button.d.ts +2 -2
  29. package/dist/components/drop/create/launch-dialog.cjs +1 -1
  30. package/dist/components/drop/create/launch-dialog.cjs.map +1 -1
  31. package/dist/components/drop/create/launch-dialog.js +1 -1
  32. package/dist/components/drop/create/launch-dialog.js.map +1 -1
  33. package/dist/components/drop/page/drop-manage.cjs +1 -1
  34. package/dist/components/drop/page/drop-manage.cjs.map +1 -1
  35. package/dist/components/drop/page/drop-manage.js +1 -1
  36. package/dist/components/drop/page/drop-manage.js.map +1 -1
  37. package/dist/components/drop/page/drop-mint-dialog.cjs +1 -1
  38. package/dist/components/drop/page/drop-mint-dialog.cjs.map +1 -1
  39. package/dist/components/drop/page/drop-mint-dialog.js +1 -1
  40. package/dist/components/drop/page/drop-mint-dialog.js.map +1 -1
  41. package/dist/components/empty-or-error.cjs +2 -2
  42. package/dist/components/empty-or-error.cjs.map +1 -1
  43. package/dist/components/empty-or-error.js +2 -2
  44. package/dist/components/empty-or-error.js.map +1 -1
  45. package/dist/components/fast-mint/fast-mint.cjs +2 -1
  46. package/dist/components/fast-mint/fast-mint.cjs.map +1 -1
  47. package/dist/components/fast-mint/fast-mint.d.cts +2 -2
  48. package/dist/components/fast-mint/fast-mint.d.ts +2 -2
  49. package/dist/components/fast-mint/fast-mint.js +2 -1
  50. package/dist/components/fast-mint/fast-mint.js.map +1 -1
  51. package/dist/components/launchpad/edition-mint-schema.d.cts +2 -2
  52. package/dist/components/launchpad/edition-mint-schema.d.ts +2 -2
  53. package/dist/components/license-request-page.cjs +1 -1
  54. package/dist/components/license-request-page.cjs.map +1 -1
  55. package/dist/components/license-request-page.js +1 -1
  56. package/dist/components/license-request-page.js.map +1 -1
  57. package/dist/components/media-wallet/activate-card.cjs +1 -1
  58. package/dist/components/media-wallet/activate-card.cjs.map +1 -1
  59. package/dist/components/media-wallet/activate-card.js +1 -1
  60. package/dist/components/media-wallet/activate-card.js.map +1 -1
  61. package/dist/components/media-wallet/media-wallet-activity.cjs +1 -1
  62. package/dist/components/media-wallet/media-wallet-activity.cjs.map +1 -1
  63. package/dist/components/media-wallet/media-wallet-activity.js +1 -1
  64. package/dist/components/media-wallet/media-wallet-activity.js.map +1 -1
  65. package/dist/components/media-wallet/media-wallet-send.cjs +2 -6
  66. package/dist/components/media-wallet/media-wallet-send.cjs.map +1 -1
  67. package/dist/components/media-wallet/media-wallet-send.js +2 -6
  68. package/dist/components/media-wallet/media-wallet-send.js.map +1 -1
  69. package/dist/components/sheet.d.cts +1 -1
  70. package/dist/components/sheet.d.ts +1 -1
  71. package/dist/components/transaction-dialog.cjs +4 -4
  72. package/dist/components/transaction-dialog.cjs.map +1 -1
  73. package/dist/components/transaction-dialog.d.cts +3 -1
  74. package/dist/components/transaction-dialog.d.ts +3 -1
  75. package/dist/components/transaction-dialog.js +4 -4
  76. package/dist/components/transaction-dialog.js.map +1 -1
  77. package/dist/components/wallet/export-key-section.cjs +3 -3
  78. package/dist/components/wallet/export-key-section.cjs.map +1 -1
  79. package/dist/components/wallet/export-key-section.d.cts +1 -2
  80. package/dist/components/wallet/export-key-section.d.ts +1 -2
  81. package/dist/components/wallet/export-key-section.js +3 -3
  82. package/dist/components/wallet/export-key-section.js.map +1 -1
  83. package/dist/index.cjs +0 -2
  84. package/dist/index.cjs.map +1 -1
  85. package/dist/index.d.cts +1 -1
  86. package/dist/index.d.ts +1 -1
  87. package/dist/index.js +0 -2
  88. package/dist/index.js.map +1 -1
  89. package/dist/utils/describe-error.cjs +16 -11
  90. package/dist/utils/describe-error.cjs.map +1 -1
  91. package/dist/utils/describe-error.d.cts +4 -4
  92. package/dist/utils/describe-error.d.ts +4 -4
  93. package/dist/utils/describe-error.js +16 -10
  94. package/dist/utils/describe-error.js.map +1 -1
  95. package/dist/utils/media-wallet/use-erc20-balance.d.cts +1 -1
  96. package/dist/utils/media-wallet/use-erc20-balance.d.ts +1 -1
  97. package/dist/utils/use-email-code.cjs +2 -2
  98. package/dist/utils/use-email-code.cjs.map +1 -1
  99. package/dist/utils/use-email-code.js +2 -2
  100. package/dist/utils/use-email-code.js.map +1 -1
  101. package/dist/utils/use-transaction.cjs +16 -2
  102. package/dist/utils/use-transaction.cjs.map +1 -1
  103. package/dist/utils/use-transaction.d.cts +1 -0
  104. package/dist/utils/use-transaction.d.ts +1 -0
  105. package/dist/utils/use-transaction.js +17 -3
  106. package/dist/utils/use-transaction.js.map +1 -1
  107. package/package.json +3 -3
@@ -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\nfunction publicationAuthor(attributes: { trait_type?: string | null; value?: string | number | boolean | null }[], metadataAuthor?: string | null): string | null {\n const text = (trait: string) => {\n const value = attributes.find((a) => a.trait_type === trait)?.value;\n return typeof value === \"string\" && value.trim() !== \"\" ? value.trim() : null;\n };\n return text(\"Author\") ?? metadataAuthor ?? text(\"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 articleText = 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 }\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 { 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"]}
@@ -51,12 +51,12 @@ const KINDS = {
51
51
  pop: { namePrefix: "POP", accents: ASSET_ACCENTS.standard, market: false, remix: false }
52
52
  };
53
53
  const PUBLICATION_TYPES = /* @__PURE__ */ new Set(["publications", "posts"]);
54
+ function traitText(attributes, trait) {
55
+ const value = attributes.find((a) => a.trait_type === trait)?.value;
56
+ return typeof value === "string" && value.trim() !== "" ? value.trim() : null;
57
+ }
54
58
  function publicationAuthor(attributes, metadataAuthor) {
55
- const text = (trait) => {
56
- const value = attributes.find((a) => a.trait_type === trait)?.value;
57
- return typeof value === "string" && value.trim() !== "" ? value.trim() : null;
58
- };
59
- return text("Author") ?? metadataAuthor ?? text("Creator");
59
+ return traitText(attributes, "Author") ?? metadataAuthor ?? traitText(attributes, "Creator");
60
60
  }
61
61
  const VARIANT_KINDS = { edition: "edition", ticket: "ticket", club: "membership", pop: "pop" };
62
62
  function detectAssetKind(service, standard) {
@@ -145,12 +145,13 @@ function AssetPageView({
145
145
  const ownerAddress = !market.isERC1155 ? holders[0]?.owner ?? token.owner ?? null : null;
146
146
  const marketCount = market.activeListings.length + market.activeBids.length;
147
147
  const { Panel } = config;
148
- const articleText = token.metadata?.description?.trim() || null;
148
+ const postContent = traitText(attributes, "Content");
149
+ const articleText = postContent ?? (token.metadata?.description?.trim() || null);
149
150
  const video = (token.metadata?.ipType ?? "").toLowerCase() === "video" ? videoEmbed(attributes) : null;
150
151
  const audio = (token.metadata?.ipType ?? "").toLowerCase() === "audio" ? audioEmbed(attributes) : null;
151
152
  const isPublication = !!articleText && PUBLICATION_TYPES.has((token.metadata?.ipType ?? "").toLowerCase());
152
153
  const publisherName = collection?.name ?? contract.slice(0, 8) + "\u2026";
153
- const overview = isPublication ? { attributes, hasTemplateData, isDisplayAttr } : video || audio ? assetAttributes(attributes.filter((a) => !VIDEO_EMBED_TRAITS.has(a.trait_type ?? "") && !AUDIO_EMBED_TRAITS.has(a.trait_type ?? ""))) : { attributes, hasTemplateData, isDisplayAttr };
154
+ const overview = isPublication ? { attributes, hasTemplateData, isDisplayAttr: (a) => isDisplayAttr(a) && !(postContent && a.trait_type === "Content") } : video || audio ? assetAttributes(attributes.filter((a) => !VIDEO_EMBED_TRAITS.has(a.trait_type ?? "") && !AUDIO_EMBED_TRAITS.has(a.trait_type ?? ""))) : { attributes, hasTemplateData, isDisplayAttr };
154
155
  const marketBlock = /* @__PURE__ */ jsxs(Fragment, { children: [
155
156
  Panel ? /* @__PURE__ */ jsx(Panel, { contract, tokenId, quantityOwned: market.quantityOwned }) : null,
156
157
  config.market ? /* @__PURE__ */ jsx(
@@ -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\nfunction publicationAuthor(attributes: { trait_type?: string | null; value?: string | number | boolean | null }[], metadataAuthor?: string | null): string | null {\n const text = (trait: string) => {\n const value = attributes.find((a) => a.trait_type === trait)?.value;\n return typeof value === \"string\" && value.trim() !== \"\" ? value.trim() : null;\n };\n return text(\"Author\") ?? metadataAuthor ?? text(\"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 articleText = 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 }\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":[]}
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":[]}
@@ -29,12 +29,10 @@ var import_external_link = require("../utils/external-link.js");
29
29
  function AssetPublication({ name, text, image, imgError, onImageError, onZoom, author, externalUrl }) {
30
30
  const link = (0, import_external_link.externalLink)(externalUrl);
31
31
  const paragraphs = text.split(/\n{2,}/).map((p) => p.trim()).filter(Boolean);
32
- const [lead, ...body] = paragraphs.length > 1 ? paragraphs : [null, ...paragraphs];
33
32
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("article", { className: "min-w-0 space-y-6", children: [
34
33
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("header", { className: "space-y-3", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h1", { className: "text-2xl lg:text-4xl font-bold leading-tight break-words", children: name }) }),
35
- lead ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "max-w-3xl text-base leading-relaxed text-foreground whitespace-pre-line", children: lead }) : null,
36
34
  image && !imgError ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", onClick: onZoom, "aria-label": "View full image", className: "block w-full overflow-hidden rounded-3xl cursor-zoom-in focus:outline-none", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("img", { src: image, alt: name, onError: onImageError, className: "w-full h-auto max-h-[80vh] object-contain" }) }) : null,
37
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "max-w-3xl space-y-4 text-sm leading-relaxed text-foreground/85 break-words", children: body.map((paragraph, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "whitespace-pre-line", children: paragraph }, i)) }),
35
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "max-w-3xl space-y-4 text-base leading-relaxed text-foreground break-words", children: paragraphs.map((paragraph, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "whitespace-pre-line", children: paragraph }, i)) }),
38
36
  author || link ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-wrap items-center gap-4", children: [
39
37
  author ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "min-w-0 break-words text-sm text-muted-foreground", children: author }) : null,
40
38
  link ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_button.Button, { asChild: true, variant: "outline", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("a", { href: link, target: "_blank", rel: "noopener noreferrer", children: [
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/asset-publication.tsx"],"sourcesContent":["\"use client\";\n\nimport { ExternalLink } from \"lucide-react\";\nimport { Button } from \"./button.js\";\nimport { externalLink } from \"../utils/external-link.js\";\n\nexport interface AssetPublicationProps {\n name: string;\n text: string;\n image: string | null;\n imgError: boolean;\n onImageError: () => void;\n onZoom: () => void;\n author?: string | null;\n externalUrl?: string | null;\n}\n\nexport function AssetPublication({ name, text, image, imgError, onImageError, onZoom, author, externalUrl }: AssetPublicationProps) {\n const link = externalLink(externalUrl);\n const paragraphs = text.split(/\\n{2,}/).map((p) => p.trim()).filter(Boolean);\n const [lead, ...body] = paragraphs.length > 1 ? paragraphs : [null, ...paragraphs];\n\n return (\n <article className=\"min-w-0 space-y-6\">\n <header className=\"space-y-3\">\n <h1 className=\"text-2xl lg:text-4xl font-bold leading-tight break-words\">{name}</h1>\n </header>\n\n {lead ? <p className=\"max-w-3xl text-base leading-relaxed text-foreground whitespace-pre-line\">{lead}</p> : null}\n\n {image && !imgError ? (\n <button type=\"button\" onClick={onZoom} aria-label=\"View full image\" className=\"block w-full overflow-hidden rounded-3xl cursor-zoom-in focus:outline-none\">\n <img src={image} alt={name} onError={onImageError} className=\"w-full h-auto max-h-[80vh] object-contain\" />\n </button>\n ) : null}\n\n <div className=\"max-w-3xl space-y-4 text-sm leading-relaxed text-foreground/85 break-words\">\n {body.map((paragraph, i) => (\n <p key={i} className=\"whitespace-pre-line\">{paragraph}</p>\n ))}\n </div>\n\n {author || link ? (\n <div className=\"flex flex-wrap items-center gap-4\">\n {author ? <p className=\"min-w-0 break-words text-sm text-muted-foreground\">{author}</p> : null}\n {link ? (\n <Button asChild variant=\"outline\">\n <a href={link} target=\"_blank\" rel=\"noopener noreferrer\">\n Read more\n <ExternalLink />\n </a>\n </Button>\n ) : null}\n </div>\n ) : null}\n </article>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAyBQ;AAvBR,0BAA6B;AAC7B,oBAAuB;AACvB,2BAA6B;AAatB,SAAS,iBAAiB,EAAE,MAAM,MAAM,OAAO,UAAU,cAAc,QAAQ,QAAQ,YAAY,GAA0B;AAClI,QAAM,WAAO,mCAAa,WAAW;AACrC,QAAM,aAAa,KAAK,MAAM,QAAQ,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,OAAO;AAC3E,QAAM,CAAC,MAAM,GAAG,IAAI,IAAI,WAAW,SAAS,IAAI,aAAa,CAAC,MAAM,GAAG,UAAU;AAEjF,SACE,6CAAC,aAAQ,WAAU,qBACjB;AAAA,gDAAC,YAAO,WAAU,aAChB,sDAAC,QAAG,WAAU,4DAA4D,gBAAK,GACjF;AAAA,IAEC,OAAO,4CAAC,OAAE,WAAU,2EAA2E,gBAAK,IAAO;AAAA,IAE3G,SAAS,CAAC,WACT,4CAAC,YAAO,MAAK,UAAS,SAAS,QAAQ,cAAW,mBAAkB,WAAU,8EAC5E,sDAAC,SAAI,KAAK,OAAO,KAAK,MAAM,SAAS,cAAc,WAAU,6CAA4C,GAC3G,IACE;AAAA,IAEJ,4CAAC,SAAI,WAAU,8EACZ,eAAK,IAAI,CAAC,WAAW,MACpB,4CAAC,OAAU,WAAU,uBAAuB,uBAApC,CAA8C,CACvD,GACH;AAAA,IAEC,UAAU,OACT,6CAAC,SAAI,WAAU,qCACZ;AAAA,eAAS,4CAAC,OAAE,WAAU,qDAAqD,kBAAO,IAAO;AAAA,MACzF,OACC,4CAAC,wBAAO,SAAO,MAAC,SAAQ,WACtB,uDAAC,OAAE,MAAM,MAAM,QAAO,UAAS,KAAI,uBAAsB;AAAA;AAAA,QAEvD,4CAAC,oCAAa;AAAA,SAChB,GACF,IACE;AAAA,OACN,IACE;AAAA,KACN;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/components/asset-publication.tsx"],"sourcesContent":["\"use client\";\n\nimport { ExternalLink } from \"lucide-react\";\nimport { Button } from \"./button.js\";\nimport { externalLink } from \"../utils/external-link.js\";\n\nexport interface AssetPublicationProps {\n name: string;\n text: string;\n image: string | null;\n imgError: boolean;\n onImageError: () => void;\n onZoom: () => void;\n author?: string | null;\n externalUrl?: string | null;\n}\n\nexport function AssetPublication({ name, text, image, imgError, onImageError, onZoom, author, externalUrl }: AssetPublicationProps) {\n const link = externalLink(externalUrl);\n const paragraphs = text.split(/\\n{2,}/).map((p) => p.trim()).filter(Boolean);\n\n return (\n <article className=\"min-w-0 space-y-6\">\n <header className=\"space-y-3\">\n <h1 className=\"text-2xl lg:text-4xl font-bold leading-tight break-words\">{name}</h1>\n </header>\n\n {image && !imgError ? (\n <button type=\"button\" onClick={onZoom} aria-label=\"View full image\" className=\"block w-full overflow-hidden rounded-3xl cursor-zoom-in focus:outline-none\">\n <img src={image} alt={name} onError={onImageError} className=\"w-full h-auto max-h-[80vh] object-contain\" />\n </button>\n ) : null}\n\n <div className=\"max-w-3xl space-y-4 text-base leading-relaxed text-foreground break-words\">\n {paragraphs.map((paragraph, i) => (\n <p key={i} className=\"whitespace-pre-line\">{paragraph}</p>\n ))}\n </div>\n\n {author || link ? (\n <div className=\"flex flex-wrap items-center gap-4\">\n {author ? <p className=\"min-w-0 break-words text-sm text-muted-foreground\">{author}</p> : null}\n {link ? (\n <Button asChild variant=\"outline\">\n <a href={link} target=\"_blank\" rel=\"noopener noreferrer\">\n Read more\n <ExternalLink />\n </a>\n </Button>\n ) : null}\n </div>\n ) : null}\n </article>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAwBQ;AAtBR,0BAA6B;AAC7B,oBAAuB;AACvB,2BAA6B;AAatB,SAAS,iBAAiB,EAAE,MAAM,MAAM,OAAO,UAAU,cAAc,QAAQ,QAAQ,YAAY,GAA0B;AAClI,QAAM,WAAO,mCAAa,WAAW;AACrC,QAAM,aAAa,KAAK,MAAM,QAAQ,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,OAAO;AAE3E,SACE,6CAAC,aAAQ,WAAU,qBACjB;AAAA,gDAAC,YAAO,WAAU,aAChB,sDAAC,QAAG,WAAU,4DAA4D,gBAAK,GACjF;AAAA,IAEC,SAAS,CAAC,WACT,4CAAC,YAAO,MAAK,UAAS,SAAS,QAAQ,cAAW,mBAAkB,WAAU,8EAC5E,sDAAC,SAAI,KAAK,OAAO,KAAK,MAAM,SAAS,cAAc,WAAU,6CAA4C,GAC3G,IACE;AAAA,IAEJ,4CAAC,SAAI,WAAU,6EACZ,qBAAW,IAAI,CAAC,WAAW,MAC1B,4CAAC,OAAU,WAAU,uBAAuB,uBAApC,CAA8C,CACvD,GACH;AAAA,IAEC,UAAU,OACT,6CAAC,SAAI,WAAU,qCACZ;AAAA,eAAS,4CAAC,OAAE,WAAU,qDAAqD,kBAAO,IAAO;AAAA,MACzF,OACC,4CAAC,wBAAO,SAAO,MAAC,SAAQ,WACtB,uDAAC,OAAE,MAAM,MAAM,QAAO,UAAS,KAAI,uBAAsB;AAAA;AAAA,QAEvD,4CAAC,oCAAa;AAAA,SAChB,GACF,IACE;AAAA,OACN,IACE;AAAA,KACN;AAEJ;","names":[]}
@@ -6,12 +6,10 @@ import { externalLink } from "../utils/external-link.js";
6
6
  function AssetPublication({ name, text, image, imgError, onImageError, onZoom, author, externalUrl }) {
7
7
  const link = externalLink(externalUrl);
8
8
  const paragraphs = text.split(/\n{2,}/).map((p) => p.trim()).filter(Boolean);
9
- const [lead, ...body] = paragraphs.length > 1 ? paragraphs : [null, ...paragraphs];
10
9
  return /* @__PURE__ */ jsxs("article", { className: "min-w-0 space-y-6", children: [
11
10
  /* @__PURE__ */ jsx("header", { className: "space-y-3", children: /* @__PURE__ */ jsx("h1", { className: "text-2xl lg:text-4xl font-bold leading-tight break-words", children: name }) }),
12
- lead ? /* @__PURE__ */ jsx("p", { className: "max-w-3xl text-base leading-relaxed text-foreground whitespace-pre-line", children: lead }) : null,
13
11
  image && !imgError ? /* @__PURE__ */ jsx("button", { type: "button", onClick: onZoom, "aria-label": "View full image", className: "block w-full overflow-hidden rounded-3xl cursor-zoom-in focus:outline-none", children: /* @__PURE__ */ jsx("img", { src: image, alt: name, onError: onImageError, className: "w-full h-auto max-h-[80vh] object-contain" }) }) : null,
14
- /* @__PURE__ */ jsx("div", { className: "max-w-3xl space-y-4 text-sm leading-relaxed text-foreground/85 break-words", children: body.map((paragraph, i) => /* @__PURE__ */ jsx("p", { className: "whitespace-pre-line", children: paragraph }, i)) }),
12
+ /* @__PURE__ */ jsx("div", { className: "max-w-3xl space-y-4 text-base leading-relaxed text-foreground break-words", children: paragraphs.map((paragraph, i) => /* @__PURE__ */ jsx("p", { className: "whitespace-pre-line", children: paragraph }, i)) }),
15
13
  author || link ? /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-4", children: [
16
14
  author ? /* @__PURE__ */ jsx("p", { className: "min-w-0 break-words text-sm text-muted-foreground", children: author }) : null,
17
15
  link ? /* @__PURE__ */ jsx(Button, { asChild: true, variant: "outline", children: /* @__PURE__ */ jsxs("a", { href: link, target: "_blank", rel: "noopener noreferrer", children: [
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/asset-publication.tsx"],"sourcesContent":["\"use client\";\n\nimport { ExternalLink } from \"lucide-react\";\nimport { Button } from \"./button.js\";\nimport { externalLink } from \"../utils/external-link.js\";\n\nexport interface AssetPublicationProps {\n name: string;\n text: string;\n image: string | null;\n imgError: boolean;\n onImageError: () => void;\n onZoom: () => void;\n author?: string | null;\n externalUrl?: string | null;\n}\n\nexport function AssetPublication({ name, text, image, imgError, onImageError, onZoom, author, externalUrl }: AssetPublicationProps) {\n const link = externalLink(externalUrl);\n const paragraphs = text.split(/\\n{2,}/).map((p) => p.trim()).filter(Boolean);\n const [lead, ...body] = paragraphs.length > 1 ? paragraphs : [null, ...paragraphs];\n\n return (\n <article className=\"min-w-0 space-y-6\">\n <header className=\"space-y-3\">\n <h1 className=\"text-2xl lg:text-4xl font-bold leading-tight break-words\">{name}</h1>\n </header>\n\n {lead ? <p className=\"max-w-3xl text-base leading-relaxed text-foreground whitespace-pre-line\">{lead}</p> : null}\n\n {image && !imgError ? (\n <button type=\"button\" onClick={onZoom} aria-label=\"View full image\" className=\"block w-full overflow-hidden rounded-3xl cursor-zoom-in focus:outline-none\">\n <img src={image} alt={name} onError={onImageError} className=\"w-full h-auto max-h-[80vh] object-contain\" />\n </button>\n ) : null}\n\n <div className=\"max-w-3xl space-y-4 text-sm leading-relaxed text-foreground/85 break-words\">\n {body.map((paragraph, i) => (\n <p key={i} className=\"whitespace-pre-line\">{paragraph}</p>\n ))}\n </div>\n\n {author || link ? (\n <div className=\"flex flex-wrap items-center gap-4\">\n {author ? <p className=\"min-w-0 break-words text-sm text-muted-foreground\">{author}</p> : null}\n {link ? (\n <Button asChild variant=\"outline\">\n <a href={link} target=\"_blank\" rel=\"noopener noreferrer\">\n Read more\n <ExternalLink />\n </a>\n </Button>\n ) : null}\n </div>\n ) : null}\n </article>\n );\n}\n"],"mappings":";AAyBQ,cAsBM,YAtBN;AAvBR,SAAS,oBAAoB;AAC7B,SAAS,cAAc;AACvB,SAAS,oBAAoB;AAatB,SAAS,iBAAiB,EAAE,MAAM,MAAM,OAAO,UAAU,cAAc,QAAQ,QAAQ,YAAY,GAA0B;AAClI,QAAM,OAAO,aAAa,WAAW;AACrC,QAAM,aAAa,KAAK,MAAM,QAAQ,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,OAAO;AAC3E,QAAM,CAAC,MAAM,GAAG,IAAI,IAAI,WAAW,SAAS,IAAI,aAAa,CAAC,MAAM,GAAG,UAAU;AAEjF,SACE,qBAAC,aAAQ,WAAU,qBACjB;AAAA,wBAAC,YAAO,WAAU,aAChB,8BAAC,QAAG,WAAU,4DAA4D,gBAAK,GACjF;AAAA,IAEC,OAAO,oBAAC,OAAE,WAAU,2EAA2E,gBAAK,IAAO;AAAA,IAE3G,SAAS,CAAC,WACT,oBAAC,YAAO,MAAK,UAAS,SAAS,QAAQ,cAAW,mBAAkB,WAAU,8EAC5E,8BAAC,SAAI,KAAK,OAAO,KAAK,MAAM,SAAS,cAAc,WAAU,6CAA4C,GAC3G,IACE;AAAA,IAEJ,oBAAC,SAAI,WAAU,8EACZ,eAAK,IAAI,CAAC,WAAW,MACpB,oBAAC,OAAU,WAAU,uBAAuB,uBAApC,CAA8C,CACvD,GACH;AAAA,IAEC,UAAU,OACT,qBAAC,SAAI,WAAU,qCACZ;AAAA,eAAS,oBAAC,OAAE,WAAU,qDAAqD,kBAAO,IAAO;AAAA,MACzF,OACC,oBAAC,UAAO,SAAO,MAAC,SAAQ,WACtB,+BAAC,OAAE,MAAM,MAAM,QAAO,UAAS,KAAI,uBAAsB;AAAA;AAAA,QAEvD,oBAAC,gBAAa;AAAA,SAChB,GACF,IACE;AAAA,OACN,IACE;AAAA,KACN;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/components/asset-publication.tsx"],"sourcesContent":["\"use client\";\n\nimport { ExternalLink } from \"lucide-react\";\nimport { Button } from \"./button.js\";\nimport { externalLink } from \"../utils/external-link.js\";\n\nexport interface AssetPublicationProps {\n name: string;\n text: string;\n image: string | null;\n imgError: boolean;\n onImageError: () => void;\n onZoom: () => void;\n author?: string | null;\n externalUrl?: string | null;\n}\n\nexport function AssetPublication({ name, text, image, imgError, onImageError, onZoom, author, externalUrl }: AssetPublicationProps) {\n const link = externalLink(externalUrl);\n const paragraphs = text.split(/\\n{2,}/).map((p) => p.trim()).filter(Boolean);\n\n return (\n <article className=\"min-w-0 space-y-6\">\n <header className=\"space-y-3\">\n <h1 className=\"text-2xl lg:text-4xl font-bold leading-tight break-words\">{name}</h1>\n </header>\n\n {image && !imgError ? (\n <button type=\"button\" onClick={onZoom} aria-label=\"View full image\" className=\"block w-full overflow-hidden rounded-3xl cursor-zoom-in focus:outline-none\">\n <img src={image} alt={name} onError={onImageError} className=\"w-full h-auto max-h-[80vh] object-contain\" />\n </button>\n ) : null}\n\n <div className=\"max-w-3xl space-y-4 text-base leading-relaxed text-foreground break-words\">\n {paragraphs.map((paragraph, i) => (\n <p key={i} className=\"whitespace-pre-line\">{paragraph}</p>\n ))}\n </div>\n\n {author || link ? (\n <div className=\"flex flex-wrap items-center gap-4\">\n {author ? <p className=\"min-w-0 break-words text-sm text-muted-foreground\">{author}</p> : null}\n {link ? (\n <Button asChild variant=\"outline\">\n <a href={link} target=\"_blank\" rel=\"noopener noreferrer\">\n Read more\n <ExternalLink />\n </a>\n </Button>\n ) : null}\n </div>\n ) : null}\n </article>\n );\n}\n"],"mappings":";AAwBQ,cAoBM,YApBN;AAtBR,SAAS,oBAAoB;AAC7B,SAAS,cAAc;AACvB,SAAS,oBAAoB;AAatB,SAAS,iBAAiB,EAAE,MAAM,MAAM,OAAO,UAAU,cAAc,QAAQ,QAAQ,YAAY,GAA0B;AAClI,QAAM,OAAO,aAAa,WAAW;AACrC,QAAM,aAAa,KAAK,MAAM,QAAQ,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,OAAO;AAE3E,SACE,qBAAC,aAAQ,WAAU,qBACjB;AAAA,wBAAC,YAAO,WAAU,aAChB,8BAAC,QAAG,WAAU,4DAA4D,gBAAK,GACjF;AAAA,IAEC,SAAS,CAAC,WACT,oBAAC,YAAO,MAAK,UAAS,SAAS,QAAQ,cAAW,mBAAkB,WAAU,8EAC5E,8BAAC,SAAI,KAAK,OAAO,KAAK,MAAM,SAAS,cAAc,WAAU,6CAA4C,GAC3G,IACE;AAAA,IAEJ,oBAAC,SAAI,WAAU,6EACZ,qBAAW,IAAI,CAAC,WAAW,MAC1B,oBAAC,OAAU,WAAU,uBAAuB,uBAApC,CAA8C,CACvD,GACH;AAAA,IAEC,UAAU,OACT,qBAAC,SAAI,WAAU,qCACZ;AAAA,eAAS,oBAAC,OAAE,WAAU,qDAAqD,kBAAO,IAAO;AAAA,MACzF,OACC,oBAAC,UAAO,SAAO,MAAC,SAAQ,WACtB,+BAAC,OAAE,MAAM,MAAM,QAAO,UAAS,KAAI,uBAAsB;AAAA;AAAA,QAEvD,oBAAC,gBAAa;AAAA,SAChB,GACF,IACE;AAAA,OACN,IACE;AAAA,KACN;AAEJ;","names":[]}
@@ -3,8 +3,8 @@ import * as React from 'react';
3
3
  import { VariantProps } from 'class-variance-authority';
4
4
 
5
5
  declare const buttonVariants: (props?: ({
6
- variant?: "ghost" | "link" | "default" | "destructive" | "outline" | "secondary" | "premium" | "tonal" | "gradient-border" | "gradient-fill" | null | undefined;
7
- size?: "icon" | "default" | "sm" | "lg" | null | undefined;
6
+ variant?: "default" | "link" | "destructive" | "outline" | "secondary" | "ghost" | "premium" | "tonal" | "gradient-border" | "gradient-fill" | null | undefined;
7
+ size?: "default" | "icon" | "sm" | "lg" | null | undefined;
8
8
  } & class_variance_authority_types.ClassProp) | undefined) => string;
9
9
  interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
10
10
  asChild?: boolean;
@@ -3,8 +3,8 @@ import * as React from 'react';
3
3
  import { VariantProps } from 'class-variance-authority';
4
4
 
5
5
  declare const buttonVariants: (props?: ({
6
- variant?: "ghost" | "link" | "default" | "destructive" | "outline" | "secondary" | "premium" | "tonal" | "gradient-border" | "gradient-fill" | null | undefined;
7
- size?: "icon" | "default" | "sm" | "lg" | null | undefined;
6
+ variant?: "default" | "link" | "destructive" | "outline" | "secondary" | "ghost" | "premium" | "tonal" | "gradient-border" | "gradient-fill" | null | undefined;
7
+ size?: "default" | "icon" | "sm" | "lg" | null | undefined;
8
8
  } & class_variance_authority_types.ClassProp) | undefined) => string;
9
9
  interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
10
10
  asChild?: boolean;
@@ -108,7 +108,7 @@ function LaunchDialog({ open, onClose, draft }) {
108
108
  }
109
109
  setStep({ kind: "done", collection, links: list ? (0, import_starknet.dropClaimLinks)(window.location.origin, collection, list) : [], warning });
110
110
  } catch (err) {
111
- setStep({ kind: "error", message: (0, import_describe_error.describeError)(err, "We couldn't launch your drop. Please try again.").message });
111
+ setStep({ kind: "error", message: (0, import_describe_error.describeError)(err).message });
112
112
  }
113
113
  };
114
114
  const close = () => {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/drop/create/launch-dialog.tsx"],"sourcesContent":["\"use client\";\n\nimport { useMemo, useState } from \"react\";\nimport { CheckCircle2, Loader2, RotateCcw, XCircle } from \"lucide-react\";\nimport { dropHref } from \"@medialane/sdk\";\nimport { buildPopAllowlist, dropClaimLinks, popClaimLinksCsv, type PopClaimLink } from \"@medialane/sdk/starknet\";\nimport { ActionDialog } from \"../../action-dialog.js\";\nimport { GradientButton } from \"../../gradient-button.js\";\nimport { Button } from \"../../button.js\";\nimport { ShareButton } from \"../../share-button.js\";\nimport { describeError } from \"../../../utils/describe-error.js\";\nimport { uploadDirectoryToIpfs, uploadFileToIpfs } from \"../../../utils/ipfs-upload.js\";\nimport { parseAllowlist } from \"../../../utils/drop/allowlist.js\";\nimport { buildDropMetadataFiles, metadataBytes, MAX_DROP_METADATA_BYTES } from \"../../../utils/drop/metadata.js\";\nimport { toDropTerms, priceLabel } from \"../../../utils/drop/sale.js\";\nimport { draftSupply, type DropDraft } from \"../../../utils/drop/draft.js\";\nimport { uploadAll, type UploadTask } from \"../../../utils/drop/upload.js\";\nimport { launchDrop, saveExclusiveContent } from \"../../../utils/drop/actions.js\";\nimport { useMedialaneApp } from \"../../medialane-app.js\";\n\ntype Step =\n | { kind: \"review\" }\n | { kind: \"uploading\" }\n | { kind: \"launching\" }\n | { kind: \"done\"; collection: string; links: PopClaimLink[]; warning: string | null }\n | { kind: \"error\"; message: string };\n\nexport function LaunchDialog({ open, onClose, draft }: { open: boolean; onClose: () => void; draft: DropDraft }) {\n const app = useMedialaneApp();\n const [step, setStep] = useState<Step>({ kind: \"review\" });\n const [tasks, setTasks] = useState<UploadTask[]>([]);\n const [baseUri, setBaseUri] = useState<string | null>(null);\n const client = app.getClient();\n const files = draft.kind === \"edition\" ? (draft.edition ? [draft.edition] : []) : draft.items.map((i) => i.file);\n const terms = toDropTerms(draft.sale);\n const list = useMemo(\n () => (draft.listOnly ? buildPopAllowlist(parseAllowlist(draft.allowlist).addresses) : null),\n [draft.listOnly, draft.allowlist],\n );\n\n const run = async () => {\n try {\n let uri = baseUri;\n if (!uri) {\n setStep({ kind: \"uploading\" });\n const initial = tasks.length > 0 ? tasks : [\n ...files.map((file, i) => ({ id: `art-${i}`, file, status: \"pending\" as const, uri: null, error: null })),\n ...(draft.cover ? [{ id: \"cover\", file: draft.cover, status: \"pending\" as const, uri: null, error: null }] : []),\n ];\n const done = await uploadAll(initial, async (f) => (await uploadFileToIpfs(client.api, f, \"image\")).uri, setTasks);\n setTasks(done);\n if (done.some((t) => t.status !== \"done\")) {\n setStep({ kind: \"error\", message: \"Some files didn't upload. Retry to send only those.\" });\n return;\n }\n const art = done.filter((t) => t.id.startsWith(\"art-\"));\n const metadata = buildDropMetadataFiles({\n kind: draft.kind,\n name: draft.name.trim(),\n description: draft.description.trim(),\n creator: app.walletAddress!,\n coverUri: done.find((t) => t.id === \"cover\")?.uri ?? null,\n license: draft.license,\n items: draft.kind === \"edition\"\n ? [{ name: \"\", description: \"\", imageUri: art[0]!.uri! }]\n : draft.items.map((it, i) => ({ name: it.name, description: it.description, imageUri: art[i]!.uri! })),\n supply: draftSupply(draft),\n });\n if (metadataBytes(metadata) > MAX_DROP_METADATA_BYTES) {\n setStep({ kind: \"error\", message: \"The descriptions are too long for this many tokens. Shorten them and try again.\" });\n return;\n }\n uri = (await uploadDirectoryToIpfs(client.api, metadata)).baseUri;\n setBaseUri(uri);\n }\n setStep({ kind: \"launching\" });\n const signer = await app.getSigner();\n const { collection } = await launchDrop({ client, signer }, {\n owner: app.walletAddress!,\n name: draft.name.trim(),\n symbol: draft.symbol,\n baseUri: uri!,\n maxSupply: draftSupply(draft),\n terms,\n allowlistRoot: list?.root,\n description: draft.description.trim() || undefined,\n });\n let warning: string | null = null;\n if (draft.gated.enabled) {\n try {\n await saveExclusiveContent(client, collection, draft.gated);\n } catch {\n warning = \"Your drop launched, but the exclusive content wasn't saved. You can add it from Manage.\";\n }\n }\n setStep({ kind: \"done\", collection, links: list ? dropClaimLinks(window.location.origin, collection, list) : [], warning });\n } catch (err) {\n setStep({ kind: \"error\", message: describeError(err, \"We couldn't launch your drop. Please try again.\").message });\n }\n };\n\n const close = () => {\n if (step.kind === \"uploading\" || step.kind === \"launching\") return;\n onClose();\n };\n\n return (\n <ActionDialog open={open} onClose={close}>\n <div className=\"space-y-5 p-6\">\n {step.kind === \"review\" && (\n <>\n <h2 className=\"text-lg font-semibold\">Review and launch</h2>\n <div className=\"space-y-2 rounded-xl border border-border p-4 text-sm\">\n <p className=\"font-semibold\">{draft.name}</p>\n <p className=\"text-xs font-semibold uppercase tracking-widest text-muted-foreground\">Fixed after launch</p>\n <Row label=\"Price\" value={priceLabel(terms.price, terms.paymentToken)} />\n <Row label=\"Supply\" value={`${draftSupply(draft).toLocaleString(\"en-US\")} ${draft.kind === \"edition\" ? (draftSupply(draft) === 1 ? \"copy\" : \"copies\") : draftSupply(draft) === 1 ? \"item\" : \"items\"}`} />\n <Row label=\"Starts\" value={terms.startTime === 0 ? \"At launch\" : new Date(terms.startTime * 1000).toLocaleString()} />\n <Row label=\"Ends\" value={terms.endTime === 0 ? \"No end date\" : new Date(terms.endTime * 1000).toLocaleString()} />\n <Row label=\"Per wallet\" value={terms.maxPerWallet === \"0\" ? \"No limit\" : terms.maxPerWallet} />\n <Row label=\"Who can mint\" value={list ? `${Object.keys(list.proofs).length} wallets on a list` : \"Everyone\"} />\n <p className=\"pt-1 text-xs text-muted-foreground\">The artwork and these terms can't be changed after launch. You can change the list later.</p>\n </div>\n <GradientButton big onClick={() => void run()}>Launch drop</GradientButton>\n </>\n )}\n {step.kind === \"uploading\" && (\n <>\n <h2 className=\"flex items-center gap-2 text-lg font-semibold\"><Loader2 className=\"h-4 w-4 animate-spin\" />Uploading</h2>\n <p className=\"text-sm text-muted-foreground\">{tasks.filter((t) => t.status === \"done\").length} of {tasks.length} files</p>\n </>\n )}\n {step.kind === \"launching\" && (\n <h2 className=\"flex items-center gap-2 text-lg font-semibold\"><Loader2 className=\"h-4 w-4 animate-spin\" />Launching your drop…</h2>\n )}\n {step.kind === \"error\" && (\n <>\n <h2 className=\"flex items-center gap-2 text-lg font-semibold\"><XCircle className=\"h-4 w-4 text-destructive\" />Not launched</h2>\n <p className=\"text-sm text-muted-foreground\">{step.message}</p>\n {tasks.some((t) => t.status === \"failed\") && (\n <ul className=\"space-y-1 text-xs text-muted-foreground\">\n {tasks.filter((t) => t.status === \"failed\").map((t) => <li key={t.id}>{t.file.name}: {t.error}</li>)}\n </ul>\n )}\n <Button onClick={() => void run()} className=\"gap-1.5\"><RotateCcw className=\"h-3.5 w-3.5\" />Try again</Button>\n </>\n )}\n {step.kind === \"done\" && (\n <>\n <h2 className=\"flex items-center gap-2 text-lg font-semibold\"><CheckCircle2 className=\"h-5 w-5 text-green-500\" />Your drop is live</h2>\n {step.warning && <p className=\"text-sm text-brand-orange\">{step.warning}</p>}\n <div className=\"flex flex-wrap gap-2\">\n <ShareButton title={draft.name} url={`${window.location.origin}${dropHref(step.collection)}`} variant=\"outline\" />\n <Button asChild variant=\"outline\"><a href={dropHref(step.collection)}>View drop</a></Button>\n {step.links.length > 0 && (\n <Button variant=\"outline\" onClick={() => downloadCsv(popClaimLinksCsv(step.links), \"claim-links.csv\")}>Download claim links</Button>\n )}\n </div>\n {step.links.length > 0 && <p className=\"text-xs text-muted-foreground\">Send each wallet its link — the link is what lets it mint.</p>}\n </>\n )}\n </div>\n </ActionDialog>\n );\n}\n\nfunction Row({ label, value }: { label: string; value: string }) {\n return <div className=\"flex justify-between gap-3\"><span className=\"text-muted-foreground\">{label}</span><span className=\"text-right font-medium\">{value}</span></div>;\n}\n\nexport function downloadCsv(csv: string, name: string) {\n const href = URL.createObjectURL(new Blob([csv], { type: \"text/csv\" }));\n Object.assign(document.createElement(\"a\"), { href, download: name }).click();\n URL.revokeObjectURL(href);\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../src/components/drop/create/launch-dialog.tsx"],"sourcesContent":["\"use client\";\n\nimport { useMemo, useState } from \"react\";\nimport { CheckCircle2, Loader2, RotateCcw, XCircle } from \"lucide-react\";\nimport { dropHref } from \"@medialane/sdk\";\nimport { buildPopAllowlist, dropClaimLinks, popClaimLinksCsv, type PopClaimLink } from \"@medialane/sdk/starknet\";\nimport { ActionDialog } from \"../../action-dialog.js\";\nimport { GradientButton } from \"../../gradient-button.js\";\nimport { Button } from \"../../button.js\";\nimport { ShareButton } from \"../../share-button.js\";\nimport { describeError } from \"../../../utils/describe-error.js\";\nimport { uploadDirectoryToIpfs, uploadFileToIpfs } from \"../../../utils/ipfs-upload.js\";\nimport { parseAllowlist } from \"../../../utils/drop/allowlist.js\";\nimport { buildDropMetadataFiles, metadataBytes, MAX_DROP_METADATA_BYTES } from \"../../../utils/drop/metadata.js\";\nimport { toDropTerms, priceLabel } from \"../../../utils/drop/sale.js\";\nimport { draftSupply, type DropDraft } from \"../../../utils/drop/draft.js\";\nimport { uploadAll, type UploadTask } from \"../../../utils/drop/upload.js\";\nimport { launchDrop, saveExclusiveContent } from \"../../../utils/drop/actions.js\";\nimport { useMedialaneApp } from \"../../medialane-app.js\";\n\ntype Step =\n | { kind: \"review\" }\n | { kind: \"uploading\" }\n | { kind: \"launching\" }\n | { kind: \"done\"; collection: string; links: PopClaimLink[]; warning: string | null }\n | { kind: \"error\"; message: string };\n\nexport function LaunchDialog({ open, onClose, draft }: { open: boolean; onClose: () => void; draft: DropDraft }) {\n const app = useMedialaneApp();\n const [step, setStep] = useState<Step>({ kind: \"review\" });\n const [tasks, setTasks] = useState<UploadTask[]>([]);\n const [baseUri, setBaseUri] = useState<string | null>(null);\n const client = app.getClient();\n const files = draft.kind === \"edition\" ? (draft.edition ? [draft.edition] : []) : draft.items.map((i) => i.file);\n const terms = toDropTerms(draft.sale);\n const list = useMemo(\n () => (draft.listOnly ? buildPopAllowlist(parseAllowlist(draft.allowlist).addresses) : null),\n [draft.listOnly, draft.allowlist],\n );\n\n const run = async () => {\n try {\n let uri = baseUri;\n if (!uri) {\n setStep({ kind: \"uploading\" });\n const initial = tasks.length > 0 ? tasks : [\n ...files.map((file, i) => ({ id: `art-${i}`, file, status: \"pending\" as const, uri: null, error: null })),\n ...(draft.cover ? [{ id: \"cover\", file: draft.cover, status: \"pending\" as const, uri: null, error: null }] : []),\n ];\n const done = await uploadAll(initial, async (f) => (await uploadFileToIpfs(client.api, f, \"image\")).uri, setTasks);\n setTasks(done);\n if (done.some((t) => t.status !== \"done\")) {\n setStep({ kind: \"error\", message: \"Some files didn't upload. Retry to send only those.\" });\n return;\n }\n const art = done.filter((t) => t.id.startsWith(\"art-\"));\n const metadata = buildDropMetadataFiles({\n kind: draft.kind,\n name: draft.name.trim(),\n description: draft.description.trim(),\n creator: app.walletAddress!,\n coverUri: done.find((t) => t.id === \"cover\")?.uri ?? null,\n license: draft.license,\n items: draft.kind === \"edition\"\n ? [{ name: \"\", description: \"\", imageUri: art[0]!.uri! }]\n : draft.items.map((it, i) => ({ name: it.name, description: it.description, imageUri: art[i]!.uri! })),\n supply: draftSupply(draft),\n });\n if (metadataBytes(metadata) > MAX_DROP_METADATA_BYTES) {\n setStep({ kind: \"error\", message: \"The descriptions are too long for this many tokens. Shorten them and try again.\" });\n return;\n }\n uri = (await uploadDirectoryToIpfs(client.api, metadata)).baseUri;\n setBaseUri(uri);\n }\n setStep({ kind: \"launching\" });\n const signer = await app.getSigner();\n const { collection } = await launchDrop({ client, signer }, {\n owner: app.walletAddress!,\n name: draft.name.trim(),\n symbol: draft.symbol,\n baseUri: uri!,\n maxSupply: draftSupply(draft),\n terms,\n allowlistRoot: list?.root,\n description: draft.description.trim() || undefined,\n });\n let warning: string | null = null;\n if (draft.gated.enabled) {\n try {\n await saveExclusiveContent(client, collection, draft.gated);\n } catch {\n warning = \"Your drop launched, but the exclusive content wasn't saved. You can add it from Manage.\";\n }\n }\n setStep({ kind: \"done\", collection, links: list ? dropClaimLinks(window.location.origin, collection, list) : [], warning });\n } catch (err) {\n setStep({ kind: \"error\", message: describeError(err).message });\n }\n };\n\n const close = () => {\n if (step.kind === \"uploading\" || step.kind === \"launching\") return;\n onClose();\n };\n\n return (\n <ActionDialog open={open} onClose={close}>\n <div className=\"space-y-5 p-6\">\n {step.kind === \"review\" && (\n <>\n <h2 className=\"text-lg font-semibold\">Review and launch</h2>\n <div className=\"space-y-2 rounded-xl border border-border p-4 text-sm\">\n <p className=\"font-semibold\">{draft.name}</p>\n <p className=\"text-xs font-semibold uppercase tracking-widest text-muted-foreground\">Fixed after launch</p>\n <Row label=\"Price\" value={priceLabel(terms.price, terms.paymentToken)} />\n <Row label=\"Supply\" value={`${draftSupply(draft).toLocaleString(\"en-US\")} ${draft.kind === \"edition\" ? (draftSupply(draft) === 1 ? \"copy\" : \"copies\") : draftSupply(draft) === 1 ? \"item\" : \"items\"}`} />\n <Row label=\"Starts\" value={terms.startTime === 0 ? \"At launch\" : new Date(terms.startTime * 1000).toLocaleString()} />\n <Row label=\"Ends\" value={terms.endTime === 0 ? \"No end date\" : new Date(terms.endTime * 1000).toLocaleString()} />\n <Row label=\"Per wallet\" value={terms.maxPerWallet === \"0\" ? \"No limit\" : terms.maxPerWallet} />\n <Row label=\"Who can mint\" value={list ? `${Object.keys(list.proofs).length} wallets on a list` : \"Everyone\"} />\n <p className=\"pt-1 text-xs text-muted-foreground\">The artwork and these terms can't be changed after launch. You can change the list later.</p>\n </div>\n <GradientButton big onClick={() => void run()}>Launch drop</GradientButton>\n </>\n )}\n {step.kind === \"uploading\" && (\n <>\n <h2 className=\"flex items-center gap-2 text-lg font-semibold\"><Loader2 className=\"h-4 w-4 animate-spin\" />Uploading</h2>\n <p className=\"text-sm text-muted-foreground\">{tasks.filter((t) => t.status === \"done\").length} of {tasks.length} files</p>\n </>\n )}\n {step.kind === \"launching\" && (\n <h2 className=\"flex items-center gap-2 text-lg font-semibold\"><Loader2 className=\"h-4 w-4 animate-spin\" />Launching your drop…</h2>\n )}\n {step.kind === \"error\" && (\n <>\n <h2 className=\"flex items-center gap-2 text-lg font-semibold\"><XCircle className=\"h-4 w-4 text-destructive\" />Not launched</h2>\n <p className=\"text-sm text-muted-foreground\">{step.message}</p>\n {tasks.some((t) => t.status === \"failed\") && (\n <ul className=\"space-y-1 text-xs text-muted-foreground\">\n {tasks.filter((t) => t.status === \"failed\").map((t) => <li key={t.id}>{t.file.name}: {t.error}</li>)}\n </ul>\n )}\n <Button onClick={() => void run()} className=\"gap-1.5\"><RotateCcw className=\"h-3.5 w-3.5\" />Try again</Button>\n </>\n )}\n {step.kind === \"done\" && (\n <>\n <h2 className=\"flex items-center gap-2 text-lg font-semibold\"><CheckCircle2 className=\"h-5 w-5 text-green-500\" />Your drop is live</h2>\n {step.warning && <p className=\"text-sm text-brand-orange\">{step.warning}</p>}\n <div className=\"flex flex-wrap gap-2\">\n <ShareButton title={draft.name} url={`${window.location.origin}${dropHref(step.collection)}`} variant=\"outline\" />\n <Button asChild variant=\"outline\"><a href={dropHref(step.collection)}>View drop</a></Button>\n {step.links.length > 0 && (\n <Button variant=\"outline\" onClick={() => downloadCsv(popClaimLinksCsv(step.links), \"claim-links.csv\")}>Download claim links</Button>\n )}\n </div>\n {step.links.length > 0 && <p className=\"text-xs text-muted-foreground\">Send each wallet its link — the link is what lets it mint.</p>}\n </>\n )}\n </div>\n </ActionDialog>\n );\n}\n\nfunction Row({ label, value }: { label: string; value: string }) {\n return <div className=\"flex justify-between gap-3\"><span className=\"text-muted-foreground\">{label}</span><span className=\"text-right font-medium\">{value}</span></div>;\n}\n\nexport function downloadCsv(csv: string, name: string) {\n const href = URL.createObjectURL(new Blob([csv], { type: \"text/csv\" }));\n Object.assign(document.createElement(\"a\"), { href, download: name }).click();\n URL.revokeObjectURL(href);\n}\n"],"mappings":"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","names":[]}
@@ -84,7 +84,7 @@ function LaunchDialog({ open, onClose, draft }) {
84
84
  }
85
85
  setStep({ kind: "done", collection, links: list ? dropClaimLinks(window.location.origin, collection, list) : [], warning });
86
86
  } catch (err) {
87
- setStep({ kind: "error", message: describeError(err, "We couldn't launch your drop. Please try again.").message });
87
+ setStep({ kind: "error", message: describeError(err).message });
88
88
  }
89
89
  };
90
90
  const close = () => {