coveo-search-ui
Version:
Coveo JavaScript Search Framework
179 lines (152 loc) • 5.72 kB
text/typescript
import { ModalBox as ModalBoxModule } from '../../ExternalModulesShim';
import { exportGlobally } from '../../GlobalExports';
import { IQueryResult } from '../../rest/QueryResult';
import { $$, Dom } from '../../utils/Dom';
import { SVGDom } from '../../utils/SVGDom';
import { SVGIcons } from '../../utils/SVGIcons';
import { Utils } from '../../utils/Utils';
import { Component } from '../Base/Component';
import { ComponentOptions } from '../Base/ComponentOptions';
import { Initialization } from '../Base/Initialization';
import { get } from '../Base/RegisteredNamedMethods';
import { IResultsComponentBindings } from '../Base/ResultsComponentBindings';
import { ResultLink } from '../ResultLink/ResultLink';
import { AccessibleModal } from '../../utils/AccessibleModal';
export interface IYouTubeThumbnailOptions {
width: string;
height: string;
embed: boolean;
}
/**
* The YouTubeThumbnail component automatically fetches the thumbnail of a YouTube video.
*
* This component differs from the standard {@link Thumbnail} component because the thumbnail it outputs is always
* clickable.
*
* Depending on the component configuration, clicking a YouTube thumbnail can either automatically open a modal box
* containing the `iframe` from YouTube, or open the target URL in the current window (see
* {@link YouTubeThumbnail.options.embed}).
*
* This component is a result template component (see [Result Templates](https://docs.coveo.com/en/413/)).
*/
export class YouTubeThumbnail extends Component {
static ID = 'YouTubeThumbnail';
static doExport = () => {
exportGlobally({
YouTubeThumbnail: YouTubeThumbnail
});
};
/**
* @componentOptions
*/
static options: IYouTubeThumbnailOptions = {
/**
* Specifies the width (in pixels) of the YouTube thumbnail.
*
* Default value is `200px`.
*/
width: ComponentOptions.buildStringOption({ defaultValue: '200px' }),
/**
* Specifies the height (in pixels) of the YouTube thumbnail.
*
* Default value is `112px`.
*/
height: ComponentOptions.buildStringOption({ defaultValue: '112px' }),
/**
* Specifies whether clicking on the YouTube thumbnail loads the video in a modal box.
*
* Setting this option to `false` causes the browser to change its current location to that of the target URL when
* the end user clicks the YouTube thumbnail.
*
* Default value is `true`.
*/
embed: ComponentOptions.buildBooleanOption({ defaultValue: true })
};
public resultLink: Dom;
private modalbox: AccessibleModal;
constructor(
public element: HTMLElement,
public options?: IYouTubeThumbnailOptions,
public bindings?: IResultsComponentBindings,
public result?: IQueryResult,
ModalBox = ModalBoxModule,
private origin?: HTMLElement
) {
super(element, YouTubeThumbnail.ID, bindings);
this.options = ComponentOptions.initComponentOptions(element, YouTubeThumbnail, options);
this.resultLink = $$('a', {
className: Component.computeCssClassName(ResultLink)
});
if (!origin) {
this.origin = this.resultLink.el;
}
const thumbnailDiv = $$('div', {
className: 'coveo-youtube-thumbnail-container'
});
this.resultLink.append(thumbnailDiv.el);
const img = $$('img', {
src: Utils.getFieldValue(this.result, 'ytthumbnailurl'),
className: 'coveo-youtube-thumbnail-img',
alt: this.result.title,
title: this.result.title
});
img.el.style.width = this.options.width;
img.el.style.height = this.options.height;
img.el.onerror = () => {
const svgVideo = $$('div', {}, SVGIcons.icons.video).el;
SVGDom.addStyleToSVGInContainer(svgVideo, {
width: this.options.width
});
$$(img).remove();
thumbnailDiv.append(svgVideo);
};
thumbnailDiv.append(img.el);
const span = $$('span', {
className: 'coveo-youtube-thumbnail-play-button'
});
thumbnailDiv.append(span.el);
$$(this.element).append(this.resultLink.el);
Initialization.automaticallyCreateComponentsInsideResult(element, result, {
ResultLink: this.options.embed ? { onClick: () => this.openYoutubeIframe() } : null
});
this.modalbox = new AccessibleModal('coveo-youtube-player', this.searchInterface.options.modalContainer, ModalBox, {
overlayClose: true
});
}
/**
* Open the result link embedded in this component.
*
* With a standard configuration of this component, this will open an iframe that automatically plays the video.
*/
public openResultLink() {
let resultLinkComponent = <ResultLink>get(this.resultLink.el);
resultLinkComponent.openLinkAsConfigured();
}
private openYoutubeIframe() {
// need to put iframe inside div : iframe with position absolute and left:0, right : 0 , bottom: 0 is not standard/supported
const iframe = $$('iframe', {
src: `https://www.youtube.com/embed/${this.extractVideoId()}?autoplay=1`,
allowfullscreen: 'allowfullscreen',
width: '100%',
height: '100%',
title: this.result.title
});
const div = $$('div');
div.append(iframe.el);
this.modalbox.openResult({
result: this.result,
options: { showDate: true, title: this.result.title },
bindings: this.bindings,
content: div.el,
validation: () => true,
origin: this.origin
});
$$($$(this.modalbox.wrapper).find('.coveo-quickview-close-button')).on('click', () => {
this.modalbox.close();
});
}
private extractVideoId() {
return this.result.clickUri.split('watch?v=')[1];
}
}
Initialization.registerAutoCreateComponent(YouTubeThumbnail);