-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathSocialShare.tsx
More file actions
157 lines (144 loc) · 4.21 KB
/
SocialShare.tsx
File metadata and controls
157 lines (144 loc) · 4.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
import React, { useEffect, useState } from 'react';
import { CopyIcon, CheckSqaureIcon, TwitterIcon, ShareIcon, WhatsAppIcon, FacebookIcon } from '../icons/icons';
import { useThemeState } from '../../theme/ThemeContext';
interface SocialShareProps {
url?: string;
title?: string;
tags?: Array<string>;
showText?: boolean;
twitter?: boolean;
copyLink?: boolean;
facebook?: boolean;
whatsApp?: boolean;
}
interface ShareLinkProps {
text?: string;
label: string;
url: string;
showText?: boolean;
icon: React.ReactNode;
}
export const ShareLink = ({ text, label, url, icon, showText }: ShareLinkProps): JSX.Element => {
return (
<a
aria-label={label}
href={url}
className="transition duration-500 ease-in-out hover:scale-125"
target="_blank"
rel="noreferrer"
>
{icon}
{showText && <span>{text}</span>}
</a>
);
};
const SocialShare = ({
url = '',
title = '',
showText = false,
twitter = true,
copyLink = true,
facebook = true,
whatsApp = true,
}: SocialShareProps): JSX.Element => {
const theme = useThemeState();
const [showShareBtn, setShowShareBtn] = useState(false);
const [copyBtnText, setCopyBtnText] = useState<'Copy Link' | 'Copied!'>('Copy Link');
useEffect(() => {
const timer = setTimeout(() => setCopyBtnText('Copy Link'), 1500);
return () => clearTimeout(timer);
}, [copyBtnText, theme]);
useEffect(() => {
if (navigator.share) {
setShowShareBtn(true);
} else {
setShowShareBtn(false);
}
}, []);
const copyLinkToClipBoard = async () => {
try {
await navigator.clipboard.writeText(url);
setCopyBtnText('Copied!');
} catch (error) {
console.error(error);
}
};
const shareExternal = async () => {
if (navigator.share) {
// Web Share API is supported
setShowShareBtn(true);
const shareData = { title, url };
try {
await navigator.share(shareData);
} catch (err) {
console.error(err);
}
} else {
// Fallback
console.info('navigator.share is not supported');
setShowShareBtn(false);
}
};
const shareContent = encodeURIComponent(
`I recommend reading '${title}' by @scriptifed_dev. \n\nRead at - ${url}\n\n`
);
const facebookShareURL = `https://www.facebook.com/dialog/share?app_id=${process.env.NEXT_PUBLIC_FACEBOOK_APP_ID}&display=popup&href=${url}&redirect_uri=${url}`;
const twitterShareURL = `https://twitter.com/intent/tweet?text=${shareContent}`;
const whatsAppShareURL = `https://wa.me/?text=${shareContent}`;
return (
<section className="flex flex-row space-x-4 pt-6">
{twitter && (
<ShareLink
showText={showText}
label="Share to Twitter"
text="Share to Twitter"
url={twitterShareURL}
icon={<TwitterIcon color={`text-${theme}-500`} />}
/>
)}
{whatsApp && (
<ShareLink
showText={showText}
label="Share to WhatsApp"
text="Share to WhatsApp"
url={whatsAppShareURL}
icon={<WhatsAppIcon color={`text-${theme}-500`} />}
/>
)}
{facebook && (
<ShareLink
showText={showText}
label="Share to Facebook"
text="Share to Facebook"
url={facebookShareURL}
icon={<FacebookIcon color={`text-${theme}-500`} />}
/>
)}
{copyLink ? (
<button
aria-label="Copy link to clipboard"
className="transition duration-500 ease-in-out hover:scale-125"
onClick={copyLinkToClipBoard}
>
{copyBtnText === 'Copy Link' ? (
<CopyIcon color={`text-${theme}-500`} />
) : (
<CheckSqaureIcon color={`text-${theme}-500`} />
)}
{showText && <span>{copyBtnText}</span>}
</button>
) : null}
{showShareBtn ? (
<button
aria-label="Share"
className="hidden lg:inline-block transition duration-500 ease-in-out hover:scale-125"
onClick={shareExternal}
>
<ShareIcon color={`text-${theme}-500`} />
{showText && <span>Share</span>}
</button>
) : null}
</section>
);
};
export default SocialShare;