nplayer
Version:
powerful danmaku video player
118 lines (104 loc) • 3.45 kB
text/typescript
import { Player } from 'src/ts/player';
import {
$, addClass, addDisposable, Component, isString, patch,
} from 'src/ts/utils';
import { Tooltip } from 'src/ts/components/tooltip';
import { Disposable } from 'src/ts/types';
import { EVENT } from 'src/ts/constants';
import { ControlItem } from '..';
import { spacerControlItem } from './spacer';
export class ControlBar extends Component {
private prevItems: ControlItem[] = [];
private spacer = spacerControlItem();
constructor(container: HTMLElement, private player: Player, items?: (ControlItem | string)[], private position = 0) {
super(container, '.control_bar');
if (position === 2) addClass(this.el, 'control_bar-top');
if (items) {
const frag = document.createDocumentFragment();
items.forEach((item) => {
item = this.initControlItem(item) as ControlItem;
if (item) {
frag.appendChild(item.el);
this.prevItems.push(item);
}
});
this.updateTooltipPos();
this.el.appendChild(frag);
}
}
private getItem(item: ControlItem | string): ControlItem | void {
if (item === 'spacer') return this.spacer;
if (isString(item)) item = this.player.getControlItem(item) as ControlItem;
if (!item || (item.isSupport && !item.isSupport(this.player))) return;
return item;
}
private initControlItem = (item: ControlItem | string): ControlItem | void => {
item = this.getItem(item) as ControlItem;
if (item) {
if (!item.el) item.el = $();
if (item.mounted) {
if (item.tooltip) {
item.tooltip.resetPos();
if (this.position === 2) item.tooltip.setBottom();
}
if (item.update) item.update(this.position);
return;
}
let tooltip: Tooltip | undefined;
if (item.tip) tooltip = new Tooltip(item.el, item.tip);
if (item.init) {
if (item.init.length > 2 && !tooltip) tooltip = new Tooltip(item.el);
item.init(this.player, this.position, tooltip as Tooltip);
}
if (item.dispose) addDisposable(this, item as Disposable);
if (!tooltip) tooltip = item.tooltip;
if (tooltip) {
tooltip.resetPos();
if (this.position === 2) tooltip.setBottom();
}
item.mounted = true;
return item;
}
}
private onHideControlItem = (item: ControlItem) => {
if (item.hide) item.hide();
}
updateTooltipPos() {
const last = this.prevItems.length - 1;
this.prevItems.forEach((item, i) => {
if (item.tooltip) {
item.tooltip.resetPos();
if (this.position === 2) item.tooltip.setBottom();
if (i === 0) {
item.tooltip.setLeft();
} else if (i === last) {
item.tooltip.setRight();
}
}
});
}
getItems(): ControlItem[] {
return this.prevItems;
}
setItems(items?: ControlItem[]): void {
if (items) {
this.prevItems = items;
}
}
update(nextItems: (string | ControlItem)[]) {
if (nextItems) {
const items: ControlItem[] = [];
nextItems.forEach((item) => {
item = this.getItem(item) as ControlItem;
if (item) items.push(item);
});
patch(this.prevItems, items, this.el, {
mount: this.initControlItem,
unmount: this.onHideControlItem,
});
this.prevItems = items;
this.updateTooltipPos();
this.player.emit(EVENT.CONTROL_ITEM_UPDATE);
}
}
}