diff --git a/projects/packages/videopress/changelog/update-videopress-privacy-edit-page b/projects/packages/videopress/changelog/update-videopress-privacy-edit-page new file mode 100644 index 000000000000..452e1cbebd87 --- /dev/null +++ b/projects/packages/videopress/changelog/update-videopress-privacy-edit-page @@ -0,0 +1,4 @@ +Significance: patch +Type: changed + +VideoPress: Support edit privacy on edit details page diff --git a/projects/packages/videopress/src/client/admin/components/edit-video-details/index.tsx b/projects/packages/videopress/src/client/admin/components/edit-video-details/index.tsx index b6f218861adb..3af6439cf53d 100644 --- a/projects/packages/videopress/src/client/admin/components/edit-video-details/index.tsx +++ b/projects/packages/videopress/src/client/admin/components/edit-video-details/index.tsx @@ -11,8 +11,14 @@ import { useBreakpointMatch, JetpackVideoPressLogo, } from '@automattic/jetpack-components'; +import { SelectControl } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; -import { Icon, chevronRightSmall, arrowLeft } from '@wordpress/icons'; +import { + Icon, + chevronRightSmall, + arrowLeft, + globe as siteDefaultPrivacyIcon, +} from '@wordpress/icons'; import classnames from 'classnames'; import { useEffect } from 'react'; import { useHistory, Prompt } from 'react-router-dom'; @@ -20,7 +26,14 @@ import { useHistory, Prompt } from 'react-router-dom'; * Internal dependencies */ import { Link } from 'react-router-dom'; +import privatePrivacyIcon from '../../../components/icons/crossed-eye-icon'; +import publicPrivacyIcon from '../../../components/icons/uncrossed-eye-icon'; import { VideoPlayer } from '../../../components/video-frame-selector'; +import { + VIDEO_PRIVACY_LEVEL_PRIVATE, + VIDEO_PRIVACY_LEVEL_PUBLIC, + VIDEO_PRIVACY_LEVEL_SITE_DEFAULT, +} from '../../../state/constants'; import { usePermission } from '../../hooks/use-permission'; import useUnloadPrevent from '../../hooks/use-unload-prevent'; import { useVideosQuery } from '../../hooks/use-videos'; @@ -144,6 +157,7 @@ const EditVideoDetails = () => { height, title, description, + privacySetting, // Playback Token isFetchingPlaybackToken, // Page State/Actions @@ -155,6 +169,7 @@ const EditVideoDetails = () => { // Metadata setTitle, setDescription, + setPrivacySetting, processing, // Poster Image useVideoAsThumbnail, @@ -261,6 +276,43 @@ const EditVideoDetails = () => { shortcode={ shortcode ?? '' } loading={ isFetchingData } /> + setPrivacySetting( value ) } + prefix={ + // Casting for unknown since allowing only a string is a mistake + // at WP Components + ( ( +
+ +
+ ) as unknown ) as string + } + options={ [ + { + label: __( 'Site default', 'jetpack-videopress-pkg' ), + value: VIDEO_PRIVACY_LEVEL_SITE_DEFAULT, + }, + { + label: __( 'Public', 'jetpack-videopress-pkg' ), + value: VIDEO_PRIVACY_LEVEL_PUBLIC, + }, + { + label: __( 'Private', 'jetpack-videopress-pkg' ), + value: VIDEO_PRIVACY_LEVEL_PRIVATE, + }, + ] } + /> diff --git a/projects/packages/videopress/src/client/admin/components/edit-video-details/style.module.scss b/projects/packages/videopress/src/client/admin/components/edit-video-details/style.module.scss index f3ab4f93ea62..a7ccb7fdd350 100644 --- a/projects/packages/videopress/src/client/admin/components/edit-video-details/style.module.scss +++ b/projects/packages/videopress/src/client/admin/components/edit-video-details/style.module.scss @@ -68,3 +68,13 @@ align-items: center; } } + +.privacy { + padding: 0 calc(var(--spacing-base) * 3); // 0|24px + margin-top: calc(var( --spacing-base) * 4); // 32px +} + +.privacy-icon { + display: flex; + margin-left: var(--spacing-base); // 8px +} diff --git a/projects/packages/videopress/src/client/admin/components/edit-video-details/use-edit-details.ts b/projects/packages/videopress/src/client/admin/components/edit-video-details/use-edit-details.ts index 9b36208a9d77..6308aebeb035 100644 --- a/projects/packages/videopress/src/client/admin/components/edit-video-details/use-edit-details.ts +++ b/projects/packages/videopress/src/client/admin/components/edit-video-details/use-edit-details.ts @@ -10,6 +10,7 @@ import { useParams, useHistory } from 'react-router-dom'; */ import useMetaUpdate from '../../../hooks/use-meta-update'; import { STORE_ID } from '../../../state'; +import { VIDEO_PRIVACY_LEVELS } from '../../../state/constants'; import usePlaybackToken from '../../hooks/use-playback-token'; import usePosterEdit from '../../hooks/use-poster-edit'; import useVideo from '../../hooks/use-video'; @@ -67,7 +68,7 @@ export default () => { const { videoId: videoIdFromParams } = useParams(); const videoId = Number( videoIdFromParams ); - const { data: video, isFetching, processing } = useVideo( Number( videoId ) ); + const { data: video, isFetching, processing, updateVideoPrivacy } = useVideo( Number( videoId ) ); const { playbackToken, isFetchingPlaybackToken } = usePlaybackToken( video ); @@ -78,6 +79,9 @@ export default () => { const [ updating, setUpdating ] = useState( false ); const [ updated, setUpdated ] = useState( false ); + const [ privacySetting, setPrivacySetting ] = useState( + VIDEO_PRIVACY_LEVELS[ video?.privacySetting ] + ); const [ formData, setFormData ] = useState( { title: video?.title, @@ -112,7 +116,11 @@ export default () => { setPosterImageSource( 'video' ); }, [ selectedTime ] ); - const hasChanges = metaChanged || selectedTime != null || libraryAttachment != null; + const hasChanges = + metaChanged || + selectedTime != null || + libraryAttachment != null || + privacySetting !== VIDEO_PRIVACY_LEVELS[ video?.privacySetting ]; const selectPosterImageFromLibrary = async () => { const attachment = await selectAttachmentFromLibrary(); @@ -134,12 +142,20 @@ export default () => { promises.push( updatePosterImageFromLibrary( libraryAttachment.id ) ); } + if ( privacySetting !== VIDEO_PRIVACY_LEVELS[ video?.privacySetting ] ) { + updateVideoPrivacy( privacySetting ); + } + // TODO: handle errors Promise.allSettled( promises ).then( () => { const videoData = { ...video, ...formData }; + // posterImage already set by the action delete videoData.posterImage; + // privacySetting already set by the action + delete videoData.privacySetting; + setUpdating( false ); dispatch?.setVideo( videoData ); setUpdated( true ); @@ -184,6 +200,8 @@ export default () => { updating, updated, selectedTime, + setPrivacySetting, + privacySetting, ...metaEditData, ...posterEditData, };