Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: added

VideoPress: set block video by providing a GUID value
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@
* WordPress dependencies
*/
import { MediaReplaceFlow } from '@wordpress/block-editor';
import { AdminAjaxQueryAttachmentsResponseItemProps } from '../../../../../types';
/**
* Internal dependencies
*/
import { VIDEOPRESS_VIDEO_ALLOWED_MEDIA_TYPES } from '../../constants';
import { VideoBlockAttributes } from '../../types';
/**
* Types
*/
import type { AdminAjaxQueryAttachmentsResponseItemProps } from '../../../../../types';
import type { VideoBlockAttributes } from '../../types';

import './style.scss';

type ReplaceControlProps = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { __ } from '@wordpress/i18n';
*/
import useResumableUploader from '../../../../../hooks/use-resumable-uploader';
import { uploadFromLibrary } from '../../../../../hooks/use-uploader';
import { pickGUIDFromUrl } from '../../../../../lib/url';
import { buildVideoPressURL } from '../../../../../lib/url';
import { VIDEOPRESS_VIDEO_ALLOWED_MEDIA_TYPES } from '../../constants';
import { PlaceholderWrapper } from '../../edit';
import { description, title } from '../../index';
Expand Down Expand Up @@ -104,20 +104,20 @@ const VideoPressUploader = ( {
/**
* Handler to add a video via an URL.
*
* @param {string} videoUrl - URL of the video to attach
* @param {string} videoSource - URL of the video to attach
* @param {string} id - Attachment ID if available
*/
function onSelectURL( videoUrl, id = undefined ) {
const videoGuid = pickGUIDFromUrl( videoUrl );
if ( ! videoGuid ) {
function onSelectURL( videoSource, id ) {
// If the video source is a VideoPress URL, we can use it directly.
const videoUrlData = buildVideoPressURL( videoSource );
if ( ! videoUrlData ) {
setUploadErrorDataState( {
data: { message: __( 'Invalid VideoPress URL', 'jetpack-videopress-pkg' ) },
} );
return;
}

// Update guid based on the URL.
setAttributes( { guid: videoGuid, src: videoUrl, id } );
setAttributes( { guid: videoUrlData.guid, src: videoUrlData.url, id } );
handleDoneUpload();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import debugFactory from 'debug';
* Internal dependencies
*/
import getMediaToken from '../../../lib/get-media-token';
import { getVideoPressUrl, pickGUIDFromUrl } from '../../../lib/url';
import { buildVideoPressURL, getVideoPressUrl } from '../../../lib/url';
import { useSyncMedia } from '../../hooks/use-video-data-update';
import ColorPanel from './components/color-panel';
import DetailsPanel from './components/details-panel';
Expand Down Expand Up @@ -481,15 +481,15 @@ export default function VideoPressEdit( {
description: media.description,
} );
} }
onSelectURL={ url => {
const videoGuid = pickGUIDFromUrl( url );
if ( ! videoGuid ) {
onSelectURL={ videoSource => {
const videoUrlData = buildVideoPressURL( videoSource );
if ( ! videoUrlData ) {
debug( 'Invalid URL. No video GUID provided' );
return;
}

// Update guid based on the URL.
setAttributes( { guid: videoGuid, src: url } );
setAttributes( { guid: videoUrlData.guid, src: videoUrlData.url } );
} }
/>
</BlockControls>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ import {
* Return media token data hiting the admin-ajax endpoint.
*
* @param {MediaTokenScopeProps} scope - The scope of the token to request.
* @param {GetMediaTokenArgsProps} args - function arguments
* @returns {MediaTokenProps} Media token data.
* @param {GetMediaTokenArgsProps} args - function arguments.
* @returns {MediaTokenProps} Media token data.
*/
const getMediaToken = function (
scope: MediaTokenScopeProps,
Expand Down
78 changes: 62 additions & 16 deletions projects/packages/videopress/src/client/lib/url/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
import { addQueryArgs } from '@wordpress/url';
import { VideoBlockAttributes } from '../../block-editor/blocks/video/types';
import { VideoBlockAttributes, VideoGUID } from '../../block-editor/blocks/video/types';

type VideoPressUrlOptions = Pick<
VideoBlockAttributes,
| 'autoplay'
| 'controls'
| 'loop'
| 'muted'
| 'playsinline'
| 'poster'
| 'preload'
| 'seekbarColor'
| 'seekbarPlayedColor'
| 'seekbarLoadingColor'
| 'useAverageColor'
>;

export const getVideoPressUrl = (
guid: string,
Expand All @@ -15,20 +30,7 @@ export const getVideoPressUrl = (
seekbarPlayedColor,
seekbarLoadingColor,
useAverageColor,
}: Pick<
VideoBlockAttributes,
| 'autoplay'
| 'controls'
| 'loop'
| 'muted'
| 'playsinline'
| 'poster'
| 'preload'
| 'seekbarColor'
| 'seekbarPlayedColor'
| 'seekbarLoadingColor'
| 'useAverageColor'
>
}: VideoPressUrlOptions
) => {
if ( ! guid ) {
return null;
Expand Down Expand Up @@ -64,7 +66,7 @@ export const getVideoPressUrl = (
return addQueryArgs( `https://videopress.com/v/${ guid }`, options );
};

export const pickGUIDFromUrl = ( url: string ) => {
export const pickGUIDFromUrl: ( url: string ) => null | string = url => {
if ( ! url ) {
return null;
}
Expand All @@ -79,3 +81,47 @@ export const pickGUIDFromUrl = ( url: string ) => {

return urlParts.groups.guid;
};

/**
* Check if a string is a valid VideoPress GUID.
*
* @param {string} value - The string to check.
* @returns {boolean | VideoGUID} Video GUID if the string is valid, false otherwise.
*/
export function isVideoPressGuid( value: string ): boolean | VideoGUID {
const guid = value.match( /^[a-zA-Z\d]{8}$/ );
if ( ! guid ) {
return false;
}

return guid[ 0 ];
}

/**
* Build a VideoPress URL from a VideoPress GUID or a VideoPress URL.
* The function returns an { url, guid } object, or false.
*
* @param {string | VideoGUID} value - The VideoPress GUID or URL.
* @param {VideoPressUrlOptions} attributes - The VideoPress URL options.
* @returns {false | string} VideoPress URL if the string is valid, false otherwise.
*/
export function buildVideoPressURL(
value: string | VideoGUID,
attributes?: VideoPressUrlOptions
): false | { url: string; guid: VideoGUID } {
const isGuidValue = isVideoPressGuid( value );
if ( isGuidValue ) {
if ( ! attributes ) {
return { url: `https://videopress.com/v/${ value }`, guid: value };
}

return { url: getVideoPressUrl( value, attributes ), guid: value };
}

const isGuidFromUrl = pickGUIDFromUrl( value );
if ( isGuidFromUrl ) {
return { url: value, guid: isGuidFromUrl };
}

return false;
}