Skip to content

Commit

Permalink
VideoPress: Add "publish first video" popover (#27714)
Browse files Browse the repository at this point in the history
* rename actions to verbs

* add firstUploadedVideoId to state

* add getFirstUploadedVideoId selector

* add dismissedFirstVideoPopover state

* add forwardRef on VideoThumbnail component

* add useFirstVideoPopover custom hook

* add href and external link flag to action popover button

* add PublishFirstVideoPopover component and remove useFirstVideoPopover hook

* add first video popover to video card and video row

* changelog

* changelog

* bump versions

* remove comment

* refactor translation to avoid build error

* fix action popover storybook controls

* add video guid to new post link query args

* create and initialize block editor content class

* bump versions

* add firstVideoProcessed state and show video post popover only after processed

* add nonce to new post link
  • Loading branch information
dhasilva authored Dec 6, 2022
1 parent 4b86d5c commit 3fcaffd
Show file tree
Hide file tree
Showing 33 changed files with 382 additions and 106 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: added

RNA: Add props to ActionPopover related to link on action button
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,18 @@ const ActionPopover = ( {
children,
step = null,
totalSteps = null,
actionButtonText = null,
actionButtonDisabled = false,
buttonContent = null,
buttonDisabled = false,
buttonHref = null,
buttonExternalLink = false,
offset = 32,
onClose,
onClick,
...otherPopoverProps
}: ActionPopoverProps ) => {
const [ isSm ] = useBreakpointMatch( 'sm' );

if ( ! title || ! children || ! actionButtonText ) {
if ( ! title || ! children || ! buttonContent ) {
return null;
}

Expand All @@ -46,8 +48,15 @@ const ActionPopover = ( {
};

const showSteps = Number.isFinite( step ) && Number.isFinite( totalSteps );
/* translators: 1 Current step, 2 Total steps */
const stepsText = showSteps ? sprintf( __( '%1$d of %2$d', 'jetpack' ), step, totalSteps ) : null;
let stepsText = null;
if ( showSteps ) {
stepsText = sprintf(
/* translators: 1 Current step, 2 Total steps */
__( '%1$d of %2$d', 'jetpack' ),
step,
totalSteps
);
}

return (
<Popover { ...popoverProps }>
Expand Down Expand Up @@ -80,10 +89,12 @@ const ActionPopover = ( {
<Button
variant="primary"
className={ styles[ 'action-button' ] }
disabled={ actionButtonDisabled }
disabled={ buttonDisabled }
onClick={ onClick }
isExternalLink={ buttonExternalLink }
href={ buttonHref }
>
{ actionButtonText }
{ buttonContent }
</Button>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,16 @@ export default {
totalSteps: {
control: { type: 'number' },
},
actionButtonText: {
buttonContent: {
control: { type: 'text' },
},
actionButtonDisabled: {
buttonDisabled: {
control: { type: 'boolean' },
},
buttonHref: {
control: { type: 'text' },
},
buttonExternalLink: {
control: { type: 'boolean' },
},
offset: {
Expand Down Expand Up @@ -89,8 +95,8 @@ const defaultArgs = {
children: 'Absque sudore et labore nullum opus perfectum est.',
step: null,
totalSteps: null,
actionButtonText: 'Next',
actionButtonDisabled: false,
buttonContent: 'Next',
buttonDisabled: false,
offset: 32,
position: 'top center',
noArrow: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ export type ActionPopoverProps = Popover.Props & {
children: React.ReactNode;
step?: number;
totalSteps?: number;
actionButtonText?: string;
actionButtonDisabled?: boolean;
buttonContent?: React.ReactNode;
buttonDisabled?: boolean;
buttonHref?: string;
buttonExternalLink?: boolean;
onClick?(): void;
};
2 changes: 1 addition & 1 deletion projects/js-packages/components/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@automattic/jetpack-components",
"version": "0.26.1",
"version": "0.26.2-alpha",
"description": "Jetpack Components Package",
"author": "Automattic",
"license": "GPL-2.0-or-later",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: added

VideoPress: Add first video popover
2 changes: 1 addition & 1 deletion projects/packages/videopress/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
"link-template": "https://github.com/Automattic/jetpack-videopress/compare/v${old}...v${new}"
},
"branch-alias": {
"dev-trunk": "0.8.x-dev"
"dev-trunk": "0.9.x-dev"
},
"version-constants": {
"::PACKAGE_VERSION": "src/class-package-version.php"
Expand Down
2 changes: 1 addition & 1 deletion projects/packages/videopress/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"private": true,
"name": "@automattic/jetpack-videopress",
"version": "0.8.4",
"version": "0.9.0-alpha",
"description": "VideoPress package",
"homepage": "https://github.com/Automattic/jetpack/tree/HEAD/projects/packages/videopress/#readme",
"bugs": {
Expand Down
1 change: 1 addition & 0 deletions projects/packages/videopress/src/class-admin-ui.php
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ public static function initial_state() {
'siteProductData' => My_Jetpack_Products::get_product( 'videopress' ),
'allowedVideoExtensions' => self::get_allowed_video_extensions(),
'initialState' => Data::get_initial_state(),
'contentNonce' => wp_create_nonce( 'videopress-content-nonce' ),
);
}

Expand Down
56 changes: 56 additions & 0 deletions projects/packages/videopress/src/class-block-editor-content.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php
/**
* VideoPress Block Editor Content
*
* @package automattic/jetpack-videopress
*/

namespace Automattic\Jetpack\VideoPress;

/**
* VideoPress block editor class for content generation
*/
class Block_Editor_Content {
/**
* Initializer
*
* This method should be called only once by the Initializer class. Do not call this method again.
*/
public static function init() {
if ( ! Status::is_active() ) {
return;
}

add_filter( 'default_content', array( static::class, 'video_block_by_guid' ), 10, 2 );
}

/**
* Generates a video block content with the given guid
*
* @param string $content Post content.
* @param WP_Post $post Post.
* @return string
*/
public static function video_block_by_guid( $content, $post ) {
if ( isset( $_GET['videopress_guid'], $_GET['_wpnonce'] )
&& wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['_wpnonce'] ) ), 'videopress-content-nonce' )
&& current_user_can( 'edit_post', $post->ID )
&& '' === $content
) {
$guid = sanitize_text_field( wp_unslash( $_GET['videopress_guid'] ) );

if ( ! empty( $guid ) ) {
// ref /client/lib/url/index.ts
$content = '<!-- wp:videopress/video {"guid":"' . $guid . '"} -->
<figure class="wp-block-videopress-video wp-block-jetpack-videopress jetpack-videopress-player">
<div class="jetpack-videopress-player__wrapper">
https://videopress.com/v/' . $guid . '?resizeToParent=true&amp;cover=true&amp;preloadContent=metadata&amp;useAverageColor=true
</div>
</figure>
<!-- /wp:videopress/video -->';
}
}

return $content;
}
}
1 change: 1 addition & 0 deletions projects/packages/videopress/src/class-initializer.php
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ private static function active_initialization() {
VideoPress_Rest_Api_V1_Settings::init();
XMLRPC::init();
Block_Editor_Extensions::init();
Block_Editor_Content::init();
self::register_oembed_providers();
if ( self::should_initialize_admin_ui() ) {
Admin_UI::init();
Expand Down
2 changes: 1 addition & 1 deletion projects/packages/videopress/src/class-package-version.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
* The Package_Version class.
*/
class Package_Version {
const PACKAGE_VERSION = '0.8.4';
const PACKAGE_VERSION = '0.9.0-alpha';

const PACKAGE_SLUG = 'videopress';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ declare global {
adminUrl: string;
adminUri: string;
siteSuffix: string;
contentNonce: string;
};
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ window.jetpackVideoPressInitialState = {
manage_url: 'http://localhost/wp-admin/admin.php?page=jetpack-videopress',
post_activation_url: '',
},
contentNonce: 'content-nonce',
};

export default {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/**
* External dependencies
*/
import { ActionPopover, Text } from '@automattic/jetpack-components';
import { useDispatch } from '@wordpress/data';
import { __ } from '@wordpress/i18n';
import { addQueryArgs } from '@wordpress/url';
/**
* Internal dependencies
*/
import { STORE_ID } from '../../../state';
import useVideo from '../../hooks/use-video';
import useVideos from '../../hooks/use-videos';
import styles from './styles.module.scss';
/**
* Types
*/
import { PublishFirstVideoPopoverProps } from './types';
import type React from 'react';

/**
* Publish First Video Popover component
*
* @param {PublishFirstVideoPopoverProps} props - Component props.
* @returns {React.ReactNode} - PublishFirstVideoPopover react component.
*/
const PublishFirstVideoPopover = ( {
id,
position = null,
anchor = null,
}: PublishFirstVideoPopoverProps ) => {
const dispatch = useDispatch( STORE_ID );
const { data } = useVideo( Number( id ) );
const { firstUploadedVideoId, firstVideoProcessed, dismissedFirstVideoPopover } = useVideos();
const showAddToPostPopover =
Number( firstUploadedVideoId ) === Number( id ) &&
firstVideoProcessed &&
! dismissedFirstVideoPopover;

const closePopover = () => dispatch.dismissFirstVideoPopover();

const nonce = window.jetpackVideoPressInitialState?.contentNonce ?? '';
const newPostURL = addQueryArgs( 'post-new.php', {
videopress_guid: data.guid,
_wpnonce: nonce,
} );

return (
showAddToPostPopover && (
<ActionPopover
title={ __( 'Publish your new video', 'jetpack-videopress-pkg' ) }
buttonContent={ __( 'Add video to post', 'jetpack-videopress-pkg' ) }
buttonHref={ newPostURL }
buttonExternalLink
anchor={ anchor }
onClose={ closePopover }
onClick={ closePopover }
noArrow={ false }
className={ styles[ 'action-popover' ] }
position={ position }
>
<Text>
{ __(
"Now that your video has been uploaded to VideoPress, it's time to show it to the world.",
'jetpack-videopress-pkg'
) }
</Text>
</ActionPopover>
)
);
};

export default PublishFirstVideoPopover;
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.action-popover {
cursor: auto;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* Types
*/
import type { Popover } from '@wordpress/components';

export type PublishFirstVideoPopoverProps = {
id: number | string;
position?: Popover.Position;
anchor?: Element;
};
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import Placeholder from '../placeholder';
/**
* Internal dependencies
*/
import PublishFirstVideoPopover from '../publish-first-video-popover';
import { ConnectVideoQuickActions } from '../video-quick-actions';
import VideoThumbnail from '../video-thumbnail';
import styles from './style.module.scss';
Expand Down Expand Up @@ -86,6 +87,7 @@ export const VideoCard = ( {
numberFormat( plays )
)
: '';
const [ anchor, setAnchor ] = useState( null );
const [ isSm ] = useBreakpointMatch( 'sm' );
const [ isOpen, setIsOpen ] = useState( false );
const disabled = loading || uploading;
Expand All @@ -110,6 +112,7 @@ export const VideoCard = ( {
duration={ loading ? null : duration }
editable={ loading ? false : editable }
uploadProgress={ uploadProgress }
ref={ setAnchor }
/>

<div className={ styles[ 'video-card__title-section' ] }>
Expand Down Expand Up @@ -147,6 +150,8 @@ export const VideoCard = ( {
) }
</div>

<PublishFirstVideoPopover id={ id } anchor={ anchor } />

{ showQuickActions && ! isSm && (
<QuickActions
id={ id }
Expand Down
Loading

0 comments on commit 3fcaffd

Please sign in to comment.