@medialane/ui 0.161.0 → 0.161.1

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.
@@ -3,7 +3,7 @@ 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;
6
+ variant?: "link" | "default" | "destructive" | "outline" | "ghost" | "secondary" | "premium" | "tonal" | "gradient-border" | "gradient-fill" | null | undefined;
7
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> {
@@ -3,7 +3,7 @@ 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;
6
+ variant?: "link" | "default" | "destructive" | "outline" | "ghost" | "secondary" | "premium" | "tonal" | "gradient-border" | "gradient-fill" | null | undefined;
7
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> {
@@ -1,10 +1,10 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
2
1
  import * as React from 'react';
2
+ import * as react_jsx_runtime from 'react/jsx-runtime';
3
3
  import { FastMintProps } from './types.cjs';
4
4
  import 'starknet';
5
5
  import '@medialane/sdk';
6
6
  import '@medialane/sdk/starknet';
7
7
 
8
- declare function FastMint(props: FastMintProps): string | number | bigint | boolean | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | react_jsx_runtime.JSX.Element | null | undefined;
8
+ declare function FastMint(props: FastMintProps): string | number | bigint | boolean | react_jsx_runtime.JSX.Element | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | null | undefined;
9
9
 
10
10
  export { FastMint };
@@ -1,10 +1,10 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
2
1
  import * as React from 'react';
2
+ import * as react_jsx_runtime from 'react/jsx-runtime';
3
3
  import { FastMintProps } from './types.js';
4
4
  import 'starknet';
5
5
  import '@medialane/sdk';
6
6
  import '@medialane/sdk/starknet';
7
7
 
8
- declare function FastMint(props: FastMintProps): string | number | bigint | boolean | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | react_jsx_runtime.JSX.Element | null | undefined;
8
+ declare function FastMint(props: FastMintProps): string | number | bigint | boolean | react_jsx_runtime.JSX.Element | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | null | undefined;
9
9
 
10
10
  export { FastMint };
@@ -25,7 +25,6 @@ module.exports = __toCommonJS(share_button_exports);
25
25
  var import_jsx_runtime = require("react/jsx-runtime");
26
26
  var import_react = require("react");
27
27
  var import_lucide_react = require("lucide-react");
28
- var import_sonner = require("sonner");
29
28
  var import_cn = require("../utils/cn.js");
30
29
  const VARIANT_CLASSES = {
31
30
  outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
@@ -56,7 +55,6 @@ function ShareButton({
56
55
  } else {
57
56
  await navigator.clipboard.writeText(shareUrl);
58
57
  setCopied(true);
59
- import_sonner.toast.success("Link copied to clipboard");
60
58
  setTimeout(() => setCopied(false), 2e3);
61
59
  }
62
60
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/share-button.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport { Share2, Check } from \"lucide-react\";\nimport { toast } from \"sonner\";\nimport { cn } from \"../utils/cn.js\";\n\nexport interface ShareButtonProps {\n title: string;\n url?: string;\n variant?: \"outline\" | \"ghost\" | \"default\";\n size?: \"sm\" | \"default\" | \"lg\" | \"icon\";\n className?: string;\n}\n\nconst VARIANT_CLASSES: Record<NonNullable<ShareButtonProps[\"variant\"]>, string> = {\n outline: \"border border-input bg-background hover:bg-accent hover:text-accent-foreground\",\n ghost: \"hover:bg-accent hover:text-accent-foreground\",\n default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n};\n\nconst SIZE_CLASSES: Record<NonNullable<ShareButtonProps[\"size\"]>, string> = {\n sm: \"h-9 px-3 text-xs rounded-md\",\n default: \"h-10 px-4 py-2 text-sm rounded-md\",\n lg: \"h-11 px-8 text-sm rounded-md\",\n icon: \"min-h-11 min-w-11 rounded-md\",\n};\n\nexport function ShareButton({\n title,\n url,\n variant = \"outline\",\n size = \"sm\",\n className,\n}: ShareButtonProps) {\n const [copied, setCopied] = useState(false);\n\n const handleShare = async () => {\n const shareUrl = url ?? (typeof window !== \"undefined\" ? window.location.href : \"\");\n if (typeof navigator !== \"undefined\" && navigator.share) {\n try {\n await navigator.share({ title, url: shareUrl });\n } catch {\n\n }\n } else {\n await navigator.clipboard.writeText(shareUrl);\n setCopied(true);\n toast.success(\"Link copied to clipboard\");\n setTimeout(() => setCopied(false), 2000);\n }\n };\n\n return (\n <button\n onClick={handleShare}\n className={cn(\n \"inline-flex items-center justify-center font-medium transition-colors\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\",\n \"disabled:pointer-events-none disabled:opacity-50\",\n VARIANT_CLASSES[variant],\n SIZE_CLASSES[size],\n className\n )}\n >\n {copied\n ? <Check className=\"h-3.5 w-3.5 text-emerald-500\" />\n : <Share2 className=\"h-3.5 w-3.5\" />\n }\n {size !== \"icon\" && (\n <span className=\"ml-1.5\">{copied ? \"Copied\" : \"Share\"}</span>\n )}\n </button>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAsDI;AApDJ,mBAAyB;AACzB,0BAA8B;AAC9B,oBAAsB;AACtB,gBAAmB;AAUnB,MAAM,kBAA4E;AAAA,EAChF,SAAS;AAAA,EACT,OAAO;AAAA,EACP,SAAS;AACX;AAEA,MAAM,eAAsE;AAAA,EAC1E,IAAI;AAAA,EACJ,SAAS;AAAA,EACT,IAAI;AAAA,EACJ,MAAM;AACR;AAEO,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV,OAAO;AAAA,EACP;AACF,GAAqB;AACnB,QAAM,CAAC,QAAQ,SAAS,QAAI,uBAAS,KAAK;AAE1C,QAAM,cAAc,YAAY;AAC9B,UAAM,WAAW,QAAQ,OAAO,WAAW,cAAc,OAAO,SAAS,OAAO;AAChF,QAAI,OAAO,cAAc,eAAe,UAAU,OAAO;AACvD,UAAI;AACF,cAAM,UAAU,MAAM,EAAE,OAAO,KAAK,SAAS,CAAC;AAAA,MAChD,QAAQ;AAAA,MAER;AAAA,IACF,OAAO;AACL,YAAM,UAAU,UAAU,UAAU,QAAQ;AAC5C,gBAAU,IAAI;AACd,0BAAM,QAAQ,0BAA0B;AACxC,iBAAW,MAAM,UAAU,KAAK,GAAG,GAAI;AAAA,IACzC;AAAA,EACF;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,SAAS;AAAA,MACT,eAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA,gBAAgB,OAAO;AAAA,QACvB,aAAa,IAAI;AAAA,QACjB;AAAA,MACF;AAAA,MAEC;AAAA,iBACG,4CAAC,6BAAM,WAAU,gCAA+B,IAChD,4CAAC,8BAAO,WAAU,eAAc;AAAA,QAEnC,SAAS,UACR,4CAAC,UAAK,WAAU,UAAU,mBAAS,WAAW,SAAQ;AAAA;AAAA;AAAA,EAE1D;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/components/share-button.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport { Share2, Check } from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\n\nexport interface ShareButtonProps {\n title: string;\n url?: string;\n variant?: \"outline\" | \"ghost\" | \"default\";\n size?: \"sm\" | \"default\" | \"lg\" | \"icon\";\n className?: string;\n}\n\nconst VARIANT_CLASSES: Record<NonNullable<ShareButtonProps[\"variant\"]>, string> = {\n outline: \"border border-input bg-background hover:bg-accent hover:text-accent-foreground\",\n ghost: \"hover:bg-accent hover:text-accent-foreground\",\n default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n};\n\nconst SIZE_CLASSES: Record<NonNullable<ShareButtonProps[\"size\"]>, string> = {\n sm: \"h-9 px-3 text-xs rounded-md\",\n default: \"h-10 px-4 py-2 text-sm rounded-md\",\n lg: \"h-11 px-8 text-sm rounded-md\",\n icon: \"min-h-11 min-w-11 rounded-md\",\n};\n\nexport function ShareButton({\n title,\n url,\n variant = \"outline\",\n size = \"sm\",\n className,\n}: ShareButtonProps) {\n const [copied, setCopied] = useState(false);\n\n const handleShare = async () => {\n const shareUrl = url ?? (typeof window !== \"undefined\" ? window.location.href : \"\");\n if (typeof navigator !== \"undefined\" && navigator.share) {\n try {\n await navigator.share({ title, url: shareUrl });\n } catch {\n\n }\n } else {\n await navigator.clipboard.writeText(shareUrl);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n }\n };\n\n return (\n <button\n onClick={handleShare}\n className={cn(\n \"inline-flex items-center justify-center font-medium transition-colors\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\",\n \"disabled:pointer-events-none disabled:opacity-50\",\n VARIANT_CLASSES[variant],\n SIZE_CLASSES[size],\n className\n )}\n >\n {copied\n ? <Check className=\"h-3.5 w-3.5 text-emerald-500\" />\n : <Share2 className=\"h-3.5 w-3.5\" />\n }\n {size !== \"icon\" && (\n <span className=\"ml-1.5\">{copied ? \"Copied\" : \"Share\"}</span>\n )}\n </button>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAoDI;AAlDJ,mBAAyB;AACzB,0BAA8B;AAC9B,gBAAmB;AAUnB,MAAM,kBAA4E;AAAA,EAChF,SAAS;AAAA,EACT,OAAO;AAAA,EACP,SAAS;AACX;AAEA,MAAM,eAAsE;AAAA,EAC1E,IAAI;AAAA,EACJ,SAAS;AAAA,EACT,IAAI;AAAA,EACJ,MAAM;AACR;AAEO,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV,OAAO;AAAA,EACP;AACF,GAAqB;AACnB,QAAM,CAAC,QAAQ,SAAS,QAAI,uBAAS,KAAK;AAE1C,QAAM,cAAc,YAAY;AAC9B,UAAM,WAAW,QAAQ,OAAO,WAAW,cAAc,OAAO,SAAS,OAAO;AAChF,QAAI,OAAO,cAAc,eAAe,UAAU,OAAO;AACvD,UAAI;AACF,cAAM,UAAU,MAAM,EAAE,OAAO,KAAK,SAAS,CAAC;AAAA,MAChD,QAAQ;AAAA,MAER;AAAA,IACF,OAAO;AACL,YAAM,UAAU,UAAU,UAAU,QAAQ;AAC5C,gBAAU,IAAI;AACd,iBAAW,MAAM,UAAU,KAAK,GAAG,GAAI;AAAA,IACzC;AAAA,EACF;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,SAAS;AAAA,MACT,eAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA,gBAAgB,OAAO;AAAA,QACvB,aAAa,IAAI;AAAA,QACjB;AAAA,MACF;AAAA,MAEC;AAAA,iBACG,4CAAC,6BAAM,WAAU,gCAA+B,IAChD,4CAAC,8BAAO,WAAU,eAAc;AAAA,QAEnC,SAAS,UACR,4CAAC,UAAK,WAAU,UAAU,mBAAS,WAAW,SAAQ;AAAA;AAAA;AAAA,EAE1D;AAEJ;","names":[]}
@@ -2,7 +2,6 @@
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import { useState } from "react";
4
4
  import { Share2, Check } from "lucide-react";
5
- import { toast } from "sonner";
6
5
  import { cn } from "../utils/cn.js";
7
6
  const VARIANT_CLASSES = {
8
7
  outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
@@ -33,7 +32,6 @@ function ShareButton({
33
32
  } else {
34
33
  await navigator.clipboard.writeText(shareUrl);
35
34
  setCopied(true);
36
- toast.success("Link copied to clipboard");
37
35
  setTimeout(() => setCopied(false), 2e3);
38
36
  }
39
37
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/share-button.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport { Share2, Check } from \"lucide-react\";\nimport { toast } from \"sonner\";\nimport { cn } from \"../utils/cn.js\";\n\nexport interface ShareButtonProps {\n title: string;\n url?: string;\n variant?: \"outline\" | \"ghost\" | \"default\";\n size?: \"sm\" | \"default\" | \"lg\" | \"icon\";\n className?: string;\n}\n\nconst VARIANT_CLASSES: Record<NonNullable<ShareButtonProps[\"variant\"]>, string> = {\n outline: \"border border-input bg-background hover:bg-accent hover:text-accent-foreground\",\n ghost: \"hover:bg-accent hover:text-accent-foreground\",\n default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n};\n\nconst SIZE_CLASSES: Record<NonNullable<ShareButtonProps[\"size\"]>, string> = {\n sm: \"h-9 px-3 text-xs rounded-md\",\n default: \"h-10 px-4 py-2 text-sm rounded-md\",\n lg: \"h-11 px-8 text-sm rounded-md\",\n icon: \"min-h-11 min-w-11 rounded-md\",\n};\n\nexport function ShareButton({\n title,\n url,\n variant = \"outline\",\n size = \"sm\",\n className,\n}: ShareButtonProps) {\n const [copied, setCopied] = useState(false);\n\n const handleShare = async () => {\n const shareUrl = url ?? (typeof window !== \"undefined\" ? window.location.href : \"\");\n if (typeof navigator !== \"undefined\" && navigator.share) {\n try {\n await navigator.share({ title, url: shareUrl });\n } catch {\n\n }\n } else {\n await navigator.clipboard.writeText(shareUrl);\n setCopied(true);\n toast.success(\"Link copied to clipboard\");\n setTimeout(() => setCopied(false), 2000);\n }\n };\n\n return (\n <button\n onClick={handleShare}\n className={cn(\n \"inline-flex items-center justify-center font-medium transition-colors\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\",\n \"disabled:pointer-events-none disabled:opacity-50\",\n VARIANT_CLASSES[variant],\n SIZE_CLASSES[size],\n className\n )}\n >\n {copied\n ? <Check className=\"h-3.5 w-3.5 text-emerald-500\" />\n : <Share2 className=\"h-3.5 w-3.5\" />\n }\n {size !== \"icon\" && (\n <span className=\"ml-1.5\">{copied ? \"Copied\" : \"Share\"}</span>\n )}\n </button>\n );\n}\n"],"mappings":";AAsDI,SAYM,KAZN;AApDJ,SAAS,gBAAgB;AACzB,SAAS,QAAQ,aAAa;AAC9B,SAAS,aAAa;AACtB,SAAS,UAAU;AAUnB,MAAM,kBAA4E;AAAA,EAChF,SAAS;AAAA,EACT,OAAO;AAAA,EACP,SAAS;AACX;AAEA,MAAM,eAAsE;AAAA,EAC1E,IAAI;AAAA,EACJ,SAAS;AAAA,EACT,IAAI;AAAA,EACJ,MAAM;AACR;AAEO,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV,OAAO;AAAA,EACP;AACF,GAAqB;AACnB,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,KAAK;AAE1C,QAAM,cAAc,YAAY;AAC9B,UAAM,WAAW,QAAQ,OAAO,WAAW,cAAc,OAAO,SAAS,OAAO;AAChF,QAAI,OAAO,cAAc,eAAe,UAAU,OAAO;AACvD,UAAI;AACF,cAAM,UAAU,MAAM,EAAE,OAAO,KAAK,SAAS,CAAC;AAAA,MAChD,QAAQ;AAAA,MAER;AAAA,IACF,OAAO;AACL,YAAM,UAAU,UAAU,UAAU,QAAQ;AAC5C,gBAAU,IAAI;AACd,YAAM,QAAQ,0BAA0B;AACxC,iBAAW,MAAM,UAAU,KAAK,GAAG,GAAI;AAAA,IACzC;AAAA,EACF;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,SAAS;AAAA,MACT,WAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA,gBAAgB,OAAO;AAAA,QACvB,aAAa,IAAI;AAAA,QACjB;AAAA,MACF;AAAA,MAEC;AAAA,iBACG,oBAAC,SAAM,WAAU,gCAA+B,IAChD,oBAAC,UAAO,WAAU,eAAc;AAAA,QAEnC,SAAS,UACR,oBAAC,UAAK,WAAU,UAAU,mBAAS,WAAW,SAAQ;AAAA;AAAA;AAAA,EAE1D;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/components/share-button.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport { Share2, Check } from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\n\nexport interface ShareButtonProps {\n title: string;\n url?: string;\n variant?: \"outline\" | \"ghost\" | \"default\";\n size?: \"sm\" | \"default\" | \"lg\" | \"icon\";\n className?: string;\n}\n\nconst VARIANT_CLASSES: Record<NonNullable<ShareButtonProps[\"variant\"]>, string> = {\n outline: \"border border-input bg-background hover:bg-accent hover:text-accent-foreground\",\n ghost: \"hover:bg-accent hover:text-accent-foreground\",\n default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n};\n\nconst SIZE_CLASSES: Record<NonNullable<ShareButtonProps[\"size\"]>, string> = {\n sm: \"h-9 px-3 text-xs rounded-md\",\n default: \"h-10 px-4 py-2 text-sm rounded-md\",\n lg: \"h-11 px-8 text-sm rounded-md\",\n icon: \"min-h-11 min-w-11 rounded-md\",\n};\n\nexport function ShareButton({\n title,\n url,\n variant = \"outline\",\n size = \"sm\",\n className,\n}: ShareButtonProps) {\n const [copied, setCopied] = useState(false);\n\n const handleShare = async () => {\n const shareUrl = url ?? (typeof window !== \"undefined\" ? window.location.href : \"\");\n if (typeof navigator !== \"undefined\" && navigator.share) {\n try {\n await navigator.share({ title, url: shareUrl });\n } catch {\n\n }\n } else {\n await navigator.clipboard.writeText(shareUrl);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n }\n };\n\n return (\n <button\n onClick={handleShare}\n className={cn(\n \"inline-flex items-center justify-center font-medium transition-colors\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\",\n \"disabled:pointer-events-none disabled:opacity-50\",\n VARIANT_CLASSES[variant],\n SIZE_CLASSES[size],\n className\n )}\n >\n {copied\n ? <Check className=\"h-3.5 w-3.5 text-emerald-500\" />\n : <Share2 className=\"h-3.5 w-3.5\" />\n }\n {size !== \"icon\" && (\n <span className=\"ml-1.5\">{copied ? \"Copied\" : \"Share\"}</span>\n )}\n </button>\n );\n}\n"],"mappings":";AAoDI,SAYM,KAZN;AAlDJ,SAAS,gBAAgB;AACzB,SAAS,QAAQ,aAAa;AAC9B,SAAS,UAAU;AAUnB,MAAM,kBAA4E;AAAA,EAChF,SAAS;AAAA,EACT,OAAO;AAAA,EACP,SAAS;AACX;AAEA,MAAM,eAAsE;AAAA,EAC1E,IAAI;AAAA,EACJ,SAAS;AAAA,EACT,IAAI;AAAA,EACJ,MAAM;AACR;AAEO,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV,OAAO;AAAA,EACP;AACF,GAAqB;AACnB,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,KAAK;AAE1C,QAAM,cAAc,YAAY;AAC9B,UAAM,WAAW,QAAQ,OAAO,WAAW,cAAc,OAAO,SAAS,OAAO;AAChF,QAAI,OAAO,cAAc,eAAe,UAAU,OAAO;AACvD,UAAI;AACF,cAAM,UAAU,MAAM,EAAE,OAAO,KAAK,SAAS,CAAC;AAAA,MAChD,QAAQ;AAAA,MAER;AAAA,IACF,OAAO;AACL,YAAM,UAAU,UAAU,UAAU,QAAQ;AAC5C,gBAAU,IAAI;AACd,iBAAW,MAAM,UAAU,KAAK,GAAG,GAAI;AAAA,IACzC;AAAA,EACF;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,SAAS;AAAA,MACT,WAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA,gBAAgB,OAAO;AAAA,QACvB,aAAa,IAAI;AAAA,QACjB;AAAA,MACF;AAAA,MAEC;AAAA,iBACG,oBAAC,SAAM,WAAU,gCAA+B,IAChD,oBAAC,UAAO,WAAU,eAAc;AAAA,QAEnC,SAAS,UACR,oBAAC,UAAK,WAAU,UAAU,mBAAS,WAAW,SAAQ;AAAA;AAAA;AAAA,EAE1D;AAEJ;","names":[]}
@@ -10,7 +10,7 @@ declare const SheetClose: React.ForwardRefExoticComponent<SheetPrimitive.DialogC
10
10
  declare const SheetPortal: React.FC<SheetPrimitive.DialogPortalProps>;
11
11
  declare const SheetOverlay: React.ForwardRefExoticComponent<Omit<SheetPrimitive.DialogOverlayProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
12
12
  declare const sheetVariants: (props?: ({
13
- side?: "left" | "right" | "bottom" | "top" | null | undefined;
13
+ side?: "bottom" | "left" | "right" | "top" | null | undefined;
14
14
  } & class_variance_authority_types.ClassProp) | undefined) => string;
15
15
  interface SheetContentProps extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>, VariantProps<typeof sheetVariants> {
16
16
  overlayClassName?: string;
@@ -10,7 +10,7 @@ declare const SheetClose: React.ForwardRefExoticComponent<SheetPrimitive.DialogC
10
10
  declare const SheetPortal: React.FC<SheetPrimitive.DialogPortalProps>;
11
11
  declare const SheetOverlay: React.ForwardRefExoticComponent<Omit<SheetPrimitive.DialogOverlayProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
12
12
  declare const sheetVariants: (props?: ({
13
- side?: "left" | "right" | "bottom" | "top" | null | undefined;
13
+ side?: "bottom" | "left" | "right" | "top" | null | undefined;
14
14
  } & class_variance_authority_types.ClassProp) | undefined) => string;
15
15
  interface SheetContentProps extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>, VariantProps<typeof sheetVariants> {
16
16
  overlayClassName?: string;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var notification_readiness_exports = {};
20
+ __export(notification_readiness_exports, {
21
+ notificationsAreLoading: () => notificationsAreLoading
22
+ });
23
+ module.exports = __toCommonJS(notification_readiness_exports);
24
+ function notificationsAreLoading(state) {
25
+ if (!state.hasAddress) return false;
26
+ return state.ordersLoading || state.receivedLoading || state.activitiesLoading;
27
+ }
28
+ // Annotate the CommonJS export names for ESM import in node:
29
+ 0 && (module.exports = {
30
+ notificationsAreLoading
31
+ });
32
+ //# sourceMappingURL=notification-readiness.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/notification-readiness.ts"],"sourcesContent":["export interface NotificationSourceState {\n ordersLoading: boolean;\n receivedLoading: boolean;\n activitiesLoading: boolean;\n hasAddress: boolean;\n}\n\nexport function notificationsAreLoading(state: NotificationSourceState): boolean {\n if (!state.hasAddress) return false;\n return state.ordersLoading || state.receivedLoading || state.activitiesLoading;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAOO,SAAS,wBAAwB,OAAyC;AAC/E,MAAI,CAAC,MAAM,WAAY,QAAO;AAC9B,SAAO,MAAM,iBAAiB,MAAM,mBAAmB,MAAM;AAC/D;","names":[]}
@@ -0,0 +1,9 @@
1
+ interface NotificationSourceState {
2
+ ordersLoading: boolean;
3
+ receivedLoading: boolean;
4
+ activitiesLoading: boolean;
5
+ hasAddress: boolean;
6
+ }
7
+ declare function notificationsAreLoading(state: NotificationSourceState): boolean;
8
+
9
+ export { type NotificationSourceState, notificationsAreLoading };
@@ -0,0 +1,9 @@
1
+ interface NotificationSourceState {
2
+ ordersLoading: boolean;
3
+ receivedLoading: boolean;
4
+ activitiesLoading: boolean;
5
+ hasAddress: boolean;
6
+ }
7
+ declare function notificationsAreLoading(state: NotificationSourceState): boolean;
8
+
9
+ export { type NotificationSourceState, notificationsAreLoading };
@@ -0,0 +1,8 @@
1
+ function notificationsAreLoading(state) {
2
+ if (!state.hasAddress) return false;
3
+ return state.ordersLoading || state.receivedLoading || state.activitiesLoading;
4
+ }
5
+ export {
6
+ notificationsAreLoading
7
+ };
8
+ //# sourceMappingURL=notification-readiness.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/notification-readiness.ts"],"sourcesContent":["export interface NotificationSourceState {\n ordersLoading: boolean;\n receivedLoading: boolean;\n activitiesLoading: boolean;\n hasAddress: boolean;\n}\n\nexport function notificationsAreLoading(state: NotificationSourceState): boolean {\n if (!state.hasAddress) return false;\n return state.ordersLoading || state.receivedLoading || state.activitiesLoading;\n}\n"],"mappings":"AAOO,SAAS,wBAAwB,OAAyC;AAC/E,MAAI,CAAC,MAAM,WAAY,QAAO;AAC9B,SAAO,MAAM,iBAAiB,MAAM,mBAAmB,MAAM;AAC/D;","names":[]}
@@ -38,6 +38,7 @@ var import_sdk = require("@medialane/sdk");
38
38
  var import_use_orders = require("./use-orders.js");
39
39
  var import_use_activities = require("./use-activities.js");
40
40
  var import_notification_storage = require("./notification-storage.js");
41
+ var import_notification_readiness = require("./notification-readiness.js");
41
42
  var import_format_activity = require("./format-activity.js");
42
43
  async function fetchAnnouncements() {
43
44
  const res = await fetch("/api/announcements");
@@ -45,10 +46,13 @@ async function fetchAnnouncements() {
45
46
  return res.json();
46
47
  }
47
48
  function useNotifications(getClient, apiConfig, address) {
48
- const [readIds, setReadIds] = (0, import_react.useState)(() => (0, import_notification_storage.getReadIds)());
49
- const { orders: userOrders } = (0, import_use_orders.useUserOrders)(getClient, address ?? null);
50
- const { orders: receivedOffers } = (0, import_use_orders.useReceivedOffers)(apiConfig, address ?? null);
51
- const { activities } = (0, import_use_activities.useActivitiesByAddress)(getClient, address ?? null);
49
+ const [readIds, setReadIds] = (0, import_react.useState)(() => /* @__PURE__ */ new Set());
50
+ (0, import_react.useEffect)(() => {
51
+ setReadIds((0, import_notification_storage.getReadIds)());
52
+ }, []);
53
+ const { orders: userOrders, isLoading: ordersLoading } = (0, import_use_orders.useUserOrders)(getClient, address ?? null);
54
+ const { orders: receivedOffers, isLoading: receivedLoading } = (0, import_use_orders.useReceivedOffers)(apiConfig, address ?? null);
55
+ const { activities, isLoading: activitiesLoading } = (0, import_use_activities.useActivitiesByAddress)(getClient, address ?? null);
52
56
  const { data: announcements = [] } = (0, import_swr.default)(
53
57
  "announcements",
54
58
  fetchAnnouncements,
@@ -155,9 +159,16 @@ function useNotifications(getClient, apiConfig, address) {
155
159
  (0, import_notification_storage.markRead)(ids);
156
160
  setReadIds((0, import_notification_storage.getReadIds)());
157
161
  }, []);
162
+ const isLoading = (0, import_notification_readiness.notificationsAreLoading)({
163
+ ordersLoading,
164
+ receivedLoading,
165
+ activitiesLoading,
166
+ hasAddress: !!address
167
+ });
158
168
  return {
159
169
  notifications,
160
170
  unreadCount,
171
+ isLoading,
161
172
  markAllRead: () => markNotificationsRead(notifications.map((n) => n.id)),
162
173
  markRead: (id) => markNotificationsRead([id])
163
174
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/use-notifications.ts"],"sourcesContent":["\"use client\";\n\nimport { useCallback, useMemo, useState } from \"react\";\nimport useSWR from \"swr\";\nimport { normalizeAddress } from \"@medialane/sdk\";\nimport type { ApiActivity } from \"@medialane/sdk\";\nimport type { MedialaneClient } from \"@medialane/sdk/starknet\";\nimport { useUserOrders, useReceivedOffers } from \"./use-orders.js\";\nimport { useActivitiesByAddress } from \"./use-activities.js\";\nimport { getReadIds, markRead } from \"./notification-storage.js\";\nimport {\n formatActivity,\n formatOrderNotification,\n formatOfferAcceptedNotification,\n formatAssetReceivedNotification,\n} from \"./format-activity.js\";\nimport type { Notification, Announcement } from \"../data/notification.js\";\nimport type { ApiFetchConfig } from \"./api-fetch.js\";\n\nasync function fetchAnnouncements(): Promise<Announcement[]> {\n const res = await fetch(\"/api/announcements\");\n if (!res.ok) return [];\n return res.json();\n}\n\nexport function useNotifications(\n getClient: () => MedialaneClient,\n apiConfig: ApiFetchConfig,\n address: string | null | undefined\n) {\n const [readIds, setReadIds] = useState<Set<string>>(() => getReadIds());\n\n const { orders: userOrders } = useUserOrders(getClient, address ?? null);\n\n const { orders: receivedOffers } = useReceivedOffers(apiConfig, address ?? null);\n const { activities } = useActivitiesByAddress(getClient, address ?? null);\n const { data: announcements = [] } = useSWR<Announcement[]>(\n \"announcements\",\n fetchAnnouncements,\n { revalidateOnFocus: false, dedupingInterval: 60_000 }\n );\n\n const notifications: Notification[] = useMemo(() => {\n const items: Notification[] = [];\n\n userOrders\n .filter((o) => o.offer.itemType === \"ERC20\" && o.status === \"FULFILLED\")\n .forEach((order) => {\n const id = `offer-accepted-${order.orderHash}`;\n const fmt = formatOfferAcceptedNotification(order);\n items.push({\n id,\n type: \"offer_accepted\",\n priority: \"spotlight\",\n celebratory: true,\n ...fmt,\n timestamp: order.updatedAt ?? order.createdAt ?? new Date().toISOString(),\n isUnread: !readIds.has(id),\n metadata: {\n amount: order.price?.formatted ?? undefined,\n currency: order.price?.currency ?? undefined,\n txHash: order.txHash?.fulfilled ?? undefined,\n assetName: order.token?.name ?? undefined,\n },\n });\n });\n\n receivedOffers.forEach((order) => {\n const id = `order-${order.orderHash}`;\n const fmt = formatOrderNotification(order);\n items.push({\n id,\n type: \"offer\",\n priority: \"spotlight\",\n celebratory: false,\n ...fmt,\n timestamp: order.createdAt ?? new Date().toISOString(),\n isUnread: !readIds.has(id),\n metadata: {\n amount: order.price?.formatted ?? undefined,\n currency: order.price?.currency ?? undefined,\n assetName: order.token?.name ?? undefined,\n },\n });\n });\n\n (activities as ApiActivity[]).slice(0, 50).forEach((event) => {\n const id = `activity-${event.txHash}-${event.type}-${event.nftTokenId ?? \"\"}`;\n\n if (\n event.type === \"transfer\" &&\n address &&\n !!event.to && normalizeAddress(\"STARKNET\", event.to) === normalizeAddress(\"STARKNET\", address)\n ) {\n const fmt = formatAssetReceivedNotification(event);\n items.push({\n id,\n type: \"asset_received\",\n priority: \"spotlight\",\n celebratory: true,\n ...fmt,\n timestamp: event.timestamp ?? new Date().toISOString(),\n isUnread: !readIds.has(id),\n metadata: {\n txHash: event.txHash ?? undefined,\n assetName: event.token?.name ?? undefined,\n },\n });\n return;\n }\n\n const isMySale =\n event.type === \"sale\" &&\n address &&\n ((!!event.offerer && normalizeAddress(\"STARKNET\", event.offerer) === normalizeAddress(\"STARKNET\", address)) ||\n (!!event.from && normalizeAddress(\"STARKNET\", event.from) === normalizeAddress(\"STARKNET\", address)));\n\n const fmt = formatActivity(event);\n items.push({\n id,\n type: event.type as Notification[\"type\"],\n priority: isMySale ? \"spotlight\" : \"normal\",\n celebratory: !!isMySale,\n ...fmt,\n timestamp: event.timestamp ?? new Date().toISOString(),\n isUnread: !readIds.has(id),\n metadata: {\n amount: event.price?.formatted ?? undefined,\n currency: event.price?.currency ?? undefined,\n txHash: event.txHash ?? undefined,\n assetName: event.token?.name ?? undefined,\n },\n });\n });\n\n announcements.forEach((ann) => {\n const id = `ann-${ann.id}`;\n items.push({\n id,\n type: \"announcement\",\n priority: ann.pinned ? \"spotlight\" : \"normal\",\n celebratory: false,\n title: ann.title,\n description: ann.body,\n image: ann.image,\n href: ann.href,\n timestamp: ann.created_at,\n isUnread: !readIds.has(id),\n });\n });\n\n items.sort(\n (a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime()\n );\n\n return items;\n }, [userOrders, receivedOffers, activities, announcements, address, readIds]);\n\n const unreadCount = notifications.filter((n) => n.isUnread).length;\n\n const markNotificationsRead = useCallback((ids: string[]) => {\n markRead(ids);\n setReadIds(getReadIds());\n }, []);\n\n return {\n notifications,\n unreadCount,\n markAllRead: () => markNotificationsRead(notifications.map((n) => n.id)),\n markRead: (id: string) => markNotificationsRead([id]),\n };\n}\n"],"mappings":"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","names":["useSWR","fmt"]}
1
+ {"version":3,"sources":["../../src/utils/use-notifications.ts"],"sourcesContent":["\"use client\";\n\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport useSWR from \"swr\";\nimport { normalizeAddress } from \"@medialane/sdk\";\nimport type { ApiActivity } from \"@medialane/sdk\";\nimport type { MedialaneClient } from \"@medialane/sdk/starknet\";\nimport { useUserOrders, useReceivedOffers } from \"./use-orders.js\";\nimport { useActivitiesByAddress } from \"./use-activities.js\";\nimport { getReadIds, markRead } from \"./notification-storage.js\";\nimport { notificationsAreLoading } from \"./notification-readiness.js\";\nimport {\n formatActivity,\n formatOrderNotification,\n formatOfferAcceptedNotification,\n formatAssetReceivedNotification,\n} from \"./format-activity.js\";\nimport type { Notification, Announcement } from \"../data/notification.js\";\nimport type { ApiFetchConfig } from \"./api-fetch.js\";\n\nasync function fetchAnnouncements(): Promise<Announcement[]> {\n const res = await fetch(\"/api/announcements\");\n if (!res.ok) return [];\n return res.json();\n}\n\nexport function useNotifications(\n getClient: () => MedialaneClient,\n apiConfig: ApiFetchConfig,\n address: string | null | undefined\n) {\n const [readIds, setReadIds] = useState<Set<string>>(() => new Set<string>());\n\n useEffect(() => {\n setReadIds(getReadIds());\n }, []);\n\n const { orders: userOrders, isLoading: ordersLoading } = useUserOrders(getClient, address ?? null);\n\n const { orders: receivedOffers, isLoading: receivedLoading } = useReceivedOffers(apiConfig, address ?? null);\n const { activities, isLoading: activitiesLoading } = useActivitiesByAddress(getClient, address ?? null);\n const { data: announcements = [] } = useSWR<Announcement[]>(\n \"announcements\",\n fetchAnnouncements,\n { revalidateOnFocus: false, dedupingInterval: 60_000 }\n );\n\n const notifications: Notification[] = useMemo(() => {\n const items: Notification[] = [];\n\n userOrders\n .filter((o) => o.offer.itemType === \"ERC20\" && o.status === \"FULFILLED\")\n .forEach((order) => {\n const id = `offer-accepted-${order.orderHash}`;\n const fmt = formatOfferAcceptedNotification(order);\n items.push({\n id,\n type: \"offer_accepted\",\n priority: \"spotlight\",\n celebratory: true,\n ...fmt,\n timestamp: order.updatedAt ?? order.createdAt ?? new Date().toISOString(),\n isUnread: !readIds.has(id),\n metadata: {\n amount: order.price?.formatted ?? undefined,\n currency: order.price?.currency ?? undefined,\n txHash: order.txHash?.fulfilled ?? undefined,\n assetName: order.token?.name ?? undefined,\n },\n });\n });\n\n receivedOffers.forEach((order) => {\n const id = `order-${order.orderHash}`;\n const fmt = formatOrderNotification(order);\n items.push({\n id,\n type: \"offer\",\n priority: \"spotlight\",\n celebratory: false,\n ...fmt,\n timestamp: order.createdAt ?? new Date().toISOString(),\n isUnread: !readIds.has(id),\n metadata: {\n amount: order.price?.formatted ?? undefined,\n currency: order.price?.currency ?? undefined,\n assetName: order.token?.name ?? undefined,\n },\n });\n });\n\n (activities as ApiActivity[]).slice(0, 50).forEach((event) => {\n const id = `activity-${event.txHash}-${event.type}-${event.nftTokenId ?? \"\"}`;\n\n if (\n event.type === \"transfer\" &&\n address &&\n !!event.to && normalizeAddress(\"STARKNET\", event.to) === normalizeAddress(\"STARKNET\", address)\n ) {\n const fmt = formatAssetReceivedNotification(event);\n items.push({\n id,\n type: \"asset_received\",\n priority: \"spotlight\",\n celebratory: true,\n ...fmt,\n timestamp: event.timestamp ?? new Date().toISOString(),\n isUnread: !readIds.has(id),\n metadata: {\n txHash: event.txHash ?? undefined,\n assetName: event.token?.name ?? undefined,\n },\n });\n return;\n }\n\n const isMySale =\n event.type === \"sale\" &&\n address &&\n ((!!event.offerer && normalizeAddress(\"STARKNET\", event.offerer) === normalizeAddress(\"STARKNET\", address)) ||\n (!!event.from && normalizeAddress(\"STARKNET\", event.from) === normalizeAddress(\"STARKNET\", address)));\n\n const fmt = formatActivity(event);\n items.push({\n id,\n type: event.type as Notification[\"type\"],\n priority: isMySale ? \"spotlight\" : \"normal\",\n celebratory: !!isMySale,\n ...fmt,\n timestamp: event.timestamp ?? new Date().toISOString(),\n isUnread: !readIds.has(id),\n metadata: {\n amount: event.price?.formatted ?? undefined,\n currency: event.price?.currency ?? undefined,\n txHash: event.txHash ?? undefined,\n assetName: event.token?.name ?? undefined,\n },\n });\n });\n\n announcements.forEach((ann) => {\n const id = `ann-${ann.id}`;\n items.push({\n id,\n type: \"announcement\",\n priority: ann.pinned ? \"spotlight\" : \"normal\",\n celebratory: false,\n title: ann.title,\n description: ann.body,\n image: ann.image,\n href: ann.href,\n timestamp: ann.created_at,\n isUnread: !readIds.has(id),\n });\n });\n\n items.sort(\n (a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime()\n );\n\n return items;\n }, [userOrders, receivedOffers, activities, announcements, address, readIds]);\n\n const unreadCount = notifications.filter((n) => n.isUnread).length;\n\n const markNotificationsRead = useCallback((ids: string[]) => {\n markRead(ids);\n setReadIds(getReadIds());\n }, []);\n\n const isLoading = notificationsAreLoading({\n ordersLoading,\n receivedLoading,\n activitiesLoading,\n hasAddress: !!address,\n });\n\n return {\n notifications,\n unreadCount,\n isLoading,\n markAllRead: () => markNotificationsRead(notifications.map((n) => n.id)),\n markRead: (id: string) => markNotificationsRead([id]),\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,mBAA0D;AAC1D,iBAAmB;AACnB,iBAAiC;AAGjC,wBAAiD;AACjD,4BAAuC;AACvC,kCAAqC;AACrC,oCAAwC;AACxC,6BAKO;AAIP,eAAe,qBAA8C;AAC3D,QAAM,MAAM,MAAM,MAAM,oBAAoB;AAC5C,MAAI,CAAC,IAAI,GAAI,QAAO,CAAC;AACrB,SAAO,IAAI,KAAK;AAClB;AAEO,SAAS,iBACd,WACA,WACA,SACA;AACA,QAAM,CAAC,SAAS,UAAU,QAAI,uBAAsB,MAAM,oBAAI,IAAY,CAAC;AAE3E,8BAAU,MAAM;AACd,mBAAW,wCAAW,CAAC;AAAA,EACzB,GAAG,CAAC,CAAC;AAEL,QAAM,EAAE,QAAQ,YAAY,WAAW,cAAc,QAAI,iCAAc,WAAW,WAAW,IAAI;AAEjG,QAAM,EAAE,QAAQ,gBAAgB,WAAW,gBAAgB,QAAI,qCAAkB,WAAW,WAAW,IAAI;AAC3G,QAAM,EAAE,YAAY,WAAW,kBAAkB,QAAI,8CAAuB,WAAW,WAAW,IAAI;AACtG,QAAM,EAAE,MAAM,gBAAgB,CAAC,EAAE,QAAI,WAAAA;AAAA,IACnC;AAAA,IACA;AAAA,IACA,EAAE,mBAAmB,OAAO,kBAAkB,IAAO;AAAA,EACvD;AAEA,QAAM,oBAAgC,sBAAQ,MAAM;AAClD,UAAM,QAAwB,CAAC;AAE/B,eACG,OAAO,CAAC,MAAM,EAAE,MAAM,aAAa,WAAW,EAAE,WAAW,WAAW,EACtE,QAAQ,CAAC,UAAU;AAClB,YAAM,KAAK,kBAAkB,MAAM,SAAS;AAC5C,YAAM,UAAM,wDAAgC,KAAK;AACjD,YAAM,KAAK;AAAA,QACT;AAAA,QACA,MAAM;AAAA,QACN,UAAU;AAAA,QACV,aAAa;AAAA,QACb,GAAG;AAAA,QACH,WAAW,MAAM,aAAa,MAAM,cAAa,oBAAI,KAAK,GAAE,YAAY;AAAA,QACxE,UAAU,CAAC,QAAQ,IAAI,EAAE;AAAA,QACzB,UAAU;AAAA,UACR,QAAQ,MAAM,OAAO,aAAa;AAAA,UAClC,UAAU,MAAM,OAAO,YAAY;AAAA,UACnC,QAAQ,MAAM,QAAQ,aAAa;AAAA,UACnC,WAAW,MAAM,OAAO,QAAQ;AAAA,QAClC;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAEH,mBAAe,QAAQ,CAAC,UAAU;AAChC,YAAM,KAAK,SAAS,MAAM,SAAS;AACnC,YAAM,UAAM,gDAAwB,KAAK;AACzC,YAAM,KAAK;AAAA,QACT;AAAA,QACA,MAAM;AAAA,QACN,UAAU;AAAA,QACV,aAAa;AAAA,QACb,GAAG;AAAA,QACH,WAAW,MAAM,cAAa,oBAAI,KAAK,GAAE,YAAY;AAAA,QACrD,UAAU,CAAC,QAAQ,IAAI,EAAE;AAAA,QACzB,UAAU;AAAA,UACR,QAAQ,MAAM,OAAO,aAAa;AAAA,UAClC,UAAU,MAAM,OAAO,YAAY;AAAA,UACnC,WAAW,MAAM,OAAO,QAAQ;AAAA,QAClC;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAED,IAAC,WAA6B,MAAM,GAAG,EAAE,EAAE,QAAQ,CAAC,UAAU;AAC5D,YAAM,KAAK,YAAY,MAAM,MAAM,IAAI,MAAM,IAAI,IAAI,MAAM,cAAc,EAAE;AAE3E,UACE,MAAM,SAAS,cACf,WACA,CAAC,CAAC,MAAM,UAAM,6BAAiB,YAAY,MAAM,EAAE,UAAM,6BAAiB,YAAY,OAAO,GAC7F;AACA,cAAMC,WAAM,wDAAgC,KAAK;AACjD,cAAM,KAAK;AAAA,UACT;AAAA,UACA,MAAM;AAAA,UACN,UAAU;AAAA,UACV,aAAa;AAAA,UACb,GAAGA;AAAA,UACH,WAAW,MAAM,cAAa,oBAAI,KAAK,GAAE,YAAY;AAAA,UACrD,UAAU,CAAC,QAAQ,IAAI,EAAE;AAAA,UACzB,UAAU;AAAA,YACR,QAAQ,MAAM,UAAU;AAAA,YACxB,WAAW,MAAM,OAAO,QAAQ;AAAA,UAClC;AAAA,QACF,CAAC;AACD;AAAA,MACF;AAEA,YAAM,WACJ,MAAM,SAAS,UACf,YACE,CAAC,CAAC,MAAM,eAAW,6BAAiB,YAAY,MAAM,OAAO,UAAM,6BAAiB,YAAY,OAAO,KACtG,CAAC,CAAC,MAAM,YAAQ,6BAAiB,YAAY,MAAM,IAAI,UAAM,6BAAiB,YAAY,OAAO;AAEtG,YAAM,UAAM,uCAAe,KAAK;AAChC,YAAM,KAAK;AAAA,QACT;AAAA,QACA,MAAM,MAAM;AAAA,QACZ,UAAU,WAAW,cAAc;AAAA,QACnC,aAAa,CAAC,CAAC;AAAA,QACf,GAAG;AAAA,QACH,WAAW,MAAM,cAAa,oBAAI,KAAK,GAAE,YAAY;AAAA,QACrD,UAAU,CAAC,QAAQ,IAAI,EAAE;AAAA,QACzB,UAAU;AAAA,UACR,QAAQ,MAAM,OAAO,aAAa;AAAA,UAClC,UAAU,MAAM,OAAO,YAAY;AAAA,UACnC,QAAQ,MAAM,UAAU;AAAA,UACxB,WAAW,MAAM,OAAO,QAAQ;AAAA,QAClC;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAED,kBAAc,QAAQ,CAAC,QAAQ;AAC7B,YAAM,KAAK,OAAO,IAAI,EAAE;AACxB,YAAM,KAAK;AAAA,QACT;AAAA,QACA,MAAM;AAAA,QACN,UAAU,IAAI,SAAS,cAAc;AAAA,QACrC,aAAa;AAAA,QACb,OAAO,IAAI;AAAA,QACX,aAAa,IAAI;AAAA,QACjB,OAAO,IAAI;AAAA,QACX,MAAM,IAAI;AAAA,QACV,WAAW,IAAI;AAAA,QACf,UAAU,CAAC,QAAQ,IAAI,EAAE;AAAA,MAC3B,CAAC;AAAA,IACH,CAAC;AAED,UAAM;AAAA,MACJ,CAAC,GAAG,MAAM,IAAI,KAAK,EAAE,SAAS,EAAE,QAAQ,IAAI,IAAI,KAAK,EAAE,SAAS,EAAE,QAAQ;AAAA,IAC5E;AAEA,WAAO;AAAA,EACT,GAAG,CAAC,YAAY,gBAAgB,YAAY,eAAe,SAAS,OAAO,CAAC;AAE5E,QAAM,cAAc,cAAc,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE;AAE5D,QAAM,4BAAwB,0BAAY,CAAC,QAAkB;AAC3D,8CAAS,GAAG;AACZ,mBAAW,wCAAW,CAAC;AAAA,EACzB,GAAG,CAAC,CAAC;AAEL,QAAM,gBAAY,uDAAwB;AAAA,IACxC;AAAA,IACA;AAAA,IACA;AAAA,IACA,YAAY,CAAC,CAAC;AAAA,EAChB,CAAC;AAED,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,aAAa,MAAM,sBAAsB,cAAc,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AAAA,IACvE,UAAU,CAAC,OAAe,sBAAsB,CAAC,EAAE,CAAC;AAAA,EACtD;AACF;","names":["useSWR","fmt"]}
@@ -5,6 +5,7 @@ import { ApiFetchConfig } from './api-fetch.cjs';
5
5
  declare function useNotifications(getClient: () => MedialaneClient, apiConfig: ApiFetchConfig, address: string | null | undefined): {
6
6
  notifications: Notification[];
7
7
  unreadCount: number;
8
+ isLoading: boolean;
8
9
  markAllRead: () => void;
9
10
  markRead: (id: string) => void;
10
11
  };
@@ -5,6 +5,7 @@ import { ApiFetchConfig } from './api-fetch.js';
5
5
  declare function useNotifications(getClient: () => MedialaneClient, apiConfig: ApiFetchConfig, address: string | null | undefined): {
6
6
  notifications: Notification[];
7
7
  unreadCount: number;
8
+ isLoading: boolean;
8
9
  markAllRead: () => void;
9
10
  markRead: (id: string) => void;
10
11
  };
@@ -1,10 +1,11 @@
1
1
  "use client";
2
- import { useCallback, useMemo, useState } from "react";
2
+ import { useCallback, useEffect, useMemo, useState } from "react";
3
3
  import useSWR from "swr";
4
4
  import { normalizeAddress } from "@medialane/sdk";
5
5
  import { useUserOrders, useReceivedOffers } from "./use-orders.js";
6
6
  import { useActivitiesByAddress } from "./use-activities.js";
7
7
  import { getReadIds, markRead } from "./notification-storage.js";
8
+ import { notificationsAreLoading } from "./notification-readiness.js";
8
9
  import {
9
10
  formatActivity,
10
11
  formatOrderNotification,
@@ -17,10 +18,13 @@ async function fetchAnnouncements() {
17
18
  return res.json();
18
19
  }
19
20
  function useNotifications(getClient, apiConfig, address) {
20
- const [readIds, setReadIds] = useState(() => getReadIds());
21
- const { orders: userOrders } = useUserOrders(getClient, address ?? null);
22
- const { orders: receivedOffers } = useReceivedOffers(apiConfig, address ?? null);
23
- const { activities } = useActivitiesByAddress(getClient, address ?? null);
21
+ const [readIds, setReadIds] = useState(() => /* @__PURE__ */ new Set());
22
+ useEffect(() => {
23
+ setReadIds(getReadIds());
24
+ }, []);
25
+ const { orders: userOrders, isLoading: ordersLoading } = useUserOrders(getClient, address ?? null);
26
+ const { orders: receivedOffers, isLoading: receivedLoading } = useReceivedOffers(apiConfig, address ?? null);
27
+ const { activities, isLoading: activitiesLoading } = useActivitiesByAddress(getClient, address ?? null);
24
28
  const { data: announcements = [] } = useSWR(
25
29
  "announcements",
26
30
  fetchAnnouncements,
@@ -127,9 +131,16 @@ function useNotifications(getClient, apiConfig, address) {
127
131
  markRead(ids);
128
132
  setReadIds(getReadIds());
129
133
  }, []);
134
+ const isLoading = notificationsAreLoading({
135
+ ordersLoading,
136
+ receivedLoading,
137
+ activitiesLoading,
138
+ hasAddress: !!address
139
+ });
130
140
  return {
131
141
  notifications,
132
142
  unreadCount,
143
+ isLoading,
133
144
  markAllRead: () => markNotificationsRead(notifications.map((n) => n.id)),
134
145
  markRead: (id) => markNotificationsRead([id])
135
146
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/use-notifications.ts"],"sourcesContent":["\"use client\";\n\nimport { useCallback, useMemo, useState } from \"react\";\nimport useSWR from \"swr\";\nimport { normalizeAddress } from \"@medialane/sdk\";\nimport type { ApiActivity } from \"@medialane/sdk\";\nimport type { MedialaneClient } from \"@medialane/sdk/starknet\";\nimport { useUserOrders, useReceivedOffers } from \"./use-orders.js\";\nimport { useActivitiesByAddress } from \"./use-activities.js\";\nimport { getReadIds, markRead } from \"./notification-storage.js\";\nimport {\n formatActivity,\n formatOrderNotification,\n formatOfferAcceptedNotification,\n formatAssetReceivedNotification,\n} from \"./format-activity.js\";\nimport type { Notification, Announcement } from \"../data/notification.js\";\nimport type { ApiFetchConfig } from \"./api-fetch.js\";\n\nasync function fetchAnnouncements(): Promise<Announcement[]> {\n const res = await fetch(\"/api/announcements\");\n if (!res.ok) return [];\n return res.json();\n}\n\nexport function useNotifications(\n getClient: () => MedialaneClient,\n apiConfig: ApiFetchConfig,\n address: string | null | undefined\n) {\n const [readIds, setReadIds] = useState<Set<string>>(() => getReadIds());\n\n const { orders: userOrders } = useUserOrders(getClient, address ?? null);\n\n const { orders: receivedOffers } = useReceivedOffers(apiConfig, address ?? null);\n const { activities } = useActivitiesByAddress(getClient, address ?? null);\n const { data: announcements = [] } = useSWR<Announcement[]>(\n \"announcements\",\n fetchAnnouncements,\n { revalidateOnFocus: false, dedupingInterval: 60_000 }\n );\n\n const notifications: Notification[] = useMemo(() => {\n const items: Notification[] = [];\n\n userOrders\n .filter((o) => o.offer.itemType === \"ERC20\" && o.status === \"FULFILLED\")\n .forEach((order) => {\n const id = `offer-accepted-${order.orderHash}`;\n const fmt = formatOfferAcceptedNotification(order);\n items.push({\n id,\n type: \"offer_accepted\",\n priority: \"spotlight\",\n celebratory: true,\n ...fmt,\n timestamp: order.updatedAt ?? order.createdAt ?? new Date().toISOString(),\n isUnread: !readIds.has(id),\n metadata: {\n amount: order.price?.formatted ?? undefined,\n currency: order.price?.currency ?? undefined,\n txHash: order.txHash?.fulfilled ?? undefined,\n assetName: order.token?.name ?? undefined,\n },\n });\n });\n\n receivedOffers.forEach((order) => {\n const id = `order-${order.orderHash}`;\n const fmt = formatOrderNotification(order);\n items.push({\n id,\n type: \"offer\",\n priority: \"spotlight\",\n celebratory: false,\n ...fmt,\n timestamp: order.createdAt ?? new Date().toISOString(),\n isUnread: !readIds.has(id),\n metadata: {\n amount: order.price?.formatted ?? undefined,\n currency: order.price?.currency ?? undefined,\n assetName: order.token?.name ?? undefined,\n },\n });\n });\n\n (activities as ApiActivity[]).slice(0, 50).forEach((event) => {\n const id = `activity-${event.txHash}-${event.type}-${event.nftTokenId ?? \"\"}`;\n\n if (\n event.type === \"transfer\" &&\n address &&\n !!event.to && normalizeAddress(\"STARKNET\", event.to) === normalizeAddress(\"STARKNET\", address)\n ) {\n const fmt = formatAssetReceivedNotification(event);\n items.push({\n id,\n type: \"asset_received\",\n priority: \"spotlight\",\n celebratory: true,\n ...fmt,\n timestamp: event.timestamp ?? new Date().toISOString(),\n isUnread: !readIds.has(id),\n metadata: {\n txHash: event.txHash ?? undefined,\n assetName: event.token?.name ?? undefined,\n },\n });\n return;\n }\n\n const isMySale =\n event.type === \"sale\" &&\n address &&\n ((!!event.offerer && normalizeAddress(\"STARKNET\", event.offerer) === normalizeAddress(\"STARKNET\", address)) ||\n (!!event.from && normalizeAddress(\"STARKNET\", event.from) === normalizeAddress(\"STARKNET\", address)));\n\n const fmt = formatActivity(event);\n items.push({\n id,\n type: event.type as Notification[\"type\"],\n priority: isMySale ? \"spotlight\" : \"normal\",\n celebratory: !!isMySale,\n ...fmt,\n timestamp: event.timestamp ?? new Date().toISOString(),\n isUnread: !readIds.has(id),\n metadata: {\n amount: event.price?.formatted ?? undefined,\n currency: event.price?.currency ?? undefined,\n txHash: event.txHash ?? undefined,\n assetName: event.token?.name ?? undefined,\n },\n });\n });\n\n announcements.forEach((ann) => {\n const id = `ann-${ann.id}`;\n items.push({\n id,\n type: \"announcement\",\n priority: ann.pinned ? \"spotlight\" : \"normal\",\n celebratory: false,\n title: ann.title,\n description: ann.body,\n image: ann.image,\n href: ann.href,\n timestamp: ann.created_at,\n isUnread: !readIds.has(id),\n });\n });\n\n items.sort(\n (a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime()\n );\n\n return items;\n }, [userOrders, receivedOffers, activities, announcements, address, readIds]);\n\n const unreadCount = notifications.filter((n) => n.isUnread).length;\n\n const markNotificationsRead = useCallback((ids: string[]) => {\n markRead(ids);\n setReadIds(getReadIds());\n }, []);\n\n return {\n notifications,\n unreadCount,\n markAllRead: () => markNotificationsRead(notifications.map((n) => n.id)),\n markRead: (id: string) => markNotificationsRead([id]),\n };\n}\n"],"mappings":"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","names":["fmt"]}
1
+ {"version":3,"sources":["../../src/utils/use-notifications.ts"],"sourcesContent":["\"use client\";\n\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport useSWR from \"swr\";\nimport { normalizeAddress } from \"@medialane/sdk\";\nimport type { ApiActivity } from \"@medialane/sdk\";\nimport type { MedialaneClient } from \"@medialane/sdk/starknet\";\nimport { useUserOrders, useReceivedOffers } from \"./use-orders.js\";\nimport { useActivitiesByAddress } from \"./use-activities.js\";\nimport { getReadIds, markRead } from \"./notification-storage.js\";\nimport { notificationsAreLoading } from \"./notification-readiness.js\";\nimport {\n formatActivity,\n formatOrderNotification,\n formatOfferAcceptedNotification,\n formatAssetReceivedNotification,\n} from \"./format-activity.js\";\nimport type { Notification, Announcement } from \"../data/notification.js\";\nimport type { ApiFetchConfig } from \"./api-fetch.js\";\n\nasync function fetchAnnouncements(): Promise<Announcement[]> {\n const res = await fetch(\"/api/announcements\");\n if (!res.ok) return [];\n return res.json();\n}\n\nexport function useNotifications(\n getClient: () => MedialaneClient,\n apiConfig: ApiFetchConfig,\n address: string | null | undefined\n) {\n const [readIds, setReadIds] = useState<Set<string>>(() => new Set<string>());\n\n useEffect(() => {\n setReadIds(getReadIds());\n }, []);\n\n const { orders: userOrders, isLoading: ordersLoading } = useUserOrders(getClient, address ?? null);\n\n const { orders: receivedOffers, isLoading: receivedLoading } = useReceivedOffers(apiConfig, address ?? null);\n const { activities, isLoading: activitiesLoading } = useActivitiesByAddress(getClient, address ?? null);\n const { data: announcements = [] } = useSWR<Announcement[]>(\n \"announcements\",\n fetchAnnouncements,\n { revalidateOnFocus: false, dedupingInterval: 60_000 }\n );\n\n const notifications: Notification[] = useMemo(() => {\n const items: Notification[] = [];\n\n userOrders\n .filter((o) => o.offer.itemType === \"ERC20\" && o.status === \"FULFILLED\")\n .forEach((order) => {\n const id = `offer-accepted-${order.orderHash}`;\n const fmt = formatOfferAcceptedNotification(order);\n items.push({\n id,\n type: \"offer_accepted\",\n priority: \"spotlight\",\n celebratory: true,\n ...fmt,\n timestamp: order.updatedAt ?? order.createdAt ?? new Date().toISOString(),\n isUnread: !readIds.has(id),\n metadata: {\n amount: order.price?.formatted ?? undefined,\n currency: order.price?.currency ?? undefined,\n txHash: order.txHash?.fulfilled ?? undefined,\n assetName: order.token?.name ?? undefined,\n },\n });\n });\n\n receivedOffers.forEach((order) => {\n const id = `order-${order.orderHash}`;\n const fmt = formatOrderNotification(order);\n items.push({\n id,\n type: \"offer\",\n priority: \"spotlight\",\n celebratory: false,\n ...fmt,\n timestamp: order.createdAt ?? new Date().toISOString(),\n isUnread: !readIds.has(id),\n metadata: {\n amount: order.price?.formatted ?? undefined,\n currency: order.price?.currency ?? undefined,\n assetName: order.token?.name ?? undefined,\n },\n });\n });\n\n (activities as ApiActivity[]).slice(0, 50).forEach((event) => {\n const id = `activity-${event.txHash}-${event.type}-${event.nftTokenId ?? \"\"}`;\n\n if (\n event.type === \"transfer\" &&\n address &&\n !!event.to && normalizeAddress(\"STARKNET\", event.to) === normalizeAddress(\"STARKNET\", address)\n ) {\n const fmt = formatAssetReceivedNotification(event);\n items.push({\n id,\n type: \"asset_received\",\n priority: \"spotlight\",\n celebratory: true,\n ...fmt,\n timestamp: event.timestamp ?? new Date().toISOString(),\n isUnread: !readIds.has(id),\n metadata: {\n txHash: event.txHash ?? undefined,\n assetName: event.token?.name ?? undefined,\n },\n });\n return;\n }\n\n const isMySale =\n event.type === \"sale\" &&\n address &&\n ((!!event.offerer && normalizeAddress(\"STARKNET\", event.offerer) === normalizeAddress(\"STARKNET\", address)) ||\n (!!event.from && normalizeAddress(\"STARKNET\", event.from) === normalizeAddress(\"STARKNET\", address)));\n\n const fmt = formatActivity(event);\n items.push({\n id,\n type: event.type as Notification[\"type\"],\n priority: isMySale ? \"spotlight\" : \"normal\",\n celebratory: !!isMySale,\n ...fmt,\n timestamp: event.timestamp ?? new Date().toISOString(),\n isUnread: !readIds.has(id),\n metadata: {\n amount: event.price?.formatted ?? undefined,\n currency: event.price?.currency ?? undefined,\n txHash: event.txHash ?? undefined,\n assetName: event.token?.name ?? undefined,\n },\n });\n });\n\n announcements.forEach((ann) => {\n const id = `ann-${ann.id}`;\n items.push({\n id,\n type: \"announcement\",\n priority: ann.pinned ? \"spotlight\" : \"normal\",\n celebratory: false,\n title: ann.title,\n description: ann.body,\n image: ann.image,\n href: ann.href,\n timestamp: ann.created_at,\n isUnread: !readIds.has(id),\n });\n });\n\n items.sort(\n (a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime()\n );\n\n return items;\n }, [userOrders, receivedOffers, activities, announcements, address, readIds]);\n\n const unreadCount = notifications.filter((n) => n.isUnread).length;\n\n const markNotificationsRead = useCallback((ids: string[]) => {\n markRead(ids);\n setReadIds(getReadIds());\n }, []);\n\n const isLoading = notificationsAreLoading({\n ordersLoading,\n receivedLoading,\n activitiesLoading,\n hasAddress: !!address,\n });\n\n return {\n notifications,\n unreadCount,\n isLoading,\n markAllRead: () => markNotificationsRead(notifications.map((n) => n.id)),\n markRead: (id: string) => markNotificationsRead([id]),\n };\n}\n"],"mappings":"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","names":["fmt"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@medialane/ui",
3
- "version": "0.161.0",
3
+ "version": "0.161.1",
4
4
  "description": "Shared UI components for Medialane apps",
5
5
  "type": "module",
6
6
  "sideEffects": false,