@linktr.ee/messaging-react 1.29.0 → 1.29.1-rc-1776408377

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.
@@ -0,0 +1,196 @@
1
+ import { jsxs as l, jsx as e, Fragment as p } from "react/jsx-runtime";
2
+ import { CheckCircleIcon as T, LockSimpleIcon as y, DownloadSimpleIcon as P, LockOpenIcon as C } from "@phosphor-icons/react";
3
+ import { useState as b, useEffect as L } from "react";
4
+ import { g as D, r as g, M as U } from "./MediaPlayer-Bf-xPB8Z.js";
5
+ const x = (s) => s === "paid" ? C : y, z = (s) => {
6
+ const { icon: t } = s;
7
+ return /* @__PURE__ */ e("div", { className: "absolute inset-0 bg-black/30", children: /* @__PURE__ */ e("div", { className: "absolute left-3 top-3 flex size-8 items-center justify-center rounded-full bg-black/60", children: /* @__PURE__ */ e(t, { className: "size-4 text-white", weight: "fill" }) }) });
8
+ }, I = (s) => {
9
+ const { thumbnail: t, mimeType: n, LockIcon: a } = s;
10
+ return /* @__PURE__ */ l("div", { className: "relative aspect-video overflow-hidden bg-black/5", children: [
11
+ t ? /* @__PURE__ */ e(
12
+ "img",
13
+ {
14
+ src: t,
15
+ alt: "",
16
+ className: "absolute inset-0 h-full w-full object-cover"
17
+ }
18
+ ) : /* @__PURE__ */ e("div", { className: "absolute inset-0 flex items-center justify-center", children: g(n, {
19
+ className: "size-12 text-black/20",
20
+ weight: "regular"
21
+ }) }),
22
+ /* @__PURE__ */ e(z, { icon: a })
23
+ ] });
24
+ }, M = (s) => {
25
+ const { source: t, thumbnail: n, mimeType: a, title: c, paymentStatus: i, isLocked: r } = s, [o, d] = b(!1);
26
+ return L(() => {
27
+ d(!1);
28
+ }, [t]), r ? /* @__PURE__ */ e(
29
+ I,
30
+ {
31
+ thumbnail: n,
32
+ mimeType: a,
33
+ LockIcon: x(i)
34
+ }
35
+ ) : /* @__PURE__ */ e("div", { className: "relative overflow-hidden bg-black/5", children: /* @__PURE__ */ e(
36
+ "img",
37
+ {
38
+ src: t,
39
+ alt: c,
40
+ className: `block w-full transition-opacity duration-300 ${o ? "opacity-100" : "opacity-0"}`,
41
+ onLoad: () => d(!0)
42
+ }
43
+ ) });
44
+ }, O = (s) => {
45
+ const { thumbnail: t, mimeType: n, paymentStatus: a, isLocked: c } = s;
46
+ return /* @__PURE__ */ l("div", { className: "relative aspect-video overflow-hidden bg-black/5", children: [
47
+ t ? /* @__PURE__ */ e(
48
+ "img",
49
+ {
50
+ src: t,
51
+ alt: "",
52
+ className: "absolute inset-0 h-full w-full object-cover"
53
+ }
54
+ ) : /* @__PURE__ */ e("div", { className: "absolute inset-0 flex items-center justify-center", children: g(n, {
55
+ className: "size-12 text-black/20",
56
+ weight: "regular"
57
+ }) }),
58
+ c && /* @__PURE__ */ e(z, { icon: x(a) })
59
+ ] });
60
+ }, R = (s) => {
61
+ const { source: t, thumbnail: n, mimeType: a, paymentStatus: c, isLocked: i } = s;
62
+ return i ? /* @__PURE__ */ e(
63
+ I,
64
+ {
65
+ thumbnail: n,
66
+ mimeType: a,
67
+ LockIcon: x(c)
68
+ }
69
+ ) : /* @__PURE__ */ e(U, { source: t, mimeType: a, poster: n });
70
+ }, A = () => /* @__PURE__ */ l("span", { className: "flex items-center gap-1", children: [
71
+ /* @__PURE__ */ e("span", { className: "size-1 rounded-full bg-white animate-bounce [animation-delay:-0.3s]" }),
72
+ /* @__PURE__ */ e("span", { className: "size-1 rounded-full bg-white animate-bounce [animation-delay:-0.15s]" }),
73
+ /* @__PURE__ */ e("span", { className: "size-1 rounded-full bg-white animate-bounce" })
74
+ ] }), E = (s) => {
75
+ const { isLocked: t, unlockLoading: n, source: a, onUnlock: c, onDownload: i } = s;
76
+ return t && c ? /* @__PURE__ */ e(
77
+ "button",
78
+ {
79
+ type: "button",
80
+ onClick: c,
81
+ disabled: n,
82
+ className: "mt-3 inline-flex h-10 w-full items-center justify-center gap-2 rounded-full bg-[#121110] px-4 text-sm font-medium leading-none text-white hover:bg-[#2a2928] disabled:opacity-70",
83
+ children: n ? /* @__PURE__ */ e(A, {}) : /* @__PURE__ */ l(p, { children: [
84
+ /* @__PURE__ */ e(y, { className: "size-4", weight: "fill" }),
85
+ "Unlock"
86
+ ] })
87
+ }
88
+ ) : !t && i && a ? /* @__PURE__ */ l(
89
+ "a",
90
+ {
91
+ href: a,
92
+ onClick: i,
93
+ className: "mt-3 inline-flex h-10 w-full items-center justify-center gap-2 rounded-full bg-[#121110] px-4 text-sm font-medium leading-none text-white hover:bg-[#2a2928]",
94
+ children: [
95
+ /* @__PURE__ */ e(P, { className: "size-4", weight: "bold" }),
96
+ "Download"
97
+ ]
98
+ }
99
+ ) : null;
100
+ }, B = (s) => {
101
+ const {
102
+ title: t,
103
+ amountText: n,
104
+ thumbnail: a,
105
+ source: c,
106
+ mimeType: i = "application/octet-stream",
107
+ detail: r,
108
+ onUnlock: o,
109
+ onDownload: d,
110
+ paymentStatus: m
111
+ } = s, [u, k] = b(c), [S, w] = b(!1);
112
+ L(() => {
113
+ c !== void 0 && k(c);
114
+ }, [c]);
115
+ const f = u === void 0, v = D(i), j = async () => {
116
+ if (o) {
117
+ w(!0);
118
+ try {
119
+ const N = await o();
120
+ k(N.source);
121
+ } catch {
122
+ } finally {
123
+ w(!1);
124
+ }
125
+ }
126
+ };
127
+ let h;
128
+ return v === "image" ? h = /* @__PURE__ */ e(
129
+ M,
130
+ {
131
+ source: u,
132
+ thumbnail: a,
133
+ mimeType: i,
134
+ title: t,
135
+ paymentStatus: m,
136
+ isLocked: f
137
+ }
138
+ ) : v === "document" ? h = /* @__PURE__ */ e(
139
+ O,
140
+ {
141
+ thumbnail: a,
142
+ mimeType: i,
143
+ paymentStatus: m,
144
+ isLocked: f
145
+ }
146
+ ) : h = /* @__PURE__ */ e(
147
+ R,
148
+ {
149
+ source: u,
150
+ thumbnail: a,
151
+ mimeType: i,
152
+ paymentStatus: m,
153
+ isLocked: f
154
+ }
155
+ ), /* @__PURE__ */ l("div", { className: "w-[280px] select-none overflow-hidden rounded-3xl bg-white shadow-card", children: [
156
+ h,
157
+ /* @__PURE__ */ l("div", { className: "px-4 pb-3 pt-3", children: [
158
+ /* @__PURE__ */ e("p", { className: "mb-1.5 truncate text-base font-medium text-black", children: t }),
159
+ /* @__PURE__ */ l("div", { className: "flex items-center gap-1", children: [
160
+ g(i, {
161
+ className: "size-5 shrink-0 text-black/55",
162
+ weight: "regular"
163
+ }),
164
+ r && /* @__PURE__ */ e("span", { className: "text-xs font-medium text-black/55", children: r }),
165
+ m === "paid" ? /* @__PURE__ */ l(p, { children: [
166
+ /* @__PURE__ */ e("span", { className: "text-xs font-medium text-black/55", children: "•" }),
167
+ /* @__PURE__ */ e("span", { className: "text-xs font-medium text-[#008236]", children: "Purchased" }),
168
+ /* @__PURE__ */ e(
169
+ T,
170
+ {
171
+ className: "size-4 text-[#008236]",
172
+ weight: "bold"
173
+ }
174
+ )
175
+ ] }) : n && /* @__PURE__ */ l(p, { children: [
176
+ /* @__PURE__ */ e("span", { className: "text-xs font-medium text-black/55", children: "•" }),
177
+ /* @__PURE__ */ e("span", { className: "text-xs font-medium text-black/55", children: n })
178
+ ] })
179
+ ] }),
180
+ /* @__PURE__ */ e(
181
+ E,
182
+ {
183
+ isLocked: f,
184
+ unlockLoading: S,
185
+ source: u,
186
+ onUnlock: o ? j : void 0,
187
+ onDownload: d
188
+ }
189
+ )
190
+ ] })
191
+ ] });
192
+ };
193
+ export {
194
+ B as default
195
+ };
196
+ //# sourceMappingURL=Visitor-BcyrCpuF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Visitor-BcyrCpuF.js","sources":["../src/components/LockedAttachment/components/Visitor.tsx"],"sourcesContent":["import {\n CheckCircleIcon,\n DownloadSimpleIcon,\n LockOpenIcon,\n LockSimpleIcon,\n} from '@phosphor-icons/react'\nimport React, { useEffect, useState } from 'react'\n\nimport { isDevBuild } from '../../../utils/isDevBuild'\nimport type {\n LockedAttachmentBaseProps,\n LockedAttachmentSource,\n PaymentStatus,\n} from '../types'\nimport { renderTypeIcon } from '../utils/icons'\nimport { getSourceType } from '../utils/mimeType'\n\nimport MediaPlayer from './MediaPlayer'\n\nexport interface VisitorCardProps extends LockedAttachmentBaseProps {\n /**\n * Called when the visitor clicks Unlock. Return the resolved source URL.\n * The component manages loading state and sets source internally on resolution.\n * Omit to hide the Unlock button.\n */\n onUnlock?: () => Promise<LockedAttachmentSource>\n /** Called when the visitor clicks Download on an unlocked card. */\n onDownload?: () => void \n}\n\nconst getLockIcon = (paymentStatus?: PaymentStatus): React.ElementType =>\n paymentStatus === 'paid' ? LockOpenIcon : LockSimpleIcon\n\n\ninterface LockOverlayProps {\n icon: React.ElementType\n}\n\nconst LockOverlay: React.FC<LockOverlayProps> = (props) => {\n const { icon: Icon } = props\n return (\n <div className=\"absolute inset-0 bg-black/30\">\n <div className=\"absolute left-3 top-3 flex size-8 items-center justify-center rounded-full bg-black/60\">\n <Icon className=\"size-4 text-white\" weight=\"fill\" />\n </div>\n </div>\n )\n}\n\ninterface LockedPreviewProps {\n thumbnail?: string\n mimeType: string\n LockIcon: React.ElementType\n}\n\nconst LockedPreview: React.FC<LockedPreviewProps> = (props) => {\n const { thumbnail, mimeType, LockIcon } = props\n return (\n <div className=\"relative aspect-video overflow-hidden bg-black/5\">\n {thumbnail ? (\n <img\n src={thumbnail}\n alt=\"\"\n className=\"absolute inset-0 h-full w-full object-cover\"\n />\n ) : (\n <div className=\"absolute inset-0 flex items-center justify-center\">\n {renderTypeIcon(mimeType, {\n className: 'size-12 text-black/20',\n weight: 'regular',\n })}\n </div>\n )}\n <LockOverlay icon={LockIcon} />\n </div>\n )\n}\n\n\ninterface ImagePreviewProps {\n source?: string\n thumbnail?: string\n mimeType: string\n title?: string\n paymentStatus?: PaymentStatus\n isLocked: boolean\n}\n\nconst ImagePreview: React.FC<ImagePreviewProps> = (props) => {\n const { source, thumbnail, mimeType, title, paymentStatus, isLocked } = props\n const [sourceReady, setSourceReady] = useState(false)\n\n useEffect(() => {\n setSourceReady(false)\n }, [source])\n\n if (isLocked) {\n return (\n <LockedPreview\n thumbnail={thumbnail}\n mimeType={mimeType}\n LockIcon={getLockIcon(paymentStatus)}\n />\n )\n }\n\n return (\n <div className=\"relative overflow-hidden bg-black/5\">\n <img\n src={source}\n alt={title}\n className={`block w-full transition-opacity duration-300 ${sourceReady ? 'opacity-100' : 'opacity-0'}`}\n onLoad={() => setSourceReady(true)}\n />\n </div>\n )\n}\n\ninterface DocumentPreviewProps {\n thumbnail?: string\n mimeType: string\n paymentStatus?: PaymentStatus\n isLocked: boolean\n}\n\nconst DocumentPreview: React.FC<DocumentPreviewProps> = (props) => {\n const { thumbnail, mimeType, paymentStatus, isLocked } = props\n return (\n <div className=\"relative aspect-video overflow-hidden bg-black/5\">\n {thumbnail ? (\n <img\n src={thumbnail}\n alt=\"\"\n className=\"absolute inset-0 h-full w-full object-cover\"\n />\n ) : (\n <div className=\"absolute inset-0 flex items-center justify-center\">\n {renderTypeIcon(mimeType, {\n className: 'size-12 text-black/20',\n weight: 'regular',\n })}\n </div>\n )}\n {isLocked && <LockOverlay icon={getLockIcon(paymentStatus)} />}\n </div>\n )\n}\n\ninterface MediaPreviewProps {\n source?: string\n thumbnail?: string\n mimeType: string\n paymentStatus?: PaymentStatus\n isLocked: boolean\n}\n\nconst MediaPreview: React.FC<MediaPreviewProps> = (props) => {\n const { source, thumbnail, mimeType, paymentStatus, isLocked } = props\n if (isLocked) {\n return (\n <LockedPreview\n thumbnail={thumbnail}\n mimeType={mimeType}\n LockIcon={getLockIcon(paymentStatus)}\n />\n )\n }\n return <MediaPlayer source={source!} mimeType={mimeType} poster={thumbnail} />\n}\n\n\nconst LoadingDots = () => (\n <span className=\"flex items-center gap-1\">\n <span className=\"size-1 rounded-full bg-white animate-bounce [animation-delay:-0.3s]\" />\n <span className=\"size-1 rounded-full bg-white animate-bounce [animation-delay:-0.15s]\" />\n <span className=\"size-1 rounded-full bg-white animate-bounce\" />\n </span>\n)\n\ninterface CardActionsProps {\n isLocked: boolean\n unlockLoading: boolean\n source?: string\n onUnlock?: () => void\n onDownload?: () => void\n}\n\nconst CardActions: React.FC<CardActionsProps> = (props) => {\n const { isLocked, unlockLoading, source, onUnlock, onDownload } = props\n\n if (isLocked && onUnlock) {\n return (\n <button\n type=\"button\"\n onClick={onUnlock}\n disabled={unlockLoading}\n className=\"mt-3 inline-flex h-10 w-full items-center justify-center gap-2 rounded-full bg-[#121110] px-4 text-sm font-medium leading-none text-white hover:bg-[#2a2928] disabled:opacity-70\"\n >\n {unlockLoading ? (\n <LoadingDots />\n ) : (\n <>\n <LockSimpleIcon className=\"size-4\" weight=\"fill\" />\n Unlock\n </>\n )}\n </button>\n )\n }\n\n if (!isLocked && onDownload && source) {\n return (\n <a\n href={source}\n onClick={onDownload}\n className=\"mt-3 inline-flex h-10 w-full items-center justify-center gap-2 rounded-full bg-[#121110] px-4 text-sm font-medium leading-none text-white hover:bg-[#2a2928]\"\n >\n <DownloadSimpleIcon className=\"size-4\" weight=\"bold\" />\n Download\n </a>\n )\n }\n\n return null\n}\n\n\nconst VisitorCard: React.FC<VisitorCardProps> = (props) => {\n const {\n title,\n amountText,\n thumbnail,\n source: sourceProp,\n mimeType = 'application/octet-stream',\n detail,\n onUnlock,\n onDownload,\n paymentStatus,\n } = props\n const [source, setSource] = useState(sourceProp)\n const [unlockLoading, setUnlockLoading] = useState(false)\n\n useEffect(() => {\n if (sourceProp !== undefined) setSource(sourceProp)\n }, [sourceProp])\n\n const isLocked = source === undefined\n const sourceType = getSourceType(mimeType)\n\n const handleUnlock = async () => {\n if (!onUnlock) return\n setUnlockLoading(true)\n try {\n const result = await onUnlock()\n setSource(result.source)\n } catch (err) {\n if (isDevBuild()) console.debug('[LockedAttachment] onUnlock failed', err)\n } finally {\n setUnlockLoading(false)\n }\n }\n\n let mediaPreview: React.ReactNode\n if (sourceType === 'image') {\n mediaPreview = (\n <ImagePreview\n source={source}\n thumbnail={thumbnail}\n mimeType={mimeType}\n title={title}\n paymentStatus={paymentStatus}\n isLocked={isLocked}\n />\n )\n } else if (sourceType === 'document') {\n mediaPreview = (\n <DocumentPreview\n thumbnail={thumbnail}\n mimeType={mimeType}\n paymentStatus={paymentStatus}\n isLocked={isLocked}\n />\n )\n } else {\n mediaPreview = (\n <MediaPreview\n source={source}\n thumbnail={thumbnail}\n mimeType={mimeType}\n paymentStatus={paymentStatus}\n isLocked={isLocked}\n />\n )\n }\n\n return (\n <div className=\"w-[280px] select-none overflow-hidden rounded-3xl bg-white shadow-card\">\n {mediaPreview}\n <div className=\"px-4 pb-3 pt-3\">\n <p className=\"mb-1.5 truncate text-base font-medium text-black\">\n {title}\n </p>\n <div className=\"flex items-center gap-1\">\n {renderTypeIcon(mimeType, {\n className: 'size-5 shrink-0 text-black/55',\n weight: 'regular',\n })}\n {detail && (\n <span className=\"text-xs font-medium text-black/55\">{detail}</span>\n )}\n {paymentStatus === 'paid' ? (\n <>\n <span className=\"text-xs font-medium text-black/55\">•</span>\n <span className=\"text-xs font-medium text-[#008236]\">\n Purchased\n </span>\n <CheckCircleIcon\n className=\"size-4 text-[#008236]\"\n weight=\"bold\"\n />\n </>\n ) : (\n amountText && (\n <>\n <span className=\"text-xs font-medium text-black/55\">•</span>\n <span className=\"text-xs font-medium text-black/55\">\n {amountText}\n </span>\n </>\n )\n )}\n </div>\n <CardActions\n isLocked={isLocked}\n unlockLoading={unlockLoading}\n source={source}\n onUnlock={onUnlock ? handleUnlock : undefined}\n onDownload={onDownload}\n />\n </div>\n </div>\n )\n}\n\nexport default VisitorCard\n"],"names":["getLockIcon","paymentStatus","LockOpenIcon","LockSimpleIcon","LockOverlay","props","Icon","jsx","LockedPreview","thumbnail","mimeType","LockIcon","jsxs","ImagePreview","source","title","isLocked","sourceReady","setSourceReady","useState","useEffect","DocumentPreview","MediaPreview","MediaPlayer","LoadingDots","CardActions","unlockLoading","onUnlock","onDownload","Fragment","DownloadSimpleIcon","VisitorCard","amountText","sourceProp","detail","setSource","setUnlockLoading","sourceType","getSourceType","handleUnlock","result","mediaPreview","renderTypeIcon","CheckCircleIcon"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -524,11 +524,8 @@ declare interface VisitorCardProps extends LockedAttachmentBaseProps {
524
524
  * Omit to hide the Unlock button.
