You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
educoder/public/react/src/modules/user/usersInfo/video/InfosVideo.js

481 lines
16 KiB

import React, { useState, useEffect, useContext, useRef, memo } from 'react';
import { Pagination, Input, Button } from 'antd'
import { ThemeContext, ActionBtn, NoneData } from 'educoder'
import axios from 'axios'
import VideoInReviewItem from './VideoInReviewItem'
import EditVideoModal from './EditVideoModal'
import './InfosVideo.css'
import InfoTab from '../common/InfoTab'
import HeadlessModal from '../common/HeadlessModal'
import ClipboardJS from 'clipboard'
import VideoPlay from '../../../courses/Video/video-play';
function useModal(initValue) {
const [visible, setVisible] = useState(initValue)
return {
visible,
setVisible
}
}
function useCategory(initValue) {
const [category, setCategory] = useState(initValue)
function changeCategory(key) {
setCategory(key)
}
return {
category,
changeCategory
}
}
function usePagination() {
const [page, setPage] = useState(1)
function onPageChange(page) {
setPage(page)
}
return {
current: page,
onChange: onPageChange
}
}
const PAGE_SIZE = 16
const DEFAULT_VIDEO_WIDTH_IN_MD = "90%" // 400
const DEFAULT_VIDEO_HEIGHT_IN_MD = "55%" // 400
let videoId = {};
let _clipboard = null;
const _items = [
{ key: 'published_at-desc', name: '最新上传' },
{ key: 'published_at-asc', name: '最早上传' },
]
function InfoVideo(props) {
const [videos, setvideos] = useState(undefined)
const [reviewvideos, setReviewvideos] = useState(undefined)
const [count, setCount] = useState(0)
const [loading, setLoading] = useState(true)
const [sortKey, setSortKey] = useState(_items[0].key)
const editModalObj = useModal(false)
const videoModalObj = useModal(false)
const categoryObj = useCategory('all')
const pageObj = usePagination()
const theme = useContext(ThemeContext);
const editModalEl = useRef(null);
const videoEl = useRef(null);
const { showNotification, history } = props;
const username = props.match.params.username;
const { user } = props;
function toUpload() {
if (props.current_user.admin || (props.current_user.is_teacher && props.checkIfProfessionalCertification())) {
history.push(`/users/${username}/videos/upload`)
} else {
props.showProfessionalCertificationDialog()
}
}
function fetchvideos() {
const fetchUrl = `/users/${username}/videos.json`
const sorts = sortKey.split('-')
setLoading(true)
axios.get(fetchUrl, {
params: {
page: pageObj.current,
per_page: PAGE_SIZE,
sort_by: sorts[0],
sort_direction: sorts[1],
//
}
}).then((response) => {
setLoading(false)
if (response.data.videos) {
setvideos(response.data.videos)
setCount(response.data.count)
}
}).catch(() => {
setLoading(false)
})
}
function fetchReviewvideos() {
const fetchUrl = `/users/${username}/videos/review.json`
const sorts = sortKey.split('-')
setLoading(true)
axios.get(fetchUrl, {
params: {
page: pageObj.current,
per_page: PAGE_SIZE,
sort_by: sorts[0],
sort_direction: sorts[1],
}
})
.then((response) => {
setLoading(false)
if (response.data.videos) {
setReviewvideos(response.data.videos)
setCount(response.data.count)
}
}).catch(() => {
})
}
useEffect(() => {
if (pageObj.current == 1) {
if (categoryObj.category == 'all') {
fetchvideos()
} else {
fetchReviewvideos()
}
} else {
pageObj.onChange(1)
}
}, [categoryObj.category])
useEffect(() => {
if (categoryObj.category == 'all') {
fetchvideos()
} else {
fetchReviewvideos()
}
}, [pageObj.current, sortKey])
useEffect(() => {
if (videoModalObj.visible == false) {
// 关闭视频
videoEl.current && videoEl.current.pause();
videoId = {};
if (_clipboard) {
_clipboard.destroy();
_clipboard = null;
}
} else {
videoEl.current && videoEl.current.play()
setTimeout(() => {
if (!_clipboard) {
_clipboard = new ClipboardJS('.copybtn');
_clipboard.on('success', (e) => {
showNotification('复制成功')
});
}
}, 200)
}
}, [videoModalObj.visible])
useEffect(() => {
}, [])
function editSuccess() {
fetchvideos()
}
function onEditVideo(item) {
videoId = {
videoId: item.id,
title: item.title
}
editModalObj.setVisible(true)
// editModalEl.current.toList(true, video);
// this.refs['editVideoModal'].setVisible(true, video);
}
function onMaskClick(item) {
videoId = {
videoId: item.id,
title: item.title,
file_url: item.play_url || item.file_url,
cover_url: item.cover_url
}
videoModalObj.setVisible(true)
}
// TODO use封装
function onSortChange(key, index) {
try {
const _item = _items[index];
_items.splice(index, 1);
_items.unshift(_item);
const keys = key.split('-');
const sorts = sortKey.split('-');
if (key === "published_at-desc") {
if (keys[1] === sorts[1]) {
setSortKey("published_at-asc")
} else {
setSortKey(key)
}
} else if (key === "published_at-asc") {
if (keys[1] === sorts[1]) {
setSortKey("published_at-desc")
} else {
setSortKey(key)
}
}
} catch (e) {
}
}
function deleteVideo(item){
props.confirm({
content: '该视频将被删除,不可恢复',
subContent: '是否确认删除?',
onOk: () => {
const url = `/users/${user && user.login}/videos/${item.id}.json`;
axios.delete(url).then(result => {
if (result) {
props.showNotification(`视频删除成功!`);
if (pageObj.current === 1) {
if (categoryObj.category === 'all') {
fetchvideos()
} else {
fetchReviewvideos()
}
} else {
pageObj.onChange(1)
}
}
}).catch(error => {
console.log(error);
})
},
onCancel() {
console.log('Cancel');
},
});
}
function getCopyText(file_url, cover_url) {
return `<video src="${file_url}" controls="true" controlslist="nodownload" width="${DEFAULT_VIDEO_WIDTH_IN_MD}" height="${DEFAULT_VIDEO_HEIGHT_IN_MD}" poster="${cover_url}">您的浏览器不支持 video 标签。</video>`
}
const _inputValue = getCopyText(videoId.file_url, videoId.cover_url);
const sorts = sortKey.split('-')
return (
<div className="educontent infoVideo">
<EditVideoModal {...props} {...editModalObj}
editSuccess={editSuccess}
{...videoId}
></EditVideoModal>
<HeadlessModal
{...videoModalObj}
className="showVideoModal"
width={800 - 1}
>
{videoModalObj.visible && <VideoPlay src={videoId.file_url} />}
<div className="df copyLine">
<Input value={_inputValue}
className="dark"
></Input>
<ActionBtn className="copybtn" data-clipboard-text={_inputValue}>复制视频地址</ActionBtn>
</div>
</HeadlessModal>
<style>{`
/* item */
.videoPublishSuccess .section {
background: #fff;
padding: 16px 20px;
padding-top: 0px;
position: relative;
text-align: center;
color: ${theme.foreground_tip};
}
.videoItem .square-main .buttonRow i {
vertical-align: top;
font-size: 16px;
color: ${theme.foreground_select} !important;
margin-left: 6px;
}
/*
(26 - 24) * 3 / 2
*/
.itemWrap {
margin-left: 3px;
}
.videoItem {
margin-right: 24px;
}
.white-panel li.active {
border-radius: 24px;
border: none !important;
color: #4CACFF;
}
.whitepanelysllisyt {
width: 70px !important;
height: 48px !important;
line-height: 46px !important;
}
.whitepanelysllisyts {
width: 80px !important;
height: 48px !important;
line-height: 46px !important;
margin-left: 30px;
}
`}</style>
<InfoTab
{...props}
categories={[{
key: 'all',
name: '全部视频',
id: 1,
}, {
key: 'review',
name: '待审核视频',
id: 2
}]}
{...categoryObj}
right={
<Button type="primary" icon="upload"
onClick={() => { toUpload() }}
className="toUploadBtn"
>
上传视频
</Button>
}
></InfoTab>
<div className="toolbarRow df" style={{
lineHeight: "40px",
}}>
<span>
<span style={{ color: theme.foreground_orange1 }}> {count} </span>
个视频
</span>
{/*{categoryObj.category == 'all' && <CRoundSelect {...props}*/}
{/*width={'90px'}*/}
{/*items={_items}*/}
{/*onSortChange={onSortChange}*/}
{/*sortKey={sortKey }*/}
{/*></CRoundSelect>}*/}
{categoryObj.category == 'all' && <div className="fr">
<li className="drop_down">
<span className="color-grey-9 font-12" style={{
marginRight: " 5px",
}}>{"最新上传"}</span>
<sapn className="relativef color-grey-9 fr"
style={{
display: "flex",
flexDirection: "column",
height: "40px",
lineHeight: "40px",
}}
>
<span
style={{
flexDirection: "column",
textAlign: "center",
height: "10px",
lineHeight: "10px",
display: "table",
marginTop: "9px",
}}
>
<i className={sorts[1] === "asc" ?
"iconfont icon-sanjiaoxing-up font-12 color-blue h10 " : "iconfont icon-sanjiaoxing-up font-12 h10"}
onClick={() => onSortChange("published_at-asc", 0)}></i>
</span>
<span
style={{
flexDirection: "column",
height: "10px",
lineHeight: "10px",
textAlign: "center",
display: "table",
}}
>
<i className={sorts[1] === "desc" ?
"iconfont icon-sanjiaoxing-down font-12 yslbottomsj color-blue h10" : "iconfont icon-sanjiaoxing-down font-12 yslbottomsj h10"}
onClick={() => onSortChange("published_at-desc", 0)}></i>
</span>
</sapn>
</li>
</div>}
</div>
{categoryObj.category == 'all' ?
<div className="itemWrap">
{
videos == undefined ? '' :
videos.length ?
videos.map((item, index) => {
return (<VideoInReviewItem
{...props}
{...item}
key={item.id}
onEditVideo={onEditVideo}
onMaskClick={onMaskClick}
getCopyText={getCopyText}
deleteVideo={user && ((user.login === item.user_login) || user.admin) ? deleteVideo : undefined}
>
</VideoInReviewItem>)
})
: <NoneData style={{ width: '100%' }}></NoneData>
}
</div>
:
<div className="itemWrap">
{
reviewvideos == undefined ? '' :
reviewvideos.length ?
reviewvideos.map((item, index) => {
return (<VideoInReviewItem
{...props}
{...item}
key={item.id}
isReview={true}
deleteVideo={user && ((user.login === item.user_login) || user.admin) ? deleteVideo : undefined}
>
</VideoInReviewItem>)
})
: <NoneData style={{ width: '100%' }}></NoneData>
}
</div>
}
{/* categoryObj.category == 'all' && */}
{
count > PAGE_SIZE &&
<div className="mt30 mb50 edu-txt-center">
<Pagination showQuickJumper total={count} pageSize={PAGE_SIZE}
{...pageObj}
/>
</div>
}
</div>
)
}
export default InfoVideo
/**
<video src="http://outin-396971199eed11e991a100163e1c7426.oss-cn-shanghai.aliyuncs.com/sv/52943d8b-16c8dc2a8ca/52943d8b-16c8dc2a8ca.mp4" controls="true" controlslist="nodownload" width="400">
您的浏览器不支持 video 标签。
</video>
*/