/**
* 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;