525
525
  */
526
526
  onUnlock?: () => Promise<LockedAttachmentSource>;
527
- /**
528
- * Called when the visitor clicks Download on an unlocked card.
529
- * May return a Promise — if so, the component shows a loader until it resolves.
530
- */
531
- onDownload?: () => void | Promise<void>;
527
+ /** Called when the visitor clicks Download on an unlocked card. */
528
+ onDownload?: () => void;
532
529
  }
533
530
 
534
531
  export declare type VoteSelection = 'up' | 'down' | null;
package/dist/index.js CHANGED
@@ -835,7 +835,7 @@ function ws(t) {
835
835
  }, [s, n == null ? void 0 : n.userID, t.id, o]);
836
836
  return { selected: o, voteUp: l, voteDown: d };
837
837
  }
838
- const _s = F.lazy(() => import("./Creator-VyMyIk2b.js")), Es = F.lazy(() => import("./Visitor-C4WqnN8H.js")), Je = () => /* @__PURE__ */ e(
838
+ const _s = F.lazy(() => import("./Creator-VyMyIk2b.js")), Es = F.lazy(() => import("./Visitor-BcyrCpuF.js")), Je = () => /* @__PURE__ */ e(
839
839
  "div",
840
840
  {
841
841
  className: "w-[280px] min-h-[200px] animate-pulse rounded-3xl bg-black/[0.06] shadow-[0px_0px_0px_1px_rgba(0,0,0,0.04),0px_1px_2px_0px_rgba(0,0,0,0.04)]",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@linktr.ee/messaging-react",
3
- "version": "1.29.0",
3
+ "version": "1.29.1-rc-1776408377",
4
4
  "description": "React messaging components built on messaging-core for web applications",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -33,10 +33,9 @@
33
33
  "storybook:build": "storybook build"
34
34
  },
35
35
  "dependencies": {
36
- "@linktr.ee/component-library": "*",
37
- "@linktr.ee/messaging-core": "^1.5.0",
38
- "@phosphor-icons/react": "^2.1.9",
39
- "stream-chat-react": "^13.12.0"
36
+ "@linktr.ee/component-library": "12.1.4",
37
+ "@linktr.ee/messaging-core": "^1.7.1",
38
+ "@phosphor-icons/react": "^2.1.10"
40
39
  },
41
40
  "devDependencies": {
42
41
  "@storybook/addon-essentials": "^8.5.0",
@@ -62,6 +61,7 @@
62
61
  "react-dom": "^18.3.1",
63
62
  "storybook": "^8.5.0",
64
63
  "stream-chat": "^9.26.0",
64
+ "stream-chat-react": "^13.12.0",
65
65
  "tailwindcss": "^3.4.17",
66
66
  "tailwindcss-animate": "^1.0.7",
67
67
  "typescript": "5.9.2",
@@ -182,7 +182,7 @@ export const Visitor: StoryFn = () => (
182
182
  detail={detail}
183
183
  amountText="AU$9.99"
184
184
  paymentStatus="paid"
185
- onDownload={() => new Promise((resolve) => setTimeout(resolve, 2000))}
185
+ onDownload={() => {}}
186
186
  />
187
187
  </td>
188
188
  ))}
@@ -24,11 +24,8 @@ export interface VisitorCardProps extends LockedAttachmentBaseProps {
24
24
  * Omit to hide the Unlock button.
25
25
  */
26
26
  onUnlock?: () => Promise<LockedAttachmentSource>
27
- /**
28
- * Called when the visitor clicks Download on an unlocked card.
29
- * May return a Promise — if so, the component shows a loader until it resolves.
30
- */
31
- onDownload?: () => void | Promise<void>
27
+ /** Called when the visitor clicks Download on an unlocked card. */
28
+ onDownload?: () => void
32
29
  }
33
30
 
34
31
  const getLockIcon = (paymentStatus?: PaymentStatus): React.ElementType =>
@@ -37,23 +34,14 @@ const getLockIcon = (paymentStatus?: PaymentStatus): React.ElementType =>
37
34
 
38
35
  interface LockOverlayProps {
39
36
  icon: React.ElementType
40
- loading?: boolean
41
37
  }
42
38
 
43
39
  const LockOverlay: React.FC<LockOverlayProps> = (props) => {
44
- const { icon: Icon, loading } = props
40
+ const { icon: Icon } = props
45
41
  return (
46
42
  <div className="absolute inset-0 bg-black/30">
47
43
  <div className="absolute left-3 top-3 flex size-8 items-center justify-center rounded-full bg-black/60">
48
- {loading ? (
49
- <span className="flex items-center gap-[2px]">
50
- <span className="size-1 rounded-full bg-white animate-bounce [animation-delay:-0.3s]" />
51
- <span className="size-1 rounded-full bg-white animate-bounce [animation-delay:-0.15s]" />
52
- <span className="size-1 rounded-full bg-white animate-bounce" />
53
- </span>
54
- ) : (
55
- <Icon className="size-4 text-white" weight="fill" />
56
- )}
44
+ <Icon className="size-4 text-white" weight="fill" />
57
45
  </div>
58
46
  </div>
59
47
  )
@@ -63,11 +51,10 @@ interface LockedPreviewProps {
63
51
  thumbnail?: string
64
52
  mimeType: string
65
53
  LockIcon: React.ElementType
66
- loading?: boolean
67
54
  }
68
55
 
69
56
  const LockedPreview: React.FC<LockedPreviewProps> = (props) => {
70
- const { thumbnail, mimeType, LockIcon, loading } = props
57
+ const { thumbnail, mimeType, LockIcon } = props
71
58
  return (
72
59
  <div className="relative aspect-video overflow-hidden bg-black/5">
73
60
  {thumbnail ? (
@@ -84,7 +71,7 @@ const LockedPreview: React.FC<LockedPreviewProps> = (props) => {
84
71
  })}
85
72
  </div>
86
73
  )}
87
- <LockOverlay icon={LockIcon} loading={loading} />
74
+ <LockOverlay icon={LockIcon} />
88
75
  </div>
89
76
  )
90
77
  }
