|
|
|
@ -1,5 +1,5 @@
|
|
|
|
|
import React, { useState, useEffect, useReducer, useContext, memo } from 'react';
|
|
|
|
|
|
|
|
|
|
import { Link, Prompt } from "react-router-dom";
|
|
|
|
|
import { getUrl2, isDev, CBreadcrumb, ActionBtn, ThemeContext } from 'educoder'
|
|
|
|
|
import axios from 'axios'
|
|
|
|
|
|
|
|
|
@ -17,22 +17,28 @@ const files = []
|
|
|
|
|
const MAX_FILE_COUNT = 3
|
|
|
|
|
const MAX_FILE_SIZE = 200
|
|
|
|
|
let noUploads = true
|
|
|
|
|
|
|
|
|
|
function VideoUploadList (props) {
|
|
|
|
|
|
|
|
|
|
// const [videoes, setVideoes] = useState([]);
|
|
|
|
|
// const [videos, setvideos] = useState([]);
|
|
|
|
|
const [state, dispatch] = useReducer(reducer, initialState);
|
|
|
|
|
const theme = useContext(ThemeContext)
|
|
|
|
|
const [couldRouteNav, setCouldRouteNav] = useState(false)
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
setCouldRouteNav(false);
|
|
|
|
|
// Chrome removed support for custom message in ver 51
|
|
|
|
|
// https://stackoverflow.com/questions/38879742/is-it-possible-to-display-a-custom-message-in-the-beforeunload-popup
|
|
|
|
|
window.addEventListener("beforeunload", beforeunload);
|
|
|
|
|
|
|
|
|
|
// window.onbeforeunload = beforeunload
|
|
|
|
|
return () => {
|
|
|
|
|
uploader = null;
|
|
|
|
|
// window.onbeforeunload = null;
|
|
|
|
|
window.removeEventListener("beforeunload", beforeunload);
|
|
|
|
|
}
|
|
|
|
|
}, [])
|
|
|
|
|
// TODO 闭包!
|
|
|
|
|
noUploads = (!state.videoes || state.videoes.length == 0);
|
|
|
|
|
noUploads = (!state.videos || state.videos.length == 0);
|
|
|
|
|
function beforeunload(e) {
|
|
|
|
|
if (noUploads) {
|
|
|
|
|
return true;
|
|
|
|
@ -62,7 +68,7 @@ function VideoUploadList (props) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
let gotTheSameFileName = false;
|
|
|
|
|
state.videoes.some((item) => {
|
|
|
|
|
state.videos.some((item) => {
|
|
|
|
|
if (item.name == file.name) {
|
|
|
|
|
gotTheSameFileName = true;
|
|
|
|
|
return true;
|
|
|
|
@ -86,7 +92,7 @@ function VideoUploadList (props) {
|
|
|
|
|
addFileSuccess: (uploadInfo) => {
|
|
|
|
|
const file = uploadInfo.file
|
|
|
|
|
console.log('addFileSuccess', uploadInfo)
|
|
|
|
|
// const newVideoes = [...videoes, {
|
|
|
|
|
// const newvideos = [...videos, {
|
|
|
|
|
// name: file.name,
|
|
|
|
|
// size: file.size,
|
|
|
|
|
// type: file.type,
|
|
|
|
@ -96,7 +102,7 @@ function VideoUploadList (props) {
|
|
|
|
|
// videoId: uploadInfo.videoId, // "719b82c875c34ac39f94feb145d25ad2"
|
|
|
|
|
// loaded: 0
|
|
|
|
|
// }]
|
|
|
|
|
// setVideoes(newVideoes)
|
|
|
|
|
// setvideos(newvideos)
|
|
|
|
|
|
|
|
|
|
// files.push(file)
|
|
|
|
|
clearInput()
|
|
|
|
@ -107,7 +113,7 @@ function VideoUploadList (props) {
|
|
|
|
|
var progressPercent = Math.ceil(progress * 100)
|
|
|
|
|
|
|
|
|
|
// let _index = -1;
|
|
|
|
|
// videoes.some((item, index) => {
|
|
|
|
|
// videos.some((item, index) => {
|
|
|
|
|
// // addFileSuccess的时候没有fileHash
|
|
|
|
|
// // if (uploadInfo.fileHash == item.fileHash) {
|
|
|
|
|
// if (uploadInfo.file.name == item.name) {
|
|
|
|
@ -119,7 +125,7 @@ function VideoUploadList (props) {
|
|
|
|
|
// TODO 这里不用reducer,会出现state被重置的问题
|
|
|
|
|
|
|
|
|
|
// if (_index == -1) {
|
|
|
|
|
// const newVideoes = [...videoes, {
|
|
|
|
|
// const newvideos = [...videos, {
|
|
|
|
|
// name: file.name,
|
|
|
|
|
// size: file.size,
|
|
|
|
|
// type: file.type,
|
|
|
|
@ -129,12 +135,12 @@ function VideoUploadList (props) {
|
|
|
|
|
// videoId: uploadInfo.videoId, // "719b82c875c34ac39f94feb145d25ad2"
|
|
|
|
|
// loaded: progressPercent
|
|
|
|
|
// }]
|
|
|
|
|
// setVideoes(newVideoes)
|
|
|
|
|
// setvideos(newvideos)
|
|
|
|
|
// return;
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// // exercise_questions : update(prevState.exercise_questions, {[index]: { isNew: {$set: false}}})
|
|
|
|
|
// setVideoes(update(videoes, {[_index]: { loaded: {$set: progressPercent}}}))
|
|
|
|
|
// setvideos(update(videos, {[_index]: { loaded: {$set: progressPercent}}}))
|
|
|
|
|
|
|
|
|
|
dispatch({type: 'updateProgress', uploadInfo, progressPercent})
|
|
|
|
|
},
|
|
|
|
@ -177,14 +183,16 @@ function VideoUploadList (props) {
|
|
|
|
|
}
|
|
|
|
|
function doDelete(index, isSuccess) {
|
|
|
|
|
uploader.deleteFile(index)
|
|
|
|
|
// uploader.cancelFile(index)
|
|
|
|
|
if (isSuccess) {
|
|
|
|
|
deleteVideoInCloud(username, state.videoes[index].videoId)
|
|
|
|
|
}
|
|
|
|
|
// uploader.deleteFile(index)
|
|
|
|
|
// deleteVideoInCloud(username, state.videos[index].videoId)
|
|
|
|
|
} else {
|
|
|
|
|
// uploader.cancelFile(index)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
clearInput()
|
|
|
|
|
dispatch({type: 'removeVideo', index})
|
|
|
|
|
// setVideoes([...videoes.splice(index, 1)])
|
|
|
|
|
// setvideos([...videos.splice(index, 1)])
|
|
|
|
|
}
|
|
|
|
|
// uploader.deleteFile(index);
|
|
|
|
|
function cancelUpload(index, isSuccess) {
|
|
|
|
@ -199,13 +207,13 @@ function VideoUploadList (props) {
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
function onPublish() {
|
|
|
|
|
if (state.videoes.length == 0) {
|
|
|
|
|
if (state.videos.length == 0) {
|
|
|
|
|
showNotification('请先上传视频')
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
const publishUrl = `/users/${username}/videos/batch_publish.json`
|
|
|
|
|
axios.post(publishUrl, {
|
|
|
|
|
videos: state.videoes.map(item => {
|
|
|
|
|
videos: state.videos.map(item => {
|
|
|
|
|
return {
|
|
|
|
|
video_id: item.videoId,
|
|
|
|
|
// todo
|
|
|
|
@ -215,7 +223,9 @@ function VideoUploadList (props) {
|
|
|
|
|
}).then((response) => {
|
|
|
|
|
// to success page
|
|
|
|
|
if (response.data.status == 0) {
|
|
|
|
|
history.push(`/users/${username}/videoes/success`)
|
|
|
|
|
dispatch({type: 'removeAll'})
|
|
|
|
|
// setCouldRouteNav(true)
|
|
|
|
|
history.push(`/users/${username}/videos/success`)
|
|
|
|
|
}
|
|
|
|
|
}).catch((error) => {
|
|
|
|
|
console.log(error)
|
|
|
|
@ -225,9 +235,14 @@ function VideoUploadList (props) {
|
|
|
|
|
dispatch({type: 'updateTitle', title, index})
|
|
|
|
|
}
|
|
|
|
|
// login
|
|
|
|
|
const protocolLine = <div>上传视频,即表示您已同意<span style={{color: theme.foreground_select}}>上传内容协议</span>,不得上传未经他人授权的作品</div>
|
|
|
|
|
const protocolLine = <div>上传视频,即表示您已同意
|
|
|
|
|
<Link to={`/users/${username}/videos/protocol`} style={{color: theme.foreground_select}}>上传内容协议</Link>,不得上传未经他人授权的作品</div>
|
|
|
|
|
return (
|
|
|
|
|
<div className="educontent videoUploadList" style={{ marginBottom: '200px' }}>
|
|
|
|
|
<Prompt
|
|
|
|
|
when={state.videos.length }
|
|
|
|
|
message='确认要离开当前页面,当前数据不可恢复'
|
|
|
|
|
/>
|
|
|
|
|
<style>{`
|
|
|
|
|
.videoUploadList .section {
|
|
|
|
|
background: #fff;
|
|
|
|
@ -294,6 +309,7 @@ function VideoUploadList (props) {
|
|
|
|
|
/* item */
|
|
|
|
|
.videoUploadList .cancelUpload {
|
|
|
|
|
flex: 0 0 200px;
|
|
|
|
|
margin-left: 2px;
|
|
|
|
|
}
|
|
|
|
|
.videoUploadList .titleInput {
|
|
|
|
|
width: 480px;
|
|
|
|
@ -332,7 +348,7 @@ function VideoUploadList (props) {
|
|
|
|
|
className="mb26"
|
|
|
|
|
separator=" > "
|
|
|
|
|
items={[
|
|
|
|
|
{ to: `/users/${username}/videoes`, name: '视频'},
|
|
|
|
|
{ to: `/users/${username}/videos`, name: '视频'},
|
|
|
|
|
{ name: '上传'}
|
|
|
|
|
]}
|
|
|
|
|
></CBreadcrumb>
|
|
|
|
@ -361,7 +377,7 @@ function VideoUploadList (props) {
|
|
|
|
|
</div>}
|
|
|
|
|
|
|
|
|
|
<div>
|
|
|
|
|
{state.videoes.map((item, vIndex) => {
|
|
|
|
|
{state.videos.map((item, vIndex) => {
|
|
|
|
|
return (
|
|
|
|
|
<VideoUpload {...props} {...item} className=""
|
|
|
|
|
cancelUpload={cancelUpload}
|
|
|
|
@ -372,24 +388,24 @@ function VideoUploadList (props) {
|
|
|
|
|
)
|
|
|
|
|
})}
|
|
|
|
|
</div>
|
|
|
|
|
{state.videoes && state.videoes.length === MAX_FILE_COUNT &&
|
|
|
|
|
{state.videos && state.videos.length === MAX_FILE_COUNT &&
|
|
|
|
|
<div className="uploadTip">
|
|
|
|
|
<i className="iconfont icon-tishi" style={{color: '#FF6F6F', verticalAlign: 'text-bottom'}}></i>
|
|
|
|
|
<span>单次最多支持3个视频文件上传</span>
|
|
|
|
|
{/* <i className="iconfont icon-tishi" style={{color: '#FF6F6F', verticalAlign: 'text-bottom'}}></i> */}
|
|
|
|
|
<span>提示:单次最多支持3个视频文件上传</span>
|
|
|
|
|
</div>}
|
|
|
|
|
|
|
|
|
|
{(!noUploads && state.videoes.length < MAX_FILE_COUNT) && <ActionBtn className="publishBtn" onClick={() => document.getElementById('fileUpload').click()}
|
|
|
|
|
{(!noUploads && state.videos.length < MAX_FILE_COUNT) && <ActionBtn className="publishBtn" onClick={() => document.getElementById('fileUpload').click()}
|
|
|
|
|
>继续添加</ActionBtn>}
|
|
|
|
|
|
|
|
|
|
<div className={`description ${noUploads ? 'noUploads' : ''}`}>
|
|
|
|
|
<div className="">视频大小:不支持断点续传,单个视频文件最大200M;单次最多支持3个视频文件上传 </div>
|
|
|
|
|
<div className="">视频规格:avi、flv、f4v、m4v、mov、mp4、rmvb、swf、webm </div>
|
|
|
|
|
<div className="">温馨提示:请勿上传违法视频。平台将为每一个视频分配一个地址,您可以通过引用改地址将视频使用在开发社区等模块</div>
|
|
|
|
|
<div className="">温馨提示:请勿上传违法视频。平台将为每一个视频分配一个地址,您可以通过引用该地址将视频使用在开发社区等模块</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{!noUploads && <React.Fragment>
|
|
|
|
|
|
|
|
|
|
{/* {(state.videoes.length < MAX_FILE_COUNT) && <Button type="primary" icon="plus-square"
|
|
|
|
|
{/* {(state.videos.length < MAX_FILE_COUNT) && <Button type="primary" icon="plus-square"
|
|
|
|
|
onClick={() => { document.getElementById('fileUpload').click()}}
|
|
|
|
|
className="fr addVideoBtn"
|
|
|
|
|
>
|
|
|
|
@ -405,8 +421,9 @@ function VideoUploadList (props) {
|
|
|
|
|
|
|
|
|
|
</React.Fragment>}
|
|
|
|
|
</div>
|
|
|
|
|
{/* windows video/* 不管用 TODO */}
|
|
|
|
|
<input type="file" id="fileUpload" style={{display: 'none'}} onChange={onUploadChange}
|
|
|
|
|
accept="video/*"
|
|
|
|
|
accept=".flv, .f4v, .rmvb, .swf, video/mp4,video/x-m4v,video/flv,video/f4v,video/rmvb,video/swf,video/*"
|
|
|
|
|
></input>
|
|
|
|
|
</div>
|
|
|
|
|
)
|
|
|
|
|