diff --git a/cards/multilang-product-prominentvideo/component.js b/cards/multilang-product-prominentvideo/component.js index 779da89eb..631515086 100644 --- a/cards/multilang-product-prominentvideo/component.js +++ b/cards/multilang-product-prominentvideo/component.js @@ -57,6 +57,7 @@ class multilang_product_prominentvideoCardComponent extends BaseCard['multilang- } onMount() { + super.onMount(); const videoSelector = '.js-HitchhikerProductProminentVideo-video'; const videoEl = this._container.querySelector(videoSelector); if (!videoEl) { diff --git a/cards/product-prominentvideo/component.js b/cards/product-prominentvideo/component.js new file mode 100644 index 000000000..29015b903 --- /dev/null +++ b/cards/product-prominentvideo/component.js @@ -0,0 +1,103 @@ +{{> cards/card_component componentName='product-prominentvideo' }} + +class product_prominentvideoCardComponent extends BaseCard['product-prominentvideo'] { + constructor(config = {}, systemConfig = {}) { + super(config, systemConfig); + } + + /** + * This returns an object that will be called `card` + * in the template. Put all mapping logic here. + * + * @param profile profile of the entity in the card + */ + dataForRender(profile) { + this.youtubeUrl = Formatter.getYoutubeUrl(profile.videos || []); + this.vimeoUrl = profile.c_vimeo; + + const linkTarget = AnswersExperience.runtimeConfig.get('linkTarget') || '_top'; + + return { + title: profile.name, // The header text of the card + url: profile.landingPageUrl, // If the card title is a clickable link, set URL here + target: linkTarget, // If the title's URL should open in a new tab, etc. + titleEventOptions: this.addDefaultEventOptions(), + subtitle: profile.featuredMessage?.description, // The sub-header text of the card + videoUrl: this.youtubeUrl || this.vimeoUrl, + details: profile.richTextDescription ? ANSWERS.formatRichText(profile.richTextDescription, 'richTextDescription', linkTarget) : null, // The text in the body of the card + // If the card's details are longer than a certain character count, you can truncate the + // text. A toggle will be supplied that can show or hide the truncated text. + // Note: If you are using rich text for the details, you should not enable this feature. + // showMoreDetails: { + // showMoreLimit: 24, // Character count limit + // showMoreText: 'Show more', // Label when toggle will show truncated text + // showLessText: 'Show less' // Label when toggle will hide truncated text + // }, + // The primary CTA of the card + CTA1: { + label: profile.c_primaryCTA ? profile.c_primaryCTA.label : null, // The CTA's label + iconName: 'chevron', // The icon to use for the CTA + url: Formatter.generateCTAFieldTypeLink(profile.c_primaryCTA), // The URL a user will be directed to when clicking + target: linkTarget, // Where the new URL will be opened + eventType: 'CTA_CLICK', // Type of Analytics event fired when clicking the CTA + eventOptions: this.addDefaultEventOptions(), + // ariaLabel: '', // Accessible text providing a descriptive label for the CTA + }, + // The secondary CTA of the card + CTA2: { + label: profile.c_secondaryCTA ? profile.c_secondaryCTA.label : null, + iconName: 'chevron', + url: Formatter.generateCTAFieldTypeLink(profile.c_secondaryCTA), + target: linkTarget, + eventType: 'CTA_CLICK', + eventOptions: this.addDefaultEventOptions(), + // ariaLabel: '', + } + }; + } + + onMount() { + super.onMount(); + const videoSelector = '.js-HitchhikerProductProminentVideo-video'; + const videoEl = this._container.querySelector(videoSelector); + if (!videoEl) { + return; + } + const addPlayer = videoApi => { + videoApi.addPlayer(videoEl, { + onPlay: () => this.onPlay() + }); + }; + if (this.youtubeUrl) { + HitchhikerJS.requireYoutubeAPI().then(addPlayer); + } else if (this.vimeoUrl) { + HitchhikerJS.requireVimeoAPI().then(addPlayer); + } + } + + onPlay() { + const event = new ANSWERS.AnalyticsEvent('CTA_CLICK') + .addOptions({ + verticalKey: this.verticalKey, + entityId: this.result?._raw?.id, + searcher: this._config.isUniversal ? 'UNIVERSAL' : 'VERTICAL', + ctaLabel: 'video_played' + }); + this.analyticsReporter.report(event); + } + + /** + * The template to render + * @returns {string} + * @override + */ + static defaultTemplateName (config) { + return 'cards/product-prominentvideo'; + } +} + +ANSWERS.registerTemplate( + 'cards/product-prominentvideo', + {{{stringifyPartial (read 'cards/product-prominentvideo/template') }}} +); +ANSWERS.registerComponentType(product_prominentvideoCardComponent); diff --git a/cards/product-prominentvideo/template.hbs b/cards/product-prominentvideo/template.hbs new file mode 100644 index 000000000..a25c5f932 --- /dev/null +++ b/cards/product-prominentvideo/template.hbs @@ -0,0 +1,124 @@ +