Skip to content

Commit 91e4b2a

Browse files
authored
fix: source switcher on mobile, tap (#908)
* fix: source switcher on mobile
1 parent b7b8ec9 commit 91e4b2a

File tree

2 files changed

+59
-43
lines changed

2 files changed

+59
-43
lines changed

src/components/source-switcher-button/source-switcher-button.js

Lines changed: 25 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import videojs from 'video.js';
2+
import SourceMenuItem from './source-switcher-menu-item';
23
import './source-switcher-button.scss';
34

45
const MenuButton = videojs.getComponent('MenuButton');
@@ -10,14 +11,13 @@ class SourceSwitcherButton extends MenuButton {
1011

1112
this.controlText(options.tooltip || 'Sources');
1213
this._emptyLabel = options.emptyLabel || 'No sources';
14+
this._items = Array.isArray(options.items) ? options.items : [];
15+
this._selectedIndex = Number.isInteger(options.defaultIndex)
16+
? options.defaultIndex
17+
: undefined;
18+
this._onSelected = typeof options.onSelected === 'function' ? options.onSelected : null;
1319

14-
this._items = options.items || [];
15-
this._selectedIndex = Number.isInteger(options.defaultIndex) ? options.defaultIndex : undefined;
16-
17-
const onSelected = typeof options.onSelected === 'function' ? options.onSelected : null;
18-
19-
this._onSelected = onSelected || null;
20-
this._setEnabled(Array.isArray(this._items) && this._items.length > 0);
20+
this._setEnabled(this._items.length > 0);
2121
}
2222

2323
buildCSSClass() {
@@ -28,7 +28,7 @@ class SourceSwitcherButton extends MenuButton {
2828
createItems() {
2929
if (!Array.isArray(this._items) || this._items.length === 0) {
3030
const empty = new MenuItem(this.player_, {
31-
label: this._emptyLabel || 'No sources',
31+
label: this._emptyLabel,
3232
selectable: false
3333
});
3434
empty.addClass('vjs-source-switcher-empty');
@@ -37,62 +37,45 @@ class SourceSwitcherButton extends MenuButton {
3737
}
3838

3939
return this._items.map(({ label, value }, index) => {
40-
const item = new MenuItem(this.player_, {
40+
return new SourceMenuItem(this.player_, {
4141
label,
42-
selectable: true,
43-
selected: index === this._selectedIndex
44-
});
45-
item.value = value;
46-
item._ssIndex = index;
47-
48-
item.on('click', () => {
49-
this.menu.children().forEach((child) => {
50-
if (child instanceof MenuItem) {
51-
child.selected(child._ssIndex === index);
52-
}
53-
});
54-
55-
this._selectedIndex = index;
56-
const payload = { index, value, label };
57-
if (this._onSelected) this._onSelected(payload, this.player_);
58-
this.player_.trigger('sourceswitcher:change', payload);
42+
value,
43+
index,
44+
selected: index === this._selectedIndex,
45+
onSelect: (payload) => this._handleItemSelect(payload)
5946
});
60-
61-
return item;
6247
});
6348
}
6449

50+
_handleItemSelect({ index }) {
51+
if (this._selectedIndex === index) return;
52+
this.setSelected(index);
53+
}
54+
6555
setItems(items) {
66-
this._items = items;
56+
this._items = Array.isArray(items) ? items : [];
6757
this._selectedIndex = this._items.length ? 0 : undefined;
6858

6959
this._setEnabled(this._items.length > 0);
7060
this._rebuildMenu();
7161
}
7262

7363
setSelected(index) {
74-
if (
75-
!Array.isArray(this._items) ||
76-
index == null ||
77-
index < 0 ||
78-
index >= this._items.length
79-
) return;
64+
if (!Array.isArray(this._items) || index == null || index < 0 || index >= this._items.length) return;
8065

8166
this._selectedIndex = index;
8267

8368
// reflect in UI if menu exists
84-
if (this.menu) {
69+
if (this.menu && typeof this.menu.children === 'function') {
8570
this.menu.children().forEach((child) => {
8671
if (child instanceof MenuItem) {
8772
child.selected(child._ssIndex === index);
8873
}
8974
});
9075
}
9176

92-
const { label, value } = this._items[index];
93-
const payload = { index, value, label };
94-
if (this._onSelected) this._onSelected(payload, this.player_);
95-
this.player_.trigger('sourceswitcher:change', payload);
77+
const { value } = this._items[index];
78+
if (this._onSelected) this._onSelected({ index, value }, this.player_);
9679
}
9780

9881
setOnSelected(fn) {
@@ -104,8 +87,7 @@ class SourceSwitcherButton extends MenuButton {
10487
this.menu.children().slice().forEach((c) => this.menu.removeChild(c));
10588
this.createItems().forEach((i) => this.menu.addItem(i));
10689

107-
// Toggle disabled class based on emptiness
108-
const el = this.el();
90+
const el = this.el && this.el();
10991
if (el) {
11092
const empty = this._items.length === 0;
11193
el.classList.toggle('vjs-source-switcher-disabled', empty);
@@ -114,7 +96,7 @@ class SourceSwitcherButton extends MenuButton {
11496
}
11597

11698
_setEnabled(enabled) {
117-
const el = this.el();
99+
const el = this.el && this.el();
118100
if (!el) return;
119101
el.classList.toggle('vjs-source-switcher-disabled', !enabled);
120102
el.setAttribute('aria-disabled', String(!enabled));
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import videojs from 'video.js';
2+
3+
const MenuItem = videojs.getComponent('MenuItem');
4+
5+
class SourceMenuItem extends MenuItem {
6+
constructor(player, options = {}) {
7+
super(player, {
8+
...options,
9+
selectable: true,
10+
multiSelectable: false,
11+
selected: !!options.selected,
12+
label: options.label
13+
});
14+
15+
this.value = options.value;
16+
this._ssIndex = options.index;
17+
this._onSelect = typeof options.onSelect === 'function' ? options.onSelect : null;
18+
}
19+
20+
handleClick(event) {
21+
super.handleClick(event);
22+
23+
if (this._onSelect) {
24+
this._onSelect({
25+
index: this._ssIndex,
26+
value: this.value,
27+
label: this.options_.label
28+
});
29+
}
30+
}
31+
}
32+
33+
videojs.registerComponent('SourceMenuItem', SourceMenuItem);
34+
export default SourceMenuItem;

0 commit comments

Comments
 (0)