605 lines
14 KiB
JavaScript
605 lines
14 KiB
JavaScript
import {__, _x, _n, _nx} from '@wordpress/i18n';
|
|
import Card from 'react-bootstrap/Card';
|
|
import {useState, useEffect} from '@wordpress/element';
|
|
import Row from 'react-bootstrap/Row';
|
|
import Col from 'react-bootstrap/Col';
|
|
import Container from 'react-bootstrap/Container';
|
|
import Modal from 'react-bootstrap/Modal';
|
|
import {
|
|
VideoLength,
|
|
VideoSize,
|
|
VideoViews,
|
|
VideoDate,
|
|
} from './VideoAttributes';
|
|
import Form from 'react-bootstrap/Form';
|
|
import InputGroup from 'react-bootstrap/InputGroup';
|
|
import Button from 'react-bootstrap/Button';
|
|
import Tab from 'react-bootstrap/Tab';
|
|
import Tabs from 'react-bootstrap/Tabs';
|
|
import DeleteModal from './DeleteModal';
|
|
import Spinner from 'react-bootstrap/Spinner';
|
|
|
|
export default function VideoModal({
|
|
video,
|
|
setVideos,
|
|
selectVideo,
|
|
children,
|
|
}) {
|
|
const [show, setShow] = useState(false);
|
|
const [title, setTitle] = useState(video.title);
|
|
const [autoPlay, setAutoPlay] = useState(false);
|
|
const [loop, setLoop] = useState(false);
|
|
const [muted, setMuted] = useState(false);
|
|
const [preload, setPreload] = useState(true);
|
|
const [embedParams, setEmbedParams] = useState('');
|
|
const [uploading, setUploading] = useState(false);
|
|
const [loading, setLoading] = useState(false);
|
|
const [iframe, setIframe] = useState(null);
|
|
|
|
useEffect(() => {
|
|
let params = [];
|
|
if (autoPlay) {
|
|
params.push('autoplay="true"');
|
|
}
|
|
if (loop) {
|
|
params.push('loop="true"');
|
|
}
|
|
if (muted) {
|
|
params.push('muted="true"');
|
|
}
|
|
if (preload) {
|
|
params.push('preload="true"');
|
|
}
|
|
setEmbedParams(params.join(' '));
|
|
}, [autoPlay, loop, muted, preload]);
|
|
|
|
useEffect(() => {
|
|
const component = (
|
|
<iframe
|
|
src={`https://iframe.mediadelivery.net/embed/${
|
|
video.videoLibraryId
|
|
}/${video.guid}?autoplay=false&v=${Math.random()}`}
|
|
loading="lazy"
|
|
allow="accelerometer; gyroscope; autoplay; encrypted-media; picture-in-picture;"
|
|
allowFullScreen={true}
|
|
></iframe>
|
|
);
|
|
setIframe(component);
|
|
}, [video]);
|
|
|
|
const getThumbnail = (file) => {
|
|
return IUP_VIDEO.cdnUrl + '/' + video.guid + '/' + file;
|
|
};
|
|
|
|
const handleShow = () => {
|
|
setShow(true);
|
|
};
|
|
const handleClose = () => {
|
|
setShow(false);
|
|
};
|
|
|
|
function updateVideo() {
|
|
setLoading(true);
|
|
const formData = new FormData();
|
|
formData.append('title', title);
|
|
formData.append('video_id', video.guid);
|
|
formData.append('nonce', IUP_VIDEO.nonce);
|
|
|
|
const options = {
|
|
method: 'POST',
|
|
headers: {
|
|
Accept: 'application/json',
|
|
},
|
|
body: formData,
|
|
};
|
|
|
|
fetch(`${ajaxurl}?action=infinite-uploads-video-update`, options)
|
|
.then((response) => response.json())
|
|
.then((data) => {
|
|
if (data.success) {
|
|
setVideos((videos) =>
|
|
videos.map((v) =>
|
|
v.guid === video.guid ? {...v, title} : v
|
|
)
|
|
);
|
|
} else {
|
|
console.error(data.data);
|
|
}
|
|
setLoading(false);
|
|
})
|
|
.catch((error) => {
|
|
console.log('Error:', error);
|
|
setLoading(false);
|
|
});
|
|
}
|
|
|
|
function setThumbnail(thumbnailFileName) {
|
|
setLoading(true);
|
|
const formData = new FormData();
|
|
formData.append('thumbnail', thumbnailFileName);
|
|
formData.append('video_id', video.guid);
|
|
formData.append('nonce', IUP_VIDEO.nonce);
|
|
|
|
const options = {
|
|
method: 'POST',
|
|
headers: {
|
|
Accept: 'application/json',
|
|
},
|
|
body: formData,
|
|
};
|
|
|
|
fetch(`${ajaxurl}?action=infinite-uploads-video-update`, options)
|
|
.then((response) => response.json())
|
|
.then((data) => {
|
|
if (data.success) {
|
|
setVideos((videos) =>
|
|
videos.map((v) =>
|
|
v.guid === video.guid
|
|
? {...v, thumbnailFileName}
|
|
: v
|
|
)
|
|
);
|
|
} else {
|
|
console.error(data.data);
|
|
}
|
|
setLoading(false);
|
|
})
|
|
.catch((error) => {
|
|
console.log('Error:', error);
|
|
setLoading(false);
|
|
});
|
|
}
|
|
|
|
function uploadThumbnail(file) {
|
|
setUploading(true);
|
|
const formData = new FormData();
|
|
formData.append('thumbnailFile', file);
|
|
formData.append('video_id', video.guid);
|
|
formData.append('nonce', IUP_VIDEO.nonce);
|
|
|
|
const options = {
|
|
method: 'POST',
|
|
headers: {
|
|
Accept: 'application/json',
|
|
},
|
|
body: formData,
|
|
};
|
|
|
|
fetch(`${ajaxurl}?action=infinite-uploads-video-update`, options)
|
|
.then((response) => response.json())
|
|
.then((data) => {
|
|
if (data.success) {
|
|
getVideo(); // refresh video data
|
|
setUploading(false);
|
|
} else {
|
|
console.error(data.data);
|
|
setUploading(false);
|
|
}
|
|
})
|
|
.catch((error) => {
|
|
console.log('Error:', error);
|
|
setUploading(false);
|
|
});
|
|
}
|
|
|
|
function getVideo() {
|
|
const options = {
|
|
method: 'GET',
|
|
headers: {
|
|
Accept: 'application/json',
|
|
AccessKey: IUP_VIDEO.apiKey,
|
|
},
|
|
};
|
|
|
|
fetch(
|
|
`https://video.bunnycdn.com/library/${IUP_VIDEO.libraryId}/videos/${video.guid}`,
|
|
options
|
|
)
|
|
.then((response) => response.json())
|
|
.then((data) => {
|
|
//replace video in videos array
|
|
setVideos((videos) =>
|
|
videos.map((v) =>
|
|
v.guid === video.guid ? {...v, ...data} : v
|
|
)
|
|
);
|
|
})
|
|
.catch((error) => {
|
|
console.error(error);
|
|
});
|
|
}
|
|
|
|
let thumbnails = [];
|
|
for (let i = 1; i <= 5; i++) {
|
|
thumbnails.push(
|
|
<Col key={i} className="mb-2">
|
|
<Card
|
|
className="bg-dark text-white h-100 p-0"
|
|
role="button"
|
|
disabled={loading || uploading}
|
|
onClick={() => setThumbnail('thumbnail_' + i + '.jpg')}
|
|
>
|
|
<div className="ratio ratio-16x9 overflow-hidden bg-black rounded">
|
|
<div
|
|
className="iup-video-thumb rounded border-0"
|
|
style={{
|
|
backgroundImage: `url("${getThumbnail(
|
|
'thumbnail_' + i + '.jpg'
|
|
)}")`,
|
|
}}
|
|
></div>
|
|
</div>
|
|
<div className="card-img-overlay rounded border-0">
|
|
<div className="card-title align-middle text-center text-white">
|
|
{__('Set', 'infinite-uploads')}
|
|
</div>
|
|
</div>
|
|
</Card>
|
|
</Col>
|
|
);
|
|
}
|
|
thumbnails.push(
|
|
<Col key="fileupload" className="mb-2">
|
|
<Card
|
|
className="h-100 p-0 border-4 border-secondary"
|
|
style={{borderStyle: 'dashed'}}
|
|
disabled={loading || uploading}
|
|
role="button"
|
|
onClick={() =>
|
|
document.getElementById('upload-thumbnail').click()
|
|
}
|
|
>
|
|
<div className="ratio ratio-16x9 overflow-hidden bg-light border-0 rounded">
|
|
<div>
|
|
{uploading ? (
|
|
<div className="h-100 w-100 d-flex align-items-center justify-content-center">
|
|
<Spinner
|
|
animation="border"
|
|
role="status"
|
|
className="text-muted"
|
|
/>
|
|
</div>
|
|
) : (
|
|
<span className="dashicons dashicons-upload h-100 w-100 d-flex align-items-center justify-content-center text-muted h3"></span>
|
|
)}
|
|
</div>
|
|
</div>
|
|
<Form.Control
|
|
type="file"
|
|
id="upload-thumbnail"
|
|
className="d-none"
|
|
accept="image/png, image/jpeg"
|
|
disabled={loading || uploading}
|
|
onChange={() =>
|
|
uploadThumbnail(
|
|
document.getElementById('upload-thumbnail')
|
|
.files[0]
|
|
)
|
|
}
|
|
/>
|
|
</Card>
|
|
</Col>
|
|
);
|
|
|
|
return (
|
|
<>
|
|
<a
|
|
className="m-3 w-100 p-0 text-decoration-none"
|
|
role="button"
|
|
aria-label={__('Open video modal', 'infinite-uploads')}
|
|
onClick={() => {
|
|
if (selectVideo) {
|
|
selectVideo(video);
|
|
} else {
|
|
handleShow();
|
|
}
|
|
}}
|
|
>
|
|
{children}
|
|
</a>
|
|
|
|
<Modal
|
|
show={show}
|
|
onHide={handleClose}
|
|
size="xl"
|
|
aria-labelledby="contained-modal-title-vcenter"
|
|
centered
|
|
>
|
|
<Modal.Header closeButton>
|
|
<Modal.Title id="contained-modal-title-vcenter">
|
|
{__('Edit Video:', 'infinite-uploads')}{' '}
|
|
{video.title}
|
|
</Modal.Title>
|
|
</Modal.Header>
|
|
<Modal.Body>
|
|
<Container fluid className="pb-3">
|
|
<Row
|
|
className="justify-content-center mb-4 mt-3"
|
|
xs={1}
|
|
lg={2}
|
|
>
|
|
<Col>
|
|
<Row className="mb-2">
|
|
<Col>
|
|
<div className="ratio ratio-16x9">
|
|
{iframe}
|
|
</div>
|
|
</Col>
|
|
</Row>
|
|
<Row className="justify-content-between text-muted text-center">
|
|
<Col>
|
|
<VideoDate video={video}/>
|
|
</Col>
|
|
<Col>
|
|
<VideoLength video={video}/>
|
|
</Col>
|
|
<Col>
|
|
<VideoViews video={video}/>
|
|
</Col>
|
|
<Col>
|
|
<VideoSize video={video}/>
|
|
</Col>
|
|
</Row>
|
|
</Col>
|
|
<Col>
|
|
<Row className="mb-4">
|
|
<Col>
|
|
<label htmlFor="video-title">
|
|
{__(
|
|
'Video Title',
|
|
'infinite-uploads'
|
|
)}
|
|
</label>
|
|
<InputGroup>
|
|
<Form.Control
|
|
id="video-title"
|
|
placeholder={__(
|
|
'Title',
|
|
'infinite-uploads'
|
|
)}
|
|
aria-label={__(
|
|
'Title',
|
|
'infinite-uploads'
|
|
)}
|
|
value={title}
|
|
onChange={(e) =>
|
|
setTitle(e.target.value)
|
|
}
|
|
disabled={
|
|
loading || uploading
|
|
}
|
|
/>
|
|
<Button
|
|
variant="primary"
|
|
className="text-white"
|
|
disabled={
|
|
loading || uploading
|
|
}
|
|
onClick={updateVideo}
|
|
>
|
|
{__(
|
|
'Update',
|
|
'infinite-uploads'
|
|
)}
|
|
</Button>
|
|
</InputGroup>
|
|
</Col>
|
|
</Row>
|
|
|
|
<Row className="mb-4">
|
|
<Col className="col-4">
|
|
<h6>
|
|
{__(
|
|
'Current Thumbnail',
|
|
'infinite-uploads'
|
|
)}
|
|
</h6>
|
|
<Card className="bg-dark text-white w-100 p-0 mb-2">
|
|
<div className="ratio ratio-16x9 overflow-hidden bg-black rounded border-0">
|
|
<div
|
|
className="iup-video-thumb rounded border-0"
|
|
style={{
|
|
backgroundImage: `url("${getThumbnail(
|
|
video.thumbnailFileName
|
|
)}")`,
|
|
}}
|
|
></div>
|
|
</div>
|
|
</Card>
|
|
</Col>
|
|
<Col className="col-8">
|
|
<p>
|
|
{__(
|
|
'Choose a new thumbnail to be displayed in the video player:',
|
|
'infinite-uploads'
|
|
)}
|
|
</p>
|
|
<Row className="justify-content-start d-flex row-cols-2 row-cols-md-3">
|
|
{thumbnails}
|
|
</Row>
|
|
</Col>
|
|
</Row>
|
|
|
|
<Row className="justify-content-end mb-3">
|
|
<Col className="justify-content-end d-flex">
|
|
<DeleteModal
|
|
video={video}
|
|
setVideos={setVideos}
|
|
/>
|
|
</Col>
|
|
</Row>
|
|
</Col>
|
|
</Row>
|
|
|
|
<Tabs defaultActiveKey="shortcode" className="mb-4">
|
|
<Tab
|
|
eventKey="shortcode"
|
|
title={
|
|
<div className="d-inline-flex align-start">
|
|
<span className="dashicons dashicons-shortcode me-1"></span>
|
|
{__(
|
|
'Embed Code',
|
|
'infinite-uploads'
|
|
)}
|
|
</div>
|
|
}
|
|
>
|
|
<Row className="justify-content-center mt-2">
|
|
<Col>
|
|
<Row>
|
|
<Col>
|
|
<p>
|
|
{__(
|
|
'Copy and paste this code into your post, page, or widget to embed the video. If using Gutenberg editor use our block.',
|
|
'infinite-uploads'
|
|
)}
|
|
</p>
|
|
</Col>
|
|
</Row>
|
|
<Row className="mb-1">
|
|
<Col>
|
|
<Form>
|
|
<Form.Check
|
|
inline
|
|
label={__(
|
|
'Autoplay',
|
|
'infinite-uploads'
|
|
)}
|
|
type="checkbox"
|
|
checked={autoPlay}
|
|
onChange={(e) =>
|
|
setAutoPlay(
|
|
e.target.checked
|
|
)
|
|
}
|
|
/>
|
|
<Form.Check
|
|
inline
|
|
label={__(
|
|
'Loop',
|
|
'infinite-uploads'
|
|
)}
|
|
type="checkbox"
|
|
checked={loop}
|
|
onChange={(e) =>
|
|
setLoop(
|
|
e.target.checked
|
|
)
|
|
}
|
|
/>
|
|
<Form.Check
|
|
inline
|
|
label={__(
|
|
'Muted',
|
|
'infinite-uploads'
|
|
)}
|
|
type="checkbox"
|
|
checked={muted}
|
|
onChange={(e) =>
|
|
setMuted(
|
|
e.target.checked
|
|
)
|
|
}
|
|
/>
|
|
<Form.Check
|
|
inline
|
|
label={__(
|
|
'Preload',
|
|
'infinite-uploads'
|
|
)}
|
|
type="checkbox"
|
|
checked={preload}
|
|
onChange={(e) =>
|
|
setPreload(
|
|
e.target.checked
|
|
)
|
|
}
|
|
style={{ display: 'none' }} // Hides the preload checkbox
|
|
/>
|
|
</Form>
|
|
</Col>
|
|
</Row>
|
|
<Row>
|
|
<Col>
|
|
<Form.Control
|
|
type="text"
|
|
aria-label="Embed Code"
|
|
readOnly
|
|
value={`[infinite-uploads-vid id="${video.guid}" ${embedParams}]`}
|
|
onClick={(e) => {
|
|
e.target.select();
|
|
document.execCommand(
|
|
'copy'
|
|
);
|
|
}}
|
|
/>
|
|
</Col>
|
|
</Row>
|
|
</Col>
|
|
</Row>
|
|
</Tab>
|
|
|
|
<Tab
|
|
eventKey="stats"
|
|
disabled
|
|
title={
|
|
<>
|
|
<span className="dashicons dashicons-chart-area me-1"></span>
|
|
{__('Stats', 'infinite-uploads')}
|
|
</>
|
|
}
|
|
>
|
|
<Row className="justify-content-center">
|
|
<Col>
|
|
<Row>
|
|
<Col>
|
|
<h5>
|
|
{__(
|
|
'Statistics',
|
|
'infinite-uploads'
|
|
)}
|
|
</h5>
|
|
<p>
|
|
{__(
|
|
'View the statistics for this video.',
|
|
'infinite-uploads'
|
|
)}
|
|
</p>
|
|
</Col>
|
|
</Row>
|
|
<Row>
|
|
<Col>Chart here</Col>
|
|
</Row>
|
|
</Col>
|
|
</Row>
|
|
</Tab>
|
|
|
|
<Tab
|
|
eventKey="captions"
|
|
disabled
|
|
title={
|
|
<>
|
|
<span className="dashicons dashicons-format-status me-1"></span>
|
|
{__('Captions', 'infinite-uploads')}
|
|
</>
|
|
}
|
|
></Tab>
|
|
|
|
<Tab
|
|
eventKey="chapters"
|
|
disabled
|
|
title={
|
|
<>
|
|
<span className="dashicons dashicons-text me-1"></span>
|
|
{__('Chapters', 'infinite-uploads')}
|
|
</>
|
|
}
|
|
></Tab>
|
|
</Tabs>
|
|
</Container>
|
|
</Modal.Body>
|
|
</Modal>
|
|
</>
|
|
);
|
|
}
|