UNPKG

bitmovin-player-ui

Version:
130 lines (110 loc) 3.74 kB
import { Component, ComponentConfig } from './Component'; import { ExternalRecommendationLink, RecommendationConfig } from '../UIConfig'; import { EventDispatcher, NoArgs, Event } from '../EventDispatcher'; import { PlayerAPI, SourceConfig } from 'bitmovin-player'; import { UIInstanceManager } from '../UIManager'; import { DOM } from '../DOM'; import { Label } from './labels/Label'; import { StringUtils } from '../utils/StringUtils'; /** * Configuration interface for the {@link RecommendationItem} */ export interface RecommendationItemConfig extends ComponentConfig { /** * The recommendation configuration for this item. */ recommendationConfig: RecommendationConfig; } /** * An item of the {@link RecommendationOverlay}. */ export class RecommendationItem extends Component<RecommendationItemConfig> { private events = { onClick: new EventDispatcher<RecommendationItem, NoArgs>(), }; constructor(config: RecommendationItemConfig) { super(config); this.config = this.mergeConfig( config, { cssClass: 'ui-recommendation-item', recommendationConfig: null, // this must be passed in from outside tabIndex: 0, }, this.config, ); } configure(player: PlayerAPI, uimanager: UIInstanceManager) { super.configure(player, uimanager); if (isExternalRecommendationLink(this.config.recommendationConfig.resource)) { return; } this.onClick.subscribe(() => { player.load(this.config.recommendationConfig.resource as SourceConfig); player.play(); }); } protected toDomElement(): DOM { const recommendationConfig = this.config.recommendationConfig; const recommendationResource = recommendationConfig.resource; let tagName: string; let additionalAttributes: { [name: string]: string } = {}; let posterUrl: string | null; if (isExternalRecommendationLink(recommendationResource)) { tagName = 'a'; additionalAttributes = { href: recommendationResource.url }; posterUrl = recommendationResource.thumbnail; } else { tagName = 'button'; posterUrl = recommendationResource.poster; } const itemElement = new DOM( tagName, { id: this.config.id, class: this.getCssClasses(), ...additionalAttributes, tabindex: this.config.tabIndex.toString(), }, this, ); if (posterUrl) { itemElement.css({ 'background-image': `url("${posterUrl}")` }); } const titleElement = new DOM( 'div', { class: this.prefixCss('title-container'), }, this, ); const innerTitleElement = new Label({ text: recommendationConfig.title, cssClass: 'title' }); titleElement.append(innerTitleElement.getDomElement()); itemElement.append(titleElement); if (recommendationConfig.duration != null) { const timeElement = new Label({ text: recommendationConfig.duration ? StringUtils.secondsToTime(recommendationConfig.duration) : '', cssClass: 'duration', }); itemElement.append(timeElement.getDomElement()); } if (!isExternalRecommendationLink(recommendationResource)) { // Only add click handler if it's not a link already and we need to load a new source itemElement.on('click', e => { e.preventDefault(); e.stopPropagation(); this.onClickEvent(); }); } return itemElement; } protected onClickEvent() { this.events.onClick.dispatch(this); } get onClick(): Event<RecommendationItem, NoArgs> { return this.events.onClick.getEvent(); } } function isExternalRecommendationLink(obj: any): obj is ExternalRecommendationLink { return 'url' in obj; }