update: 更新历史视频库

This commit is contained in:
LittleBoy 2024-12-25 20:37:49 +08:00
parent 0699fa1145
commit 94d300d0be
6 changed files with 77 additions and 74 deletions

View File

@ -24,6 +24,7 @@ type Props = {
onChange?: (state: State) => void;
onProgress?: (current:number,duration:number) => void;
muted?: boolean;
autoPlay?: boolean;
}
export type PlayerInstance = {
play: (url: string, currentTime: number) => void;
@ -79,7 +80,7 @@ export const Player = React.forwardRef<PlayerInstance, Props>((props, ref) => {
controls: props.showControls,
// muted:props.muted,
poster: props.poster,
autoplay: true,
autoplay: typeof(props.autoPlay) != 'undefined' ? props.autoPlay : true,
licenseUrl: 'https://license.vod2.myqcloud.com/license/v2/1328581896_1/v_cube.license'
}
)

View File

@ -1,49 +1,59 @@
import {Button, Form, Input, Select, Space} from "antd";
import {useSetState} from "ahooks";
import {PlayCircleOutlined} from "@ant-design/icons";
import {PlayCircleOutlined, SearchOutlined} from "@ant-design/icons";
import {SearchListTimes} from "@/pages/news/components/news-source.ts";
import React from "react";
import TimeSelect from "@/components/form/time-select.tsx";
type Props = {
onSearch?: (params: VideoSearchParams) => void;
onBtnStartClick?: () => Promise<void>;
loading?:boolean;
loading?: boolean;
}
export default function SearchForm({onSearch, onBtnStartClick,loading}: Props) {
export default function SearchForm({onSearch, onBtnStartClick, loading}: Props) {
const [state, setState] = useSetState<{
pushing?: boolean;
}>({})
const onFinish = (values) => {
onSearch?.({
...values,
pagination: {page: 1, limit: 10}
time_flag: number;
title?: string;
}>({
time_flag:0
})
const onFinish = (params: Partial<VideoSearchParams>) => {
onSearch?.({
time_flag: params.time_flag,
title: params.title,
pagination: {page: 1, limit: 12}
})
//console.log(values)
}
return (<div className={'search-panel'}>
const handleTimeFilter = (time_flag: number) => {
setState({time_flag})
onFinish({
title:state.title,time_flag
})
}
return (<div className={'search-panel pt-6 pb-2'}>
<div className="flex justify-between items-center">
<div className="search-form">
<Form<VideoSearchParams> className={""} layout="inline" onFinish={onFinish} initialValues={{title:'',time_flag:0}}>
<Form.Item name="title">
<Input className="w-[200px]" allowClear placeholder={'请输入搜索信息'}/>
</Form.Item>
<Form.Item label={'更新时间'} name="time_flag" className="w-[250px]">
<Select
options={SearchListTimes}
optionRender={(option) => (
<div className="flex items-center">
<span role="icon" className={`radio-icon`}></span>
<span role="listitem" aria-label={String(option.label)}>{option.label}</span>
</div>
)}
<div className="flex items-center gap-4">
<Input
className="w-[270px] rounded-3xl"
prefix={<SearchOutlined/>}
onChange={e=>setState({title: e.target.value})}
onPressEnter={()=>onFinish(state)}
onBlur={()=>onFinish(state)}
allowClear
placeholder={'请输入视频标题关键字进行信息'}
/>
</Form.Item>
<Form.Item>
<Space size={10}>
<Button loading={loading} type={'primary'} htmlType={'submit'}></Button>
</Space>
</Form.Item>
</Form>
<TimeSelect
className="w-[120px] ml-1"
value={state.time_flag}
onChange={handleTimeFilter}
/>
</div>
</div>
<Space size={10}>
<Button

View File

@ -8,6 +8,7 @@ import ArticleGroup from "@/components/article/group";
import * as article from "@/service/api/article.ts";
import {push2room} from "@/service/api/video.ts";
import {showErrorToast, showToast} from "@/components/message.ts";
import {formatTime, timeFromNow} from "@/util/strings.ts";
type Props = {
video?: VideoInfo;
@ -51,35 +52,24 @@ export default function VideoDetail({video, onClose}: Props) {
}, [video])
return (<>
<Modal open={!!video} title="新闻视频详情" width={1000} footer={null} onCancel={onClose}>
<Modal open={!!video} title={null} width={1500} footer={null} onCancel={onClose}>
<div className="header text-2xl" style={{marginTop:-10}}>{video?.title || "新闻视频详情"}</div>
<div className="flex gap-2 my-5">
<div className="news-video w-[350px]">
<div className="video-container bg-gray-100 rounded overflow-hidden h-[640px]">
<Player url={video?.oss_video_url} poster={video?.cover} showControls={true}
className="w-[360px] h-[640px] bg-white"/>
<div className="video-container bg-gray-100 rounded overflow-hidden h-[560px]">
<Player autoPlay={false} url={video?.oss_video_url} poster={video?.cover} showControls={true}
className="w-[360px] h-[560px] bg-white"/>
</div>
<div className="video-info text-right text-sm text-gray-600 mt-3">
<span>创建时间: 5小时前</span>
<span>: {timeFromNow(video?.ctime)}</span>
</div>
</div>
<div className="detail flex-1 ml-5">
<div className="text-lg"></div>
<div className="article-title mt-5 items-center flex">
<span className="text text-base"></span>
<span className="ml-4 flex-1">
<Input value={video?.title}/>
</span>
</div>
<div className="aricle-body mt-3">
<div className="title">
<span className="text text-base"></span>
</div>
<div className="box mt-1">
<ArticleGroup groups={groups}/>
</div>
</div>
</div>
</div>
<div className="footer flex justify-between">
<div className="action flex gap-2">
<Button loading={state.pushing} type="primary" onClick={pushToRoom}></Button>

View File

@ -1,11 +1,8 @@
import {Checkbox, Image, Tag} from "antd";
import {Checkbox, Tag} from "antd";
import {IconDelete} from "@/components/icons";
import {useState} from "react";
import ImageCover from './cover.png'
import {formatDuration, timeFromNow} from "@/util/strings.ts";
import dayjs from "dayjs";
type VideoItemProps = {
videoInfo: VideoInfo;
@ -25,7 +22,7 @@ export default function VideoItem(props: VideoItemProps) {
}
}
return <div className={'video-item bg-gray-100 hover:drop-shadow-md rounded overflow-hidden relative group'}>
return <div className={'video-item bg-white rounded overflow-hidden relative group'}>
<div className={`controls absolute top-1 right-1 z-[2] p-1 rounded items-center gap-2 bg-white/80 ${state.checked?'flex':'hidden'} group-hover:flex`}>
<span onClick={props.onRemove} className={'cursor-pointer text-blue-500 text-2xl cursor-pointer'}><IconDelete /></span>
{!props.onLive && <Checkbox onChange={e=>handleCheckedChange(e.target.checked)} />}
@ -34,7 +31,7 @@ export default function VideoItem(props: VideoItemProps) {
<img className={'w-full cursor-pointer h-[180px] object-cover'} src={props.videoInfo.cover}/>
</div>
<div className="text-sm py-2 px-3">
<div className="title my-1 cursor-pointer" onClick={props.onClick}>{props.videoInfo.title}</div>
<div className="title my-1 cursor-pointer line-clamp-1" onClick={props.onClick}>{props.videoInfo.title}</div>
<div className="info flex justify-between gap-2 text-sm">
<div className="video-time-info text-gray-500">
<span>: {formatDuration(Math.ceil(props.videoInfo.duration / 1000))}</span>

View File

@ -6,6 +6,7 @@ import VideoItem from "@/pages/library/components/video-item.tsx";
import SearchForm from "@/pages/library/components/search-form.tsx";
import VideoDetail from "@/pages/library/components/video-detail.tsx";
import {search} from "@/service/api/video.ts";
import InfiniteScroller from "@/components/scoller/infinite-scroller.tsx";
export default function LibraryIndex() {
const [modal, contextHolder] = Modal.useModal();
@ -14,7 +15,7 @@ export default function LibraryIndex() {
time_flag: 0,
pagination: {
page: 1,
limit: 10
limit: 12
}
})
const {data,loading} = useRequest(() => search(params), {
@ -42,7 +43,7 @@ export default function LibraryIndex() {
const [detailVideo, setDetailVideo] = useState<VideoInfo>()
return (<>
<div className={'container py-20'}>
<div className={'container pb-5'}>
{contextHolder}
<div className="search-form-container mb-5">
<SearchForm
@ -51,7 +52,8 @@ export default function LibraryIndex() {
loading={loading}
/>
</div>
<div className="bg-white rounded p-5">
<div className="">
<InfiniteScroller loading={loading} pagination={data?.pagination} onCallback={()=>{}}>
<div className={'video-list-container grid gap-5 grid-cols-4'}>
{data?.list?.map((it, idx) => (
<VideoItem
@ -67,6 +69,7 @@ export default function LibraryIndex() {
/>
))}
</div>
</InfiniteScroller>
<div className="video-page-container flex justify-center mt-5">
{data?.pagination && data?.pagination.total > 0 ? <div className="flex justify-center mt-10">
<Pagination

View File

@ -3,13 +3,15 @@ import {Suspense,} from "react";
import {ConfigProvider,App} from "antd";
import zhCN from 'antd/locale/zh_CN';
// for date-picker i18n
import dayjs from "dayjs";
import 'dayjs/locale/zh-cn';
import ErrorBoundary from "./error.tsx";
import Loader from "@/components/loader.tsx";
import routes from "@/routes/routes.tsx";
dayjs.locale('zh-cn');
const router = createBrowserRouter([
...routes,
{path: '*', element: <ErrorBoundary/>}