-
Notifications
You must be signed in to change notification settings - Fork 78
/
YouTubeThumbnail.ts
171 lines (145 loc) · 5.45 KB
/
YouTubeThumbnail.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
import { ModalBox as ModalBoxModule } from '../../ExternalModulesShim';
import { exportGlobally } from '../../GlobalExports';
import { IQueryResult } from '../../rest/QueryResult';
import { $$, Dom } from '../../utils/Dom';
import { DomUtils } from '../../utils/DomUtils';
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
) {
super(element, YouTubeThumbnail.ID, bindings);
this.options = ComponentOptions.initComponentOptions(element, YouTubeThumbnail, options);
this.resultLink = $$('a', {
className: Component.computeCssClassName(ResultLink)
});
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', element.ownerDocument.body as HTMLBodyElement, 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%'
});
const div = $$('div');
div.append(iframe.el);
this.modalbox.open(
DomUtils.getQuickviewHeader(this.result, { showDate: true, title: this.result.title }, this.bindings).el,
div.el,
() => true
);
$$($$(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);