@linktr.ee/messaging-react 1.32.0 → 1.32.1-rc-1777007852

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/dist/Card-1CQEn-OT.js +171 -0
  2. package/dist/Card-1CQEn-OT.js.map +1 -0
  3. package/dist/Card-ClE_iExA.js +177 -0
  4. package/dist/Card-ClE_iExA.js.map +1 -0
  5. package/dist/{MediaPlayer-BCsdmsON.js → MediaPlayer-B9Ws2NeE.js} +115 -135
  6. package/dist/MediaPlayer-B9Ws2NeE.js.map +1 -0
  7. package/dist/index.d.ts +3 -2
  8. package/dist/index.js +1 -1
  9. package/dist/index.js.map +1 -1
  10. package/package.json +1 -1
  11. package/src/components/LockedAttachment/LockedAttachment.stories.tsx +136 -93
  12. package/src/components/LockedAttachment/components/Creator/Card.tsx +106 -106
  13. package/src/components/LockedAttachment/components/Creator/CardThumbnail.tsx +114 -0
  14. package/src/components/LockedAttachment/components/MediaPlayer.tsx +80 -66
  15. package/src/components/LockedAttachment/components/Visitor/Card.tsx +53 -78
  16. package/src/components/LockedAttachment/components/Visitor/CardActions.tsx +3 -3
  17. package/src/components/LockedAttachment/components/Visitor/CardThumbnail.tsx +81 -0
  18. package/src/components/LockedAttachment/types.ts +2 -0
  19. package/dist/Card-C5t3dZ5q.js +0 -350
  20. package/dist/Card-C5t3dZ5q.js.map +0 -1
  21. package/dist/Card-Cn2va-Qr.js +0 -205
  22. package/dist/Card-Cn2va-Qr.js.map +0 -1
  23. package/dist/MediaPlayer-BCsdmsON.js.map +0 -1
  24. package/src/components/LockedAttachment/components/Creator/CardAudioPreview.tsx +0 -161
  25. package/src/components/LockedAttachment/components/Creator/CardCollapsedThumbnail.tsx +0 -58
  26. package/src/components/LockedAttachment/components/Creator/CardImagePreview.tsx +0 -56
  27. package/src/components/LockedAttachment/components/Creator/CardVideoPreview.tsx +0 -91
  28. package/src/components/LockedAttachment/components/Visitor/CardImagePreview.tsx +0 -39
  29. package/src/components/LockedAttachment/components/Visitor/CardMediaPreview.tsx +0 -36
  30. package/src/components/LockedAttachment/components/Visitor/CardThumbnailPreview.tsx +0 -45
