Skip to content

Commit

Permalink
Add the product-prominentvideo card to the Theme. (#847)
Browse files Browse the repository at this point in the history
This PR adds the English-only variant of the `multilang-product-prominentvideo` card to the Theme. All calls to `translateJS` were replaced with static text. This PR also fixes the toggling of `Show More`/`Show Less` in both cards by adding `super.onMount` to the cards' custom `onMount`. 

TEST=manual

Verified I could use this card on a test vertical.
  • Loading branch information
tmeyer2115 committed Jun 23, 2021
1 parent 2be0f05 commit c5b39f5
Show file tree
Hide file tree
Showing 3 changed files with 228 additions and 0 deletions.
1 change: 1 addition & 0 deletions cards/multilang-product-prominentvideo/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
103 changes: 103 additions & 0 deletions cards/product-prominentvideo/component.js
Original file line number Diff line number Diff line change
@@ -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);
124 changes: 124 additions & 0 deletions cards/product-prominentvideo/template.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
<div class="HitchhikerProductProminentVideo {{cardName}}">
<div class="HitchhikerProductProminentVideo-header">
{{> title }}
{{> subtitle }}
</div>
{{> video }}
{{> content }}
</div>

{{#*inline 'title'}}
{{#if card.title}}
<div class="HitchhikerProductProminentVideo-title">
{{#if card.url}}
<a class="HitchhikerProductProminentVideo-titleLink"
href="{{#unless (isNonRelativeUrl card.url)}}{{@root.relativePath}}/{{/unless}}{{card.url}}"
target={{#if card.target}}"{{card.target}}"{{else}}"_top"{{/if}}
data-eventtype="TITLE_CLICK"
data-eventoptions='{{json card.titleEventOptions}}'>
{{card.title}}
</a>
{{else}}
{{card.title}}
{{/if}}
</div>
{{/if}}
{{/inline}}

{{#*inline 'subtitle'}}
{{#if card.subtitle}}
<div class="HitchhikerProductProminentVideo-subtitle">
{{card.subtitle}}
</div>
{{/if}}
{{/inline}}

{{#*inline 'video'}}
{{#if card.videoUrl}}
<div class="HitchhikerProductProminentVideo-videoWrapper">
<iframe
class="HitchhikerProductProminentVideo-video js-HitchhikerProductProminentVideo-video"
src="{{card.videoUrl}}"
allowfullscreen
frameBorder='0'
webkitAllowFullScreen
mozallowfullscreen>
</iframe>
</div>
{{/if}}
{{/inline}}

{{#*inline 'content'}}
{{#if (any card.details (all card.CTA1 card.CTA1.url card.CTA1.label) (all card.CTA2 card.CTA2.url card.CTA2.label))}}
<div class="HitchhikerProductProminentVideo-contentWrapper">
{{> details }}
{{> ctas }}
</div>
{{/if}}
{{/inline}}

{{! Displays the details for the card. If showMoreDetails has been configured,
this partial handles the show more toggle, show less toggle, truncated details,
and full details. If showMoreDetails has not been configured, it will display the
the regular card details.
}}
{{#*inline 'details'}}
{{#if card.details}}
<div class="HitchhikerProductProminentVideo-cardDetails">
{{#if showExcessDetailsToggle}}
<div class="HitchhikerProductProminentVideo-detailsText js-HitchhikerCard-detailsText">
{{{truncatedDetails}}}
</div>
{{/if}}
<div class="HitchhikerProductProminentVideo-detailsText js-HitchhikerCard-detailsText{{#if showExcessDetailsToggle}} js-hidden{{/if}}">
{{{card.details}}}
</div>
{{#if showExcessDetailsToggle}}
<button class="HitchhikerCard-detailsToggle js-HitchhikerCard-detailsToggle">
{{card.showMoreDetails.showMoreText}}
<span data-component="IconComponent"
data-opts='{ "iconName": "chevron", "classNames": "Icon--sm Icon-collapseDown" }'></span>
</button>
<button class="HitchhikerCard-detailsToggle js-HitchhikerCard-detailsToggle js-hidden">
{{card.showMoreDetails.showLessText}}
<span data-component="IconComponent"
data-opts='{ "iconName": "chevron", "classNames": "Icon--sm Icon-collapseUp" }'></span>
</button>
{{/if}}
</div>
{{/if}}
{{/inline}}

{{#*inline 'ctas'}}
{{#if (any (all card.CTA1 card.CTA1.url card.CTA1.label) (all card.CTA2 card.CTA2.url card.CTA2.label))}}
<div class="HitchhikerProductProminentVideo-ctasWrapper">
{{> CTA card.CTA1 ctaName="primaryCTA" }}
{{> CTA card.CTA2 ctaName="secondaryCTA" }}
</div>
{{/if}}
{{/inline}}

{{#*inline 'CTA'}}
{{#if (all url label)}}
<div class="HitchhikerProductProminentVideo-{{ctaName}}">
<a class="HitchhikerCTA js-HitchhikerCTA{{#if modifiers}} {{modifiers}}{{/if}}"
href="{{#unless (isNonRelativeUrl url)}}{{@root.relativePath}}/{{/unless}}{{url}}"
data-eventtype="{{eventType}}"
data-eventoptions='{{json eventOptions}}'
target="{{#if target}}{{target}}{{else}}_top{{/if}}"
{{#if ariaLabel}}aria-label="{{ariaLabel}}"{{/if}}>
{{#if (any iconName iconUrl)}}
<div class="HitchhikerCTA-iconWrapper">
<div class="HitchhikerCTA-icon"
data-component="IconComponent"
data-opts='{"iconName": "{{iconName}}","iconUrl": "{{#if iconUrl}}{{#unless (isNonRelativeUrl iconUrl)}}{{@root.relativePath}}/{{/unless}}{{iconUrl}}{{/if}}"}'>
</div>
</div>
{{/if}}
<div class='HitchhikerCTA-iconLabel'>
{{label}}
</div>
</a>
</div>
{{/if}}
{{/inline}}

0 comments on commit c5b39f5

Please sign in to comment.