196 lines
4.8 KiB
JavaScript
196 lines
4.8 KiB
JavaScript
import $ from "jquery";
|
|
|
|
/**
|
|
* _Text()
|
|
*
|
|
* A helper class to control the text area for audio controls.
|
|
*
|
|
* @private
|
|
* @param {HTMLElement} div - The div of the text area.
|
|
*/
|
|
class _Text {
|
|
constructor(div) {
|
|
this._element = div;
|
|
|
|
this._text = "";
|
|
this._flashing = false;
|
|
|
|
this._flash_timeout = null;
|
|
}
|
|
|
|
flashText(text) {
|
|
let element = this._element;
|
|
let flash_timeout = this._flash_timeout;
|
|
|
|
element.html(text);
|
|
this._flashing = true;
|
|
|
|
clearTimeout(flash_timeout);
|
|
this._flash_timeout = setTimeout(() => {
|
|
this._flashing = false;
|
|
}, 1000);
|
|
}
|
|
|
|
setText(text) {
|
|
let element = this._element;
|
|
let flashing = this._flashing;
|
|
|
|
if (!flashing) {
|
|
element.html(text);
|
|
}
|
|
|
|
this._text = text;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* _Button()
|
|
*
|
|
* A helper class to control the indicator button for audio controls.
|
|
*
|
|
* @private
|
|
* @param {HTMLElement} button - The div of the button.
|
|
*/
|
|
class _Button {
|
|
constructor(button) {
|
|
this._element = button;
|
|
|
|
this._classes = "";
|
|
this._flash_classes = "";
|
|
this._flashing = false;
|
|
|
|
this._flash_timeout = null;
|
|
}
|
|
|
|
click(callback) {
|
|
this._element.click(callback);
|
|
}
|
|
|
|
flashIcon(icon) {
|
|
let classes = this._classes;
|
|
let element = this._element;
|
|
let flash_classes = this._flash_classes;
|
|
let flash_timeout = this._flash_timeout;
|
|
|
|
// We remove any potentially current classes, and add the
|
|
// requested icon class.
|
|
element.removeClass(flash_classes);
|
|
element.removeClass(classes);
|
|
element.addClass(icon);
|
|
|
|
// We keep track of the classes we are flashing and the fact
|
|
// that we are flashing, so that we can remove the correct
|
|
// classes later.
|
|
this._flash_classes = icon;
|
|
this._flashing = true;
|
|
|
|
// If we previously started a timeout, we'll want to cancel it
|
|
// now, since otherwise *it* will clear out our classes.
|
|
clearTimeout(flash_timeout);
|
|
|
|
// We start a timeout to reset to the original classes.
|
|
this._flash_timeout = setTimeout(() => {
|
|
element.removeClass(this._flash_classes);
|
|
element.addClass(this._classes);
|
|
|
|
this._flash_classes = "";
|
|
this._flashing = false;
|
|
}, 1000);
|
|
}
|
|
|
|
setIcon(icon) {
|
|
let classes = this._classes;
|
|
let element = this._element;
|
|
let flashing = this._flashing;
|
|
|
|
// If we are currently flashing an icon, we'll hold off on
|
|
// changing the icon.
|
|
if (!flashing) {
|
|
element.removeClass(classes);
|
|
element.addClass(icon);
|
|
}
|
|
|
|
this._classes = icon;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Controls()
|
|
*
|
|
* A class to manage music player controls.
|
|
*
|
|
* @param {AudioManager} audioManager - The audio manager to interact with.
|
|
*/
|
|
class Controls {
|
|
constructor(audioManager) {
|
|
this._element = $("#playerControls");
|
|
this._button = new _Button($("#playerControls #playerButton"));
|
|
this._text = new _Text($("#playerControls #playerText"));
|
|
this._audioManager = audioManager;
|
|
|
|
this._setAudioEvents({
|
|
canplay: () => this._audioManager.audio.play(),
|
|
error: () => this.setError(this._audioManager.audio.error.message),
|
|
loadstart: () => this.setLoading(),
|
|
playing: () => this.setPlaying(),
|
|
stalled: () => this.setLoading("Stalling")
|
|
});
|
|
|
|
this._button.click(() => this.mute());
|
|
}
|
|
|
|
setPlaying() {
|
|
let button = this._button;
|
|
let text = this._text;
|
|
|
|
button.setIcon("fa-play");
|
|
text.setText("");
|
|
}
|
|
|
|
setLoading(reason = "Loading") {
|
|
let button = this._button;
|
|
let text = this._text;
|
|
|
|
button.setIcon("fa-spin fa-spinner");
|
|
text.setText(reason);
|
|
}
|
|
|
|
setError(reason = "") {
|
|
let button = this._button;
|
|
let text = this._text;
|
|
|
|
if (reason == "") {
|
|
reason = "Error";
|
|
} else {
|
|
reason = `Error: ${reason}`;
|
|
}
|
|
|
|
button.setIcon("fa-stop-circle");
|
|
text.setText(reason);
|
|
}
|
|
|
|
mute() {
|
|
let audioManager = this._audioManager;
|
|
let button = this._button;
|
|
let text = this._text;
|
|
|
|
audioManager.mute();
|
|
|
|
if (audioManager.muted) {
|
|
button.flashIcon("fa-volume-off");
|
|
text.flashText("Muted");
|
|
} else {
|
|
button.flashIcon("fa-volume-up");
|
|
text.flashText("Unmuted");
|
|
}
|
|
}
|
|
|
|
_setAudioEvents(events) {
|
|
for (let [event, handler] of Object.entries(events)) {
|
|
this._audioManager.addEventListener(event, handler);
|
|
}
|
|
}
|
|
}
|
|
|
|
export default Controls;
|