'use client'; import { useState } from 'react'; import type { PlazaStats } from '@/types/plaza'; import { LoginPrompt } from '@/components/auth/LoginPrompt'; import { formatCount } from '@/lib/format'; import { PlazaApiError, togglePostReaction } from '@/lib/api'; import { plazaPath, siteOrigin } from '@/lib/site'; type PostActionsProps = { postId: string; stats: PlazaStats; viewerReacted?: { liked: boolean; collected: boolean } | null; }; export function PostActions({ postId, stats, viewerReacted }: PostActionsProps) { const [liked, setLiked] = useState(viewerReacted?.liked ?? false); const [collected, setCollected] = useState(viewerReacted?.collected ?? false); const [likeCount, setLikeCount] = useState(stats.like_count); const [collectCount, setCollectCount] = useState(stats.collect_count); const [shareHint, setShareHint] = useState(''); const [shareOpen, setShareOpen] = useState(false); const [loginOpen, setLoginOpen] = useState(false); const [busy, setBusy] = useState<'like' | 'collect' | null>(null); const handleReaction = async (type: 'like' | 'collect') => { if (busy) return; const active = type === 'like' ? liked : collected; setBusy(type); try { await togglePostReaction(postId, type, active); if (type === 'like') { setLiked(!active); setLikeCount((value) => Math.max(0, value + (active ? -1 : 1))); } else { setCollected(!active); setCollectCount((value) => Math.max(0, value + (active ? -1 : 1))); } } catch (error) { if (error instanceof PlazaApiError && error.code === 'unauthorized') { setLoginOpen(true); } } finally { setBusy(null); } }; const shareUrl = `${siteOrigin()}${plazaPath(`p/${postId}`)}`; const shareImageUrl = `${siteOrigin()}${plazaPath(`p/${postId}/opengraph-image`)}`; const handleShare = async () => { try { await navigator.clipboard.writeText(shareUrl); setShareHint('链接已复制'); } catch { setShareHint(shareUrl); } try { await togglePostReaction(postId, 'share', false); } catch { // 未登录时忽略 share 计数 } window.setTimeout(() => setShareHint(''), 2500); }; const handleCopyImageLink = async () => { try { await navigator.clipboard.writeText(shareImageUrl); setShareHint('分享图链接已复制'); } catch { setShareHint(shareImageUrl); } setShareOpen(false); window.setTimeout(() => setShareHint(''), 2500); }; return ( <>
{shareOpen ? (
预览分享图
) : null} {shareHint ? {shareHint} : null}
setLoginOpen(false)} /> ); }