diff --git a/components/x-gift-article/__tests__/x-gift-article.test.jsx b/components/x-gift-article/__tests__/x-gift-article.test.jsx index d917b1117..dcdbeb28c 100644 --- a/components/x-gift-article/__tests__/x-gift-article.test.jsx +++ b/components/x-gift-article/__tests__/x-gift-article.test.jsx @@ -20,7 +20,8 @@ const baseArgs = { }, id: 'base-gift-article-static-id', enterpriseApiBaseUrl: `https://enterprise-sharing-api.ft.com`, - hasHighlights: true + highlight: + 'Lorem ipsum dolor sit amet consectetur, adipisicing elit. Dolorum quos, quis quas ad, minima fuga at nemo deleniti hic repellendus totam. Impedit mollitia quam repellat harum. Nostrum sapiente minima soluta , Lorem ipsum dolor sit amet consectetur, adipisicing elit. Dolorum quos, quis quas ad, minima fuga at nemo deleniti hic repellendus totam. Impedit mollitia quam repellat harum. Nostrum sapiente minima soluta.' } describe('x-gift-article', () => { @@ -128,7 +129,8 @@ describe('x-gift-article', () => { showAdvancedSharingOptions: true, giftCredits: 10, monthlyAllowance: 100, - hasHighlights: true + highlight: + 'Lorem ipsum dolor sit amet consectetur, adipisicing elit. Dolorum quos, quis quas ad, minima fuga at nemo deleniti hic repellendus totam. Impedit mollitia quam repellat harum. Nostrum sapiente minima soluta , Lorem ipsum dolor sit amet consectetur, adipisicing elit. Dolorum quos, quis quas ad, minima fuga at nemo deleniti hic repellendus totam. Impedit mollitia quam repellat harum. Nostrum sapiente minima soluta.' } // Add a message to the document body to simulate the banner that is shown when the article content has changed. @@ -155,7 +157,8 @@ describe('x-gift-article', () => { showAdvancedSharingOptions: true, giftCredits: 10, monthlyAllowance: 100, - hasHighlights: true + highlight: + 'Lorem ipsum dolor sit amet consectetur, adipisicing elit. Dolorum quos, quis quas ad, minima fuga at nemo deleniti hic repellendus totam. Impedit mollitia quam repellat harum. Nostrum sapiente minima soluta , Lorem ipsum dolor sit amet consectetur, adipisicing elit. Dolorum quos, quis quas ad, minima fuga at nemo deleniti hic repellendus totam. Impedit mollitia quam repellat harum. Nostrum sapiente minima soluta.' } delete window.location @@ -178,7 +181,8 @@ describe('x-gift-article', () => { showAdvancedSharingOptions: true, giftCredits: 10, monthlyAllowance: 100, - hasHighlights: true + highlight: + 'Lorem ipsum dolor sit amet consectetur, adipisicing elit. Dolorum quos, quis quas ad, minima fuga at nemo deleniti hic repellendus totam. Impedit mollitia quam repellat harum. Nostrum sapiente minima soluta , Lorem ipsum dolor sit amet consectetur, adipisicing elit. Dolorum quos, quis quas ad, minima fuga at nemo deleniti hic repellendus totam. Impedit mollitia quam repellat harum. Nostrum sapiente minima soluta.' } delete window.location diff --git a/components/x-gift-article/src/GiftArticle.jsx b/components/x-gift-article/src/GiftArticle.jsx index 2c662abfc..d4925b715 100644 --- a/components/x-gift-article/src/GiftArticle.jsx +++ b/components/x-gift-article/src/GiftArticle.jsx @@ -27,27 +27,21 @@ const withGiftFormActions = withActions( showGiftUrlSection() { return updaters.showGiftUrlSection }, - showEnterpriseUrlSection() { return updaters.showGiftEnterpriseSection }, - showNonSubscriberSharingOptions() { return updaters.showNonSubscriberSharingOptions }, - showNonGiftUrlSection() { return updaters.showNonGiftUrlSection }, - showAdvancedSharingOptions() { return updaters.showAdvancedSharingOptions }, - hideNonSubscriberSharingOptions() { return updaters.hideNonSubscriberSharingOptions }, - async createGiftUrl() { return async (state) => { let response @@ -67,7 +61,6 @@ const withGiftFormActions = withActions( } } }, - async shortenNonGiftUrl() { return async (state) => { if (state.isNonGiftUrlShortened) { @@ -94,7 +87,6 @@ const withGiftFormActions = withActions( } } }, - async createEnterpriseUrl() { return async (state) => { const { redemptionUrl, redemptionLimit } = await enterpriseApi.getESUrl( @@ -117,7 +109,6 @@ const withGiftFormActions = withActions( } } }, - copyGiftUrl(event) { copyToClipboard(event) @@ -128,7 +119,6 @@ const withGiftFormActions = withActions( return { showCopyConfirmation: true } } }, - copyEnterpriseUrl(event) { copyToClipboard(event) @@ -139,7 +129,6 @@ const withGiftFormActions = withActions( return { showCopyConfirmation: true } } }, - copyNonGiftUrl(event) { copyToClipboard(event) @@ -150,33 +139,27 @@ const withGiftFormActions = withActions( return { showCopyConfirmation: true } } }, - emailGiftUrl() { return (state) => { tracking.emailLink('giftLink', state.urls.gift) } }, - emailEnterpriseUrl() { return (state) => { tracking.emailLink('enterpriseLink', state.urls.enterprise) } }, - emailNonGiftUrl() { return (state) => { tracking.emailLink('nonGiftLink', state.urls.nonGift) } }, - hideCopyConfirmation() { return { showCopyConfirmation: false } }, - shareByNativeShare() { throw new Error(`shareByNativeShare should be implemented by x-gift-article's consumers`) }, - activate() { return async (state) => { const { enabled, limit, hasCredits, requestAccess, budget, isRegisteredUser } = @@ -253,12 +236,6 @@ const withGiftFormActions = withActions( return { includeHighlights } } }, - checkIfHasHighlights() { - return (state) => { - state.hasHighlights = !!document.getElementsByClassName(state.highlightClassName).length - return { hasHighlights: state.hasHighlights } - } - }, saveHighlightsHandler() { return () => { return { @@ -281,6 +258,13 @@ const withGiftFormActions = withActions( showHighlightsSuccessMessage: false } } + }, + getHighlightPreview() { + return (state) => { + state.highlight = document.querySelector(`.${state.highlightClassName}`)?.textContent + state.highlightClassName = document.querySelector(`.${state.highlightClassName}`)?.classList.value + return { highlight: state.highlight, highlightClassName: state.highlightClassName } + } } } }, @@ -312,10 +296,10 @@ const withGiftFormActions = withActions( isGiftUrlCreated: false, isGiftUrlShortened: false, isNonGiftUrlShortened: false, - includeHighlights: false, + includeHighlights: true, showAdvancedSharingOptions: false, showNonSubscriberOptions: false, - hasHighlights: false, + highlight: undefined, showHighlightsRecipientMessage, showHighlightsSuccessMessage: false, showHighlightsCheckbox: !new URL(location.href).searchParams.has('highlights'), @@ -330,7 +314,7 @@ const withGiftFormActions = withActions( mailtoUrls: { gift: undefined, enterprise: undefined, - nonGift: createMailtoUrl(props.article.title, `${props.article.url}?shareType=nongift`) + nonGift: createMailtoUrl(props, `${props.article.url}?shareType=nongift`) }, showFreeArticleAlert: false } diff --git a/components/x-gift-article/src/IncludeHighlights.jsx b/components/x-gift-article/src/IncludeHighlights.jsx index 66224f1dd..ab7f0171d 100644 --- a/components/x-gift-article/src/IncludeHighlights.jsx +++ b/components/x-gift-article/src/IncludeHighlights.jsx @@ -1,32 +1,47 @@ import { h } from '@financial-times/x-engine' -import { canShareWithNonSubscribers, isNonSubscriberOption } from './lib/highlightsHelpers' +import { canShareWithNonSubscribers, isNonSubscriberOption, trimHighlights } from './lib/highlightsHelpers' export const IncludeHighlights = (props) => { - const { actions, hasHighlights, enterpriseEnabled, includeHighlights } = props + const { actions, highlight, enterpriseEnabled, includeHighlights, highlightClassName } = props const _canShareWithNonSubscribers = canShareWithNonSubscribers(props) const _isNonSubscriberOption = isNonSubscriberOption(props) const includeHighlightsHandler = (event) => { - actions.setIncludeHighlights(event.target.checked) + actions.setIncludeHighlights(!event.target.checked) } - return hasHighlights && enterpriseEnabled && (_canShareWithNonSubscribers || !_isNonSubscriberOption) ? ( + return highlight !== undefined && + enterpriseEnabled && + (_canShareWithNonSubscribers || !_isNonSubscriberOption) ? (
+ {includeHighlights && ( +
+

+ + Highlighted text when shared: + +

+ + + {trimHighlights(highlight)} + +
+ )}
-
diff --git a/components/x-gift-article/src/ShareArticleDialog.scss b/components/x-gift-article/src/ShareArticleDialog.scss index 31038308c..83ac29569 100644 --- a/components/x-gift-article/src/ShareArticleDialog.scss +++ b/components/x-gift-article/src/ShareArticleDialog.scss @@ -199,6 +199,17 @@ margin-top: oSpacingByName('s6'); } + .shared-article-dialog__include-highlights-quote-wrapper { + margin-bottom: oSpacingByName('s6'); + } + + .shared-article-dialog__include-highlights-quote { + @include oTypographySans($scale: 0, $include-font-family: 0); + font-family: Georgia, serif; + padding: oSpacingByName('s1') oSpacingByName('s3'); + display: block; + } + .share-article-dialog__create-link-button { width: 100%; margin-top: oSpacingByName('s6'); diff --git a/components/x-gift-article/src/SocialShareButtons.jsx b/components/x-gift-article/src/SocialShareButtons.jsx index fad1d9325..0852c706e 100644 --- a/components/x-gift-article/src/SocialShareButtons.jsx +++ b/components/x-gift-article/src/SocialShareButtons.jsx @@ -1,7 +1,17 @@ import { h } from '@financial-times/x-engine' import { ShareType } from './lib/constants' +import { trimHighlights } from './lib/highlightsHelpers' -export const SocialShareButtons = ({ actions, mailtoUrl, shareType, enterpriseEnabled, url, article }) => { +export const SocialShareButtons = ({ + actions, + mailtoUrl, + shareType, + enterpriseEnabled, + url, + article, + highlight, + includeHighlights +}) => { const onClickHandler = (event) => { switch (shareType) { case ShareType.gift: @@ -17,17 +27,19 @@ export const SocialShareButtons = ({ actions, mailtoUrl, shareType, enterpriseEn } } + const sharedText = includeHighlights ? `${article.title} - "${trimHighlights(highlight)}"` : article.title + const mobileShareLinks = { facebook: `http://www.facebook.com/sharer.php?u=${encodeURIComponent(url)}&t=${encodeURIComponent( - article.title + sharedText )}`, twitter: `https://twitter.com/intent/tweet?url=${encodeURIComponent(url)}&text=${encodeURIComponent( - article.title + sharedText )}&via=financialtimes`, - linkedin: `http://www.linkedin.com/shareArticle?mini=true&url=${encodeURIComponent( + linkedin: `https://linkedin.com/sharing/share-offsite/?url=${encodeURIComponent( url - )}&title=${encodeURIComponent(article.title)}&source=Financial+Times`, - whatsapp: `https://wa.me?text=${encodeURIComponent(article.title)}%20-%20${encodeURIComponent(url)}` + )}&text='${sharedText}'`, + whatsapp: `https://wa.me?text=${encodeURIComponent(sharedText)}%20-%20${encodeURIComponent(url)}` } return ( diff --git a/components/x-gift-article/src/lib/highlightsHelpers.js b/components/x-gift-article/src/lib/highlightsHelpers.js index 31ce77dbb..cc32ea91e 100644 --- a/components/x-gift-article/src/lib/highlightsHelpers.js +++ b/components/x-gift-article/src/lib/highlightsHelpers.js @@ -39,3 +39,6 @@ export const canShareWithNonSubscribers = ({ giftCredits, enterpriseHasCredits } export const isNonSubscriberOption = ({ showNonSubscriberOptions, showAdvancedSharingOptions }) => showNonSubscriberOptions || showAdvancedSharingOptions + +export const trimHighlights = (text, maxWordsCount = 30) => + text.split(' ').length > maxWordsCount ? `${text.split(' ').slice(0, maxWordsCount).join(' ')} ...` : text diff --git a/components/x-gift-article/src/lib/share-link-actions.js b/components/x-gift-article/src/lib/share-link-actions.js index 975bb8f13..4006519bb 100644 --- a/components/x-gift-article/src/lib/share-link-actions.js +++ b/components/x-gift-article/src/lib/share-link-actions.js @@ -1,3 +1,4 @@ +const { trimHighlights } = require('./highlightsHelpers') function getGreeting() { const hours = new Date().getHours() // Determine the appropriate greeting based on the current hour @@ -12,11 +13,12 @@ function getGreeting() { return 'Good evening' } -function createMailtoUrl(articleTitle, shareUrl) { +function createMailtoUrl({ article, includeHighlights, highlight }, shareUrl) { const subject = 'Read this article from the Financial Times' const greeting = getGreeting() + const sharedText = includeHighlights ? `${article.title} - "${trimHighlights(highlight)}"` : article.title const body = encodeURIComponent( - `${greeting},\n\nI read this article from the Financial Times and thought it would interest you.\n\n${articleTitle}\n${shareUrl}\n\nBest wishes,` + `${greeting},\n\nI read this article from the Financial Times and thought it would interest you.\n\n${sharedText}\n${shareUrl}\n\nBest wishes,` ) return `mailto:?subject=${subject}&body=${body}` diff --git a/components/x-gift-article/src/lib/updaters.js b/components/x-gift-article/src/lib/updaters.js index 4bd475989..2bb6d256b 100644 --- a/components/x-gift-article/src/lib/updaters.js +++ b/components/x-gift-article/src/lib/updaters.js @@ -66,7 +66,7 @@ export const hideNonSubscriberSharingOptions = (props) => ({ export const setGiftUrl = (url, redemptionLimit, isShortened, isEnterprise = false) => (props) => { - const mailtoUrl = createMailtoUrl(props.article.title, url) + const mailtoUrl = createMailtoUrl(props, url) return { url, @@ -100,7 +100,7 @@ export const setAllowance = (giftCredits, monthlyAllowance, nextRenewalDate) => } export const setShortenedNonGiftUrl = (shortenedUrl) => (props) => { - const mailtoUrl = createMailtoUrl(props.article.title, shortenedUrl) + const mailtoUrl = createMailtoUrl(props, shortenedUrl) return { url: shortenedUrl, diff --git a/components/x-gift-article/storybook/share-article-modal-b2b-highlights.jsx b/components/x-gift-article/storybook/share-article-modal-b2b-highlights.jsx index 87fccaa64..2e37846e3 100644 --- a/components/x-gift-article/storybook/share-article-modal-b2b-highlights.jsx +++ b/components/x-gift-article/storybook/share-article-modal-b2b-highlights.jsx @@ -13,7 +13,8 @@ exports.args = { }, id: 'base-gift-article-static-id', enterpriseApiBaseUrl: `https://enterprise-sharing-api.ft.com`, - hasHighlights: true + highlight: + 'Lorem ipsum dolor sit amet consectetur, adipisicing elit. Dolorum quos, quis quas ad, minima fuga at nemo deleniti hic repellendus totam. Impedit mollitia quam repellat harum. Nostrum sapiente minima soluta , Lorem ipsum dolor sit amet consectetur, adipisicing elit. Dolorum quos, quis quas ad, minima fuga at nemo deleniti hic repellendus totam. Impedit mollitia quam repellat harum. Nostrum sapiente minima soluta.' } exports.fetchMock = (fetchMock) => { diff --git a/components/x-gift-article/storybook/share-article-modal-b2b-save-highlights-message.jsx b/components/x-gift-article/storybook/share-article-modal-b2b-save-highlights-message.jsx index 4d7c9cb46..16850ceed 100644 --- a/components/x-gift-article/storybook/share-article-modal-b2b-save-highlights-message.jsx +++ b/components/x-gift-article/storybook/share-article-modal-b2b-save-highlights-message.jsx @@ -13,7 +13,6 @@ exports.args = { }, id: 'base-gift-article-static-id', enterpriseApiBaseUrl: `https://enterprise-sharing-api.ft.com`, - hasHighlights: false, showHighlightsCheckbox: false, showHighlightsRecipientMessage: true } diff --git a/components/x-gift-article/storybook/share-article-modal-with-advanced-sharing-free-article.jsx b/components/x-gift-article/storybook/share-article-modal-with-advanced-sharing-free-article.jsx index cde70540a..3cf9d3ba2 100644 --- a/components/x-gift-article/storybook/share-article-modal-with-advanced-sharing-free-article.jsx +++ b/components/x-gift-article/storybook/share-article-modal-with-advanced-sharing-free-article.jsx @@ -13,7 +13,8 @@ exports.args = { }, id: 'base-gift-article-static-id', enterpriseApiBaseUrl: `https://enterprise-sharing-api.ft.com`, - hasHighlights: true + highlight: + 'Lorem ipsum dolor sit amet consectetur, adipisicing elit. Dolorum quos, quis quas ad, minima fuga at nemo deleniti hic repellendus totam. Impedit mollitia quam repellat harum. Nostrum sapiente minima soluta , Lorem ipsum dolor sit amet consectetur, adipisicing elit. Dolorum quos, quis quas ad, minima fuga at nemo deleniti hic repellendus totam. Impedit mollitia quam repellat harum. Nostrum sapiente minima soluta.' } exports.fetchMock = (fetchMock) => { diff --git a/components/x-gift-article/storybook/share-article-modal-with-advanced-sharing-no-both-credits.jsx b/components/x-gift-article/storybook/share-article-modal-with-advanced-sharing-no-both-credits.jsx index 9b06fbe89..5691ce96e 100644 --- a/components/x-gift-article/storybook/share-article-modal-with-advanced-sharing-no-both-credits.jsx +++ b/components/x-gift-article/storybook/share-article-modal-with-advanced-sharing-no-both-credits.jsx @@ -13,7 +13,8 @@ exports.args = { }, id: 'base-gift-article-static-id', enterpriseApiBaseUrl: `https://enterprise-sharing-api.ft.com`, - hasHighlights: true + highlight: + 'Lorem ipsum dolor sit amet consectetur, adipisicing elit. Dolorum quos, quis quas ad, minima fuga at nemo deleniti hic repellendus totam. Impedit mollitia quam repellat harum. Nostrum sapiente minima soluta , Lorem ipsum dolor sit amet consectetur, adipisicing elit. Dolorum quos, quis quas ad, minima fuga at nemo deleniti hic repellendus totam. Impedit mollitia quam repellat harum. Nostrum sapiente minima soluta.' } exports.fetchMock = (fetchMock) => { diff --git a/components/x-gift-article/storybook/share-article-modal-with-advanced-sharing-no-enterprise-credits.jsx b/components/x-gift-article/storybook/share-article-modal-with-advanced-sharing-no-enterprise-credits.jsx index a13ff6ec7..9fd7bb384 100644 --- a/components/x-gift-article/storybook/share-article-modal-with-advanced-sharing-no-enterprise-credits.jsx +++ b/components/x-gift-article/storybook/share-article-modal-with-advanced-sharing-no-enterprise-credits.jsx @@ -13,7 +13,8 @@ exports.args = { }, id: 'base-gift-article-static-id', enterpriseApiBaseUrl: `https://enterprise-sharing-api.ft.com`, - hasHighlights: true + highlight: + 'Lorem ipsum dolor sit amet consectetur, adipisicing elit. Dolorum quos, quis quas ad, minima fuga at nemo deleniti hic repellendus totam. Impedit mollitia quam repellat harum. Nostrum sapiente minima soluta , Lorem ipsum dolor sit amet consectetur, adipisicing elit. Dolorum quos, quis quas ad, minima fuga at nemo deleniti hic repellendus totam. Impedit mollitia quam repellat harum. Nostrum sapiente minima soluta.' } exports.fetchMock = (fetchMock) => { diff --git a/components/x-gift-article/storybook/share-article-modal-with-advanced-sharing-no-gift-credits.jsx b/components/x-gift-article/storybook/share-article-modal-with-advanced-sharing-no-gift-credits.jsx index 05baae6c4..5b880dfb4 100644 --- a/components/x-gift-article/storybook/share-article-modal-with-advanced-sharing-no-gift-credits.jsx +++ b/components/x-gift-article/storybook/share-article-modal-with-advanced-sharing-no-gift-credits.jsx @@ -13,7 +13,8 @@ exports.args = { }, id: 'base-gift-article-static-id', enterpriseApiBaseUrl: `https://enterprise-sharing-api.ft.com`, - hasHighlights: true + highlight: + 'Lorem ipsum dolor sit amet consectetur, adipisicing elit. Dolorum quos, quis quas ad, minima fuga at nemo deleniti hic repellendus totam. Impedit mollitia quam repellat harum. Nostrum sapiente minima soluta , Lorem ipsum dolor sit amet consectetur, adipisicing elit. Dolorum quos, quis quas ad, minima fuga at nemo deleniti hic repellendus totam. Impedit mollitia quam repellat harum. Nostrum sapiente minima soluta.' } exports.fetchMock = (fetchMock) => { diff --git a/components/x-gift-article/storybook/share-article-modal-with-advanced-sharing-save-highlights-message.jsx b/components/x-gift-article/storybook/share-article-modal-with-advanced-sharing-save-highlights-message.jsx index e8c8d8832..eb52e51c1 100644 --- a/components/x-gift-article/storybook/share-article-modal-with-advanced-sharing-save-highlights-message.jsx +++ b/components/x-gift-article/storybook/share-article-modal-with-advanced-sharing-save-highlights-message.jsx @@ -13,7 +13,6 @@ exports.args = { }, id: 'base-gift-article-static-id', enterpriseApiBaseUrl: `https://enterprise-sharing-api.ft.com`, - hasHighlights: false, showHighlightsCheckbox: false, showHighlightsRecipientMessage: true } diff --git a/components/x-gift-article/storybook/share-article-modal-with-advanced-sharing.jsx b/components/x-gift-article/storybook/share-article-modal-with-advanced-sharing.jsx index 266a38d7a..3f2bbda93 100644 --- a/components/x-gift-article/storybook/share-article-modal-with-advanced-sharing.jsx +++ b/components/x-gift-article/storybook/share-article-modal-with-advanced-sharing.jsx @@ -13,7 +13,8 @@ exports.args = { }, id: 'base-gift-article-static-id', enterpriseApiBaseUrl: `https://enterprise-sharing-api.ft.com`, - hasHighlights: true + highlight: + 'Lorem ipsum dolor sit amet consectetur, adipisicing elit. Dolorum quos, quis quas ad, minima fuga at nemo deleniti hic repellendus totam. Impedit mollitia quam repellat harum. Nostrum sapiente minima soluta , Lorem ipsum dolor sit amet consectetur, adipisicing elit. Dolorum quos, quis quas ad, minima fuga at nemo deleniti hic repellendus totam. Impedit mollitia quam repellat harum. Nostrum sapiente minima soluta.' } exports.fetchMock = (fetchMock) => {