react-sharesheet 1.0.0 → 1.2.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/README.md +84 -102
- package/dist/content.d.mts +3 -3
- package/dist/content.d.ts +3 -3
- package/dist/content.js +296 -271
- package/dist/content.js.map +1 -1
- package/dist/content.mjs +298 -273
- package/dist/content.mjs.map +1 -1
- package/dist/drawer.d.mts +3 -3
- package/dist/drawer.d.ts +3 -3
- package/dist/drawer.js +298 -275
- package/dist/drawer.js.map +1 -1
- package/dist/drawer.mjs +300 -277
- package/dist/drawer.mjs.map +1 -1
- package/dist/headless-B7I228Dt.d.mts +98 -0
- package/dist/headless-BiSYHizs.d.ts +98 -0
- package/dist/headless.d.mts +3 -50
- package/dist/headless.d.ts +3 -50
- package/dist/headless.js +165 -0
- package/dist/headless.js.map +1 -1
- package/dist/headless.mjs +163 -1
- package/dist/headless.mjs.map +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +339 -277
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +329 -278
- package/dist/index.mjs.map +1 -1
- package/dist/{platforms-DU1DVDFq.d.mts → platforms-omqzPfYX.d.mts} +17 -23
- package/dist/{platforms-DU1DVDFq.d.ts → platforms-omqzPfYX.d.ts} +17 -23
- package/package.json +24 -7
- package/src/ShareSheetContent.tsx +157 -311
- package/src/ShareSheetDrawer.tsx +2 -4
- package/src/__tests__/hooks.test.ts +203 -0
- package/src/__tests__/og-fetcher.test.ts +144 -0
- package/src/__tests__/platforms.test.ts +148 -0
- package/src/__tests__/setup.ts +22 -0
- package/src/__tests__/share-functions.test.ts +152 -0
- package/src/__tests__/utils.test.ts +64 -0
- package/src/headless.ts +4 -1
- package/src/hooks.ts +60 -2
- package/src/index.ts +20 -4
- package/src/og-fetcher.ts +64 -0
- package/src/share-functions.ts +25 -1
- package/src/types.ts +17 -24
- package/src/utils.ts +125 -0
package/dist/content.js
CHANGED
|
@@ -47,10 +47,111 @@ function openUrl(url) {
|
|
|
47
47
|
function getSafeUrl(shareUrl) {
|
|
48
48
|
return shareUrl || (typeof window !== "undefined" ? window.location.href : "");
|
|
49
49
|
}
|
|
50
|
+
function isMobileDevice() {
|
|
51
|
+
if (typeof navigator === "undefined") return false;
|
|
52
|
+
const userAgent = navigator.userAgent || navigator.vendor || "";
|
|
53
|
+
const mobileRegex = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini|Mobile|mobile|CriOS/i;
|
|
54
|
+
const hasTouch = typeof window !== "undefined" && ("ontouchstart" in window || navigator.maxTouchPoints > 0);
|
|
55
|
+
return mobileRegex.test(userAgent);
|
|
56
|
+
}
|
|
57
|
+
var MOBILE_ONLY_PLATFORMS = [
|
|
58
|
+
"instagram",
|
|
59
|
+
"tiktok",
|
|
60
|
+
"threads",
|
|
61
|
+
"sms"
|
|
62
|
+
];
|
|
63
|
+
function checkPlatformAvailability(platform) {
|
|
64
|
+
const isMobile = isMobileDevice();
|
|
65
|
+
if (MOBILE_ONLY_PLATFORMS.includes(platform)) {
|
|
66
|
+
if (!isMobile) {
|
|
67
|
+
return {
|
|
68
|
+
available: false,
|
|
69
|
+
reason: `${platform} requires a mobile device with the app installed`
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (platform === "sms" && !isMobile) {
|
|
74
|
+
return {
|
|
75
|
+
available: false,
|
|
76
|
+
reason: "SMS sharing requires a mobile device"
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
if (platform === "native") {
|
|
80
|
+
const canShare = typeof navigator !== "undefined" && "share" in navigator;
|
|
81
|
+
if (!canShare) {
|
|
82
|
+
return {
|
|
83
|
+
available: false,
|
|
84
|
+
reason: "Native share is not supported by this browser"
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return { available: true };
|
|
89
|
+
}
|
|
90
|
+
function getAllPlatformAvailability() {
|
|
91
|
+
const platforms = [
|
|
92
|
+
"native",
|
|
93
|
+
"copy",
|
|
94
|
+
"download",
|
|
95
|
+
"whatsapp",
|
|
96
|
+
"telegram",
|
|
97
|
+
"instagram",
|
|
98
|
+
"facebook",
|
|
99
|
+
"snapchat",
|
|
100
|
+
"sms",
|
|
101
|
+
"email",
|
|
102
|
+
"linkedin",
|
|
103
|
+
"reddit",
|
|
104
|
+
"x",
|
|
105
|
+
"tiktok",
|
|
106
|
+
"threads"
|
|
107
|
+
];
|
|
108
|
+
const result = {};
|
|
109
|
+
for (const platform of platforms) {
|
|
110
|
+
result[platform] = checkPlatformAvailability(platform);
|
|
111
|
+
}
|
|
112
|
+
return result;
|
|
113
|
+
}
|
|
114
|
+
function warnUnavailablePlatform(platform, reason) {
|
|
115
|
+
console.warn(
|
|
116
|
+
`[react-sharesheet] ${platform} sharing is not available: ${reason}. This share option may not work correctly on this device.`
|
|
117
|
+
);
|
|
118
|
+
}
|
|
50
119
|
|
|
51
120
|
// src/hooks.ts
|
|
52
121
|
var import_react = require("react");
|
|
53
122
|
|
|
123
|
+
// src/og-fetcher.ts
|
|
124
|
+
var ogCache = /* @__PURE__ */ new Map();
|
|
125
|
+
async function fetchOGData(url) {
|
|
126
|
+
if (ogCache.has(url)) {
|
|
127
|
+
return ogCache.get(url);
|
|
128
|
+
}
|
|
129
|
+
try {
|
|
130
|
+
const apiUrl = `https://api.microlink.io?url=${encodeURIComponent(url)}`;
|
|
131
|
+
const response = await fetch(apiUrl);
|
|
132
|
+
if (!response.ok) {
|
|
133
|
+
throw new Error(`Failed to fetch OG data: ${response.status}`);
|
|
134
|
+
}
|
|
135
|
+
const json = await response.json();
|
|
136
|
+
if (json.status !== "success" || !json.data) {
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
const { title, description, image, url: canonicalUrl, publisher } = json.data;
|
|
140
|
+
const ogData = {
|
|
141
|
+
title: title || void 0,
|
|
142
|
+
description: description || void 0,
|
|
143
|
+
image: image?.url || void 0,
|
|
144
|
+
url: canonicalUrl || url,
|
|
145
|
+
siteName: publisher || void 0
|
|
146
|
+
};
|
|
147
|
+
ogCache.set(url, ogData);
|
|
148
|
+
return ogData;
|
|
149
|
+
} catch (error) {
|
|
150
|
+
console.warn("[react-sharesheet] Failed to fetch OG data:", error);
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
54
155
|
// src/share-functions.ts
|
|
55
156
|
function shareToWhatsApp(url, text) {
|
|
56
157
|
const encoded = encodeURIComponent(`${text}
|
|
@@ -72,12 +173,24 @@ function shareToFacebook(url) {
|
|
|
72
173
|
openUrl(`https://www.facebook.com/sharer/sharer.php?u=${encodedUrl}`);
|
|
73
174
|
}
|
|
74
175
|
function openInstagram() {
|
|
176
|
+
const availability = checkPlatformAvailability("instagram");
|
|
177
|
+
if (!availability.available) {
|
|
178
|
+
warnUnavailablePlatform("instagram", availability.reason);
|
|
179
|
+
}
|
|
75
180
|
window.location.href = "instagram://";
|
|
76
181
|
}
|
|
77
182
|
function openTikTok() {
|
|
183
|
+
const availability = checkPlatformAvailability("tiktok");
|
|
184
|
+
if (!availability.available) {
|
|
185
|
+
warnUnavailablePlatform("tiktok", availability.reason);
|
|
186
|
+
}
|
|
78
187
|
window.location.href = "tiktok://";
|
|
79
188
|
}
|
|
80
189
|
function openThreads() {
|
|
190
|
+
const availability = checkPlatformAvailability("threads");
|
|
191
|
+
if (!availability.available) {
|
|
192
|
+
warnUnavailablePlatform("threads", availability.reason);
|
|
193
|
+
}
|
|
81
194
|
window.location.href = "threads://";
|
|
82
195
|
}
|
|
83
196
|
function shareToSnapchat(url) {
|
|
@@ -85,6 +198,10 @@ function shareToSnapchat(url) {
|
|
|
85
198
|
openUrl(`https://www.snapchat.com/scan?attachmentUrl=${encodedUrl}`);
|
|
86
199
|
}
|
|
87
200
|
function shareViaSMS(url, text) {
|
|
201
|
+
const availability = checkPlatformAvailability("sms");
|
|
202
|
+
if (!availability.available) {
|
|
203
|
+
warnUnavailablePlatform("sms", availability.reason);
|
|
204
|
+
}
|
|
88
205
|
const body = encodeURIComponent(`${text}
|
|
89
206
|
${url}`);
|
|
90
207
|
window.location.href = `sms:?body=${body}`;
|
|
@@ -122,6 +239,12 @@ function useShareSheet({
|
|
|
122
239
|
const canNativeShare = (0, import_react.useMemo)(() => {
|
|
123
240
|
return typeof navigator !== "undefined" && "share" in navigator;
|
|
124
241
|
}, []);
|
|
242
|
+
const isMobile = (0, import_react.useMemo)(() => {
|
|
243
|
+
return isMobileDevice();
|
|
244
|
+
}, []);
|
|
245
|
+
const platformAvailability = (0, import_react.useMemo)(() => {
|
|
246
|
+
return getAllPlatformAvailability();
|
|
247
|
+
}, []);
|
|
125
248
|
const safeUrl = getSafeUrl(shareUrl);
|
|
126
249
|
const copyLink = (0, import_react.useCallback)(async () => {
|
|
127
250
|
if (!safeUrl) return;
|
|
@@ -210,6 +333,8 @@ function useShareSheet({
|
|
|
210
333
|
copied,
|
|
211
334
|
downloading,
|
|
212
335
|
safeUrl,
|
|
336
|
+
isMobile,
|
|
337
|
+
platformAvailability,
|
|
213
338
|
copyLink,
|
|
214
339
|
nativeShare,
|
|
215
340
|
downloadFile,
|
|
@@ -227,6 +352,37 @@ function useShareSheet({
|
|
|
227
352
|
shareReddit
|
|
228
353
|
};
|
|
229
354
|
}
|
|
355
|
+
function useOGData(url) {
|
|
356
|
+
const [ogData, setOgData] = (0, import_react.useState)(null);
|
|
357
|
+
const [loading, setLoading] = (0, import_react.useState)(false);
|
|
358
|
+
const [error, setError] = (0, import_react.useState)(null);
|
|
359
|
+
(0, import_react.useEffect)(() => {
|
|
360
|
+
if (!url) {
|
|
361
|
+
setOgData(null);
|
|
362
|
+
setLoading(false);
|
|
363
|
+
setError(null);
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
let cancelled = false;
|
|
367
|
+
setLoading(true);
|
|
368
|
+
setError(null);
|
|
369
|
+
fetchOGData(url).then((data) => {
|
|
370
|
+
if (!cancelled) {
|
|
371
|
+
setOgData(data);
|
|
372
|
+
setLoading(false);
|
|
373
|
+
}
|
|
374
|
+
}).catch((err) => {
|
|
375
|
+
if (!cancelled) {
|
|
376
|
+
setError(err instanceof Error ? err.message : "Failed to fetch OG data");
|
|
377
|
+
setLoading(false);
|
|
378
|
+
}
|
|
379
|
+
});
|
|
380
|
+
return () => {
|
|
381
|
+
cancelled = true;
|
|
382
|
+
};
|
|
383
|
+
}, [url]);
|
|
384
|
+
return { ogData, loading, error };
|
|
385
|
+
}
|
|
230
386
|
|
|
231
387
|
// src/platforms.tsx
|
|
232
388
|
var import_lucide_react = require("lucide-react");
|
|
@@ -364,32 +520,6 @@ var CSS_VAR_DEFAULTS = CSS_VAR_UI_DEFAULTS;
|
|
|
364
520
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
365
521
|
var DEFAULT_BUTTON_SIZE = 45;
|
|
366
522
|
var DEFAULT_ICON_SIZE = 22;
|
|
367
|
-
var IMAGE_EXTENSIONS = ["jpg", "jpeg", "png", "gif", "webp", "svg", "bmp", "ico", "avif"];
|
|
368
|
-
var VIDEO_EXTENSIONS = ["mp4", "webm", "mov", "avi", "mkv", "m4v", "ogv"];
|
|
369
|
-
var AUDIO_EXTENSIONS = ["mp3", "wav", "ogg", "m4a", "aac", "flac", "wma"];
|
|
370
|
-
function detectPreviewType(url) {
|
|
371
|
-
try {
|
|
372
|
-
const pathname = new URL(url, "http://localhost").pathname;
|
|
373
|
-
const ext = pathname.split(".").pop()?.toLowerCase() || "";
|
|
374
|
-
if (IMAGE_EXTENSIONS.includes(ext)) return "image";
|
|
375
|
-
if (VIDEO_EXTENSIONS.includes(ext)) return "video";
|
|
376
|
-
if (AUDIO_EXTENSIONS.includes(ext)) return "audio";
|
|
377
|
-
if (url.includes("/api/og") || url.includes("og-image")) return "image";
|
|
378
|
-
if (url.includes("youtube.com") || url.includes("vimeo.com")) return "video";
|
|
379
|
-
return "link";
|
|
380
|
-
} catch {
|
|
381
|
-
return "link";
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
function getFilenameFromUrl(url) {
|
|
385
|
-
try {
|
|
386
|
-
const pathname = new URL(url, "http://localhost").pathname;
|
|
387
|
-
const filename = pathname.split("/").pop() || "";
|
|
388
|
-
return decodeURIComponent(filename);
|
|
389
|
-
} catch {
|
|
390
|
-
return url;
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
523
|
var defaultClasses = {
|
|
394
524
|
root: "max-w-md mx-auto",
|
|
395
525
|
header: "text-center mb-2",
|
|
@@ -398,12 +528,8 @@ var defaultClasses = {
|
|
|
398
528
|
preview: "flex justify-center mb-4 px-4",
|
|
399
529
|
previewSkeleton: "rounded-xl overflow-hidden",
|
|
400
530
|
previewImage: "",
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
previewFileIcon: "",
|
|
404
|
-
previewFilename: "truncate",
|
|
405
|
-
previewLink: "",
|
|
406
|
-
grid: "px-2 py-6 flex flex-row items-center gap-4 gap-y-6 flex-wrap justify-center",
|
|
531
|
+
previewMeta: "",
|
|
532
|
+
grid: "px-2 py-6 flex flex-row items-start gap-4 gap-y-6 flex-wrap justify-center",
|
|
407
533
|
button: "flex flex-col items-center gap-0 text-xs w-[60px] outline-none cursor-pointer group",
|
|
408
534
|
buttonIcon: "p-2 rounded-full transition-all flex items-center justify-center group-hover:scale-110 group-active:scale-95 mb-2",
|
|
409
535
|
buttonLabel: ""
|
|
@@ -417,28 +543,10 @@ var shimmerKeyframes = `
|
|
|
417
543
|
function cssVar(name, fallback) {
|
|
418
544
|
return `var(${name}, ${fallback})`;
|
|
419
545
|
}
|
|
420
|
-
function normalizePreview(preview) {
|
|
421
|
-
if (!preview) return null;
|
|
422
|
-
if (typeof preview === "string") {
|
|
423
|
-
const type2 = detectPreviewType(preview);
|
|
424
|
-
return {
|
|
425
|
-
url: preview,
|
|
426
|
-
type: type2,
|
|
427
|
-
filename: getFilenameFromUrl(preview)
|
|
428
|
-
};
|
|
429
|
-
}
|
|
430
|
-
const type = preview.type === "auto" || !preview.type ? detectPreviewType(preview.url) : preview.type;
|
|
431
|
-
return {
|
|
432
|
-
...preview,
|
|
433
|
-
type,
|
|
434
|
-
filename: preview.filename || getFilenameFromUrl(preview.url)
|
|
435
|
-
};
|
|
436
|
-
}
|
|
437
546
|
function ShareSheetContent({
|
|
438
547
|
title = "Share",
|
|
439
548
|
shareUrl,
|
|
440
549
|
shareText,
|
|
441
|
-
preview,
|
|
442
550
|
downloadUrl,
|
|
443
551
|
downloadFilename,
|
|
444
552
|
className,
|
|
@@ -453,15 +561,15 @@ function ShareSheetContent({
|
|
|
453
561
|
labels = {},
|
|
454
562
|
icons = {}
|
|
455
563
|
}) {
|
|
456
|
-
const [
|
|
457
|
-
const [
|
|
458
|
-
const
|
|
459
|
-
|
|
564
|
+
const [imageLoaded, setImageLoaded] = (0, import_react2.useState)(false);
|
|
565
|
+
const [imageError, setImageError] = (0, import_react2.useState)(false);
|
|
566
|
+
const { ogData, loading: ogLoading } = useOGData(shareUrl);
|
|
567
|
+
const handleImageLoad = (0, import_react2.useCallback)(() => {
|
|
568
|
+
setImageLoaded(true);
|
|
460
569
|
}, []);
|
|
461
|
-
const
|
|
462
|
-
|
|
570
|
+
const handleImageError = (0, import_react2.useCallback)(() => {
|
|
571
|
+
setImageError(true);
|
|
463
572
|
}, []);
|
|
464
|
-
const previewConfig = (0, import_react2.useMemo)(() => normalizePreview(preview), [preview]);
|
|
465
573
|
const shareSheet = useShareSheet({
|
|
466
574
|
shareUrl,
|
|
467
575
|
shareText,
|
|
@@ -497,6 +605,15 @@ function ShareSheetContent({
|
|
|
497
605
|
return PLATFORM_IDS.map((id) => {
|
|
498
606
|
const Icon = PLATFORM_ICONS[id];
|
|
499
607
|
const defaultLabel = dynamicLabels[id] ?? PLATFORM_LABELS[id];
|
|
608
|
+
const availability = shareSheet.platformAvailability[id];
|
|
609
|
+
let condition = true;
|
|
610
|
+
if (id === "native") {
|
|
611
|
+
condition = shareSheet.canNativeShare;
|
|
612
|
+
} else if (id === "download") {
|
|
613
|
+
condition = !!downloadUrl;
|
|
614
|
+
} else if (!availability.available) {
|
|
615
|
+
condition = false;
|
|
616
|
+
}
|
|
500
617
|
return {
|
|
501
618
|
id,
|
|
502
619
|
label: labels[id] ?? defaultLabel,
|
|
@@ -505,11 +622,10 @@ function ShareSheetContent({
|
|
|
505
622
|
bgColor: cssVar(PLATFORM_CSS_VARS[id], PLATFORM_COLORS[id].bg),
|
|
506
623
|
textColor: PLATFORM_COLORS[id].text,
|
|
507
624
|
onClick: shareActions[id],
|
|
508
|
-
|
|
509
|
-
condition: id === "native" ? shareSheet.canNativeShare : id === "download" ? !!downloadUrl : true
|
|
625
|
+
condition
|
|
510
626
|
};
|
|
511
627
|
});
|
|
512
|
-
}, [iconSize, labels, icons, dynamicLabels, shareActions, shareSheet.canNativeShare, downloadUrl]);
|
|
628
|
+
}, [iconSize, labels, icons, dynamicLabels, shareActions, shareSheet.canNativeShare, shareSheet.platformAvailability, downloadUrl]);
|
|
513
629
|
const visibleButtons = (0, import_react2.useMemo)(() => {
|
|
514
630
|
return buttons.filter((btn) => {
|
|
515
631
|
if (btn.condition === false) return false;
|
|
@@ -518,49 +634,30 @@ function ShareSheetContent({
|
|
|
518
634
|
return true;
|
|
519
635
|
});
|
|
520
636
|
}, [buttons, show, hide]);
|
|
521
|
-
const
|
|
637
|
+
const bgColor = cssVar(CSS_VARS_UI.previewBg, CSS_VAR_UI_DEFAULTS[CSS_VARS_UI.previewBg]);
|
|
638
|
+
const shimmerColor = cssVar(CSS_VARS_UI.previewShimmer, CSS_VAR_UI_DEFAULTS[CSS_VARS_UI.previewShimmer]);
|
|
639
|
+
const textColor = cssVar(CSS_VARS_UI.subtitleColor, CSS_VAR_UI_DEFAULTS[CSS_VARS_UI.subtitleColor]);
|
|
522
640
|
const renderPreview = () => {
|
|
523
|
-
|
|
524
|
-
const
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
const textColor = cssVar(CSS_VARS_UI.subtitleColor, CSS_VAR_UI_DEFAULTS[CSS_VARS_UI.subtitleColor]);
|
|
528
|
-
const UrlLabel = ({ displayUrl = url }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
529
|
-
"div",
|
|
530
|
-
{
|
|
531
|
-
className: cn(defaultClasses.previewFilename, classNames.previewFilename),
|
|
532
|
-
style: {
|
|
533
|
-
color: textColor,
|
|
534
|
-
fontSize: "10px",
|
|
535
|
-
opacity: 0.5,
|
|
536
|
-
textAlign: "center",
|
|
537
|
-
marginTop: "6px"
|
|
538
|
-
},
|
|
539
|
-
children: displayUrl
|
|
540
|
-
}
|
|
541
|
-
);
|
|
542
|
-
const PlaceholderCard = ({
|
|
543
|
-
icon: IconComponent,
|
|
544
|
-
isLoading = false,
|
|
545
|
-
label,
|
|
546
|
-
displayUrl
|
|
547
|
-
}) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", flexDirection: "column", alignItems: "center" }, children: [
|
|
548
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
641
|
+
const ogImage = ogData?.image;
|
|
642
|
+
const hasImage = ogImage && !imageError;
|
|
643
|
+
if (ogLoading) {
|
|
644
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", width: "100%" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
549
645
|
"div",
|
|
550
646
|
{
|
|
551
647
|
className: cn(defaultClasses.previewSkeleton, classNames.previewSkeleton),
|
|
552
648
|
style: {
|
|
553
649
|
position: "relative",
|
|
554
650
|
backgroundColor: bgColor,
|
|
555
|
-
width: "
|
|
556
|
-
|
|
651
|
+
width: "100%",
|
|
652
|
+
maxWidth: "320px",
|
|
653
|
+
aspectRatio: "1.91 / 1",
|
|
557
654
|
overflow: "hidden",
|
|
558
655
|
display: "flex",
|
|
559
656
|
alignItems: "center",
|
|
560
657
|
justifyContent: "center"
|
|
561
658
|
},
|
|
562
659
|
children: [
|
|
563
|
-
|
|
660
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { position: "absolute", inset: 0, overflow: "hidden" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
564
661
|
"div",
|
|
565
662
|
{
|
|
566
663
|
style: {
|
|
@@ -571,197 +668,125 @@ function ShareSheetContent({
|
|
|
571
668
|
}
|
|
572
669
|
}
|
|
573
670
|
) }),
|
|
574
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.
|
|
575
|
-
"div",
|
|
576
|
-
{
|
|
577
|
-
style: {
|
|
578
|
-
display: "flex",
|
|
579
|
-
flexDirection: "column",
|
|
580
|
-
alignItems: "center",
|
|
581
|
-
justifyContent: "center",
|
|
582
|
-
gap: "8px"
|
|
583
|
-
},
|
|
584
|
-
children: [
|
|
585
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconComponent, { size: 32, style: { color: textColor, opacity: 0.4 } }),
|
|
586
|
-
label && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { color: textColor, fontSize: "11px", opacity: 0.4 }, children: label })
|
|
587
|
-
]
|
|
588
|
-
}
|
|
589
|
-
)
|
|
671
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.Link2, { size: 32, style: { color: textColor, opacity: 0.4 } })
|
|
590
672
|
]
|
|
591
673
|
}
|
|
592
|
-
)
|
|
593
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(UrlLabel, { displayUrl })
|
|
594
|
-
] });
|
|
595
|
-
if (mediaError && (type === "image" || type === "video")) {
|
|
596
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PlaceholderCard, { icon: import_lucide_react2.Link2, displayUrl: url });
|
|
674
|
+
) });
|
|
597
675
|
}
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
children: [
|
|
617
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { position: "absolute", inset: 0, overflow: "hidden" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
618
|
-
"div",
|
|
619
|
-
{
|
|
620
|
-
style: {
|
|
621
|
-
position: "absolute",
|
|
622
|
-
inset: 0,
|
|
623
|
-
background: `linear-gradient(90deg, transparent, ${shimmerColor}, transparent)`,
|
|
624
|
-
animation: "sharesheet-shimmer 1.5s infinite"
|
|
625
|
-
}
|
|
626
|
-
}
|
|
627
|
-
) }),
|
|
628
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.Image, { size: 32, style: { color: textColor, opacity: 0.4 } })
|
|
629
|
-
]
|
|
630
|
-
}
|
|
631
|
-
),
|
|
632
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(UrlLabel, {}),
|
|
633
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
634
|
-
"img",
|
|
635
|
-
{
|
|
636
|
-
src: url,
|
|
637
|
-
alt: alt || "Preview",
|
|
638
|
-
onLoad: handleMediaLoad,
|
|
639
|
-
onError: handleMediaError,
|
|
640
|
-
style: { display: "none" }
|
|
641
|
-
}
|
|
642
|
-
)
|
|
643
|
-
] });
|
|
644
|
-
}
|
|
645
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", flexDirection: "column", alignItems: "center" }, children: [
|
|
646
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
647
|
-
"img",
|
|
676
|
+
if (!ogData || !hasImage) {
|
|
677
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", width: "100%" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
678
|
+
"div",
|
|
679
|
+
{
|
|
680
|
+
className: cn(defaultClasses.previewSkeleton, classNames.previewSkeleton),
|
|
681
|
+
style: {
|
|
682
|
+
position: "relative",
|
|
683
|
+
backgroundColor: bgColor,
|
|
684
|
+
width: "100%",
|
|
685
|
+
maxWidth: "320px",
|
|
686
|
+
aspectRatio: "1.91 / 1",
|
|
687
|
+
overflow: "hidden",
|
|
688
|
+
display: "flex",
|
|
689
|
+
alignItems: "center",
|
|
690
|
+
justifyContent: "center"
|
|
691
|
+
},
|
|
692
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
693
|
+
"div",
|
|
648
694
|
{
|
|
649
|
-
src: url,
|
|
650
|
-
alt: alt || "Preview",
|
|
651
|
-
className: cn(defaultClasses.previewImage, classNames.previewImage),
|
|
652
695
|
style: {
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
if (!mediaLoaded) {
|
|
665
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", flexDirection: "column", alignItems: "center" }, children: [
|
|
666
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
667
|
-
"div",
|
|
668
|
-
{
|
|
669
|
-
className: cn(defaultClasses.previewSkeleton, classNames.previewSkeleton),
|
|
670
|
-
style: {
|
|
671
|
-
position: "relative",
|
|
672
|
-
backgroundColor: bgColor,
|
|
673
|
-
width: "200px",
|
|
674
|
-
height: "120px",
|
|
675
|
-
overflow: "hidden",
|
|
676
|
-
display: "flex",
|
|
677
|
-
alignItems: "center",
|
|
678
|
-
justifyContent: "center"
|
|
679
|
-
},
|
|
680
|
-
children: [
|
|
681
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { position: "absolute", inset: 0, overflow: "hidden" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
682
|
-
"div",
|
|
683
|
-
{
|
|
684
|
-
style: {
|
|
685
|
-
position: "absolute",
|
|
686
|
-
inset: 0,
|
|
687
|
-
background: `linear-gradient(90deg, transparent, ${shimmerColor}, transparent)`,
|
|
688
|
-
animation: "sharesheet-shimmer 1.5s infinite"
|
|
689
|
-
}
|
|
690
|
-
}
|
|
691
|
-
) }),
|
|
692
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.Film, { size: 32, style: { color: textColor, opacity: 0.4 } })
|
|
693
|
-
]
|
|
694
|
-
}
|
|
695
|
-
),
|
|
696
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(UrlLabel, {}),
|
|
697
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
698
|
-
"video",
|
|
699
|
-
{
|
|
700
|
-
src: url,
|
|
701
|
-
poster,
|
|
702
|
-
onLoadedData: handleMediaLoad,
|
|
703
|
-
onError: handleMediaError,
|
|
704
|
-
style: { display: "none" },
|
|
705
|
-
muted: true,
|
|
706
|
-
playsInline: true,
|
|
707
|
-
preload: "metadata"
|
|
708
|
-
}
|
|
709
|
-
)
|
|
710
|
-
] });
|
|
711
|
-
}
|
|
712
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", flexDirection: "column", alignItems: "center" }, children: [
|
|
713
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { position: "relative", borderRadius: "12px", overflow: "hidden" }, children: [
|
|
714
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
715
|
-
"video",
|
|
716
|
-
{
|
|
717
|
-
src: url,
|
|
718
|
-
poster,
|
|
719
|
-
className: cn(defaultClasses.previewVideo, classNames.previewVideo),
|
|
720
|
-
style: {
|
|
721
|
-
maxWidth: "100%",
|
|
722
|
-
maxHeight: "180px",
|
|
723
|
-
display: "block"
|
|
724
|
-
},
|
|
725
|
-
muted: true,
|
|
726
|
-
playsInline: true,
|
|
727
|
-
preload: "metadata"
|
|
728
|
-
}
|
|
729
|
-
),
|
|
730
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
731
|
-
"div",
|
|
732
|
-
{
|
|
733
|
-
style: {
|
|
734
|
-
position: "absolute",
|
|
735
|
-
inset: 0,
|
|
736
|
-
display: "flex",
|
|
737
|
-
alignItems: "center",
|
|
738
|
-
justifyContent: "center",
|
|
739
|
-
pointerEvents: "none"
|
|
740
|
-
},
|
|
741
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
742
|
-
"div",
|
|
696
|
+
display: "flex",
|
|
697
|
+
flexDirection: "column",
|
|
698
|
+
alignItems: "center",
|
|
699
|
+
justifyContent: "center",
|
|
700
|
+
gap: "8px",
|
|
701
|
+
padding: "16px"
|
|
702
|
+
},
|
|
703
|
+
children: [
|
|
704
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.Link2, { size: 32, style: { color: textColor, opacity: 0.4 } }),
|
|
705
|
+
ogData?.title && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
706
|
+
"span",
|
|
743
707
|
{
|
|
744
708
|
style: {
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
709
|
+
color: textColor,
|
|
710
|
+
fontSize: "12px",
|
|
711
|
+
opacity: 0.6,
|
|
712
|
+
textAlign: "center",
|
|
713
|
+
maxWidth: "280px",
|
|
714
|
+
overflow: "hidden",
|
|
715
|
+
textOverflow: "ellipsis",
|
|
716
|
+
display: "-webkit-box",
|
|
717
|
+
WebkitLineClamp: 2,
|
|
718
|
+
WebkitBoxOrient: "vertical"
|
|
748
719
|
},
|
|
749
|
-
children:
|
|
720
|
+
children: ogData.title
|
|
750
721
|
}
|
|
751
722
|
)
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
case "audio":
|
|
758
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PlaceholderCard, { icon: import_lucide_react2.Music, label: filename || "Audio", displayUrl: url });
|
|
759
|
-
case "file":
|
|
760
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PlaceholderCard, { icon: import_lucide_react2.FileText, label: filename || "File", displayUrl: url });
|
|
761
|
-
case "link":
|
|
762
|
-
default:
|
|
763
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PlaceholderCard, { icon: import_lucide_react2.Link2, displayUrl: url });
|
|
723
|
+
]
|
|
724
|
+
}
|
|
725
|
+
)
|
|
726
|
+
}
|
|
727
|
+
) });
|
|
764
728
|
}
|
|
729
|
+
if (!imageLoaded) {
|
|
730
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", width: "100%" }, children: [
|
|
731
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
732
|
+
"div",
|
|
733
|
+
{
|
|
734
|
+
className: cn(defaultClasses.previewSkeleton, classNames.previewSkeleton),
|
|
735
|
+
style: {
|
|
736
|
+
position: "relative",
|
|
737
|
+
backgroundColor: bgColor,
|
|
738
|
+
width: "100%",
|
|
739
|
+
maxWidth: "320px",
|
|
740
|
+
aspectRatio: "1.91 / 1",
|
|
741
|
+
overflow: "hidden",
|
|
742
|
+
display: "flex",
|
|
743
|
+
alignItems: "center",
|
|
744
|
+
justifyContent: "center"
|
|
745
|
+
},
|
|
746
|
+
children: [
|
|
747
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { position: "absolute", inset: 0, overflow: "hidden" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
748
|
+
"div",
|
|
749
|
+
{
|
|
750
|
+
style: {
|
|
751
|
+
position: "absolute",
|
|
752
|
+
inset: 0,
|
|
753
|
+
background: `linear-gradient(90deg, transparent, ${shimmerColor}, transparent)`,
|
|
754
|
+
animation: "sharesheet-shimmer 1.5s infinite"
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
) }),
|
|
758
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.Image, { size: 32, style: { color: textColor, opacity: 0.4 } })
|
|
759
|
+
]
|
|
760
|
+
}
|
|
761
|
+
),
|
|
762
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
763
|
+
"img",
|
|
764
|
+
{
|
|
765
|
+
src: ogImage,
|
|
766
|
+
alt: ogData.title || "Preview",
|
|
767
|
+
onLoad: handleImageLoad,
|
|
768
|
+
onError: handleImageError,
|
|
769
|
+
style: { display: "none" }
|
|
770
|
+
}
|
|
771
|
+
)
|
|
772
|
+
] });
|
|
773
|
+
}
|
|
774
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", width: "100%" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
775
|
+
"img",
|
|
776
|
+
{
|
|
777
|
+
src: ogImage,
|
|
778
|
+
alt: ogData.title || "Preview",
|
|
779
|
+
className: cn(defaultClasses.previewImage, classNames.previewImage),
|
|
780
|
+
style: {
|
|
781
|
+
width: "100%",
|
|
782
|
+
maxWidth: "320px",
|
|
783
|
+
height: "auto",
|
|
784
|
+
borderRadius: "12px",
|
|
785
|
+
opacity: 1,
|
|
786
|
+
transition: "opacity 0.3s ease-in-out"
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
) });
|
|
765
790
|
};
|
|
766
791
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: cn(defaultClasses.root, classNames.root, className), children: [
|
|
767
792
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("style", { dangerouslySetInnerHTML: { __html: shimmerKeyframes } }),
|
|
@@ -783,7 +808,7 @@ function ShareSheetContent({
|
|
|
783
808
|
}
|
|
784
809
|
)
|
|
785
810
|
] }),
|
|
786
|
-
|
|
811
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: cn(defaultClasses.preview, classNames.preview), children: renderPreview() }),
|
|
787
812
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: cn(defaultClasses.grid, classNames.grid), children: visibleButtons.map((btn) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
788
813
|
"button",
|
|
789
814
|
{
|