Skip to content

Commit b6be1bc

Browse files
committed
share buttons
1 parent 5036307 commit b6be1bc

File tree

1 file changed

+212
-116
lines changed

1 file changed

+212
-116
lines changed

src/components/ShareButtons.js

Lines changed: 212 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -1,141 +1,237 @@
1-
import React from 'react';
1+
import React, { useState, useEffect } from 'react';
22
import {
33
FacebookLogo,
44
TwitterLogo,
55
LinkedinLogo,
66
LinkSimple,
77
WhatsappLogo,
8-
RedditLogo, // Added RedditLogo
8+
RedditLogo,
99
} from '@phosphor-icons/react';
1010
import { useToast } from '../hooks/useToast';
1111

1212
const ShareButtons = ({ title, url }) => {
1313
const { addToast } = useToast();
14+
const [isMobile, setIsMobile] = useState(false);
1415

15-
const shareViaWebShare = async () => {
16-
if (navigator.share) {
17-
try {
18-
await navigator.share({
19-
title: title,
20-
url: url,
21-
});
22-
console.log('Shared successfully');
23-
} catch (error) {
24-
console.error('Error sharing:', error);
25-
}
26-
} else {
27-
fallbackCopyTextToClipboard(url);
28-
}
29-
};
30-
31-
const fallbackCopyTextToClipboard = (text) => {
32-
navigator.clipboard.writeText(text).then(
33-
() => {
34-
addToast({
35-
title: 'Success',
36-
message: 'Link copied to clipboard!',
37-
duration: 3000,
38-
});
39-
},
40-
(err) => {
41-
addToast({
42-
title: 'Error',
43-
message: 'Failed to copy link!',
44-
duration: 3000,
45-
});
46-
console.error('Async: Could not copy text: ', err);
47-
},
48-
);
49-
};
50-
51-
const shareOnTwitter = () => {
52-
window.open(
53-
`https://twitter.com/intent/tweet?text=${encodeURIComponent(
54-
title,
55-
)}&url=${encodeURIComponent(url)}`,
56-
'_blank',
57-
);
58-
};
59-
60-
const shareOnFacebook = () => {
61-
window.open(
62-
`https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(url)}`,
63-
'_blank',
16+
useEffect(() => {
17+
const userAgent =
18+
typeof window.navigator === 'undefined' ? '' : navigator.userAgent;
19+
const mobile = Boolean(
20+
userAgent.match(
21+
/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile|WPDesktop/i,
22+
),
6423
);
65-
};
24+
setIsMobile(mobile);
25+
}, []);
6626

67-
const shareOnLinkedIn = () => {
68-
window.open(
69-
`https://www.linkedin.com/shareArticle?mini=true&url=${encodeURIComponent(
70-
url,
71-
)}&title=${encodeURIComponent(title)}`,
72-
'_blank',
73-
);
27+
// Fallback for copying text to clipboard when navigator.clipboard is not available
28+
const fallbackCopyTextToClipboard = (text) => {
29+
const textArea = document.createElement('textarea');
30+
textArea.value = text;
31+
textArea.style.position = 'fixed'; // Make it invisible
32+
textArea.style.left = '-9999px';
33+
document.body.appendChild(textArea);
34+
textArea.focus();
35+
textArea.select();
36+
try {
37+
document.execCommand('copy');
38+
addToast({
39+
title: 'Success',
40+
message: 'Link copied to clipboard!',
41+
duration: 3000,
42+
});
43+
} catch (err) {
44+
addToast({
45+
title: 'Error',
46+
message: 'Failed to copy link!',
47+
duration: 3000,
48+
});
49+
console.error('Fallback: Could not copy text: ', err);
50+
}
51+
document.body.removeChild(textArea);
7452
};
7553

76-
const shareOnWhatsApp = () => {
77-
window.open(
78-
`https://api.whatsapp.com/send?text=${encodeURIComponent(
79-
`${title} ${url}`,
80-
)}`,
81-
'_blank',
82-
);
83-
};
54+
const handleShare = (platformUrl, platformName) => {
55+
console.log(`Attempting to share on ${platformName}:`, {
56+
title,
57+
url,
58+
platformUrl,
59+
});
8460

85-
const shareOnReddit = () => {
86-
window.open(
87-
`https://www.reddit.com/submit?url=${encodeURIComponent(
88-
url,
89-
)}&title=${encodeURIComponent(title)}`,
90-
'_blank',
91-
);
61+
if (navigator.share && isMobile) {
62+
// Only use Web Share API on mobile
63+
console.log(`Web Share API available for ${platformName} on mobile.`);
64+
navigator
65+
.share({
66+
title: title,
67+
text: title,
68+
url: url,
69+
})
70+
.then(() => {
71+
console.log(
72+
`Shared successfully via Web Share API on ${platformName}`,
73+
);
74+
})
75+
.catch((error) => {
76+
console.error(
77+
`Error sharing via Web Share API on ${platformName}:`,
78+
error,
79+
);
80+
// Fallback to platform-specific sharing if Web Share API fails or is cancelled
81+
console.log(
82+
`Web Share API failed or cancelled, falling back for ${platformName}`,
83+
);
84+
if (platformName === 'Copy Link') {
85+
if (navigator.clipboard && navigator.clipboard.writeText) {
86+
navigator.clipboard.writeText(url).then(
87+
() => {
88+
addToast({
89+
title: 'Success',
90+
message: 'Link copied to clipboard!',
91+
duration: 3000,
92+
});
93+
},
94+
(err) => {
95+
addToast({
96+
title: 'Error',
97+
message: 'Failed to copy link!',
98+
duration: 3000,
99+
});
100+
console.error('Async: Could not copy text: ', err);
101+
},
102+
);
103+
} else {
104+
fallbackCopyTextToClipboard(url);
105+
}
106+
} else {
107+
window.open(platformUrl, '_blank');
108+
}
109+
});
110+
} else {
111+
// Fallback for browsers that do not support Web Share API or on desktop
112+
console.log(
113+
`Web Share API not supported or on desktop, falling back for ${platformName}`,
114+
);
115+
if (platformName === 'Copy Link') {
116+
if (navigator.clipboard && navigator.clipboard.writeText) {
117+
navigator.clipboard.writeText(url).then(
118+
() => {
119+
addToast({
120+
title: 'Success',
121+
message: 'Link copied to clipboard!',
122+
duration: 3000,
123+
});
124+
},
125+
(err) => {
126+
addToast({
127+
title: 'Error',
128+
message: 'Failed to copy link!',
129+
duration: 3000,
130+
});
131+
console.error('Async: Could not copy text: ', err);
132+
},
133+
);
134+
} else {
135+
fallbackCopyTextToClipboard(url);
136+
}
137+
} else {
138+
window.open(platformUrl, '_blank');
139+
}
140+
}
92141
};
93142

94143
return (
95144
<div className="flex items-center gap-2 mt-4">
96145
<span className="text-gray-400 text-sm">Share:</span>
97-
<button
98-
onClick={shareOnTwitter}
99-
className="text-gray-400 hover:text-blue-400 transition-colors"
100-
aria-label="Share on Twitter"
101-
>
102-
<TwitterLogo size={24} />
103-
</button>
104-
<button
105-
onClick={shareOnFacebook}
106-
className="text-gray-400 hover:text-blue-600 transition-colors"
107-
aria-label="Share on Facebook"
108-
>
109-
<FacebookLogo size={24} />
110-
</button>
111-
<button
112-
onClick={shareOnLinkedIn}
113-
className="text-gray-400 hover:text-blue-700 transition-colors"
114-
aria-label="Share on LinkedIn"
115-
>
116-
<LinkedinLogo size={24} />
117-
</button>
118-
<button
119-
onClick={shareOnWhatsApp}
120-
className="text-gray-400 hover:text-green-500 transition-colors"
121-
aria-label="Share on WhatsApp"
122-
>
123-
<WhatsappLogo size={24} />
124-
</button>
125-
<button
126-
onClick={shareOnReddit}
127-
className="text-gray-400 hover:text-orange-500 transition-colors"
128-
aria-label="Share on Reddit"
129-
>
130-
<RedditLogo size={24} />
131-
</button>
132-
<button
133-
onClick={shareViaWebShare}
134-
className="text-gray-400 hover:text-primary-400 transition-colors"
135-
aria-label="Copy link"
136-
>
137-
<LinkSimple size={24} />
138-
</button>
146+
{isMobile ? (
147+
<button
148+
onClick={() => handleShare(null, 'Copy Link')} // On mobile, only show Copy Link
149+
className="text-gray-400 hover:text-primary-400 transition-colors"
150+
aria-label="Copy link"
151+
>
152+
<LinkSimple size={24} />
153+
</button>
154+
) : (
155+
<>
156+
<button
157+
onClick={() =>
158+
handleShare(
159+
`https://twitter.com/intent/tweet?text=${encodeURIComponent(
160+
title,
161+
)}&url=${encodeURIComponent(url)}`,
162+
'Twitter',
163+
)
164+
}
165+
className="text-gray-400 hover:text-blue-400 transition-colors"
166+
aria-label="Share on Twitter"
167+
>
168+
<TwitterLogo size={24} />
169+
</button>
170+
<button
171+
onClick={() =>
172+
handleShare(
173+
`https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(
174+
url,
175+
)}`,
176+
'Facebook',
177+
)
178+
}
179+
className="text-gray-400 hover:text-blue-600 transition-colors"
180+
aria-label="Share on Facebook"
181+
>
182+
<FacebookLogo size={24} />
183+
</button>
184+
<button
185+
onClick={() =>
186+
handleShare(
187+
`https://www.linkedin.com/shareArticle?mini=true&url=${encodeURIComponent(
188+
url,
189+
)}&title=${encodeURIComponent(title)}`,
190+
'LinkedIn',
191+
)
192+
}
193+
className="text-gray-400 hover:text-blue-700 transition-colors"
194+
aria-label="Share on LinkedIn"
195+
>
196+
<LinkedinLogo size={24} />
197+
</button>
198+
<button
199+
onClick={() =>
200+
handleShare(
201+
`https://api.whatsapp.com/send?text=${encodeURIComponent(
202+
`${title} ${url}`,
203+
)}`,
204+
'WhatsApp',
205+
)
206+
}
207+
className="text-gray-400 hover:text-green-500 transition-colors"
208+
aria-label="Share on WhatsApp"
209+
>
210+
<WhatsappLogo size={24} />
211+
</button>
212+
<button
213+
onClick={() =>
214+
handleShare(
215+
`https://www.reddit.com/submit?url=${encodeURIComponent(
216+
url,
217+
)}&title=${encodeURIComponent(title)}`,
218+
'Reddit',
219+
)
220+
}
221+
className="text-gray-400 hover:text-orange-500 transition-colors"
222+
aria-label="Share on Reddit"
223+
>
224+
<RedditLogo size={24} />
225+
</button>
226+
<button
227+
onClick={() => handleShare(null, 'Copy Link')} // Pass null for platformUrl for Copy Link
228+
className="text-gray-400 hover:text-primary-400 transition-colors"
229+
aria-label="Copy link"
230+
>
231+
<LinkSimple size={24} />
232+
</button>
233+
</>
234+
)}
139235
</div>
140236
);
141237
};

0 commit comments

Comments
 (0)