| | |
| | | //edit.js |
| | | import { __ } from '@wordpress/i18n'; |
| | | import { |
| | | useBlockProps, |
| | |
| | | } from '@wordpress/components'; |
| | | import './editor.scss'; |
| | | |
| | | const ALLOWED_VIDEO_TYPES = ['video/mp4', 'video/webm', 'video/ogg', 'video/ogv']; |
| | | const ALLOWED_VIDEO_TYPES = ['video']; |
| | | |
| | | const INNER_BLOCKS_TEMPLATE = [ |
| | | ['core/heading', { |
| | |
| | | }] |
| | | ]; |
| | | |
| | | |
| | | |
| | | export default function Edit({ attributes, setAttributes }) { |
| | | const { |
| | | posterId, |
| | | posterUrl, |
| | | videoSources, |
| | | mobileSources, |
| | | fadeEffect, |
| | | overlayOpacity, |
| | | contentAlignment, |
| | |
| | | }); |
| | | }; |
| | | |
| | | const onSelectVideo = (media, isMobile = false) => { |
| | | const newSource = { |
| | | id: media.id, |
| | | url: media.url, |
| | | mime: media.mime |
| | | }; |
| | | const onSelectVideos = (mediaItems) => { |
| | | // multiple=true returns an array |
| | | const items = Array.isArray(mediaItems) ? mediaItems : [mediaItems]; |
| | | const newSources = items |
| | | .filter(media => !videoSources.some(s => s.id === media.id)) |
| | | .map(media => ({ |
| | | id: media.id, |
| | | url: media.url, |
| | | mime: media.mime |
| | | })); |
| | | |
| | | if (isMobile) { |
| | | // Check if this format already exists in mobile sources |
| | | const exists = mobileSources.some(s => s.mime === media.mime); |
| | | if (!exists) { |
| | | setAttributes({ |
| | | mobileSources: [...mobileSources, newSource] |
| | | }); |
| | | } |
| | | } else { |
| | | // Check if this format already exists in desktop sources |
| | | const exists = videoSources.some(s => s.mime === media.mime); |
| | | if (!exists) { |
| | | setAttributes({ |
| | | videoSources: [...videoSources, newSource] |
| | | }); |
| | | } |
| | | if (newSources.length) { |
| | | setAttributes({ |
| | | videoSources: [...videoSources, ...newSources] |
| | | }); |
| | | } |
| | | }; |
| | | |
| | | const removeVideoSource = (index, isMobile = false) => { |
| | | if (isMobile) { |
| | | const updated = [...mobileSources]; |
| | | updated.splice(index, 1); |
| | | setAttributes({ mobileSources: updated }); |
| | | } else { |
| | | const updated = [...videoSources]; |
| | | updated.splice(index, 1); |
| | | setAttributes({ videoSources: updated }); |
| | | } |
| | | const removeVideoSource = (index) => { |
| | | const updated = [...videoSources]; |
| | | updated.splice(index, 1); |
| | | setAttributes({ videoSources: updated }); |
| | | }; |
| | | |
| | | const renderVideoSourceList = (sources, isMobile = false) => { |
| | |
| | | </BaseControl> |
| | | |
| | | <BaseControl |
| | | label={__('Desktop Video Sources', 'jvb')} |
| | | help={__('Add multiple formats for better browser support', 'jvb')} |
| | | label={__('Video Sources', 'jvb')} |
| | | help={__('Add multiple formats for better browser support (mp4, webm, etc.)', 'jvb')} |
| | | > |
| | | {renderVideoSourceList(videoSources, false)} |
| | | {videoSources.length > 0 && ( |
| | | <ul className="video-source-list"> |
| | | {videoSources.map((source, index) => ( |
| | | <li key={index} className="video-source-item"> |
| | | <span className="video-source-mime">{source.mime}</span> |
| | | <Button |
| | | isDestructive |
| | | isSmall |
| | | onClick={() => removeVideoSource(index)} |
| | | > |
| | | {__('Remove', 'jvb')} |
| | | </Button> |
| | | </li> |
| | | ))} |
| | | </ul> |
| | | )} |
| | | <MediaUploadCheck> |
| | | <MediaUpload |
| | | onSelect={(media) => onSelectVideo(media, false)} |
| | | multiple={true} |
| | | onSelect={onSelectVideos} |
| | | allowedTypes={ALLOWED_VIDEO_TYPES} |
| | | render={({ open }) => ( |
| | | <Button |
| | | onClick={open} |
| | | variant="secondary" |
| | | > |
| | | {__('Add Desktop Video', 'jvb')} |
| | | </Button> |
| | | )} |
| | | /> |
| | | </MediaUploadCheck> |
| | | </BaseControl> |
| | | |
| | | <BaseControl |
| | | label={__('Mobile Video Sources (Optional)', 'jvb')} |
| | | help={__('Smaller videos for mobile devices', 'jvb')} |
| | | > |
| | | {renderVideoSourceList(mobileSources, true)} |
| | | <MediaUploadCheck> |
| | | <MediaUpload |
| | | onSelect={(media) => onSelectVideo(media, true)} |
| | | allowedTypes={ALLOWED_VIDEO_TYPES} |
| | | render={({ open }) => ( |
| | | <Button |
| | | onClick={open} |
| | | variant="secondary" |
| | | > |
| | | {__('Add Mobile Video', 'jvb')} |
| | | <Button onClick={open} variant="secondary"> |
| | | {__('Add Video', 'jvb')} |
| | | </Button> |
| | | )} |
| | | /> |
| | |
| | | <div className="video-info"> |
| | | <p> |
| | | {videoSources.length} {__('desktop source(s)', 'jvb')} |
| | | {mobileSources.length > 0 && |
| | | `, ${mobileSources.length} ${__('mobile source(s)', 'jvb')}` |
| | | } |
| | | </p> |
| | | </div> |
| | | </div> |