@@ -1,7 +1,7 @@
1
- import { jsxs as z, jsx as n } from "react/jsx-runtime";
2
- import { FileIcon as _, ImageIcon as Y, SpeakerHighIcon as Z, VideoCameraIcon as J, FileMdIcon as Q, FileTextIcon as ee, FileZipIcon as te, FilePptIcon as ne, FileCsvIcon as ae, FileXlsIcon as re, FileDocIcon as ie, FilePdfIcon as oe, CircleNotchIcon as se, PlayIcon as H, PauseIcon as le } from "@phosphor-icons/react";
3
- import ce, { useState as s, useRef as M, useEffect as L, useCallback as C } from "react";
4
- const ue = [
1
+ import { jsxs as T, jsx as n } from "react/jsx-runtime";
2
+ import { FileIcon as _, ImageIcon as G, SpeakerHighIcon as Y, VideoCameraIcon as Z, FileMdIcon as J, FileTextIcon as Q, FileZipIcon as ee, FilePptIcon as te, FileCsvIcon as ne, FileXlsIcon as ae, FileDocIcon as ie, FilePdfIcon as re, CircleNotchIcon as oe, PlayIcon as H, PauseIcon as se } from "@phosphor-icons/react";
3
+ import le, { useRef as P, useState as s, useCallback as F, useEffect as E } from "react";
4
+ const ce = [
5
5
  [/pdf/, "pdf"],
6
6
  [/wordprocessingml|msword|\.doc/, "doc"],
7
7
  [/spreadsheetml|ms-excel|\.xls/, "xls"],
@@ -11,159 +11,139 @@ const ue = [
11
11
  [/plain|rtf/, "text"],
12
12
  [/markdown/, "markdown"]
13
13
  ];
14
- function X(a) {
14
+ function $(a) {
15
15
  return a.startsWith("video/") ? "video" : a.startsWith("audio/") ? "audio" : a.startsWith("image/") ? "image" : "document";
16
16
  }
17
- function de(a) {
18
- const r = ue.find(
19
- ([i]) => i.test(a)
17
+ function ue(a) {
18
+ const i = ce.find(
19
+ ([r]) => r.test(a)
20
20
  );
21
- return r ? r[1] : "generic";
21
+ return i ? i[1] : "generic";
22
22
  }
23
- const fe = {
24
- video: J,
25
- audio: Z,
26
- image: Y,
23
+ const de = {
24
+ video: Z,
25
+ audio: Y,
26
+ image: G,
27
27
  document: _
28
- }, me = {
29
- pdf: oe,
28
+ }, fe = {
29
+ pdf: re,
30
30
  doc: ie,
31
- xls: re,
32
- csv: ae,
33
- ppt: ne,
34
- zip: te,
35
- text: ee,
36
- markdown: Q,
31
+ xls: ae,
32
+ csv: ne,
33
+ ppt: te,
34
+ zip: ee,
35
+ text: Q,
36
+ markdown: J,
37
37
  generic: _
38
38
  };
39
- function he(a) {
40
- const r = X(a);
41
- return r !== "document" ? fe[r] : me[de(a)];
39
+ function me(a) {
40
+ const i = $(a);
41
+ return i !== "document" ? de[i] : fe[ue(a)];
42
42
  }
43
- function pe(a, r) {
44
- return ce.createElement(he(a), r);
43
+ function he(a, i) {
44
+ return le.createElement(me(a), i);
45
45
  }
46
- const ve = (a, r) => a === "audio" && !r ? "bg-black/5" : "bg-black", we = (a) => {
47
- var r, i;
48
- return "touches" in a ? ((r = a.touches[0]) == null ? void 0 : r.clientX) ?? ((i = a.changedTouches[0]) == null ? void 0 : i.clientX) ?? 0 : a.clientX;
49
- }, xe = ({
46
+ const pe = (a) => {
47
+ var i, r;
48
+ return "touches" in a ? ((i = a.touches[0]) == null ? void 0 : i.clientX) ?? ((r = a.changedTouches[0]) == null ? void 0 : r.clientX) ?? 0 : a.clientX;
49
+ }, be = ({
50
50
  source: a,
51
- mimeType: r,
52
- poster: i,
53
- autoPlay: q = !1,
51
+ mimeType: i,
52
+ poster: r,
53
+ autoPlay: X = !1,
54
54
  playing: u,
55
55
  loop: y = !1,
56
56
  controls: v = !0,
57
- showProgress: K = !1,
58
- onContainerClick: x,
59
- muted: D = !1
57
+ showProgress: q = !1,
58
+ muted: z = !1
60
59
  }) => {
61
- const k = X(r), [d, o] = s(q), R = M(u);
62
- L(() => {
63
- u !== void 0 && u !== R.current && (R.current = u, o(u));
64
- }, [u]);
65
- const [w, g] = s(0), [f, A] = s(!1), [S, j] = s(!1), [T, B] = s(null), [U, m] = s(!1), [O, W] = s(!0), [N, I] = s(!1), h = M(null), F = M(null), l = M(null);
66
- L(() => {
67
- if (!d) {
60
+ const M = $(i), d = P(null), C = P(null), l = P(null), D = P(u), [f, o] = s(X), [w, g] = s(0), [m, R] = s(!1), [A, S] = s(!1), [x, k] = s(!1), [K, h] = s(!1), [j, O] = s(!0), [L, U] = s(null), W = F(() => {
61
+ k(!1), o(!0);
62
+ }, []), N = F((e) => {
63
+ const t = C.current;
64
+ if (!t) return 0;
65
+ const p = t.getBoundingClientRect();
66
+ return Math.max(
67
+ 0,
68
+ Math.min(1, (pe(e) - p.left) / p.width)
69
+ );
70
+ }, []), c = F((e) => {
71
+ const t = d.current;
72
+ t && t.duration && (t.currentTime = e * t.duration);
73
+ }, []), I = (e) => {
74
+ e.stopPropagation(), R(!0);
75
+ const t = N(e);
76
+ g(t), c(t);
77
+ };
78
+ E(() => {
79
+ u !== void 0 && u !== D.current && (D.current = u, o(u));
80
+ }, [u]), E(() => {
81
+ if (!f) {
68
82
  l.current !== null && (cancelAnimationFrame(l.current), l.current = null);
69
83
  return;
70
84
  }
71
85
  const e = () => {
72
- const t = h.current;
73
- t && t.duration && !f && g(t.currentTime / t.duration), l.current = requestAnimationFrame(e);
86
+ const t = d.current;
87
+ t && t.duration && !m && g(t.currentTime / t.duration), l.current = requestAnimationFrame(e);
74
88
  };
75
89
  return l.current = requestAnimationFrame(e), () => {
76
90
  l.current !== null && cancelAnimationFrame(l.current);
77
91
  };
78
- }, [d, f]), L(() => {
79
- const e = h.current;
80
- e && (d ? e.play().catch((t) => {
81
- o(!1), I(!0);
92
+ }, [f, m]), E(() => {
93
+ const e = d.current;
94
+ e && (f ? e.play().catch((t) => {
95
+ o(!1), k(!0);
82
96
  }) : e.pause());
83
- }, [d]);
84
- const $ = C(() => {
85
- I(!1), o(!0);
86
- }, []), P = C(
87
- (e) => {
88
- const t = F.current;
89
- if (!t) return 0;
90
- const p = t.getBoundingClientRect();
91
- return Math.max(
92
- 0,
93
- Math.min(1, (we(e) - p.left) / p.width)
94
- );
95
- },
96
- []
97
- ), c = C((e) => {
98
- const t = h.current;
99
- t && t.duration && (t.currentTime = e * t.duration);
100
- }, []), E = (e) => {
101
- e.stopPropagation(), A(!0);
102
- const t = P(e);
103
- g(t), c(t);
104
- };
105
- L(() => {
106
- if (!f) return;
107
- const e = (p) => g(P(p)), t = (p) => {
108
- A(!1), c(P(p));
97
+ }, [f]), E(() => {
98
+ if (!m) return;
99
+ const e = (p) => g(N(p)), t = (p) => {
100
+ R(!1), c(N(p));
109
101
  };
110
102
  return window.addEventListener("mousemove", e), window.addEventListener("mouseup", t), window.addEventListener("touchmove", e, { passive: !0 }), window.addEventListener("touchend", t), () => {
111
103
  window.removeEventListener("mousemove", e), window.removeEventListener("mouseup", t), window.removeEventListener("touchmove", e), window.removeEventListener("touchend", t);
112
104
  };
113
- }, [f, P, c]);
114
- const V = T ? { aspectRatio: String(T) } : void 0, G = T ? "" : " aspect-video", b = Math.round(w * 100);
115
- return /* @__PURE__ */ z(
105
+ }, [m, N, c]);
106
+ const V = L ? { aspectRatio: String(L) } : void 0, B = L ? "" : " aspect-video", b = Math.round(w * 100);
107
+ return /* @__PURE__ */ T(
116
108
  "div",
117
109
  {
118
110
  role: "button",
119
111
  tabIndex: 0,
120
- className: `relative cursor-pointer overflow-hidden ${ve(k, i)}${G}`,
112
+ className: `relative cursor-pointer overflow-hidden bg-black ${B}`,
121
113
  style: V,
122
114
  onClick: () => {
123
- if (!N) {
124
- if (x) {
125
- x();
126
- return;
127
- }
128
- v && o((e) => !e);
129
- }
115
+ x || v && o((e) => !e);
130
116
  },
131
117
  onKeyDown: (e) => {
132
- if (!(e.key !== "Enter" && e.key !== " ") && (e.preventDefault(), !N)) {
133
- if (x) {
134
- x();
135
- return;
136
- }
137
- v && o((t) => !t);
138
- }
118
+ e.key !== "Enter" && e.key !== " " || (e.preventDefault(), !x && v && o((t) => !t));
139
119
  },
140
120
  children: [
141
- i && (k === "audio" || O) && /* @__PURE__ */ n(
121
+ r && (M === "audio" || j) && /* @__PURE__ */ n(
142
122
  "img",
143
123
  {
144
- src: i,
124
+ src: r,
145
125
  alt: "",
146
126
  className: "absolute inset-0 h-full w-full object-cover"
147
127
  }
148
128
  ),
149
- !i && (k === "audio" || O) && /* @__PURE__ */ n("div", { className: "absolute inset-0 flex items-center justify-center", children: pe(r, {
129
+ !r && (M === "audio" || j) && /* @__PURE__ */ n("div", { className: "absolute inset-0 flex items-center justify-center", children: he(i, {
150
130
  className: "size-12 text-black/20",
151
131
  weight: "regular"
152
132
  }) }),
153
- /* @__PURE__ */ n("div", { className: "absolute inset-0", children: k === "audio" ? /* @__PURE__ */ n(
133
+ /* @__PURE__ */ n("div", { className: "absolute inset-0", children: M === "audio" ? /* @__PURE__ */ n(
154
134
  "audio",
155
135
  {
156
- ref: h,
136
+ ref: d,
157
137
  src: a,
158
138
  loop: y,
159
- muted: D,
139
+ muted: z,
160
140
  style: { width: "100%", height: "100%" },
161
- onLoadStart: () => m(!0),
141
+ onLoadStart: () => h(!0),
162
142
  onCanPlay: () => {
163
- m(!1), W(!1);
143
+ h(!1), O(!1);
164
144
  },
165
- onWaiting: () => m(!0),
166
- onPlay: () => I(!1),
145
+ onWaiting: () => h(!0),
146
+ onPlay: () => k(!1),
167
147
  onEnded: () => {
168
148
  y || (o(!1), g(0));
169
149
  },
@@ -172,21 +152,21 @@ const ve = (a, r) => a === "audio" && !r ? "bg-black/5" : "bg-black", we = (a) =
172
152
  ) : /* @__PURE__ */ n(
173
153
  "video",
174
154
  {
175
- ref: h,
155
+ ref: d,
176
156
  src: a,
177
157
  loop: y,
178
- muted: D,
158
+ muted: z,
179
159
  playsInline: !0,
180
160
  style: { width: "100%", height: "100%" },
181
- onLoadStart: () => m(!0),
161
+ onLoadStart: () => h(!0),
182
162
  onCanPlay: () => {
183
- m(!1), W(!1);
163
+ h(!1), O(!1);
184
164
  },
185
- onWaiting: () => m(!0),
186
- onPlay: () => I(!1),
165
+ onWaiting: () => h(!0),
166
+ onPlay: () => k(!1),
187
167
  onLoadedMetadata: () => {
188
- const e = h.current;
189
- e instanceof HTMLVideoElement && e.videoWidth && e.videoHeight && B(e.videoWidth / e.videoHeight);
168
+ const e = d.current;
169
+ e instanceof HTMLVideoElement && e.videoWidth && e.videoHeight && U(e.videoWidth / e.videoHeight);
190
170
  },
191
171
  onEnded: () => {
192
172
  y || (o(!1), g(0));
@@ -194,14 +174,14 @@ const ve = (a, r) => a === "audio" && !r ? "bg-black/5" : "bg-black", we = (a) =
194
174
  children: /* @__PURE__ */ n("track", { kind: "captions" })
195
175
  }
196
176
  ) }),
197
- U && !N && /* @__PURE__ */ n("div", { className: "absolute inset-0 z-10 flex items-center justify-center", children: /* @__PURE__ */ n(
198
- se,
177
+ K && !x && /* @__PURE__ */ n("div", { className: "absolute inset-0 z-10 flex items-center justify-center", children: /* @__PURE__ */ n(
178
+ oe,
199
179
  {
200
180
  className: "size-8 animate-spin text-white/80",
201
181
  weight: "bold"
202
182
  }
203
183
  ) }),
204
- N && !v && /* @__PURE__ */ n(
184
+ x && !v && /* @__PURE__ */ n(
205
185
  "div",
206
186
  {
207
187
  className: "absolute inset-0 z-30 flex cursor-pointer items-center justify-center bg-black/35",
@@ -209,15 +189,15 @@ const ve = (a, r) => a === "audio" && !r ? "bg-black/5" : "bg-black", we = (a) =
209
189
  tabIndex: 0,
210
190
  "aria-label": "Play preview",
211
191
  onClick: (e) => {
212
- e.stopPropagation(), $();
192
+ e.stopPropagation(), W();
213
193
  },
214
194
  onKeyDown: (e) => {
215
- e.key !== "Enter" && e.key !== " " || (e.preventDefault(), e.stopPropagation(), $());
195
+ e.key !== "Enter" && e.key !== " " || (e.preventDefault(), e.stopPropagation(), W());
216
196
  },
217
197
  children: /* @__PURE__ */ n("span", { className: "flex size-16 items-center justify-center rounded-full bg-white/20 text-white backdrop-blur-sm", children: /* @__PURE__ */ n(H, { className: "size-9 translate-x-0.5", weight: "fill" }) })
218
198
  }
219
199
  ),
220
- K && !v && /* @__PURE__ */ n("div", { className: "absolute inset-x-0 bottom-0 px-3 pb-2.5 pt-6 bg-gradient-to-t from-black/40 to-transparent", children: /* @__PURE__ */ n(
200
+ q && !v && /* @__PURE__ */ n("div", { className: "absolute inset-x-0 bottom-0 px-3 pb-2.5 pt-6 bg-gradient-to-t from-black/40 to-transparent", children: /* @__PURE__ */ n(
221
201
  "div",
222
202
  {
223
203
  role: "slider",
@@ -226,10 +206,10 @@ const ve = (a, r) => a === "audio" && !r ? "bg-black/5" : "bg-black", we = (a) =
226
206
  "aria-valuemin": 0,
227
207
  "aria-valuemax": 100,
228
208
  tabIndex: 0,
229
- ref: F,
209
+ ref: C,
230
210
  className: "relative flex h-4 w-full cursor-pointer items-center",
231
- onMouseDown: E,
232
- onTouchStart: E,
211
+ onMouseDown: I,
212
+ onTouchStart: I,
233
213
  onClick: (e) => e.stopPropagation(),
234
214
  onKeyDown: (e) => {
235
215
  e.key === "ArrowRight" && c(Math.min(1, w + 0.05)), e.key === "ArrowLeft" && c(Math.max(0, w - 0.05));
@@ -243,7 +223,7 @@ const ve = (a, r) => a === "audio" && !r ? "bg-black/5" : "bg-black", we = (a) =
243
223
  ) })
244
224
  }
245
225
  ) }),
246
- v && /* @__PURE__ */ z("div", { className: "absolute inset-x-0 bottom-0 flex items-center gap-2 bg-gradient-to-t from-black/60 to-transparent px-3 pb-2.5 pt-6 transition-all duration-200", children: [
226
+ v && /* @__PURE__ */ T("div", { className: "absolute inset-x-0 bottom-0 flex items-center gap-2 bg-gradient-to-t from-black/60 to-transparent px-3 pb-2.5 pt-6 transition-all duration-200", children: [
247
227
  /* @__PURE__ */ n(
248
228
  "button",
249
229
  {
@@ -252,11 +232,11 @@ const ve = (a, r) => a === "audio" && !r ? "bg-black/5" : "bg-black", we = (a) =
252
232
  e.stopPropagation(), o((t) => !t);
253
233
  },
254
234
  className: "shrink-0 text-white",
255
- "aria-label": d ? "Pause" : "Play",
256
- children: d ? /* @__PURE__ */ n(le, { className: "size-5", weight: "fill" }) : /* @__PURE__ */ n(H, { className: "size-5 translate-x-px", weight: "fill" })
235
+ "aria-label": f ? "Pause" : "Play",
236
+ children: f ? /* @__PURE__ */ n(se, { className: "size-5", weight: "fill" }) : /* @__PURE__ */ n(H, { className: "size-5 translate-x-px", weight: "fill" })
257
237
  }
258
238
  ),
259
- /* @__PURE__ */ z(
239
+ /* @__PURE__ */ T(
260
240
  "div",
261
241
  {
262
242
  role: "slider",
@@ -265,13 +245,13 @@ const ve = (a, r) => a === "audio" && !r ? "bg-black/5" : "bg-black", we = (a) =
265
245
  "aria-valuemin": 0,
266
246
  "aria-valuemax": 100,
267
247
  tabIndex: 0,
268
- ref: F,
248
+ ref: C,
269
249
  className: "relative flex h-4 w-full cursor-pointer items-center",
270
- onMouseDown: E,
271
- onTouchStart: E,
250
+ onMouseDown: I,
251
+ onTouchStart: I,
272
252
  onClick: (e) => e.stopPropagation(),
273
- onMouseEnter: () => j(!0),
274
- onMouseLeave: () => j(!1),
253
+ onMouseEnter: () => S(!0),
254
+ onMouseLeave: () => S(!1),
275
255
  onKeyDown: (e) => {
276
256
  e.key === "ArrowRight" && c(Math.min(1, w + 0.05)), e.key === "ArrowLeft" && c(Math.max(0, w - 0.05));
277
257
  },
@@ -279,7 +259,7 @@ const ve = (a, r) => a === "audio" && !r ? "bg-black/5" : "bg-black", we = (a) =
279
259
  /* @__PURE__ */ n(
280
260
  "div",
281
261
  {
282
- className: `w-full overflow-hidden rounded-full bg-white/30 transition-all duration-200 ${S || f ? "h-1.5" : "h-1"}`,
262
+ className: `w-full overflow-hidden rounded-full bg-white/30 transition-all duration-200 ${A || m ? "h-1.5" : "h-1"}`,
283
263
  children: /* @__PURE__ */ n(
284
264
  "div",
285
265
  {
@@ -292,7 +272,7 @@ const ve = (a, r) => a === "audio" && !r ? "bg-black/5" : "bg-black", we = (a) =
292
272
  /* @__PURE__ */ n(
293
273
  "div",
294
274
  {
295
- className: `absolute size-3 -translate-x-1/2 rounded-full bg-white shadow transition-[opacity,transform] duration-200 ${S || f ? "scale-100 opacity-100" : "scale-0 opacity-0"}`,
275
+ className: `absolute size-3 -translate-x-1/2 rounded-full bg-white shadow transition-[opacity,transform] duration-200 ${A || m ? "scale-100 opacity-100" : "scale-0 opacity-0"}`,
296
276
  style: { left: `${b}%` }
297
277
  }
298
278
  )
@@ -305,8 +285,8 @@ const ve = (a, r) => a === "audio" && !r ? "bg-black/5" : "bg-black", we = (a) =
305
285
  );
306
286
  };
307
287
  export {
308
- xe as M,
309
- X as g,
310
- pe as r
288
+ be as M,
289
+ $ as g,
290
+ he as r
311
291
  };
312
- //# sourceMappingURL=MediaPlayer-BCsdmsON.js.map
292
+ //# sourceMappingURL=MediaPlayer-B9Ws2NeE.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MediaPlayer-B9Ws2NeE.js","sources":["../src/components/LockedAttachment/utils/mimeType.ts","../src/components/LockedAttachment/utils/icons.ts","../src/components/LockedAttachment/components/MediaPlayer.tsx"],"sourcesContent":["export type AttachmentSourceType = 'image' | 'audio' | 'video' | 'document'\n\nexport type DocumentIconType =\n | 'pdf'\n | 'doc'\n | 'xls'\n | 'csv'\n | 'ppt'\n | 'zip'\n | 'text'\n | 'markdown'\n | 'generic'\n\nconst DOCUMENT_ICON_PATTERNS: Array<[RegExp, DocumentIconType]> = [\n [/pdf/, 'pdf'],\n [/wordprocessingml|msword|\\.doc/, 'doc'],\n [/spreadsheetml|ms-excel|\\.xls/, 'xls'],\n [/csv/, 'csv'],\n [/presentationml|ms-powerpoint|\\.ppt/, 'ppt'],\n [/zip|x-rar|x-7z|x-tar|x-gzip/, 'zip'],\n [/plain|rtf/, 'text'],\n [/markdown/, 'markdown'],\n]\n\nexport function getSourceType(mimeType: string): AttachmentSourceType {\n if (mimeType.startsWith('video/')) return 'video'\n if (mimeType.startsWith('audio/')) return 'audio'\n if (mimeType.startsWith('image/')) return 'image'\n return 'document'\n}\n\nexport function getDocumentIconType(mimeType: string): DocumentIconType {\n const match = DOCUMENT_ICON_PATTERNS.find(([pattern]) =>\n pattern.test(mimeType)\n )\n return match ? match[1] : 'generic'\n}\n","import {\n FileIcon,\n FileCsvIcon,\n FileDocIcon,\n FileMdIcon,\n FilePdfIcon,\n FilePptIcon,\n FileTextIcon,\n FileXlsIcon,\n FileZipIcon,\n ImageIcon,\n SpeakerHighIcon,\n VideoCameraIcon,\n IconProps,\n} from '@phosphor-icons/react'\nimport React from 'react'\n\nimport { getDocumentIconType, getSourceType } from './mimeType'\nimport type { AttachmentSourceType } from './mimeType'\n\nexport const MEDIA_TYPE_ICON: Record<AttachmentSourceType, React.ElementType> =\n {\n video: VideoCameraIcon,\n audio: SpeakerHighIcon,\n image: ImageIcon,\n document: FileIcon,\n }\n\nconst DOCUMENT_ICON_COMPONENT = {\n pdf: FilePdfIcon,\n doc: FileDocIcon,\n xls: FileXlsIcon,\n csv: FileCsvIcon,\n ppt: FilePptIcon,\n zip: FileZipIcon,\n text: FileTextIcon,\n markdown: FileMdIcon,\n generic: FileIcon,\n} as const\n\nexport function getTypeIcon(mimeType: string): React.ElementType {\n const sourceType = getSourceType(mimeType)\n if (sourceType !== 'document') return MEDIA_TYPE_ICON[sourceType]\n return DOCUMENT_ICON_COMPONENT[getDocumentIconType(mimeType)]\n}\n\n/** Use instead of `<TypeIcon />` where TypeIcon = getTypeIcon(mime) to satisfy react-hooks/static-components. */\nexport function renderTypeIcon(\n mimeType: string,\n props: IconProps\n): React.ReactElement {\n return React.createElement(getTypeIcon(mimeType), props)\n}\n","import { CircleNotchIcon, PauseIcon, PlayIcon } from '@phosphor-icons/react'\nimport React, { useCallback, useEffect, useRef, useState } from 'react'\n\nimport { isDevBuild } from '../../../utils/isDevBuild'\nimport { renderTypeIcon } from '../utils/icons'\nimport { getSourceType } from '../utils/mimeType'\n\ntype TouchEventUnion =\n | MouseEvent\n | TouchEvent\n | React.MouseEvent\n | React.TouchEvent\n\n\nconst getClientXFromEvent = (e: TouchEventUnion): number => {\n if ('touches' in e) {\n return e.touches[0]?.clientX ?? e.changedTouches[0]?.clientX ?? 0\n }\n return e.clientX\n}\n\nexport interface MediaPlayerProps {\n source: string\n mimeType: string\n poster?: string\n autoPlay?: boolean\n /** Controlled playing state. When provided, syncs to internal play/pause. */\n playing?: boolean\n loop?: boolean\n controls?: boolean\n showProgress?: boolean\n /** When true, requests muted playback (helps autoplay policies on video). */\n muted?: boolean\n}\n\nconst MediaPlayer: React.FC<MediaPlayerProps> = ({\n source,\n mimeType,\n poster,\n autoPlay = false,\n playing: playingProp,\n loop = false,\n controls = true,\n showProgress = false,\n muted = false,\n}) => {\n // --- Derived ---\n const sourceType = getSourceType(mimeType)\n\n // --- Refs ---\n const playerRef = useRef<HTMLMediaElement>(null)\n const trackRef = useRef<HTMLDivElement>(null)\n const rafRef = useRef<number | null>(null)\n const prevPlayingPropRef = useRef(playingProp)\n\n // --- State: playback ---\n const [playing, setPlaying] = useState(autoPlay)\n const [played, setPlayed] = useState(0)\n const [seeking, setSeeking] = useState(false)\n\n // --- State: UI ---\n const [scrubberHovered, setScrubberHovered] = useState(false)\n /** Set when autoplay/play() was rejected so user can start via gesture (no controls UI). */\n const [manualPlayRequired, setManualPlayRequired] = useState(false)\n\n // --- State: loading ---\n const [buffering, setBuffering] = useState(false)\n /** True until the first canPlay fires for the current source — hides controls/spinner behind poster. */\n const [initialLoad, setInitialLoad] = useState(true)\n const [videoAspect, setVideoAspect] = useState<number | null>(null)\n\n // --- Callbacks ---\n const startPlaybackFromGesture = useCallback(() => {\n setManualPlayRequired(false)\n setPlaying(true)\n }, [])\n\n const getFraction = useCallback((e: TouchEventUnion) => {\n const track = trackRef.current\n if (!track) return 0\n const rect = track.getBoundingClientRect()\n return Math.max(\n 0,\n Math.min(1, (getClientXFromEvent(e) - rect.left) / rect.width)\n )\n }, [])\n\n const seekTo = useCallback((fraction: number) => {\n const el = playerRef.current\n if (el && el.duration) el.currentTime = fraction * el.duration\n }, [])\n\n const handleTrackPointerDown = (\n e: React.MouseEvent<HTMLDivElement> | React.TouchEvent<HTMLDivElement>\n ) => {\n e.stopPropagation()\n setSeeking(true)\n const fraction = getFraction(e)\n setPlayed(fraction)\n seekTo(fraction)\n }\n\n // --- Effects ---\n\n // Sync controlled playing prop to internal state\n useEffect(() => {\n if (\n playingProp !== undefined &&\n playingProp !== prevPlayingPropRef.current\n ) {\n prevPlayingPropRef.current = playingProp\n setPlaying(playingProp)\n }\n }, [playingProp])\n\n // RAF-driven progress updates\n useEffect(() => {\n if (!playing) {\n if (rafRef.current !== null) {\n cancelAnimationFrame(rafRef.current)\n rafRef.current = null\n }\n return\n }\n const tick = () => {\n const el = playerRef.current\n if (el && el.duration && !seeking) setPlayed(el.currentTime / el.duration)\n rafRef.current = requestAnimationFrame(tick)\n }\n rafRef.current = requestAnimationFrame(tick)\n return () => {\n if (rafRef.current !== null) cancelAnimationFrame(rafRef.current)\n }\n }, [playing, seeking])\n\n // ReactPlayer v3 uses native HTML media elements and does not support a\n // declarative `playing` prop — playback must be driven imperatively.\n useEffect(() => {\n const el = playerRef.current\n if (!el) return\n if (playing) {\n void el.play().catch((err) => {\n setPlaying(false)\n setManualPlayRequired(true)\n if (isDevBuild()) {\n console.debug('[MediaPlayer] play() failed', err)\n }\n })\n } else {\n el.pause()\n }\n }, [playing])\n\n // Global seeking listeners\n useEffect(() => {\n if (!seeking) return\n const onMove = (e: MouseEvent | TouchEvent) => setPlayed(getFraction(e))\n const onUp = (e: MouseEvent | TouchEvent) => {\n setSeeking(false)\n seekTo(getFraction(e))\n }\n window.addEventListener('mousemove', onMove)\n window.addEventListener('mouseup', onUp)\n window.addEventListener('touchmove', onMove, { passive: true })\n window.addEventListener('touchend', onUp)\n return () => {\n window.removeEventListener('mousemove', onMove)\n window.removeEventListener('mouseup', onUp)\n window.removeEventListener('touchmove', onMove)\n window.removeEventListener('touchend', onUp)\n }\n }, [seeking, getFraction, seekTo])\n\n // --- Derived render values ---\n // Use natural aspect ratio once metadata loads, fall back to 16:9 before then.\n const aspectStyle = videoAspect\n ? { aspectRatio: String(videoAspect) }\n : undefined\n const aspectClass = !videoAspect ? ' aspect-video' : ''\n const scrubberPercent = Math.round(played * 100)\n\n return (\n <div\n role=\"button\"\n tabIndex={0}\n className={`relative cursor-pointer overflow-hidden bg-black ${aspectClass}`}\n style={aspectStyle}\n onClick={() => {\n if (manualPlayRequired) return\n if (controls) setPlaying((p) => !p)\n }}\n onKeyDown={(e) => {\n if (e.key !== 'Enter' && e.key !== ' ') return\n e.preventDefault()\n if (manualPlayRequired) return\n if (controls) setPlaying((p) => !p)\n }}\n >\n {/* For audio, poster persists as a visual background. For video, hide once loaded. */}\n {poster && (sourceType === 'audio' || initialLoad) && (\n <img\n src={poster}\n alt=\"\"\n className=\"absolute inset-0 h-full w-full object-cover\"\n />\n )}\n {!poster && (sourceType === 'audio' || initialLoad) && (\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 <div className=\"absolute inset-0\">\n {sourceType === 'audio' ? (\n <audio\n ref={playerRef as React.RefObject<HTMLAudioElement>}\n src={source}\n loop={loop}\n muted={muted}\n style={{ width: '100%', height: '100%' }}\n onLoadStart={() => setBuffering(true)}\n onCanPlay={() => {\n setBuffering(false)\n setInitialLoad(false)\n }}\n onWaiting={() => setBuffering(true)}\n onPlay={() => setManualPlayRequired(false)}\n onEnded={() => {\n if (!loop) {\n setPlaying(false)\n setPlayed(0)\n }\n }}\n >\n <track kind=\"captions\" />\n </audio>\n ) : (\n <video\n ref={playerRef as React.RefObject<HTMLVideoElement>}\n src={source}\n loop={loop}\n muted={muted}\n playsInline\n style={{ width: '100%', height: '100%' }}\n onLoadStart={() => setBuffering(true)}\n onCanPlay={() => {\n setBuffering(false)\n setInitialLoad(false)\n }}\n onWaiting={() => setBuffering(true)}\n onPlay={() => setManualPlayRequired(false)}\n onLoadedMetadata={() => {\n const el = playerRef.current\n if (\n el instanceof HTMLVideoElement &&\n el.videoWidth &&\n el.videoHeight\n ) {\n setVideoAspect(el.videoWidth / el.videoHeight)\n }\n }}\n onEnded={() => {\n if (!loop) {\n setPlaying(false)\n setPlayed(0)\n }\n }}\n >\n <track kind=\"captions\" />\n </video>\n )}\n </div>\n\n {buffering && !manualPlayRequired && (\n <div className=\"absolute inset-0 z-10 flex items-center justify-center\">\n <CircleNotchIcon\n className=\"size-8 animate-spin text-white/80\"\n weight=\"bold\"\n />\n </div>\n )}\n\n {manualPlayRequired && !controls && (\n <div\n className=\"absolute inset-0 z-30 flex cursor-pointer items-center justify-center bg-black/35\"\n role=\"button\"\n tabIndex={0}\n aria-label=\"Play preview\"\n onClick={(e) => {\n e.stopPropagation()\n startPlaybackFromGesture()\n }}\n onKeyDown={(e) => {\n if (e.key !== 'Enter' && e.key !== ' ') return\n e.preventDefault()\n e.stopPropagation()\n startPlaybackFromGesture()\n }}\n >\n <span className=\"flex size-16 items-center justify-center rounded-full bg-white/20 text-white backdrop-blur-sm\">\n <PlayIcon className=\"size-9 translate-x-0.5\" weight=\"fill\" />\n </span>\n </div>\n )}\n\n {showProgress && !controls && (\n <div className=\"absolute inset-x-0 bottom-0 px-3 pb-2.5 pt-6 bg-gradient-to-t from-black/40 to-transparent\">\n <div\n role=\"slider\"\n aria-label=\"Playback position\"\n aria-valuenow={scrubberPercent}\n aria-valuemin={0}\n aria-valuemax={100}\n tabIndex={0}\n ref={trackRef}\n className=\"relative flex h-4 w-full cursor-pointer items-center\"\n onMouseDown={handleTrackPointerDown}\n onTouchStart={handleTrackPointerDown}\n onClick={(e) => e.stopPropagation()}\n onKeyDown={(e) => {\n if (e.key === 'ArrowRight') seekTo(Math.min(1, played + 0.05))\n if (e.key === 'ArrowLeft') seekTo(Math.max(0, played - 0.05))\n }}\n >\n <div className=\"w-full overflow-hidden rounded-full bg-white/30 h-1\">\n <div\n className=\"h-full rounded-full bg-white\"\n style={{ width: `${scrubberPercent}%` }}\n />\n </div>\n </div>\n </div>\n )}\n\n {controls && (\n <div className=\"absolute inset-x-0 bottom-0 flex items-center gap-2 bg-gradient-to-t from-black/60 to-transparent px-3 pb-2.5 pt-6 transition-all duration-200\">\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation()\n setPlaying((p) => !p)\n }}\n className=\"shrink-0 text-white\"\n aria-label={playing ? 'Pause' : 'Play'}\n >\n {playing ? (\n <PauseIcon className=\"size-5\" weight=\"fill\" />\n ) : (\n <PlayIcon className=\"size-5 translate-x-px\" weight=\"fill\" />\n )}\n </button>\n\n <div\n role=\"slider\"\n aria-label=\"Playback position\"\n aria-valuenow={scrubberPercent}\n aria-valuemin={0}\n aria-valuemax={100}\n tabIndex={0}\n ref={trackRef}\n className=\"relative flex h-4 w-full cursor-pointer items-center\"\n onMouseDown={handleTrackPointerDown}\n onTouchStart={handleTrackPointerDown}\n onClick={(e) => e.stopPropagation()}\n onMouseEnter={() => setScrubberHovered(true)}\n onMouseLeave={() => setScrubberHovered(false)}\n onKeyDown={(e) => {\n if (e.key === 'ArrowRight') seekTo(Math.min(1, played + 0.05))\n if (e.key === 'ArrowLeft') seekTo(Math.max(0, played - 0.05))\n }}\n >\n <div\n className={`w-full overflow-hidden rounded-full bg-white/30 transition-all duration-200 ${scrubberHovered || seeking ? 'h-1.5' : 'h-1'}`}\n >\n <div\n className=\"h-full rounded-full bg-white\"\n style={{ width: `${scrubberPercent}%` }}\n />\n </div>\n <div\n className={`absolute size-3 -translate-x-1/2 rounded-full bg-white shadow transition-[opacity,transform] duration-200 ${scrubberHovered || seeking ? 'scale-100 opacity-100' : 'scale-0 opacity-0'}`}\n style={{ left: `${scrubberPercent}%` }}\n />\n </div>\n </div>\n )}\n </div>\n )\n}\n\nexport default MediaPlayer\n"],"names":["DOCUMENT_ICON_PATTERNS","getSourceType","mimeType","getDocumentIconType","match","pattern","MEDIA_TYPE_ICON","VideoCameraIcon","SpeakerHighIcon","ImageIcon","FileIcon","DOCUMENT_ICON_COMPONENT","FilePdfIcon","FileDocIcon","FileXlsIcon","FileCsvIcon","FilePptIcon","FileZipIcon","FileTextIcon","FileMdIcon","getTypeIcon","sourceType","renderTypeIcon","props","React","getClientXFromEvent","e","_a","_b","MediaPlayer","source","poster","autoPlay","playingProp","loop","controls","showProgress","muted","playerRef","useRef","trackRef","rafRef","prevPlayingPropRef","playing","setPlaying","useState","played","setPlayed","seeking","setSeeking","scrubberHovered","setScrubberHovered","manualPlayRequired","setManualPlayRequired","buffering","setBuffering","initialLoad","setInitialLoad","videoAspect","setVideoAspect","startPlaybackFromGesture","useCallback","getFraction","track","rect","seekTo","fraction","el","handleTrackPointerDown","useEffect","tick","err","onMove","onUp","aspectStyle","aspectClass","scrubberPercent","jsxs","p","jsx","CircleNotchIcon","PlayIcon","PauseIcon"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -220,11 +220,10 @@ export declare interface ChannelViewProps {
220
220
  }
221
221
 
222
222
  export declare interface CreatorCardProps extends LockedAttachmentBaseProps {
223
- isPreview?: boolean;
224
223
  placeholderTitle?: string;
225
224
  placeholderAmountText?: string;
226
- sourceUrl?: string;
227
225
  onDismiss?: () => void;
226
+ onPreviewClick?: () => LockedAttachmentSource;
228
227
  }
229
228
 
230
229
  export declare const CustomMessageProvider: Provider<Partial<CustomMessageRegistry>>;
@@ -296,6 +295,8 @@ export declare interface LockedAttachmentSource {
296
295
  sourceUrl: string;
297
296
  /** URL opened when the visitor clicks Download — may be a file or a web destination. */
298
297
  redeemUrl?: string;
298
+ /** Thumbnail URL from the fetched asset — overrides the metadata thumbnail when present. */
299
+ thumbnailUrl?: string;
299
300
  }
300
301
 
301
302
  declare type MessageCustomType = 'MESSAGE_TIP' | 'MESSAGE_PAID' | 'MESSAGE_CHATBOT' | 'MESSAGE_ATTACHMENT' | AgeSafetySystemType | DmAgentSystemType;
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: m };
837
837
  }
838
- const _s = U.lazy(() => import("./Card-C5t3dZ5q.js")), Es = U.lazy(() => import("./Card-Cn2va-Qr.js")), mt = () => /* @__PURE__ */ e(
838
+ const _s = U.lazy(() => import("./Card-1CQEn-OT.js")), Es = U.lazy(() => import("./Card-ClE_iExA.js")), mt = () => /* @__PURE__ */ e(
839
839
  "div",
840
840
  {
841
841
  className: "w-[280px] min-h-[200px] animate-pulse rounded-[24px] bg-black/[0.06] shadow-[0_0_0_1px_rgba(0,0,0,0.04),0_4px_8px_rgba(0,0,0,0.06)]",