From b02b0dd7be6ea6a37fb5ed89564d38991ab4f45a Mon Sep 17 00:00:00 2001 From: Chris Holder Date: Fri, 10 Jan 2025 14:58:52 -0600 Subject: [PATCH] Auto-launch reader onboading on first visit --- client/reader/onboarding/constants.tsx | 1 + client/reader/onboarding/index.tsx | 45 +++++++++++++++++--------- 2 files changed, 31 insertions(+), 15 deletions(-) diff --git a/client/reader/onboarding/constants.tsx b/client/reader/onboarding/constants.tsx index 9c63d0e2ce15b0..2b46b393a8fd49 100644 --- a/client/reader/onboarding/constants.tsx +++ b/client/reader/onboarding/constants.tsx @@ -1,2 +1,3 @@ export const READER_ONBOARDING_PREFERENCE_KEY = 'has_completed_reader_onboarding'; +export const READER_ONBOARDING_SEEN_PREFERENCE_KEY = 'has_seen_reader_onboarding'; export const READER_ONBOARDING_TRACKS_EVENT_PREFIX = 'calypso_reader_onboarding_'; diff --git a/client/reader/onboarding/index.tsx b/client/reader/onboarding/index.tsx index 9435648f1d325f..eed7306d99192d 100644 --- a/client/reader/onboarding/index.tsx +++ b/client/reader/onboarding/index.tsx @@ -5,16 +5,18 @@ import { Checklist, ChecklistItem, Task } from '@automattic/launchpad'; import { translate } from 'i18n-calypso'; import React, { useState, useEffect } from 'react'; import { + READER_ONBOARDING_SEEN_PREFERENCE_KEY, READER_ONBOARDING_PREFERENCE_KEY, READER_ONBOARDING_TRACKS_EVENT_PREFIX, } from 'calypso/reader/onboarding/constants'; import InterestsModal from 'calypso/reader/onboarding/interests-modal'; import SubscribeModal from 'calypso/reader/onboarding/subscribe-modal'; -import { useSelector } from 'calypso/state'; +import { useDispatch, useSelector } from 'calypso/state'; import { getCurrentUserDate, isCurrentUserEmailVerified, } from 'calypso/state/current-user/selectors'; +import { savePreference } from 'calypso/state/preferences/actions'; import { getPreference, hasReceivedRemotePreferences } from 'calypso/state/preferences/selectors'; import { getReaderFollowedTags } from 'calypso/state/reader/tags/selectors'; @@ -33,10 +35,15 @@ const ReaderOnboarding = ( { const hasCompletedOnboarding = useSelector( ( state ) => getPreference( state, READER_ONBOARDING_PREFERENCE_KEY ) ); + const hasSeenOnboarding = useSelector( ( state ) => + getPreference( state, READER_ONBOARDING_SEEN_PREFERENCE_KEY ) + ); const preferencesLoaded = useSelector( hasReceivedRemotePreferences ); const userRegistrationDate = useSelector( getCurrentUserDate ); const isEmailVerified = useSelector( isCurrentUserEmailVerified ); + const dispatch = useDispatch(); + const shouldShowOnboarding = forceShow || isEnabled( 'reader/force-onboarding' ) || @@ -46,20 +53,6 @@ const ReaderOnboarding = ( { isEmailVerified && new Date( userRegistrationDate ) >= new Date( '2024-10-01T00:00:00Z' ) ); - // Track if user viewed Reader Onboarding. - useEffect( () => { - if ( shouldShowOnboarding ) { - recordTracksEvent( `${ READER_ONBOARDING_TRACKS_EVENT_PREFIX }viewed` ); - } - }, [ shouldShowOnboarding ] ); - - // Notify the parent component if onboarding will render. - onRender?.( shouldShowOnboarding ); - - if ( ! shouldShowOnboarding ) { - return null; - } - // Modal state handlers with tracking. const openInterestsModal = () => { recordTracksEvent( `${ READER_ONBOARDING_TRACKS_EVENT_PREFIX }interests_modal_open` ); @@ -94,6 +87,28 @@ const ReaderOnboarding = ( { task?.actionDispatch?.(); }; + // Track if user viewed Reader Onboarding. + useEffect( () => { + if ( shouldShowOnboarding ) { + recordTracksEvent( `${ READER_ONBOARDING_TRACKS_EVENT_PREFIX }viewed` ); + } + }, [ shouldShowOnboarding, dispatch ] ); + + // Auto-open the interests modal if onboarding should render and it has never been opened before + useEffect( () => { + if ( shouldShowOnboarding && ! hasSeenOnboarding ) { + openInterestsModal(); + dispatch( savePreference( READER_ONBOARDING_SEEN_PREFERENCE_KEY, true ) ); + } + }, [ shouldShowOnboarding, hasSeenOnboarding, dispatch ] ); + + // Notify the parent component if onboarding will render. + onRender?.( shouldShowOnboarding ); + + if ( ! shouldShowOnboarding ) { + return null; + } + const taskOneCompleted = followedTags ? followedTags.length > 2 : false; const tasks: Task[] = [