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.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/ShareSheetContent.tsx
|
|
2
2
|
import { useMemo as useMemo2, useState as useState2, useCallback as useCallback2 } from "react";
|
|
3
|
-
import { Image,
|
|
3
|
+
import { Image, Link2 } from "lucide-react";
|
|
4
4
|
|
|
5
5
|
// src/utils.ts
|
|
6
6
|
import { clsx } from "clsx";
|
|
@@ -14,9 +14,110 @@ function openUrl(url) {
|
|
|
14
14
|
function getSafeUrl(shareUrl) {
|
|
15
15
|
return shareUrl || (typeof window !== "undefined" ? window.location.href : "");
|
|
16
16
|
}
|
|
17
|
+
function isMobileDevice() {
|
|
18
|
+
if (typeof navigator === "undefined") return false;
|
|
19
|
+
const userAgent = navigator.userAgent || navigator.vendor || "";
|
|
20
|
+
const mobileRegex = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini|Mobile|mobile|CriOS/i;
|
|
21
|
+
const hasTouch = typeof window !== "undefined" && ("ontouchstart" in window || navigator.maxTouchPoints > 0);
|
|
22
|
+
return mobileRegex.test(userAgent);
|
|
23
|
+
}
|
|
24
|
+
var MOBILE_ONLY_PLATFORMS = [
|
|
25
|
+
"instagram",
|
|
26
|
+
"tiktok",
|
|
27
|
+
"threads",
|
|
28
|
+
"sms"
|
|
29
|
+
];
|
|
30
|
+
function checkPlatformAvailability(platform) {
|
|
31
|
+
const isMobile = isMobileDevice();
|
|
32
|
+
if (MOBILE_ONLY_PLATFORMS.includes(platform)) {
|
|
33
|
+
if (!isMobile) {
|
|
34
|
+
return {
|
|
35
|
+
available: false,
|
|
36
|
+
reason: `${platform} requires a mobile device with the app installed`
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
if (platform === "sms" && !isMobile) {
|
|
41
|
+
return {
|
|
42
|
+
available: false,
|
|
43
|
+
reason: "SMS sharing requires a mobile device"
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
if (platform === "native") {
|
|
47
|
+
const canShare = typeof navigator !== "undefined" && "share" in navigator;
|
|
48
|
+
if (!canShare) {
|
|
49
|
+
return {
|
|
50
|
+
available: false,
|
|
51
|
+
reason: "Native share is not supported by this browser"
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return { available: true };
|
|
56
|
+
}
|
|
57
|
+
function getAllPlatformAvailability() {
|
|
58
|
+
const platforms = [
|
|
59
|
+
"native",
|
|
60
|
+
"copy",
|
|
61
|
+
"download",
|
|
62
|
+
"whatsapp",
|
|
63
|
+
"telegram",
|
|
64
|
+
"instagram",
|
|
65
|
+
"facebook",
|
|
66
|
+
"snapchat",
|
|
67
|
+
"sms",
|
|
68
|
+
"email",
|
|
69
|
+
"linkedin",
|
|
70
|
+
"reddit",
|
|
71
|
+
"x",
|
|
72
|
+
"tiktok",
|
|
73
|
+
"threads"
|
|
74
|
+
];
|
|
75
|
+
const result = {};
|
|
76
|
+
for (const platform of platforms) {
|
|
77
|
+
result[platform] = checkPlatformAvailability(platform);
|
|
78
|
+
}
|
|
79
|
+
return result;
|
|
80
|
+
}
|
|
81
|
+
function warnUnavailablePlatform(platform, reason) {
|
|
82
|
+
console.warn(
|
|
83
|
+
`[react-sharesheet] ${platform} sharing is not available: ${reason}. This share option may not work correctly on this device.`
|
|
84
|
+
);
|
|
85
|
+
}
|
|
17
86
|
|
|
18
87
|
// src/hooks.ts
|
|
19
|
-
import { useMemo, useState, useCallback } from "react";
|
|
88
|
+
import { useMemo, useState, useCallback, useEffect } from "react";
|
|
89
|
+
|
|
90
|
+
// src/og-fetcher.ts
|
|
91
|
+
var ogCache = /* @__PURE__ */ new Map();
|
|
92
|
+
async function fetchOGData(url) {
|
|
93
|
+
if (ogCache.has(url)) {
|
|
94
|
+
return ogCache.get(url);
|
|
95
|
+
}
|
|
96
|
+
try {
|
|
97
|
+
const apiUrl = `https://api.microlink.io?url=${encodeURIComponent(url)}`;
|
|
98
|
+
const response = await fetch(apiUrl);
|
|
99
|
+
if (!response.ok) {
|
|
100
|
+
throw new Error(`Failed to fetch OG data: ${response.status}`);
|
|
101
|
+
}
|
|
102
|
+
const json = await response.json();
|
|
103
|
+
if (json.status !== "success" || !json.data) {
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
const { title, description, image, url: canonicalUrl, publisher } = json.data;
|
|
107
|
+
const ogData = {
|
|
108
|
+
title: title || void 0,
|
|
109
|
+
description: description || void 0,
|
|
110
|
+
image: image?.url || void 0,
|
|
111
|
+
url: canonicalUrl || url,
|
|
112
|
+
siteName: publisher || void 0
|
|
113
|
+
};
|
|
114
|
+
ogCache.set(url, ogData);
|
|
115
|
+
return ogData;
|
|
116
|
+
} catch (error) {
|
|
117
|
+
console.warn("[react-sharesheet] Failed to fetch OG data:", error);
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
20
121
|
|
|
21
122
|
// src/share-functions.ts
|
|
22
123
|
function shareToWhatsApp(url, text) {
|
|
@@ -39,12 +140,24 @@ function shareToFacebook(url) {
|
|
|
39
140
|
openUrl(`https://www.facebook.com/sharer/sharer.php?u=${encodedUrl}`);
|
|
40
141
|
}
|
|
41
142
|
function openInstagram() {
|
|
143
|
+
const availability = checkPlatformAvailability("instagram");
|
|
144
|
+
if (!availability.available) {
|
|
145
|
+
warnUnavailablePlatform("instagram", availability.reason);
|
|
146
|
+
}
|
|
42
147
|
window.location.href = "instagram://";
|
|
43
148
|
}
|
|
44
149
|
function openTikTok() {
|
|
150
|
+
const availability = checkPlatformAvailability("tiktok");
|
|
151
|
+
if (!availability.available) {
|
|
152
|
+
warnUnavailablePlatform("tiktok", availability.reason);
|
|
153
|
+
}
|
|
45
154
|
window.location.href = "tiktok://";
|
|
46
155
|
}
|
|
47
156
|
function openThreads() {
|
|
157
|
+
const availability = checkPlatformAvailability("threads");
|
|
158
|
+
if (!availability.available) {
|
|
159
|
+
warnUnavailablePlatform("threads", availability.reason);
|
|
160
|
+
}
|
|
48
161
|
window.location.href = "threads://";
|
|
49
162
|
}
|
|
50
163
|
function shareToSnapchat(url) {
|
|
@@ -52,6 +165,10 @@ function shareToSnapchat(url) {
|
|
|
52
165
|
openUrl(`https://www.snapchat.com/scan?attachmentUrl=${encodedUrl}`);
|
|
53
166
|
}
|
|
54
167
|
function shareViaSMS(url, text) {
|
|
168
|
+
const availability = checkPlatformAvailability("sms");
|
|
169
|
+
if (!availability.available) {
|
|
170
|
+
warnUnavailablePlatform("sms", availability.reason);
|
|
171
|
+
}
|
|
55
172
|
const body = encodeURIComponent(`${text}
|
|
56
173
|
${url}`);
|
|
57
174
|
window.location.href = `sms:?body=${body}`;
|
|
@@ -89,6 +206,12 @@ function useShareSheet({
|
|
|
89
206
|
const canNativeShare = useMemo(() => {
|
|
90
207
|
return typeof navigator !== "undefined" && "share" in navigator;
|
|
91
208
|
}, []);
|
|
209
|
+
const isMobile = useMemo(() => {
|
|
210
|
+
return isMobileDevice();
|
|
211
|
+
}, []);
|
|
212
|
+
const platformAvailability = useMemo(() => {
|
|
213
|
+
return getAllPlatformAvailability();
|
|
214
|
+
}, []);
|
|
92
215
|
const safeUrl = getSafeUrl(shareUrl);
|
|
93
216
|
const copyLink = useCallback(async () => {
|
|
94
217
|
if (!safeUrl) return;
|
|
@@ -177,6 +300,8 @@ function useShareSheet({
|
|
|
177
300
|
copied,
|
|
178
301
|
downloading,
|
|
179
302
|
safeUrl,
|
|
303
|
+
isMobile,
|
|
304
|
+
platformAvailability,
|
|
180
305
|
copyLink,
|
|
181
306
|
nativeShare,
|
|
182
307
|
downloadFile,
|
|
@@ -194,6 +319,37 @@ function useShareSheet({
|
|
|
194
319
|
shareReddit
|
|
195
320
|
};
|
|
196
321
|
}
|
|
322
|
+
function useOGData(url) {
|
|
323
|
+
const [ogData, setOgData] = useState(null);
|
|
324
|
+
const [loading, setLoading] = useState(false);
|
|
325
|
+
const [error, setError] = useState(null);
|
|
326
|
+
useEffect(() => {
|
|
327
|
+
if (!url) {
|
|
328
|
+
setOgData(null);
|
|
329
|
+
setLoading(false);
|
|
330
|
+
setError(null);
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
let cancelled = false;
|
|
334
|
+
setLoading(true);
|
|
335
|
+
setError(null);
|
|
336
|
+
fetchOGData(url).then((data) => {
|
|
337
|
+
if (!cancelled) {
|
|
338
|
+
setOgData(data);
|
|
339
|
+
setLoading(false);
|
|
340
|
+
}
|
|
341
|
+
}).catch((err) => {
|
|
342
|
+
if (!cancelled) {
|
|
343
|
+
setError(err instanceof Error ? err.message : "Failed to fetch OG data");
|
|
344
|
+
setLoading(false);
|
|
345
|
+
}
|
|
346
|
+
});
|
|
347
|
+
return () => {
|
|
348
|
+
cancelled = true;
|
|
349
|
+
};
|
|
350
|
+
}, [url]);
|
|
351
|
+
return { ogData, loading, error };
|
|
352
|
+
}
|
|
197
353
|
|
|
198
354
|
// src/platforms.tsx
|
|
199
355
|
import {
|
|
@@ -345,32 +501,6 @@ var CSS_VAR_DEFAULTS = CSS_VAR_UI_DEFAULTS;
|
|
|
345
501
|
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
346
502
|
var DEFAULT_BUTTON_SIZE = 45;
|
|
347
503
|
var DEFAULT_ICON_SIZE = 22;
|
|
348
|
-
var IMAGE_EXTENSIONS = ["jpg", "jpeg", "png", "gif", "webp", "svg", "bmp", "ico", "avif"];
|
|
349
|
-
var VIDEO_EXTENSIONS = ["mp4", "webm", "mov", "avi", "mkv", "m4v", "ogv"];
|
|
350
|
-
var AUDIO_EXTENSIONS = ["mp3", "wav", "ogg", "m4a", "aac", "flac", "wma"];
|
|
351
|
-
function detectPreviewType(url) {
|
|
352
|
-
try {
|
|
353
|
-
const pathname = new URL(url, "http://localhost").pathname;
|
|
354
|
-
const ext = pathname.split(".").pop()?.toLowerCase() || "";
|
|
355
|
-
if (IMAGE_EXTENSIONS.includes(ext)) return "image";
|
|
356
|
-
if (VIDEO_EXTENSIONS.includes(ext)) return "video";
|
|
357
|
-
if (AUDIO_EXTENSIONS.includes(ext)) return "audio";
|
|
358
|
-
if (url.includes("/api/og") || url.includes("og-image")) return "image";
|
|
359
|
-
if (url.includes("youtube.com") || url.includes("vimeo.com")) return "video";
|
|
360
|
-
return "link";
|
|
361
|
-
} catch {
|
|
362
|
-
return "link";
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
function getFilenameFromUrl(url) {
|
|
366
|
-
try {
|
|
367
|
-
const pathname = new URL(url, "http://localhost").pathname;
|
|
368
|
-
const filename = pathname.split("/").pop() || "";
|
|
369
|
-
return decodeURIComponent(filename);
|
|
370
|
-
} catch {
|
|
371
|
-
return url;
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
504
|
var defaultClasses = {
|
|
375
505
|
root: "max-w-md mx-auto",
|
|
376
506
|
header: "text-center mb-2",
|
|
@@ -379,12 +509,8 @@ var defaultClasses = {
|
|
|
379
509
|
preview: "flex justify-center mb-4 px-4",
|
|
380
510
|
previewSkeleton: "rounded-xl overflow-hidden",
|
|
381
511
|
previewImage: "",
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
previewFileIcon: "",
|
|
385
|
-
previewFilename: "truncate",
|
|
386
|
-
previewLink: "",
|
|
387
|
-
grid: "px-2 py-6 flex flex-row items-center gap-4 gap-y-6 flex-wrap justify-center",
|
|
512
|
+
previewMeta: "",
|
|
513
|
+
grid: "px-2 py-6 flex flex-row items-start gap-4 gap-y-6 flex-wrap justify-center",
|
|
388
514
|
button: "flex flex-col items-center gap-0 text-xs w-[60px] outline-none cursor-pointer group",
|
|
389
515
|
buttonIcon: "p-2 rounded-full transition-all flex items-center justify-center group-hover:scale-110 group-active:scale-95 mb-2",
|
|
390
516
|
buttonLabel: ""
|
|
@@ -398,28 +524,10 @@ var shimmerKeyframes = `
|
|
|
398
524
|
function cssVar(name, fallback) {
|
|
399
525
|
return `var(${name}, ${fallback})`;
|
|
400
526
|
}
|
|
401
|
-
function normalizePreview(preview) {
|
|
402
|
-
if (!preview) return null;
|
|
403
|
-
if (typeof preview === "string") {
|
|
404
|
-
const type2 = detectPreviewType(preview);
|
|
405
|
-
return {
|
|
406
|
-
url: preview,
|
|
407
|
-
type: type2,
|
|
408
|
-
filename: getFilenameFromUrl(preview)
|
|
409
|
-
};
|
|
410
|
-
}
|
|
411
|
-
const type = preview.type === "auto" || !preview.type ? detectPreviewType(preview.url) : preview.type;
|
|
412
|
-
return {
|
|
413
|
-
...preview,
|
|
414
|
-
type,
|
|
415
|
-
filename: preview.filename || getFilenameFromUrl(preview.url)
|
|
416
|
-
};
|
|
417
|
-
}
|
|
418
527
|
function ShareSheetContent({
|
|
419
528
|
title = "Share",
|
|
420
529
|
shareUrl,
|
|
421
530
|
shareText,
|
|
422
|
-
preview,
|
|
423
531
|
downloadUrl,
|
|
424
532
|
downloadFilename,
|
|
425
533
|
className,
|
|
@@ -434,15 +542,15 @@ function ShareSheetContent({
|
|
|
434
542
|
labels = {},
|
|
435
543
|
icons = {}
|
|
436
544
|
}) {
|
|
437
|
-
const [
|
|
438
|
-
const [
|
|
439
|
-
const
|
|
440
|
-
|
|
545
|
+
const [imageLoaded, setImageLoaded] = useState2(false);
|
|
546
|
+
const [imageError, setImageError] = useState2(false);
|
|
547
|
+
const { ogData, loading: ogLoading } = useOGData(shareUrl);
|
|
548
|
+
const handleImageLoad = useCallback2(() => {
|
|
549
|
+
setImageLoaded(true);
|
|
441
550
|
}, []);
|
|
442
|
-
const
|
|
443
|
-
|
|
551
|
+
const handleImageError = useCallback2(() => {
|
|
552
|
+
setImageError(true);
|
|
444
553
|
}, []);
|
|
445
|
-
const previewConfig = useMemo2(() => normalizePreview(preview), [preview]);
|
|
446
554
|
const shareSheet = useShareSheet({
|
|
447
555
|
shareUrl,
|
|
448
556
|
shareText,
|
|
@@ -478,6 +586,15 @@ function ShareSheetContent({
|
|
|
478
586
|
return PLATFORM_IDS.map((id) => {
|
|
479
587
|
const Icon = PLATFORM_ICONS[id];
|
|
480
588
|
const defaultLabel = dynamicLabels[id] ?? PLATFORM_LABELS[id];
|
|
589
|
+
const availability = shareSheet.platformAvailability[id];
|
|
590
|
+
let condition = true;
|
|
591
|
+
if (id === "native") {
|
|
592
|
+
condition = shareSheet.canNativeShare;
|
|
593
|
+
} else if (id === "download") {
|
|
594
|
+
condition = !!downloadUrl;
|
|
595
|
+
} else if (!availability.available) {
|
|
596
|
+
condition = false;
|
|
597
|
+
}
|
|
481
598
|
return {
|
|
482
599
|
id,
|
|
483
600
|
label: labels[id] ?? defaultLabel,
|
|
@@ -486,11 +603,10 @@ function ShareSheetContent({
|
|
|
486
603
|
bgColor: cssVar(PLATFORM_CSS_VARS[id], PLATFORM_COLORS[id].bg),
|
|
487
604
|
textColor: PLATFORM_COLORS[id].text,
|
|
488
605
|
onClick: shareActions[id],
|
|
489
|
-
|
|
490
|
-
condition: id === "native" ? shareSheet.canNativeShare : id === "download" ? !!downloadUrl : true
|
|
606
|
+
condition
|
|
491
607
|
};
|
|
492
608
|
});
|
|
493
|
-
}, [iconSize, labels, icons, dynamicLabels, shareActions, shareSheet.canNativeShare, downloadUrl]);
|
|
609
|
+
}, [iconSize, labels, icons, dynamicLabels, shareActions, shareSheet.canNativeShare, shareSheet.platformAvailability, downloadUrl]);
|
|
494
610
|
const visibleButtons = useMemo2(() => {
|
|
495
611
|
return buttons.filter((btn) => {
|
|
496
612
|
if (btn.condition === false) return false;
|
|
@@ -499,49 +615,30 @@ function ShareSheetContent({
|
|
|
499
615
|
return true;
|
|
500
616
|
});
|
|
501
617
|
}, [buttons, show, hide]);
|
|
502
|
-
const
|
|
618
|
+
const bgColor = cssVar(CSS_VARS_UI.previewBg, CSS_VAR_UI_DEFAULTS[CSS_VARS_UI.previewBg]);
|
|
619
|
+
const shimmerColor = cssVar(CSS_VARS_UI.previewShimmer, CSS_VAR_UI_DEFAULTS[CSS_VARS_UI.previewShimmer]);
|
|
620
|
+
const textColor = cssVar(CSS_VARS_UI.subtitleColor, CSS_VAR_UI_DEFAULTS[CSS_VARS_UI.subtitleColor]);
|
|
503
621
|
const renderPreview = () => {
|
|
504
|
-
|
|
505
|
-
const
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
const textColor = cssVar(CSS_VARS_UI.subtitleColor, CSS_VAR_UI_DEFAULTS[CSS_VARS_UI.subtitleColor]);
|
|
509
|
-
const UrlLabel = ({ displayUrl = url }) => /* @__PURE__ */ jsx2(
|
|
510
|
-
"div",
|
|
511
|
-
{
|
|
512
|
-
className: cn(defaultClasses.previewFilename, classNames.previewFilename),
|
|
513
|
-
style: {
|
|
514
|
-
color: textColor,
|
|
515
|
-
fontSize: "10px",
|
|
516
|
-
opacity: 0.5,
|
|
517
|
-
textAlign: "center",
|
|
518
|
-
marginTop: "6px"
|
|
519
|
-
},
|
|
520
|
-
children: displayUrl
|
|
521
|
-
}
|
|
522
|
-
);
|
|
523
|
-
const PlaceholderCard = ({
|
|
524
|
-
icon: IconComponent,
|
|
525
|
-
isLoading = false,
|
|
526
|
-
label,
|
|
527
|
-
displayUrl
|
|
528
|
-
}) => /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", alignItems: "center" }, children: [
|
|
529
|
-
/* @__PURE__ */ jsxs(
|
|
622
|
+
const ogImage = ogData?.image;
|
|
623
|
+
const hasImage = ogImage && !imageError;
|
|
624
|
+
if (ogLoading) {
|
|
625
|
+
return /* @__PURE__ */ jsx2("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", width: "100%" }, children: /* @__PURE__ */ jsxs(
|
|
530
626
|
"div",
|
|
531
627
|
{
|
|
532
628
|
className: cn(defaultClasses.previewSkeleton, classNames.previewSkeleton),
|
|
533
629
|
style: {
|
|
534
630
|
position: "relative",
|
|
535
631
|
backgroundColor: bgColor,
|
|
536
|
-
width: "
|
|
537
|
-
|
|
632
|
+
width: "100%",
|
|
633
|
+
maxWidth: "320px",
|
|
634
|
+
aspectRatio: "1.91 / 1",
|
|
538
635
|
overflow: "hidden",
|
|
539
636
|
display: "flex",
|
|
540
637
|
alignItems: "center",
|
|
541
638
|
justifyContent: "center"
|
|
542
639
|
},
|
|
543
640
|
children: [
|
|
544
|
-
|
|
641
|
+
/* @__PURE__ */ jsx2("div", { style: { position: "absolute", inset: 0, overflow: "hidden" }, children: /* @__PURE__ */ jsx2(
|
|
545
642
|
"div",
|
|
546
643
|
{
|
|
547
644
|
style: {
|
|
@@ -552,197 +649,125 @@ function ShareSheetContent({
|
|
|
552
649
|
}
|
|
553
650
|
}
|
|
554
651
|
) }),
|
|
555
|
-
/* @__PURE__ */
|
|
556
|
-
"div",
|
|
557
|
-
{
|
|
558
|
-
style: {
|
|
559
|
-
display: "flex",
|
|
560
|
-
flexDirection: "column",
|
|
561
|
-
alignItems: "center",
|
|
562
|
-
justifyContent: "center",
|
|
563
|
-
gap: "8px"
|
|
564
|
-
},
|
|
565
|
-
children: [
|
|
566
|
-
/* @__PURE__ */ jsx2(IconComponent, { size: 32, style: { color: textColor, opacity: 0.4 } }),
|
|
567
|
-
label && /* @__PURE__ */ jsx2("span", { style: { color: textColor, fontSize: "11px", opacity: 0.4 }, children: label })
|
|
568
|
-
]
|
|
569
|
-
}
|
|
570
|
-
)
|
|
652
|
+
/* @__PURE__ */ jsx2(Link2, { size: 32, style: { color: textColor, opacity: 0.4 } })
|
|
571
653
|
]
|
|
572
654
|
}
|
|
573
|
-
)
|
|
574
|
-
/* @__PURE__ */ jsx2(UrlLabel, { displayUrl })
|
|
575
|
-
] });
|
|
576
|
-
if (mediaError && (type === "image" || type === "video")) {
|
|
577
|
-
return /* @__PURE__ */ jsx2(PlaceholderCard, { icon: Link2, displayUrl: url });
|
|
655
|
+
) });
|
|
578
656
|
}
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
children: [
|
|
598
|
-
/* @__PURE__ */ jsx2("div", { style: { position: "absolute", inset: 0, overflow: "hidden" }, children: /* @__PURE__ */ jsx2(
|
|
599
|
-
"div",
|
|
600
|
-
{
|
|
601
|
-
style: {
|
|
602
|
-
position: "absolute",
|
|
603
|
-
inset: 0,
|
|
604
|
-
background: `linear-gradient(90deg, transparent, ${shimmerColor}, transparent)`,
|
|
605
|
-
animation: "sharesheet-shimmer 1.5s infinite"
|
|
606
|
-
}
|
|
607
|
-
}
|
|
608
|
-
) }),
|
|
609
|
-
/* @__PURE__ */ jsx2(Image, { size: 32, style: { color: textColor, opacity: 0.4 } })
|
|
610
|
-
]
|
|
611
|
-
}
|
|
612
|
-
),
|
|
613
|
-
/* @__PURE__ */ jsx2(UrlLabel, {}),
|
|
614
|
-
/* @__PURE__ */ jsx2(
|
|
615
|
-
"img",
|
|
616
|
-
{
|
|
617
|
-
src: url,
|
|
618
|
-
alt: alt || "Preview",
|
|
619
|
-
onLoad: handleMediaLoad,
|
|
620
|
-
onError: handleMediaError,
|
|
621
|
-
style: { display: "none" }
|
|
622
|
-
}
|
|
623
|
-
)
|
|
624
|
-
] });
|
|
625
|
-
}
|
|
626
|
-
return /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", alignItems: "center" }, children: [
|
|
627
|
-
/* @__PURE__ */ jsx2(
|
|
628
|
-
"img",
|
|
657
|
+
if (!ogData || !hasImage) {
|
|
658
|
+
return /* @__PURE__ */ jsx2("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", width: "100%" }, children: /* @__PURE__ */ jsx2(
|
|
659
|
+
"div",
|
|
660
|
+
{
|
|
661
|
+
className: cn(defaultClasses.previewSkeleton, classNames.previewSkeleton),
|
|
662
|
+
style: {
|
|
663
|
+
position: "relative",
|
|
664
|
+
backgroundColor: bgColor,
|
|
665
|
+
width: "100%",
|
|
666
|
+
maxWidth: "320px",
|
|
667
|
+
aspectRatio: "1.91 / 1",
|
|
668
|
+
overflow: "hidden",
|
|
669
|
+
display: "flex",
|
|
670
|
+
alignItems: "center",
|
|
671
|
+
justifyContent: "center"
|
|
672
|
+
},
|
|
673
|
+
children: /* @__PURE__ */ jsxs(
|
|
674
|
+
"div",
|
|
629
675
|
{
|
|
630
|
-
src: url,
|
|
631
|
-
alt: alt || "Preview",
|
|
632
|
-
className: cn(defaultClasses.previewImage, classNames.previewImage),
|
|
633
676
|
style: {
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
if (!mediaLoaded) {
|
|
646
|
-
return /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", alignItems: "center" }, children: [
|
|
647
|
-
/* @__PURE__ */ jsxs(
|
|
648
|
-
"div",
|
|
649
|
-
{
|
|
650
|
-
className: cn(defaultClasses.previewSkeleton, classNames.previewSkeleton),
|
|
651
|
-
style: {
|
|
652
|
-
position: "relative",
|
|
653
|
-
backgroundColor: bgColor,
|
|
654
|
-
width: "200px",
|
|
655
|
-
height: "120px",
|
|
656
|
-
overflow: "hidden",
|
|
657
|
-
display: "flex",
|
|
658
|
-
alignItems: "center",
|
|
659
|
-
justifyContent: "center"
|
|
660
|
-
},
|
|
661
|
-
children: [
|
|
662
|
-
/* @__PURE__ */ jsx2("div", { style: { position: "absolute", inset: 0, overflow: "hidden" }, children: /* @__PURE__ */ jsx2(
|
|
663
|
-
"div",
|
|
664
|
-
{
|
|
665
|
-
style: {
|
|
666
|
-
position: "absolute",
|
|
667
|
-
inset: 0,
|
|
668
|
-
background: `linear-gradient(90deg, transparent, ${shimmerColor}, transparent)`,
|
|
669
|
-
animation: "sharesheet-shimmer 1.5s infinite"
|
|
670
|
-
}
|
|
671
|
-
}
|
|
672
|
-
) }),
|
|
673
|
-
/* @__PURE__ */ jsx2(Film, { size: 32, style: { color: textColor, opacity: 0.4 } })
|
|
674
|
-
]
|
|
675
|
-
}
|
|
676
|
-
),
|
|
677
|
-
/* @__PURE__ */ jsx2(UrlLabel, {}),
|
|
678
|
-
/* @__PURE__ */ jsx2(
|
|
679
|
-
"video",
|
|
680
|
-
{
|
|
681
|
-
src: url,
|
|
682
|
-
poster,
|
|
683
|
-
onLoadedData: handleMediaLoad,
|
|
684
|
-
onError: handleMediaError,
|
|
685
|
-
style: { display: "none" },
|
|
686
|
-
muted: true,
|
|
687
|
-
playsInline: true,
|
|
688
|
-
preload: "metadata"
|
|
689
|
-
}
|
|
690
|
-
)
|
|
691
|
-
] });
|
|
692
|
-
}
|
|
693
|
-
return /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", alignItems: "center" }, children: [
|
|
694
|
-
/* @__PURE__ */ jsxs("div", { style: { position: "relative", borderRadius: "12px", overflow: "hidden" }, children: [
|
|
695
|
-
/* @__PURE__ */ jsx2(
|
|
696
|
-
"video",
|
|
697
|
-
{
|
|
698
|
-
src: url,
|
|
699
|
-
poster,
|
|
700
|
-
className: cn(defaultClasses.previewVideo, classNames.previewVideo),
|
|
701
|
-
style: {
|
|
702
|
-
maxWidth: "100%",
|
|
703
|
-
maxHeight: "180px",
|
|
704
|
-
display: "block"
|
|
705
|
-
},
|
|
706
|
-
muted: true,
|
|
707
|
-
playsInline: true,
|
|
708
|
-
preload: "metadata"
|
|
709
|
-
}
|
|
710
|
-
),
|
|
711
|
-
/* @__PURE__ */ jsx2(
|
|
712
|
-
"div",
|
|
713
|
-
{
|
|
714
|
-
style: {
|
|
715
|
-
position: "absolute",
|
|
716
|
-
inset: 0,
|
|
717
|
-
display: "flex",
|
|
718
|
-
alignItems: "center",
|
|
719
|
-
justifyContent: "center",
|
|
720
|
-
pointerEvents: "none"
|
|
721
|
-
},
|
|
722
|
-
children: /* @__PURE__ */ jsx2(
|
|
723
|
-
"div",
|
|
677
|
+
display: "flex",
|
|
678
|
+
flexDirection: "column",
|
|
679
|
+
alignItems: "center",
|
|
680
|
+
justifyContent: "center",
|
|
681
|
+
gap: "8px",
|
|
682
|
+
padding: "16px"
|
|
683
|
+
},
|
|
684
|
+
children: [
|
|
685
|
+
/* @__PURE__ */ jsx2(Link2, { size: 32, style: { color: textColor, opacity: 0.4 } }),
|
|
686
|
+
ogData?.title && /* @__PURE__ */ jsx2(
|
|
687
|
+
"span",
|
|
724
688
|
{
|
|
725
689
|
style: {
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
690
|
+
color: textColor,
|
|
691
|
+
fontSize: "12px",
|
|
692
|
+
opacity: 0.6,
|
|
693
|
+
textAlign: "center",
|
|
694
|
+
maxWidth: "280px",
|
|
695
|
+
overflow: "hidden",
|
|
696
|
+
textOverflow: "ellipsis",
|
|
697
|
+
display: "-webkit-box",
|
|
698
|
+
WebkitLineClamp: 2,
|
|
699
|
+
WebkitBoxOrient: "vertical"
|
|
729
700
|
},
|
|
730
|
-
children:
|
|
701
|
+
children: ogData.title
|
|
731
702
|
}
|
|
732
703
|
)
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
case "audio":
|
|
739
|
-
return /* @__PURE__ */ jsx2(PlaceholderCard, { icon: Music, label: filename || "Audio", displayUrl: url });
|
|
740
|
-
case "file":
|
|
741
|
-
return /* @__PURE__ */ jsx2(PlaceholderCard, { icon: FileText, label: filename || "File", displayUrl: url });
|
|
742
|
-
case "link":
|
|
743
|
-
default:
|
|
744
|
-
return /* @__PURE__ */ jsx2(PlaceholderCard, { icon: Link2, displayUrl: url });
|
|
704
|
+
]
|
|
705
|
+
}
|
|
706
|
+
)
|
|
707
|
+
}
|
|
708
|
+
) });
|
|
745
709
|
}
|
|
710
|
+
if (!imageLoaded) {
|
|
711
|
+
return /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", width: "100%" }, children: [
|
|
712
|
+
/* @__PURE__ */ jsxs(
|
|
713
|
+
"div",
|
|
714
|
+
{
|
|
715
|
+
className: cn(defaultClasses.previewSkeleton, classNames.previewSkeleton),
|
|
716
|
+
style: {
|
|
717
|
+
position: "relative",
|
|
718
|
+
backgroundColor: bgColor,
|
|
719
|
+
width: "100%",
|
|
720
|
+
maxWidth: "320px",
|
|
721
|
+
aspectRatio: "1.91 / 1",
|
|
722
|
+
overflow: "hidden",
|
|
723
|
+
display: "flex",
|
|
724
|
+
alignItems: "center",
|
|
725
|
+
justifyContent: "center"
|
|
726
|
+
},
|
|
727
|
+
children: [
|
|
728
|
+
/* @__PURE__ */ jsx2("div", { style: { position: "absolute", inset: 0, overflow: "hidden" }, children: /* @__PURE__ */ jsx2(
|
|
729
|
+
"div",
|
|
730
|
+
{
|
|
731
|
+
style: {
|
|
732
|
+
position: "absolute",
|
|
733
|
+
inset: 0,
|
|
734
|
+
background: `linear-gradient(90deg, transparent, ${shimmerColor}, transparent)`,
|
|
735
|
+
animation: "sharesheet-shimmer 1.5s infinite"
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
) }),
|
|
739
|
+
/* @__PURE__ */ jsx2(Image, { size: 32, style: { color: textColor, opacity: 0.4 } })
|
|
740
|
+
]
|
|
741
|
+
}
|
|
742
|
+
),
|
|
743
|
+
/* @__PURE__ */ jsx2(
|
|
744
|
+
"img",
|
|
745
|
+
{
|
|
746
|
+
src: ogImage,
|
|
747
|
+
alt: ogData.title || "Preview",
|
|
748
|
+
onLoad: handleImageLoad,
|
|
749
|
+
onError: handleImageError,
|
|
750
|
+
style: { display: "none" }
|
|
751
|
+
}
|
|
752
|
+
)
|
|
753
|
+
] });
|
|
754
|
+
}
|
|
755
|
+
return /* @__PURE__ */ jsx2("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", width: "100%" }, children: /* @__PURE__ */ jsx2(
|
|
756
|
+
"img",
|
|
757
|
+
{
|
|
758
|
+
src: ogImage,
|
|
759
|
+
alt: ogData.title || "Preview",
|
|
760
|
+
className: cn(defaultClasses.previewImage, classNames.previewImage),
|
|
761
|
+
style: {
|
|
762
|
+
width: "100%",
|
|
763
|
+
maxWidth: "320px",
|
|
764
|
+
height: "auto",
|
|
765
|
+
borderRadius: "12px",
|
|
766
|
+
opacity: 1,
|
|
767
|
+
transition: "opacity 0.3s ease-in-out"
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
) });
|
|
746
771
|
};
|
|
747
772
|
return /* @__PURE__ */ jsxs("div", { className: cn(defaultClasses.root, classNames.root, className), children: [
|
|
748
773
|
/* @__PURE__ */ jsx2("style", { dangerouslySetInnerHTML: { __html: shimmerKeyframes } }),
|
|
@@ -764,7 +789,7 @@ function ShareSheetContent({
|
|
|
764
789
|
}
|
|
765
790
|
)
|
|
766
791
|
] }),
|
|
767
|
-
|
|
792
|
+
/* @__PURE__ */ jsx2("div", { className: cn(defaultClasses.preview, classNames.preview), children: renderPreview() }),
|
|
768
793
|
/* @__PURE__ */ jsx2("div", { className: cn(defaultClasses.grid, classNames.grid), children: visibleButtons.map((btn) => /* @__PURE__ */ jsxs(
|
|
769
794
|
"button",
|
|
770
795
|
{
|