Skip to content

Commit 4f0ded7

Browse files
authored
feat(ui): Add Loop, PIP, Cast, AirPlay buttons to control panel (shaka-project#3255)
These menu items are now available to be placed in the control panel of the UI. Issue shaka-project#2676
1 parent 198a6d4 commit 4f0ded7

File tree

7 files changed

+39
-1
lines changed

7 files changed

+39
-1
lines changed

docs/tutorials/ui-customization.md

+7
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,13 @@ The following elements can be added to the UI bar using this configuration value
6060
* fast_forward: adds a button that fast forwards the presentation on click; that is, it
6161
starts playing the presentation at an increased speed
6262
* spacer: adds a chunk of empty space between the adjacent elements.
63+
* picture_in_picture: adds a button that enables/disables picture-in-picture mode on browsers
64+
that support it. Button is invisible on other browsers.
65+
* loop: adds a button that controls if the currently selected video is played in a loop.
66+
* airplay: adds a button that opens a AirPlay dialog. The button is visible only if the browser
67+
supports AirPlay.
68+
* cast: adds a button that opens a Chromecast dialog. The button is visible only if there is
69+
at least one Chromecast device on the same network available for casting.
6370
<!-- TODO: If we add more buttons that can be put in the order this way, list them here. -->
6471

6572
Similarly, the 'overflowMenuButtons' configuration option can be used to control

ui/airplay_button.js

+5
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ goog.provide('shaka.ui.AirPlayButton');
1010
goog.require('goog.asserts');
1111
goog.require('shaka.Player');
1212
goog.require('shaka.ui.Constants');
13+
goog.require('shaka.ui.Controls');
1314
goog.require('shaka.ui.Element');
1415
goog.require('shaka.ui.Enums');
1516
goog.require('shaka.ui.Locales');
@@ -46,6 +47,7 @@ shaka.ui.AirPlayButton = class extends shaka.ui.Element {
4647

4748
const label = shaka.util.Dom.createHTMLElement('label');
4849
label.classList.add('shaka-overflow-button-label');
50+
label.classList.add('shaka-overflow-menu-only');
4951
this.airplayNameSpan_ = shaka.util.Dom.createHTMLElement('span');
5052
label.appendChild(this.airplayNameSpan_);
5153

@@ -157,3 +159,6 @@ shaka.ui.AirPlayButton.Factory = class {
157159

158160
shaka.ui.OverflowMenu.registerElement(
159161
'airplay', new shaka.ui.AirPlayButton.Factory());
162+
163+
shaka.ui.Controls.registerElement(
164+
'airplay', new shaka.ui.AirPlayButton.Factory());

ui/cast_button.js

+5
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ goog.provide('shaka.ui.CastButton');
99

1010
goog.require('shaka.cast.CastProxy');
1111
goog.require('shaka.ui.Constants');
12+
goog.require('shaka.ui.Controls');
1213
goog.require('shaka.ui.Element');
1314
goog.require('shaka.ui.Enums');
1415
goog.require('shaka.ui.Locales');
@@ -51,6 +52,7 @@ shaka.ui.CastButton = class extends shaka.ui.Element {
5152

5253
const label = shaka.util.Dom.createHTMLElement('label');
5354
label.classList.add('shaka-overflow-button-label');
55+
label.classList.add('shaka-overflow-menu-only');
5456
this.castNameSpan_ = shaka.util.Dom.createHTMLElement('span');
5557
label.appendChild(this.castNameSpan_);
5658

@@ -179,3 +181,6 @@ shaka.ui.CastButton.Factory = class {
179181

180182
shaka.ui.OverflowMenu.registerElement(
181183
'cast', new shaka.ui.CastButton.Factory());
184+
185+
shaka.ui.Controls.registerElement(
186+
'cast', new shaka.ui.CastButton.Factory());

ui/enums.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ shaka.ui.Enums.MaterialDesignIcons = {
3636
'PLAY': 'play_arrow',
3737
'PLAYBACK_RATE': 'slow_motion_video',
3838
'PAUSE': 'pause',
39-
'LOOP': 'loop',
39+
'LOOP': 'repeat',
40+
'UNLOOP': 'repeat_on',
4041
'AIRPLAY': 'airplay',
4142
'REPLAY': 'replay',
4243
};

ui/less/containers.less

+5
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,11 @@
170170
}
171171
}
172172

173+
/* Buttons hide certain items if they are found inside the control panel */
174+
.shaka-controls-button-panel .shaka-overflow-menu-only {
175+
display: none;
176+
}
177+
173178
/* The container for the giant play button. Sits above (Y axis) the
174179
* other video controls and seek bar, in the middle of the video frame, on top
175180
* of (Z axis) the video. */

ui/loop_button.js

+10
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
goog.provide('shaka.ui.LoopButton');
99

1010
goog.require('shaka.ui.Constants');
11+
goog.require('shaka.ui.Controls');
1112
goog.require('shaka.ui.Element');
1213
goog.require('shaka.ui.Enums');
1314
goog.require('shaka.ui.Locales');
@@ -44,6 +45,7 @@ shaka.ui.LoopButton = class extends shaka.ui.Element {
4445

4546
const label = shaka.util.Dom.createHTMLElement('label');
4647
label.classList.add('shaka-overflow-button-label');
48+
label.classList.add('shaka-overflow-menu-only');
4749
this.nameSpan_ = shaka.util.Dom.createHTMLElement('span');
4850
this.nameSpan_.textContent = this.localization.resolve(LocIds.LOOP);
4951
label.appendChild(this.nameSpan_);
@@ -133,6 +135,7 @@ shaka.ui.LoopButton = class extends shaka.ui.Element {
133135
*/
134136
updateLocalizedStrings_() {
135137
const LocIds = shaka.ui.Locales.Ids;
138+
const Icons = shaka.ui.Enums.MaterialDesignIcons;
136139

137140
this.nameSpan_.textContent =
138141
this.localization.resolve(LocIds.LOOP);
@@ -141,6 +144,10 @@ shaka.ui.LoopButton = class extends shaka.ui.Element {
141144

142145
this.currentState_.textContent = this.localization.resolve(labelText);
143146

147+
const icon = this.video.loop ? Icons.UNLOOP : Icons.LOOP;
148+
149+
this.icon_.textContent = icon;
150+
144151
const ariaText = this.video.loop ?
145152
LocIds.EXIT_LOOP_MODE : LocIds.ENTER_LOOP_MODE;
146153

@@ -163,3 +170,6 @@ shaka.ui.LoopButton.Factory = class {
163170

164171
shaka.ui.OverflowMenu.registerElement(
165172
'loop', new shaka.ui.LoopButton.Factory());
173+
174+
shaka.ui.Controls.registerElement(
175+
'loop', new shaka.ui.LoopButton.Factory());

ui/pip_button.js

+5
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
goog.provide('shaka.ui.PipButton');
99

1010
goog.require('shaka.ui.Constants');
11+
goog.require('shaka.ui.Controls');
1112
goog.require('shaka.ui.Element');
1213
goog.require('shaka.ui.Enums');
1314
goog.require('shaka.ui.Locales');
@@ -48,6 +49,7 @@ shaka.ui.PipButton = class extends shaka.ui.Element {
4849

4950
const label = shaka.util.Dom.createHTMLElement('label');
5051
label.classList.add('shaka-overflow-button-label');
52+
label.classList.add('shaka-overflow-menu-only');
5153
this.pipNameSpan_ = shaka.util.Dom.createHTMLElement('span');
5254
this.pipNameSpan_.textContent =
5355
this.localization.resolve(LocIds.PICTURE_IN_PICTURE);
@@ -235,3 +237,6 @@ shaka.ui.PipButton.Factory = class {
235237

236238
shaka.ui.OverflowMenu.registerElement(
237239
'picture_in_picture', new shaka.ui.PipButton.Factory());
240+
241+
shaka.ui.Controls.registerElement(
242+
'picture_in_picture', new shaka.ui.PipButton.Factory());

0 commit comments

Comments
 (0)