Skip to content

Commit

Permalink
Add/value to active state videopress card (#38812)
Browse files Browse the repository at this point in the history
* Add value to active state of VideoPress card

* changelog

* Return videoCount if error on featured stats call

* Update time format to accomodate years

* Update definition of videopress active

* Show stats if user has videos

* Simplify logic of videopress value section

* Left align protect headings per design

* Update monthly views heading to 30-day views

* Add transient

* Specify transient key to my jetpack

* Fixup project versions
  • Loading branch information
CodeyGuyDylan committed Aug 15, 2024
1 parent ee09161 commit 7015560
Show file tree
Hide file tree
Showing 14 changed files with 174 additions and 42 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import useProduct from '../../../data/products/use-product';
import baseStyles from '../style.module.scss';
import { AutoFirewallStatus } from './auto-firewall-status';
import { InfoTooltip } from './info-tooltip';
import { LoginsBlockedStatus } from './logins-blocked-status';
Expand Down Expand Up @@ -40,13 +41,13 @@ const ProtectValueSection = () => {
<ScanAndThreatStatus />
</div>
<div className="value-section__auto-firewall">
<div className="value-section__heading">Auto-Firewall</div>
<div className={ baseStyles.valueSectionHeading }>Auto-Firewall</div>
<div className="value-section__data">
<AutoFirewallStatus />
</div>
</div>
<div className="value-section__logins-blocked">
<div className="value-section__heading">Logins Blocked</div>
<div className={ baseStyles.valueSectionHeading }>Logins Blocked</div>
<div className="value-section__data">
<LoginsBlockedStatus />
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@ import useProduct from '../../../data/products/use-product';
import { getMyJetpackWindowInitialState } from '../../../data/utils/get-my-jetpack-window-state';
import useAnalytics from '../../../hooks/use-analytics';
import useMyJetpackConnection from '../../../hooks/use-my-jetpack-connection';
import baseStyles from '../style.module.scss';
import ShieldOff from './assets/shield-off.svg';
import ShieldPartial from './assets/shield-partial.svg';
import ShieldSuccess from './assets/shield-success.svg';
import { InfoTooltip } from './info-tooltip';
import { useProtectTooltipCopy } from './use-protect-tooltip-copy';
import type { ReactElement, PropsWithChildren } from 'react';
import type { PropsWithChildren, ReactElement } from 'react';

export const ScanAndThreatStatus = () => {
const slug = 'protect';
Expand Down Expand Up @@ -115,7 +116,9 @@ function ThreatStatus( {
if ( criticalThreatCount ) {
return (
<>
<div className="value-section__heading">{ __( 'Threats', 'jetpack-my-jetpack' ) }</div>
<div className={ baseStyles.valueSectionHeading }>
{ __( 'Threats', 'jetpack-my-jetpack' ) }
</div>
<div className="value-section__data">
<div className="scan-threats__critical-threats">
<div className="scan-threats__threat-count">{ numThreats }</div>
Expand Down Expand Up @@ -151,7 +154,9 @@ function ThreatStatus( {

return (
<>
<div className="value-section__heading">{ __( 'Threats', 'jetpack-my-jetpack' ) }</div>
<div className={ baseStyles.valueSectionHeading }>
{ __( 'Threats', 'jetpack-my-jetpack' ) }
</div>
<div className="value-section__data">
<div className="scan-threats__threat-count">{ numThreats }</div>
</div>
Expand All @@ -174,7 +179,9 @@ function ScanStatus( { status }: { status: 'success' | 'partial' | 'off' } ) {
if ( status === 'success' ) {
return (
<>
<div className="value-section__heading">{ __( 'Scan', 'jetpack-my-jetpack' ) }</div>
<div className={ baseStyles.valueSectionHeading }>
{ __( 'Scan', 'jetpack-my-jetpack' ) }
</div>
<div className="value-section__data">
<div>
<img
Expand All @@ -191,7 +198,9 @@ function ScanStatus( { status }: { status: 'success' | 'partial' | 'off' } ) {
if ( status === 'partial' ) {
return (
<>
<div className="value-section__heading">{ __( 'Scan', 'jetpack-my-jetpack' ) }</div>
<div className={ baseStyles.valueSectionHeading }>
{ __( 'Scan', 'jetpack-my-jetpack' ) }
</div>
<div className="value-section__data">
<div>
<img
Expand Down Expand Up @@ -223,7 +232,7 @@ function ScanStatus( { status }: { status: 'success' | 'partial' | 'off' } ) {
}
return (
<>
<div className="value-section__heading">{ __( 'Scan', 'jetpack-my-jetpack' ) }</div>
<div className={ baseStyles.valueSectionHeading }>{ __( 'Scan', 'jetpack-my-jetpack' ) }</div>
<div className="value-section__data">
<div>
<img
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,7 @@
> div {
display: flex;
flex-direction: column;
}

&__heading {
font-size: var(--font-body-extra-small);
color: var(--jp-gray-100);
font-weight: 500;
margin-bottom: calc(var(--spacing-base) + 2px);
line-height: var(--font-title-small);
text-align: center;
align-items: flex-start;
}

&__last-scan {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,14 @@
}
}

.valueSectionHeading {
font-size: var(--font-body-extra-small);
color: var(--jp-gray-100);
font-weight: 500;
margin-bottom: calc(var(--spacing-base) + 2px);
line-height: var(--font-title-small);
}

// Since we're adding so much info into the My Jetpack product cards, here we'll increase
// the min-width of the cards to 300px, and otherwise wrap around.
@media screen and (min-width: 599px) and (max-width: 1290px) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*/
import { Text } from '@automattic/jetpack-components';
import { useCallback } from 'react';
import { PRODUCT_STATUSES } from '../../../constants';
import { PRODUCT_SLUGS } from '../../../data/constants';
import useProduct from '../../../data/products/use-product';
import { getMyJetpackWindowInitialState } from '../../../data/utils/get-my-jetpack-window-state';
Expand All @@ -17,9 +18,12 @@ const slug = PRODUCT_SLUGS.VIDEOPRESS;

const VideopressCard: ProductCardComponent = ( { admin } ) => {
const { detail } = useProduct( slug );
const { isPluginActive = false } = detail || {};
const { status } = detail || {};
const { videopress: data } = getMyJetpackWindowInitialState();

const isPluginActive =
status === PRODUCT_STATUSES.ACTIVE || status === PRODUCT_STATUSES.CAN_UPGRADE;

const descriptionText = useVideoPressCardDescription( {
isPluginActive,
videoCount: data.videoCount,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,22 @@ p.description {
color: var( --jp-gray-70 );
font-size: var( --font-body-small );
margin: 0 0 1rem;
}

.videopress-card__value-section {
display: flex;

&__container {
display: flex;
flex-direction: column;
align-items: flex-start;

width: 50%;
}

&__value {
font-size: calc( var( --font-headline-small ) - 4px );
color: var( --jp-gray-90 );
line-height: 1.125;
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
import { __ } from '@wordpress/i18n';
import formatNumber from '../../../utils/format-number';
import formatTime from '../../../utils/format-time';
import baseStyles from '../style.module.scss';
import type { FC } from 'react';

import './style.scss';
Expand All @@ -8,11 +12,50 @@ interface VideoPressValueSectionProps {
}

const VideoPressValueSection: FC< VideoPressValueSectionProps > = ( { isPluginActive, data } ) => {
if ( ! isPluginActive && data.videoCount ) {
return <span className="videopress-card__video-count">{ data.videoCount }</span>;
const { videoCount, featuredStats } = data || {};
const shortenedNumberConfig: Intl.NumberFormatOptions = {
maximumFractionDigits: 1,
notation: 'compact',
};

if ( ! videoCount ) {
return null;
}

if ( ! isPluginActive ) {
return <span className="videopress-card__video-count">{ videoCount }</span>;
}

return null;
const currentViews = featuredStats?.data?.views?.current;
const currentWatchTime = featuredStats?.data?.watch_time?.current;

if ( currentViews === undefined || currentWatchTime === undefined ) {
return null;
}

return (
<div className="videopress-card__value-section">
<div className="videopress-card__value-section__container">
<span className={ baseStyles.valueSectionHeading }>
{ __( '30-Day views', 'jetpack-my-jetpack' ) }
</span>

<span className="videopress-card__value-section__value">
{ formatNumber( currentViews, shortenedNumberConfig ) }
</span>
</div>

<div className="videopress-card__value-section__container">
<span className={ baseStyles.valueSectionHeading }>
{ __( 'Total time watched', 'jetpack-my-jetpack' ) }
</span>

<span className="videopress-card__value-section__value">
{ formatTime( currentWatchTime ) }
</span>
</div>
</div>
);
};

export default VideoPressValueSection;
Original file line number Diff line number Diff line change
@@ -1,19 +1,11 @@
import { numberFormat } from '@automattic/jetpack-components';
import { Card } from '@wordpress/components';
import { arrowDown, arrowUp, Icon } from '@wordpress/icons';
import clsx from 'clsx';
import PropTypes from 'prop-types';
import React from 'react';
import formatNumber from '../../utils/format-number';
import styles from './style.module.scss';

const formatNumber = ( number, config = {} ) => {
if ( number === null || ! Number.isFinite( number ) ) {
return '-';
}

return numberFormat( number, config );
};

const subtract = ( a, b ) => {
if ( typeof a !== 'number' || typeof b !== 'number' ) {
return null;
Expand Down
13 changes: 13 additions & 0 deletions projects/packages/my-jetpack/_inc/utils/format-number.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { numberFormat } from '@automattic/jetpack-components';

type FormatNumberFunction = ( number: number, config: Intl.NumberFormatOptions ) => string;

const formatNumber: FormatNumberFunction = ( number, config = {} ) => {
if ( number === null || ! Number.isFinite( number ) ) {
return '-';
}

return numberFormat( number, config );
};

export default formatNumber;
28 changes: 28 additions & 0 deletions projects/packages/my-jetpack/_inc/utils/format-time.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
type FormatTimeFunction = ( seconds: number ) => string;

const formatTime: FormatTimeFunction = ( seconds: number ) => {
const minutes = Math.floor( seconds / 60 );
const hours = Math.floor( minutes / 60 );
const days = Math.floor( hours / 24 );
const years = Math.floor( days / 365 );

if ( years > 0 ) {
return `${ years }y ${ days % 365 }d`;
}

if ( days > 0 ) {
return `${ days }d ${ hours % 24 }h`;
}

if ( hours > 0 ) {
return `${ hours }h ${ minutes % 60 }m`;
}

if ( minutes > 0 ) {
return `${ minutes }m ${ seconds % 60 }s`;
}

return `${ seconds }s`;
};

export default formatTime;
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: added

Add value to active card state on VideoPress My Jetpack card
24 changes: 18 additions & 6 deletions projects/packages/my-jetpack/src/class-initializer.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,10 @@ class Initializer {
'jetpack-search',
);

const MY_JETPACK_SITE_INFO_TRANSIENT_KEY = 'my-jetpack-site-info';

const MY_JETPACK_SITE_INFO_TRANSIENT_KEY = 'my-jetpack-site-info';
const UPDATE_HISTORICALLY_ACTIVE_JETPACK_MODULES_KEY = 'update-historically-active-jetpack-modules';

const MISSING_CONNECTION_NOTIFICATION_KEY = 'missing-connection';
const MISSING_CONNECTION_NOTIFICATION_KEY = 'missing-connection';
const VIDEOPRESS_STATS_KEY = 'my-jetpack-videopress-stats';

/**
* Holds info/data about the site (from the /sites/%d endpoint)
Expand Down Expand Up @@ -314,10 +313,23 @@ public static function get_videopress_stats() {
);
}

$videopress_stats = new VideoPress_Stats();
$featured_stats = get_transient( self::VIDEOPRESS_STATS_KEY );

if ( ! $featured_stats ) {
$videopress_stats = new VideoPress_Stats();
$featured_stats = $videopress_stats->get_featured_stats( 60 );
}

if ( is_wp_error( $featured_stats ) || ! $featured_stats ) {
return array(
'videoCount' => $video_count,
);
}

set_transient( self::VIDEOPRESS_STATS_KEY, $featured_stats, HOUR_IN_SECONDS );

return array(
'featuredStats' => $videopress_stats->get_featured_stats(),
'featuredStats' => $featured_stats,
'videoCount' => $video_count,
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: added

Add value to active card state on VideoPress My Jetpack card
Loading

0 comments on commit 7015560

Please sign in to comment.