@@ -97,11 +84,10 @@ interface ImagePreviewProps {
97
84
  title?: string
98
85
  paymentStatus?: PaymentStatus
99
86
  isLocked: boolean
100
- loading?: boolean
101
87
  }
102
88
 
103
89
  const ImagePreview: React.FC<ImagePreviewProps> = (props) => {
104
- const { source, thumbnail, mimeType, title, paymentStatus, isLocked, loading } = props
90
+ const { source, thumbnail, mimeType, title, paymentStatus, isLocked } = props
105
91
  const [sourceReady, setSourceReady] = useState(false)
106
92
 
107
93
  useEffect(() => {
@@ -114,7 +100,6 @@ const ImagePreview: React.FC<ImagePreviewProps> = (props) => {
114
100
  thumbnail={thumbnail}
115
101
  mimeType={mimeType}
116
102
  LockIcon={getLockIcon(paymentStatus)}
117
- loading={loading}
118
103
  />
119
104
  )
120
105
  }
@@ -136,11 +121,10 @@ interface DocumentPreviewProps {
136
121
  mimeType: string
137
122
  paymentStatus?: PaymentStatus
138
123
  isLocked: boolean
139
- loading?: boolean
140
124
  }
141
125
 
142
126
  const DocumentPreview: React.FC<DocumentPreviewProps> = (props) => {
143
- const { thumbnail, mimeType, paymentStatus, isLocked, loading } = props
127
+ const { thumbnail, mimeType, paymentStatus, isLocked } = props
144
128
  return (
145
129
  <div className="relative aspect-video overflow-hidden bg-black/5">
146
130
  {thumbnail ? (
@@ -157,7 +141,7 @@ const DocumentPreview: React.FC<DocumentPreviewProps> = (props) => {
157
141
  })}
158
142
  </div>
159
143
  )}
160
- {isLocked && <LockOverlay icon={getLockIcon(paymentStatus)} loading={loading} />}
144
+ {isLocked && <LockOverlay icon={getLockIcon(paymentStatus)} />}
161
145
  </div>
162
146
  )
163
147
  }
