@linktr.ee/messaging-react 1.31.0-rc-1776677746 → 1.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{Creator-DGe3CQ_j.js → Card-C5t3dZ5q.js} +177 -150
- package/dist/Card-C5t3dZ5q.js.map +1 -0
- package/dist/Card-Cn2va-Qr.js +205 -0
- package/dist/Card-Cn2va-Qr.js.map +1 -0
- package/dist/index.d.ts +35 -30
- package/dist/index.js +951 -956
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/ChannelView.tsx +24 -36
- package/src/components/CustomMessage/CustomMessage.stories.tsx +1 -14
- package/src/components/CustomMessage/context.tsx +20 -0
- package/src/components/CustomMessage/index.tsx +39 -28
- package/src/components/LockedAttachment/LockedAttachment.stories.tsx +8 -13
- package/src/components/LockedAttachment/components/Creator/Card.tsx +159 -0
- package/src/components/LockedAttachment/components/Creator/CardAudioPreview.tsx +161 -0
- package/src/components/LockedAttachment/components/Creator/CardCollapsedThumbnail.tsx +58 -0
- package/src/components/LockedAttachment/components/Creator/CardImagePreview.tsx +56 -0
- package/src/components/LockedAttachment/components/Creator/CardVideoPreview.tsx +91 -0
- package/src/components/LockedAttachment/components/Creator/index.tsx +2 -0
- package/src/components/LockedAttachment/components/Visitor/Card.tsx +186 -0
- package/src/components/LockedAttachment/components/Visitor/CardActions.tsx +71 -0
- package/src/components/LockedAttachment/components/Visitor/CardImagePreview.tsx +39 -0
- package/src/components/LockedAttachment/components/Visitor/CardMediaPreview.tsx +36 -0
- package/src/components/LockedAttachment/components/Visitor/CardThumbnailPreview.tsx +45 -0
- package/src/components/LockedAttachment/components/Visitor/index.ts +2 -0
- package/src/components/LockedAttachment/index.tsx +16 -23
- package/src/components/LockedAttachment/types.ts +14 -1
- package/src/components/MessagingShell/index.tsx +0 -6
- package/src/index.ts +4 -1
- package/src/types.ts +0 -21
- package/dist/Creator-DGe3CQ_j.js.map +0 -1
- package/dist/Visitor-DyJTWB2_.js +0 -204
- package/dist/Visitor-DyJTWB2_.js.map +0 -1
- package/src/components/LockedAttachment/components/Creator.tsx +0 -470
- package/src/components/LockedAttachment/components/Visitor.tsx +0 -356
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import { jsx as e, jsxs as c, Fragment as y } from "react/jsx-runtime";
|
|
2
|
+
import { LockSimpleIcon as I, DownloadSimpleIcon as D, CheckCircleIcon as M, LockOpenIcon as R } from "@phosphor-icons/react";
|
|
3
|
+
import O, { useState as z, useRef as g, useCallback as L, useEffect as T } from "react";
|
|
4
|
+
import { r as _, M as A, g as E } from "./MediaPlayer-BCsdmsON.js";
|
|
5
|
+
const V = (n) => {
|
|
6
|
+
const {
|
|
7
|
+
isLocked: r,
|
|
8
|
+
isUnlocking: s = !1,
|
|
9
|
+
sourceUrl: t,
|
|
10
|
+
redeemUrl: i,
|
|
11
|
+
onUnlockClicked: a,
|
|
12
|
+
onDownloadClicked: o
|
|
13
|
+
} = n;
|
|
14
|
+
return r && a != null ? /* @__PURE__ */ e(
|
|
15
|
+
"button",
|
|
16
|
+
{
|
|
17
|
+
type: "button",
|
|
18
|
+
onClick: a,
|
|
19
|
+
disabled: s,
|
|
20
|
+
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",
|
|
21
|
+
children: s ? /* @__PURE__ */ e($, {}) : /* @__PURE__ */ c(O.Fragment, { children: [
|
|
22
|
+
/* @__PURE__ */ e(I, { className: "size-4", weight: "fill" }),
|
|
23
|
+
"Unlock"
|
|
24
|
+
] })
|
|
25
|
+
}
|
|
26
|
+
) : !r && o != null && t != null ? /* @__PURE__ */ c(
|
|
27
|
+
"a",
|
|
28
|
+
{
|
|
29
|
+
href: i ?? t,
|
|
30
|
+
target: "_blank",
|
|
31
|
+
rel: "noopener noreferrer",
|
|
32
|
+
onClick: o,
|
|
33
|
+
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]",
|
|
34
|
+
children: [
|
|
35
|
+
/* @__PURE__ */ e(D, { className: "size-4", weight: "bold" }),
|
|
36
|
+
"Download"
|
|
37
|
+
]
|
|
38
|
+
}
|
|
39
|
+
) : null;
|
|
40
|
+
}, $ = () => /* @__PURE__ */ c("span", { className: "flex items-center gap-1", children: [
|
|
41
|
+
/* @__PURE__ */ e("span", { className: "size-1 rounded-full bg-white animate-bounce [animation-delay:-0.3s]" }),
|
|
42
|
+
/* @__PURE__ */ e("span", { className: "size-1 rounded-full bg-white animate-bounce [animation-delay:-0.15s]" }),
|
|
43
|
+
/* @__PURE__ */ e("span", { className: "size-1 rounded-full bg-white animate-bounce" })
|
|
44
|
+
] }), x = (n) => {
|
|
45
|
+
const { thumbnailUrl: r, mimeType: s, LockIcon: t } = n;
|
|
46
|
+
return /* @__PURE__ */ c("div", { className: "relative aspect-video overflow-hidden bg-black/5", children: [
|
|
47
|
+
r != null ? /* @__PURE__ */ e(
|
|
48
|
+
"img",
|
|
49
|
+
{
|
|
50
|
+
src: r,
|
|
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: _(s, {
|
|
55
|
+
className: "size-12 text-black/20",
|
|
56
|
+
weight: "regular"
|
|
57
|
+
}) }),
|
|
58
|
+
t != null ? /* @__PURE__ */ e(q, { icon: t }) : null
|
|
59
|
+
] });
|
|
60
|
+
}, q = ({ icon: n }) => /* @__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(n, { className: "size-4 text-white", weight: "fill" }) }) }), B = (n) => {
|
|
61
|
+
const { sourceUrl: r, thumbnailUrl: s, mimeType: t, title: i, LockIcon: a } = n, [o, h] = z(!1);
|
|
62
|
+
return a != null ? /* @__PURE__ */ e(
|
|
63
|
+
x,
|
|
64
|
+
{
|
|
65
|
+
thumbnailUrl: s,
|
|
66
|
+
mimeType: t,
|
|
67
|
+
LockIcon: a
|
|
68
|
+
}
|
|
69
|
+
) : /* @__PURE__ */ e("div", { className: "relative overflow-hidden bg-black/5", children: /* @__PURE__ */ e(
|
|
70
|
+
"img",
|
|
71
|
+
{
|
|
72
|
+
src: r,
|
|
73
|
+
alt: i,
|
|
74
|
+
className: `block w-full transition-opacity duration-300 ${o ? "opacity-100" : "opacity-0"}`,
|
|
75
|
+
onLoad: () => h(!0)
|
|
76
|
+
}
|
|
77
|
+
) });
|
|
78
|
+
}, F = (n) => {
|
|
79
|
+
const { sourceUrl: r, thumbnailUrl: s, mimeType: t, LockIcon: i } = n;
|
|
80
|
+
return i != null ? /* @__PURE__ */ e(
|
|
81
|
+
x,
|
|
82
|
+
{
|
|
83
|
+
thumbnailUrl: s,
|
|
84
|
+
mimeType: t,
|
|
85
|
+
LockIcon: i
|
|
86
|
+
}
|
|
87
|
+
) : /* @__PURE__ */ e(
|
|
88
|
+
A,
|
|
89
|
+
{
|
|
90
|
+
source: r ?? "",
|
|
91
|
+
mimeType: t,
|
|
92
|
+
poster: s
|
|
93
|
+
}
|
|
94
|
+
);
|
|
95
|
+
};
|
|
96
|
+
function G(n) {
|
|
97
|
+
return n === "paid" ? R : I;
|
|
98
|
+
}
|
|
99
|
+
const S = ({
|
|
100
|
+
title: n,
|
|
101
|
+
amountText: r,
|
|
102
|
+
thumbnailUrl: s,
|
|
103
|
+
mimeType: t = "application/octet-stream",
|
|
104
|
+
detail: i,
|
|
105
|
+
onUnlockClick: a,
|
|
106
|
+
onFetchSource: o,
|
|
107
|
+
onDownloadClick: h,
|
|
108
|
+
paymentStatus: d,
|
|
109
|
+
isUnlocking: j = !1
|
|
110
|
+
}) => {
|
|
111
|
+
const [l, C] = z(), w = g(!1), b = g(!1), u = g(o);
|
|
112
|
+
u.current = o;
|
|
113
|
+
const k = l === void 0, N = E(t), p = k ? G(d) : void 0, m = L(async () => {
|
|
114
|
+
var v;
|
|
115
|
+
if (!b.current) {
|
|
116
|
+
b.current = !0;
|
|
117
|
+
try {
|
|
118
|
+
const U = await ((v = u.current) == null ? void 0 : v.call(u));
|
|
119
|
+
U && C(U);
|
|
120
|
+
} finally {
|
|
121
|
+
b.current = !1;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}, []);
|
|
125
|
+
T(() => {
|
|
126
|
+
if (!w.current) {
|
|
127
|
+
w.current = !0;
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
d === "paid" && m();
|
|
131
|
+
}, [d, m]);
|
|
132
|
+
const P = L(() => {
|
|
133
|
+
d === "paid" ? m() : a == null || a();
|
|
134
|
+
}, [d, a, m]);
|
|
135
|
+
let f;
|
|
136
|
+
return N === "image" ? f = /* @__PURE__ */ e(
|
|
137
|
+
B,
|
|
138
|
+
{
|
|
139
|
+
sourceUrl: l == null ? void 0 : l.sourceUrl,
|
|
140
|
+
thumbnailUrl: s,
|
|
141
|
+
mimeType: t,
|
|
142
|
+
title: n,
|
|
143
|
+
LockIcon: p
|
|
144
|
+
},
|
|
145
|
+
l == null ? void 0 : l.sourceUrl
|
|
146
|
+
) : N === "document" ? f = /* @__PURE__ */ e(
|
|
147
|
+
x,
|
|
148
|
+
{
|
|
149
|
+
thumbnailUrl: s,
|
|
150
|
+
mimeType: t,
|
|
151
|
+
LockIcon: p
|
|
152
|
+
},
|
|
153
|
+
l == null ? void 0 : l.sourceUrl
|
|
154
|
+
) : f = /* @__PURE__ */ e(
|
|
155
|
+
F,
|
|
156
|
+
{
|
|
157
|
+
sourceUrl: l == null ? void 0 : l.sourceUrl,
|
|
158
|
+
thumbnailUrl: s,
|
|
159
|
+
mimeType: t,
|
|
160
|
+
LockIcon: p
|
|
161
|
+
},
|
|
162
|
+
l == null ? void 0 : l.sourceUrl
|
|
163
|
+
), /* @__PURE__ */ c("div", { className: "w-[280px] select-none overflow-hidden rounded-[24px] bg-white shadow-[0_0_0_1px_rgba(0,0,0,0.04),0_4px_8px_rgba(0,0,0,0.06)]", children: [
|
|
164
|
+
f,
|
|
165
|
+
/* @__PURE__ */ c("div", { className: "px-4 pb-3 pt-3", children: [
|
|
166
|
+
/* @__PURE__ */ e("p", { className: "mb-1.5 truncate text-base font-medium text-black", children: n }),
|
|
167
|
+
/* @__PURE__ */ c("div", { className: "flex items-center gap-1", children: [
|
|
168
|
+
_(t, {
|
|
169
|
+
className: "size-5 shrink-0 text-black/55",
|
|
170
|
+
weight: "regular"
|
|
171
|
+
}),
|
|
172
|
+
i != null ? /* @__PURE__ */ e("span", { className: "text-xs font-medium text-black/55", children: i }) : null,
|
|
173
|
+
d === "paid" ? /* @__PURE__ */ c(y, { children: [
|
|
174
|
+
/* @__PURE__ */ e("span", { className: "text-xs font-medium text-black/55", children: "•" }),
|
|
175
|
+
/* @__PURE__ */ e("span", { className: "text-xs font-medium text-[#008236]", children: "Purchased" }),
|
|
176
|
+
/* @__PURE__ */ e(
|
|
177
|
+
M,
|
|
178
|
+
{
|
|
179
|
+
className: "size-4 text-[#008236]",
|
|
180
|
+
weight: "bold"
|
|
181
|
+
}
|
|
182
|
+
)
|
|
183
|
+
] }) : r != null ? /* @__PURE__ */ c(y, { children: [
|
|
184
|
+
/* @__PURE__ */ e("span", { className: "text-xs font-medium text-black/55", children: "•" }),
|
|
185
|
+
/* @__PURE__ */ e("span", { className: "text-xs font-medium text-black/55", children: r })
|
|
186
|
+
] }) : null
|
|
187
|
+
] }),
|
|
188
|
+
/* @__PURE__ */ e(
|
|
189
|
+
V,
|
|
190
|
+
{
|
|
191
|
+
isLocked: k,
|
|
192
|
+
isUnlocking: j,
|
|
193
|
+
sourceUrl: l == null ? void 0 : l.sourceUrl,
|
|
194
|
+
redeemUrl: l == null ? void 0 : l.redeemUrl,
|
|
195
|
+
onUnlockClicked: P,
|
|
196
|
+
onDownloadClicked: h
|
|
197
|
+
}
|
|
198
|
+
)
|
|
199
|
+
] })
|
|
200
|
+
] });
|
|
201
|
+
};
|
|
202
|
+
export {
|
|
203
|
+
S as default
|
|
204
|
+
};
|
|
205
|
+
//# sourceMappingURL=Card-Cn2va-Qr.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Card-Cn2va-Qr.js","sources":["../src/components/LockedAttachment/components/Visitor/CardActions.tsx","../src/components/LockedAttachment/components/Visitor/CardThumbnailPreview.tsx","../src/components/LockedAttachment/components/Visitor/CardImagePreview.tsx","../src/components/LockedAttachment/components/Visitor/CardMediaPreview.tsx","../src/components/LockedAttachment/components/Visitor/Card.tsx"],"sourcesContent":["import { DownloadSimpleIcon, LockSimpleIcon } from '@phosphor-icons/react'\nimport React from 'react'\n\ninterface CardActionsProps {\n isLocked: boolean\n isUnlocking?: boolean\n sourceUrl?: string\n redeemUrl?: string\n onUnlockClicked?: () => void\n onDownloadClicked?: () => void\n}\n\nconst CardActions: React.FC<CardActionsProps> = (props) => {\n const {\n isLocked,\n isUnlocking = false,\n sourceUrl,\n redeemUrl,\n onUnlockClicked,\n onDownloadClicked,\n } = props\n\n if (isLocked && onUnlockClicked != null) {\n return (\n <button\n type=\"button\"\n onClick={onUnlockClicked}\n disabled={isUnlocking}\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 {isUnlocking ? (\n <LoadingDots />\n ) : (\n <React.Fragment>\n <LockSimpleIcon className=\"size-4\" weight=\"fill\" />\n Unlock\n </React.Fragment>\n )}\n </button>\n )\n }\n\n if (!isLocked && onDownloadClicked != null && sourceUrl != null) {\n return (\n <a\n href={redeemUrl ?? sourceUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n onClick={onDownloadClicked}\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\nconst LoadingDots: React.FC = () => {\n return (\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}\n\nexport default CardActions\n","import React from 'react'\n\nimport { renderTypeIcon } from '../../utils/icons'\n\ninterface ThumbnailPreviewProps {\n thumbnailUrl?: string\n mimeType: string\n LockIcon?: React.ElementType\n}\n\nconst ThumbnailPreview: React.FC<ThumbnailPreviewProps> = (props) => {\n const { thumbnailUrl, mimeType, LockIcon } = props\n\n return (\n <div className=\"relative aspect-video overflow-hidden bg-black/5\">\n {thumbnailUrl != null ? (\n <img\n src={thumbnailUrl}\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 {LockIcon != null ? <LockOverlay icon={LockIcon} /> : null}\n </div>\n )\n}\n\nconst LockOverlay: React.FC<{ icon: React.ElementType }> = ({ icon: Icon }) => {\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\nexport default ThumbnailPreview\n","import React, { useState } from 'react'\n\nimport ThumbnailPreview from './CardThumbnailPreview'\n\ninterface ImagePreviewProps {\n sourceUrl?: string\n thumbnailUrl?: string\n mimeType: string\n title?: string\n LockIcon?: React.ElementType\n}\n\nconst ImagePreview: React.FC<ImagePreviewProps> = (props) => {\n const { sourceUrl, thumbnailUrl, mimeType, title, LockIcon } = props\n const [sourceReady, setSourceReady] = useState(false)\n\n if (LockIcon != null) {\n return (\n <ThumbnailPreview\n thumbnailUrl={thumbnailUrl}\n mimeType={mimeType}\n LockIcon={LockIcon}\n />\n )\n }\n\n return (\n <div className=\"relative overflow-hidden bg-black/5\">\n <img\n src={sourceUrl}\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\nexport default ImagePreview\n","import React from 'react'\n\nimport MediaPlayer from '../MediaPlayer'\n\nimport ThumbnailPreview from './CardThumbnailPreview'\n\ninterface MediaPreviewProps {\n sourceUrl?: string\n thumbnailUrl?: string\n mimeType: string\n LockIcon?: React.ElementType\n}\n\nconst MediaPreview: React.FC<MediaPreviewProps> = (props) => {\n const { sourceUrl, thumbnailUrl, mimeType, LockIcon } = props\n\n if (LockIcon != null) {\n return (\n <ThumbnailPreview\n thumbnailUrl={thumbnailUrl}\n mimeType={mimeType}\n LockIcon={LockIcon}\n />\n )\n }\n\n return (\n <MediaPlayer\n source={sourceUrl ?? ''}\n mimeType={mimeType}\n poster={thumbnailUrl}\n />\n )\n}\n\nexport default MediaPreview\n","import {\n CheckCircleIcon,\n LockOpenIcon,\n LockSimpleIcon,\n} from '@phosphor-icons/react'\nimport React, { useCallback, useEffect, useRef, useState } from 'react'\n\nimport type {\n LockedAttachmentBaseProps,\n LockedAttachmentSource,\n PaymentStatus,\n} from '../../types'\nimport { renderTypeIcon } from '../../utils/icons'\nimport { getSourceType } from '../../utils/mimeType'\n\nimport CardActions from './CardActions'\nimport ImagePreview from './CardImagePreview'\nimport MediaPreview from './CardMediaPreview'\nimport ThumbnailPreview from './CardThumbnailPreview'\n\nexport interface VisitorCardProps extends LockedAttachmentBaseProps {\n /**\n * Called when the visitor clicks Unlock on an unpaid attachment.\n * Use this to open a checkout flow. Omit to hide the Unlock button.\n */\n onUnlockClick?: () => void\n /**\n * Called to fetch the attachment source — fired automatically when\n * paymentStatus transitions to 'paid', or immediately on click when\n * paymentStatus is already 'paid'. Return a LockedAttachmentSource to\n * unlock the card.\n */\n onFetchSource?: () => Promise<LockedAttachmentSource | void>\n /**\n * Called when the visitor clicks Download on an unlocked card.\n * Omit to hide the Download button.\n */\n onDownloadClick?: () => void\n /**\n * When true, shows loading dots on the Unlock button.\n * Driven by the LockedAttachmentContext (e.g. checkout in progress, payment processing).\n */\n isUnlocking?: boolean\n}\n\nfunction getLockIcon(paymentStatus?: PaymentStatus): React.ElementType {\n return paymentStatus === 'paid' ? LockOpenIcon : LockSimpleIcon\n}\n\nconst VisitorCard: React.FC<VisitorCardProps> = ({\n title,\n amountText,\n thumbnailUrl,\n mimeType = 'application/octet-stream',\n detail,\n onUnlockClick,\n onFetchSource,\n onDownloadClick,\n paymentStatus,\n isUnlocking = false,\n}) => {\n const [source, setSource] = useState<LockedAttachmentSource | undefined>()\n const hasMounted = useRef(false)\n const fetchingRef = useRef(false)\n // Stable ref so fetchSource doesn't change identity when onFetchSource prop changes\n const onFetchSourceRef = useRef(onFetchSource)\n onFetchSourceRef.current = onFetchSource\n\n const isLocked = source === undefined\n const sourceType = getSourceType(mimeType)\n const LockIcon = isLocked ? getLockIcon(paymentStatus) : undefined\n\n const fetchSource = useCallback(async (): Promise<void> => {\n if (fetchingRef.current) return\n fetchingRef.current = true\n try {\n const result = await onFetchSourceRef.current?.()\n if (result) setSource(result)\n } finally {\n fetchingRef.current = false\n }\n }, []) // stable — reads onFetchSource via ref\n\n // When paymentStatus transitions to 'paid' (e.g. after checkout completes),\n // automatically fetch the source. Skipped on mount.\n useEffect(() => {\n if (!hasMounted.current) {\n hasMounted.current = true\n return\n }\n\n if (paymentStatus === 'paid') {\n void fetchSource()\n }\n }, [paymentStatus, fetchSource])\n\n const handleUnlockClick = useCallback(() => {\n if (paymentStatus === 'paid') {\n void fetchSource()\n } else {\n onUnlockClick?.()\n }\n }, [paymentStatus, onUnlockClick, fetchSource])\n\n let mediaPreview: React.ReactNode\n if (sourceType === 'image') {\n mediaPreview = (\n <ImagePreview\n key={source?.sourceUrl}\n sourceUrl={source?.sourceUrl}\n thumbnailUrl={thumbnailUrl}\n mimeType={mimeType}\n title={title}\n LockIcon={LockIcon}\n />\n )\n } else if (sourceType === 'document') {\n mediaPreview = (\n <ThumbnailPreview\n key={source?.sourceUrl}\n thumbnailUrl={thumbnailUrl}\n mimeType={mimeType}\n LockIcon={LockIcon}\n />\n )\n } else {\n mediaPreview = (\n <MediaPreview\n key={source?.sourceUrl}\n sourceUrl={source?.sourceUrl}\n thumbnailUrl={thumbnailUrl}\n mimeType={mimeType}\n LockIcon={LockIcon}\n />\n )\n }\n\n return (\n <div className=\"w-[280px] select-none overflow-hidden rounded-[24px] bg-white shadow-[0_0_0_1px_rgba(0,0,0,0.04),0_4px_8px_rgba(0,0,0,0.06)]\">\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 != null ? (\n <span className=\"text-xs font-medium text-black/55\">{detail}</span>\n ) : null}\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 ) : amountText != null ? (\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 ) : null}\n </div>\n <CardActions\n isLocked={isLocked}\n isUnlocking={isUnlocking}\n sourceUrl={source?.sourceUrl}\n redeemUrl={source?.redeemUrl}\n onUnlockClicked={handleUnlockClick}\n onDownloadClicked={onDownloadClick}\n />\n </div>\n </div>\n )\n}\n\nexport default VisitorCard\n"],"names":["CardActions","props","isLocked","isUnlocking","sourceUrl","redeemUrl","onUnlockClicked","onDownloadClicked","jsx","LoadingDots","jsxs","React","LockSimpleIcon","DownloadSimpleIcon","ThumbnailPreview","thumbnailUrl","mimeType","LockIcon","LockOverlay","Icon","ImagePreview","title","sourceReady","setSourceReady","useState","MediaPreview","MediaPlayer","getLockIcon","paymentStatus","LockOpenIcon","VisitorCard","amountText","detail","onUnlockClick","onFetchSource","onDownloadClick","source","setSource","hasMounted","useRef","fetchingRef","onFetchSourceRef","sourceType","getSourceType","fetchSource","useCallback","result","_a","useEffect","handleUnlockClick","mediaPreview","renderTypeIcon","Fragment","CheckCircleIcon"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ import { EmptyStateIndicatorProps } from 'stream-chat-react';
|
|
|
7
7
|
import { JSX as JSX_2 } from 'react/jsx-runtime';
|
|
8
8
|
import { LocalMessage } from 'stream-chat';
|
|
9
9
|
import { MessagingUser } from '@linktr.ee/messaging-core';
|
|
10
|
+
import { Provider } from 'react';
|
|
10
11
|
import { SendMessageAPIResponse } from 'stream-chat';
|
|
11
12
|
import { StreamChat } from 'stream-chat';
|
|
12
13
|
import { StreamChatService } from '@linktr.ee/messaging-core';
|
|
@@ -111,7 +112,7 @@ export declare const ChannelView: default_2.NamedExoticComponent<ChannelViewProp
|
|
|
111
112
|
* Props that MessagingShell passes through to ChannelView.
|
|
112
113
|
* ChannelViewProps is the source of truth for these props.
|
|
113
114
|
*/
|
|
114
|
-
declare type ChannelViewPassthroughProps = Pick<ChannelViewProps, 'renderMessageInputActions' | 'renderConversationFooter' | 'CustomChannelEmptyState' | 'onDeleteConversationClick' | 'onBlockParticipantClick' | 'onReportParticipantClick' | 'dmAgentEnabled' | 'messageMetadata' | 'onMessageSent' | 'showStarButton' | 'chatbotVotingEnabled' | 'renderChannelBanner' | 'customProfileContent' | 'customChannelActions' | 'renderMessage'
|
|
115
|
+
declare type ChannelViewPassthroughProps = Pick<ChannelViewProps, 'renderMessageInputActions' | 'renderConversationFooter' | 'CustomChannelEmptyState' | 'onDeleteConversationClick' | 'onBlockParticipantClick' | 'onReportParticipantClick' | 'dmAgentEnabled' | 'messageMetadata' | 'onMessageSent' | 'showStarButton' | 'chatbotVotingEnabled' | 'renderChannelBanner' | 'customProfileContent' | 'customChannelActions' | 'renderMessage'>;
|
|
115
116
|
|
|
116
117
|
/**
|
|
117
118
|
* ChannelView component props
|
|
@@ -216,24 +217,9 @@ export declare interface ChannelViewProps {
|
|
|
216
217
|
* )}
|
|
217
218
|
*/
|
|
218
219
|
renderMessage?: (messageNode: React.ReactElement, message: LocalMessage) => React.ReactNode;
|
|
219
|
-
/**
|
|
220
|
-
* Called when the visitor clicks Unlock on a locked attachment card.
|
|
221
|
-
* Fire-and-forget; host is responsible for opening checkout and tracking unlock state.
|
|
222
|
-
*/
|
|
223
|
-
onAttachmentUnlockClick?: (message: LocalMessage, channel: Channel) => void;
|
|
224
|
-
/**
|
|
225
|
-
* Called when the visitor clicks Download on an unlocked attachment card.
|
|
226
|
-
*/
|
|
227
|
-
onAttachmentDownloadClick?: (message: LocalMessage, channel: Channel) => void;
|
|
228
|
-
/**
|
|
229
|
-
* Returns the current unlock state for a given message ID.
|
|
230
|
-
* Called by CustomMessage on each render to drive controlled props on LockedAttachment.
|
|
231
|
-
* Host owns sourceUrl / redeemUrl state.
|
|
232
|
-
*/
|
|
233
|
-
onAttachmentUnlocked?: (message: LocalMessage, channel: Channel) => LockedAttachmentSource;
|
|
234
220
|
}
|
|
235
221
|
|
|
236
|
-
declare interface CreatorCardProps extends LockedAttachmentBaseProps {
|
|
222
|
+
export declare interface CreatorCardProps extends LockedAttachmentBaseProps {
|
|
237
223
|
isPreview?: boolean;
|
|
238
224
|
placeholderTitle?: string;
|
|
239
225
|
placeholderAmountText?: string;
|
|
@@ -241,6 +227,12 @@ declare interface CreatorCardProps extends LockedAttachmentBaseProps {
|
|
|
241
227
|
onDismiss?: () => void;
|
|
242
228
|
}
|
|
243
229
|
|
|
230
|
+
export declare const CustomMessageProvider: Provider<Partial<CustomMessageRegistry>>;
|
|
231
|
+
|
|
232
|
+
export declare interface CustomMessageRegistry {
|
|
233
|
+
LockedAttachment: LockedAttachmentContextValue;
|
|
234
|
+
}
|
|
235
|
+
|
|
244
236
|
declare type DmAgentSystemType = 'SYSTEM_DM_AGENT_PAUSED' | 'SYSTEM_DM_AGENT_RESUMED';
|
|
245
237
|
|
|
246
238
|
export declare interface Faq {
|
|
@@ -278,18 +270,26 @@ export declare interface FaqListProps {
|
|
|
278
270
|
*/
|
|
279
271
|
export declare const formatRelativeTime: (date: Date) => string;
|
|
280
272
|
|
|
281
|
-
export declare const LockedAttachment:
|
|
273
|
+
export declare const LockedAttachment: {
|
|
274
|
+
Creator: (props: CreatorCardProps) => JSX_2.Element;
|
|
275
|
+
Visitor: (props: VisitorCardProps) => JSX_2.Element;
|
|
276
|
+
};
|
|
282
277
|
|
|
283
278
|
declare interface LockedAttachmentBaseProps {
|
|
284
|
-
mimeType: string;
|
|
285
279
|
title?: string;
|
|
280
|
+
mimeType?: string;
|
|
286
281
|
thumbnailUrl?: string;
|
|
287
282
|
detail?: string;
|
|
288
283
|
amountText?: string;
|
|
289
284
|
paymentStatus?: PaymentStatus;
|
|
290
285
|
}
|
|
291
286
|
|
|
292
|
-
export declare
|
|
287
|
+
export declare interface LockedAttachmentContextValue {
|
|
288
|
+
isUnlocking: (id: string) => boolean;
|
|
289
|
+
onUnlockClick?: (message: LocalMessage, channel: Channel) => void;
|
|
290
|
+
onDownloadClick?: (message: LocalMessage, channel: Channel) => void;
|
|
291
|
+
onFetchSource?: (message: LocalMessage, channel: Channel) => Promise<LockedAttachmentSource | void>;
|
|
292
|
+
}
|
|
293
293
|
|
|
294
294
|
export declare interface LockedAttachmentSource {
|
|
295
295
|
/** Proxied URL used by the media player for in-app playback. */
|
|
@@ -427,10 +427,6 @@ export declare interface MessagingShellProps extends ChannelViewPassthroughProps
|
|
|
427
427
|
renderMessagePreview?: (message: LocalMessage | undefined, defaultPreview?: string) => React.ReactNode;
|
|
428
428
|
}
|
|
429
429
|
|
|
430
|
-
declare type Never<T, K extends keyof T = keyof T> = {
|
|
431
|
-
[P in K]?: never;
|
|
432
|
-
};
|
|
433
|
-
|
|
434
430
|
/**
|
|
435
431
|
* Generic participant interface for different host environments
|
|
436
432
|
*/
|
|
@@ -485,6 +481,8 @@ export declare interface ParticipantSource {
|
|
|
485
481
|
*/
|
|
486
482
|
declare type PaymentStatus = 'pending' | 'paid' | 'failed' | 'refunded';
|
|
487
483
|
|
|
484
|
+
export declare function useCustomMessage<K extends keyof CustomMessageRegistry>(key: K): CustomMessageRegistry[K];
|
|
485
|
+
|
|
488
486
|
/**
|
|
489
487
|
* Hook that wraps Stream Chat reactions to provide toggle-style
|
|
490
488
|
* upvote/downvote behavior on a message.
|
|
@@ -524,22 +522,29 @@ export declare const useParticipants: (participantSource: ParticipantSource, opt
|
|
|
524
522
|
refresh: () => void;
|
|
525
523
|
};
|
|
526
524
|
|
|
527
|
-
declare interface VisitorCardProps extends LockedAttachmentBaseProps {
|
|
525
|
+
export declare interface VisitorCardProps extends LockedAttachmentBaseProps {
|
|
528
526
|
/**
|
|
529
|
-
* Called when the visitor clicks Unlock
|
|
527
|
+
* Called when the visitor clicks Unlock on an unpaid attachment.
|
|
528
|
+
* Use this to open a checkout flow. Omit to hide the Unlock button.
|
|
530
529
|
*/
|
|
531
530
|
onUnlockClick?: () => void;
|
|
531
|
+
/**
|
|
532
|
+
* Called to fetch the attachment source — fired automatically when
|
|
533
|
+
* paymentStatus transitions to 'paid', or immediately on click when
|
|
534
|
+
* paymentStatus is already 'paid'. Return a LockedAttachmentSource to
|
|
535
|
+
* unlock the card.
|
|
536
|
+
*/
|
|
537
|
+
onFetchSource?: () => Promise<LockedAttachmentSource | void>;
|
|
532
538
|
/**
|
|
533
539
|
* Called when the visitor clicks Download on an unlocked card.
|
|
534
540
|
* Omit to hide the Download button.
|
|
535
541
|
*/
|
|
536
542
|
onDownloadClick?: () => void;
|
|
537
543
|
/**
|
|
538
|
-
*
|
|
539
|
-
*
|
|
540
|
-
* so this component receives no Stream Chat types.
|
|
544
|
+
* When true, shows loading dots on the Unlock button.
|
|
545
|
+
* Driven by the LockedAttachmentContext (e.g. checkout in progress, payment processing).
|
|
541
546
|
*/
|
|
542
|
-
|
|
547
|
+
isUnlocking?: boolean;
|
|
543
548
|
}
|
|
544
549
|
|
|
545
550
|
export declare type VoteSelection = 'up' | 'down' | null;
|