update 删除
This commit is contained in:
parent
ae6dd65e7a
commit
4cdcfb0636
@ -2,7 +2,7 @@ import {useSortable} from "@dnd-kit/sortable";
|
||||
import {useSetState} from "ahooks";
|
||||
import React, {useEffect} from "react";
|
||||
import {clsx} from "clsx";
|
||||
import {Checkbox, Popconfirm} from "antd";
|
||||
import {App, Checkbox, Popconfirm} from "antd";
|
||||
import {CheckCircleFilled, MenuOutlined, MinusCircleFilled, LoadingOutlined} from "@ant-design/icons";
|
||||
|
||||
import ImageCover from '@/assets/images/cover.png'
|
||||
@ -17,6 +17,7 @@ type Props = {
|
||||
index?: number;
|
||||
checked?: boolean;
|
||||
active?: boolean;
|
||||
playing?: boolean;
|
||||
onCheckedChange?: (checked: boolean) => void;
|
||||
onPlay?: () => void;
|
||||
onEdit?: () => void;
|
||||
@ -29,7 +30,7 @@ type Props = {
|
||||
|
||||
export const VideoListItem = (
|
||||
{
|
||||
id, video, onRemove, checked,
|
||||
id, video, onRemove, checked,playing,
|
||||
onCheckedChange, onEdit, active, editable,
|
||||
className, sortable, type, index,onItemClick
|
||||
}: Props) => {
|
||||
@ -45,11 +46,19 @@ export const VideoListItem = (
|
||||
}, [checked])
|
||||
|
||||
const generating = (type == 'create' && video.status == VideoStatus.Generating )
|
||||
|
||||
const {modal} = App.useApp()
|
||||
const handleDelete = () => {
|
||||
if(!onRemove) return;
|
||||
modal.confirm({
|
||||
title: '提示',
|
||||
centered: true,
|
||||
content: '是否要删除该视频',
|
||||
onOk: onRemove,
|
||||
})
|
||||
}
|
||||
return <div
|
||||
className={`video-item ${className}`}
|
||||
ref={setNodeRef} style={{transform: `translateY(${transform?.y || 0}px)`,}}
|
||||
onClick={onItemClick}
|
||||
>
|
||||
<div className={`list-row ${generating ? 'disabled' : ''} ${active?'playing':''}`}>
|
||||
<div
|
||||
@ -57,7 +66,7 @@ export const VideoListItem = (
|
||||
{... (sortable && !generating?listeners:{})}
|
||||
{... (sortable && !generating?attributes:{})}
|
||||
>{index}</div>
|
||||
<div className="col cover cursor-pointer">
|
||||
<div className="col cover cursor-pointer" onClick={onItemClick}>
|
||||
<div className="relative">
|
||||
<img className="w-[100px] h-[56px] object-cover" src={video.cover || ImageCover}/>
|
||||
{generating &&
|
||||
@ -66,7 +75,7 @@ export const VideoListItem = (
|
||||
</div>
|
||||
}
|
||||
{/* && active*/}
|
||||
{!generating && active && <div className={'absolute rounded inset-0 bg-black/30 text-sm text-white flex items-center justify-center'}>
|
||||
{!generating && playing && <div className={'absolute rounded inset-0 bg-black/30 text-sm text-white flex items-center justify-center'}>
|
||||
<div className="text-center">
|
||||
<IconPlaying className="inline-block text-xl" />
|
||||
<div>播放中</div>
|
||||
@ -104,14 +113,7 @@ export const VideoListItem = (
|
||||
<IconEdit/>
|
||||
</button>}
|
||||
|
||||
{onRemove && <Popconfirm
|
||||
title={<div style={{minWidth: 150}}><span>请确认删除此视频?</span></div>}
|
||||
onConfirm={onRemove}
|
||||
okText="删除"
|
||||
cancelText="取消"
|
||||
>
|
||||
<button className="hover:text-blue-500"><IconDelete/></button>
|
||||
</Popconfirm>}
|
||||
{onRemove && <button className="hover:text-blue-500" onClick={handleDelete}><IconDelete/></button>}
|
||||
<Checkbox checked={state.checked} onChange={() => {
|
||||
if (onCheckedChange) {
|
||||
onCheckedChange(!state.checked)
|
||||
|
@ -174,6 +174,12 @@ export default function LiveIndex() {
|
||||
// 计算总时长
|
||||
return videoData.reduce((sum, v) => sum + Math.ceil(v.video_duration / 1000), 0);
|
||||
}, [videoData])
|
||||
// 根据当前播放index计算已经播放时长
|
||||
const currentTotalDuration = useMemo(() => {
|
||||
if (state.activeIndex == -1 || !videoData || videoData.length == 0) return 0;
|
||||
// 计算总时长
|
||||
return videoData.filter((_,index)=>(index <= state.activeIndex)).reduce((sum, v) => sum + Math.ceil(v.video_duration / 1000), 0);
|
||||
}, [videoData])
|
||||
|
||||
const currentSelectedId = useMemo(() => {
|
||||
if (state.activeIndex < 0 || state.activeIndex >= videoData.length) return [];
|
||||
@ -185,16 +191,15 @@ export default function LiveIndex() {
|
||||
{contextHolder}
|
||||
<div className="flex">
|
||||
<div className="video-player-container mr-8 flex flex-col">
|
||||
<div className="text-center text-base">数字人直播间</div>
|
||||
<div className="text-center text-base">
|
||||
<span>{formatDuration(currentTotalDuration)} / {formatDuration(totalDuration)}</span>
|
||||
</div>
|
||||
<div className="video-player flex justify-center flex-1 mt-5">
|
||||
<div className="live-player relative rounded overflow-hidden w-[360px] h-[636px]"
|
||||
style={{backgroundColor: 'hsl(210, 100%, 48%)'}}>
|
||||
<Player ref={player} className="w-[360px] h-[636px] bg-white" muted={true}/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-4 text-center text-sm">
|
||||
<span>视频时长: {formatDuration(totalDuration)}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="video-list-container video-list-sort-container flex-1">
|
||||
@ -282,17 +287,17 @@ export default function LiveIndex() {
|
||||
</div>
|
||||
<div className="page-action">
|
||||
<ButtonToTop visible={state.showToTop} onClick={() => scrollerRef.current?.scrollToPosition(0)}/>
|
||||
<ButtonBatch
|
||||
className='bg-gray-300 hover:bg-gray-400 text-white'
|
||||
selected={currentSelectedId}
|
||||
emptyMessage={`请选择要删除的视频`}
|
||||
confirmMessage={`是否删除当前的${currentSelectedId.length}条视频?`}
|
||||
onSuccess={loadList}
|
||||
onProcess={processDeleteVideo}
|
||||
>
|
||||
<span className={'text'}>批量删除</span>
|
||||
<IconDelete/>
|
||||
</ButtonBatch>
|
||||
{checkedIdArray.length > 0 && <ButtonBatch
|
||||
className='bg-gray-300 hover:bg-gray-400 text-white'
|
||||
selected={checkedIdArray}
|
||||
emptyMessage={`请选择要删除的视频`}
|
||||
confirmMessage={`是否删除当前的${checkedIdArray.length}条视频?`}
|
||||
onSuccess={loadList}
|
||||
onProcess={processDeleteVideo}
|
||||
>
|
||||
<span className={'text'}>批量删除</span>
|
||||
<IconDelete/>
|
||||
</ButtonBatch>}
|
||||
</div>
|
||||
</div>)
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
import {Checkbox, Empty, Modal} from "antd";
|
||||
import {Checkbox, Empty} from "antd";
|
||||
import React, {useEffect, useMemo, useRef, useState} from "react";
|
||||
import {DndContext} from "@dnd-kit/core";
|
||||
import {arrayMove, SortableContext} from "@dnd-kit/sortable";
|
||||
@ -9,7 +9,7 @@ import ArticleEditModal from "@/components/article/edit-modal.tsx";
|
||||
import {deleteByIds, getList, modifyOrder, VideoStatus} from "@/service/api/video.ts";
|
||||
import {formatDuration} from "@/util/strings.ts";
|
||||
import ButtonBatch from "@/components/button-batch.tsx";
|
||||
import {showToast} from "@/components/message.ts";
|
||||
import {showErrorToast, showToast} from "@/components/message.ts";
|
||||
import {Player, PlayerInstance} from "@/components/video/player.tsx";
|
||||
import ButtonPush2Room from "@/pages/video/components/button-push2room.tsx";
|
||||
import ButtonToTop from "@/components/scoller/button-to-top.tsx";
|
||||
@ -21,7 +21,6 @@ export default function VideoIndex() {
|
||||
const [editId, setEditId] = useState(-1)
|
||||
const loc = useLocation()
|
||||
const [videoData, setVideoData] = useState<VideoInfo[]>([])
|
||||
const [modal, contextHolder] = Modal.useModal()
|
||||
const player = useRef<PlayerInstance | null>(null)
|
||||
const scrollerRef = useRef<InfiniteScrollerRef|null>(null)
|
||||
const [state, setState] = useSetState({
|
||||
@ -101,9 +100,14 @@ export default function VideoIndex() {
|
||||
}
|
||||
}
|
||||
},[videoData,scrollerRef])
|
||||
const processDeleteVideo = async (ids: Id[]) => {
|
||||
deleteByIds(ids).then(() => {
|
||||
showToast('删除成功!', 'success')
|
||||
loadList()
|
||||
}).catch(showErrorToast)
|
||||
}
|
||||
|
||||
return (<div className="container py-10 page-live">
|
||||
{contextHolder}
|
||||
<div className="flex">
|
||||
<div className="video-player-container mr-16 w-[360px] flex flex-col">
|
||||
<div className="text-center text-base text-gray-400">预览视频 - 点击视频列表播放</div>
|
||||
@ -176,7 +180,8 @@ export default function VideoIndex() {
|
||||
id={v.id}
|
||||
key={index}
|
||||
type={'create'}
|
||||
active={state.playingIndex == index}
|
||||
active={checkedIdArray.includes(v.id)}
|
||||
playing={state.playingIndex == index}
|
||||
checked={checkedIdArray.includes(v.id)}
|
||||
className={`list-item-${index} mt-3 mb-2 list-item-state-${v.status}`}
|
||||
onCheckedChange={(checked) => {
|
||||
@ -187,7 +192,7 @@ export default function VideoIndex() {
|
||||
})
|
||||
}}
|
||||
onItemClick={ () => playVideo(v, index)}
|
||||
onRemove={()=>{}}
|
||||
onRemove={() => processDeleteVideo([v.id])}
|
||||
onEdit={v.status == VideoStatus.Generating ? undefined : () => {
|
||||
setEditId(v.article_id)
|
||||
}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user