'use client'; import React, { useState, useEffect } from 'react'; import { Modal, Button, Spin, QRCode, message } from 'antd'; import { Youtube, Instagram, Share2, Copy, ExternalLink, Loader2 } from 'lucide-react'; import { shareApiUrl } from '@/lib/env'; import { VideoShareForm } from './VideoShareForm'; interface ShareModalProps { /** 是否显示弹框 */ visible: boolean; /** 关闭弹框回调 */ onClose: () => void; /** 项目信息 */ project: { project_id: string; name?: string; final_video_url?: string; final_simple_video_url?: string; }; } interface SharePlatform { id: string; name: string; icon: React.ReactNode; color: string; description: string; apiPath: string | null; } const sharePlatforms: SharePlatform[] = [ { id: 'youtube', name: 'YouTube', icon: , color: 'text-red-500', description: 'Share to YouTube', apiPath: '/api/video-share/youtube/auth/url' }, { id: 'tiktok', name: 'TikTok', icon: , color: 'text-black', description: 'Share to TikTok', apiPath: '/api/video-share/tiktok/auth/url' }, { id: 'instagram', name: 'Instagram', icon: , color: 'text-pink-500', description: 'Share to Instagram', apiPath: null // 开发中 }, { id: 'reddit', name: 'Reddit', icon: , color: 'text-orange-500', description: 'Share to Reddit', apiPath: '/api/video-share/reddit/auth/url' }, { id: 'twitter', name: 'X (Twitter)', icon: , color: 'text-blue-400', description: 'Share to X (Twitter)', apiPath: '/api/video-share/x/auth/url' }, { id: 'copy', name: 'Copy Link', icon: , color: 'text-gray-400', description: 'Copy video link to clipboard', apiPath: null // 本地功能 } ]; export default function ShareModal({ visible, onClose, project }: ShareModalProps) { const [loadingPlatform, setLoadingPlatform] = useState(null); const [showShareForm, setShowShareForm] = useState(false); const [authError, setAuthError] = useState(null); const [selectedPlatform, setSelectedPlatform] = useState(''); /** * 监听 URL 参数变化,处理授权回调 */ useEffect(() => { if (!visible) return; const urlParams = new URLSearchParams(window.location.search); const platform = urlParams.get('platform'); const status = urlParams.get('status'); const error = urlParams.get('error'); if (platform && status) { // 统一转换成小写 const normalizedPlatform = platform.toLowerCase(); setSelectedPlatform(normalizedPlatform); if (status === 'success') { setAuthError(null); setShowShareForm(true); message.success(`${platform} 授权成功!`); } else if (status === 'error') { setAuthError(error || '授权失败,请重试'); setShowShareForm(true); message.error(`${platform} 授权失败`); } // 清理 URL 参数 const newUrl = window.location.pathname; window.history.replaceState({}, '', newUrl); } }, [visible]); /** * 获取用户ID */ const getUserId = () => { const currentUser = JSON.parse(localStorage.getItem('currentUser') || '{}'); return currentUser.id || currentUser.userId; }; /** * 通用平台授权检查 */ const checkPlatformAuth = async (apiPath: string, platformName: string, platformId: string) => { const userId = getUserId(); if (!userId) { message.error('用户ID不存在,请先登录'); return; } const response = await fetch(`${shareApiUrl}${apiPath}?user_id=${userId}`, { method: 'GET', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${localStorage.getItem('token') || ''}`, 'ngrok-skip-browser-warning': 'true' } }); const data = await response.json(); if (data.successful && data.code === 0) { const { has_valid_token, auth_url } = data.data; if (!has_valid_token) { // 需要用户授权,跳转到授权页面 window.open(auth_url, '_blank'); message.info('请在新窗口完成授权'); } else { // 用户已授权,直接显示上传表单 setSelectedPlatform(platformId); setAuthError(null); setShowShareForm(true); message.success(`${platformName} 已授权,可以直接上传视频`); } } else { message.error(data.message || `获取${platformName}授权信息失败`); } }; /** * 处理平台分享 */ const handlePlatformShare = async (platformId: string) => { setLoadingPlatform(platformId); try { const platform = sharePlatforms.find(p => p.id === platformId); if (!platform) return; if (platformId === 'copy') { await handleCopyLink(); } else if (platformId === 'instagram') { message.info('Instagram分享功能正在开发中,敬请期待!'); } else if (platform.apiPath) { await checkPlatformAuth(platform.apiPath, platform.name, platformId); } else { console.log(`Share to ${platformId} not implemented yet`); } } catch (error) { console.error(`Share to ${platformId} failed:`, error); message.error(`操作失败:${error instanceof Error ? error.message : '未知错误'}`); } finally { setLoadingPlatform(null); } }; /** * 复制链接处理 */ const handleCopyLink = async () => { try { const videoUrl = project.final_video_url || project.final_simple_video_url; if (videoUrl) { await navigator.clipboard.writeText(videoUrl); message.success('视频链接已复制到剪贴板'); } else { message.error('视频链接不存在'); } } catch (error) { console.error('复制链接失败:', error); message.error('复制链接失败,请手动复制'); } }; // 获取视频链接用于生成二维码 const getVideoUrl = () => { return project.final_video_url || project.final_simple_video_url || ''; }; /** * 处理视频分享提交成功 */ const handleVideoShare = (videoUrl: string, videoName: string) => { // 上传成功后的处理 setShowShareForm(false); setSelectedPlatform(''); setAuthError(null); // 延迟关闭主对话框,让用户看到成功提示 setTimeout(() => { onClose(); }, 1000); }; /** * 关闭分享表单 */ const handleCancelShareForm = () => { setShowShareForm(false); setAuthError(null); setSelectedPlatform(''); }; return ( {showShareForm ? `分享到 ${selectedPlatform}` : 'Share Video'} } open={visible} onCancel={onClose} footer={null} width={showShareForm ? 500 : 720} className="share-modal" styles={{ content: { backgroundColor: 'rgba(27, 27, 27, 0.8)', backdropFilter: 'blur(20px)', border: '1px solid rgba(255, 255, 255, 0.1)', }, header: { backgroundColor: 'rgba(27, 27, 27, 0.6)', backdropFilter: 'blur(20px)', borderBottom: '1px solid rgba(255, 255, 255, 0.1)', }, body: { backgroundColor: 'transparent', } }} > {showShareForm ? ( /* 显示视频分享表单 */ ) : ( /* 显示平台选择界面 */
{/* 左侧:二维码区域 */}
{/* 右侧:平台选择区域 */}

Share to Platform

Choose a platform to share your video

{/* 分享平台选择 */}
{sharePlatforms.map((platform) => ( ))}
)}
); }