fix: 이전 공유하기 기능 제거
This commit is contained in:
parent
e400884eb7
commit
63d60caabd
@ -1,5 +1,4 @@
|
|||||||
import React, { useEffect, useLayoutEffect, useRef, useState } from 'react';
|
import React, { useRef, useState } from 'react';
|
||||||
import { createPortal } from 'react-dom';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { API_URL, toggleVideoLike } from '../utils/api';
|
import { API_URL, toggleVideoLike } from '../utils/api';
|
||||||
import { buildVideoShareUrl, tryNativeShare } from '../utils/nativeShare';
|
import { buildVideoShareUrl, tryNativeShare } from '../utils/nativeShare';
|
||||||
@ -25,96 +24,29 @@ const ContentCardSocialActions: React.FC<ContentCardSocialActionsProps> = ({
|
|||||||
|
|
||||||
const [likeCount, setLikeCount] = useState(initialLikeCount);
|
const [likeCount, setLikeCount] = useState(initialLikeCount);
|
||||||
const [isLiked, setIsLiked] = useState(initialIsLiked);
|
const [isLiked, setIsLiked] = useState(initialIsLiked);
|
||||||
const [copied, setCopied] = useState(false);
|
|
||||||
const [shareMenuOpen, setShareMenuOpen] = useState(false);
|
|
||||||
const [menuPos, setMenuPos] = useState<{ top: number; left: number } | null>(null);
|
|
||||||
const [anchorRect, setAnchorRect] = useState<{ top: number; bottom: number; left: number } | null>(null);
|
|
||||||
|
|
||||||
const shareBtnRef = useRef<HTMLButtonElement>(null);
|
|
||||||
const shareMenuRef = useRef<HTMLDivElement>(null);
|
|
||||||
const likeDebounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
const likeDebounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
||||||
|
|
||||||
const shareUrl = buildVideoShareUrl(API_URL, videoId);
|
const shareUrl = buildVideoShareUrl(API_URL, videoId);
|
||||||
const shareTitle = storeName || t('videoDetail.kakaoDefaultTitle');
|
const shareTitle = storeName || t('videoDetail.kakaoDefaultTitle');
|
||||||
const shareDescription = t('videoDetail.kakaoDescription', { region: region ?? '' });
|
const shareDescription = t('videoDetail.kakaoDescription', { region: region ?? '' });
|
||||||
|
|
||||||
useEffect(() => {
|
const handleShareBtnClick = async (e: React.MouseEvent) => {
|
||||||
if (!shareMenuOpen) return;
|
e.stopPropagation();
|
||||||
|
|
||||||
const closeMenu = () => setShareMenuOpen(false);
|
const handled = await tryNativeShare({
|
||||||
|
title: shareTitle,
|
||||||
const handleClickOutside = (e: MouseEvent) => {
|
text: shareDescription,
|
||||||
if (
|
url: shareUrl,
|
||||||
shareMenuRef.current && !shareMenuRef.current.contains(e.target as Node) &&
|
});
|
||||||
shareBtnRef.current && !shareBtnRef.current.contains(e.target as Node)
|
if (handled) {
|
||||||
) {
|
return;
|
||||||
closeMenu();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
document.addEventListener('mousedown', handleClickOutside);
|
|
||||||
window.addEventListener('scroll', closeMenu, true);
|
|
||||||
window.addEventListener('resize', closeMenu);
|
|
||||||
return () => {
|
|
||||||
document.removeEventListener('mousedown', handleClickOutside);
|
|
||||||
window.removeEventListener('scroll', closeMenu, true);
|
|
||||||
window.removeEventListener('resize', closeMenu);
|
|
||||||
};
|
|
||||||
}, [shareMenuOpen]);
|
|
||||||
|
|
||||||
// 메뉴가 뷰포트 밖으로 넘어가지 않도록 실제 렌더된 크기 기준으로 위치 보정
|
|
||||||
useLayoutEffect(() => {
|
|
||||||
if (!shareMenuOpen || !anchorRect || !shareMenuRef.current) return;
|
|
||||||
const margin = 8;
|
|
||||||
const menuRect = shareMenuRef.current.getBoundingClientRect();
|
|
||||||
|
|
||||||
let left = anchorRect.left;
|
|
||||||
if (left + menuRect.width > window.innerWidth - margin) {
|
|
||||||
left = window.innerWidth - menuRect.width - margin;
|
|
||||||
}
|
}
|
||||||
left = Math.max(margin, left);
|
|
||||||
|
|
||||||
let top = anchorRect.bottom + 6;
|
|
||||||
if (top + menuRect.height > window.innerHeight - margin) {
|
|
||||||
top = anchorRect.top - menuRect.height - 6;
|
|
||||||
}
|
|
||||||
top = Math.max(margin, top);
|
|
||||||
|
|
||||||
setMenuPos((prev) => (prev && prev.top === top && prev.left === left ? prev : { top, left }));
|
|
||||||
}, [shareMenuOpen, anchorRect]);
|
|
||||||
|
|
||||||
const handleCopyLink = async () => {
|
|
||||||
try {
|
try {
|
||||||
await navigator.clipboard.writeText(shareUrl);
|
await navigator.clipboard.writeText(shareUrl);
|
||||||
} catch {
|
} catch {
|
||||||
// clipboard API 미지원 환경에서는 무시
|
// clipboard API 미지원 환경에서는 무시
|
||||||
}
|
}
|
||||||
setCopied(true);
|
|
||||||
setTimeout(() => setCopied(false), 2000);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleKakaoShare = () => {
|
|
||||||
const kakao = window.Kakao;
|
|
||||||
if (kakao?.Share) {
|
|
||||||
// 공유 URL(백엔드 OG 페이지)을 스크랩해 제목/설명/이미지를 자동으로 채운다.
|
|
||||||
// 다른 채널과 동일한 shareUrl을 쓰므로 카카오만을 위한 별도 콘텐츠 지정이 필요 없다.
|
|
||||||
kakao.Share.sendScrap({ requestUrl: shareUrl });
|
|
||||||
} else if (navigator.share) {
|
|
||||||
navigator.share({ title: shareTitle, text: shareDescription, url: shareUrl }).catch(() => {});
|
|
||||||
} else {
|
|
||||||
handleCopyLink();
|
|
||||||
}
|
|
||||||
setShareMenuOpen(false);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleFacebookShare = () => {
|
|
||||||
window.open(`https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(shareUrl)}`, '_blank', 'noopener,width=600,height=600');
|
|
||||||
setShareMenuOpen(false);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleTwitterShare = () => {
|
|
||||||
window.open(`https://twitter.com/intent/tweet?url=${encodeURIComponent(shareUrl)}`, '_blank', 'noopener,width=600,height=600');
|
|
||||||
setShareMenuOpen(false);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleLikeClick = (e: React.MouseEvent) => {
|
const handleLikeClick = (e: React.MouseEvent) => {
|
||||||
@ -140,28 +72,6 @@ const ContentCardSocialActions: React.FC<ContentCardSocialActionsProps> = ({
|
|||||||
}, 500);
|
}, 500);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleShareBtnClick = async (e: React.MouseEvent) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
|
|
||||||
const handled = await tryNativeShare({
|
|
||||||
title: shareTitle,
|
|
||||||
text: shareDescription,
|
|
||||||
url: shareUrl,
|
|
||||||
});
|
|
||||||
if (handled) {
|
|
||||||
setShareMenuOpen(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const rect = shareBtnRef.current?.getBoundingClientRect();
|
|
||||||
if (rect) {
|
|
||||||
// 초기 추정 위치(측정 전 첫 렌더용) — useLayoutEffect가 실제 크기 기준으로 다시 보정한다
|
|
||||||
setAnchorRect({ top: rect.top, bottom: rect.bottom, left: rect.left });
|
|
||||||
setMenuPos({ top: rect.bottom + 6, left: rect.left });
|
|
||||||
}
|
|
||||||
setShareMenuOpen((v) => !v);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="content-card-social" onClick={(e) => e.stopPropagation()}>
|
<div className="content-card-social" onClick={(e) => e.stopPropagation()}>
|
||||||
<button
|
<button
|
||||||
@ -182,7 +92,6 @@ const ContentCardSocialActions: React.FC<ContentCardSocialActionsProps> = ({
|
|||||||
</span>
|
</span>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
ref={shareBtnRef}
|
|
||||||
className="content-card-share-btn"
|
className="content-card-share-btn"
|
||||||
onClick={handleShareBtnClick}
|
onClick={handleShareBtnClick}
|
||||||
title={t('videoDetail.share')}
|
title={t('videoDetail.share')}
|
||||||
@ -192,42 +101,6 @@ const ContentCardSocialActions: React.FC<ContentCardSocialActionsProps> = ({
|
|||||||
<line x1="8.59" y1="13.51" x2="15.42" y2="17.49" /><line x1="15.41" y1="6.51" x2="8.59" y2="10.49" />
|
<line x1="8.59" y1="13.51" x2="15.42" y2="17.49" /><line x1="15.41" y1="6.51" x2="8.59" y2="10.49" />
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
{shareMenuOpen && menuPos && createPortal(
|
|
||||||
<div
|
|
||||||
ref={shareMenuRef}
|
|
||||||
className="video-detail-share-menu"
|
|
||||||
style={{ position: 'fixed', top: menuPos.top, left: menuPos.left }}
|
|
||||||
>
|
|
||||||
<button className="video-detail-share-item" onClick={handleKakaoShare}>
|
|
||||||
<svg width="18" height="18" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<rect width="20" height="20" rx="4" fill="#FEE500" />
|
|
||||||
<path fillRule="evenodd" clipRule="evenodd" d="M10 3.5C6.134 3.5 3 6.01 3 9.1c0 1.98 1.2 3.72 3.01 4.76l-.74 2.75a.19.19 0 0 0 .28.21l3.37-2.23c.34.04.69.06 1.06.06 3.866 0 7-2.51 7-5.6S13.866 3.5 10 3.5z" fill="#3C1E1E" />
|
|
||||||
</svg>
|
|
||||||
{t('videoDetail.shareKakao')}
|
|
||||||
</button>
|
|
||||||
<button className="video-detail-share-item" onClick={handleFacebookShare}>
|
|
||||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="#1877F2">
|
|
||||||
<path d="M24 12.073C24 5.405 18.627 0 12 0S0 5.405 0 12.073C0 18.1 4.388 23.094 10.125 24v-8.437H7.078v-3.49h3.047V9.41c0-3.025 1.792-4.697 4.533-4.697 1.312 0 2.686.235 2.686.235v2.97h-1.513c-1.491 0-1.956.93-1.956 1.887v2.268h3.328l-.532 3.49h-2.796V24C19.612 23.094 24 18.1 24 12.073z" />
|
|
||||||
</svg>
|
|
||||||
{t('videoDetail.shareFacebook')}
|
|
||||||
</button>
|
|
||||||
<button className="video-detail-share-item" onClick={handleTwitterShare}>
|
|
||||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor">
|
|
||||||
<path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z" />
|
|
||||||
</svg>
|
|
||||||
{t('videoDetail.shareTwitter')}
|
|
||||||
</button>
|
|
||||||
<button className="video-detail-share-item" onClick={() => { handleCopyLink(); setShareMenuOpen(false); }}>
|
|
||||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
|
|
||||||
<rect x="9" y="9" width="13" height="13" rx="2" />
|
|
||||||
<path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" />
|
|
||||||
</svg>
|
|
||||||
{copied ? t('videoDetail.copied') : t('videoDetail.copyUrl')}
|
|
||||||
</button>
|
|
||||||
</div>,
|
|
||||||
document.body
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -32,7 +32,6 @@ const VideoDetailContent: React.FC<VideoDetailContentProps> = ({ videoId, isModa
|
|||||||
const [isLiked, setIsLiked] = useState(false);
|
const [isLiked, setIsLiked] = useState(false);
|
||||||
|
|
||||||
const [copied, setCopied] = useState(false);
|
const [copied, setCopied] = useState(false);
|
||||||
const [shareMenuOpen, setShareMenuOpen] = useState(false);
|
|
||||||
const [isLandscape, setIsLandscape] = useState(false);
|
const [isLandscape, setIsLandscape] = useState(false);
|
||||||
const [showLoginModal, setShowLoginModal] = useState(false);
|
const [showLoginModal, setShowLoginModal] = useState(false);
|
||||||
|
|
||||||
@ -107,42 +106,6 @@ const VideoDetailContent: React.FC<VideoDetailContentProps> = ({ videoId, isModa
|
|||||||
const shareTitle = video?.store_name ?? t('videoDetail.kakaoDefaultTitle');
|
const shareTitle = video?.store_name ?? t('videoDetail.kakaoDefaultTitle');
|
||||||
const shareDescription = t('videoDetail.kakaoDescription', { region: video?.region ?? '' });
|
const shareDescription = t('videoDetail.kakaoDescription', { region: video?.region ?? '' });
|
||||||
|
|
||||||
const handleCopyLink = async () => {
|
|
||||||
try {
|
|
||||||
await navigator.clipboard.writeText(shareUrl);
|
|
||||||
} catch {
|
|
||||||
// clipboard API 미지원 환경에서는 무시
|
|
||||||
}
|
|
||||||
setCopied(true);
|
|
||||||
setTimeout(() => setCopied(false), 2000);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleKakaoShare = () => {
|
|
||||||
const kakao = window.Kakao;
|
|
||||||
if (kakao?.Share) {
|
|
||||||
// 공유 URL(백엔드 OG 페이지)을 스크랩해 제목/설명/이미지를 자동으로 채운다.
|
|
||||||
// 다른 채널과 동일한 shareUrl을 쓰므로 카카오만을 위한 별도 콘텐츠 지정이 필요 없다.
|
|
||||||
kakao.Share.sendScrap({ requestUrl: shareUrl });
|
|
||||||
} else if (navigator.share) {
|
|
||||||
navigator.share({ title: shareTitle, text: shareDescription, url: shareUrl }).catch(() => {});
|
|
||||||
} else {
|
|
||||||
handleCopyLink();
|
|
||||||
}
|
|
||||||
setShareMenuOpen(false);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleFacebookShare = () => {
|
|
||||||
window.open(`https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(shareUrl)}`, '_blank', 'noopener,width=600,height=600');
|
|
||||||
setShareMenuOpen(false);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleTwitterShare = () => {
|
|
||||||
window.open(`https://twitter.com/intent/tweet?url=${encodeURIComponent(shareUrl)}`, '_blank', 'noopener,width=600,height=600');
|
|
||||||
setShareMenuOpen(false);
|
|
||||||
};
|
|
||||||
|
|
||||||
const shareMenuRef = React.useRef<HTMLDivElement>(null);
|
|
||||||
|
|
||||||
const handleShareButtonClick = async () => {
|
const handleShareButtonClick = async () => {
|
||||||
const handled = await tryNativeShare({
|
const handled = await tryNativeShare({
|
||||||
title: shareTitle,
|
title: shareTitle,
|
||||||
@ -150,24 +113,18 @@ const VideoDetailContent: React.FC<VideoDetailContentProps> = ({ videoId, isModa
|
|||||||
url: shareUrl,
|
url: shareUrl,
|
||||||
});
|
});
|
||||||
if (handled) {
|
if (handled) {
|
||||||
setShareMenuOpen(false);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setShareMenuOpen((open) => !open);
|
try {
|
||||||
|
await navigator.clipboard.writeText(shareUrl);
|
||||||
|
setCopied(true);
|
||||||
|
setTimeout(() => setCopied(false), 2000);
|
||||||
|
} catch {
|
||||||
|
// clipboard API 미지원 환경에서는 무시
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!shareMenuOpen) return;
|
|
||||||
const handleClickOutside = (e: MouseEvent) => {
|
|
||||||
if (shareMenuRef.current && !shareMenuRef.current.contains(e.target as Node)) {
|
|
||||||
setShareMenuOpen(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
document.addEventListener('mousedown', handleClickOutside);
|
|
||||||
return () => document.removeEventListener('mousedown', handleClickOutside);
|
|
||||||
}, [shareMenuOpen]);
|
|
||||||
|
|
||||||
const likeDebounceRef = React.useRef<ReturnType<typeof setTimeout> | null>(null);
|
const likeDebounceRef = React.useRef<ReturnType<typeof setTimeout> | null>(null);
|
||||||
|
|
||||||
const handleLike = () => {
|
const handleLike = () => {
|
||||||
@ -292,52 +249,16 @@ const VideoDetailContent: React.FC<VideoDetailContentProps> = ({ videoId, isModa
|
|||||||
</svg>
|
</svg>
|
||||||
{likeCount}
|
{likeCount}
|
||||||
</button>
|
</button>
|
||||||
<div style={{ position: 'relative' }} ref={shareMenuRef}>
|
<button
|
||||||
<button
|
className="video-detail-copy-btn"
|
||||||
className="video-detail-copy-btn"
|
onClick={handleShareButtonClick}
|
||||||
onClick={handleShareButtonClick}
|
>
|
||||||
>
|
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
|
||||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
|
<circle cx="18" cy="5" r="3"/><circle cx="6" cy="12" r="3"/><circle cx="18" cy="19" r="3"/>
|
||||||
<circle cx="18" cy="5" r="3"/><circle cx="6" cy="12" r="3"/><circle cx="18" cy="19" r="3"/>
|
<line x1="8.59" y1="13.51" x2="15.42" y2="17.49"/><line x1="15.41" y1="6.51" x2="8.59" y2="10.49"/>
|
||||||
<line x1="8.59" y1="13.51" x2="15.42" y2="17.49"/><line x1="15.41" y1="6.51" x2="8.59" y2="10.49"/>
|
</svg>
|
||||||
</svg>
|
{copied ? t('videoDetail.copied') : t('videoDetail.share')}
|
||||||
{copied ? t('videoDetail.copied') : t('videoDetail.share')}
|
</button>
|
||||||
</button>
|
|
||||||
{shareMenuOpen && (
|
|
||||||
<div className="video-detail-share-menu">
|
|
||||||
{/* 카카오톡 */}
|
|
||||||
<button className="video-detail-share-item" onClick={handleKakaoShare}>
|
|
||||||
<svg width="18" height="18" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<rect width="20" height="20" rx="4" fill="#FEE500"/>
|
|
||||||
<path fillRule="evenodd" clipRule="evenodd" d="M10 3.5C6.134 3.5 3 6.01 3 9.1c0 1.98 1.2 3.72 3.01 4.76l-.74 2.75a.19.19 0 0 0 .28.21l3.37-2.23c.34.04.69.06 1.06.06 3.866 0 7-2.51 7-5.6S13.866 3.5 10 3.5z" fill="#3C1E1E"/>
|
|
||||||
</svg>
|
|
||||||
{t('videoDetail.shareKakao')}
|
|
||||||
</button>
|
|
||||||
{/* 페이스북 */}
|
|
||||||
<button className="video-detail-share-item" onClick={handleFacebookShare}>
|
|
||||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="#1877F2">
|
|
||||||
<path d="M24 12.073C24 5.405 18.627 0 12 0S0 5.405 0 12.073C0 18.1 4.388 23.094 10.125 24v-8.437H7.078v-3.49h3.047V9.41c0-3.025 1.792-4.697 4.533-4.697 1.312 0 2.686.235 2.686.235v2.97h-1.513c-1.491 0-1.956.93-1.956 1.887v2.268h3.328l-.532 3.49h-2.796V24C19.612 23.094 24 18.1 24 12.073z"/>
|
|
||||||
</svg>
|
|
||||||
{t('videoDetail.shareFacebook')}
|
|
||||||
</button>
|
|
||||||
{/* X (트위터) */}
|
|
||||||
<button className="video-detail-share-item" onClick={handleTwitterShare}>
|
|
||||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor">
|
|
||||||
<path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/>
|
|
||||||
</svg>
|
|
||||||
{t('videoDetail.shareTwitter')}
|
|
||||||
</button>
|
|
||||||
{/* URL 복사 */}
|
|
||||||
<button className="video-detail-share-item" onClick={() => { handleCopyLink(); setShareMenuOpen(false); }}>
|
|
||||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
|
|
||||||
<rect x="9" y="9" width="13" height="13" rx="2"/>
|
|
||||||
<path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/>
|
|
||||||
</svg>
|
|
||||||
{copied ? t('videoDetail.copied') : t('videoDetail.copyUrl')}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* 댓글 섹션 */}
|
{/* 댓글 섹션 */}
|
||||||
|
|||||||
@ -1,8 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* 기기의 네이티브 공유 시트를 열고 요청을 처리했는지 반환합니다.
|
* 기기의 네이티브 공유 시트를 열고 요청을 처리했는지 반환합니다.
|
||||||
*
|
*
|
||||||
* 사용자가 공유 시트를 닫은 경우도 정상적으로 처리된 것으로 간주해
|
* 사용자가 공유 시트를 닫은 경우도 정상적으로 처리된 것으로 간주합니다.
|
||||||
* 별도의 공유 메뉴가 뒤이어 열리지 않도록 합니다.
|
|
||||||
*/
|
*/
|
||||||
export async function tryNativeShare(data: ShareData): Promise<boolean> {
|
export async function tryNativeShare(data: ShareData): Promise<boolean> {
|
||||||
if (typeof navigator.share !== 'function') {
|
if (typeof navigator.share !== 'function') {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user