-
Notifications
You must be signed in to change notification settings - Fork 0
/
AdDisplay.ts
93 lines (81 loc) · 3.27 KB
/
AdDisplay.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
import * as shadyCss from '@webcomponents/shadycss';
import textDisplayCss from '../TextDisplay.css';
import adDisplayCss from './AdDisplay.css';
import { StateReceiverMixin } from '../StateReceiverMixin';
import type { Ads, ChromelessPlayer } from 'theoplayer/chromeless';
import { arrayFind, setTextContent } from '../../util/CommonUtils';
import { isLinearAd } from '../../util/AdUtils';
import { createTemplate } from '../../util/TemplateUtils';
const template = createTemplate('theoplayer-ad-display', `<style>${textDisplayCss}\n${adDisplayCss}</style><span></span>`);
const AD_EVENTS = ['adbreakbegin', 'adbreakend', 'adbreakchange', 'updateadbreak', 'adbegin', 'adend', 'adskip', 'addad', 'updatead'] as const;
/**
* `<theoplayer-ad-countdown>` - A control that shows when an advertisement is playing,
* and the number of the current ad in the ad break (if the break has multiple ads).
*
* @group Components
*/
export class AdDisplay extends StateReceiverMixin(HTMLElement, ['player']) {
private readonly _spanEl: HTMLElement;
private _player: ChromelessPlayer | undefined;
private _ads: Ads | undefined;
constructor() {
super();
const shadowRoot = this.attachShadow({ mode: 'open' });
shadowRoot.appendChild(template().content.cloneNode(true));
this._spanEl = shadowRoot.querySelector('span')!;
this._upgradeProperty('player');
}
protected _upgradeProperty(prop: keyof this) {
if (this.hasOwnProperty(prop)) {
let value = this[prop];
delete this[prop];
this[prop] = value;
}
}
connectedCallback(): void {
shadyCss.styleElement(this);
this._updateFromPlayer();
}
get player(): ChromelessPlayer | undefined {
return this._player;
}
set player(player: ChromelessPlayer | undefined) {
if (this._player === player) {
return;
}
this._ads?.removeEventListener(AD_EVENTS, this._updateFromPlayer);
this._player = player;
this._ads = player?.ads;
this._updateFromPlayer();
this._ads?.addEventListener(AD_EVENTS, this._updateFromPlayer);
}
private readonly _updateFromPlayer = () => {
const ads = this._player?.ads;
const linearAds = (ads?.currentAdBreak?.ads ?? []).filter(isLinearAd);
if (ads === undefined || !ads.playing || linearAds.length === 0) {
setTextContent(this._spanEl, '');
this.style.display = 'none';
return;
}
if (linearAds.length > 1) {
const currentAds = this._player!.ads!.currentAds || [];
const currentLinearAd = arrayFind(currentAds, isLinearAd);
if (currentLinearAd) {
const currentAdIndex = linearAds.indexOf(currentLinearAd);
if (currentAdIndex >= 0) {
setTextContent(this._spanEl, `Ad ${currentAdIndex + 1} of ${linearAds.length}`);
this.style.display = '';
return;
}
}
}
setTextContent(this._spanEl, 'Ad');
this.style.display = '';
};
}
customElements.define('theoplayer-ad-display', AdDisplay);
declare global {
interface HTMLElementTagNameMap {
'theoplayer-ad-display': AdDisplay;
}
}