返回 AiToEarn
VideoChooseItem.tsx
1 import React, { ForwardedRef, forwardRef, memo, useMemo } from 'react';
2 import { IVideoChooseItem } from '@/views/publish/children/videoPage/videoPage';
3 import { Alert, Avatar, Button, Tooltip } from 'antd';
4 import { AccountPlatInfoMap } from '@/views/account/comment';
5 import {
6 CaretRightOutlined,
7 DeleteOutlined,
8 EditOutlined,
9 PlusOutlined,
10 VideoCameraFilled,
11 SwapOutlined,
12 ExclamationCircleOutlined,
13 } from '@ant-design/icons';
14 import { useVideoPageStore } from '@/views/publish/children/videoPage/useVideoPageStore';
15 import { useShallow } from 'zustand/react/shallow';
16 import VideoChoose from '@/components/Choose/VideoChoose';
17 import { formatSeconds } from '@/utils';
18 import { AccountStatus } from '../../../../../../commont/AccountEnum';
19 import { AccountChooseType } from '../page';
20
21 export interface IVideoChooseItemRef {}
22
23 export interface IVideoChooseItemProps {
24 videoChooseItem: IVideoChooseItem;
25 // 用户单选触发
26 onAccountOneChoose: (id: string, type: AccountChooseType) => void;
27 }
28
29 // 选择视频完成后渲染的列表 item
30 const VideoChooseItem = memo(
31 forwardRef(
32 (
33 { videoChooseItem, onAccountOneChoose }: IVideoChooseItemProps,
34 ref: ForwardedRef<IVideoChooseItemRef>,
35 ) => {
36 // 数据是否准备完毕
37 const prepareEnd = !!(videoChooseItem.video && videoChooseItem.account);
38 const {
39 deleteAloneVideo,
40 aloneAdd,
41 deleteData,
42 setCurrChooseAccountId,
43 setVideoPubSetModalOpen,
44 setLoadingPageLoading,
45 accountRestart,
46 } = useVideoPageStore(
47 useShallow((state) => ({
48 deleteAloneVideo: state.deleteAloneVideo,
49 aloneAdd: state.aloneAdd,
50 deleteData: state.deleteData,
51 setCurrChooseAccountId: state.setCurrChooseAccountId,
52 setVideoPubSetModalOpen: state.setVideoPubSetModalOpen,
53 setLoadingPageLoading: state.setLoadingPageLoading,
54 accountRestart: state.accountRestart,
55 })),
56 );
57
58 // 分辨率是否合规
59 const isDpiCompliance = useMemo(() => {
60 if (!videoChooseItem.video) return true;
61 return (
62 videoChooseItem.video.height < 640 ||
63 videoChooseItem.video.width < 480
64 );
65 }, []);
66
67 return (
68 <div className="videoChooseItem">
69 <div className="videoChooseItem-core">
70 <div
71 className="videoChooseItem-left"
72 key={videoChooseItem.video?.videoPath}
73 >
74 {videoChooseItem.video ? (
75 <>
76 <div className="videoChooseItem-video">
77 <div
78 className="videoChooseItem-video-close"
79 onClick={() => deleteAloneVideo(videoChooseItem.id)}
80 >
81 x
82 </div>
83 <div className="videoChooseItem-video-play">
84 <img src={videoChooseItem.video.cover.imgUrl} />
85 {prepareEnd && (
86 <div
87 className="videoChooseItem-video-play-click"
88 onClick={() => {
89 setVideoPubSetModalOpen(true);
90 setCurrChooseAccountId(videoChooseItem.id);
91 }}
92 >
93 <CaretRightOutlined />
94 </div>
95 )}
96 </div>
97 </div>
98 <div className="videoChooseItem-left-info">
99 <p
100 className="videoChooseItem-left-title"
101 title={videoChooseItem.video?.filename}
102 >
103 {videoChooseItem.video?.filename}
104 </p>
105 <div className="videoChooseItem-left-bottom">
106 <div className="videoChooseItem-left-bottom-item">
107 <label>时长</label>
108 <span>
109 {formatSeconds(videoChooseItem.video.duration)}
110 </span>
111 </div>
112 <div
113 className={[
114 'videoChooseItem-left-bottom-item',
115 isDpiCompliance &&
116 'videoChooseItem-left-bottom-item--warning',
117 ].join(' ')}
118 >
119 <label>分辨率</label>
120 <span>
121 {videoChooseItem.video.width}*
122 {videoChooseItem.video.height}
123 </span>
124 {isDpiCompliance && (
125 <Tooltip title="视频清晰度过低,有概率被平台限流或不能发布,推荐您上传 460*640 分辨率以上的视频">
126 <ExclamationCircleOutlined />
127 </Tooltip>
128 )}
129 </div>
130 </div>
131 </div>
132 </>
133 ) : (
134 <div className="videoChooseItem-left-chooseVideo">
135 <VideoChoose
136 onChoose={(videoFile) => {
137 setLoadingPageLoading(false);
138 aloneAdd({
139 video: videoFile,
140 id: videoChooseItem.id,
141 });
142 }}
143 onStartShoose={() => {
144 setLoadingPageLoading(true);
145 }}
146 >
147 <VideoCameraFilled />
148 <span className="videoChooseItem-left-chooseVideo-name">
149 添加视频
150 </span>
151 </VideoChoose>
152 </div>
153 )}
154 </div>
155
156 <div className="videoChooseItem-right">
157 {videoChooseItem.account ? (
158 <div className="videoChooseItem-account">
159 <div className="videoChooseItem-account-avatar">
160 <Avatar src={videoChooseItem.account.avatar} size="large" />
161 <div
162 className="videoChooseItem-account-avatar-replace"
163 onClick={() => {
164 onAccountOneChoose(
165 videoChooseItem.id,
166 AccountChooseType.Replace,
167 );
168 }}
169 >
170 <SwapOutlined />
171 </div>
172 </div>
173 <div className="videoChooseItem-account-con">
174 <div className="videoChooseItem-account-top">
175 <Tooltip title={videoChooseItem.account.nickname}>
176 <span className="videoChooseItem-account-top-name">
177 {videoChooseItem.account.nickname}
178 </span>
179 </Tooltip>
180 <img
181 src={
182 AccountPlatInfoMap.get(videoChooseItem.account.type)
183 ?.icon
184 }
185 />
186 </div>
187 {videoChooseItem.account.status ===
188 AccountStatus.DISABLE && (
189 <Alert
190 message="登录失效"
191 type="error"
192 showIcon
193 onClick={() => {
194 accountRestart(videoChooseItem.account!.type);
195 }}
196 />
197 )}
198 </div>
199 </div>
200 ) : (
201 <div
202 className="videoChooseItem-noAccount"
203 onClick={() => {
204 onAccountOneChoose(
205 videoChooseItem.id,
206 AccountChooseType.Radio,
207 );
208 }}
209 >
210 <div className="videoChooseItem-noAccount-icon">
211 <PlusOutlined />
212 </div>
213 <span>添加账号</span>
214 </div>
215 )}
216 </div>
217 </div>
218
219 <div className="videoChooseItem-options">
220 <Button
221 color="primary"
222 type="text"
223 size="small"
224 icon={<EditOutlined />}
225 disabled={!prepareEnd}
226 onClick={() => {
227 setVideoPubSetModalOpen(true);
228 setCurrChooseAccountId(videoChooseItem.id);
229 }}
230 >
231 发布设置
232 </Button>
233 <Button
234 onClick={() => {
235 deleteData(videoChooseItem.id);
236 }}
237 type="text"
238 size="small"
239 danger
240 icon={<DeleteOutlined />}
241 >
242 删除
243 </Button>
244 </div>
245 </div>
246 );
247 },
248 ),
249 );
250 VideoChooseItem.displayName = 'VideoChooseItem';
251
252 export default VideoChooseItem;
253
253 lines Plain Text