import {h, Component, createRef} from 'preact';
import {LayoutHotspot, shallowCompareHotspots} from '../utils/hotspot';
import Hotspot from './Hotspot';
import {AnalyticsEvents} from '../utils/analyticsEvents';
const { withPlayer } = KalturaPlayer.ui.components;
const { withText, Text } = KalturaPlayer.ui.preacti18n;
const translates = {
hotspotRemoved: (
{`{hotspotLabel} hotspot removed`}
),
hotspotAdded: (
{`{hotspotLabel} hotspot added`}
)
};
const hotspotsContainerStyles = {
position: 'absolute',
display: 'block',
overflow: 'visible',
top: 0,
left: 0,
width: 0,
height: 0
};
export interface Props {
hotspots: LayoutHotspot[];
pauseVideo(): void;
seekTo(time: number): void;
sendAnalytics(event: AnalyticsEvents): void;
dispatcher(name: string, payload?: any): void;
hotspotRemoved?: string;
hotspotAdded?: string;
player?: any;
}
@withPlayer
@withText(translates)
export default class HotspotWrapper extends Component {
private liveRegionRef = createRef();
private previousHotspotMap: Map = new Map();
shouldComponentUpdate(nextProps: Props) {
return !shallowCompareHotspots(this.props.hotspots, nextProps.hotspots);
}
componentDidUpdate() {
const currentMap = new Map(
this.props.hotspots
.filter(h => typeof h.label === 'string')
.map(h => [h.id, h.label!])
);
let announced = false;
// Announce removed hotspots
this.previousHotspotMap.forEach((label, id) => {
if (!currentMap.has(id) && !announced) {
if (this.props.hotspotRemoved) {
const message = this.props.hotspotRemoved.replace('{hotspotLabel}', label);
this.announceHotspotChange(message);
}
announced = true;
}
});
// Announce added hotspots
if (!announced) {
currentMap.forEach((label, id) => {
if (!this.previousHotspotMap.has(id) && !announced) {
if (this.props.hotspotAdded) {
const message = this.props.hotspotAdded.replace('{hotspotLabel}', label);
this.announceHotspotChange(message);
}
announced = true;
}
});
}
this.previousHotspotMap = currentMap;
}
private announceHotspotChange(message: string) {
const liveRegion = this.liveRegionRef.current;
if (!liveRegion) return;
liveRegion.textContent = '';
//setTimeout ensures the DOM change happens in two separate cycles
// which solves the issue that the hotspot removal is announced only the first time.
setTimeout(() => {
liveRegion.textContent = message;
});
}
private renderHotspots = (visualHotspot: LayoutHotspot[]) => {
if (!visualHotspot) {
return null;
}
const {seekTo, pauseVideo, sendAnalytics, dispatcher} = this.props;
return visualHotspot.map(hotspotData => (
));
};
render() {
const {hotspots} = this.props;
const hotspotsElements = this.renderHotspots(hotspots);
const targetId = this.props.player?.config?.targetId;
const liveRegionId = `hotspot-liveRegion-${targetId}`;
return (
);
}
}