@@ -168,18 +152,16 @@ interface MediaPreviewProps {
168
152
  mimeType: string
169
153
  paymentStatus?: PaymentStatus
170
154
  isLocked: boolean
171
- loading?: boolean
172
155
  }
173
156
 
174
157
  const MediaPreview: React.FC<MediaPreviewProps> = (props) => {
175
- const { source, thumbnail, mimeType, paymentStatus, isLocked, loading } = props
158
+ const { source, thumbnail, mimeType, paymentStatus, isLocked } = props
176
159
  if (isLocked) {
177
160
  return (
178
161
  <LockedPreview
179
162
  thumbnail={thumbnail}
180
163
  mimeType={mimeType}
181
164
  LockIcon={getLockIcon(paymentStatus)}
182
- loading={loading}
183
165
  />
184
166
  )
185
167
  }
@@ -198,16 +180,13 @@ const LoadingDots = () => (
198
180
  interface CardActionsProps {
199
181
  isLocked: boolean
200
182
  unlockLoading: boolean
201
- downloadLoading: boolean
202
- paymentStatus?: PaymentStatus
203
183
  source?: string
204
184
  onUnlock?: () => void
205
185
  onDownload?: () => void
206
186
  }
207
187
 
208
188
  const CardActions: React.FC<CardActionsProps> = (props) => {
209
- const { isLocked, unlockLoading, downloadLoading, paymentStatus, source, onUnlock, onDownload } = props
210
- const LockIcon = getLockIcon(paymentStatus)
189
+ const { isLocked, unlockLoading, source, onUnlock, onDownload } = props
211
190
 
212
191
  if (isLocked && onUnlock) {
213
192
  return (
@@ -215,18 +194,14 @@ const CardActions: React.FC<CardActionsProps> = (props) => {
215
194
  type="button"
216
195
  onClick={onUnlock}
217
196
  disabled={unlockLoading}
218
- className="mt-3 inline-flex h-10 w-full items-center justify-center gap-2 rounded-full bg-[#121110] px-4 text-sm font-medium leading-none text-white disabled:opacity-70"
197
+ className="mt-3 inline-flex h-10 w-full items-center justify-center gap-2 rounded-full bg-[#121110] px-4 text-sm font-medium leading-none text-white hover:bg-[#2a2928] disabled:opacity-70"
219
198
  >
220
199
  {unlockLoading ? (
221
200
  <LoadingDots />
222
201
  ) : (
223
202
  <>
224
- {paymentStatus === 'paid' ? (
225
- <LockOpenIcon className="size-4" weight="fill" />
226
- ) : (
227
- <LockIcon className="size-4" weight="fill" />
228
- )}
229
- {paymentStatus === 'paid' ? 'Open' : 'Unlock'}
203
+ <LockSimpleIcon className="size-4" weight="fill" />
204
+ Unlock
230
205
  </>
231
206
  )}
232
207
  </button>
@@ -235,21 +210,14 @@ const CardActions: React.FC<CardActionsProps> = (props) => {
235
210
 
236
211
  if (!isLocked && onDownload && source) {
237
212
  return (
238
- <button
239
- type="button"
213
+ <a
214
+ href={source}
240
215
  onClick={onDownload}
241
- disabled={downloadLoading}
242
- className="mt-3 inline-flex h-10 w-full items-center justify-center gap-2 rounded-full bg-[#121110] px-4 text-sm font-medium leading-none text-white disabled:opacity-70"
216
+ className="mt-3 inline-flex h-10 w-full items-center justify-center gap-2 rounded-full bg-[#121110] px-4 text-sm font-medium leading-none text-white hover:bg-[#2a2928]"
243
217
  >
244
- {downloadLoading ? (
245
- <LoadingDots />
246
- ) : (
247
- <>
248
- <DownloadSimpleIcon className="size-4" weight="bold" />
249
- Download
250
- </>
251
- )}
252
- </button>
218
+ <DownloadSimpleIcon className="size-4" weight="bold" />
219
+ Download
220
+ </a>
253
221
  )
254
222
  }
255
223
 
@@ -271,7 +239,6 @@ const VisitorCard: React.FC<VisitorCardProps> = (props) => {
271
239
  } = props
272
240
  const [source, setSource] = useState(sourceProp)
273
241
  const [unlockLoading, setUnlockLoading] = useState(false)
274
- const [downloadLoading, setDownloadLoading] = useState(false)
275
242
 
276
243
  useEffect(() => {
277
244
  if (sourceProp !== undefined) setSource(sourceProp)
@@ -293,18 +260,6 @@ const VisitorCard: React.FC<VisitorCardProps> = (props) => {
293
260
  }
294
261
  }
295
262
 
296
- const handleDownload = async () => {
297
- if (!onDownload) return
298
- setDownloadLoading(true)
299
- try {
300
- await onDownload()
301
- } catch (err) {
302
- if (isDevBuild()) console.debug('[LockedAttachment] onDownload failed', err)
303
- } finally {
304
- setDownloadLoading(false)
305
- }
306
- }
307
-
308
263
  let mediaPreview: React.ReactNode
309
264
  if (sourceType === 'image') {
310
265
  mediaPreview = (
@@ -315,7 +270,6 @@ const VisitorCard: React.FC<VisitorCardProps> = (props) => {
315
270
  title={title}
316
271
  paymentStatus={paymentStatus}
317
272
  isLocked={isLocked}
318
- loading={unlockLoading}
319
273
  />
320
274
  )
321
275
  } else if (sourceType === 'document') {
@@ -325,7 +279,6 @@ const VisitorCard: React.FC<VisitorCardProps> = (props) => {
325
279
  mimeType={mimeType}
326
280
  paymentStatus={paymentStatus}
327
281
  isLocked={isLocked}
328
- loading={unlockLoading}
329
282
  />
330
283
  )
331
284
  } else {
@@ -336,7 +289,6 @@ const VisitorCard: React.FC<VisitorCardProps> = (props) => {
336
289
  mimeType={mimeType}
337
290
  paymentStatus={paymentStatus}
338
291
  isLocked={isLocked}
339
- loading={unlockLoading}
340
292
  />
341
293
  )
342
294
  }
@@ -381,11 +333,9 @@ const VisitorCard: React.FC<VisitorCardProps> = (props) => {
381
333
  <CardActions
382
334
  isLocked={isLocked}
383
335
  unlockLoading={unlockLoading}
384
- downloadLoading={downloadLoading}
385
- paymentStatus={paymentStatus}
386
336
  source={source}
387
337
  onUnlock={onUnlock ? handleUnlock : undefined}
388
- onDownload={onDownload ? handleDownload : undefined}
338
+ onDownload={onDownload}
389
339
  />
390
340
  </div>
391
341
  </div>
@@ -1,218 +0,0 @@
1
- import { jsxs as o, jsx as e, Fragment as g } from "react/jsx-runtime";
2
- import { CheckCircleIcon as U, LockOpenIcon as I, DownloadSimpleIcon as M, LockSimpleIcon as O } from "@phosphor-icons/react";
3
- import { useState as b, useEffect as S } from "react";
4
- import { g as R, r as k, M as A } from "./MediaPlayer-Bf-xPB8Z.js";
5
- const w = (s) => s === "paid" ? I : O, j = (s) => {
6
- const { icon: t, loading: a } = s;
7
- return /* @__PURE__ */ e("div", { className: "absolute inset-0 bg-black/30", children: /* @__PURE__ */ e("div", { className: "absolute left-3 top-3 flex size-8 items-center justify-center rounded-full bg-black/60", children: a ? /* @__PURE__ */ o("span", { className: "flex items-center gap-[2px]", children: [
8
- /* @__PURE__ */ e("span", { className: "size-1 rounded-full bg-white animate-bounce [animation-delay:-0.3s]" }),
9
- /* @__PURE__ */ e("span", { className: "size-1 rounded-full bg-white animate-bounce [animation-delay:-0.15s]" }),
10
- /* @__PURE__ */ e("span", { className: "size-1 rounded-full bg-white animate-bounce" })
11
- ] }) : /* @__PURE__ */ e(t, { className: "size-4 text-white", weight: "fill" }) }) });
12
- }, D = (s) => {
13
- const { thumbnail: t, mimeType: a, LockIcon: i, loading: n } = s;
14
- return /* @__PURE__ */ o("div", { className: "relative aspect-video overflow-hidden bg-black/5", children: [
15
- t ? /* @__PURE__ */ e(
16
- "img",
17
- {
18
- src: t,
19
- alt: "",
20
- className: "absolute inset-0 h-full w-full object-cover"
21
- }
22
- ) : /* @__PURE__ */ e("div", { className: "absolute inset-0 flex items-center justify-center", children: k(a, {
23
- className: "size-12 text-black/20",
24
- weight: "regular"
25
- }) }),
26
- /* @__PURE__ */ e(j, { icon: i, loading: n })
27
- ] });
28
- }, E = (s) => {
29
- const { source: t, thumbnail: a, mimeType: i, title: n, paymentStatus: l, isLocked: c, loading: d } = s, [m, r] = b(!1);
30
- return S(() => {
31
- r(!1);
32
- }, [t]), c ? /* @__PURE__ */ e(
33
- D,
34
- {
35
- thumbnail: a,
36
- mimeType: i,
37
- LockIcon: w(l),
38
- loading: d
39
- }
40
- ) : /* @__PURE__ */ e("div", { className: "relative overflow-hidden bg-black/5", children: /* @__PURE__ */ e(
41
- "img",
42
- {
43
- src: t,
44
- alt: n,
45
- className: `block w-full transition-opacity duration-300 ${m ? "opacity-100" : "opacity-0"}`,
46
- onLoad: () => r(!0)
47
- }
48
- ) });
49
- }, F = (s) => {
50
- const { thumbnail: t, mimeType: a, paymentStatus: i, isLocked: n, loading: l } = s;
51
- return /* @__PURE__ */ o("div", { className: "relative aspect-video overflow-hidden bg-black/5", children: [
52
- t ? /* @__PURE__ */ e(
53
- "img",
54
- {
55
- src: t,
56
- alt: "",
57
- className: "absolute inset-0 h-full w-full object-cover"
58
- }
59
- ) : /* @__PURE__ */ e("div", { className: "absolute inset-0 flex items-center justify-center", children: k(a, {
60
- className: "size-12 text-black/20",
61
- weight: "regular"
62
- }) }),
63
- n && /* @__PURE__ */ e(j, { icon: w(i), loading: l })
64
- ] });
65
- }, V = (s) => {
66
- const { source: t, thumbnail: a, mimeType: i, paymentStatus: n, isLocked: l, loading: c } = s;
67
- return l ? /* @__PURE__ */ e(
68
- D,
69
- {
70
- thumbnail: a,
71
- mimeType: i,
72
- LockIcon: w(n),
73
- loading: c
74
- }
75
- ) : /* @__PURE__ */ e(A, { source: t, mimeType: i, poster: a });
76
- }, z = () => /* @__PURE__ */ o("span", { className: "flex items-center gap-1", children: [
77
- /* @__PURE__ */ e("span", { className: "size-1 rounded-full bg-white animate-bounce [animation-delay:-0.3s]" }),
78
- /* @__PURE__ */ e("span", { className: "size-1 rounded-full bg-white animate-bounce [animation-delay:-0.15s]" }),
79
- /* @__PURE__ */ e("span", { className: "size-1 rounded-full bg-white animate-bounce" })
80
- ] }), $ = (s) => {
81
- const { isLocked: t, unlockLoading: a, downloadLoading: i, paymentStatus: n, source: l, onUnlock: c, onDownload: d } = s, m = w(n);
82
- return t && c ? /* @__PURE__ */ e(
83
- "button",
84
- {
85
- type: "button",
86
- onClick: c,
87
- disabled: a,
88
- className: "mt-3 inline-flex h-10 w-full items-center justify-center gap-2 rounded-full bg-[#121110] px-4 text-sm font-medium leading-none text-white disabled:opacity-70",
89
- children: a ? /* @__PURE__ */ e(z, {}) : /* @__PURE__ */ o(g, { children: [
90
- n === "paid" ? /* @__PURE__ */ e(I, { className: "size-4", weight: "fill" }) : /* @__PURE__ */ e(m, { className: "size-4", weight: "fill" }),
91
- n === "paid" ? "Open" : "Unlock"
92
- ] })
93
- }
94
- ) : !t && d && l ? /* @__PURE__ */ e(
95
- "button",
96
- {
97
- type: "button",
98
- onClick: d,
99
- disabled: i,
100
- className: "mt-3 inline-flex h-10 w-full items-center justify-center gap-2 rounded-full bg-[#121110] px-4 text-sm font-medium leading-none text-white disabled:opacity-70",
101
- children: i ? /* @__PURE__ */ e(z, {}) : /* @__PURE__ */ o(g, { children: [
102
- /* @__PURE__ */ e(M, { className: "size-4", weight: "bold" }),
103
- "Download"
104
- ] })
105
- }
106
- ) : null;
107
- }, J = (s) => {
108
- const {
109
- title: t,
110
- amountText: a,
111
- thumbnail: i,
112
- source: n,
113
- mimeType: l = "application/octet-stream",
114
- detail: c,
115
- onUnlock: d,
116
- onDownload: m,
117
- paymentStatus: r
118
- } = s, [u, y] = b(n), [f, N] = b(!1), [T, v] = b(!1);
119
- S(() => {
120
- n !== void 0 && y(n);
121
- }, [n]);
122
- const p = u === void 0, L = R(l), P = async () => {
123
- if (d) {
124
- N(!0);
125
- try {
126
- const x = await d();
127
- y(x.source);
128
- } catch {
129
- } finally {
130
- N(!1);
131
- }
132
- }
133
- }, C = async () => {
134
- if (m) {
135
- v(!0);
136
- try {
137
- await m();
138
- } catch {
139
- } finally {
140
- v(!1);
141
- }
142
- }
143
- };
144
- let h;
145
- return L === "image" ? h = /* @__PURE__ */ e(
146
- E,
147
- {
148
- source: u,
149
- thumbnail: i,
150
- mimeType: l,
151
- title: t,
152
- paymentStatus: r,
153
- isLocked: p,
154
- loading: f
155
- }
156
- ) : L === "document" ? h = /* @__PURE__ */ e(
157
- F,
158
- {
159
- thumbnail: i,
160
- mimeType: l,
161
- paymentStatus: r,
162
- isLocked: p,
163
- loading: f
164
- }
165
- ) : h = /* @__PURE__ */ e(
166
- V,
167
- {
168
- source: u,
169
- thumbnail: i,
170
- mimeType: l,
171
- paymentStatus: r,
172
- isLocked: p,
173
- loading: f
174
- }
175
- ), /* @__PURE__ */ o("div", { className: "w-[280px] select-none overflow-hidden rounded-3xl bg-white shadow-card", children: [
176
- h,
177
- /* @__PURE__ */ o("div", { className: "px-4 pb-3 pt-3", children: [
178
- /* @__PURE__ */ e("p", { className: "mb-1.5 truncate text-base font-medium text-black", children: t }),
179
- /* @__PURE__ */ o("div", { className: "flex items-center gap-1", children: [
180
- k(l, {
181
- className: "size-5 shrink-0 text-black/55",
182
- weight: "regular"
183
- }),
184
- c && /* @__PURE__ */ e("span", { className: "text-xs font-medium text-black/55", children: c }),
185
- r === "paid" ? /* @__PURE__ */ o(g, { children: [
186
- /* @__PURE__ */ e("span", { className: "text-xs font-medium text-black/55", children: "•" }),
187
- /* @__PURE__ */ e("span", { className: "text-xs font-medium text-[#008236]", children: "Purchased" }),
188
- /* @__PURE__ */ e(
189
- U,
190
- {
191
- className: "size-4 text-[#008236]",
192
- weight: "bold"
193
- }
194
- )
195
- ] }) : a && /* @__PURE__ */ o(g, { children: [
196
- /* @__PURE__ */ e("span", { className: "text-xs font-medium text-black/55", children: "•" }),
197
- /* @__PURE__ */ e("span", { className: "text-xs font-medium text-black/55", children: a })
198
- ] })
199
- ] }),
200
- /* @__PURE__ */ e(
201
- $,
202
- {
203
- isLocked: p,
204
- unlockLoading: f,
205
- downloadLoading: T,
206
- paymentStatus: r,
207
- source: u,
208
- onUnlock: d ? P : void 0,
209
- onDownload: m ? C : void 0
210
- }
211
- )
212
- ] })
213
- ] });
214
- };
215
- export {
216
- J as default
217
- };
218
- //# sourceMappingURL=Visitor-C4WqnN8H.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Visitor-C4WqnN8H.js","sources":["../src/components/LockedAttachment/components/Visitor.tsx"],"sourcesContent":["import {\n CheckCircleIcon,\n DownloadSimpleIcon,\n LockOpenIcon,\n LockSimpleIcon,\n} from '@phosphor-icons/react'\nimport React, { useEffect, useState } from 'react'\n\nimport { isDevBuild } from '../../../utils/isDevBuild'\nimport type {\n LockedAttachmentBaseProps,\n LockedAttachmentSource,\n PaymentStatus,\n} from '../types'\nimport { renderTypeIcon } from '../utils/icons'\nimport { getSourceType } from '../utils/mimeType'\n\nimport MediaPlayer from './MediaPlayer'\n\nexport interface VisitorCardProps extends LockedAttachmentBaseProps {\n /**\n * Called when the visitor clicks Unlock. Return the resolved source URL.\n * The component manages loading state and sets source internally on resolution.\n * Omit to hide the Unlock button.\n */\n onUnlock?: () => Promise<LockedAttachmentSource>\n /**\n * Called when the visitor clicks Download on an unlocked card.\n * May return a Promise — if so, the component shows a loader until it resolves.\n */\n onDownload?: () => void | Promise<void>\n}\n\nconst getLockIcon = (paymentStatus?: PaymentStatus): React.ElementType =>\n paymentStatus === 'paid' ? LockOpenIcon : LockSimpleIcon\n\n\ninterface LockOverlayProps {\n icon: React.ElementType\n loading?: boolean\n}\n\nconst LockOverlay: React.FC<LockOverlayProps> = (props) => {\n const { icon: Icon, loading } = props\n return (\n <div className=\"absolute inset-0 bg-black/30\">\n <div className=\"absolute left-3 top-3 flex size-8 items-center justify-center rounded-full bg-black/60\">\n {loading ? (\n <span className=\"flex items-center gap-[2px]\">\n <span className=\"size-1 rounded-full bg-white animate-bounce [animation-delay:-0.3s]\" />\n <span className=\"size-1 rounded-full bg-white animate-bounce [animation-delay:-0.15s]\" />\n <span className=\"size-1 rounded-full bg-white animate-bounce\" />\n </span>\n ) : (\n <Icon className=\"size-4 text-white\" weight=\"fill\" />\n )}\n </div>\n </div>\n )\n}\n\ninterface LockedPreviewProps {\n thumbnail?: string\n mimeType: string\n LockIcon: React.ElementType\n loading?: boolean\n}\n\nconst LockedPreview: React.FC<LockedPreviewProps> = (props) => {\n const { thumbnail, mimeType, LockIcon, loading } = props\n return (\n <div className=\"relative aspect-video overflow-hidden bg-black/5\">\n {thumbnail ? (\n <img\n src={thumbnail}\n alt=\"\"\n className=\"absolute inset-0 h-full w-full object-cover\"\n />\n ) : (\n <div className=\"absolute inset-0 flex items-center justify-center\">\n {renderTypeIcon(mimeType, {\n className: 'size-12 text-black/20',\n weight: 'regular',\n })}\n </div>\n )}\n <LockOverlay icon={LockIcon} loading={loading} />\n </div>\n )\n}\n\n\ninterface ImagePreviewProps {\n source?: string\n thumbnail?: string\n mimeType: string\n title?: string\n paymentStatus?: PaymentStatus\n isLocked: boolean\n loading?: boolean\n}\n\nconst ImagePreview: React.FC<ImagePreviewProps> = (props) => {\n const { source, thumbnail, mimeType, title, paymentStatus, isLocked, loading } = props\n const [sourceReady, setSourceReady] = useState(false)\n\n useEffect(() => {\n setSourceReady(false)\n }, [source])\n\n if (isLocked) {\n return (\n <LockedPreview\n thumbnail={thumbnail}\n mimeType={mimeType}\n LockIcon={getLockIcon(paymentStatus)}\n loading={loading}\n />\n )\n }\n\n return (\n <div className=\"relative overflow-hidden bg-black/5\">\n <img\n src={source}\n alt={title}\n className={`block w-full transition-opacity duration-300 ${sourceReady ? 'opacity-100' : 'opacity-0'}`}\n onLoad={() => setSourceReady(true)}\n />\n </div>\n )\n}\n\ninterface DocumentPreviewProps {\n thumbnail?: string\n mimeType: string\n paymentStatus?: PaymentStatus\n isLocked: boolean\n loading?: boolean\n}\n\nconst DocumentPreview: React.FC<DocumentPreviewProps> = (props) => {\n const { thumbnail, mimeType, paymentStatus, isLocked, loading } = props\n return (\n <div className=\"relative aspect-video overflow-hidden bg-black/5\">\n {thumbnail ? (\n <img\n src={thumbnail}\n alt=\"\"\n className=\"absolute inset-0 h-full w-full object-cover\"\n />\n ) : (\n <div className=\"absolute inset-0 flex items-center justify-center\">\n {renderTypeIcon(mimeType, {\n className: 'size-12 text-black/20',\n weight: 'regular',\n })}\n </div>\n )}\n {isLocked && <LockOverlay icon={getLockIcon(paymentStatus)} loading={loading} />}\n </div>\n )\n}\n\ninterface MediaPreviewProps {\n source?: string\n thumbnail?: string\n mimeType: string\n paymentStatus?: PaymentStatus\n isLocked: boolean\n loading?: boolean\n}\n\nconst MediaPreview: React.FC<MediaPreviewProps> = (props) => {\n const { source, thumbnail, mimeType, paymentStatus, isLocked, loading } = props\n if (isLocked) {\n return (\n <LockedPreview\n thumbnail={thumbnail}\n mimeType={mimeType}\n LockIcon={getLockIcon(paymentStatus)}\n loading={loading}\n />\n )\n }\n return <MediaPlayer source={source!} mimeType={mimeType} poster={thumbnail} />\n}\n\n\nconst LoadingDots = () => (\n <span className=\"flex items-center gap-1\">\n <span className=\"size-1 rounded-full bg-white animate-bounce [animation-delay:-0.3s]\" />\n <span className=\"size-1 rounded-full bg-white animate-bounce [animation-delay:-0.15s]\" />\n <span className=\"size-1 rounded-full bg-white animate-bounce\" />\n </span>\n)\n\ninterface CardActionsProps {\n isLocked: boolean\n unlockLoading: boolean\n downloadLoading: boolean\n paymentStatus?: PaymentStatus\n source?: string\n onUnlock?: () => void\n onDownload?: () => void\n}\n\nconst CardActions: React.FC<CardActionsProps> = (props) => {\n const { isLocked, unlockLoading, downloadLoading, paymentStatus, source, onUnlock, onDownload } = props\n const LockIcon = getLockIcon(paymentStatus)\n\n if (isLocked && onUnlock) {\n return (\n <button\n type=\"button\"\n onClick={onUnlock}\n disabled={unlockLoading}\n className=\"mt-3 inline-flex h-10 w-full items-center justify-center gap-2 rounded-full bg-[#121110] px-4 text-sm font-medium leading-none text-white disabled:opacity-70\"\n >\n {unlockLoading ? (\n <LoadingDots />\n ) : (\n <>\n {paymentStatus === 'paid' ? (\n <LockOpenIcon className=\"size-4\" weight=\"fill\" />\n ) : (\n <LockIcon className=\"size-4\" weight=\"fill\" />\n )}\n {paymentStatus === 'paid' ? 'Open' : 'Unlock'}\n </>\n )}\n </button>\n )\n }\n\n if (!isLocked && onDownload && source) {\n return (\n <button\n type=\"button\"\n onClick={onDownload}\n disabled={downloadLoading}\n className=\"mt-3 inline-flex h-10 w-full items-center justify-center gap-2 rounded-full bg-[#121110] px-4 text-sm font-medium leading-none text-white disabled:opacity-70\"\n >\n {downloadLoading ? (\n <LoadingDots />\n ) : (\n <>\n <DownloadSimpleIcon className=\"size-4\" weight=\"bold\" />\n Download\n </>\n )}\n </button>\n )\n }\n\n return null\n}\n\n\nconst VisitorCard: React.FC<VisitorCardProps> = (props) => {\n const {\n title,\n amountText,\n thumbnail,\n source: sourceProp,\n mimeType = 'application/octet-stream',\n detail,\n onUnlock,\n onDownload,\n paymentStatus,\n } = props\n const [source, setSource] = useState(sourceProp)\n const [unlockLoading, setUnlockLoading] = useState(false)\n const [downloadLoading, setDownloadLoading] = useState(false)\n\n useEffect(() => {\n if (sourceProp !== undefined) setSource(sourceProp)\n }, [sourceProp])\n\n const isLocked = source === undefined\n const sourceType = getSourceType(mimeType)\n\n const handleUnlock = async () => {\n if (!onUnlock) return\n setUnlockLoading(true)\n try {\n const result = await onUnlock()\n setSource(result.source)\n } catch (err) {\n if (isDevBuild()) console.debug('[LockedAttachment] onUnlock failed', err)\n } finally {\n setUnlockLoading(false)\n }\n }\n\n const handleDownload = async () => {\n if (!onDownload) return\n setDownloadLoading(true)\n try {\n await onDownload()\n } catch (err) {\n if (isDevBuild()) console.debug('[LockedAttachment] onDownload failed', err)\n } finally {\n setDownloadLoading(false)\n }\n }\n\n let mediaPreview: React.ReactNode\n if (sourceType === 'image') {\n mediaPreview = (\n <ImagePreview\n source={source}\n thumbnail={thumbnail}\n mimeType={mimeType}\n title={title}\n paymentStatus={paymentStatus}\n isLocked={isLocked}\n loading={unlockLoading}\n />\n )\n } else if (sourceType === 'document') {\n mediaPreview = (\n <DocumentPreview\n thumbnail={thumbnail}\n mimeType={mimeType}\n paymentStatus={paymentStatus}\n isLocked={isLocked}\n loading={unlockLoading}\n />\n )\n } else {\n mediaPreview = (\n <MediaPreview\n source={source}\n thumbnail={thumbnail}\n mimeType={mimeType}\n paymentStatus={paymentStatus}\n isLocked={isLocked}\n loading={unlockLoading}\n />\n )\n }\n\n return (\n <div className=\"w-[280px] select-none overflow-hidden rounded-3xl bg-white shadow-card\">\n {mediaPreview}\n <div className=\"px-4 pb-3 pt-3\">\n <p className=\"mb-1.5 truncate text-base font-medium text-black\">\n {title}\n </p>\n <div className=\"flex items-center gap-1\">\n {renderTypeIcon(mimeType, {\n className: 'size-5 shrink-0 text-black/55',\n weight: 'regular',\n })}\n {detail && (\n <span className=\"text-xs font-medium text-black/55\">{detail}</span>\n )}\n {paymentStatus === 'paid' ? (\n <>\n <span className=\"text-xs font-medium text-black/55\">•</span>\n <span className=\"text-xs font-medium text-[#008236]\">\n Purchased\n </span>\n <CheckCircleIcon\n className=\"size-4 text-[#008236]\"\n weight=\"bold\"\n />\n </>\n ) : (\n amountText && (\n <>\n <span className=\"text-xs font-medium text-black/55\">•</span>\n <span className=\"text-xs font-medium text-black/55\">\n {amountText}\n </span>\n </>\n )\n )}\n </div>\n <CardActions\n isLocked={isLocked}\n unlockLoading={unlockLoading}\n downloadLoading={downloadLoading}\n paymentStatus={paymentStatus}\n source={source}\n onUnlock={onUnlock ? handleUnlock : undefined}\n onDownload={onDownload ? handleDownload : undefined}\n />\n </div>\n </div>\n )\n}\n\nexport default VisitorCard\n"],"names":["getLockIcon","paymentStatus","LockOpenIcon","LockSimpleIcon","LockOverlay","props","Icon","loading","jsx","jsxs","LockedPreview","thumbnail","mimeType","LockIcon","ImagePreview","source","title","isLocked","sourceReady","setSourceReady","useState","useEffect","DocumentPreview","MediaPreview","MediaPlayer","LoadingDots","CardActions","unlockLoading","downloadLoading","onUnlock","onDownload","Fragment","DownloadSimpleIcon","VisitorCard","amountText","sourceProp","detail","setSource","setUnlockLoading","setDownloadLoading","sourceType","getSourceType","handleUnlock","result","handleDownload","mediaPreview","renderTypeIcon","CheckCircleIcon"],"mappings":"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"}