Skip to content

Commit

Permalink
My Jetpack: add connection animation (#40343)
Browse files Browse the repository at this point in the history
* My Jetpack: add new loading logic to My Jetpack

* changelog

* Add animation

* Adjust animation rhythm

* Fix sentences

* Adjust duration of the connected screen

* Adjust error handling and spacing

* Reset notices when initializing site connection
  • Loading branch information
IanRamosC authored Dec 2, 2024
1 parent 8c05e7a commit 7489029
Show file tree
Hide file tree
Showing 8 changed files with 217 additions and 51 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { useContext, useEffect, useLayoutEffect, useState } from 'react';
* Internal dependencies
*/
import { NoticeContext } from '../../context/notices/noticeContext';
import { NOTICE_SITE_CONNECTION_ERROR } from '../../context/notices/noticeTemplates';
import {
REST_API_CHAT_AUTHENTICATION_ENDPOINT,
REST_API_CHAT_AVAILABILITY_ENDPOINT,
Expand Down Expand Up @@ -151,13 +152,15 @@ export default function MyJetpackScreen() {
welcomeFlowExperiment={ welcomeFlowExperiment }
setWelcomeFlowExperiment={ setWelcomeFlowExperiment }
>
{ noticeMessage && siteIsRegistered && (
<GlobalNotice
message={ noticeMessage }
title={ noticeTitle }
options={ noticeOptions }
/>
) }
{ noticeMessage &&
( siteIsRegistered ||
noticeOptions?.id === NOTICE_SITE_CONNECTION_ERROR.options.id ) && (
<GlobalNotice
message={ noticeMessage }
title={ noticeTitle }
options={ noticeOptions }
/>
) }
</WelcomeFlow>
) : (
noticeMessage && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { initializeExPlat, loadExperimentAssignment } from '@automattic/jetpack-
import { __ } from '@wordpress/i18n';
import { useCallback, useContext } from 'react';
import { NoticeContext } from '../../context/notices/noticeContext';
import { NOTICE_SITE_CONNECTED } from '../../context/notices/noticeTemplates';
import { NOTICE_SITE_CONNECTION_ERROR } from '../../context/notices/noticeTemplates';
import useProductsByOwnership from '../../data/products/use-products-by-ownership';
import { getMyJetpackWindowInitialState } from '../../data/utils/get-my-jetpack-window-state';
import useAnalytics from '../../hooks/use-analytics';
Expand Down Expand Up @@ -47,13 +47,16 @@ const ConnectionStep = ( {
const { refetch: refetchOwnershipData } = useProductsByOwnership();

const onConnectSiteClick = useCallback( async () => {
resetNotice();

recordEvent( 'jetpack_myjetpack_welcome_banner_connect_site_click' );
onUpdateWelcomeFlowExperiment( state => ( { ...state, isLoading: true } ) );
await onActivateSite();

recordEvent( 'jetpack_myjetpack_welcome_banner_connect_site_success' );

try {
await onActivateSite();

recordEvent( 'jetpack_myjetpack_welcome_banner_connect_site_success' );

await sideloadTracks();

initializeExPlat();
Expand All @@ -70,9 +73,9 @@ const ConnectionStep = ( {
if ( variationName === 'treatment' ) {
window.location.href = jetpackPlansPath;
}
} catch ( error ) {
setNotice( NOTICE_SITE_CONNECTION_ERROR, resetNotice );
} finally {
resetNotice();
setNotice( NOTICE_SITE_CONNECTED, resetNotice );
refetchOwnershipData();

onUpdateWelcomeFlowExperiment( state => ( { ...state, isLoading: false } ) );
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import { Col, Text } from '@automattic/jetpack-components';
import { SVG, Path } from '@wordpress/components';
import { Spinner } from '@wordpress/components';
import { __, sprintf } from '@wordpress/i18n';
import clsx from 'clsx';
import styles from './style.module.scss';

const JetpackLogo = () => (
<SVG className="logo" viewBox="0 0 88 88" fill="none" xmlns="http://www.w3.org/2000/svg">
<Path
className={ styles[ 'circle-outline' ] }
d="M44 86C67.196 86 86 67.196 86 44C86 20.804 67.196 2 44 2C20.804 2 2 20.804 2 44C2 67.196 20.804 86 44 86Z"
stroke="#003010"
strokeWidth="1"
/>
<Path
className={ styles[ 'triangles-outline' ] }
d="M41.7319 8.73633V51.3088H19.8159L41.7319 8.73633ZM46.1835 79.2694V36.6129H68.1835L46.1835 79.2694Z"
stroke="#003010"
strokeWidth="1"
/>
<Path
className={ styles[ 'circle-fill' ] }
d="M44 88C68.3005 88 88 68.3005 88 44C88 19.6995 68.3005 0 44 0C19.6995 0 0 19.6995 0 44C0 68.3005 19.6995 88 44 88Z"
fill="#003010"
/>
<Path
className={ styles[ 'triangles-fill' ] }
fillRule="evenodd"
clipRule="evenodd"
d="M41.7319 8.73633V51.3088H19.8159L41.7319 8.73633ZM46.1835 79.2694V36.6129H68.1835L46.1835 79.2694Z"
fill="#48FF50"
/>
</SVG>
);

interface LoadingStepProps {
type: string;
}

const LoadingStep = ( { type }: LoadingStepProps ) => {
if ( type === 'connecting' || type === 'connection-ready' ) {
const connectingTitle = __( 'Connecting Jetpack', 'jetpack-my-jetpack' );
const connectingDescription = __(
'Getting things ready in the background — almost there!',
'jetpack-my-jetpack'
);
const connectionReadyTitle = sprintf(
/* translators: %s: is an emoji */
__( 'Jetpack is connected %s', 'jetpack-my-jetpack' ),
'🎉'
);
const connectionReadyDescription = __(
'You’re connected and ready to fly!',
'jetpack-my-jetpack'
);

return (
<Col className={ styles[ 'loading-banner' ] }>
<div
className={ clsx( styles[ 'banner-loader' ], {
[ styles[ 'connection-ready' ] ]: type === 'connection-ready',
} ) }
>
<JetpackLogo />
</div>
<Text variant="title-medium" mb={ 1 }>
{ type === 'connecting' ? connectingTitle : connectionReadyTitle }
</Text>
<Text variant="body-small">
{ type === 'connecting' ? connectingDescription : connectionReadyDescription }
</Text>
</Col>
);
}

if ( type === 'recommendations' ) {
return (
<Col className={ styles[ 'loading-banner' ] }>
<div className={ styles[ 'banner-loader' ] }>
<Spinner />
</div>
<Text variant="title-medium" mb={ 1 }>
{ __( 'Finding the best Jetpack tools', 'jetpack-my-jetpack' ) }
</Text>
<Text variant="body-small">
{ __(
'We’re crunching the numbers to find the Jetpack tools that are the best match for your site.',
'jetpack-my-jetpack'
) }
</Text>
</Col>
);
}

return <></>;
};

export default LoadingStep;
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import useAnalytics from '../../hooks/use-analytics';
import useMyJetpackConnection from '../../hooks/use-my-jetpack-connection';
import { CardWrapper } from '../card';
import ConnectionStep from './ConnectionStep';
import EvaluationProcessingStep from './EvaluationProcessingStep';
import EvaluationStep, { EvaluationAreas } from './EvaluationStep';
import LoadingStep from './LoadingStep';
import styles from './style.module.scss';
import type { FC, PropsWithChildren } from 'react';

Expand Down Expand Up @@ -46,8 +46,26 @@ const WelcomeFlow: FC< Props > = ( {
const [ isProcessingEvaluation, setIsProcessingEvaluation ] = useState( false );
const [ prevStep, setPrevStep ] = useState( '' );

const [ isConnectionReady, setIsConnectionReady ] = useState( null );

useEffect( () => {
if ( prevStep === 'site-connecting' && ! siteIsRegistering && siteIsRegistered ) {
setIsConnectionReady( true );

const timer = setTimeout( () => setIsConnectionReady( false ), 3000 );

return () => clearTimeout( timer );
}
}, [ prevStep, siteIsRegistered, siteIsRegistering ] );

const currentStep = useMemo( () => {
if ( ! siteIsRegistered || welcomeFlowExperiment.isLoading ) {
if (
siteIsRegistering ||
isConnectionReady ||
( siteIsRegistered && prevStep === 'site-connecting' && isConnectionReady === null )
) {
return 'site-connecting';
} else if ( ! siteIsRegistered || welcomeFlowExperiment.isLoading ) {
return 'connection';
} else if ( ! isProcessingEvaluation ) {
if ( ! recommendedModules && ! isJetpackUserNew() ) {
Expand All @@ -62,10 +80,13 @@ const WelcomeFlow: FC< Props > = ( {

return 'evaluation-processing';
}, [
isProcessingEvaluation,
recommendedModules,
siteIsRegistered,
isConnectionReady,
siteIsRegistering,
prevStep,
welcomeFlowExperiment.isLoading,
isProcessingEvaluation,
recommendedModules,
] );

useEffect( () => {
Expand Down Expand Up @@ -146,7 +167,10 @@ const WelcomeFlow: FC< Props > = ( {
onSubmitEvaluation={ handleEvaluation }
/>
) }
{ 'evaluation-processing' === currentStep && <EvaluationProcessingStep /> }
{ 'evaluation-processing' === currentStep && <LoadingStep type="recommendations" /> }
{ 'site-connecting' === currentStep && (
<LoadingStep type={ siteIsRegistering ? 'connecting' : 'connection-ready' } />
) }
</Container>
</CardWrapper>
<Button
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,12 @@ $sans-font: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen-San
padding-left: calc( var( --spacing-base ) * 3 );
}

.banner-evaluation {
.loading-banner {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 144px 0;
padding: 144px 32px;
background-image: radial-gradient(circle at 80% 80%, rgba(6, 158, 8, 0.15) 5%, rgba(255, 255, 255, 0) 50%);
background-repeat: no-repeat;
background-position: 100% 80%;
Expand All @@ -131,16 +131,63 @@ $sans-font: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen-San
margin-bottom: 24px;

svg {
width: 48px;
height: 48px;
width: 88px;
height: 88px;
color: var( --jp-green-40 );
animation: breathe 2s infinite ease-out 2s;
animation-delay: 2s;

circle {
stroke: var( --jp-green-5 );
.circle-outline, .circle-fill, .triangles-outline, .triangles-fill {
opacity: 0;
}

circle, path {
stroke-width: 4px;
.circle-outline {
stroke-dasharray: 276;
stroke-dashoffset: 276;
animation: drawCircle 2s ease-out forwards;
}

.triangles-outline {
animation: fadeIn 0.5s ease-in-out 1.5s forwards;
}
}

&.connection-ready {
svg {
animation: none;

.circle-fill {
animation: fadeIn 0.85s ease-out 0s forwards;
}
.triangles-fill {
animation: fadeIn 0.85s ease-out 0s forwards;
}
}
}
}

@keyframes drawCircle {
0% {
opacity: 1;
stroke-dashoffset: 276;
}
100% {
opacity: 1;
stroke-dashoffset: 0;
}
}

@keyframes breathe {
0%, 100% {
transform: scale(1);
}
50% {
transform: scale(1.06);
}
}

@keyframes fadeIn {
to {
opacity: 1;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,14 @@ export const NOTICE_SITE_CONNECTED: Notice = {
hideCloseButton: false,
},
};

export const NOTICE_SITE_CONNECTION_ERROR: Notice = {
message: __( 'Site connection failed. Please try again.', 'jetpack-my-jetpack' ),
options: {
id: 'site-connection-error-notice',
level: 'error',
actions: [],
priority: NOTICE_PRIORITY_HIGH,
hideCloseButton: false,
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: added

My Jetpack: add animation during site connection to make it less confusing to users connecting their site for the first time.

0 comments on commit 7489029

Please sign in to comment.