nicecode-v2/packages/biz/src/VideoPlayerCard/VideoPlayerCard.tsx
2024-03-10 16:19:57 +08:00

104 lines
3.6 KiB
TypeScript

import { Card, Space, CardProps, Spin, Button } from 'antd';
import { theme } from 'antd/lib';
import { VideoPlayer, type VideoViewRef } from '@zhst/meta';
import React, { useState, useEffect, ReactNode, useRef } from 'react';
import { CloseOutlined, LoadingOutlined } from '@ant-design/icons';
import './index.less'
export interface VideoPlayerCardProps {
windowKey?: string;
selectedWindowKey?: string;
showType?: 'video' | "image";
imgSrc?: string;
videoSrc?: string;
cardProps?: CardProps;
errorReasonText?: string;
isWindowLoading?: boolean;
size?: 'large' | 'small';
title?: string | ReactNode
handleCloseButtonClick?: (key?: string) => void;
handleWindowClick?: (key?: string) => void;
}
export const VideoPlayerCard: React.FC<VideoPlayerCardProps> = (props) => {
const componentName = `zhst-biz-video-player-card`;
const { showType, imgSrc, videoSrc, cardProps, isWindowLoading, errorReasonText, size, title, handleCloseButtonClick, handleWindowClick, windowKey, selectedWindowKey = '' } = props;
const [cardContent, setCardContent] = useState<JSX.Element | null>(null);
const { useToken } = theme
const { token } = useToken()
const videoRef = useRef<VideoViewRef>(null)
const selectedBorderStyle = {
border: `2px solid ${token.colorPrimary}`, boxShadow: " 0px 2px 9px 0px rgba(0,0,0,0.16)"
}
const cardStyle: React.CSSProperties = {
...(size === 'large' ? { height: 931 } : { height: 456, cursor: 'pointer' }),
...(size === 'small' && selectedWindowKey === windowKey ? selectedBorderStyle : {})
};
const videoPlayerCardStyle = size === 'small' ? { width: "calc(50% - 20px)" } : { flex: 1 }
useEffect(() => {
if (!isWindowLoading && (videoSrc || imgSrc)) {
let contentElement: JSX.Element | null = null;
if (videoSrc) {
contentElement = (
<VideoPlayer ref={videoRef} url={videoSrc} />
);
videoRef.current?.setShowCrop(true)
} else if (imgSrc) {
contentElement = (
<img
alt="首帧图"
src={imgSrc}
style={{ width: "100%", height: "100%", display: 'block' }}
/>
);
}
setCardContent(contentElement);
} else {
setCardContent(null)
}
}, [showType, imgSrc, videoSrc, isWindowLoading]);
return (
<div className={componentName} onClick={() => { handleWindowClick?.(windowKey) }} style={videoPlayerCardStyle}>
<Card
title={
<Space style={{ width: "100%", justifyContent: "space-between" }}>
<div>{title}</div>
<div className="card-close-button">
<Button type="text" onClick={() => { handleCloseButtonClick?.(windowKey) }} >
<CloseOutlined />
</Button>
</div>
</Space>}
style={{ display: "flex", flexDirection: "column", borderRadius: 4, overflow: "hidden", ...cardStyle }}
bodyStyle={{ flex: 1 }}
{...cardProps}
>
{cardContent ? (
<>
{cardContent}
</>
) : (
<div style={{ backgroundColor: '#000', height: '100%', display: 'flex', padding: '20px', boxSizing: 'border-box' }}>
{
isWindowLoading ?
<div style={{ flex: 1, display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
<Spin indicator={<LoadingOutlined style={{ fontSize: 24 }} />} />
</div>
: !!errorReasonText && <span style={{ color: token.colorError }}>{errorReasonText}</span>
}
</div>
)}
{/* 其他内容 */}
</Card>
</div>
);
};
export default VideoPlayerCard;