125 lines
3.5 KiB
TypeScript
125 lines
3.5 KiB
TypeScript
export type SharePlatform = 'facebook' | 'twitter' | 'instagram' | 'tiktok' | 'telegram' | 'link';
|
|
|
|
export interface ShareData {
|
|
title: string;
|
|
url: string;
|
|
excerpt?: string;
|
|
image?: string;
|
|
tags?: string[];
|
|
}
|
|
|
|
export const getShareUrl = (
|
|
platform: Exclude<SharePlatform, 'link'>,
|
|
data: ShareData
|
|
): string => {
|
|
const { title, url } = data;
|
|
const encodedUrl = encodeURIComponent(url);
|
|
const encodedTitle = encodeURIComponent(title);
|
|
|
|
switch (platform) {
|
|
case 'facebook':
|
|
return `https://www.facebook.com/sharer/sharer.php?u=${encodedUrl}`;
|
|
case 'twitter':
|
|
return `https://twitter.com/intent/tweet?url=${encodedUrl}&text=${encodedTitle}`;
|
|
case 'instagram':
|
|
// Instagram doesn't have a web share URL, will use Web Share API in component
|
|
return url;
|
|
case 'tiktok':
|
|
// TikTok has limited web share support, will use Web Share API in component
|
|
return url;
|
|
case 'telegram':
|
|
return `https://t.me/share/url?url=${encodedUrl}&text=${encodedTitle}`;
|
|
default:
|
|
return url;
|
|
}
|
|
};
|
|
|
|
export const copyToClipboard = async (text: string): Promise<boolean> => {
|
|
try {
|
|
if (navigator.clipboard && window.isSecureContext) {
|
|
await navigator.clipboard.writeText(text);
|
|
return true;
|
|
} else {
|
|
// Fallback for older browsers
|
|
const textArea = document.createElement('textarea');
|
|
textArea.value = text;
|
|
textArea.style.position = 'fixed';
|
|
textArea.style.left = '-999999px';
|
|
textArea.style.top = '-999999px';
|
|
document.body.appendChild(textArea);
|
|
textArea.focus();
|
|
textArea.select();
|
|
const success = document.execCommand('copy');
|
|
document.body.removeChild(textArea);
|
|
return success;
|
|
}
|
|
} catch (error) {
|
|
console.error('Failed to copy to clipboard:', error);
|
|
return false;
|
|
}
|
|
};
|
|
|
|
export const getPlatformIcon = (platform: SharePlatform): string => {
|
|
switch (platform) {
|
|
case 'facebook':
|
|
return 'Facebook';
|
|
case 'twitter':
|
|
return 'Twitter';
|
|
case 'instagram':
|
|
return 'Instagram';
|
|
case 'tiktok':
|
|
return 'TikTok';
|
|
case 'telegram':
|
|
return 'Send';
|
|
case 'link':
|
|
return 'Link';
|
|
default:
|
|
return 'Share2';
|
|
}
|
|
};
|
|
|
|
export const getPlatformLabel = (platform: SharePlatform): string => {
|
|
switch (platform) {
|
|
case 'facebook':
|
|
return 'Facebook';
|
|
case 'twitter':
|
|
return 'Twitter';
|
|
case 'instagram':
|
|
return 'Instagram';
|
|
case 'tiktok':
|
|
return 'TikTok';
|
|
case 'telegram':
|
|
return 'Telegram';
|
|
case 'link':
|
|
return 'Copy Link';
|
|
default:
|
|
return 'Share';
|
|
}
|
|
};
|
|
|
|
export const generateSocialMetaTags = (data: ShareData & { articleId: string }) => {
|
|
const { title, excerpt, image, url } = data;
|
|
|
|
// Default values if not provided
|
|
const ogTitle = title || 'Placebo.mk - Sarcastic News from Macedonia';
|
|
const ogDescription = excerpt || 'Latest news and articles from Macedonia with a sarcastic twist';
|
|
const ogImage = image || '/placeholder-image.jpg';
|
|
const ogUrl = url || (typeof window !== 'undefined' ? window.location.href : '');
|
|
|
|
return {
|
|
ogTitle,
|
|
ogDescription,
|
|
ogImage,
|
|
ogUrl,
|
|
ogType: 'article' as const,
|
|
twitterCard: 'summary_large_image' as const,
|
|
twitterTitle: ogTitle,
|
|
twitterDescription: ogDescription,
|
|
twitterImage: ogImage,
|
|
};
|
|
};
|
|
|
|
export const truncateForTwitter = (text: string, maxLength: number = 280): string => {
|
|
if (text.length <= maxLength) return text;
|
|
return text.substring(0, maxLength - 3) + '...';
|
|
}; |