import { format } from 'date-fns' import { Clock, Eye, Hash, Maximize, Users } from 'lucide-react' import React from 'react' import { isDark } from '../../../../utils/theme' import { DefaultLayout } from '../../../components/DefaultLayout' import { QRCodeWithAvatar } from '../../../components/QRCodeWithAvatar' import type { PosterProps } from '../../../types/ctx' import { DouyinCommentIcon, DouyinFavoriteIcon, DouyinLikeIcon, DouyinShareIcon } from '../../components/Icons' import type { DouyinDynamicData } from './types' /** * 抖音Logo头部组件 * @param props 组件属性 * @returns JSX元素 */ const DouyinHeader: React.FC<{ useDarkTheme?: boolean }> = ({ useDarkTheme }) => { return (
抖音Logo
记录美好生活
) } /** * 作品封面组件 * @param props 组件属性 * @returns JSX元素 */ const CoverSection: React.FC<{ imageUrl: string }> = ({ imageUrl }) => { return (
封面
) } /** * 作品信息组件 * @param props 组件属性 * @returns JSX元素 */ const InfoSection: React.FC> = (props) => { return (
{props.data.dianzan}点赞
·
{props.data.pinglun}评论
·
{props.data.shouchang}收藏
·
{props.data.share}分享
发布于: {props.data.create_time}
图片生成于: {format(new Date(), 'yyyy-MM-dd HH:mm:ss')}
) } /** * 用户信息组件 * @param props 组件属性 * @returns JSX元素 */ const UserInfoSection: React.FC & { coCreatorCount?: number }> = (props) => { return (
{/* 头像和用户名/抖音号 */}
{/* 头像 */}
头像
{/* 用户名和抖音号 - 纵向排列 */}
@{props.data.username}
抖音号: {props.data.抖音号}
{/* 用户统计信息 */}
获赞
{props.data.获赞}
关注
{props.data.关注}
粉丝
{props.data.粉丝}
) } /** 共创者信息 */ const CoCreatorsInfo: React.FC<{ info?: DouyinDynamicData['cooperation_info'] }> = ({ info }) => { const creators = info?.co_creators ?? [] if (creators.length === 0) return null const items = creators.slice(0, 50) // 根据容器宽度,计算可显示的条目数;剩余用省略占位符 const listRef = React.useRef(null) const [visibleCount, setVisibleCount] = React.useState(items.length) React.useEffect(() => { const calc = () => { const el = listRef.current if (!el) return const containerWidth = el.offsetWidth // 每项实际宽度约152px(头像w-38),间距gap-8=32px,右内边距pr-2=8px const ITEM_W = 152 const GAP = 32 const PAD_R = 8 const capacity = Math.floor((containerWidth - PAD_R) / (ITEM_W + GAP)) const needEllipsis = items.length > capacity const nextVisible = needEllipsis ? Math.max(0, capacity - 1) : items.length setVisibleCount(nextVisible) } calc() window.addEventListener('resize', calc) return () => window.removeEventListener('resize', calc) }, [items.length]) return (
{items.slice(0, visibleCount).map((c, idx) => { const avatar = c.avatar_url return (
共创者头像
{c.nickname || '未提供'}
{c.role_title || '未提供'}
) })} {items.length > visibleCount && (
···
还有{items.length - visibleCount}人
共创
)}
) } /** * 抖音动态组件 * @param props 组件属性 * @returns JSX元素 */ export const DouyinDynamic: React.FC> = (props) => { const coCreatorCount = props.data.cooperation_info?.co_creator_nums ?? props.data.cooperation_info?.co_creators?.length ?? undefined return (
{/* 头部Logo */}
{/* 封面 */}
{/* 作品信息 */}
{coCreatorCount && coCreatorCount > 0 && (
{coCreatorCount}人共创
)}
{/* 底部信息区域 */}
{/* 左侧:用户信息 */} {/* 右侧:二维码 */}
) } export default DouyinDynamic