/** * External dependencies */ import { Text, Button, useBreakpointMatch } from '@automattic/jetpack-components'; import { dateI18n } from '@wordpress/date'; import { sprintf, __ } from '@wordpress/i18n'; import { Icon, chevronDown, chevronUp } from '@wordpress/icons'; import classNames from 'classnames'; import { useState, useRef } from 'react'; /** * Internal dependencies */ import privateIcon from '../../../components/icons/crossed-eye-icon'; import { usePermission } from '../../hooks/use-permission'; import useVideo from '../../hooks/use-video'; import Checkbox from '../checkbox'; import Placeholder from '../placeholder'; import { ConnectVideoQuickActions } from '../video-quick-actions'; import VideoThumbnail from '../video-thumbnail'; import StatsBase from './stats'; import styles from './style.module.scss'; /** * Types */ import { VideoRowProps } from './types'; const millisecondsToMinutesAndSeconds = ( milliseconds?: number ) => { if ( milliseconds ) { const minutes = Math.floor( milliseconds / 60000 ); const seconds = Math.floor( ( milliseconds % 60000 ) / 1000 ); return `${ minutes }:${ seconds < 10 ? '0' : '' }${ seconds }`; } }; const Stats = ( { duration, uploadDate, plays, isPrivate, loading = false, }: { duration?: string; uploadDate?: string; plays?: number; isPrivate?: boolean; loading?: boolean; } ) => { const [ isSmall ] = useBreakpointMatch( 'sm' ); const durationLabel = __( 'Duration', 'jetpack-videopress-pkg' ); const playsLabel = __( 'Plays', 'jetpack-videopress-pkg' ); const privacyLabel = __( 'Privacy', 'jetpack-videopress-pkg' ); const privateLabel = __( 'Private', 'jetpack-videopress-pkg' ); const publicLabel = __( 'Public', 'jetpack-videopress-pkg' ); const privacyElement = isSmall ? ( <> { privacyLabel } { isPrivate ? privateLabel : publicLabel } ) : ( isPrivate && ); const durationElement = isSmall && duration ? ( <> { durationLabel } { duration } ) : ( duration ); const playsElement = isSmall && Number.isFinite( plays ) ? ( <> { playsLabel } { plays } ) : ( plays ); const uploadElement = isSmall ? null : uploadDate; return ( ); }; export const VideoRow = ( { id, className = '', checked = false, title, titleAdornment = null, thumbnail, showThumbnail = false, duration, uploadDate, plays, isPrivate, onActionClick, onSelect, showActionButton = true, showQuickActions = true, showCheckbox = true, loading = false, uploading = false, processing = false, isUpdatingPoster = false, actionButtonLabel = __( 'Edit video details', 'jetpack-videopress-pkg' ), disableActionButton = false, disabled = false, uploadProgress, }: VideoRowProps ) => { const textRef = useRef( null ); const checkboxRef = useRef( null ); const { canPerformAction } = usePermission(); const [ isSmall ] = useBreakpointMatch( 'sm' ); const [ keyPressed, setKeyDown ] = useState( false ); const [ expanded, setExpanded ] = useState( false ); const durationInMinutesAndSeconds = millisecondsToMinutesAndSeconds( duration ); const uploadDateFormatted = dateI18n( 'M j, Y', uploadDate, null ); const isEllipsisActive = textRef?.current?.offsetWidth < textRef?.current?.scrollWidth; const showTitleLabel = ! isSmall && isEllipsisActive; const showActions = ( showActionButton || showQuickActions ) && ! loading && ! disabled; const showBottom = ! loading && ( ! isSmall || ( isSmall && expanded ) ); const canExpand = isSmall && ! loading && ( showActionButton || Boolean( duration ) || Number.isFinite( plays ) || typeof isPrivate === 'boolean' ); const hoverDisabled = isSmall || loading || disabled; const isSpaceOrEnter = code => code === 'Space' || code === 'Enter'; const wrapperAriaLabel = sprintf( /* translators: 1 Video title, 2 Video duration, 3 Video upload date */ __( 'Video: %1$s, Duration: %2$s, Upload Date: %3$s. Click to edit details.', 'jetpack-videopress-pkg' ), title, durationInMinutesAndSeconds, uploadDateFormatted ); const handleClickWithStopPropagation = callback => event => { event.stopPropagation(); callback?.( event ); }; const actionButton = ( ); const handleInfoWrapperClick = e => { if ( canExpand ) { setExpanded( current => ! current ); } else { handleClick( e ); } }; const handleClick = e => { if ( e.target !== checkboxRef.current ) { checkboxRef?.current?.click(); } }; const handleKeyDown = e => { if ( isSpaceOrEnter( e?.code ) ) { setKeyDown( true ); } }; const handleKeyUp = e => { if ( isSpaceOrEnter( e?.code ) ) { setKeyDown( false ); handleClick( e ); } }; return (
{ showCheckbox && (
) }
{ showThumbnail && (
) }
{ showTitleLabel && ( { title } ) } { loading ? ( ) : ( { title } { titleAdornment } ) } { isSmall && ( <> { loading ? ( ) : ( { uploadDateFormatted } ) } ) }
{ canExpand && }
{ showBottom && (
{ ! isSmall && showActions && (
{ showActionButton && actionButton } { showQuickActions && id && }
) } { isSmall && (
{ showActionButton && actionButton } { showQuickActions && id && }
) }
) }
); }; export const ConnectVideoRow = ( { id, ...restProps }: VideoRowProps ) => { const { isDeleting, uploading, processing, isUpdatingPoster, data, uploadProgress } = useVideo( id ); const loading = ( isDeleting || restProps?.loading ) && ! uploading && ! processing; return ( ); }; export type { VideoRowProps }; export { StatsBase as Stats }; export default ConnectVideoRow;