Skip to content

Commit

Permalink
Alternative Support Widget Experiment (#78282)
Browse files Browse the repository at this point in the history
  • Loading branch information
AllTerrainDeveloper authored and pull[bot] committed Mar 1, 2024
1 parent 1788a8a commit 4561068
Show file tree
Hide file tree
Showing 16 changed files with 592 additions and 18 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/assets/images/odysseus/wapuu-inverse.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
22 changes: 21 additions & 1 deletion client/layout/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ import { isWpMobileApp, isWcMobileApp } from 'calypso/lib/mobile-app';
import { isWooOAuth2Client } from 'calypso/lib/oauth2-clients';
import { getMessagePathForJITM } from 'calypso/lib/route';
import UserVerificationChecker from 'calypso/lib/user/verification-checker';
import OdysseusAssistant from 'calypso/odysseus';
import { OdysseusAssistantProvider } from 'calypso/odysseus/context';
import { isOffline } from 'calypso/state/application/selectors';
import { getCurrentOAuth2Client } from 'calypso/state/oauth2-clients/ui/selectors';
import { getPreference } from 'calypso/state/preferences/selectors';
Expand Down Expand Up @@ -198,6 +200,17 @@ class Layout extends Component {
// intentionally don't remove these in unmount
}

shouldShowOdysseusAssistant() {
// We will only show the Odysseus Assistant under the "Upgrades" menu.
return (
[ 'plans', 'add-ons', 'domains', 'email', 'site-purchases', 'checkout' ].includes(
this.props.sectionName
) &&
! this.props.isOffline &&
config.isEnabled( 'odysseus' )
);
}

renderMasterbar( loadHelpCenterIcon ) {
if ( this.props.masterbarIsHidden ) {
return <EmptyMasterbar />;
Expand Down Expand Up @@ -305,7 +318,14 @@ class Layout extends Component {
{ this.props.secondary }
</div>
<div id="primary" className="layout__primary">
{ this.props.primary }
{ this.shouldShowOdysseusAssistant() ? (
<OdysseusAssistantProvider sectionName={ this.props.sectionName }>
{ this.props.primary }
<OdysseusAssistant />
</OdysseusAssistantProvider>
) : (
this.props.primary
) }
</div>
</div>
<AsyncLoad require="calypso/layout/community-translator" placeholder={ null } />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
usePromoteWidget,
PromoteWidgetStatus,
} from 'calypso/lib/promote-post';
import { useOdysseusAssistantContext } from 'calypso/odysseus/context';
import { bumpStat, composeAnalytics, recordTracksEvent } from 'calypso/state/analytics/actions';
import { savePreference } from 'calypso/state/preferences/actions';
import { getPreference } from 'calypso/state/preferences/selectors';
Expand Down Expand Up @@ -68,13 +69,23 @@ export const QuickLinks = ( {
siteEditorUrl,
} ) => {
const translate = useTranslate();
const { sendNudge } = useOdysseusAssistantContext();
const [
debouncedUpdateHomeQuickLinksToggleStatus,
,
flushDebouncedUpdateHomeQuickLinksToggleStatus,
] = useDebouncedCallback( updateHomeQuickLinksToggleStatus, 1000 );
const isPromotePostActive = usePromoteWidget() === PromoteWidgetStatus.ENABLED;

const addNewDomain = () => {
sendNudge( {
nudge: 'add-domain',
initialMessage:
'I see you want to add a domain. I can give you a few tips on how to do that.',
} );
trackAddDomainAction();
};

const customizerLinks =
isStaticHomePage && canEditPages ? (
<ActionBox
Expand Down Expand Up @@ -174,7 +185,7 @@ export const QuickLinks = ( {
<ActionBox
href={ `/domains/add/${ siteSlug }` }
hideLinkIndicator
onClick={ trackAddDomainAction }
onClick={ addNewDomain }
label={ translate( 'Add a domain' ) }
gridicon="add-outline"
/>
Expand Down
29 changes: 16 additions & 13 deletions client/my-sites/domains/domain-management/list/domain-row.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import Badge from 'calypso/components/badge';
import { useMyDomainInputMode } from 'calypso/components/domains/connect-domain-step/constants';
import EllipsisMenu from 'calypso/components/ellipsis-menu';
import FormCheckbox from 'calypso/components/forms/form-checkbox';
import MaterialIcon from 'calypso/components/material-icon';
import PopoverMenuItem from 'calypso/components/popover-menu/item';
import {
canCurrentUserAddEmail,
Expand Down Expand Up @@ -39,6 +38,7 @@ import {
emailManagement,
emailManagementPurchaseNewEmailAccount,
} from 'calypso/my-sites/email/paths';
import { useOdysseusAssistantContext } from 'calypso/odysseus/context';
import { recordTracksEvent } from 'calypso/state/analytics/actions';

import './domain-row.scss';
Expand Down Expand Up @@ -95,16 +95,7 @@ class DomainRow extends PureComponent {
}

renderSite() {
const { site, translate } = this.props;
if ( site?.options?.is_domain_only ) {
return (
<div className="domain-row__site-cell">
<Button href={ createSiteFromDomainOnly( site?.slug, site?.ID ) } plain>
<MaterialIcon icon="add" /> { translate( 'Create site' ) }
</Button>
</div>
);
}
const { site } = this.props;
return (
<div className="domain-row__site-cell">
<Button href={ domainManagementList( site?.slug ) } plain>
Expand Down Expand Up @@ -345,7 +336,12 @@ class DomainRow extends PureComponent {
};

goToDNSManagement = () => {
const { currentRoute, domain, site } = this.props;
const { currentRoute, domain, site, sendNudge } = this.props;
sendNudge( {
nudge: 'dns-settings',
initialMessage: `I see you want to change your DNS settings for your domain ${ domain.name }. That's a complex thing, but I can guide you and help you at any moment.`,
context: { domain: domain.domain },
} );
page( domainManagementDns( site.slug, domain.domain, currentRoute ) );
};

Expand Down Expand Up @@ -537,4 +533,11 @@ class DomainRow extends PureComponent {
}
}

export default connect()( localize( DomainRow ) );
function withOdysseusAssistantContext( Component ) {
return function WrappedComponent( props ) {
const { sendNudge } = useOdysseusAssistantContext();
return <Component { ...props } sendNudge={ sendNudge } />;
};
}

export default connect()( withOdysseusAssistantContext( localize( DomainRow ) ) );
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Button, CompactCard } from '@automattic/components';
import { useTranslate } from 'i18n-calypso';
import SectionHeader from 'calypso/components/section-header';
import { emailManagementPurchaseNewEmailAccount } from 'calypso/my-sites/email/paths';
import { useOdysseusAssistantContext } from 'calypso/odysseus/context';
import { useSelector } from 'calypso/state';
import getCurrentRoute from 'calypso/state/selectors/get-current-route';
import { getSelectedSite } from 'calypso/state/ui/selectors';
Expand All @@ -16,7 +17,7 @@ type EmailListInactiveItemProps = {

const EmailListInactiveItem = ( { domain, source }: EmailListInactiveItemProps ) => {
const translate = useTranslate();

const { sendNudge } = useOdysseusAssistantContext();
const selectedSite = useSelector( getSelectedSite );
const currentRoute = useSelector( getCurrentRoute );

Expand All @@ -31,6 +32,15 @@ const EmailListInactiveItem = ( { domain, source }: EmailListInactiveItemProps )
currentRoute,
source
) }
onClick={ () => {
sendNudge( {
nudge: 'email-comparison',
initialMessage: `I see you want to an email provider to your domain ${ domain.name }. I can give you a few tips on how to do that.`,
context: {
domain: domain.name,
},
} );
} }
>
{ translate( 'Add Email' ) }
</Button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
MailboxFormFieldBase,
MutableFormFieldNames,
} from 'calypso/my-sites/email/form/mailboxes/types';
import { useOdysseusAssistantContext } from 'calypso/odysseus/context';
import type { ReactNode } from 'react';

import './style.scss';
Expand Down Expand Up @@ -123,6 +124,7 @@ const NewMailBoxList = (
};

const [ mailboxes, setMailboxes ] = useState( [ createNewMailbox() ] );
const { sendNudge } = useOdysseusAssistantContext();
const isTitan = provider === EmailProvider.Titan;

const persistMailboxesToState = useCallback( () => {
Expand All @@ -137,6 +139,12 @@ const NewMailBoxList = (
}, [ hiddenFieldNames.join( '' ) ] ); // eslint-disable-line react-hooks/exhaustive-deps

const addMailbox = () => {
sendNudge( {
nudge: 'add-mailbox',
initialMessage:
'I see you want to add a mailbox. I can give you a few tips on how to do that.',
context: { mailbox_count: mailboxes.length, domain: selectedDomainName },
} );
const newMailboxes = [ ...mailboxes, createNewMailbox() ];
const eventName = isTitan
? 'calypso_email_titan_add_mailboxes_add_another_mailbox_button_click'
Expand All @@ -157,8 +165,14 @@ const NewMailBoxList = (

setMailboxes( newMailboxes );
recordTracksEvent( eventName, { mailbox_count: newMailboxes.length } );
sendNudge( {
nudge: 'remove-mailbox',
initialMessage:
'I see you want to remove a mailbox. I can give you a few tips on how to do that.',
context: { mailbox_count: newMailboxes.length, domain: selectedDomainName },
} );
},
[ isTitan, mailboxes ]
[ isTitan, mailboxes, sendNudge ]
);

const handleCancel = () => onCancel();
Expand Down
16 changes: 15 additions & 1 deletion client/my-sites/plans/main.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { addQueryArgs } from '@wordpress/url';
import { localize, useTranslate } from 'i18n-calypso';
import page from 'page';
import PropTypes from 'prop-types';
import { Component } from 'react';
import { Component, useEffect } from 'react';
import { connect } from 'react-redux';
import Banner from 'calypso/components/banner';
import DocumentHead from 'calypso/components/data/document-head';
Expand All @@ -36,6 +36,7 @@ import { PerformanceTrackerStop } from 'calypso/lib/performance-tracking';
import PlansNavigation from 'calypso/my-sites/plans/navigation';
import P2PlansMain from 'calypso/my-sites/plans/p2-plans-main';
import PlansFeaturesMain from 'calypso/my-sites/plans-features-main';
import { useOdysseusAssistantContext } from 'calypso/odysseus/context';
import { getPlanSlug } from 'calypso/state/plans/selectors';
import { getByPurchaseId } from 'calypso/state/purchases/selectors';
import { canCurrentUser } from 'calypso/state/selectors/can-current-user';
Expand Down Expand Up @@ -473,6 +474,19 @@ const ConnectedPlans = connect( ( state ) => {
} )( withCartKey( withShoppingCart( localize( withTrackingTool( 'HotJar' )( Plans ) ) ) ) );

export default function PlansWrapper( props ) {
const { sendNudge } = useOdysseusAssistantContext();

useEffect( () => {
if ( props.intervalType === 'monthly' ) {
sendNudge( {
nudge: 'monthly-plan',
initialMessage:
'I see you are sitting on a monthly plan. I can recommend you to switch to an annual plan, so you can save some money.',
context: { plan: 'monthly' },
} );
}
}, [ props.intervalType ] );

return (
<CalypsoShoppingCartProvider>
<ConnectedPlans { ...props } />
Expand Down
56 changes: 56 additions & 0 deletions client/odysseus/context/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { createContext, useContext, useState } from 'react';
import type { ReactNode } from 'react';

// eslint-disable-next-line @typescript-eslint/no-empty-function
const noop = () => {};

export type Nudge = {
nudge: string;
initialMessage: string;
context?: Record< string, unknown >;
};
interface OdysseusAssistantContextInterface {
currentView: string;
setCurrentView: ( currentView: string ) => void;
sectionName: string;
sendNudge: ( nudge: Nudge ) => void;
lastNudge: Nudge | null;
}

const defaultCurrentViewContextInterface = {
currentView: '',
setCurrentView: noop,
sectionName: '',
sendNudge: noop,
lastNudge: null,
};

// Create a new context
const OdysseusAssistantContext = createContext< OdysseusAssistantContextInterface >(
defaultCurrentViewContextInterface
);

// Custom hook to access the OdysseusAssistantContext
const useOdysseusAssistantContext = () => useContext( OdysseusAssistantContext );

// Create a provider component for the context
const OdysseusAssistantProvider = ( {
sectionName,
children,
}: {
sectionName: string;
children: ReactNode;
} ) => {
const [ currentView, setCurrentView ] = useState( '' );
const [ lastNudge, setLastNudge ] = useState< Nudge | null >( null );

return (
<OdysseusAssistantContext.Provider
value={ { currentView, setCurrentView, sectionName, sendNudge: setLastNudge, lastNudge } }
>
{ children }
</OdysseusAssistantContext.Provider>
);
};

export { OdysseusAssistantContext, OdysseusAssistantProvider, useOdysseusAssistantContext };
Loading

0 comments on commit 4561068

Please sign in to comment.