woocommerce/plugins/woocommerce-admin/client/header/index.js

189 lines
5.1 KiB
JavaScript
Raw Normal View History

/**
* External dependencies
*/
import { __, sprintf } from '@wordpress/i18n';
import { useEffect, useLayoutEffect, useRef } from '@wordpress/element';
import { Tooltip } from '@wordpress/components';
import classnames from 'classnames';
import { decodeEntities } from '@wordpress/html-entities';
Add WooCommerce Mobile App Banner Ad for Android and iOS (https://github.com/woocommerce/woocommerce-admin/pull/5037) Fixes woocommerce/woocommerce-admin#4654 The feature calls for a mobile app ad banner to be displayed to users on mobile devices. Based on the discussion in woocommerce/woocommerce-admin#4654 this implements the following: 1. [an iOS Smart App Banner](https://developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariWebContent/PromotingAppswithAppBanners/PromotingAppswithAppBanners.html). This banner is a meta tag that is generated in PHP. It will only display on iOS devices. One note about this: **This tag is not directly trackable like the implemented Android banner. If we would like to track its success then I believe [these instructions are relevant](https://stackoverflow.com/questions/12906502/is-it-possible-to-track-click-throughs-from-iphone-smart-banner/20422334woocommerce/woocommerce-admin#20422334)**. 2. A mobile app banner ad that **only displays on Android** and only displays at the `738px` breakpoint specified in the issue. To only display this banner ad on Android, we use basic checking of the user agent string. I weighed this up against other approaches and for this kind of niche use case a simple UA string check is (imho) still the best way to do this. 3. The banner ad makes use of user preferences to retain a per user setting that determines if that user has dismissed the Android banner. We don't/can't do anything like this for the iOS Smart App Banner (but in theory we shouldn't need to).
2020-08-27 01:46:53 +00:00
import { useUserPreferences } from '@woocommerce/data';
import { getSetting } from '@woocommerce/wc-admin-settings';
import { Text } from '@woocommerce/experimental';
import { Icon, chevronLeft } from '@wordpress/icons';
import { getHistory, updateQueryString } from '@woocommerce/navigation';
import { ENTER, SPACE } from '@wordpress/keycodes';
import { recordEvent } from '@woocommerce/tracks';
/**
* Internal dependencies
*/
import './style.scss';
import ActivityPanel from './activity-panel';
Add WooCommerce Mobile App Banner Ad for Android and iOS (https://github.com/woocommerce/woocommerce-admin/pull/5037) Fixes woocommerce/woocommerce-admin#4654 The feature calls for a mobile app ad banner to be displayed to users on mobile devices. Based on the discussion in woocommerce/woocommerce-admin#4654 this implements the following: 1. [an iOS Smart App Banner](https://developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariWebContent/PromotingAppswithAppBanners/PromotingAppswithAppBanners.html). This banner is a meta tag that is generated in PHP. It will only display on iOS devices. One note about this: **This tag is not directly trackable like the implemented Android banner. If we would like to track its success then I believe [these instructions are relevant](https://stackoverflow.com/questions/12906502/is-it-possible-to-track-click-throughs-from-iphone-smart-banner/20422334woocommerce/woocommerce-admin#20422334)**. 2. A mobile app banner ad that **only displays on Android** and only displays at the `738px` breakpoint specified in the issue. To only display this banner ad on Android, we use basic checking of the user agent string. I weighed this up against other approaches and for this kind of niche use case a simple UA string check is (imho) still the best way to do this. 3. The banner ad makes use of user preferences to retain a per user setting that determines if that user has dismissed the Android banner. We don't/can't do anything like this for the iOS Smart App Banner (but in theory we shouldn't need to).
2020-08-27 01:46:53 +00:00
import { MobileAppBanner } from '../mobile-banner';
import useIsScrolled from '../hooks/useIsScrolled';
import Navigation from '../navigation';
const renderTaskListBackButton = () => {
const currentUrl = new URL( window.location.href );
const task = currentUrl.searchParams.get( 'task' );
if ( task ) {
const homeText = __( 'WooCommerce Home', 'woocommerce-admin' );
const navigateHome = () => {
recordEvent( 'topbar_back_button', {
page_name: getPageTitle( window.title ),
} );
updateQueryString( {}, getHistory().location.pathname, {} );
};
// if it's a task list page, render a back button to the homescreen
return (
<Tooltip text={ homeText }>
<div
tabIndex="0"
role="button"
data-testid="header-back-button"
className="woocommerce-layout__header-back-button"
onKeyDown={ ( { keyCode } ) => {
if ( keyCode === ENTER || keyCode === SPACE ) {
navigateHome();
}
} }
>
<Icon icon={ chevronLeft } onClick={ navigateHome } />
</div>
</Tooltip>
);
}
return null;
};
const getPageTitle = ( defaultTitle ) => {
const currentUrl = new URL( window.location.href );
const task = currentUrl.searchParams.get( 'task' );
// If it's the task list then render a title based on which task the user is on.
return (
{
payments: __( 'Set up payments', 'woocommerce-admin' ),
tax: __( 'Add tax rates', 'woocommerce-admin' ),
appearance: __( 'Personalize your store', 'woocommerce-admin' ),
products: __( 'Add products', 'woocommerce-admin' ),
shipping: __( 'Set up shipping costs', 'woocommerce-admin' ),
}[ task ] || defaultTitle
);
};
export const Header = ( { sections, isEmbedded = false, query } ) => {
const headerElement = useRef( null );
const siteTitle = getSetting( 'siteTitle', '' );
const pageTitle = sections.slice( -1 )[ 0 ];
const isScrolled = useIsScrolled();
Add WooCommerce Mobile App Banner Ad for Android and iOS (https://github.com/woocommerce/woocommerce-admin/pull/5037) Fixes woocommerce/woocommerce-admin#4654 The feature calls for a mobile app ad banner to be displayed to users on mobile devices. Based on the discussion in woocommerce/woocommerce-admin#4654 this implements the following: 1. [an iOS Smart App Banner](https://developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariWebContent/PromotingAppswithAppBanners/PromotingAppswithAppBanners.html). This banner is a meta tag that is generated in PHP. It will only display on iOS devices. One note about this: **This tag is not directly trackable like the implemented Android banner. If we would like to track its success then I believe [these instructions are relevant](https://stackoverflow.com/questions/12906502/is-it-possible-to-track-click-throughs-from-iphone-smart-banner/20422334woocommerce/woocommerce-admin#20422334)**. 2. A mobile app banner ad that **only displays on Android** and only displays at the `738px` breakpoint specified in the issue. To only display this banner ad on Android, we use basic checking of the user agent string. I weighed this up against other approaches and for this kind of niche use case a simple UA string check is (imho) still the best way to do this. 3. The banner ad makes use of user preferences to retain a per user setting that determines if that user has dismissed the Android banner. We don't/can't do anything like this for the iOS Smart App Banner (but in theory we shouldn't need to).
2020-08-27 01:46:53 +00:00
const { updateUserPreferences, ...userData } = useUserPreferences();
const isModalDismissed = userData.android_app_banner_dismissed === 'yes';
let debounceTimer = null;
const className = classnames( 'woocommerce-layout__header', {
'is-scrolled': isScrolled,
} );
useLayoutEffect( () => {
updateBodyMargin();
window.addEventListener( 'resize', updateBodyMargin );
return () => {
window.removeEventListener( 'resize', updateBodyMargin );
const wpBody = document.querySelector( '#wpbody' );
if ( ! wpBody ) {
return;
}
wpBody.style.marginTop = null;
};
}, [ isModalDismissed ] );
const updateBodyMargin = () => {
clearTimeout( debounceTimer );
debounceTimer = setTimeout( function () {
const wpBody = document.querySelector( '#wpbody' );
if ( ! wpBody || ! headerElement.current ) {
return;
}
wpBody.style.marginTop = `${ headerElement.current.offsetHeight }px`;
}, 200 );
};
useEffect( () => {
if ( ! isEmbedded ) {
Add WooCommerce Mobile App Banner Ad for Android and iOS (https://github.com/woocommerce/woocommerce-admin/pull/5037) Fixes woocommerce/woocommerce-admin#4654 The feature calls for a mobile app ad banner to be displayed to users on mobile devices. Based on the discussion in woocommerce/woocommerce-admin#4654 this implements the following: 1. [an iOS Smart App Banner](https://developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariWebContent/PromotingAppswithAppBanners/PromotingAppswithAppBanners.html). This banner is a meta tag that is generated in PHP. It will only display on iOS devices. One note about this: **This tag is not directly trackable like the implemented Android banner. If we would like to track its success then I believe [these instructions are relevant](https://stackoverflow.com/questions/12906502/is-it-possible-to-track-click-throughs-from-iphone-smart-banner/20422334woocommerce/woocommerce-admin#20422334)**. 2. A mobile app banner ad that **only displays on Android** and only displays at the `738px` breakpoint specified in the issue. To only display this banner ad on Android, we use basic checking of the user agent string. I weighed this up against other approaches and for this kind of niche use case a simple UA string check is (imho) still the best way to do this. 3. The banner ad makes use of user preferences to retain a per user setting that determines if that user has dismissed the Android banner. We don't/can't do anything like this for the iOS Smart App Banner (but in theory we shouldn't need to).
2020-08-27 01:46:53 +00:00
const documentTitle = sections
.map( ( section ) => {
return Array.isArray( section ) ? section[ 1 ] : section;
} )
.reverse()
.join( ' &lsaquo; ' );
const decodedTitle = decodeEntities(
sprintf(
/* translators: 1: document title. 2: page title */
__(
'%1$s &lsaquo; %2$s &#8212; WooCommerce',
'woocommerce-admin'
),
documentTitle,
siteTitle
)
);
if ( document.title !== decodedTitle ) {
document.title = decodedTitle;
}
}
Add WooCommerce Mobile App Banner Ad for Android and iOS (https://github.com/woocommerce/woocommerce-admin/pull/5037) Fixes woocommerce/woocommerce-admin#4654 The feature calls for a mobile app ad banner to be displayed to users on mobile devices. Based on the discussion in woocommerce/woocommerce-admin#4654 this implements the following: 1. [an iOS Smart App Banner](https://developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariWebContent/PromotingAppswithAppBanners/PromotingAppswithAppBanners.html). This banner is a meta tag that is generated in PHP. It will only display on iOS devices. One note about this: **This tag is not directly trackable like the implemented Android banner. If we would like to track its success then I believe [these instructions are relevant](https://stackoverflow.com/questions/12906502/is-it-possible-to-track-click-throughs-from-iphone-smart-banner/20422334woocommerce/woocommerce-admin#20422334)**. 2. A mobile app banner ad that **only displays on Android** and only displays at the `738px` breakpoint specified in the issue. To only display this banner ad on Android, we use basic checking of the user agent string. I weighed this up against other approaches and for this kind of niche use case a simple UA string check is (imho) still the best way to do this. 3. The banner ad makes use of user preferences to retain a per user setting that determines if that user has dismissed the Android banner. We don't/can't do anything like this for the iOS Smart App Banner (but in theory we shouldn't need to).
2020-08-27 01:46:53 +00:00
}, [ isEmbedded, sections, siteTitle ] );
const dismissHandler = () => {
updateUserPreferences( {
android_app_banner_dismissed: 'yes',
} );
};
const backButton = renderTaskListBackButton();
const backButtonClass = backButton ? 'with-back-button' : '';
return (
<div className={ className } ref={ headerElement }>
Add WooCommerce Mobile App Banner Ad for Android and iOS (https://github.com/woocommerce/woocommerce-admin/pull/5037) Fixes woocommerce/woocommerce-admin#4654 The feature calls for a mobile app ad banner to be displayed to users on mobile devices. Based on the discussion in woocommerce/woocommerce-admin#4654 this implements the following: 1. [an iOS Smart App Banner](https://developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariWebContent/PromotingAppswithAppBanners/PromotingAppswithAppBanners.html). This banner is a meta tag that is generated in PHP. It will only display on iOS devices. One note about this: **This tag is not directly trackable like the implemented Android banner. If we would like to track its success then I believe [these instructions are relevant](https://stackoverflow.com/questions/12906502/is-it-possible-to-track-click-throughs-from-iphone-smart-banner/20422334woocommerce/woocommerce-admin#20422334)**. 2. A mobile app banner ad that **only displays on Android** and only displays at the `738px` breakpoint specified in the issue. To only display this banner ad on Android, we use basic checking of the user agent string. I weighed this up against other approaches and for this kind of niche use case a simple UA string check is (imho) still the best way to do this. 3. The banner ad makes use of user preferences to retain a per user setting that determines if that user has dismissed the Android banner. We don't/can't do anything like this for the iOS Smart App Banner (but in theory we shouldn't need to).
2020-08-27 01:46:53 +00:00
{ ! isModalDismissed && (
<MobileAppBanner
onDismiss={ dismissHandler }
onInstall={ dismissHandler }
/>
) }
<div className="woocommerce-layout__header-wrapper">
{ window.wcAdminFeatures.navigation && <Navigation /> }
{ renderTaskListBackButton() }
<Text
className={ `woocommerce-layout__header-heading ${ backButtonClass }` }
as="h1"
>
{ getPageTitle( decodeEntities( pageTitle ) ) }
</Text>
{ window.wcAdminFeatures[ 'activity-panels' ] && (
<ActivityPanel
isEmbedded={ isEmbedded }
query={ query }
userPreferencesData={ {
...userData,
updateUserPreferences,
} }
/>
) }
</div>
</div>
);
};