101 lines
2.9 KiB
TypeScript
101 lines
2.9 KiB
TypeScript
import { useState, useCallback } from 'react';
|
|
import { type SharePlatform, type ShareData, getShareUrl, copyToClipboard } from '@/lib/social-utils';
|
|
import { trackShare } from '@/lib/analytics';
|
|
|
|
interface UseSocialShareOptions {
|
|
onSuccess?: (platform: SharePlatform) => void;
|
|
onError?: (platform: SharePlatform, error: Error) => void;
|
|
onCopySuccess?: () => void;
|
|
onCopyError?: (error: Error) => void;
|
|
}
|
|
|
|
interface UseSocialShareReturn {
|
|
isSharing: boolean;
|
|
isCopying: boolean;
|
|
lastSharedPlatform: SharePlatform | null;
|
|
share: (platform: SharePlatform, data: ShareData & { articleId: string }) => Promise<void>;
|
|
copyLink: (url: string) => Promise<boolean>;
|
|
}
|
|
|
|
export function useSocialShare(options: UseSocialShareOptions = {}): UseSocialShareReturn {
|
|
const [isSharing, setIsSharing] = useState(false);
|
|
const [isCopying, setIsCopying] = useState(false);
|
|
const [lastSharedPlatform, setLastSharedPlatform] = useState<SharePlatform | null>(null);
|
|
|
|
const share = useCallback(async (
|
|
platform: SharePlatform,
|
|
data: ShareData & { articleId: string }
|
|
) => {
|
|
setIsSharing(true);
|
|
setLastSharedPlatform(platform);
|
|
|
|
try {
|
|
// Track the share event
|
|
await trackShare({
|
|
articleId: data.articleId,
|
|
platform,
|
|
userAgent: navigator.userAgent,
|
|
});
|
|
|
|
// Call success callback
|
|
if (options.onSuccess) {
|
|
options.onSuccess(platform);
|
|
}
|
|
|
|
// Open share URL for social platforms (not for 'link')
|
|
if (platform !== 'link') {
|
|
const shareUrl = getShareUrl(platform, data);
|
|
window.open(shareUrl, '_blank', 'noopener,noreferrer');
|
|
}
|
|
} catch (error) {
|
|
console.error(`Failed to share on ${platform}:`, error);
|
|
|
|
// Call error callback
|
|
if (options.onError) {
|
|
options.onError(platform, error as Error);
|
|
}
|
|
|
|
// Still open the share URL even if tracking fails (for social platforms)
|
|
if (platform !== 'link') {
|
|
const shareUrl = getShareUrl(platform, data);
|
|
window.open(shareUrl, '_blank', 'noopener,noreferrer');
|
|
}
|
|
} finally {
|
|
setIsSharing(false);
|
|
}
|
|
}, [options]);
|
|
|
|
const copyLink = useCallback(async (url: string): Promise<boolean> => {
|
|
setIsCopying(true);
|
|
|
|
try {
|
|
const success = await copyToClipboard(url);
|
|
|
|
if (success && options.onCopySuccess) {
|
|
options.onCopySuccess();
|
|
} else if (!success && options.onCopyError) {
|
|
options.onCopyError(new Error('Failed to copy to clipboard'));
|
|
}
|
|
|
|
return success;
|
|
} catch (error) {
|
|
console.error('Failed to copy link:', error);
|
|
|
|
if (options.onCopyError) {
|
|
options.onCopyError(error as Error);
|
|
}
|
|
|
|
return false;
|
|
} finally {
|
|
setIsCopying(false);
|
|
}
|
|
}, [options]);
|
|
|
|
return {
|
|
isSharing,
|
|
isCopying,
|
|
lastSharedPlatform,
|
|
share,
|
|
copyLink,
|
|
};
|
|
} |