installed plugin Infinite Uploads
version 2.0.8
This commit is contained in:
@ -0,0 +1,44 @@
|
||||
{
|
||||
"$schema": "https://schemas.wp.org/trunk/block.json",
|
||||
"apiVersion": 2,
|
||||
"name": "infinite-uploads/video",
|
||||
"version": "0.1.0",
|
||||
"title": "Infinite Uploads Video",
|
||||
"category": "media",
|
||||
"icon": "format-video",
|
||||
"description": "Upload & Embed a video via Infinite Uploads Video Cloud.",
|
||||
"attributes": {
|
||||
"video_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"autoplay": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"loop": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"muted": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"preload": {
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
}
|
||||
},
|
||||
"supports": {
|
||||
"html": false,
|
||||
"anchor": true,
|
||||
"align": true,
|
||||
"spacing": {
|
||||
"margin": true,
|
||||
"padding": true
|
||||
}
|
||||
},
|
||||
"textdomain": "infinite-uploads",
|
||||
"editorScript": "file:../../../build/block.js",
|
||||
"editorStyle": "file:../../../build/block.css",
|
||||
"style": "file:../../../build/style-block.css"
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,40 @@
|
||||
import {__, _x} from '@wordpress/i18n';
|
||||
import {Button, Modal} from '@wordpress/components';
|
||||
import {useState, useEffect} from '@wordpress/element';
|
||||
import Library from '../../../admin/components/Library';
|
||||
import {InfiniteUploadsIcon} from '../Images';
|
||||
import './styles.scss';
|
||||
|
||||
export default function LibraryModal({selectVideo, ...props}) {
|
||||
const [isOpen, setOpen] = useState(false);
|
||||
const openModal = () => setOpen(true);
|
||||
const closeModal = () => setOpen(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Button variant="primary" onClick={openModal}>
|
||||
{__('Select from Library', 'infinite-uploads')}
|
||||
</Button>
|
||||
{isOpen && (
|
||||
<Modal
|
||||
{...props}
|
||||
isDismissible={true}
|
||||
onRequestClose={closeModal}
|
||||
icon={InfiniteUploadsIcon(false)}
|
||||
style={{width: '98%'}}
|
||||
title={__('Cloud Video Library', 'infinite-uploads')}
|
||||
className="iup-block-library-model"
|
||||
>
|
||||
<p>
|
||||
{__(
|
||||
'Select a video from your library to insert into the editor.',
|
||||
'infinite-uploads'
|
||||
)}
|
||||
</p>
|
||||
|
||||
<Library selectVideo={selectVideo}/>
|
||||
</Modal>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
//scope bootstrap styles to library modal only
|
||||
.iup-block-library-model {
|
||||
@import '~bootstrap/scss/bootstrap';
|
||||
|
||||
.components-modal__header-heading {
|
||||
margin-bottom: 0;
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
|
||||
.bg-black {
|
||||
background-color: #000 !important;
|
||||
}
|
||||
|
||||
.text-secondary {
|
||||
color: #6c757d !important;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.rounded-top {
|
||||
border-top-left-radius: 0.375rem !important;
|
||||
border-top-right-radius: 0.375rem !important;
|
||||
}
|
||||
|
||||
.btn .dashicons {
|
||||
font-size: 1.5rem;
|
||||
line-height: 1;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
.rounded-pill {
|
||||
border-radius: 50rem !important;
|
||||
}
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
/**
|
||||
* WordPress dependencies
|
||||
*/
|
||||
import {__, _x} from '@wordpress/i18n';
|
||||
import {ToggleControl, SelectControl} from '@wordpress/components';
|
||||
import {useMemo, useCallback, Platform} from '@wordpress/element';
|
||||
|
||||
const VideoSettings = ({setAttributes, attributes}) => {
|
||||
const {autoplay, loop, muted, preload} = attributes;
|
||||
|
||||
const autoPlayHelpText = __(
|
||||
'Autoplay may cause usability issues for some users.'
|
||||
);
|
||||
const getAutoplayHelp = Platform.select({
|
||||
web: useCallback((checked) => {
|
||||
return checked ? autoPlayHelpText : null;
|
||||
}, []),
|
||||
native: autoPlayHelpText,
|
||||
});
|
||||
|
||||
const toggleFactory = useMemo(() => {
|
||||
const toggleAttribute = (attribute) => {
|
||||
return (newValue) => {
|
||||
setAttributes({[attribute]: newValue});
|
||||
};
|
||||
};
|
||||
|
||||
return {
|
||||
autoplay: toggleAttribute('autoplay'),
|
||||
loop: toggleAttribute('loop'),
|
||||
muted: toggleAttribute('muted'),
|
||||
preload: toggleAttribute('preload'),
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<ToggleControl
|
||||
label={__('Autoplay')}
|
||||
onChange={toggleFactory.autoplay}
|
||||
checked={autoplay}
|
||||
help={getAutoplayHelp}
|
||||
/>
|
||||
<ToggleControl
|
||||
label={__('Loop')}
|
||||
onChange={toggleFactory.loop}
|
||||
checked={loop}
|
||||
/>
|
||||
<ToggleControl
|
||||
label={__('Muted')}
|
||||
onChange={toggleFactory.muted}
|
||||
checked={muted}
|
||||
/>
|
||||
<ToggleControl
|
||||
label={__('Preload')}
|
||||
onChange={toggleFactory.preload}
|
||||
checked={preload}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default VideoSettings;
|
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Because of the way Uppy is designed, we can't use onBeforeUpload to set the video_id as it does not support async.
|
||||
* So this custom plugin is used to set the video_id before the upload starts.
|
||||
*
|
||||
* @see https://uppy.io/docs/writing-plugins/#Example-of-a-custom-plugin
|
||||
*/
|
||||
import {UIPlugin} from '@uppy/core';
|
||||
|
||||
class UppyCreateVid extends UIPlugin {
|
||||
constructor(uppy, opts) {
|
||||
super(uppy, {...{}, ...opts});
|
||||
|
||||
this.id = this.opts.id || 'CreateVid';
|
||||
this.type = 'modifier';
|
||||
}
|
||||
|
||||
createVideo(title) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const formData = new FormData();
|
||||
formData.append('title', title);
|
||||
formData.append('nonce', IUP_VIDEO.nonce);
|
||||
|
||||
const options = {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
},
|
||||
body: formData,
|
||||
};
|
||||
|
||||
fetch(
|
||||
`${ajaxurl}?action=infinite-uploads-video-create`,
|
||||
options
|
||||
)
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
console.log(data);
|
||||
if (data.success) {
|
||||
resolve(data.data);
|
||||
} else {
|
||||
reject(data.data);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log('Error:', error);
|
||||
return reject(error);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
prepareUpload = (fileIDs) => {
|
||||
const promises = fileIDs.map((fileID) => {
|
||||
const file = this.uppy.getFile(fileID);
|
||||
//get the title from the file name and remove the extension
|
||||
const title = file.name.replace(/\.[^/.]+$/, '');
|
||||
|
||||
return this.createVideo(title)
|
||||
.then((upload) => {
|
||||
console.log(`Video ${upload.VideoId} created`);
|
||||
this.opts.uploadAuth.current = {...this.opts.uploadAuth.current, [fileID]: upload};
|
||||
})
|
||||
.catch((err) => {
|
||||
this.uppy.log(
|
||||
`Video could not be created ${file.id}:`,
|
||||
'warning'
|
||||
);
|
||||
this.uppy.log(err, 'warning');
|
||||
});
|
||||
});
|
||||
|
||||
const emitPreprocessCompleteForAll = () => {
|
||||
fileIDs.forEach((fileID) => {
|
||||
const file = this.uppy.getFile(fileID);
|
||||
this.uppy.emit('preprocess-complete', file);
|
||||
});
|
||||
};
|
||||
|
||||
// Why emit `preprocess-complete` for all files at once, instead of
|
||||
// above when each is processed?
|
||||
// Because it leads to StatusBar showing a weird “upload 6 files” button,
|
||||
// while waiting for all the files to complete pre-processing.
|
||||
return Promise.all(promises).then(emitPreprocessCompleteForAll);
|
||||
};
|
||||
|
||||
install() {
|
||||
this.uppy.addPreProcessor(this.prepareUpload);
|
||||
}
|
||||
|
||||
uninstall() {
|
||||
this.uppy.removePreProcessor(this.prepareUpload);
|
||||
}
|
||||
}
|
||||
|
||||
export default UppyCreateVid;
|
340
wp-content/plugins/infinite-uploads/inc/video/block/edit.js
Normal file
340
wp-content/plugins/infinite-uploads/inc/video/block/edit.js
Normal file
@ -0,0 +1,340 @@
|
||||
/**
|
||||
* WordPress components that create the necessary UI elements for the block
|
||||
*
|
||||
* @see https://developer.wordpress.org/block-editor/packages/packages-components/
|
||||
*
|
||||
* See https://github.com/WordPress/gutenberg/blob/trunk/packages/block-library/src/video/
|
||||
*/
|
||||
/**
|
||||
* React hook that is used to mark the block wrapper element.
|
||||
* It provides all the necessary props like the class name.
|
||||
*
|
||||
* @see https://developer.wordpress.org/block-editor/packages/packages-block-editor/#useBlockProps
|
||||
*/
|
||||
import {useSelect} from '@wordpress/data';
|
||||
import {
|
||||
PanelBody, Placeholder, Spinner,
|
||||
ToolbarButton,
|
||||
} from '@wordpress/components';
|
||||
import {useBlockProps, InspectorControls, BlockControls} from '@wordpress/block-editor';
|
||||
import {replace} from '@wordpress/icons';
|
||||
import {InfiniteUploadsIcon} from './components/Images';
|
||||
import {__, sprintf} from '@wordpress/i18n';
|
||||
import {useRef, useEffect, useState} from '@wordpress/element';
|
||||
import Uppy from '@uppy/core';
|
||||
import Tus from '@uppy/tus';
|
||||
import {DragDrop, StatusBar, useUppy} from '@uppy/react';
|
||||
import UppyCreateVid from './edit-uppy-plugin';
|
||||
import VideoCommonSettings from './edit-common-settings';
|
||||
import LibraryModal from './components/LibraryModal';
|
||||
import '../../assets/css/admin.css';
|
||||
|
||||
//pulled from wp_localize_script later
|
||||
|
||||
/**
|
||||
* The edit function describes the structure of your block in the context of the
|
||||
* editor. This represents what the editor will render when the block is used.
|
||||
*
|
||||
* @see https://developer.wordpress.org/block-editor/developers/block-api/block-edit-save/#edit
|
||||
*
|
||||
* @param {Object} props Properties passed to the function.
|
||||
* @param {Object} props.attributes Available block attributes.
|
||||
* @param {Function} props.setAttributes Function that updates individual attributes.
|
||||
*
|
||||
* @return {WPElement} Element to render.
|
||||
*/
|
||||
export default function Edit({clientId, attributes, setAttributes}) {
|
||||
const blockProps = useBlockProps();
|
||||
const isSelected = useSelect((select) =>
|
||||
select('core/block-editor').isBlockSelected(clientId, true)
|
||||
);
|
||||
|
||||
/* Possible video statuses
|
||||
Created = 0
|
||||
Uploaded = 1
|
||||
Processing = 2
|
||||
Transcoding = 3
|
||||
Finished = 4
|
||||
Error = 5
|
||||
UploadFailed = 6
|
||||
*/
|
||||
const [video, setVideo] = useState(null);
|
||||
const [isUploading, setUploading] = useState(false);
|
||||
const [showOverlay, setShowOverlay] = useState(true);
|
||||
const uploadAuth = useRef(null);
|
||||
|
||||
//reenable the click overlay whenever the block is unselected so we can click back on it
|
||||
useEffect(() => {
|
||||
if (!isSelected) {
|
||||
setShowOverlay(true);
|
||||
}
|
||||
}, [isSelected]);
|
||||
|
||||
useEffect(() => {
|
||||
if (attributes.video_id) {
|
||||
getVideo();
|
||||
}
|
||||
}, []);
|
||||
|
||||
//poll the video status every 5 seconds while status is 2-3
|
||||
useEffect(() => {
|
||||
if (video && (video.status === 2 || video.status === 3)) {
|
||||
const interval = setInterval(() => {
|
||||
getVideo();
|
||||
}, 5000);
|
||||
return () => clearInterval(interval);
|
||||
}
|
||||
}, [video]);
|
||||
|
||||
const uppy = useUppy(() => {
|
||||
return new Uppy({
|
||||
debug: true,
|
||||
restrictions: {
|
||||
maxNumberOfFiles: 1,
|
||||
allowedFileTypes: ['video/*'],
|
||||
},
|
||||
autoProceed: true,
|
||||
allowMultipleUploadBatches: false,
|
||||
onBeforeUpload: (files) => {
|
||||
//TODO trigger error if video_id is null
|
||||
},
|
||||
})
|
||||
.use(Tus, {
|
||||
endpoint: 'https://video.bunnycdn.com/tusupload',
|
||||
retryDelays: [0, 1000, 3000, 5000, 10000],
|
||||
onBeforeRequest: (req, file) => {
|
||||
//console.log('Video Auth:', uploadAuth.current[file.id]);
|
||||
if (uploadAuth.current[file.id]) {
|
||||
setAttributes({
|
||||
video_id: uploadAuth.current[file.id].VideoId,
|
||||
});
|
||||
attributes.video_id = uploadAuth.current[file.id].VideoId; //I don't know why this is needed
|
||||
} else {
|
||||
throw new Error('Error fetching auth.');
|
||||
return false;
|
||||
}
|
||||
|
||||
req.setHeader(
|
||||
'AuthorizationSignature',
|
||||
uploadAuth.current[file.id].AuthorizationSignature
|
||||
);
|
||||
req.setHeader(
|
||||
'AuthorizationExpire',
|
||||
uploadAuth.current[file.id].AuthorizationExpire
|
||||
);
|
||||
req.setHeader('VideoId', uploadAuth.current[file.id].VideoId);
|
||||
req.setHeader('LibraryId', IUP_VIDEO.libraryId);
|
||||
},
|
||||
})
|
||||
.use(UppyCreateVid, {uploadAuth}); //our custom plugin
|
||||
});
|
||||
|
||||
let uploadSuccess = useRef(false);
|
||||
uppy.on('upload', (data) => {
|
||||
// data object consists of `id` with upload ID and `fileIDs` array
|
||||
// with file IDs in current upload
|
||||
// data: { id, fileIDs }
|
||||
setUploading(true);
|
||||
uploadSuccess.current = false;
|
||||
});
|
||||
|
||||
uppy.on('cancel-all', () => {
|
||||
setUploading(false);
|
||||
});
|
||||
uppy.on('error', (error) => {
|
||||
console.error(error.stack);
|
||||
setUploading(false);
|
||||
});
|
||||
uppy.on('upload-error', (file, error, response) => {
|
||||
console.log('error with file:', file.id);
|
||||
console.log('error message:', error);
|
||||
setUploading(false);
|
||||
});
|
||||
uppy.on('upload-success', (file, response) => {
|
||||
if (!uploadSuccess.current) {
|
||||
uploadSuccess.current = true;
|
||||
getVideo();
|
||||
}
|
||||
setUploading(false);
|
||||
});
|
||||
|
||||
function getVideo() {
|
||||
if (!attributes.video_id) {
|
||||
return false;
|
||||
}
|
||||
const options = {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
AccessKey: IUP_VIDEO.apiKey,
|
||||
},
|
||||
};
|
||||
|
||||
fetch(
|
||||
`https://video.bunnycdn.com/library/${IUP_VIDEO.libraryId}/videos/${attributes.video_id}`,
|
||||
options
|
||||
)
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
console.log('Video:', data);
|
||||
setVideo(data);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
});
|
||||
}
|
||||
|
||||
const selectVideo = (video) => {
|
||||
setAttributes({video_id: video.guid});
|
||||
setVideo(video);
|
||||
setUploading(false);
|
||||
};
|
||||
|
||||
if (
|
||||
!isUploading &&
|
||||
attributes.video_id &&
|
||||
video &&
|
||||
[1, 2, 3, 4].includes(video.status)
|
||||
) {
|
||||
if (video.status === 4) {
|
||||
return (
|
||||
<>
|
||||
<div {...blockProps}>
|
||||
<figure className="iup-video-embed-wrapper">
|
||||
<iframe
|
||||
src={`https://iframe.mediadelivery.net/embed/${IUP_VIDEO.libraryId}/${attributes.video_id}?autoplay=${attributes.autoplay}&preload=${attributes.preload}&loop=${attributes.loop}&muted=${attributes.muted}`}
|
||||
loading="lazy"
|
||||
className="iup-video-embed"
|
||||
sandbox="allow-scripts allow-same-origin allow-presentation"
|
||||
allow="accelerometer; gyroscope; autoplay; encrypted-media; picture-in-picture;"
|
||||
allowFullScreen={true}
|
||||
></iframe>
|
||||
</figure>
|
||||
{showOverlay && (
|
||||
<button
|
||||
className="iup-video-overlay"
|
||||
onClick={() => setShowOverlay(false)}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<BlockControls group="other">
|
||||
<ToolbarButton
|
||||
onClick={() => setAttributes({video_id: null})}
|
||||
icon={replace}
|
||||
label={__('Replace Video', 'infinite-uploads')}
|
||||
/>
|
||||
</BlockControls>
|
||||
<InspectorControls>
|
||||
<PanelBody title={__('Settings')}>
|
||||
<VideoCommonSettings
|
||||
setAttributes={setAttributes}
|
||||
attributes={attributes}
|
||||
/>
|
||||
</PanelBody>
|
||||
</InspectorControls>
|
||||
</>
|
||||
);
|
||||
} else {
|
||||
let label = '';
|
||||
let style = {};
|
||||
if (video.status === 3) {
|
||||
label = sprintf(
|
||||
__('Video %d%% encoded...', 'infinite-uploads'),
|
||||
video.encodeProgress
|
||||
);
|
||||
style = {
|
||||
backgroundImage: `url("${IUP_VIDEO.cdnUrl}/${attributes.video_id}/${video.thumbnailFileName}")`,
|
||||
};
|
||||
} else if (video.status <= 1) {
|
||||
label = __('Awaiting Upload...', 'infinite-uploads');
|
||||
} else if (video.status > 4) {
|
||||
label = __('Video Error. Upload again.', 'infinite-uploads');
|
||||
} else {
|
||||
label = sprintf(
|
||||
__('Video %d%% processed...', 'infinite-uploads'),
|
||||
video.encodeProgress
|
||||
);
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<div {...blockProps}>
|
||||
<div className="ratio-16-9-outer">
|
||||
<div className="ratio-16-9-inner" style={style}>
|
||||
<div className="ratio-16-9-content">
|
||||
<Spinner
|
||||
style={{
|
||||
height: '0.9em',
|
||||
width: '0.9em',
|
||||
}}
|
||||
/>{' '}
|
||||
{label}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<InspectorControls>
|
||||
<PanelBody title={__('Settings')}>
|
||||
<VideoCommonSettings
|
||||
setAttributes={setAttributes}
|
||||
attributes={attributes}
|
||||
/>
|
||||
</PanelBody>
|
||||
</InspectorControls>
|
||||
</>
|
||||
);
|
||||
}
|
||||
} else {
|
||||
return (
|
||||
<div {...blockProps}>
|
||||
<Placeholder
|
||||
icon={InfiniteUploadsIcon}
|
||||
instructions={__(
|
||||
'Upload a new video direct to the cloud or select a video from your cloud library.',
|
||||
'infinite-uploads'
|
||||
)}
|
||||
label={__('Infinite Uploads Video', 'infinite-uploads')}
|
||||
>
|
||||
<div className="placeholder-wrapper">
|
||||
<div className="uppy-wrapper">
|
||||
{!isUploading ? (
|
||||
<DragDrop
|
||||
width="100%"
|
||||
height="100%"
|
||||
// assuming `props.uppy` contains an Uppy instance:
|
||||
uppy={uppy}
|
||||
locale={{
|
||||
strings: {
|
||||
// Text to show on the droppable area.
|
||||
// `%{browse}` is replaced with a link that opens the system file selection dialog.
|
||||
dropHereOr: __(
|
||||
'Drop video file here or %{browse}.',
|
||||
'infinite-uploads'
|
||||
),
|
||||
// Used as the label for the link that opens the system file selection dialog.
|
||||
browse: __(
|
||||
'browse files',
|
||||
'infinite-uploads'
|
||||
),
|
||||
},
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
<StatusBar
|
||||
// assuming `props.uppy` contains an Uppy instance:
|
||||
uppy={uppy}
|
||||
hideUploadButton={false}
|
||||
hideAfterFinish={true}
|
||||
showProgressDetails
|
||||
/>
|
||||
</div>
|
||||
{!isUploading && (
|
||||
<LibraryModal selectVideo={selectVideo}/>
|
||||
)}
|
||||
</div>
|
||||
</Placeholder>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
102
wp-content/plugins/infinite-uploads/inc/video/block/editor.scss
Normal file
102
wp-content/plugins/infinite-uploads/inc/video/block/editor.scss
Normal file
@ -0,0 +1,102 @@
|
||||
/**
|
||||
* The following styles get applied inside the editor only.
|
||||
*
|
||||
* Replace them with your own styles or remove the file completely.
|
||||
*/
|
||||
.wp-block-infinite-uploads-video {
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
text-align: left;
|
||||
color: #1e1e1e;
|
||||
-moz-font-smoothing: subpixel-antialiased;
|
||||
-webkit-font-smoothing: subpixel-antialiased;
|
||||
border-radius: 2px;
|
||||
background-color: #fff;
|
||||
box-shadow: inset 0 0 0 1px #1e1e1e;
|
||||
outline: 1px solid transparent;
|
||||
|
||||
@import '../../../node_modules/@uppy/core/dist/style';
|
||||
@import '../../../node_modules/@uppy/drag-drop/dist/style';
|
||||
@import '../../../node_modules/@uppy/status-bar/dist/style';
|
||||
|
||||
.placeholder-wrapper {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.uppy-wrapper {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.uppy-StatusBar-progress {
|
||||
height: 1em;
|
||||
background-color: var(--wp-admin-theme-color);
|
||||
}
|
||||
|
||||
.uppy-StatusBar::before {
|
||||
height: 1em;
|
||||
}
|
||||
|
||||
.uppy-StatusBar-content {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.uppy-StatusBar-actions {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.uppy-DragDrop-inner {
|
||||
padding: 40px 20px;
|
||||
}
|
||||
|
||||
.uppy-DragDrop-arrow {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.ratio-16-9-outer {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
|
||||
&:before {
|
||||
content: '';
|
||||
display: block;
|
||||
padding-top: calc(9 / 16) * 100%;
|
||||
}
|
||||
|
||||
> .ratio-16-9-inner {
|
||||
background-size: cover;
|
||||
background-position: 50% 50%;
|
||||
background-repeat: no-repeat;
|
||||
background-color: #000000;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.ratio-16-9-content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: white;
|
||||
font-size: 1.5em;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.iup-video-overlay {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
border: 0;
|
||||
background: none;
|
||||
}
|
||||
}
|
||||
|
50
wp-content/plugins/infinite-uploads/inc/video/block/index.js
Normal file
50
wp-content/plugins/infinite-uploads/inc/video/block/index.js
Normal file
@ -0,0 +1,50 @@
|
||||
/**
|
||||
* Registers a new block provided a unique name and an object defining its behavior.
|
||||
*
|
||||
* @see https://developer.wordpress.org/block-editor/developers/block-api/#registering-a-block
|
||||
*/
|
||||
import {registerBlockType} from '@wordpress/blocks';
|
||||
|
||||
/**
|
||||
* Lets webpack process CSS, SASS or SCSS files referenced in JavaScript files.
|
||||
* All files containing `style` keyword are bundled together. The code used
|
||||
* gets applied both to the front of your site and to the editor. All other files
|
||||
* get applied to the editor only.
|
||||
*
|
||||
* @see https://www.npmjs.com/package/@wordpress/scripts#using-css
|
||||
*/
|
||||
import './style.scss';
|
||||
import './editor.scss';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import Edit from './edit';
|
||||
import save from './save';
|
||||
import metadata from './block.json';
|
||||
import {InfiniteUploadsIcon} from './components/Images';
|
||||
|
||||
/**
|
||||
* Every block starts by registering a new block type definition.
|
||||
*
|
||||
* @see https://developer.wordpress.org/block-editor/developers/block-api/#registering-a-block
|
||||
*/
|
||||
registerBlockType(metadata.name, {
|
||||
/**
|
||||
* Used to construct a preview for the block to be shown in the block inserter.
|
||||
*/
|
||||
example: {
|
||||
attributes: {
|
||||
video_id: '',
|
||||
},
|
||||
},
|
||||
/**
|
||||
* @see ./edit.js
|
||||
*/
|
||||
edit: Edit,
|
||||
/**
|
||||
* @see ./save.js
|
||||
*/
|
||||
save,
|
||||
icon: InfiniteUploadsIcon(false),
|
||||
});
|
40
wp-content/plugins/infinite-uploads/inc/video/block/save.js
Normal file
40
wp-content/plugins/infinite-uploads/inc/video/block/save.js
Normal file
@ -0,0 +1,40 @@
|
||||
/**
|
||||
* React hook that is used to mark the block wrapper element.
|
||||
* It provides all the necessary props like the class name.
|
||||
*
|
||||
* @see https://developer.wordpress.org/block-editor/packages/packages-block-editor/#useBlockProps
|
||||
*/
|
||||
import {useBlockProps} from '@wordpress/block-editor';
|
||||
|
||||
/**
|
||||
* The save function defines the way in which the different attributes should
|
||||
* be combined into the final markup, which is then serialized by the block
|
||||
* editor into `post_content`.
|
||||
*
|
||||
* @see https://developer.wordpress.org/block-editor/developers/block-api/block-edit-save/#save
|
||||
*
|
||||
* @param {Object} props Properties passed to the function.
|
||||
* @param {Object} props.attributes Available block attributes.
|
||||
* @return {WPElement} Element to render.
|
||||
*/
|
||||
export default function save({attributes}) {
|
||||
const blockProps = useBlockProps.save();
|
||||
if (attributes.video_id) {
|
||||
return (
|
||||
<figure {...blockProps}>
|
||||
<div className="iup-video-embed-wrapper">
|
||||
<iframe
|
||||
src={`https://iframe.mediadelivery.net/embed/${IUP_VIDEO.libraryId}/${attributes.video_id}?autoplay=${attributes.autoplay}&preload=${attributes.preload}&loop=${attributes.loop}&muted=${attributes.muted}`}
|
||||
loading="lazy"
|
||||
className="iup-video-embed"
|
||||
sandbox="allow-scripts allow-same-origin allow-presentation"
|
||||
allow="accelerometer; gyroscope; autoplay; encrypted-media; picture-in-picture;"
|
||||
allowFullScreen={true}
|
||||
></iframe>
|
||||
</div>
|
||||
</figure>
|
||||
);
|
||||
} else {
|
||||
return <div {...blockProps}></div>;
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
/**
|
||||
* The following styles get applied both on the front of your site
|
||||
* and in the editor.
|
||||
*
|
||||
* Replace them with your own styles or remove the file completely.
|
||||
*/
|
||||
.wp-block-infinite-uploads-video {
|
||||
.iup-video-embed-wrapper {
|
||||
position: relative;
|
||||
padding-top: 56.25%;
|
||||
min-width: var(--wp--style--global--content-size);
|
||||
}
|
||||
|
||||
.iup-video-embed {
|
||||
border: none;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user