@medialane/ui 0.310.0 → 0.311.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.
- package/dist/components/account/input-otp.d.cts +2 -2
- package/dist/components/account/input-otp.d.ts +2 -2
- package/dist/components/activity-card.cjs +2 -2
- package/dist/components/activity-card.cjs.map +1 -1
- package/dist/components/activity-card.js +2 -2
- package/dist/components/activity-card.js.map +1 -1
- package/dist/components/animated-token-media.cjs +2 -2
- package/dist/components/animated-token-media.cjs.map +1 -1
- package/dist/components/animated-token-media.js +2 -2
- package/dist/components/animated-token-media.js.map +1 -1
- package/dist/components/asset-card.cjs +1 -1
- package/dist/components/asset-card.cjs.map +1 -1
- package/dist/components/asset-card.js +1 -1
- package/dist/components/asset-card.js.map +1 -1
- package/dist/components/badge.d.cts +1 -1
- package/dist/components/badge.d.ts +1 -1
- package/dist/components/button.d.cts +2 -2
- package/dist/components/button.d.ts +2 -2
- package/dist/components/collection-card.cjs +1 -1
- package/dist/components/collection-card.cjs.map +1 -1
- package/dist/components/collection-card.js +1 -1
- package/dist/components/collection-card.js.map +1 -1
- package/dist/components/creators-page.cjs +2 -2
- package/dist/components/creators-page.cjs.map +1 -1
- package/dist/components/creators-page.js +2 -2
- package/dist/components/creators-page.js.map +1 -1
- package/dist/components/drop/drop-card.cjs +1 -1
- package/dist/components/drop/drop-card.cjs.map +1 -1
- package/dist/components/drop/drop-card.js +1 -1
- package/dist/components/drop/drop-card.js.map +1 -1
- package/dist/components/editions-page.cjs +1 -1
- package/dist/components/editions-page.cjs.map +1 -1
- package/dist/components/editions-page.js +1 -1
- package/dist/components/editions-page.js.map +1 -1
- package/dist/components/launchpad/edition-mint-schema.d.cts +2 -2
- package/dist/components/launchpad/edition-mint-schema.d.ts +2 -2
- package/dist/components/listing-card.cjs +4 -4
- package/dist/components/listing-card.cjs.map +1 -1
- package/dist/components/listing-card.js +4 -4
- package/dist/components/listing-card.js.map +1 -1
- package/dist/components/media-wallet/nft-strip.cjs +1 -1
- package/dist/components/media-wallet/nft-strip.cjs.map +1 -1
- package/dist/components/media-wallet/nft-strip.js +1 -1
- package/dist/components/media-wallet/nft-strip.js.map +1 -1
- package/dist/components/remix-browse-page.cjs +1 -1
- package/dist/components/remix-browse-page.cjs.map +1 -1
- package/dist/components/remix-browse-page.js +1 -1
- package/dist/components/remix-browse-page.js.map +1 -1
- package/dist/components/token-card.cjs +1 -1
- package/dist/components/token-card.cjs.map +1 -1
- package/dist/components/token-card.js +1 -1
- package/dist/components/token-card.js.map +1 -1
- package/dist/medialane.css +7 -0
- package/dist/utils/media-wallet/use-erc20-balance.d.cts +1 -1
- package/dist/utils/media-wallet/use-erc20-balance.d.ts +1 -1
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as input_otp from 'input-otp';
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
|
|
4
|
-
declare const InputOTP: React.ForwardRefExoticComponent<(Omit<Omit<React.InputHTMLAttributes<HTMLInputElement>, "
|
|
4
|
+
declare const InputOTP: React.ForwardRefExoticComponent<(Omit<Omit<React.InputHTMLAttributes<HTMLInputElement>, "value" | "onChange" | "maxLength" | "textAlign" | "onComplete" | "pushPasswordManagerStrategy" | "pasteTransformer" | "containerClassName" | "noScriptCSSFallback"> & {
|
|
5
5
|
value?: string;
|
|
6
6
|
onChange?: (newValue: string) => unknown;
|
|
7
7
|
maxLength: number;
|
|
@@ -14,7 +14,7 @@ declare const InputOTP: React.ForwardRefExoticComponent<(Omit<Omit<React.InputHT
|
|
|
14
14
|
} & {
|
|
15
15
|
render: (props: input_otp.RenderProps) => React.ReactNode;
|
|
16
16
|
children?: never;
|
|
17
|
-
} & React.RefAttributes<HTMLInputElement>, "ref"> | Omit<Omit<React.InputHTMLAttributes<HTMLInputElement>, "
|
|
17
|
+
} & React.RefAttributes<HTMLInputElement>, "ref"> | Omit<Omit<React.InputHTMLAttributes<HTMLInputElement>, "value" | "onChange" | "maxLength" | "textAlign" | "onComplete" | "pushPasswordManagerStrategy" | "pasteTransformer" | "containerClassName" | "noScriptCSSFallback"> & {
|
|
18
18
|
value?: string;
|
|
19
19
|
onChange?: (newValue: string) => unknown;
|
|
20
20
|
maxLength: number;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as input_otp from 'input-otp';
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
|
|
4
|
-
declare const InputOTP: React.ForwardRefExoticComponent<(Omit<Omit<React.InputHTMLAttributes<HTMLInputElement>, "
|
|
4
|
+
declare const InputOTP: React.ForwardRefExoticComponent<(Omit<Omit<React.InputHTMLAttributes<HTMLInputElement>, "value" | "onChange" | "maxLength" | "textAlign" | "onComplete" | "pushPasswordManagerStrategy" | "pasteTransformer" | "containerClassName" | "noScriptCSSFallback"> & {
|
|
5
5
|
value?: string;
|
|
6
6
|
onChange?: (newValue: string) => unknown;
|
|
7
7
|
maxLength: number;
|
|
@@ -14,7 +14,7 @@ declare const InputOTP: React.ForwardRefExoticComponent<(Omit<Omit<React.InputHT
|
|
|
14
14
|
} & {
|
|
15
15
|
render: (props: input_otp.RenderProps) => React.ReactNode;
|
|
16
16
|
children?: never;
|
|
17
|
-
} & React.RefAttributes<HTMLInputElement>, "ref"> | Omit<Omit<React.InputHTMLAttributes<HTMLInputElement>, "
|
|
17
|
+
} & React.RefAttributes<HTMLInputElement>, "ref"> | Omit<Omit<React.InputHTMLAttributes<HTMLInputElement>, "value" | "onChange" | "maxLength" | "textAlign" | "onComplete" | "pushPasswordManagerStrategy" | "pasteTransformer" | "containerClassName" | "noScriptCSSFallback"> & {
|
|
18
18
|
value?: string;
|
|
19
19
|
onChange?: (newValue: string) => unknown;
|
|
20
20
|
maxLength: number;
|
|
@@ -88,7 +88,7 @@ function ActivityCard({
|
|
|
88
88
|
const shortActor = actor ? actor.length > 10 ? `${actor.slice(0, 6)}\u2026${actor.slice(-4)}` : actor : null;
|
|
89
89
|
const message = ACTIVITY_MESSAGES[activity.type]?.(shortActor) ?? config.label;
|
|
90
90
|
const body = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
91
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "aspect-square relative bg-muted", children: [
|
|
91
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "aspect-square relative overflow-hidden bg-muted", children: [
|
|
92
92
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
93
93
|
import_animated_token_media.AnimatedTokenMedia,
|
|
94
94
|
{
|
|
@@ -131,7 +131,7 @@ function ActivityCard({
|
|
|
131
131
|
] })
|
|
132
132
|
] })
|
|
133
133
|
] });
|
|
134
|
-
const className = "card-base block active:scale-[0.99] transition-all";
|
|
134
|
+
const className = "card-base group block active:scale-[0.99] transition-all";
|
|
135
135
|
return contract && tokenId ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_link.default, { href: (0, import_sdk.assetHref)(activity.chain ?? "STARKNET", contract, tokenId), className, children: body }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className, children: body });
|
|
136
136
|
}
|
|
137
137
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/activity-card.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"./link.js\";\nimport { ExternalLink } from \"lucide-react\";\nimport { CurrencyIcon } from \"./currency-icon.js\";\nimport { AnimatedTokenMedia } from \"./animated-token-media.js\";\nimport { ACTIVITY_TYPE_CONFIG } from \"../data/activity.js\";\nimport { isLivingRenderCollection } from \"../data/living-render-collections.js\";\nimport { timeAgo } from \"../utils/time.js\";\nimport { formatDisplayPrice } from \"../utils/format.js\";\nimport { cn } from \"../utils/cn.js\";\nimport { assetHref, type ApiActivity, type Chain } from \"@medialane/sdk\";\nimport { useImageUrl } from \"../utils/use-image-url.js\";\n\ntype ActivityWithEnrichment = ApiActivity & {\n chain?: Chain;\n token?: { name: string | null; image: string | null; animationUrl?: string | null } | null;\n amount?: string;\n};\n\nexport const ACTIVITY_MESSAGES: Record<string, (actor: string | null) => string> = {\n mint: (actor) => actor ? `Minted by ${actor}` : \"Newly minted\",\n listing: (actor) => actor ? `Listed by ${actor}` : \"Listed for sale\",\n sale: (actor) => actor ? `Purchased by ${actor}` : \"Sold\",\n offer: (actor) => actor ? `Offer by ${actor}` : \"Offer placed\",\n transfer: (actor) => actor ? `Transferred by ${actor}` : \"Transferred\",\n cancelled: (actor) => actor ? `Cancelled by ${actor}` : \"Listing cancelled\",\n};\n\nexport function ActivityCardSkeleton() {\n return (\n <div className=\"card-base\">\n <div className=\"aspect-square w-full bg-muted animate-pulse\" />\n <div className=\"p-4 space-y-2\">\n <div className=\"h-4 w-32 bg-muted animate-pulse rounded\" />\n <div className=\"h-3 w-24 bg-muted animate-pulse rounded\" />\n </div>\n </div>\n );\n}\n\nexport interface ActivityCardProps {\n activity: ApiActivity;\n\n}\n\nexport function ActivityCard({\n activity: rawActivity,\n}: ActivityCardProps) {\n const resolveImage = useImageUrl();\n const activity = rawActivity as ActivityWithEnrichment;\n const config = ACTIVITY_TYPE_CONFIG[activity.type] ?? {\n label: activity.type,\n variant: \"outline\" as const,\n icon: ExternalLink,\n colorClass: \"text-muted-foreground\",\n bgClass: \"bg-muted\",\n };\n const Icon = config.icon;\n\n const contract = activity.nftContract ?? activity.contractAddress ?? null;\n const tokenId = activity.nftTokenId ?? activity.tokenId ?? null;\n const actor =\n activity.offerer ??\n activity.fulfiller ??\n ((activity.type as string) === \"mint\" ? activity.to : activity.from) ??\n null;\n\n const tokenName = activity.token?.name ?? (tokenId ? `#${tokenId}` : \"—\");\n const rawImage = activity.token?.image ?? null;\n const tokenImage = resolveImage(rawImage);\n\n const animationUrl = activity.token?.animationUrl ?? null;\n const live = !!(activity.chain && contract) && isLivingRenderCollection(activity.chain.toUpperCase() as Chain, contract);\n const amount = activity.amount && Number(activity.amount) > 1 ? activity.amount : null;\n\n const shortActor = actor\n ? actor.length > 10\n ? `${actor.slice(0, 6)}…${actor.slice(-4)}`\n : actor\n : null;\n const message = ACTIVITY_MESSAGES[activity.type]?.(shortActor) ?? config.label;\n\n const body = (\n <>\n <div className=\"aspect-square relative bg-muted\">\n <AnimatedTokenMedia\n image={tokenImage}\n animationUrl={animationUrl}\n live={live}\n alt={tokenName}\n mode=\"fill\"\n sizes=\"256px\"\n className=\"object-cover\"\n fallback={\n <div className=\"absolute inset-0 bg-gradient-to-br from-muted-foreground/10 to-muted-foreground/5\" aria-hidden />\n }\n />\n\n <span className=\"absolute top-2.5 left-2.5 inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-2xs font-semibold bg-background/75 backdrop-blur-md border border-border/40\">\n <Icon className={cn(\"h-3 w-3\", config.colorClass)} aria-hidden />\n <span className={config.colorClass}>{config.label}</span>\n </span>\n {amount && (\n <span className=\"absolute bottom-2.5 right-2.5 px-2 py-0.5 rounded-full text-2xs font-bold bg-violet-500 text-white\">\n ×{amount}\n </span>\n )}\n </div>\n <div className=\"p-4 space-y-1.5\">\n <p className=\"text-base font-semibold truncate\">{tokenName}</p>\n <p\n className=\"text-xs text-muted-foreground truncate\"\n title={new Date(activity.timestamp).toLocaleString()}\n >\n {message} · {timeAgo(activity.timestamp)}\n </p>\n {activity.price?.formatted && (\n <p className=\"text-sm font-bold tabular-nums flex items-center gap-1.5 pt-0.5\">\n {activity.price.currency && <CurrencyIcon symbol={activity.price.currency} size={13} aria-hidden />}\n {formatDisplayPrice(activity.price.formatted)}\n </p>\n )}\n </div>\n </>\n );\n\n const className = \"card-base block active:scale-[0.99] transition-all\";\n\n return contract && tokenId ? (\n <Link href={assetHref(activity.chain ?? \"STARKNET\", contract, tokenId)} className={className}>\n {body}\n </Link>\n ) : (\n <div className={className}>{body}</div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAgCM;AA9BN,kBAAiB;AACjB,0BAA6B;AAC7B,2BAA6B;AAC7B,kCAAmC;AACnC,sBAAqC;AACrC,uCAAyC;AACzC,kBAAwB;AACxB,oBAAmC;AACnC,gBAAmB;AACnB,iBAAwD;AACxD,2BAA4B;AAQrB,MAAM,oBAAsE;AAAA,EACjF,MAAW,CAAC,UAAU,QAAQ,aAAa,KAAK,KAAK;AAAA,EACrD,SAAW,CAAC,UAAU,QAAQ,aAAa,KAAK,KAAK;AAAA,EACrD,MAAW,CAAC,UAAU,QAAQ,gBAAgB,KAAK,KAAK;AAAA,EACxD,OAAW,CAAC,UAAU,QAAQ,YAAY,KAAK,KAAK;AAAA,EACpD,UAAW,CAAC,UAAU,QAAQ,kBAAkB,KAAK,KAAK;AAAA,EAC1D,WAAW,CAAC,UAAU,QAAQ,gBAAgB,KAAK,KAAK;AAC1D;AAEO,SAAS,uBAAuB;AACrC,SACE,6CAAC,SAAI,WAAU,aACb;AAAA,gDAAC,SAAI,WAAU,+CAA8C;AAAA,IAC7D,6CAAC,SAAI,WAAU,iBACb;AAAA,kDAAC,SAAI,WAAU,2CAA0C;AAAA,MACzD,4CAAC,SAAI,WAAU,2CAA0C;AAAA,OAC3D;AAAA,KACF;AAEJ;AAOO,SAAS,aAAa;AAAA,EAC3B,UAAU;AACZ,GAAsB;AACpB,QAAM,mBAAe,kCAAY;AACjC,QAAM,WAAW;AACjB,QAAM,SAAS,qCAAqB,SAAS,IAAI,KAAK;AAAA,IACpD,OAAO,SAAS;AAAA,IAChB,SAAS;AAAA,IACT,MAAM;AAAA,IACN,YAAY;AAAA,IACZ,SAAS;AAAA,EACX;AACA,QAAM,OAAO,OAAO;AAEpB,QAAM,WAAW,SAAS,eAAe,SAAS,mBAAmB;AACrE,QAAM,UAAU,SAAS,cAAc,SAAS,WAAW;AAC3D,QAAM,QACJ,SAAS,WACT,SAAS,cACP,SAAS,SAAoB,SAAS,SAAS,KAAK,SAAS,SAC/D;AAEF,QAAM,YAAY,SAAS,OAAO,SAAS,UAAU,IAAI,OAAO,KAAK;AACrE,QAAM,WAAW,SAAS,OAAO,SAAS;AAC1C,QAAM,aAAa,aAAa,QAAQ;AAExC,QAAM,eAAe,SAAS,OAAO,gBAAgB;AACrD,QAAM,OAAO,CAAC,EAAE,SAAS,SAAS,iBAAa,2DAAyB,SAAS,MAAM,YAAY,GAAY,QAAQ;AACvH,QAAM,SAAS,SAAS,UAAU,OAAO,SAAS,MAAM,IAAI,IAAI,SAAS,SAAS;AAElF,QAAM,aAAa,QACf,MAAM,SAAS,KACb,GAAG,MAAM,MAAM,GAAG,CAAC,CAAC,SAAI,MAAM,MAAM,EAAE,CAAC,KACvC,QACF;AACJ,QAAM,UAAU,kBAAkB,SAAS,IAAI,IAAI,UAAU,KAAK,OAAO;AAEzE,QAAM,OACJ,4EACE;AAAA,iDAAC,SAAI,WAAU,
|
|
1
|
+
{"version":3,"sources":["../../src/components/activity-card.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"./link.js\";\nimport { ExternalLink } from \"lucide-react\";\nimport { CurrencyIcon } from \"./currency-icon.js\";\nimport { AnimatedTokenMedia } from \"./animated-token-media.js\";\nimport { ACTIVITY_TYPE_CONFIG } from \"../data/activity.js\";\nimport { isLivingRenderCollection } from \"../data/living-render-collections.js\";\nimport { timeAgo } from \"../utils/time.js\";\nimport { formatDisplayPrice } from \"../utils/format.js\";\nimport { cn } from \"../utils/cn.js\";\nimport { assetHref, type ApiActivity, type Chain } from \"@medialane/sdk\";\nimport { useImageUrl } from \"../utils/use-image-url.js\";\n\ntype ActivityWithEnrichment = ApiActivity & {\n chain?: Chain;\n token?: { name: string | null; image: string | null; animationUrl?: string | null } | null;\n amount?: string;\n};\n\nexport const ACTIVITY_MESSAGES: Record<string, (actor: string | null) => string> = {\n mint: (actor) => actor ? `Minted by ${actor}` : \"Newly minted\",\n listing: (actor) => actor ? `Listed by ${actor}` : \"Listed for sale\",\n sale: (actor) => actor ? `Purchased by ${actor}` : \"Sold\",\n offer: (actor) => actor ? `Offer by ${actor}` : \"Offer placed\",\n transfer: (actor) => actor ? `Transferred by ${actor}` : \"Transferred\",\n cancelled: (actor) => actor ? `Cancelled by ${actor}` : \"Listing cancelled\",\n};\n\nexport function ActivityCardSkeleton() {\n return (\n <div className=\"card-base\">\n <div className=\"aspect-square w-full bg-muted animate-pulse\" />\n <div className=\"p-4 space-y-2\">\n <div className=\"h-4 w-32 bg-muted animate-pulse rounded\" />\n <div className=\"h-3 w-24 bg-muted animate-pulse rounded\" />\n </div>\n </div>\n );\n}\n\nexport interface ActivityCardProps {\n activity: ApiActivity;\n\n}\n\nexport function ActivityCard({\n activity: rawActivity,\n}: ActivityCardProps) {\n const resolveImage = useImageUrl();\n const activity = rawActivity as ActivityWithEnrichment;\n const config = ACTIVITY_TYPE_CONFIG[activity.type] ?? {\n label: activity.type,\n variant: \"outline\" as const,\n icon: ExternalLink,\n colorClass: \"text-muted-foreground\",\n bgClass: \"bg-muted\",\n };\n const Icon = config.icon;\n\n const contract = activity.nftContract ?? activity.contractAddress ?? null;\n const tokenId = activity.nftTokenId ?? activity.tokenId ?? null;\n const actor =\n activity.offerer ??\n activity.fulfiller ??\n ((activity.type as string) === \"mint\" ? activity.to : activity.from) ??\n null;\n\n const tokenName = activity.token?.name ?? (tokenId ? `#${tokenId}` : \"—\");\n const rawImage = activity.token?.image ?? null;\n const tokenImage = resolveImage(rawImage);\n\n const animationUrl = activity.token?.animationUrl ?? null;\n const live = !!(activity.chain && contract) && isLivingRenderCollection(activity.chain.toUpperCase() as Chain, contract);\n const amount = activity.amount && Number(activity.amount) > 1 ? activity.amount : null;\n\n const shortActor = actor\n ? actor.length > 10\n ? `${actor.slice(0, 6)}…${actor.slice(-4)}`\n : actor\n : null;\n const message = ACTIVITY_MESSAGES[activity.type]?.(shortActor) ?? config.label;\n\n const body = (\n <>\n <div className=\"aspect-square relative overflow-hidden bg-muted\">\n <AnimatedTokenMedia\n image={tokenImage}\n animationUrl={animationUrl}\n live={live}\n alt={tokenName}\n mode=\"fill\"\n sizes=\"256px\"\n className=\"object-cover\"\n fallback={\n <div className=\"absolute inset-0 bg-gradient-to-br from-muted-foreground/10 to-muted-foreground/5\" aria-hidden />\n }\n />\n\n <span className=\"absolute top-2.5 left-2.5 inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-2xs font-semibold bg-background/75 backdrop-blur-md border border-border/40\">\n <Icon className={cn(\"h-3 w-3\", config.colorClass)} aria-hidden />\n <span className={config.colorClass}>{config.label}</span>\n </span>\n {amount && (\n <span className=\"absolute bottom-2.5 right-2.5 px-2 py-0.5 rounded-full text-2xs font-bold bg-violet-500 text-white\">\n ×{amount}\n </span>\n )}\n </div>\n <div className=\"p-4 space-y-1.5\">\n <p className=\"text-base font-semibold truncate\">{tokenName}</p>\n <p\n className=\"text-xs text-muted-foreground truncate\"\n title={new Date(activity.timestamp).toLocaleString()}\n >\n {message} · {timeAgo(activity.timestamp)}\n </p>\n {activity.price?.formatted && (\n <p className=\"text-sm font-bold tabular-nums flex items-center gap-1.5 pt-0.5\">\n {activity.price.currency && <CurrencyIcon symbol={activity.price.currency} size={13} aria-hidden />}\n {formatDisplayPrice(activity.price.formatted)}\n </p>\n )}\n </div>\n </>\n );\n\n const className = \"card-base group block active:scale-[0.99] transition-all\";\n\n return contract && tokenId ? (\n <Link href={assetHref(activity.chain ?? \"STARKNET\", contract, tokenId)} className={className}>\n {body}\n </Link>\n ) : (\n <div className={className}>{body}</div>\n );\n}\n"],"mappings":"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","names":["Link"]}
|
|
@@ -53,7 +53,7 @@ function ActivityCard({
|
|
|
53
53
|
const shortActor = actor ? actor.length > 10 ? `${actor.slice(0, 6)}\u2026${actor.slice(-4)}` : actor : null;
|
|
54
54
|
const message = ACTIVITY_MESSAGES[activity.type]?.(shortActor) ?? config.label;
|
|
55
55
|
const body = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
56
|
-
/* @__PURE__ */ jsxs("div", { className: "aspect-square relative bg-muted", children: [
|
|
56
|
+
/* @__PURE__ */ jsxs("div", { className: "aspect-square relative overflow-hidden bg-muted", children: [
|
|
57
57
|
/* @__PURE__ */ jsx(
|
|
58
58
|
AnimatedTokenMedia,
|
|
59
59
|
{
|
|
@@ -96,7 +96,7 @@ function ActivityCard({
|
|
|
96
96
|
] })
|
|
97
97
|
] })
|
|
98
98
|
] });
|
|
99
|
-
const className = "card-base block active:scale-[0.99] transition-all";
|
|
99
|
+
const className = "card-base group block active:scale-[0.99] transition-all";
|
|
100
100
|
return contract && tokenId ? /* @__PURE__ */ jsx(Link, { href: assetHref(activity.chain ?? "STARKNET", contract, tokenId), className, children: body }) : /* @__PURE__ */ jsx("div", { className, children: body });
|
|
101
101
|
}
|
|
102
102
|
export {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/activity-card.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"./link.js\";\nimport { ExternalLink } from \"lucide-react\";\nimport { CurrencyIcon } from \"./currency-icon.js\";\nimport { AnimatedTokenMedia } from \"./animated-token-media.js\";\nimport { ACTIVITY_TYPE_CONFIG } from \"../data/activity.js\";\nimport { isLivingRenderCollection } from \"../data/living-render-collections.js\";\nimport { timeAgo } from \"../utils/time.js\";\nimport { formatDisplayPrice } from \"../utils/format.js\";\nimport { cn } from \"../utils/cn.js\";\nimport { assetHref, type ApiActivity, type Chain } from \"@medialane/sdk\";\nimport { useImageUrl } from \"../utils/use-image-url.js\";\n\ntype ActivityWithEnrichment = ApiActivity & {\n chain?: Chain;\n token?: { name: string | null; image: string | null; animationUrl?: string | null } | null;\n amount?: string;\n};\n\nexport const ACTIVITY_MESSAGES: Record<string, (actor: string | null) => string> = {\n mint: (actor) => actor ? `Minted by ${actor}` : \"Newly minted\",\n listing: (actor) => actor ? `Listed by ${actor}` : \"Listed for sale\",\n sale: (actor) => actor ? `Purchased by ${actor}` : \"Sold\",\n offer: (actor) => actor ? `Offer by ${actor}` : \"Offer placed\",\n transfer: (actor) => actor ? `Transferred by ${actor}` : \"Transferred\",\n cancelled: (actor) => actor ? `Cancelled by ${actor}` : \"Listing cancelled\",\n};\n\nexport function ActivityCardSkeleton() {\n return (\n <div className=\"card-base\">\n <div className=\"aspect-square w-full bg-muted animate-pulse\" />\n <div className=\"p-4 space-y-2\">\n <div className=\"h-4 w-32 bg-muted animate-pulse rounded\" />\n <div className=\"h-3 w-24 bg-muted animate-pulse rounded\" />\n </div>\n </div>\n );\n}\n\nexport interface ActivityCardProps {\n activity: ApiActivity;\n\n}\n\nexport function ActivityCard({\n activity: rawActivity,\n}: ActivityCardProps) {\n const resolveImage = useImageUrl();\n const activity = rawActivity as ActivityWithEnrichment;\n const config = ACTIVITY_TYPE_CONFIG[activity.type] ?? {\n label: activity.type,\n variant: \"outline\" as const,\n icon: ExternalLink,\n colorClass: \"text-muted-foreground\",\n bgClass: \"bg-muted\",\n };\n const Icon = config.icon;\n\n const contract = activity.nftContract ?? activity.contractAddress ?? null;\n const tokenId = activity.nftTokenId ?? activity.tokenId ?? null;\n const actor =\n activity.offerer ??\n activity.fulfiller ??\n ((activity.type as string) === \"mint\" ? activity.to : activity.from) ??\n null;\n\n const tokenName = activity.token?.name ?? (tokenId ? `#${tokenId}` : \"—\");\n const rawImage = activity.token?.image ?? null;\n const tokenImage = resolveImage(rawImage);\n\n const animationUrl = activity.token?.animationUrl ?? null;\n const live = !!(activity.chain && contract) && isLivingRenderCollection(activity.chain.toUpperCase() as Chain, contract);\n const amount = activity.amount && Number(activity.amount) > 1 ? activity.amount : null;\n\n const shortActor = actor\n ? actor.length > 10\n ? `${actor.slice(0, 6)}…${actor.slice(-4)}`\n : actor\n : null;\n const message = ACTIVITY_MESSAGES[activity.type]?.(shortActor) ?? config.label;\n\n const body = (\n <>\n <div className=\"aspect-square relative bg-muted\">\n <AnimatedTokenMedia\n image={tokenImage}\n animationUrl={animationUrl}\n live={live}\n alt={tokenName}\n mode=\"fill\"\n sizes=\"256px\"\n className=\"object-cover\"\n fallback={\n <div className=\"absolute inset-0 bg-gradient-to-br from-muted-foreground/10 to-muted-foreground/5\" aria-hidden />\n }\n />\n\n <span className=\"absolute top-2.5 left-2.5 inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-2xs font-semibold bg-background/75 backdrop-blur-md border border-border/40\">\n <Icon className={cn(\"h-3 w-3\", config.colorClass)} aria-hidden />\n <span className={config.colorClass}>{config.label}</span>\n </span>\n {amount && (\n <span className=\"absolute bottom-2.5 right-2.5 px-2 py-0.5 rounded-full text-2xs font-bold bg-violet-500 text-white\">\n ×{amount}\n </span>\n )}\n </div>\n <div className=\"p-4 space-y-1.5\">\n <p className=\"text-base font-semibold truncate\">{tokenName}</p>\n <p\n className=\"text-xs text-muted-foreground truncate\"\n title={new Date(activity.timestamp).toLocaleString()}\n >\n {message} · {timeAgo(activity.timestamp)}\n </p>\n {activity.price?.formatted && (\n <p className=\"text-sm font-bold tabular-nums flex items-center gap-1.5 pt-0.5\">\n {activity.price.currency && <CurrencyIcon symbol={activity.price.currency} size={13} aria-hidden />}\n {formatDisplayPrice(activity.price.formatted)}\n </p>\n )}\n </div>\n </>\n );\n\n const className = \"card-base block active:scale-[0.99] transition-all\";\n\n return contract && tokenId ? (\n <Link href={assetHref(activity.chain ?? \"STARKNET\", contract, tokenId)} className={className}>\n {body}\n </Link>\n ) : (\n <div className={className}>{body}</div>\n );\n}\n"],"mappings":";AAgCM,SAoDF,UApDE,KACA,YADA;AA9BN,OAAO,UAAU;AACjB,SAAS,oBAAoB;AAC7B,SAAS,oBAAoB;AAC7B,SAAS,0BAA0B;AACnC,SAAS,4BAA4B;AACrC,SAAS,gCAAgC;AACzC,SAAS,eAAe;AACxB,SAAS,0BAA0B;AACnC,SAAS,UAAU;AACnB,SAAS,iBAA+C;AACxD,SAAS,mBAAmB;AAQrB,MAAM,oBAAsE;AAAA,EACjF,MAAW,CAAC,UAAU,QAAQ,aAAa,KAAK,KAAK;AAAA,EACrD,SAAW,CAAC,UAAU,QAAQ,aAAa,KAAK,KAAK;AAAA,EACrD,MAAW,CAAC,UAAU,QAAQ,gBAAgB,KAAK,KAAK;AAAA,EACxD,OAAW,CAAC,UAAU,QAAQ,YAAY,KAAK,KAAK;AAAA,EACpD,UAAW,CAAC,UAAU,QAAQ,kBAAkB,KAAK,KAAK;AAAA,EAC1D,WAAW,CAAC,UAAU,QAAQ,gBAAgB,KAAK,KAAK;AAC1D;AAEO,SAAS,uBAAuB;AACrC,SACE,qBAAC,SAAI,WAAU,aACb;AAAA,wBAAC,SAAI,WAAU,+CAA8C;AAAA,IAC7D,qBAAC,SAAI,WAAU,iBACb;AAAA,0BAAC,SAAI,WAAU,2CAA0C;AAAA,MACzD,oBAAC,SAAI,WAAU,2CAA0C;AAAA,OAC3D;AAAA,KACF;AAEJ;AAOO,SAAS,aAAa;AAAA,EAC3B,UAAU;AACZ,GAAsB;AACpB,QAAM,eAAe,YAAY;AACjC,QAAM,WAAW;AACjB,QAAM,SAAS,qBAAqB,SAAS,IAAI,KAAK;AAAA,IACpD,OAAO,SAAS;AAAA,IAChB,SAAS;AAAA,IACT,MAAM;AAAA,IACN,YAAY;AAAA,IACZ,SAAS;AAAA,EACX;AACA,QAAM,OAAO,OAAO;AAEpB,QAAM,WAAW,SAAS,eAAe,SAAS,mBAAmB;AACrE,QAAM,UAAU,SAAS,cAAc,SAAS,WAAW;AAC3D,QAAM,QACJ,SAAS,WACT,SAAS,cACP,SAAS,SAAoB,SAAS,SAAS,KAAK,SAAS,SAC/D;AAEF,QAAM,YAAY,SAAS,OAAO,SAAS,UAAU,IAAI,OAAO,KAAK;AACrE,QAAM,WAAW,SAAS,OAAO,SAAS;AAC1C,QAAM,aAAa,aAAa,QAAQ;AAExC,QAAM,eAAe,SAAS,OAAO,gBAAgB;AACrD,QAAM,OAAO,CAAC,EAAE,SAAS,SAAS,aAAa,yBAAyB,SAAS,MAAM,YAAY,GAAY,QAAQ;AACvH,QAAM,SAAS,SAAS,UAAU,OAAO,SAAS,MAAM,IAAI,IAAI,SAAS,SAAS;AAElF,QAAM,aAAa,QACf,MAAM,SAAS,KACb,GAAG,MAAM,MAAM,GAAG,CAAC,CAAC,SAAI,MAAM,MAAM,EAAE,CAAC,KACvC,QACF;AACJ,QAAM,UAAU,kBAAkB,SAAS,IAAI,IAAI,UAAU,KAAK,OAAO;AAEzE,QAAM,OACJ,iCACE;AAAA,yBAAC,SAAI,WAAU,
|
|
1
|
+
{"version":3,"sources":["../../src/components/activity-card.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"./link.js\";\nimport { ExternalLink } from \"lucide-react\";\nimport { CurrencyIcon } from \"./currency-icon.js\";\nimport { AnimatedTokenMedia } from \"./animated-token-media.js\";\nimport { ACTIVITY_TYPE_CONFIG } from \"../data/activity.js\";\nimport { isLivingRenderCollection } from \"../data/living-render-collections.js\";\nimport { timeAgo } from \"../utils/time.js\";\nimport { formatDisplayPrice } from \"../utils/format.js\";\nimport { cn } from \"../utils/cn.js\";\nimport { assetHref, type ApiActivity, type Chain } from \"@medialane/sdk\";\nimport { useImageUrl } from \"../utils/use-image-url.js\";\n\ntype ActivityWithEnrichment = ApiActivity & {\n chain?: Chain;\n token?: { name: string | null; image: string | null; animationUrl?: string | null } | null;\n amount?: string;\n};\n\nexport const ACTIVITY_MESSAGES: Record<string, (actor: string | null) => string> = {\n mint: (actor) => actor ? `Minted by ${actor}` : \"Newly minted\",\n listing: (actor) => actor ? `Listed by ${actor}` : \"Listed for sale\",\n sale: (actor) => actor ? `Purchased by ${actor}` : \"Sold\",\n offer: (actor) => actor ? `Offer by ${actor}` : \"Offer placed\",\n transfer: (actor) => actor ? `Transferred by ${actor}` : \"Transferred\",\n cancelled: (actor) => actor ? `Cancelled by ${actor}` : \"Listing cancelled\",\n};\n\nexport function ActivityCardSkeleton() {\n return (\n <div className=\"card-base\">\n <div className=\"aspect-square w-full bg-muted animate-pulse\" />\n <div className=\"p-4 space-y-2\">\n <div className=\"h-4 w-32 bg-muted animate-pulse rounded\" />\n <div className=\"h-3 w-24 bg-muted animate-pulse rounded\" />\n </div>\n </div>\n );\n}\n\nexport interface ActivityCardProps {\n activity: ApiActivity;\n\n}\n\nexport function ActivityCard({\n activity: rawActivity,\n}: ActivityCardProps) {\n const resolveImage = useImageUrl();\n const activity = rawActivity as ActivityWithEnrichment;\n const config = ACTIVITY_TYPE_CONFIG[activity.type] ?? {\n label: activity.type,\n variant: \"outline\" as const,\n icon: ExternalLink,\n colorClass: \"text-muted-foreground\",\n bgClass: \"bg-muted\",\n };\n const Icon = config.icon;\n\n const contract = activity.nftContract ?? activity.contractAddress ?? null;\n const tokenId = activity.nftTokenId ?? activity.tokenId ?? null;\n const actor =\n activity.offerer ??\n activity.fulfiller ??\n ((activity.type as string) === \"mint\" ? activity.to : activity.from) ??\n null;\n\n const tokenName = activity.token?.name ?? (tokenId ? `#${tokenId}` : \"—\");\n const rawImage = activity.token?.image ?? null;\n const tokenImage = resolveImage(rawImage);\n\n const animationUrl = activity.token?.animationUrl ?? null;\n const live = !!(activity.chain && contract) && isLivingRenderCollection(activity.chain.toUpperCase() as Chain, contract);\n const amount = activity.amount && Number(activity.amount) > 1 ? activity.amount : null;\n\n const shortActor = actor\n ? actor.length > 10\n ? `${actor.slice(0, 6)}…${actor.slice(-4)}`\n : actor\n : null;\n const message = ACTIVITY_MESSAGES[activity.type]?.(shortActor) ?? config.label;\n\n const body = (\n <>\n <div className=\"aspect-square relative overflow-hidden bg-muted\">\n <AnimatedTokenMedia\n image={tokenImage}\n animationUrl={animationUrl}\n live={live}\n alt={tokenName}\n mode=\"fill\"\n sizes=\"256px\"\n className=\"object-cover\"\n fallback={\n <div className=\"absolute inset-0 bg-gradient-to-br from-muted-foreground/10 to-muted-foreground/5\" aria-hidden />\n }\n />\n\n <span className=\"absolute top-2.5 left-2.5 inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-2xs font-semibold bg-background/75 backdrop-blur-md border border-border/40\">\n <Icon className={cn(\"h-3 w-3\", config.colorClass)} aria-hidden />\n <span className={config.colorClass}>{config.label}</span>\n </span>\n {amount && (\n <span className=\"absolute bottom-2.5 right-2.5 px-2 py-0.5 rounded-full text-2xs font-bold bg-violet-500 text-white\">\n ×{amount}\n </span>\n )}\n </div>\n <div className=\"p-4 space-y-1.5\">\n <p className=\"text-base font-semibold truncate\">{tokenName}</p>\n <p\n className=\"text-xs text-muted-foreground truncate\"\n title={new Date(activity.timestamp).toLocaleString()}\n >\n {message} · {timeAgo(activity.timestamp)}\n </p>\n {activity.price?.formatted && (\n <p className=\"text-sm font-bold tabular-nums flex items-center gap-1.5 pt-0.5\">\n {activity.price.currency && <CurrencyIcon symbol={activity.price.currency} size={13} aria-hidden />}\n {formatDisplayPrice(activity.price.formatted)}\n </p>\n )}\n </div>\n </>\n );\n\n const className = \"card-base group block active:scale-[0.99] transition-all\";\n\n return contract && tokenId ? (\n <Link href={assetHref(activity.chain ?? \"STARKNET\", contract, tokenId)} className={className}>\n {body}\n </Link>\n ) : (\n <div className={className}>{body}</div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -92,7 +92,7 @@ function AnimatedTokenMedia({
|
|
|
92
92
|
unoptimized: true,
|
|
93
93
|
sizes,
|
|
94
94
|
priority,
|
|
95
|
-
className: (0, import_cn.cn)(className, "
|
|
95
|
+
className: (0, import_cn.cn)(className, "card-media", loaded ? "opacity-100" : "opacity-0"),
|
|
96
96
|
onLoad: () => setLoaded(true),
|
|
97
97
|
onError: handleImageError
|
|
98
98
|
}
|
|
@@ -105,7 +105,7 @@ function AnimatedTokenMedia({
|
|
|
105
105
|
height: 0,
|
|
106
106
|
sizes,
|
|
107
107
|
priority,
|
|
108
|
-
className: (0, import_cn.cn)(className ?? "w-full h-auto", "
|
|
108
|
+
className: (0, import_cn.cn)(className ?? "w-full h-auto", "card-media", loaded ? "opacity-100" : "opacity-0"),
|
|
109
109
|
onLoad: () => setLoaded(true),
|
|
110
110
|
onError: handleImageError
|
|
111
111
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/animated-token-media.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport Image from \"./image.js\";\nimport { useIntersectionActive } from \"../utils/use-intersection-active.js\";\nimport { cn } from \"../utils/cn.js\";\n\nexport interface AnimatedTokenMediaProps {\n\n image: string | null;\n alt: string;\n\n animationUrl?: string | null;\n\n live?: boolean;\n\n mode?: \"fill\" | \"natural\";\n className?: string;\n sizes?: string;\n priority?: boolean;\n\n imgError?: boolean;\n onImageError?: () => void;\n\n fallback?: React.ReactNode;\n}\n\nexport function AnimatedTokenMedia({\n image,\n alt,\n animationUrl,\n live = false,\n mode = \"fill\",\n className,\n sizes,\n priority,\n imgError: imgErrorProp,\n onImageError,\n fallback,\n}: AnimatedTokenMediaProps) {\n const [internalError, setInternalError] = useState(false);\n const imgError = imgErrorProp ?? internalError;\n const handleImageError = () => {\n setInternalError(true);\n onImageError?.();\n };\n\n const [loaded, setLoaded] = useState(false);\n useEffect(() => setLoaded(false), [image]);\n\n const [ref, isVisible] = useIntersectionActive<HTMLDivElement>();\n const showLive = live && !!animationUrl && isVisible;\n\n return (\n <div ref={ref} className={mode === \"fill\" ? \"absolute inset-0\" : \"relative w-full\"}>\n {showLive ? (\n <iframe\n src={animationUrl!}\n title={alt}\n sandbox=\"allow-scripts\"\n loading=\"lazy\"\n className={\n mode === \"fill\"\n ? \"absolute inset-0 w-full h-full border-0\"\n : \"w-full aspect-square border-0\"\n }\n />\n ) : image && !imgError ? (\n <>\n {!loaded && (\n <div\n className={cn(\n \"animate-[shimmer_1.6s_ease-in-out_infinite] bg-foreground/[0.06] absolute\",\n mode === \"fill\" ? \"inset-0\" : \"inset-x-0 top-0 aspect-square\"\n )}\n style={{\n backgroundImage:\n \"linear-gradient(90deg, transparent, color-mix(in srgb, var(--foreground) 8%, transparent), transparent)\",\n backgroundSize: \"200% 100%\",\n }}\n />\n )}\n {mode === \"fill\" ? (\n <Image\n src={image}\n alt={alt}\n fill\n unoptimized\n sizes={sizes}\n priority={priority}\n className={cn(className, \"
|
|
1
|
+
{"version":3,"sources":["../../src/components/animated-token-media.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport Image from \"./image.js\";\nimport { useIntersectionActive } from \"../utils/use-intersection-active.js\";\nimport { cn } from \"../utils/cn.js\";\n\nexport interface AnimatedTokenMediaProps {\n\n image: string | null;\n alt: string;\n\n animationUrl?: string | null;\n\n live?: boolean;\n\n mode?: \"fill\" | \"natural\";\n className?: string;\n sizes?: string;\n priority?: boolean;\n\n imgError?: boolean;\n onImageError?: () => void;\n\n fallback?: React.ReactNode;\n}\n\nexport function AnimatedTokenMedia({\n image,\n alt,\n animationUrl,\n live = false,\n mode = \"fill\",\n className,\n sizes,\n priority,\n imgError: imgErrorProp,\n onImageError,\n fallback,\n}: AnimatedTokenMediaProps) {\n const [internalError, setInternalError] = useState(false);\n const imgError = imgErrorProp ?? internalError;\n const handleImageError = () => {\n setInternalError(true);\n onImageError?.();\n };\n\n const [loaded, setLoaded] = useState(false);\n useEffect(() => setLoaded(false), [image]);\n\n const [ref, isVisible] = useIntersectionActive<HTMLDivElement>();\n const showLive = live && !!animationUrl && isVisible;\n\n return (\n <div ref={ref} className={mode === \"fill\" ? \"absolute inset-0\" : \"relative w-full\"}>\n {showLive ? (\n <iframe\n src={animationUrl!}\n title={alt}\n sandbox=\"allow-scripts\"\n loading=\"lazy\"\n className={\n mode === \"fill\"\n ? \"absolute inset-0 w-full h-full border-0\"\n : \"w-full aspect-square border-0\"\n }\n />\n ) : image && !imgError ? (\n <>\n {!loaded && (\n <div\n className={cn(\n \"animate-[shimmer_1.6s_ease-in-out_infinite] bg-foreground/[0.06] absolute\",\n mode === \"fill\" ? \"inset-0\" : \"inset-x-0 top-0 aspect-square\"\n )}\n style={{\n backgroundImage:\n \"linear-gradient(90deg, transparent, color-mix(in srgb, var(--foreground) 8%, transparent), transparent)\",\n backgroundSize: \"200% 100%\",\n }}\n />\n )}\n {mode === \"fill\" ? (\n <Image\n src={image}\n alt={alt}\n fill\n unoptimized\n sizes={sizes}\n priority={priority}\n className={cn(className, \"card-media\", loaded ? \"opacity-100\" : \"opacity-0\")}\n onLoad={() => setLoaded(true)}\n onError={handleImageError}\n />\n ) : (\n <Image\n src={image}\n alt={alt}\n width={0}\n height={0}\n sizes={sizes}\n priority={priority}\n className={cn(className ?? \"w-full h-auto\", \"card-media\", loaded ? \"opacity-100\" : \"opacity-0\")}\n onLoad={() => setLoaded(true)}\n onError={handleImageError}\n />\n )}\n </>\n ) : (\n fallback ?? null\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAwDQ;AAtDR,mBAAoC;AACpC,mBAAkB;AAClB,qCAAsC;AACtC,gBAAmB;AAsBZ,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV;AAAA,EACA;AACF,GAA4B;AAC1B,QAAM,CAAC,eAAe,gBAAgB,QAAI,uBAAS,KAAK;AACxD,QAAM,WAAW,gBAAgB;AACjC,QAAM,mBAAmB,MAAM;AAC7B,qBAAiB,IAAI;AACrB,mBAAe;AAAA,EACjB;AAEA,QAAM,CAAC,QAAQ,SAAS,QAAI,uBAAS,KAAK;AAC1C,8BAAU,MAAM,UAAU,KAAK,GAAG,CAAC,KAAK,CAAC;AAEzC,QAAM,CAAC,KAAK,SAAS,QAAI,sDAAsC;AAC/D,QAAM,WAAW,QAAQ,CAAC,CAAC,gBAAgB;AAE3C,SACE,4CAAC,SAAI,KAAU,WAAW,SAAS,SAAS,qBAAqB,mBAC9D,qBACC;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MACL,OAAO;AAAA,MACP,SAAQ;AAAA,MACR,SAAQ;AAAA,MACR,WACE,SAAS,SACL,4CACA;AAAA;AAAA,EAER,IACE,SAAS,CAAC,WACZ,4EACG;AAAA,KAAC,UACA;AAAA,MAAC;AAAA;AAAA,QACC,eAAW;AAAA,UACT;AAAA,UACA,SAAS,SAAS,YAAY;AAAA,QAChC;AAAA,QACA,OAAO;AAAA,UACL,iBACE;AAAA,UACF,gBAAgB;AAAA,QAClB;AAAA;AAAA,IACF;AAAA,IAED,SAAS,SACR;AAAA,MAAC,aAAAA;AAAA,MAAA;AAAA,QACC,KAAK;AAAA,QACL;AAAA,QACA,MAAI;AAAA,QACJ,aAAW;AAAA,QACX;AAAA,QACA;AAAA,QACA,eAAW,cAAG,WAAW,cAAc,SAAS,gBAAgB,WAAW;AAAA,QAC3E,QAAQ,MAAM,UAAU,IAAI;AAAA,QAC5B,SAAS;AAAA;AAAA,IACX,IAEA;AAAA,MAAC,aAAAA;AAAA,MAAA;AAAA,QACC,KAAK;AAAA,QACL;AAAA,QACA,OAAO;AAAA,QACP,QAAQ;AAAA,QACR;AAAA,QACA;AAAA,QACA,eAAW,cAAG,aAAa,iBAAiB,cAAc,SAAS,gBAAgB,WAAW;AAAA,QAC9F,QAAQ,MAAM,UAAU,IAAI;AAAA,QAC5B,SAAS;AAAA;AAAA,IACX;AAAA,KAEJ,IAEA,YAAY,MAEhB;AAEJ;","names":["Image"]}
|
|
@@ -59,7 +59,7 @@ function AnimatedTokenMedia({
|
|
|
59
59
|
unoptimized: true,
|
|
60
60
|
sizes,
|
|
61
61
|
priority,
|
|
62
|
-
className: cn(className, "
|
|
62
|
+
className: cn(className, "card-media", loaded ? "opacity-100" : "opacity-0"),
|
|
63
63
|
onLoad: () => setLoaded(true),
|
|
64
64
|
onError: handleImageError
|
|
65
65
|
}
|
|
@@ -72,7 +72,7 @@ function AnimatedTokenMedia({
|
|
|
72
72
|
height: 0,
|
|
73
73
|
sizes,
|
|
74
74
|
priority,
|
|
75
|
-
className: cn(className ?? "w-full h-auto", "
|
|
75
|
+
className: cn(className ?? "w-full h-auto", "card-media", loaded ? "opacity-100" : "opacity-0"),
|
|
76
76
|
onLoad: () => setLoaded(true),
|
|
77
77
|
onError: handleImageError
|
|
78
78
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/animated-token-media.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport Image from \"./image.js\";\nimport { useIntersectionActive } from \"../utils/use-intersection-active.js\";\nimport { cn } from \"../utils/cn.js\";\n\nexport interface AnimatedTokenMediaProps {\n\n image: string | null;\n alt: string;\n\n animationUrl?: string | null;\n\n live?: boolean;\n\n mode?: \"fill\" | \"natural\";\n className?: string;\n sizes?: string;\n priority?: boolean;\n\n imgError?: boolean;\n onImageError?: () => void;\n\n fallback?: React.ReactNode;\n}\n\nexport function AnimatedTokenMedia({\n image,\n alt,\n animationUrl,\n live = false,\n mode = \"fill\",\n className,\n sizes,\n priority,\n imgError: imgErrorProp,\n onImageError,\n fallback,\n}: AnimatedTokenMediaProps) {\n const [internalError, setInternalError] = useState(false);\n const imgError = imgErrorProp ?? internalError;\n const handleImageError = () => {\n setInternalError(true);\n onImageError?.();\n };\n\n const [loaded, setLoaded] = useState(false);\n useEffect(() => setLoaded(false), [image]);\n\n const [ref, isVisible] = useIntersectionActive<HTMLDivElement>();\n const showLive = live && !!animationUrl && isVisible;\n\n return (\n <div ref={ref} className={mode === \"fill\" ? \"absolute inset-0\" : \"relative w-full\"}>\n {showLive ? (\n <iframe\n src={animationUrl!}\n title={alt}\n sandbox=\"allow-scripts\"\n loading=\"lazy\"\n className={\n mode === \"fill\"\n ? \"absolute inset-0 w-full h-full border-0\"\n : \"w-full aspect-square border-0\"\n }\n />\n ) : image && !imgError ? (\n <>\n {!loaded && (\n <div\n className={cn(\n \"animate-[shimmer_1.6s_ease-in-out_infinite] bg-foreground/[0.06] absolute\",\n mode === \"fill\" ? \"inset-0\" : \"inset-x-0 top-0 aspect-square\"\n )}\n style={{\n backgroundImage:\n \"linear-gradient(90deg, transparent, color-mix(in srgb, var(--foreground) 8%, transparent), transparent)\",\n backgroundSize: \"200% 100%\",\n }}\n />\n )}\n {mode === \"fill\" ? (\n <Image\n src={image}\n alt={alt}\n fill\n unoptimized\n sizes={sizes}\n priority={priority}\n className={cn(className, \"
|
|
1
|
+
{"version":3,"sources":["../../src/components/animated-token-media.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport Image from \"./image.js\";\nimport { useIntersectionActive } from \"../utils/use-intersection-active.js\";\nimport { cn } from \"../utils/cn.js\";\n\nexport interface AnimatedTokenMediaProps {\n\n image: string | null;\n alt: string;\n\n animationUrl?: string | null;\n\n live?: boolean;\n\n mode?: \"fill\" | \"natural\";\n className?: string;\n sizes?: string;\n priority?: boolean;\n\n imgError?: boolean;\n onImageError?: () => void;\n\n fallback?: React.ReactNode;\n}\n\nexport function AnimatedTokenMedia({\n image,\n alt,\n animationUrl,\n live = false,\n mode = \"fill\",\n className,\n sizes,\n priority,\n imgError: imgErrorProp,\n onImageError,\n fallback,\n}: AnimatedTokenMediaProps) {\n const [internalError, setInternalError] = useState(false);\n const imgError = imgErrorProp ?? internalError;\n const handleImageError = () => {\n setInternalError(true);\n onImageError?.();\n };\n\n const [loaded, setLoaded] = useState(false);\n useEffect(() => setLoaded(false), [image]);\n\n const [ref, isVisible] = useIntersectionActive<HTMLDivElement>();\n const showLive = live && !!animationUrl && isVisible;\n\n return (\n <div ref={ref} className={mode === \"fill\" ? \"absolute inset-0\" : \"relative w-full\"}>\n {showLive ? (\n <iframe\n src={animationUrl!}\n title={alt}\n sandbox=\"allow-scripts\"\n loading=\"lazy\"\n className={\n mode === \"fill\"\n ? \"absolute inset-0 w-full h-full border-0\"\n : \"w-full aspect-square border-0\"\n }\n />\n ) : image && !imgError ? (\n <>\n {!loaded && (\n <div\n className={cn(\n \"animate-[shimmer_1.6s_ease-in-out_infinite] bg-foreground/[0.06] absolute\",\n mode === \"fill\" ? \"inset-0\" : \"inset-x-0 top-0 aspect-square\"\n )}\n style={{\n backgroundImage:\n \"linear-gradient(90deg, transparent, color-mix(in srgb, var(--foreground) 8%, transparent), transparent)\",\n backgroundSize: \"200% 100%\",\n }}\n />\n )}\n {mode === \"fill\" ? (\n <Image\n src={image}\n alt={alt}\n fill\n unoptimized\n sizes={sizes}\n priority={priority}\n className={cn(className, \"card-media\", loaded ? \"opacity-100\" : \"opacity-0\")}\n onLoad={() => setLoaded(true)}\n onError={handleImageError}\n />\n ) : (\n <Image\n src={image}\n alt={alt}\n width={0}\n height={0}\n sizes={sizes}\n priority={priority}\n className={cn(className ?? \"w-full h-auto\", \"card-media\", loaded ? \"opacity-100\" : \"opacity-0\")}\n onLoad={() => setLoaded(true)}\n onError={handleImageError}\n />\n )}\n </>\n ) : (\n fallback ?? null\n )}\n </div>\n );\n}\n"],"mappings":";AAwDQ,SAYA,UAZA,KAYA,YAZA;AAtDR,SAAS,WAAW,gBAAgB;AACpC,OAAO,WAAW;AAClB,SAAS,6BAA6B;AACtC,SAAS,UAAU;AAsBZ,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV;AAAA,EACA;AACF,GAA4B;AAC1B,QAAM,CAAC,eAAe,gBAAgB,IAAI,SAAS,KAAK;AACxD,QAAM,WAAW,gBAAgB;AACjC,QAAM,mBAAmB,MAAM;AAC7B,qBAAiB,IAAI;AACrB,mBAAe;AAAA,EACjB;AAEA,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,KAAK;AAC1C,YAAU,MAAM,UAAU,KAAK,GAAG,CAAC,KAAK,CAAC;AAEzC,QAAM,CAAC,KAAK,SAAS,IAAI,sBAAsC;AAC/D,QAAM,WAAW,QAAQ,CAAC,CAAC,gBAAgB;AAE3C,SACE,oBAAC,SAAI,KAAU,WAAW,SAAS,SAAS,qBAAqB,mBAC9D,qBACC;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MACL,OAAO;AAAA,MACP,SAAQ;AAAA,MACR,SAAQ;AAAA,MACR,WACE,SAAS,SACL,4CACA;AAAA;AAAA,EAER,IACE,SAAS,CAAC,WACZ,iCACG;AAAA,KAAC,UACA;AAAA,MAAC;AAAA;AAAA,QACC,WAAW;AAAA,UACT;AAAA,UACA,SAAS,SAAS,YAAY;AAAA,QAChC;AAAA,QACA,OAAO;AAAA,UACL,iBACE;AAAA,UACF,gBAAgB;AAAA,QAClB;AAAA;AAAA,IACF;AAAA,IAED,SAAS,SACR;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACL;AAAA,QACA,MAAI;AAAA,QACJ,aAAW;AAAA,QACX;AAAA,QACA;AAAA,QACA,WAAW,GAAG,WAAW,cAAc,SAAS,gBAAgB,WAAW;AAAA,QAC3E,QAAQ,MAAM,UAAU,IAAI;AAAA,QAC5B,SAAS;AAAA;AAAA,IACX,IAEA;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACL;AAAA,QACA,OAAO;AAAA,QACP,QAAQ;AAAA,QACR;AAAA,QACA;AAAA,QACA,WAAW,GAAG,aAAa,iBAAiB,cAAc,SAAS,gBAAgB,WAAW;AAAA,QAC9F,QAAQ,MAAM,UAAU,IAAI;AAAA,QAC5B,SAAS;AAAA;AAAA,IACX;AAAA,KAEJ,IAEA,YAAY,MAEhB;AAEJ;","names":[]}
|
|
@@ -79,7 +79,7 @@ function AssetCard({
|
|
|
79
79
|
alt: name,
|
|
80
80
|
mode: "fill",
|
|
81
81
|
sizes: "(max-width: 640px) 50vw, (max-width: 1024px) 33vw, 22vw",
|
|
82
|
-
className: "object-cover
|
|
82
|
+
className: "object-cover",
|
|
83
83
|
fallback: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "absolute inset-0 flex items-center justify-center bg-gradient-to-br from-brand-blue/25 via-brand-purple/25 to-brand-rose/25", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "text-sm font-semibold text-muted-foreground tabular-nums", children: [
|
|
84
84
|
"#",
|
|
85
85
|
fallbackId ?? "?"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/asset-card.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"./link.js\";\nimport { Loader2 } from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\nimport { PriceChipContent } from \"./dual-price.js\";\nimport { IpTypeBadge } from \"./ip-type-badge.js\";\nimport { SoulboundBadge } from \"./soulbound-card.js\";\nimport { AnimatedTokenMedia } from \"./animated-token-media.js\";\nimport { useImageUrl } from \"../utils/use-image-url.js\";\n\nexport interface AssetCardPrice {\n formatted?: string | null;\n currency?: string | null;\n\n usdValue?: string | null;\n}\n\nexport interface AssetCardProps {\n\n href: string;\n\n name: string;\n\n image?: string | null;\n\n animationUrl?: string | null;\n\n live?: boolean;\n\n subtitle?: string | null;\n\n ipType?: string | null;\n\n price?: AssetCardPrice | null;\n\n fallbackId?: string | null;\n\n indexing?: boolean;\n\n soulbound?: boolean;\n\n ipTypeBaseUrl?: string;\n className?: string;\n}\n\nexport function AssetCard({\n href,\n name,\n image,\n animationUrl,\n live = false,\n subtitle,\n ipType,\n price,\n fallbackId,\n indexing = false,\n soulbound = false,\n ipTypeBaseUrl = \"\",\n className,\n}: AssetCardProps) {\n const resolveImage = useImageUrl();\n const resolved = resolveImage(image, { width: 480 });\n const hasPrice = !!price?.formatted;\n\n return (\n <div\n className={cn(\n \"group relative flex flex-col w-full overflow-hidden rounded-xl bg-card\",\n className\n )}\n >\n\n {ipType && (\n <div className=\"absolute top-2 right-2 z-10\">\n <IpTypeBadge ipType={ipType} size=\"sm\" baseUrl={ipTypeBaseUrl} />\n </div>\n )}\n\n <Link href={href} className=\"block relative aspect-square bg-muted overflow-hidden\">\n <AnimatedTokenMedia\n image={resolved}\n animationUrl={animationUrl}\n live={live}\n alt={name}\n mode=\"fill\"\n sizes=\"(max-width: 640px) 50vw, (max-width: 1024px) 33vw, 22vw\"\n className=\"object-cover
|
|
1
|
+
{"version":3,"sources":["../../src/components/asset-card.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"./link.js\";\nimport { Loader2 } from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\nimport { PriceChipContent } from \"./dual-price.js\";\nimport { IpTypeBadge } from \"./ip-type-badge.js\";\nimport { SoulboundBadge } from \"./soulbound-card.js\";\nimport { AnimatedTokenMedia } from \"./animated-token-media.js\";\nimport { useImageUrl } from \"../utils/use-image-url.js\";\n\nexport interface AssetCardPrice {\n formatted?: string | null;\n currency?: string | null;\n\n usdValue?: string | null;\n}\n\nexport interface AssetCardProps {\n\n href: string;\n\n name: string;\n\n image?: string | null;\n\n animationUrl?: string | null;\n\n live?: boolean;\n\n subtitle?: string | null;\n\n ipType?: string | null;\n\n price?: AssetCardPrice | null;\n\n fallbackId?: string | null;\n\n indexing?: boolean;\n\n soulbound?: boolean;\n\n ipTypeBaseUrl?: string;\n className?: string;\n}\n\nexport function AssetCard({\n href,\n name,\n image,\n animationUrl,\n live = false,\n subtitle,\n ipType,\n price,\n fallbackId,\n indexing = false,\n soulbound = false,\n ipTypeBaseUrl = \"\",\n className,\n}: AssetCardProps) {\n const resolveImage = useImageUrl();\n const resolved = resolveImage(image, { width: 480 });\n const hasPrice = !!price?.formatted;\n\n return (\n <div\n className={cn(\n \"group relative flex flex-col w-full overflow-hidden rounded-xl bg-card\",\n className\n )}\n >\n\n {ipType && (\n <div className=\"absolute top-2 right-2 z-10\">\n <IpTypeBadge ipType={ipType} size=\"sm\" baseUrl={ipTypeBaseUrl} />\n </div>\n )}\n\n <Link href={href} className=\"block relative aspect-square bg-muted overflow-hidden\">\n <AnimatedTokenMedia\n image={resolved}\n animationUrl={animationUrl}\n live={live}\n alt={name}\n mode=\"fill\"\n sizes=\"(max-width: 640px) 50vw, (max-width: 1024px) 33vw, 22vw\"\n className=\"object-cover\"\n fallback={\n <div className=\"absolute inset-0 flex items-center justify-center bg-gradient-to-br from-brand-blue/25 via-brand-purple/25 to-brand-rose/25\">\n <span className=\"text-sm font-semibold text-muted-foreground tabular-nums\">\n #{fallbackId ?? \"?\"}\n </span>\n </div>\n }\n />\n\n {indexing && (\n <div className=\"absolute bottom-0 inset-x-0 flex items-center justify-center gap-1.5 bg-black/50 backdrop-blur-sm py-1.5\">\n <Loader2 className=\"h-3 w-3 animate-spin text-white/70\" />\n <span className=\"text-2xs text-white/70\">Indexing…</span>\n </div>\n )}\n </Link>\n\n <div className=\"px-3 py-3 space-y-1\">\n <Link href={href} className=\"block min-w-0\">\n <p className=\"text-base font-semibold tracking-tight line-clamp-2 break-words leading-snug\">\n {name}\n </p>\n {subtitle && (\n <p className=\"text-xs text-muted-foreground line-clamp-1 leading-snug\">\n {subtitle}\n </p>\n )}\n </Link>\n\n {soulbound && <SoulboundBadge />}\n\n {hasPrice && !indexing && (\n <div className=\"flex items-center gap-1.5 text-sm font-bold tabular-nums pt-0.5\">\n <PriceChipContent\n amountFormatted={price!.formatted}\n currency={price!.currency}\n usdValue={price!.usdValue}\n tone=\"solid\"\n />\n </div>\n )}\n </div>\n </div>\n );\n}\n\nexport function AssetCardSkeleton() {\n return (\n <div className=\"flex flex-col w-full overflow-hidden rounded-xl bg-card\">\n <div className=\"aspect-square w-full animate-pulse bg-muted\" />\n <div className=\"px-3 py-3 space-y-1.5\">\n <div className=\"h-4 w-3/4 rounded-md animate-pulse bg-muted\" />\n <div className=\"h-3.5 w-2/5 rounded-md animate-pulse bg-muted\" />\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA2EU;AAzEV,kBAAiB;AACjB,0BAAwB;AACxB,gBAAmB;AACnB,wBAAiC;AACjC,2BAA4B;AAC5B,4BAA+B;AAC/B,kCAAmC;AACnC,2BAA4B;AAqCrB,SAAS,UAAU;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,gBAAgB;AAAA,EAChB;AACF,GAAmB;AACjB,QAAM,mBAAe,kCAAY;AACjC,QAAM,WAAW,aAAa,OAAO,EAAE,OAAO,IAAI,CAAC;AACnD,QAAM,WAAW,CAAC,CAAC,OAAO;AAE1B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,eAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MAGC;AAAA,kBACC,4CAAC,SAAI,WAAU,+BACb,sDAAC,oCAAY,QAAgB,MAAK,MAAK,SAAS,eAAe,GACjE;AAAA,QAGF,6CAAC,YAAAA,SAAA,EAAK,MAAY,WAAU,yDAC1B;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,OAAO;AAAA,cACP;AAAA,cACA;AAAA,cACA,KAAK;AAAA,cACL,MAAK;AAAA,cACL,OAAM;AAAA,cACN,WAAU;AAAA,cACV,UACE,4CAAC,SAAI,WAAU,+HACb,uDAAC,UAAK,WAAU,4DAA2D;AAAA;AAAA,gBACvE,cAAc;AAAA,iBAClB,GACF;AAAA;AAAA,UAEJ;AAAA,UAEC,YACC,6CAAC,SAAI,WAAU,4GACb;AAAA,wDAAC,+BAAQ,WAAU,sCAAqC;AAAA,YACxD,4CAAC,UAAK,WAAU,0BAAyB,4BAAS;AAAA,aACpD;AAAA,WAEJ;AAAA,QAEA,6CAAC,SAAI,WAAU,uBACb;AAAA,uDAAC,YAAAA,SAAA,EAAK,MAAY,WAAU,iBAC1B;AAAA,wDAAC,OAAE,WAAU,gFACV,gBACH;AAAA,YACC,YACC,4CAAC,OAAE,WAAU,2DACV,oBACH;AAAA,aAEJ;AAAA,UAEC,aAAa,4CAAC,wCAAe;AAAA,UAE7B,YAAY,CAAC,YACZ,4CAAC,SAAI,WAAU,mEACb;AAAA,YAAC;AAAA;AAAA,cACC,iBAAiB,MAAO;AAAA,cACxB,UAAU,MAAO;AAAA,cACjB,UAAU,MAAO;AAAA,cACjB,MAAK;AAAA;AAAA,UACP,GACF;AAAA,WAEJ;AAAA;AAAA;AAAA,EACF;AAEJ;AAEO,SAAS,oBAAoB;AAClC,SACE,6CAAC,SAAI,WAAU,2DACb;AAAA,gDAAC,SAAI,WAAU,+CAA8C;AAAA,IAC7D,6CAAC,SAAI,WAAU,yBACb;AAAA,kDAAC,SAAI,WAAU,+CAA8C;AAAA,MAC7D,4CAAC,SAAI,WAAU,iDAAgD;AAAA,OACjE;AAAA,KACF;AAEJ;","names":["Link"]}
|
|
@@ -45,7 +45,7 @@ function AssetCard({
|
|
|
45
45
|
alt: name,
|
|
46
46
|
mode: "fill",
|
|
47
47
|
sizes: "(max-width: 640px) 50vw, (max-width: 1024px) 33vw, 22vw",
|
|
48
|
-
className: "object-cover
|
|
48
|
+
className: "object-cover",
|
|
49
49
|
fallback: /* @__PURE__ */ jsx("div", { className: "absolute inset-0 flex items-center justify-center bg-gradient-to-br from-brand-blue/25 via-brand-purple/25 to-brand-rose/25", children: /* @__PURE__ */ jsxs("span", { className: "text-sm font-semibold text-muted-foreground tabular-nums", children: [
|
|
50
50
|
"#",
|
|
51
51
|
fallbackId ?? "?"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/asset-card.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"./link.js\";\nimport { Loader2 } from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\nimport { PriceChipContent } from \"./dual-price.js\";\nimport { IpTypeBadge } from \"./ip-type-badge.js\";\nimport { SoulboundBadge } from \"./soulbound-card.js\";\nimport { AnimatedTokenMedia } from \"./animated-token-media.js\";\nimport { useImageUrl } from \"../utils/use-image-url.js\";\n\nexport interface AssetCardPrice {\n formatted?: string | null;\n currency?: string | null;\n\n usdValue?: string | null;\n}\n\nexport interface AssetCardProps {\n\n href: string;\n\n name: string;\n\n image?: string | null;\n\n animationUrl?: string | null;\n\n live?: boolean;\n\n subtitle?: string | null;\n\n ipType?: string | null;\n\n price?: AssetCardPrice | null;\n\n fallbackId?: string | null;\n\n indexing?: boolean;\n\n soulbound?: boolean;\n\n ipTypeBaseUrl?: string;\n className?: string;\n}\n\nexport function AssetCard({\n href,\n name,\n image,\n animationUrl,\n live = false,\n subtitle,\n ipType,\n price,\n fallbackId,\n indexing = false,\n soulbound = false,\n ipTypeBaseUrl = \"\",\n className,\n}: AssetCardProps) {\n const resolveImage = useImageUrl();\n const resolved = resolveImage(image, { width: 480 });\n const hasPrice = !!price?.formatted;\n\n return (\n <div\n className={cn(\n \"group relative flex flex-col w-full overflow-hidden rounded-xl bg-card\",\n className\n )}\n >\n\n {ipType && (\n <div className=\"absolute top-2 right-2 z-10\">\n <IpTypeBadge ipType={ipType} size=\"sm\" baseUrl={ipTypeBaseUrl} />\n </div>\n )}\n\n <Link href={href} className=\"block relative aspect-square bg-muted overflow-hidden\">\n <AnimatedTokenMedia\n image={resolved}\n animationUrl={animationUrl}\n live={live}\n alt={name}\n mode=\"fill\"\n sizes=\"(max-width: 640px) 50vw, (max-width: 1024px) 33vw, 22vw\"\n className=\"object-cover
|
|
1
|
+
{"version":3,"sources":["../../src/components/asset-card.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"./link.js\";\nimport { Loader2 } from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\nimport { PriceChipContent } from \"./dual-price.js\";\nimport { IpTypeBadge } from \"./ip-type-badge.js\";\nimport { SoulboundBadge } from \"./soulbound-card.js\";\nimport { AnimatedTokenMedia } from \"./animated-token-media.js\";\nimport { useImageUrl } from \"../utils/use-image-url.js\";\n\nexport interface AssetCardPrice {\n formatted?: string | null;\n currency?: string | null;\n\n usdValue?: string | null;\n}\n\nexport interface AssetCardProps {\n\n href: string;\n\n name: string;\n\n image?: string | null;\n\n animationUrl?: string | null;\n\n live?: boolean;\n\n subtitle?: string | null;\n\n ipType?: string | null;\n\n price?: AssetCardPrice | null;\n\n fallbackId?: string | null;\n\n indexing?: boolean;\n\n soulbound?: boolean;\n\n ipTypeBaseUrl?: string;\n className?: string;\n}\n\nexport function AssetCard({\n href,\n name,\n image,\n animationUrl,\n live = false,\n subtitle,\n ipType,\n price,\n fallbackId,\n indexing = false,\n soulbound = false,\n ipTypeBaseUrl = \"\",\n className,\n}: AssetCardProps) {\n const resolveImage = useImageUrl();\n const resolved = resolveImage(image, { width: 480 });\n const hasPrice = !!price?.formatted;\n\n return (\n <div\n className={cn(\n \"group relative flex flex-col w-full overflow-hidden rounded-xl bg-card\",\n className\n )}\n >\n\n {ipType && (\n <div className=\"absolute top-2 right-2 z-10\">\n <IpTypeBadge ipType={ipType} size=\"sm\" baseUrl={ipTypeBaseUrl} />\n </div>\n )}\n\n <Link href={href} className=\"block relative aspect-square bg-muted overflow-hidden\">\n <AnimatedTokenMedia\n image={resolved}\n animationUrl={animationUrl}\n live={live}\n alt={name}\n mode=\"fill\"\n sizes=\"(max-width: 640px) 50vw, (max-width: 1024px) 33vw, 22vw\"\n className=\"object-cover\"\n fallback={\n <div className=\"absolute inset-0 flex items-center justify-center bg-gradient-to-br from-brand-blue/25 via-brand-purple/25 to-brand-rose/25\">\n <span className=\"text-sm font-semibold text-muted-foreground tabular-nums\">\n #{fallbackId ?? \"?\"}\n </span>\n </div>\n }\n />\n\n {indexing && (\n <div className=\"absolute bottom-0 inset-x-0 flex items-center justify-center gap-1.5 bg-black/50 backdrop-blur-sm py-1.5\">\n <Loader2 className=\"h-3 w-3 animate-spin text-white/70\" />\n <span className=\"text-2xs text-white/70\">Indexing…</span>\n </div>\n )}\n </Link>\n\n <div className=\"px-3 py-3 space-y-1\">\n <Link href={href} className=\"block min-w-0\">\n <p className=\"text-base font-semibold tracking-tight line-clamp-2 break-words leading-snug\">\n {name}\n </p>\n {subtitle && (\n <p className=\"text-xs text-muted-foreground line-clamp-1 leading-snug\">\n {subtitle}\n </p>\n )}\n </Link>\n\n {soulbound && <SoulboundBadge />}\n\n {hasPrice && !indexing && (\n <div className=\"flex items-center gap-1.5 text-sm font-bold tabular-nums pt-0.5\">\n <PriceChipContent\n amountFormatted={price!.formatted}\n currency={price!.currency}\n usdValue={price!.usdValue}\n tone=\"solid\"\n />\n </div>\n )}\n </div>\n </div>\n );\n}\n\nexport function AssetCardSkeleton() {\n return (\n <div className=\"flex flex-col w-full overflow-hidden rounded-xl bg-card\">\n <div className=\"aspect-square w-full animate-pulse bg-muted\" />\n <div className=\"px-3 py-3 space-y-1.5\">\n <div className=\"h-4 w-3/4 rounded-md animate-pulse bg-muted\" />\n <div className=\"h-3.5 w-2/5 rounded-md animate-pulse bg-muted\" />\n </div>\n </div>\n );\n}\n"],"mappings":";AA2EU,cAeI,YAfJ;AAzEV,OAAO,UAAU;AACjB,SAAS,eAAe;AACxB,SAAS,UAAU;AACnB,SAAS,wBAAwB;AACjC,SAAS,mBAAmB;AAC5B,SAAS,sBAAsB;AAC/B,SAAS,0BAA0B;AACnC,SAAS,mBAAmB;AAqCrB,SAAS,UAAU;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,gBAAgB;AAAA,EAChB;AACF,GAAmB;AACjB,QAAM,eAAe,YAAY;AACjC,QAAM,WAAW,aAAa,OAAO,EAAE,OAAO,IAAI,CAAC;AACnD,QAAM,WAAW,CAAC,CAAC,OAAO;AAE1B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MAGC;AAAA,kBACC,oBAAC,SAAI,WAAU,+BACb,8BAAC,eAAY,QAAgB,MAAK,MAAK,SAAS,eAAe,GACjE;AAAA,QAGF,qBAAC,QAAK,MAAY,WAAU,yDAC1B;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,OAAO;AAAA,cACP;AAAA,cACA;AAAA,cACA,KAAK;AAAA,cACL,MAAK;AAAA,cACL,OAAM;AAAA,cACN,WAAU;AAAA,cACV,UACE,oBAAC,SAAI,WAAU,+HACb,+BAAC,UAAK,WAAU,4DAA2D;AAAA;AAAA,gBACvE,cAAc;AAAA,iBAClB,GACF;AAAA;AAAA,UAEJ;AAAA,UAEC,YACC,qBAAC,SAAI,WAAU,4GACb;AAAA,gCAAC,WAAQ,WAAU,sCAAqC;AAAA,YACxD,oBAAC,UAAK,WAAU,0BAAyB,4BAAS;AAAA,aACpD;AAAA,WAEJ;AAAA,QAEA,qBAAC,SAAI,WAAU,uBACb;AAAA,+BAAC,QAAK,MAAY,WAAU,iBAC1B;AAAA,gCAAC,OAAE,WAAU,gFACV,gBACH;AAAA,YACC,YACC,oBAAC,OAAE,WAAU,2DACV,oBACH;AAAA,aAEJ;AAAA,UAEC,aAAa,oBAAC,kBAAe;AAAA,UAE7B,YAAY,CAAC,YACZ,oBAAC,SAAI,WAAU,mEACb;AAAA,YAAC;AAAA;AAAA,cACC,iBAAiB,MAAO;AAAA,cACxB,UAAU,MAAO;AAAA,cACjB,UAAU,MAAO;AAAA,cACjB,MAAK;AAAA;AAAA,UACP,GACF;AAAA,WAEJ;AAAA;AAAA;AAAA,EACF;AAEJ;AAEO,SAAS,oBAAoB;AAClC,SACE,qBAAC,SAAI,WAAU,2DACb;AAAA,wBAAC,SAAI,WAAU,+CAA8C;AAAA,IAC7D,qBAAC,SAAI,WAAU,yBACb;AAAA,0BAAC,SAAI,WAAU,+CAA8C;AAAA,MAC7D,oBAAC,SAAI,WAAU,iDAAgD;AAAA,OACjE;AAAA,KACF;AAEJ;","names":[]}
|
|
@@ -4,7 +4,7 @@ import * as React from 'react';
|
|
|
4
4
|
import { VariantProps } from 'class-variance-authority';
|
|
5
5
|
|
|
6
6
|
declare const badgeVariants: (props?: ({
|
|
7
|
-
variant?: "default" | "
|
|
7
|
+
variant?: "default" | "destructive" | "outline" | "secondary" | null | undefined;
|
|
8
8
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
9
9
|
interface BadgeProps extends React.HTMLAttributes<HTMLDivElement>, VariantProps<typeof badgeVariants> {
|
|
10
10
|
}
|
|
@@ -4,7 +4,7 @@ import * as React from 'react';
|
|
|
4
4
|
import { VariantProps } from 'class-variance-authority';
|
|
5
5
|
|
|
6
6
|
declare const badgeVariants: (props?: ({
|
|
7
|
-
variant?: "default" | "
|
|
7
|
+
variant?: "default" | "destructive" | "outline" | "secondary" | null | undefined;
|
|
8
8
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
9
9
|
interface BadgeProps extends React.HTMLAttributes<HTMLDivElement>, VariantProps<typeof badgeVariants> {
|
|
10
10
|
}
|
|
@@ -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?: "link" | "default" | "
|
|
7
|
-
size?: "
|
|
6
|
+
variant?: "link" | "default" | "destructive" | "outline" | "secondary" | "ghost" | "premium" | "tonal" | "gradient-border" | "gradient-fill" | null | undefined;
|
|
7
|
+
size?: "icon" | "default" | "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?: "link" | "default" | "
|
|
7
|
-
size?: "
|
|
6
|
+
variant?: "link" | "default" | "destructive" | "outline" | "secondary" | "ghost" | "premium" | "tonal" | "gradient-border" | "gradient-fill" | null | undefined;
|
|
7
|
+
size?: "icon" | "default" | "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;
|
|
@@ -76,7 +76,7 @@ function CollectionCard({ collection, href, settingsHref, className }) {
|
|
|
76
76
|
src: imageUrl,
|
|
77
77
|
alt: collection.name ?? "Collection",
|
|
78
78
|
fill: true,
|
|
79
|
-
className: "object-cover
|
|
79
|
+
className: "object-cover card-media",
|
|
80
80
|
onError: () => setImgError(true),
|
|
81
81
|
unoptimized: true
|
|
82
82
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/collection-card.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport Link from \"./link.js\";\nimport Image from \"./image.js\";\nimport { Loader2, Settings2 } from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\nimport { formatDisplayPrice } from \"../utils/format.js\";\nimport { MotionCard } from \"./motion-primitives.js\";\nimport { CurrencyIcon } from \"./currency-icon.js\";\nimport type { ApiCollection } from \"@medialane/sdk\";\nimport { useImageUrl } from \"../utils/use-image-url.js\";\n\nfunction parseFloorPrice(floor: string | null | undefined): { amount: string; symbol: string } | null {\n if (!floor) return null;\n const formatted = formatDisplayPrice(floor);\n const parts = formatted.trim().split(/\\s+/);\n if (parts.length < 2) return null;\n const symbol = parts[parts.length - 1];\n const amount = parts.slice(0, -1).join(\" \");\n return { amount, symbol };\n}\n\nexport interface CollectionCardProps {\n collection: ApiCollection;\n\n href?: string;\n\n settingsHref?: string;\n className?: string;\n}\n\nexport function CollectionCard({ collection, href, settingsHref, className }: CollectionCardProps) {\n const resolveImage = useImageUrl();\n const [imgError, setImgError] = useState(false);\n const imageUrl = resolveImage(collection.image, { width: 480 });\n const showImage = imageUrl && !imgError;\n const floor = parseFloorPrice(collection.floorPrice);\n\n return (\n <MotionCard className={cn(\"card-base group relative\", className)}>\n {settingsHref && (\n <Link\n href={settingsHref}\n onClick={(e) => e.stopPropagation()}\n className=\"absolute top-2 right-2 z-10 min-h-11 min-w-11 rounded-full flex items-center justify-center\"\n aria-label=\"Collection settings\"\n >\n <span className=\"flex h-7 w-7 items-center justify-center rounded-full bg-black/40 backdrop-blur-sm text-white/70 hover:text-white hover:bg-black/60 transition-colors\">\n <Settings2 className=\"h-3.5 w-3.5\" />\n </span>\n </Link>\n )}\n\n <Link href={href ?? `/collections/${collection.contractAddress}`} className=\"block relative h-full\">\n <div className=\"relative aspect-square w-full overflow-hidden bg-muted\">\n {showImage ? (\n <Image\n src={imageUrl}\n alt={collection.name ?? \"Collection\"}\n fill\n className=\"object-cover
|
|
1
|
+
{"version":3,"sources":["../../src/components/collection-card.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport Link from \"./link.js\";\nimport Image from \"./image.js\";\nimport { Loader2, Settings2 } from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\nimport { formatDisplayPrice } from \"../utils/format.js\";\nimport { MotionCard } from \"./motion-primitives.js\";\nimport { CurrencyIcon } from \"./currency-icon.js\";\nimport type { ApiCollection } from \"@medialane/sdk\";\nimport { useImageUrl } from \"../utils/use-image-url.js\";\n\nfunction parseFloorPrice(floor: string | null | undefined): { amount: string; symbol: string } | null {\n if (!floor) return null;\n const formatted = formatDisplayPrice(floor);\n const parts = formatted.trim().split(/\\s+/);\n if (parts.length < 2) return null;\n const symbol = parts[parts.length - 1];\n const amount = parts.slice(0, -1).join(\" \");\n return { amount, symbol };\n}\n\nexport interface CollectionCardProps {\n collection: ApiCollection;\n\n href?: string;\n\n settingsHref?: string;\n className?: string;\n}\n\nexport function CollectionCard({ collection, href, settingsHref, className }: CollectionCardProps) {\n const resolveImage = useImageUrl();\n const [imgError, setImgError] = useState(false);\n const imageUrl = resolveImage(collection.image, { width: 480 });\n const showImage = imageUrl && !imgError;\n const floor = parseFloorPrice(collection.floorPrice);\n\n return (\n <MotionCard className={cn(\"card-base group relative\", className)}>\n {settingsHref && (\n <Link\n href={settingsHref}\n onClick={(e) => e.stopPropagation()}\n className=\"absolute top-2 right-2 z-10 min-h-11 min-w-11 rounded-full flex items-center justify-center\"\n aria-label=\"Collection settings\"\n >\n <span className=\"flex h-7 w-7 items-center justify-center rounded-full bg-black/40 backdrop-blur-sm text-white/70 hover:text-white hover:bg-black/60 transition-colors\">\n <Settings2 className=\"h-3.5 w-3.5\" />\n </span>\n </Link>\n )}\n\n <Link href={href ?? `/collections/${collection.contractAddress}`} className=\"block relative h-full\">\n <div className=\"relative aspect-square w-full overflow-hidden bg-muted\">\n {showImage ? (\n <Image\n src={imageUrl}\n alt={collection.name ?? \"Collection\"}\n fill\n className=\"object-cover card-media\"\n onError={() => setImgError(true)}\n unoptimized\n />\n ) : (\n <div className=\"absolute inset-0 bg-gradient-to-br from-brand-purple/30 via-brand-blue/20 to-brand-navy/40\" />\n )}\n\n <div className=\"absolute inset-x-2 bottom-2 flex flex-col items-start gap-1\">\n {!collection.name && collection.metadataStatus === \"PENDING\" ? (\n <span className=\"flex items-center gap-1 rounded-full px-2.5 py-1 text-2xs text-white bg-black/30 backdrop-blur-md\">\n <Loader2 className=\"h-2.5 w-2.5 animate-spin\" />\n Indexing…\n </span>\n ) : (\n <p className=\"max-w-full truncate rounded-full px-3 py-1 text-sm font-bold leading-tight text-white bg-black/30 backdrop-blur-md\">\n {collection.name ?? \"Unnamed Collection\"}\n </p>\n )}\n\n {(collection.totalSupply != null || floor) && (\n <div className=\"flex flex-wrap items-center gap-1\">\n {collection.totalSupply != null && (\n <span className=\"rounded-full px-2.5 py-1 text-2xs font-medium text-white bg-black/30 backdrop-blur-md\">\n {collection.totalSupply.toLocaleString()}\n </span>\n )}\n {floor && (\n <span className=\"inline-flex items-center gap-1 rounded-full px-2.5 py-1 text-2xs font-bold text-white bg-black/30 backdrop-blur-md\">\n Floor\n <CurrencyIcon symbol={floor.symbol} size={10} />\n {floor.amount}\n </span>\n )}\n </div>\n )}\n </div>\n </div>\n </Link>\n </MotionCard>\n );\n}\n\nexport function CollectionCardSkeleton() {\n return (\n <div className=\"card-base overflow-hidden\">\n <div className=\"relative aspect-square w-full overflow-hidden bg-muted\">\n <div className=\"absolute inset-0 animate-pulse bg-muted\" />\n <div className=\"absolute bottom-3 left-3 right-3 space-y-1.5\">\n <div className=\"h-4 w-2/3 rounded-md bg-muted-foreground/20 animate-pulse\" />\n <div className=\"h-3 w-1/3 rounded-md bg-muted-foreground/20 animate-pulse\" />\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiDY;AA/CZ,mBAAyB;AACzB,kBAAiB;AACjB,mBAAkB;AAClB,0BAAmC;AACnC,gBAAmB;AACnB,oBAAmC;AACnC,+BAA2B;AAC3B,2BAA6B;AAE7B,2BAA4B;AAE5B,SAAS,gBAAgB,OAA6E;AACpG,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,gBAAY,kCAAmB,KAAK;AAC1C,QAAM,QAAQ,UAAU,KAAK,EAAE,MAAM,KAAK;AAC1C,MAAI,MAAM,SAAS,EAAG,QAAO;AAC7B,QAAM,SAAS,MAAM,MAAM,SAAS,CAAC;AACrC,QAAM,SAAS,MAAM,MAAM,GAAG,EAAE,EAAE,KAAK,GAAG;AAC1C,SAAO,EAAE,QAAQ,OAAO;AAC1B;AAWO,SAAS,eAAe,EAAE,YAAY,MAAM,cAAc,UAAU,GAAwB;AACjG,QAAM,mBAAe,kCAAY;AACjC,QAAM,CAAC,UAAU,WAAW,QAAI,uBAAS,KAAK;AAC9C,QAAM,WAAW,aAAa,WAAW,OAAO,EAAE,OAAO,IAAI,CAAC;AAC9D,QAAM,YAAY,YAAY,CAAC;AAC/B,QAAM,QAAQ,gBAAgB,WAAW,UAAU;AAEnD,SACE,6CAAC,uCAAW,eAAW,cAAG,4BAA4B,SAAS,GAC5D;AAAA,oBACC;AAAA,MAAC,YAAAA;AAAA,MAAA;AAAA,QACC,MAAM;AAAA,QACN,SAAS,CAAC,MAAM,EAAE,gBAAgB;AAAA,QAClC,WAAU;AAAA,QACV,cAAW;AAAA,QAEX,sDAAC,UAAK,WAAU,yJACd,sDAAC,iCAAU,WAAU,eAAc,GACrC;AAAA;AAAA,IACF;AAAA,IAGF,4CAAC,YAAAA,SAAA,EAAK,MAAM,QAAQ,gBAAgB,WAAW,eAAe,IAAI,WAAU,yBAC1E,uDAAC,SAAI,WAAU,0DACZ;AAAA,kBACC;AAAA,QAAC,aAAAC;AAAA,QAAA;AAAA,UACC,KAAK;AAAA,UACL,KAAK,WAAW,QAAQ;AAAA,UACxB,MAAI;AAAA,UACJ,WAAU;AAAA,UACV,SAAS,MAAM,YAAY,IAAI;AAAA,UAC/B,aAAW;AAAA;AAAA,MACb,IAEA,4CAAC,SAAI,WAAU,8FAA6F;AAAA,MAG9G,6CAAC,SAAI,WAAU,+DACZ;AAAA,SAAC,WAAW,QAAQ,WAAW,mBAAmB,YACjD,6CAAC,UAAK,WAAU,qGACd;AAAA,sDAAC,+BAAQ,WAAU,4BAA2B;AAAA,UAAE;AAAA,WAElD,IAEA,4CAAC,OAAE,WAAU,sHACV,qBAAW,QAAQ,sBACtB;AAAA,SAGA,WAAW,eAAe,QAAQ,UAClC,6CAAC,SAAI,WAAU,qCACZ;AAAA,qBAAW,eAAe,QACzB,4CAAC,UAAK,WAAU,yFACb,qBAAW,YAAY,eAAe,GACzC;AAAA,UAED,SACC,6CAAC,UAAK,WAAU,sHAAqH;AAAA;AAAA,YAEnI,4CAAC,qCAAa,QAAQ,MAAM,QAAQ,MAAM,IAAI;AAAA,YAC7C,MAAM;AAAA,aACT;AAAA,WAEJ;AAAA,SAEJ;AAAA,OACF,GACF;AAAA,KACF;AAEJ;AAEO,SAAS,yBAAyB;AACvC,SACE,4CAAC,SAAI,WAAU,6BACb,uDAAC,SAAI,WAAU,0DACb;AAAA,gDAAC,SAAI,WAAU,2CAA0C;AAAA,IACzD,6CAAC,SAAI,WAAU,gDACb;AAAA,kDAAC,SAAI,WAAU,6DAA4D;AAAA,MAC3E,4CAAC,SAAI,WAAU,6DAA4D;AAAA,OAC7E;AAAA,KACF,GACF;AAEJ;","names":["Link","Image"]}
|
|
@@ -42,7 +42,7 @@ function CollectionCard({ collection, href, settingsHref, className }) {
|
|
|
42
42
|
src: imageUrl,
|
|
43
43
|
alt: collection.name ?? "Collection",
|
|
44
44
|
fill: true,
|
|
45
|
-
className: "object-cover
|
|
45
|
+
className: "object-cover card-media",
|
|
46
46
|
onError: () => setImgError(true),
|
|
47
47
|
unoptimized: true
|
|
48
48
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/collection-card.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport Link from \"./link.js\";\nimport Image from \"./image.js\";\nimport { Loader2, Settings2 } from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\nimport { formatDisplayPrice } from \"../utils/format.js\";\nimport { MotionCard } from \"./motion-primitives.js\";\nimport { CurrencyIcon } from \"./currency-icon.js\";\nimport type { ApiCollection } from \"@medialane/sdk\";\nimport { useImageUrl } from \"../utils/use-image-url.js\";\n\nfunction parseFloorPrice(floor: string | null | undefined): { amount: string; symbol: string } | null {\n if (!floor) return null;\n const formatted = formatDisplayPrice(floor);\n const parts = formatted.trim().split(/\\s+/);\n if (parts.length < 2) return null;\n const symbol = parts[parts.length - 1];\n const amount = parts.slice(0, -1).join(\" \");\n return { amount, symbol };\n}\n\nexport interface CollectionCardProps {\n collection: ApiCollection;\n\n href?: string;\n\n settingsHref?: string;\n className?: string;\n}\n\nexport function CollectionCard({ collection, href, settingsHref, className }: CollectionCardProps) {\n const resolveImage = useImageUrl();\n const [imgError, setImgError] = useState(false);\n const imageUrl = resolveImage(collection.image, { width: 480 });\n const showImage = imageUrl && !imgError;\n const floor = parseFloorPrice(collection.floorPrice);\n\n return (\n <MotionCard className={cn(\"card-base group relative\", className)}>\n {settingsHref && (\n <Link\n href={settingsHref}\n onClick={(e) => e.stopPropagation()}\n className=\"absolute top-2 right-2 z-10 min-h-11 min-w-11 rounded-full flex items-center justify-center\"\n aria-label=\"Collection settings\"\n >\n <span className=\"flex h-7 w-7 items-center justify-center rounded-full bg-black/40 backdrop-blur-sm text-white/70 hover:text-white hover:bg-black/60 transition-colors\">\n <Settings2 className=\"h-3.5 w-3.5\" />\n </span>\n </Link>\n )}\n\n <Link href={href ?? `/collections/${collection.contractAddress}`} className=\"block relative h-full\">\n <div className=\"relative aspect-square w-full overflow-hidden bg-muted\">\n {showImage ? (\n <Image\n src={imageUrl}\n alt={collection.name ?? \"Collection\"}\n fill\n className=\"object-cover
|
|
1
|
+
{"version":3,"sources":["../../src/components/collection-card.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport Link from \"./link.js\";\nimport Image from \"./image.js\";\nimport { Loader2, Settings2 } from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\nimport { formatDisplayPrice } from \"../utils/format.js\";\nimport { MotionCard } from \"./motion-primitives.js\";\nimport { CurrencyIcon } from \"./currency-icon.js\";\nimport type { ApiCollection } from \"@medialane/sdk\";\nimport { useImageUrl } from \"../utils/use-image-url.js\";\n\nfunction parseFloorPrice(floor: string | null | undefined): { amount: string; symbol: string } | null {\n if (!floor) return null;\n const formatted = formatDisplayPrice(floor);\n const parts = formatted.trim().split(/\\s+/);\n if (parts.length < 2) return null;\n const symbol = parts[parts.length - 1];\n const amount = parts.slice(0, -1).join(\" \");\n return { amount, symbol };\n}\n\nexport interface CollectionCardProps {\n collection: ApiCollection;\n\n href?: string;\n\n settingsHref?: string;\n className?: string;\n}\n\nexport function CollectionCard({ collection, href, settingsHref, className }: CollectionCardProps) {\n const resolveImage = useImageUrl();\n const [imgError, setImgError] = useState(false);\n const imageUrl = resolveImage(collection.image, { width: 480 });\n const showImage = imageUrl && !imgError;\n const floor = parseFloorPrice(collection.floorPrice);\n\n return (\n <MotionCard className={cn(\"card-base group relative\", className)}>\n {settingsHref && (\n <Link\n href={settingsHref}\n onClick={(e) => e.stopPropagation()}\n className=\"absolute top-2 right-2 z-10 min-h-11 min-w-11 rounded-full flex items-center justify-center\"\n aria-label=\"Collection settings\"\n >\n <span className=\"flex h-7 w-7 items-center justify-center rounded-full bg-black/40 backdrop-blur-sm text-white/70 hover:text-white hover:bg-black/60 transition-colors\">\n <Settings2 className=\"h-3.5 w-3.5\" />\n </span>\n </Link>\n )}\n\n <Link href={href ?? `/collections/${collection.contractAddress}`} className=\"block relative h-full\">\n <div className=\"relative aspect-square w-full overflow-hidden bg-muted\">\n {showImage ? (\n <Image\n src={imageUrl}\n alt={collection.name ?? \"Collection\"}\n fill\n className=\"object-cover card-media\"\n onError={() => setImgError(true)}\n unoptimized\n />\n ) : (\n <div className=\"absolute inset-0 bg-gradient-to-br from-brand-purple/30 via-brand-blue/20 to-brand-navy/40\" />\n )}\n\n <div className=\"absolute inset-x-2 bottom-2 flex flex-col items-start gap-1\">\n {!collection.name && collection.metadataStatus === \"PENDING\" ? (\n <span className=\"flex items-center gap-1 rounded-full px-2.5 py-1 text-2xs text-white bg-black/30 backdrop-blur-md\">\n <Loader2 className=\"h-2.5 w-2.5 animate-spin\" />\n Indexing…\n </span>\n ) : (\n <p className=\"max-w-full truncate rounded-full px-3 py-1 text-sm font-bold leading-tight text-white bg-black/30 backdrop-blur-md\">\n {collection.name ?? \"Unnamed Collection\"}\n </p>\n )}\n\n {(collection.totalSupply != null || floor) && (\n <div className=\"flex flex-wrap items-center gap-1\">\n {collection.totalSupply != null && (\n <span className=\"rounded-full px-2.5 py-1 text-2xs font-medium text-white bg-black/30 backdrop-blur-md\">\n {collection.totalSupply.toLocaleString()}\n </span>\n )}\n {floor && (\n <span className=\"inline-flex items-center gap-1 rounded-full px-2.5 py-1 text-2xs font-bold text-white bg-black/30 backdrop-blur-md\">\n Floor\n <CurrencyIcon symbol={floor.symbol} size={10} />\n {floor.amount}\n </span>\n )}\n </div>\n )}\n </div>\n </div>\n </Link>\n </MotionCard>\n );\n}\n\nexport function CollectionCardSkeleton() {\n return (\n <div className=\"card-base overflow-hidden\">\n <div className=\"relative aspect-square w-full overflow-hidden bg-muted\">\n <div className=\"absolute inset-0 animate-pulse bg-muted\" />\n <div className=\"absolute bottom-3 left-3 right-3 space-y-1.5\">\n <div className=\"h-4 w-2/3 rounded-md bg-muted-foreground/20 animate-pulse\" />\n <div className=\"h-3 w-1/3 rounded-md bg-muted-foreground/20 animate-pulse\" />\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":";AAiDY,cAsBE,YAtBF;AA/CZ,SAAS,gBAAgB;AACzB,OAAO,UAAU;AACjB,OAAO,WAAW;AAClB,SAAS,SAAS,iBAAiB;AACnC,SAAS,UAAU;AACnB,SAAS,0BAA0B;AACnC,SAAS,kBAAkB;AAC3B,SAAS,oBAAoB;AAE7B,SAAS,mBAAmB;AAE5B,SAAS,gBAAgB,OAA6E;AACpG,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,YAAY,mBAAmB,KAAK;AAC1C,QAAM,QAAQ,UAAU,KAAK,EAAE,MAAM,KAAK;AAC1C,MAAI,MAAM,SAAS,EAAG,QAAO;AAC7B,QAAM,SAAS,MAAM,MAAM,SAAS,CAAC;AACrC,QAAM,SAAS,MAAM,MAAM,GAAG,EAAE,EAAE,KAAK,GAAG;AAC1C,SAAO,EAAE,QAAQ,OAAO;AAC1B;AAWO,SAAS,eAAe,EAAE,YAAY,MAAM,cAAc,UAAU,GAAwB;AACjG,QAAM,eAAe,YAAY;AACjC,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAC9C,QAAM,WAAW,aAAa,WAAW,OAAO,EAAE,OAAO,IAAI,CAAC;AAC9D,QAAM,YAAY,YAAY,CAAC;AAC/B,QAAM,QAAQ,gBAAgB,WAAW,UAAU;AAEnD,SACE,qBAAC,cAAW,WAAW,GAAG,4BAA4B,SAAS,GAC5D;AAAA,oBACC;AAAA,MAAC;AAAA;AAAA,QACC,MAAM;AAAA,QACN,SAAS,CAAC,MAAM,EAAE,gBAAgB;AAAA,QAClC,WAAU;AAAA,QACV,cAAW;AAAA,QAEX,8BAAC,UAAK,WAAU,yJACd,8BAAC,aAAU,WAAU,eAAc,GACrC;AAAA;AAAA,IACF;AAAA,IAGF,oBAAC,QAAK,MAAM,QAAQ,gBAAgB,WAAW,eAAe,IAAI,WAAU,yBAC1E,+BAAC,SAAI,WAAU,0DACZ;AAAA,kBACC;AAAA,QAAC;AAAA;AAAA,UACC,KAAK;AAAA,UACL,KAAK,WAAW,QAAQ;AAAA,UACxB,MAAI;AAAA,UACJ,WAAU;AAAA,UACV,SAAS,MAAM,YAAY,IAAI;AAAA,UAC/B,aAAW;AAAA;AAAA,MACb,IAEA,oBAAC,SAAI,WAAU,8FAA6F;AAAA,MAG9G,qBAAC,SAAI,WAAU,+DACZ;AAAA,SAAC,WAAW,QAAQ,WAAW,mBAAmB,YACjD,qBAAC,UAAK,WAAU,qGACd;AAAA,8BAAC,WAAQ,WAAU,4BAA2B;AAAA,UAAE;AAAA,WAElD,IAEA,oBAAC,OAAE,WAAU,sHACV,qBAAW,QAAQ,sBACtB;AAAA,SAGA,WAAW,eAAe,QAAQ,UAClC,qBAAC,SAAI,WAAU,qCACZ;AAAA,qBAAW,eAAe,QACzB,oBAAC,UAAK,WAAU,yFACb,qBAAW,YAAY,eAAe,GACzC;AAAA,UAED,SACC,qBAAC,UAAK,WAAU,sHAAqH;AAAA;AAAA,YAEnI,oBAAC,gBAAa,QAAQ,MAAM,QAAQ,MAAM,IAAI;AAAA,YAC7C,MAAM;AAAA,aACT;AAAA,WAEJ;AAAA,SAEJ;AAAA,OACF,GACF;AAAA,KACF;AAEJ;AAEO,SAAS,yBAAyB;AACvC,SACE,oBAAC,SAAI,WAAU,6BACb,+BAAC,SAAI,WAAU,0DACb;AAAA,wBAAC,SAAI,WAAU,2CAA0C;AAAA,IACzD,qBAAC,SAAI,WAAU,gDACb;AAAA,0BAAC,SAAI,WAAU,6DAA4D;AAAA,MAC3E,oBAAC,SAAI,WAAU,6DAA4D;AAAA,OAC7E;AAAA,KACF,GACF;AAEJ;","names":[]}
|
|
@@ -66,7 +66,7 @@ function CreatorCard({ creator }) {
|
|
|
66
66
|
import_link.default,
|
|
67
67
|
{
|
|
68
68
|
href: (0, import_sdk.profileHref)({ username: creator.username, address: creator.walletAddress }),
|
|
69
|
-
className: "block relative aspect-square overflow-hidden rounded-2xl active:scale-[0.98] transition-transform duration-150 select-none",
|
|
69
|
+
className: "group block relative aspect-square overflow-hidden rounded-2xl active:scale-[0.98] transition-transform duration-150 select-none",
|
|
70
70
|
children: [
|
|
71
71
|
resolvedImage ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
72
72
|
import_image.default,
|
|
@@ -76,7 +76,7 @@ function CreatorCard({ creator }) {
|
|
|
76
76
|
"aria-hidden": true,
|
|
77
77
|
fill: true,
|
|
78
78
|
sizes: "(min-width: 1024px) 25vw, (min-width: 640px) 50vw, 100vw",
|
|
79
|
-
className: "absolute inset-0 w-full h-full object-cover",
|
|
79
|
+
className: "absolute inset-0 w-full h-full object-cover card-media",
|
|
80
80
|
unoptimized: true
|
|
81
81
|
}
|
|
82
82
|
) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "absolute inset-0", style: { background: fallbackGradient } }),
|